/* DWARF 2 debugging format support for GDB.
- Copyright (C) 1994-2015 Free Software Foundation, Inc.
+ Copyright (C) 1994-2017 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
#include "block.h"
#include "addrmap.h"
#include "typeprint.h"
-#include "jv-lang.h"
#include "psympriv.h"
#include <sys/stat.h>
#include "completer.h"
#include "filestuff.h"
#include "build-id.h"
#include "namespace.h"
+#include "common/gdb_unlinker.h"
+#include "common/function-view.h"
+#include "common/gdb_optional.h"
+#include "common/underlying.h"
#include <fcntl.h>
#include <sys/types.h>
+#include <algorithm>
typedef struct symbol *symbolp;
DEF_VEC_P (symbolp);
struct dwarf2_section_info abbrev;
struct dwarf2_section_info line;
struct dwarf2_section_info loc;
+ struct dwarf2_section_info loclists;
struct dwarf2_section_info macinfo;
struct dwarf2_section_info macro;
struct dwarf2_section_info str;
+ struct dwarf2_section_info line_str;
struct dwarf2_section_info ranges;
+ struct dwarf2_section_info rnglists;
struct dwarf2_section_info addr;
struct dwarf2_section_info frame;
struct dwarf2_section_info eh_frame;
{ ".debug_abbrev", ".zdebug_abbrev" },
{ ".debug_line", ".zdebug_line" },
{ ".debug_loc", ".zdebug_loc" },
+ { ".debug_loclists", ".zdebug_loclists" },
{ ".debug_macinfo", ".zdebug_macinfo" },
{ ".debug_macro", ".zdebug_macro" },
{ ".debug_str", ".zdebug_str" },
+ { ".debug_line_str", ".zdebug_line_str" },
{ ".debug_ranges", ".zdebug_ranges" },
+ { ".debug_rnglists", ".zdebug_rnglists" },
{ ".debug_types", ".zdebug_types" },
{ ".debug_addr", ".zdebug_addr" },
{ ".debug_frame", ".zdebug_frame" },
struct dwarf2_section_names info_dwo;
struct dwarf2_section_names line_dwo;
struct dwarf2_section_names loc_dwo;
+ struct dwarf2_section_names loclists_dwo;
struct dwarf2_section_names macinfo_dwo;
struct dwarf2_section_names macro_dwo;
struct dwarf2_section_names str_dwo;
{ ".debug_info.dwo", ".zdebug_info.dwo" },
{ ".debug_line.dwo", ".zdebug_line.dwo" },
{ ".debug_loc.dwo", ".zdebug_loc.dwo" },
+ { ".debug_loclists.dwo", ".zdebug_loclists.dwo" },
{ ".debug_macinfo.dwo", ".zdebug_macinfo.dwo" },
{ ".debug_macro.dwo", ".zdebug_macro.dwo" },
{ ".debug_str.dwo", ".zdebug_str.dwo" },
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;
/* Size of the length field; either 4 or 12. */
unsigned int initial_length_size;
+ enum dwarf_unit_type unit_type;
+
/* 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_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). */
+ short dwarf_version;
+
/* Flag indicating this compilation unit will be read in before
any of the current compilation units are processed. */
unsigned int queued : 1;
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
struct dwarf2_section_info abbrev;
struct dwarf2_section_info line;
struct dwarf2_section_info loc;
+ struct dwarf2_section_info loclists;
struct dwarf2_section_info macinfo;
struct dwarf2_section_info macro;
struct dwarf2_section_info str;
/* 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;
unsigned int has_pc_info : 1;
unsigned int may_be_inlined : 1;
+ /* This DIE has been marked DW_AT_main_subprogram. */
+ unsigned int main_subprogram : 1;
+
/* Flag set if the SCOPE field of this structure has been
computed. */
unsigned int scope_set : 1;
/* 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. */
{
ENUM_BITFIELD(dwarf_attribute) name : 16;
ENUM_BITFIELD(dwarf_form) form : 16;
+
+ /* It is valid only if FORM is DW_FORM_implicit_const. */
+ LONGEST implicit_const;
};
/* Size of abbrev_table.abbrev_hash_table. */
{
/* 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
const struct comp_unit_head *,
unsigned int *);
-static const char *read_indirect_string_from_dwz (struct dwz_file *, LONGEST);
+static const char *read_indirect_line_string (bfd *, const gdb_byte *,
+ const struct comp_unit_head *,
+ unsigned int *);
-static ULONGEST read_unsigned_leb128 (bfd *, const gdb_byte *, unsigned int *);
+static const char *read_indirect_string_from_dwz (struct dwz_file *, LONGEST);
static LONGEST read_signed_leb128 (bfd *, const gdb_byte *, unsigned int *);
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 int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
struct dwarf2_cu *, struct partial_symtab *);
-static int dwarf2_get_pc_bounds (struct die_info *,
- CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *,
- struct partial_symtab *);
+/* How dwarf2_get_pc_bounds constructed its *LOWPC and *HIGHPC return
+ values. Keep the items ordered with increasing constraints compliance. */
+enum pc_bounds_kind
+{
+ /* No attribute DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges was found. */
+ PC_BOUNDS_NOT_PRESENT,
+
+ /* Some of the attributes DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges
+ were present but they do not form a valid range of PC addresses. */
+ PC_BOUNDS_INVALID,
+
+ /* Discontiguous range was found - that is DW_AT_ranges was found. */
+ PC_BOUNDS_RANGES,
+
+ /* Contiguous range was found - DW_AT_low_pc and DW_AT_high_pc were found. */
+ PC_BOUNDS_HIGH_LOW,
+};
+
+static enum pc_bounds_kind dwarf2_get_pc_bounds (struct die_info *,
+ CORE_ADDR *, CORE_ADDR *,
+ struct dwarf2_cu *,
+ struct partial_symtab *);
static void get_scope_pc_bounds (struct die_info *,
CORE_ADDR *, CORE_ADDR *,
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);
+/* Expected enum dwarf_unit_type for read_comp_unit_head. */
+enum class rcuh_kind { COMPILE, TYPE };
+
static const gdb_byte *read_and_check_comp_unit_head
(struct comp_unit_head *header,
struct dwarf2_section_info *section,
struct dwarf2_section_info *abbrev_section, const gdb_byte *info_ptr,
- int is_debug_types_section);
+ rcuh_kind section_kind);
static void init_cutu_and_read_dies
(struct dwarf2_per_cu_data *this_cu, struct abbrev_table *abbrev_table,
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. */
static hashval_t
line_header_hash_voidp (const void *item)
{
- const struct line_header *ofs = item;
+ const struct line_header *ofs = (const struct line_header *) item;
return line_header_hash (ofs);
}
static int
line_header_eq_voidp (const void *item_lhs, const void *item_rhs)
{
- const struct line_header *ofs_lhs = item_lhs;
- const struct line_header *ofs_rhs = item_rhs;
+ 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);
}
dwarf2_has_info (struct objfile *objfile,
const struct dwarf2_debug_sections *names)
{
- dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+ dwarf2_per_objfile = ((struct dwarf2_per_objfile *)
+ objfile_data (objfile, dwarf2_objfile_data_key));
if (!dwarf2_per_objfile)
{
/* Initialize per-objfile state. */
dwarf2_per_objfile->loc.s.section = sectp;
dwarf2_per_objfile->loc.size = bfd_get_section_size (sectp);
}
+ else if (section_is_p (sectp->name, &names->loclists))
+ {
+ dwarf2_per_objfile->loclists.s.section = sectp;
+ dwarf2_per_objfile->loclists.size = bfd_get_section_size (sectp);
+ }
else if (section_is_p (sectp->name, &names->macinfo))
{
dwarf2_per_objfile->macinfo.s.section = sectp;
dwarf2_per_objfile->str.s.section = sectp;
dwarf2_per_objfile->str.size = bfd_get_section_size (sectp);
}
+ else if (section_is_p (sectp->name, &names->line_str))
+ {
+ dwarf2_per_objfile->line_str.s.section = sectp;
+ dwarf2_per_objfile->line_str.size = bfd_get_section_size (sectp);
+ }
else if (section_is_p (sectp->name, &names->addr))
{
dwarf2_per_objfile->addr.s.section = sectp;
dwarf2_per_objfile->ranges.s.section = sectp;
dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp);
}
+ else if (section_is_p (sectp->name, &names->rnglists))
+ {
+ dwarf2_per_objfile->rnglists.s.section = sectp;
+ dwarf2_per_objfile->rnglists.size = bfd_get_section_size (sectp);
+ }
else if (section_is_p (sectp->name, &names->types))
{
struct dwarf2_section_info type_section;
return;
}
- buf = obstack_alloc (&objfile->objfile_obstack, info->size);
+ buf = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, info->size);
info->buffer = buf;
/* When debugging .o files, we may need to apply relocations; see
bfd_size_type *sizep)
{
struct dwarf2_per_objfile *data
- = objfile_data (objfile, dwarf2_objfile_data_key);
+ = (struct dwarf2_per_objfile *) objfile_data (objfile,
+ dwarf2_objfile_data_key);
struct dwarf2_section_info *info;
/* We may see an objfile without any DWARF, in which case we just
static void
locate_dwz_sections (bfd *abfd, asection *sectp, void *arg)
{
- struct dwz_file *dwz_file = arg;
+ struct dwz_file *dwz_file = (struct dwz_file *) arg;
/* Note that we only support the standard ELF names, because .dwz
is ELF-only (at the time of writing). */
static struct dwz_file *
dwarf2_get_dwz_file (void)
{
- bfd *dwz_bfd;
char *data;
struct cleanup *cleanup;
const char *filename;
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
work, try to use the build-id instead. */
- dwz_bfd = gdb_bfd_open (filename, gnutarget, -1);
+ gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename, gnutarget, -1));
if (dwz_bfd != NULL)
{
- if (!build_id_verify (dwz_bfd, buildid_len, buildid))
- {
- gdb_bfd_unref (dwz_bfd);
- dwz_bfd = NULL;
- }
+ if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
+ dwz_bfd.release ();
}
if (dwz_bfd == NULL)
result = OBSTACK_ZALLOC (&dwarf2_per_objfile->objfile->objfile_obstack,
struct dwz_file);
- result->dwz_bfd = dwz_bfd;
+ result->dwz_bfd = dwz_bfd.release ();
- bfd_map_over_sections (dwz_bfd, locate_dwz_sections, result);
+ bfd_map_over_sections (result->dwz_bfd, locate_dwz_sections, result);
do_cleanups (cleanup);
- gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, dwz_bfd);
+ gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, result->dwz_bfd);
dwarf2_per_objfile->dwz_file = result;
return result;
}
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. */
static hashval_t
hash_file_name_entry (const void *e)
{
- const struct quick_file_names *file_data = e;
+ const struct quick_file_names *file_data
+ = (const struct quick_file_names *) e;
return hash_stmt_list_entry (&file_data->hash);
}
static int
eq_file_name_entry (const void *a, const void *b)
{
- const struct quick_file_names *ea = a;
- const struct quick_file_names *eb = b;
+ const struct quick_file_names *ea = (const struct quick_file_names *) a;
+ const struct quick_file_names *eb = (const struct quick_file_names *) b;
return eq_stmt_list_entry (&ea->hash, &eb->hash);
}
static void
delete_file_name_entry (void *e)
{
- struct quick_file_names *file_data = e;
+ struct quick_file_names *file_data = (struct quick_file_names *) e;
int i;
for (i = 0; i < file_data->num_file_names; ++i)
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,
int (*cmp) (const char *, const char *);
if (current_language->la_language == language_cplus
- || current_language->la_language == language_java
|| current_language->la_language == language_fortran
|| current_language->la_language == language_d)
{
static void
dw2_setup (struct objfile *objfile)
{
- dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+ dwarf2_per_objfile = ((struct dwarf2_per_objfile *)
+ objfile_data (objfile, dwarf2_objfile_data_key));
gdb_assert (dwarf2_per_objfile);
}
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)
{
- lh_cu->v.quick->file_names = *slot;
+ lh_cu->v.quick->file_names = (struct quick_file_names *) *slot;
return;
}
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;
if (file_matcher != NULL)
{
- struct cleanup *cleanup;
- htab_t visited_found, visited_not_found;
-
- visited_found = htab_create_alloc (10,
- htab_hash_pointer, htab_eq_pointer,
- NULL, xcalloc, xfree);
- cleanup = make_cleanup_htab_delete (visited_found);
- visited_not_found = htab_create_alloc (10,
- htab_hash_pointer, htab_eq_pointer,
- NULL, xcalloc, xfree);
- make_cleanup_htab_delete (visited_not_found);
+ htab_up visited_found (htab_create_alloc (10, htab_hash_pointer,
+ htab_eq_pointer,
+ NULL, xcalloc, xfree));
+ htab_up visited_not_found (htab_create_alloc (10, htab_hash_pointer,
+ htab_eq_pointer,
+ NULL, xcalloc, xfree));
/* The rule is CUs specify all the files, including those used by
any TU, so there's no need to scan TUs here. */
if (file_data == NULL)
continue;
- if (htab_find (visited_not_found, file_data) != NULL)
+ if (htab_find (visited_not_found.get (), file_data) != NULL)
continue;
- else if (htab_find (visited_found, file_data) != NULL)
+ else if (htab_find (visited_found.get (), file_data) != NULL)
{
per_cu->v.quick->mark = 1;
continue;
{
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;
}
slot = htab_find_slot (per_cu->v.quick->mark
- ? visited_found
- : visited_not_found,
+ ? visited_found.get ()
+ : visited_not_found.get (),
file_data, INSERT);
*slot = file_data;
}
-
- do_cleanups (cleanup);
}
for (iter = 0; iter < index->symbol_table_slots; ++iter)
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);
}
}
}
if (!objfile->psymtabs_addrmap)
return NULL;
- data = addrmap_find (objfile->psymtabs_addrmap, pc);
+ data = (struct dwarf2_per_cu_data *) addrmap_find (objfile->psymtabs_addrmap,
+ pc);
if (!data)
return NULL;
void *data, int need_fullname)
{
int i;
- struct cleanup *cleanup;
- htab_t visited = htab_create_alloc (10, htab_hash_pointer, htab_eq_pointer,
- NULL, xcalloc, xfree);
+ htab_up visited (htab_create_alloc (10, htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree));
- cleanup = make_cleanup_htab_delete (visited);
dw2_setup (objfile);
/* The rule is CUs specify all the files, including those used by
if (per_cu->v.quick->compunit_symtab)
{
- void **slot = htab_find_slot (visited, per_cu->v.quick->file_names,
+ void **slot = htab_find_slot (visited.get (),
+ per_cu->v.quick->file_names,
INSERT);
*slot = per_cu->v.quick->file_names;
if (file_data == NULL)
continue;
- slot = htab_find_slot (visited, file_data, INSERT);
+ slot = htab_find_slot (visited.get (), file_data, INSERT);
if (*slot)
{
/* Already visited. */
(*fun) (file_data->file_names[j], this_real_name, data);
}
}
-
- do_cleanups (cleanup);
}
static int
/* This isn't really ideal: all the data we allocate on the
objfile's obstack is still uselessly kept around. However,
freeing it seems unsafe. */
- struct cleanup *cleanups = make_cleanup_discard_psymtabs (objfile);
-
+ psymtab_discarder psymtabs (objfile);
dwarf2_build_psymtabs_hard (objfile);
- discard_cleanups (cleanups);
+ psymtabs.keep ();
}
CATCH (except, RETURN_MASK_ERROR)
{
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
}
/* Read in the comp unit header information from the debug_info at info_ptr.
+ Use rcuh_kind::COMPILE as the default type if not known by the caller.
NOTE: This leaves members offset, first_die_offset to be filled in
by the caller. */
static const gdb_byte *
read_comp_unit_head (struct comp_unit_head *cu_header,
- const gdb_byte *info_ptr, bfd *abfd)
+ const gdb_byte *info_ptr,
+ struct dwarf2_section_info *section,
+ rcuh_kind section_kind)
{
int signed_addr;
unsigned int bytes_read;
+ const char *filename = get_section_file_name (section);
+ bfd *abfd = get_section_bfd_owner (section);
cu_header->length = read_initial_length (abfd, info_ptr, &bytes_read);
cu_header->initial_length_size = bytes_read;
info_ptr += bytes_read;
cu_header->version = read_2_bytes (abfd, info_ptr);
info_ptr += 2;
- cu_header->abbrev_offset.sect_off = read_offset (abfd, info_ptr, cu_header,
- &bytes_read);
+ if (cu_header->version < 5)
+ switch (section_kind)
+ {
+ case rcuh_kind::COMPILE:
+ cu_header->unit_type = DW_UT_compile;
+ break;
+ case rcuh_kind::TYPE:
+ cu_header->unit_type = DW_UT_type;
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("read_comp_unit_head: invalid section_kind"));
+ }
+ else
+ {
+ cu_header->unit_type = static_cast<enum dwarf_unit_type>
+ (read_1_byte (abfd, info_ptr));
+ info_ptr += 1;
+ switch (cu_header->unit_type)
+ {
+ case DW_UT_compile:
+ if (section_kind != rcuh_kind::COMPILE)
+ error (_("Dwarf Error: wrong unit_type in compilation unit header "
+ "(is DW_UT_compile, should be DW_UT_type) [in module %s]"),
+ filename);
+ break;
+ case DW_UT_type:
+ section_kind = rcuh_kind::TYPE;
+ break;
+ default:
+ error (_("Dwarf Error: wrong unit_type in compilation unit header "
+ "(is %d, should be %d or %d) [in module %s]"),
+ cu_header->unit_type, DW_UT_compile, DW_UT_type, filename);
+ }
+
+ cu_header->addr_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ }
+ cu_header->abbrev_sect_off = (sect_offset) read_offset (abfd, info_ptr,
+ cu_header,
+ &bytes_read);
info_ptr += bytes_read;
- cu_header->addr_size = read_1_byte (abfd, info_ptr);
- info_ptr += 1;
+ if (cu_header->version < 5)
+ {
+ cu_header->addr_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ }
signed_addr = bfd_get_sign_extend_vma (abfd);
if (signed_addr < 0)
internal_error (__FILE__, __LINE__,
_("read_comp_unit_head: dwarf from non elf file"));
cu_header->signed_addr_p = signed_addr;
+ if (section_kind == rcuh_kind::TYPE)
+ {
+ LONGEST type_offset;
+
+ cu_header->signature = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+
+ type_offset = read_offset (abfd, info_ptr, cu_header, &bytes_read);
+ info_ptr += bytes_read;
+ 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);
+ }
+
return info_ptr;
}
struct dwarf2_section_info *section,
struct dwarf2_section_info *abbrev_section)
{
- bfd *abfd = get_section_bfd_owner (section);
const char *filename = get_section_file_name (section);
- if (header->version != 2 && header->version != 3 && header->version != 4)
+ if (header->version < 2 || header->version > 5)
error (_("Dwarf Error: wrong version in compilation unit header "
- "(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
+ "(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);
}
struct dwarf2_section_info *section,
struct dwarf2_section_info *abbrev_section,
const gdb_byte *info_ptr,
- int is_debug_types_section)
-{
- 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;
-
- info_ptr = read_comp_unit_head (header, info_ptr, abfd);
-
- /* If we're reading a type unit, skip over the signature and
- type_offset fields. */
- if (is_debug_types_section)
- info_ptr += 8 /*signature*/ + header->offset_size;
-
- header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
-
- error_check_comp_unit_head (header, section, abbrev_section);
-
- return info_ptr;
-}
-
-/* Read in the types comp unit header information from .debug_types entry at
- types_ptr. The result is a pointer to one past the end of the header. */
-
-static const gdb_byte *
-read_and_check_type_unit_head (struct comp_unit_head *header,
- struct dwarf2_section_info *section,
- struct dwarf2_section_info *abbrev_section,
- const gdb_byte *info_ptr,
- ULONGEST *signature,
- cu_offset *type_offset_in_tu)
+ rcuh_kind section_kind)
{
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;
-
- info_ptr = read_comp_unit_head (header, info_ptr, abfd);
+ header->sect_off = (sect_offset) (beg_of_comp_unit - section->buffer);
- /* If we're reading a type unit, skip over the signature and
- type_offset fields. */
- if (signature != NULL)
- *signature = read_8_bytes (abfd, info_ptr);
- info_ptr += 8;
- if (type_offset_in_tu != NULL)
- type_offset_in_tu->cu_off = read_offset_1 (abfd, info_ptr,
- header->offset_size);
- info_ptr += header->offset_size;
+ 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 length, initial_length_size, offset_size;
- sect_offset abbrev_offset;
+ unsigned int initial_length_size, offset_size;
+ uint16_t version;
dwarf2_read_section (dwarf2_per_objfile->objfile, section);
- info_ptr = section->buffer + offset.sect_off;
- length = read_initial_length (abfd, info_ptr, &initial_length_size);
+ 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 + 2 /*version*/;
- abbrev_offset.sect_off = read_offset_1 (abfd, info_ptr, offset_size);
- return abbrev_offset;
+ info_ptr += initial_length_size;
+
+ version = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ if (version >= 5)
+ {
+ /* Skip unit type and address size. */
+ info_ptr += 2;
+ }
+
+ 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
hash_signatured_type (const void *item)
{
- const struct signatured_type *sig_type = item;
+ const struct signatured_type *sig_type
+ = (const struct signatured_type *) item;
/* This drops the top 32 bits of the signature, but is ok for a hash. */
return sig_type->signature;
static int
eq_signatured_type (const void *item_lhs, const void *item_rhs)
{
- const struct signatured_type *lhs = item_lhs;
- const struct signatured_type *rhs = item_rhs;
+ const struct signatured_type *lhs = (const struct signatured_type *) item_lhs;
+ const struct signatured_type *rhs = (const struct signatured_type *) item_rhs;
return lhs->signature == rhs->signature;
}
static int
add_signatured_type_cu_to_table (void **slot, void *datum)
{
- struct signatured_type *sigt = *slot;
- struct signatured_type ***datap = datum;
+ struct signatured_type *sigt = (struct signatured_type *) *slot;
+ struct signatured_type ***datap = (struct signatured_type ***) datum;
**datap = sigt;
++*datap;
return 1;
}
-/* Create the hash table of all entries in the .debug_types
- (or .debug_types.dwo) section(s).
- If reading a DWO file, then DWO_FILE is a pointer to the DWO file object,
- otherwise it is NULL.
-
- The result is a pointer to the hash table or NULL if there are no types.
-
- Note: This function processes DWO files only, not DWP files. */
+/* A helper for create_debug_types_hash_table. Read types from SECTION
+ and fill them into TYPES_HTAB. It will process only type units,
+ therefore DW_UT_type. */
-static htab_t
-create_debug_types_hash_table (struct dwo_file *dwo_file,
- VEC (dwarf2_section_info_def) *types)
+static void
+create_debug_type_hash_table (struct dwo_file *dwo_file,
+ dwarf2_section_info *section, htab_t &types_htab,
+ rcuh_kind section_kind)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- htab_t types_htab = NULL;
- int ix;
- struct dwarf2_section_info *section;
struct dwarf2_section_info *abbrev_section;
-
- if (VEC_empty (dwarf2_section_info_def, types))
- return NULL;
+ bfd *abfd;
+ const gdb_byte *info_ptr, *end_ptr;
abbrev_section = (dwo_file != NULL
? &dwo_file->sections.abbrev
: &dwarf2_per_objfile->abbrev);
if (dwarf_read_debug)
- fprintf_unfiltered (gdb_stdlog, "Reading .debug_types%s for %s:\n",
- dwo_file ? ".dwo" : "",
+ fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
+ get_section_name (section),
get_section_file_name (abbrev_section));
- for (ix = 0;
- VEC_iterate (dwarf2_section_info_def, types, ix, section);
- ++ix)
- {
- bfd *abfd;
- const gdb_byte *info_ptr, *end_ptr;
+ dwarf2_read_section (objfile, section);
+ info_ptr = section->buffer;
- dwarf2_read_section (objfile, section);
- info_ptr = section->buffer;
+ if (info_ptr == NULL)
+ return;
- if (info_ptr == NULL)
- continue;
+ /* We can't set abfd until now because the section may be empty or
+ not present, in which case the bfd is unknown. */
+ abfd = get_section_bfd_owner (section);
- /* We can't set abfd until now because the section may be empty or
- not present, in which case the bfd is unknown. */
- abfd = get_section_bfd_owner (section);
+ /* We don't use init_cutu_and_read_dies_simple, or some such, here
+ because we don't need to read any dies: the signature is in the
+ header. */
- /* We don't use init_cutu_and_read_dies_simple, or some such, here
- because we don't need to read any dies: the signature is in the
- header. */
+ end_ptr = info_ptr + section->size;
+ while (info_ptr < end_ptr)
+ {
+ struct signatured_type *sig_type;
+ struct dwo_unit *dwo_tu;
+ void **slot;
+ const gdb_byte *ptr = info_ptr;
+ struct comp_unit_head header;
+ unsigned int length;
- end_ptr = info_ptr + section->size;
- while (info_ptr < end_ptr)
- {
- sect_offset offset;
- cu_offset type_offset_in_tu;
- ULONGEST signature;
- struct signatured_type *sig_type;
- struct dwo_unit *dwo_tu;
- void **slot;
- const gdb_byte *ptr = info_ptr;
- struct comp_unit_head header;
- unsigned int length;
+ sect_offset sect_off = (sect_offset) (ptr - section->buffer);
- offset.sect_off = 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. */
+ /* We need to read the type's signature in order to build the hash
+ table, but we don't need anything else just yet. */
- ptr = read_and_check_type_unit_head (&header, section,
- abbrev_section, ptr,
- &signature, &type_offset_in_tu);
+ ptr = read_and_check_comp_unit_head (&header, section,
+ abbrev_section, ptr, section_kind);
- length = get_cu_length (&header);
+ length = get_cu_length (&header);
- /* Skip dummy type units. */
- if (ptr >= info_ptr + length
- || peek_abbrev_code (abfd, ptr) == 0)
- {
- info_ptr += length;
- continue;
- }
+ /* Skip dummy type units. */
+ if (ptr >= info_ptr + length
+ || peek_abbrev_code (abfd, ptr) == 0
+ || header.unit_type != DW_UT_type)
+ {
+ info_ptr += length;
+ continue;
+ }
- if (types_htab == NULL)
- {
- if (dwo_file)
- types_htab = allocate_dwo_unit_table (objfile);
- else
- types_htab = allocate_signatured_type_table (objfile);
- }
+ if (types_htab == NULL)
+ {
+ if (dwo_file)
+ types_htab = allocate_dwo_unit_table (objfile);
+ else
+ types_htab = allocate_signatured_type_table (objfile);
+ }
+
+ if (dwo_file)
+ {
+ sig_type = NULL;
+ dwo_tu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwo_unit);
+ dwo_tu->dwo_file = dwo_file;
+ dwo_tu->signature = header.signature;
+ dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu;
+ dwo_tu->section = section;
+ dwo_tu->sect_off = sect_off;
+ dwo_tu->length = length;
+ }
+ else
+ {
+ /* N.B.: type_offset is not usable if this type uses a DWO file.
+ The real type_offset is in the DWO file. */
+ dwo_tu = NULL;
+ sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct signatured_type);
+ sig_type->signature = header.signature;
+ 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.sect_off = sect_off;
+ sig_type->per_cu.length = length;
+ }
+
+ slot = htab_find_slot (types_htab,
+ dwo_file ? (void*) dwo_tu : (void *) sig_type,
+ INSERT);
+ gdb_assert (slot != NULL);
+ if (*slot != NULL)
+ {
+ sect_offset dup_sect_off;
if (dwo_file)
{
- sig_type = NULL;
- dwo_tu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwo_unit);
- dwo_tu->dwo_file = dwo_file;
- dwo_tu->signature = signature;
- dwo_tu->type_offset_in_tu = type_offset_in_tu;
- dwo_tu->section = section;
- dwo_tu->offset = offset;
- dwo_tu->length = length;
+ const struct dwo_unit *dup_tu
+ = (const struct dwo_unit *) *slot;
+
+ dup_sect_off = dup_tu->sect_off;
}
else
{
- /* N.B.: type_offset is not usable if this type uses a DWO file.
- The real type_offset is in the DWO file. */
- dwo_tu = NULL;
- sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct signatured_type);
- sig_type->signature = signature;
- sig_type->type_offset_in_tu = type_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.length = length;
+ const struct signatured_type *dup_tu
+ = (const struct signatured_type *) *slot;
+
+ dup_sect_off = dup_tu->per_cu.sect_off;
}
- slot = htab_find_slot (types_htab,
- dwo_file ? (void*) dwo_tu : (void *) sig_type,
- INSERT);
- gdb_assert (slot != NULL);
- if (*slot != NULL)
- {
- sect_offset dup_offset;
+ complaint (&symfile_complaints,
+ _("debug type entry at offset 0x%x is duplicate to"
+ " the entry at offset 0x%x, signature %s"),
+ to_underlying (sect_off), to_underlying (dup_sect_off),
+ hex_string (header.signature));
+ }
+ *slot = dwo_file ? (void *) dwo_tu : (void *) sig_type;
- if (dwo_file)
- {
- const struct dwo_unit *dup_tu = *slot;
+ if (dwarf_read_debug > 1)
+ fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature %s\n",
+ to_underlying (sect_off),
+ hex_string (header.signature));
- dup_offset = dup_tu->offset;
- }
- else
- {
- const struct signatured_type *dup_tu = *slot;
+ info_ptr += length;
+ }
+}
- dup_offset = dup_tu->per_cu.offset;
- }
+/* Create the hash table of all entries in the .debug_types
+ (or .debug_types.dwo) section(s).
+ If reading a DWO file, then DWO_FILE is a pointer to the DWO file object,
+ otherwise it is NULL.
- 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,
- hex_string (signature));
- }
- *slot = dwo_file ? (void *) dwo_tu : (void *) sig_type;
+ The result is a pointer to the hash table or NULL if there are no types.
- if (dwarf_read_debug > 1)
- fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature %s\n",
- offset.sect_off,
- hex_string (signature));
+ Note: This function processes DWO files only, not DWP files. */
- info_ptr += length;
- }
- }
+static void
+create_debug_types_hash_table (struct dwo_file *dwo_file,
+ VEC (dwarf2_section_info_def) *types,
+ htab_t &types_htab)
+{
+ int ix;
+ struct dwarf2_section_info *section;
- return types_htab;
+ if (VEC_empty (dwarf2_section_info_def, types))
+ return;
+
+ for (ix = 0;
+ VEC_iterate (dwarf2_section_info_def, types, ix, section);
+ ++ix)
+ create_debug_type_hash_table (dwo_file, section, types_htab,
+ rcuh_kind::TYPE);
}
/* Create the hash table of all entries in the .debug_types section,
static int
create_all_type_units (struct objfile *objfile)
{
- htab_t types_htab;
+ htab_t types_htab = NULL;
struct signatured_type **iter;
- types_htab = create_debug_types_hash_table (NULL, dwarf2_per_objfile->types);
+ create_debug_type_hash_table (NULL, &dwarf2_per_objfile->info, types_htab,
+ rcuh_kind::COMPILE);
+ create_debug_types_hash_table (NULL, dwarf2_per_objfile->types, types_htab);
if (types_htab == NULL)
{
dwarf2_per_objfile->signatured_types = NULL;
dwarf2_per_objfile->n_allocated_type_units = 1;
dwarf2_per_objfile->n_allocated_type_units *= 2;
dwarf2_per_objfile->all_type_units
- = xrealloc (dwarf2_per_objfile->all_type_units,
- dwarf2_per_objfile->n_allocated_type_units
- * sizeof (struct signatured_type *));
+ = XRESIZEVEC (struct signatured_type *,
+ dwarf2_per_objfile->all_type_units,
+ dwarf2_per_objfile->n_allocated_type_units);
++dwarf2_per_objfile->tu_stats.nr_all_type_units_reallocs;
}
dwarf2_per_objfile->n_type_units = n_type_units;
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;
find_sig_entry.signature = sig;
slot = htab_find_slot (dwarf2_per_objfile->signatured_types,
&find_sig_entry, INSERT);
- sig_entry = *slot;
+ sig_entry = (struct signatured_type *) *slot;
/* We can get here with the TU already read, *or* in the process of being
read. Don't reassign the global entry to point to this DWO if that's
if (dwo_file->tus == NULL)
return NULL;
find_dwo_entry.signature = sig;
- dwo_entry = htab_find (dwo_file->tus, &find_dwo_entry);
+ dwo_entry = (struct dwo_unit *) htab_find (dwo_file->tus, &find_dwo_entry);
if (dwo_entry == NULL)
return NULL;
find_sig_entry.signature = sig;
slot = htab_find_slot (dwarf2_per_objfile->signatured_types,
&find_sig_entry, INSERT);
- sig_entry = *slot;
+ sig_entry = (struct signatured_type *) *slot;
/* Have we already tried to read this TU?
Note: sig_entry can be NULL if the skeleton TU was removed (thus it
if (dwarf2_per_objfile->signatured_types == NULL)
return NULL;
find_entry.signature = sig;
- entry = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
+ entry = ((struct signatured_type *)
+ htab_find (dwarf2_per_objfile->signatured_types, &find_entry));
return entry;
}
}
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);
if (this_cu->is_debug_types)
{
- ULONGEST header_signature;
- cu_offset type_offset_in_tu;
struct signatured_type *sig_type = (struct signatured_type *) this_cu;
- info_ptr = read_and_check_type_unit_head (&cu->header, section,
+ info_ptr = read_and_check_comp_unit_head (&cu->header, section,
dwo_abbrev_section,
- info_ptr,
- &header_signature,
- &type_offset_in_tu);
+ info_ptr, rcuh_kind::TYPE);
/* This is not an assert because it can be caused by bad debug info. */
- if (sig_type->signature != header_signature)
+ if (sig_type->signature != cu->header.signature)
{
error (_("Dwarf Error: signature mismatch %s vs %s while reading"
" TU at offset 0x%x [in module %s]"),
hex_string (sig_type->signature),
- hex_string (header_signature),
- dwo_unit->offset.sect_off,
+ hex_string (cu->header.signature),
+ 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 = 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, 0);
- gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+ info_ptr, rcuh_kind::COMPILE);
+ 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
{
if (this_cu->is_debug_types)
{
- ULONGEST signature;
- cu_offset type_offset_in_tu;
-
- info_ptr = read_and_check_type_unit_head (&cu->header, section,
+ info_ptr = read_and_check_comp_unit_head (&cu->header, section,
abbrev_section, info_ptr,
- &signature,
- &type_offset_in_tu);
+ rcuh_kind::TYPE);
/* Since per_cu is the first member of struct signatured_type,
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 == signature);
- gdb_assert (sig_type->type_offset_in_tu.cu_off
- == type_offset_in_tu.cu_off);
- gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
+ gdb_assert (sig_type->signature == cu->header.signature);
+ 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;
}
else
{
info_ptr = read_and_check_comp_unit_head (&cu->header, section,
abbrev_section,
- info_ptr, 0);
+ 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);
+ (this_cu->is_debug_types
+ ? rcuh_kind::TYPE
+ : rcuh_kind::COMPILE));
this_cu->length = get_cu_length (&cu.header);
static hashval_t
hash_type_unit_group (const void *item)
{
- const struct type_unit_group *tu_group = item;
+ const struct type_unit_group *tu_group
+ = (const struct type_unit_group *) item;
return hash_stmt_list_entry (&tu_group->hash);
}
static int
eq_type_unit_group (const void *item_lhs, const void *item_rhs)
{
- const struct type_unit_group *lhs = item_lhs;
- const struct type_unit_group *rhs = item_rhs;
+ const struct type_unit_group *lhs = (const struct type_unit_group *) item_lhs;
+ const struct type_unit_group *rhs = (const struct type_unit_group *) item_rhs;
return eq_stmt_list_entry (&lhs->hash, &rhs->hash);
}
}
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)
{
- tu_group = *slot;
+ tu_group = (struct type_unit_group *) *slot;
gdb_assert (tu_group != 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;
CORE_ADDR baseaddr;
CORE_ADDR best_lowpc = 0, best_highpc = 0;
struct partial_symtab *pst;
- int has_pc_info;
+ enum pc_bounds_kind cu_bounds_kind;
const char *filename;
- struct process_psymtab_comp_unit_data *info = data;
+ struct process_psymtab_comp_unit_data *info
+ = (struct process_psymtab_comp_unit_data *) data;
if (comp_unit_die->tag == DW_TAG_partial_unit && !info->want_partial_unit)
return;
/* Possibly set the default values of LOWPC and HIGHPC from
`DW_AT_ranges'. */
- has_pc_info = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc,
- &best_highpc, cu, pst);
- if (has_pc_info == 1 && best_lowpc < best_highpc)
+ cu_bounds_kind = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc,
+ &best_highpc, cu, pst);
+ if (cu_bounds_kind == PC_BOUNDS_HIGH_LOW && best_lowpc < best_highpc)
/* Store the contiguous range if it is not empty; it can be empty for
CUs with no code. */
addrmap_set_empty (objfile->psymtabs_addrmap,
first_die = load_partial_dies (reader, info_ptr, 1);
scan_partial_symbols (first_die, &lowpc, &highpc,
- ! has_pc_info, cu);
+ cu_bounds_kind <= PC_BOUNDS_INVALID, cu);
/* If we didn't find a lowpc, set it to highpc to avoid
complaints from `maint check'. */
/* If the compilation unit didn't have an explicit address range,
then use the information extracted from its child dies. */
- if (! has_pc_info)
+ if (cu_bounds_kind <= PC_BOUNDS_INVALID)
{
best_lowpc = lowpc;
best_highpc = highpc;
"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);
static int
sort_tu_by_abbrev_offset (const void *ap, const void *bp)
{
- const struct tu_abbrev_offset * const *a = ap;
- const struct tu_abbrev_offset * const *b = bp;
- unsigned int aoff = (*a)->abbrev_offset.sect_off;
- unsigned int boff = (*b)->abbrev_offset.sect_off;
+ const struct tu_abbrev_offset * const *a
+ = (const struct tu_abbrev_offset * const*) ap;
+ const struct tu_abbrev_offset * const *b
+ = (const struct tu_abbrev_offset * const*) bp;
+ sect_offset aoff = (*a)->abbrev_offset;
+ sect_offset boff = (*b)->abbrev_offset;
return (aoff > boff) - (aoff < boff);
}
static void
build_type_psymtabs_1 (void)
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
struct cleanup *cleanups;
struct abbrev_table *abbrev_table;
sect_offset abbrev_offset;
struct tu_abbrev_offset *sorted_by_abbrev;
- struct type_unit_group **iter;
int i;
/* It's up to the caller to not call us multiple times. */
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)
{
process_skeletonless_type_unit (void **slot, void *info)
{
struct dwo_unit *dwo_unit = (struct dwo_unit *) *slot;
- struct objfile *objfile = info;
+ struct objfile *objfile = (struct objfile *) info;
struct signatured_type find_entry, *entry;
/* If this TU doesn't exist in the global table, add it and read it in. */
static void
psymtabs_addrmap_cleanup (void *o)
{
- struct objfile *objfile = o;
+ struct objfile *objfile = (struct objfile *) o;
objfile->psymtabs_addrmap = 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;
if (*n_comp_units == *n_allocated)
{
*n_allocated *= 2;
- *all_comp_units = xrealloc (*all_comp_units,
- *n_allocated
- * sizeof (struct dwarf2_per_cu_data *));
+ *all_comp_units = XRESIZEVEC (struct dwarf2_per_cu_data *,
+ *all_comp_units, *n_allocated);
}
(*all_comp_units)[*n_comp_units] = this_cu;
++*n_comp_units;
{
add_partial_symbol (pdi, cu);
}
+ if (cu->language == language_rust && pdi->has_children)
+ scan_partial_symbols (pdi->die_child, lowpc, highpc,
+ set_addrmap, cu);
break;
case DW_TAG_enumeration_type:
if (!pdi->is_declaration)
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);
/* Functions used to compute the fully scoped name of a partial DIE.
Normally, this is simple. For C++, the parent DIE's fully scoped
- name is concatenated with "::" and the partial DIE's name. For
- Java, the same thing occurs except that "." is used instead of "::".
+ name is concatenated with "::" and the partial DIE's name.
Enumerators are an exception; they use the scope of their parent
enumeration type, i.e. the name of the enumeration type is not
prepended to the enumerator.
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;
}
struct dwarf2_cu *ref_cu = cu;
/* DW_FORM_ref_addr is using section offset. */
- attr.name = 0;
+ 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));
of the global scope. But in Ada, we want to be able to access
nested procedures globally. So all Ada subprograms are stored
in the global scope. */
- /* prim_record_minimal_symbol (actual_name, addr, mst_text,
- objfile); */
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
VAR_DOMAIN, LOC_BLOCK,
}
else
{
- /* prim_record_minimal_symbol (actual_name, addr, mst_file_text,
- objfile); */
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
VAR_DOMAIN, LOC_BLOCK,
&objfile->static_psymbols,
addr, cu->language, objfile);
}
+
+ if (pdi->main_subprogram && actual_name != NULL)
+ set_objfile_main_name (objfile, actual_name, cu->language);
break;
case DW_TAG_constant:
{
return;
}
- /* prim_record_minimal_symbol (actual_name, addr + baseaddr,
- mst_file_data, objfile); */
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
VAR_DOMAIN, LOC_STATIC,
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
STRUCT_DOMAIN, LOC_TYPEDEF,
- (cu->language == language_cplus
- || cu->language == language_java)
+ cu->language == language_cplus
? &objfile->global_psymbols
: &objfile->static_psymbols,
0, cu->language, objfile);
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
VAR_DOMAIN, LOC_CONST,
- (cu->language == language_cplus
- || cu->language == language_java)
+ cu->language == language_cplus
? &objfile->global_psymbols
: &objfile->static_psymbols,
0, cu->language, objfile);
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;
struct dwarf2_cu *cu = reader->cu;
const gdb_byte *buffer = reader->buffer;
const gdb_byte *buffer_end = reader->buffer_end;
- const gdb_byte *start_info_ptr = info_ptr;
unsigned int form, i;
for (i = 0; i < abbrev->num_attrs; i++)
_("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,
info_ptr += 1;
break;
case DW_FORM_flag_present:
+ case DW_FORM_implicit_const:
break;
case DW_FORM_data2:
case DW_FORM_ref2:
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;
}
/* Restore our global data. */
- dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+ dwarf2_per_objfile
+ = (struct dwarf2_per_objfile *) objfile_data (objfile,
+ dwarf2_objfile_data_key);
/* If this psymtab is constructed from a debug-only objfile, the
has_section_at_zero flag will not necessarily be correct. We
if (objfile->separate_debug_objfile_backlink)
{
struct dwarf2_per_objfile *dpo_backlink
- = objfile_data (objfile->separate_debug_objfile_backlink,
- dwarf2_objfile_data_key);
+ = ((struct dwarf2_per_objfile *)
+ objfile_data (objfile->separate_debug_objfile_backlink,
+ dwarf2_objfile_data_key));
dwarf2_per_objfile->has_section_at_zero
= dpo_backlink->has_section_at_zero;
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;
}
psymtab_to_symtab_1 (pst->dependencies[i]);
}
- per_cu = pst->read_symtab_private;
+ per_cu = (struct dwarf2_per_cu_data *) pst->read_symtab_private;
if (per_cu == NULL)
{
static hashval_t
die_hash (const void *item)
{
- const struct die_info *die = item;
+ 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
static int
die_eq (const void *item_lhs, const void *item_rhs)
{
- const struct die_info *die_lhs = item_lhs;
- const struct die_info *die_rhs = item_rhs;
+ 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.
void *data)
{
struct dwarf2_cu *cu = reader->cu;
- enum language *language_ptr = data;
+ enum language *language_ptr = (enum language *) data;
gdb_assert (cu->die_hash == NULL);
cu->die_hash =
{
struct objfile *objfile = cu->objfile;
const char *saved_package_name
- = obstack_copy0 (&objfile->per_bfd->storage_obstack,
- package_name,
- strlen (package_name));
- struct type *type = init_type (TYPE_CODE_MODULE, 0, 0,
- saved_package_name, objfile);
+ = (const char *) obstack_copy0 (&objfile->per_bfd->storage_obstack,
+ package_name,
+ strlen (package_name));
+ struct type *type = init_type (objfile, TYPE_CODE_MODULE, 0,
+ saved_package_name);
struct symbol *sym;
TYPE_TAG_NAME (type) = TYPE_NAME (type);
attr = dwarf2_attr (die, DW_AT_import, cu);
if (attr != NULL)
{
- struct dwarf2_per_cu_data *per_cu;
- struct symtab *imported_symtab;
- 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))
static void
reset_die_in_process (void *arg)
{
- struct die_info *die = arg;
+ struct die_info *die = (struct die_info *) arg;
die->in_process = 0;
}
case DW_TAG_catch_block:
read_lexical_block_scope (die, cu);
break;
+ case DW_TAG_call_site:
case DW_TAG_GNU_call_site:
read_call_site_scope (die, cu);
break;
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;
}
}
-/* Retrieve the last character from a mem_file. */
-
-static void
-do_ui_file_peek_last (void *object, const char *buffer, long length)
-{
- char *last_char_p = (char *) object;
-
- if (length > 0)
- *last_char_p = buffer[length - 1];
-}
-
/* Compute the fully qualified name of DIE in CU. If PHYSNAME is nonzero,
compute the physname for the object, which include a method's:
- - formal parameters (C++/Java),
+ - formal parameters (C++),
- receiver type (Go),
- - return type (Java).
The term "physname" is a bit confusing.
For C++, for example, it is the demangled name.
if (name == NULL)
name = dwarf2_name (die, cu);
- /* For Fortran GDB prefers DW_AT_*linkage_name if present but otherwise
- compute it by typename_concat inside GDB. */
+ /* For Fortran GDB prefers DW_AT_*linkage_name for the physname if present
+ but otherwise compute it by typename_concat inside GDB.
+ FIXME: Actually this is not really true, or at least not always true.
+ It's all very confusing. SYMBOL_SET_NAMES doesn't try to demangle
+ Fortran names because there is no mangling standard. So new_symbol_full
+ will set the demangled name to the result of dwarf2_full_name, and it is
+ the demangled name that GDB uses if it exists. */
if (cu->language == language_ada
|| (cu->language == language_fortran && physname))
{
to be able to reference. Ideally, we want the user to be able
to reference this entity using either natural or linkage name,
but we haven't started looking at this enhancement yet. */
- const char *name;
+ const char *linkage_name;
- name = dwarf2_string_attr (die, DW_AT_linkage_name, cu);
- if (name == NULL)
- name = dwarf2_string_attr (die, DW_AT_MIPS_linkage_name, cu);
- if (name != NULL)
- return name;
+ linkage_name = dwarf2_string_attr (die, DW_AT_linkage_name, cu);
+ if (linkage_name == NULL)
+ linkage_name = dwarf2_string_attr (die, DW_AT_MIPS_linkage_name, cu);
+ if (linkage_name != NULL)
+ return linkage_name;
}
/* These are the only languages we know how to qualify names in. */
if (name != NULL
- && (cu->language == language_cplus || cu->language == language_java
- || cu->language == language_fortran || cu->language == language_d))
+ && (cu->language == language_cplus
+ || cu->language == language_fortran || cu->language == language_d
+ || cu->language == language_rust))
{
if (die_needs_namespace (die, cu))
{
long length;
const char *prefix;
- struct ui_file *buf;
- char *intermediate_name;
const char *canonical_name = NULL;
+ string_file buf;
+
prefix = determine_prefix (die, cu);
- buf = mem_fileopen ();
if (*prefix != '\0')
{
char *prefixed_name = typename_concat (NULL, prefix, name,
physname, cu);
- fputs_unfiltered (prefixed_name, buf);
+ buf.puts (prefixed_name);
xfree (prefixed_name);
}
else
- fputs_unfiltered (name, buf);
+ buf.puts (name);
/* Template parameters may be specified in the DIE's DW_AT_name, or
as children with DW_TAG_template_type_param or
if (first)
{
- fputs_unfiltered ("<", buf);
+ buf.puts ("<");
first = 0;
}
else
- fputs_unfiltered (", ", buf);
+ buf.puts (", ");
attr = dwarf2_attr (child, DW_AT_type, cu);
if (attr == NULL)
{
complaint (&symfile_complaints,
_("template parameter missing DW_AT_type"));
- fputs_unfiltered ("UNKNOWN_TYPE", buf);
+ buf.puts ("UNKNOWN_TYPE");
continue;
}
type = die_type (child, cu);
if (child->tag == DW_TAG_template_type_param)
{
- c_print_type (type, "", buf, -1, 0, &type_print_raw_options);
+ c_print_type (type, "", &buf, -1, 0, &type_print_raw_options);
continue;
}
complaint (&symfile_complaints,
_("template parameter missing "
"DW_AT_const_value"));
- fputs_unfiltered ("UNKNOWN_VALUE", buf);
+ buf.puts ("UNKNOWN_VALUE");
continue;
}
if (TYPE_NOSIGN (type))
/* GDB prints characters as NUMBER 'CHAR'. If that's
changed, this can use value_print instead. */
- c_printchar (value, type, buf);
+ c_printchar (value, type, &buf);
else
{
struct value_print_options opts;
the radix. */
get_formatted_print_options (&opts, 'd');
opts.raw = 1;
- value_print (v, buf, &opts);
+ value_print (v, &buf, &opts);
release_value (v);
value_free (v);
}
{
/* Close the argument list, with a space if necessary
(nested templates). */
- char last_char = '\0';
- ui_file_put (buf, do_ui_file_peek_last, &last_char);
- if (last_char == '>')
- fputs_unfiltered (" >", buf);
+ if (!buf.empty () && buf.string ().back () == '>')
+ buf.puts (" >");
else
- fputs_unfiltered (">", buf);
+ buf.puts (">");
}
}
- /* For Java and C++ methods, append formal parameter type
+ /* For C++ methods, append formal parameter type
information, if PHYSNAME. */
if (physname && die->tag == DW_TAG_subprogram
- && (cu->language == language_cplus
- || cu->language == language_java))
+ && cu->language == language_cplus)
{
struct type *type = read_type_die (die, cu);
- c_type_print_args (type, buf, 1, cu->language,
+ c_type_print_args (type, &buf, 1, cu->language,
&type_print_raw_options);
- if (cu->language == language_java)
- {
- /* For java, we must append the return type to method
- names. */
- if (die->tag == DW_TAG_subprogram)
- java_print_type (TYPE_TARGET_TYPE (type), "", buf,
- 0, 0, &type_print_raw_options);
- }
- else if (cu->language == language_cplus)
+ if (cu->language == language_cplus)
{
/* Assume that an artificial first parameter is
"this", but do not crash if it is not. RealView
&& TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_PTR
&& TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type,
0))))
- fputs_unfiltered (" const", buf);
+ buf.puts (" const");
}
}
- intermediate_name = ui_file_xstrdup (buf, &length);
- ui_file_delete (buf);
+ const std::string &intermediate_name = buf.string ();
if (cu->language == language_cplus)
canonical_name
- = dwarf2_canonicalize_name (intermediate_name, cu,
+ = dwarf2_canonicalize_name (intermediate_name.c_str (), cu,
&objfile->per_bfd->storage_obstack);
/* If we only computed INTERMEDIATE_NAME, or if
INTERMEDIATE_NAME is already canonical, then we need to
copy it to the appropriate obstack. */
- if (canonical_name == NULL || canonical_name == intermediate_name)
- name = obstack_copy0 (&objfile->per_bfd->storage_obstack,
- intermediate_name,
- strlen (intermediate_name));
+ if (canonical_name == NULL || canonical_name == intermediate_name.c_str ())
+ name = ((const char *)
+ obstack_copy0 (&objfile->per_bfd->storage_obstack,
+ intermediate_name.c_str (),
+ intermediate_name.length ()));
else
name = canonical_name;
-
- xfree (intermediate_name);
}
}
not have a name. NAME may either be from a previous call to
dwarf2_name or NULL.
- The output string will be canonicalized (if C++/Java). */
+ The output string will be canonicalized (if C++). */
static const char *
dwarf2_full_name (const char *name, struct die_info *die, struct dwarf2_cu *cu)
allocated on the objfile_objstack or NULL if the DIE does not have a
name.
- The output string will be canonicalized (if C++/Java). */
+ The output string will be canonicalized (if C++). */
static const char *
dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- struct attribute *attr;
const char *retval, *mangled = NULL, *canon = NULL;
struct cleanup *back_to;
int need_copy = 1;
if (mangled == NULL)
mangled = dwarf2_string_attr (die, DW_AT_MIPS_linkage_name, cu);
+ /* rustc emits invalid values for DW_AT_linkage_name. Ignore these.
+ See https://github.com/rust-lang/rust/issues/32925. */
+ if (cu->language == language_rust && mangled != NULL
+ && strchr (mangled, '{') != NULL)
+ mangled = NULL;
+
/* DW_AT_linkage_name is missing in some cases - depend on what GDB
has computed. */
if (mangled != NULL)
else
{
demangled = gdb_demangle (mangled,
- (DMGL_PARAMS | DMGL_ANSI
- | (cu->language == language_java
- ? DMGL_JAVA | DMGL_RET_POSTFIX
- : DMGL_RET_DROP)));
+ (DMGL_PARAMS | DMGL_ANSI | DMGL_RET_DROP));
}
if (demangled)
{
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
retval = canon;
if (need_copy)
- retval = obstack_copy0 (&objfile->per_bfd->storage_obstack,
- retval, strlen (retval));
+ retval = ((const char *)
+ obstack_copy0 (&objfile->per_bfd->storage_obstack,
+ retval, strlen (retval)));
do_cleanups (back_to);
return retval;
{
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 = 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. */
- 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)
if (die->tag == DW_TAG_partial_unit && slot != NULL)
{
gdb_assert (*slot != NULL);
- cu->line_header = *slot;
+ cu->line_header = (struct line_header *) *slot;
return;
}
}
/* 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;
- bfd *abfd = objfile->obfd;
CORE_ADDR baseaddr;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
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)
refers to information in the line number info statement program
header, so we can only read it if we've read the header
successfully. */
- attr = dwarf2_attr (die, DW_AT_GNU_macros, cu);
+ attr = dwarf2_attr (die, DW_AT_macros, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (die, DW_AT_GNU_macros, cu);
if (attr && cu->line_header)
{
if (dwarf2_attr (die, DW_AT_macro_info, cu))
complaint (&symfile_complaints,
- _("CU refers to both DW_AT_GNU_macros and DW_AT_macro_info"));
+ _("CU refers to both DW_AT_macros and DW_AT_macro_info"));
dwarf_decode_macros (cu, DW_UNSND (attr), 1);
}
dwarf_decode_macros (cu, macro_offset, 0);
}
}
-
- do_cleanups (back_to);
}
/* TU version of handle_DW_AT_stmt_list for read_type_unit_scope.
static void
setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
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)
{
struct compunit_symtab *cust = dwarf2_start_symtab (cu, "", NULL, 0);
- tu_group->num_symtabs = lh->num_file_names;
- tu_group->symtabs = XNEWVEC (struct symtab *, lh->num_file_names);
+ /* Note: We don't assign tu_group->compunit_symtab yet because we're
+ still initializing it, and our caller (a few levels up)
+ process_full_type_unit still needs to know if this is the first
+ time. */
+
+ tu_group->num_symtabs = 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
static hashval_t
hash_dwo_file (const void *item)
{
- const struct dwo_file *dwo_file = item;
+ const struct dwo_file *dwo_file = (const struct dwo_file *) item;
hashval_t hash;
hash = htab_hash_string (dwo_file->dwo_name);
static int
eq_dwo_file (const void *item_lhs, const void *item_rhs)
{
- const struct dwo_file *lhs = item_lhs;
- const struct dwo_file *rhs = item_rhs;
+ const struct dwo_file *lhs = (const struct dwo_file *) item_lhs;
+ const struct dwo_file *rhs = (const struct dwo_file *) item_rhs;
if (strcmp (lhs->dwo_name, rhs->dwo_name) != 0)
return 0;
static hashval_t
hash_dwo_unit (const void *item)
{
- const struct dwo_unit *dwo_unit = item;
+ const struct dwo_unit *dwo_unit = (const struct dwo_unit *) item;
/* This drops the top 32 bits of the id, but is ok for a hash. */
return dwo_unit->signature;
static int
eq_dwo_unit (const void *item_lhs, const void *item_rhs)
{
- const struct dwo_unit *lhs = item_lhs;
- const struct dwo_unit *rhs = item_rhs;
+ const struct dwo_unit *lhs = (const struct dwo_unit *) item_lhs;
+ const struct dwo_unit *rhs = (const struct dwo_unit *) item_rhs;
/* The signature is assumed to be unique within the DWO file.
So while object file CU dwo_id's always have the value zero,
void *datap)
{
struct dwarf2_cu *cu = reader->cu;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
- 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 = datap;
+ struct create_dwo_cu_data *data = (struct create_dwo_cu_data *) datap;
struct dwo_file *dwo_file = data->dwo_file;
struct dwo_unit *dwo_unit = &data->dwo_unit;
struct attribute *attr;
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.
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwarf2_section_info *section = &dwo_file->sections.info;
- bfd *abfd;
- htab_t cu_htab;
const gdb_byte *info_ptr, *end_ptr;
struct create_dwo_cu_data create_dwo_cu_data;
struct dwo_unit *dwo_unit;
if (info_ptr == NULL)
return NULL;
- /* We can't set abfd until now because the section may be empty or
- not present, in which case section->asection will be NULL. */
- abfd = get_section_bfd_owner (section);
-
if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
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 virtual_v1_dwo_sections sections;
void **dwo_file_slot;
char *virtual_dwo_name;
- struct dwarf2_section_info *cutu;
struct cleanup *cleanups;
int i;
virtual_dwo_name);
}
dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
- dwo_file->dwo_name = obstack_copy0 (&objfile->objfile_obstack,
- virtual_dwo_name,
- strlen (virtual_dwo_name));
+ dwo_file->dwo_name
+ = (const char *) obstack_copy0 (&objfile->objfile_obstack,
+ virtual_dwo_name,
+ strlen (virtual_dwo_name));
dwo_file->comp_dir = comp_dir;
dwo_file->sections.abbrev = sections.abbrev;
dwo_file->sections.line = sections.line;
fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
virtual_dwo_name);
}
- dwo_file = *dwo_file_slot;
+ dwo_file = (struct dwo_file *) *dwo_file_slot;
}
do_cleanups (cleanups);
struct virtual_v2_dwo_sections sections;
void **dwo_file_slot;
char *virtual_dwo_name;
- struct dwarf2_section_info *cutu;
struct cleanup *cleanups;
int i;
virtual_dwo_name);
}
dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
- dwo_file->dwo_name = obstack_copy0 (&objfile->objfile_obstack,
- virtual_dwo_name,
- strlen (virtual_dwo_name));
+ dwo_file->dwo_name
+ = (const char *) obstack_copy0 (&objfile->objfile_obstack,
+ virtual_dwo_name,
+ strlen (virtual_dwo_name));
dwo_file->comp_dir = comp_dir;
dwo_file->sections.abbrev =
create_dwp_v2_section (&dwp_file->sections.abbrev,
fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
virtual_dwo_name);
}
- dwo_file = *dwo_file_slot;
+ dwo_file = (struct dwo_file *) *dwo_file_slot;
}
do_cleanups (cleanups);
uint32_t hash2 = ((signature >> 32) & mask) | 1;
unsigned int i;
void **slot;
- struct dwo_unit find_dwo_cu, *dwo_cu;
+ struct dwo_unit find_dwo_cu;
memset (&find_dwo_cu, 0, sizeof (find_dwo_cu));
find_dwo_cu.signature = signature;
&find_dwo_cu, INSERT);
if (*slot != NULL)
- return *slot;
+ return (struct dwo_unit *) *slot;
/* Use a for loop so that we don't loop forever on bad debug info. */
for (i = 0; i < dwp_htab->nr_slots; ++i)
comp_dir, signature,
is_debug_types);
}
- return *slot;
+ return (struct dwo_unit *) *slot;
}
if (signature_in_table == 0)
return NULL;
If unable to find/open the file, return NULL.
NOTE: This function is derived from symfile_bfd_open. */
-static bfd *
+static gdb_bfd_ref_ptr
try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd)
{
- bfd *sym_bfd;
int desc, flags;
char *absolute_name;
/* Blech. OPF_TRY_CWD_FIRST also disables searching the path list if
{
if (*debug_file_directory != '\0')
search_path = concat (".", dirname_separator_string,
- debug_file_directory, NULL);
+ debug_file_directory, (char *) NULL);
else
search_path = xstrdup (".");
}
if (desc < 0)
return NULL;
- sym_bfd = gdb_bfd_open (absolute_name, gnutarget, desc);
+ gdb_bfd_ref_ptr sym_bfd (gdb_bfd_open (absolute_name, gnutarget, desc));
xfree (absolute_name);
if (sym_bfd == NULL)
return NULL;
- bfd_set_cacheable (sym_bfd, 1);
+ bfd_set_cacheable (sym_bfd.get (), 1);
- if (!bfd_check_format (sym_bfd, bfd_object))
- {
- gdb_bfd_unref (sym_bfd); /* This also closes desc. */
- return NULL;
- }
+ if (!bfd_check_format (sym_bfd.get (), bfd_object))
+ return NULL;
/* Success. Record the bfd as having been included by the objfile's bfd.
This is important because things like demangled_names_hash lives in the
objfile's per_bfd space and may have references to things like symbol
names that live in the DWO/DWP file's per_bfd space. PR 16426. */
- gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, sym_bfd);
+ gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, sym_bfd.get ());
return sym_bfd;
}
Upon success, the canonicalized path of the file is stored in the bfd,
same as symfile_bfd_open. */
-static bfd *
+static gdb_bfd_ref_ptr
open_dwo_file (const char *file_name, const char *comp_dir)
{
- bfd *abfd;
-
if (IS_ABSOLUTE_PATH (file_name))
return try_open_dwop_file (file_name, 0 /*is_dwp*/, 0 /*search_cwd*/);
if (comp_dir != NULL)
{
- char *path_to_try = concat (comp_dir, SLASH_STRING, file_name, NULL);
+ char *path_to_try = concat (comp_dir, SLASH_STRING,
+ file_name, (char *) NULL);
/* NOTE: If comp_dir is a relative path, this will also try the
search path, which seems useful. */
- abfd = try_open_dwop_file (path_to_try, 0 /*is_dwp*/, 1 /*search_cwd*/);
+ gdb_bfd_ref_ptr abfd (try_open_dwop_file (path_to_try, 0 /*is_dwp*/,
+ 1 /*search_cwd*/));
xfree (path_to_try);
if (abfd != NULL)
return abfd;
static void
dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp, void *dwo_sections_ptr)
{
- struct dwo_sections *dwo_sections = dwo_sections_ptr;
+ struct dwo_sections *dwo_sections = (struct dwo_sections *) dwo_sections_ptr;
const struct dwop_section_names *names = &dwop_section_names;
if (section_is_p (sectp->name, &names->abbrev_dwo))
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwo_file *dwo_file;
- bfd *dbfd;
struct cleanup *cleanups;
- dbfd = open_dwo_file (dwo_name, comp_dir);
+ gdb_bfd_ref_ptr dbfd (open_dwo_file (dwo_name, comp_dir));
if (dbfd == NULL)
{
if (dwarf_read_debug)
dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
dwo_file->dwo_name = dwo_name;
dwo_file->comp_dir = comp_dir;
- dwo_file->dbfd = dbfd;
+ dwo_file->dbfd = dbfd.release ();
cleanups = make_cleanup (free_dwo_file_cleanup, dwo_file);
- bfd_map_over_sections (dbfd, dwarf2_locate_dwo_sections, &dwo_file->sections);
+ bfd_map_over_sections (dwo_file->dbfd, dwarf2_locate_dwo_sections,
+ &dwo_file->sections);
dwo_file->cu = create_dwo_cu (dwo_file);
- dwo_file->tus = create_debug_types_hash_table (dwo_file,
- dwo_file->sections.types);
+ create_debug_types_hash_table (dwo_file, dwo_file->sections.types,
+ dwo_file->tus);
discard_cleanups (cleanups);
dwarf2_locate_common_dwp_sections (bfd *abfd, asection *sectp,
void *dwp_file_ptr)
{
- struct dwp_file *dwp_file = dwp_file_ptr;
+ struct dwp_file *dwp_file = (struct dwp_file *) dwp_file_ptr;
const struct dwop_section_names *names = &dwop_section_names;
unsigned int elf_section_nr = elf_section_data (sectp)->this_idx;
static void
dwarf2_locate_v2_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
{
- struct dwp_file *dwp_file = dwp_file_ptr;
+ struct dwp_file *dwp_file = (struct dwp_file *) dwp_file_ptr;
const struct dwop_section_names *names = &dwop_section_names;
unsigned int elf_section_nr = elf_section_data (sectp)->this_idx;
static hashval_t
hash_dwp_loaded_cutus (const void *item)
{
- const struct dwo_unit *dwo_unit = item;
+ const struct dwo_unit *dwo_unit = (const struct dwo_unit *) item;
/* This drops the top 32 bits of the signature, but is ok for a hash. */
return dwo_unit->signature;
static int
eq_dwp_loaded_cutus (const void *a, const void *b)
{
- const struct dwo_unit *dua = a;
- const struct dwo_unit *dub = b;
+ const struct dwo_unit *dua = (const struct dwo_unit *) a;
+ const struct dwo_unit *dub = (const struct dwo_unit *) b;
return dua->signature == dub->signature;
}
Upon success, the canonicalized path of the file is stored in the bfd,
same as symfile_bfd_open. */
-static bfd *
+static gdb_bfd_ref_ptr
open_dwp_file (const char *file_name)
{
- bfd *abfd;
-
- abfd = try_open_dwop_file (file_name, 1 /*is_dwp*/, 1 /*search_cwd*/);
+ gdb_bfd_ref_ptr abfd (try_open_dwop_file (file_name, 1 /*is_dwp*/,
+ 1 /*search_cwd*/));
if (abfd != NULL)
return abfd;
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwp_file *dwp_file;
- char *dwp_name;
- bfd *dbfd;
- struct cleanup *cleanups;
/* Try to find first .dwp for the binary file before any symbolic links
resolving. */
- dwp_name = xstrprintf ("%s.dwp", objfile->original_name);
- cleanups = make_cleanup (xfree, dwp_name);
- dbfd = open_dwp_file (dwp_name);
+ /* 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);
+
+ dwp_name = ldirname (objfile->original_name) + SLASH_STRING + backlink_basename;
+ }
+ else
+ dwp_name = objfile->original_name;
+
+ dwp_name += ".dwp";
+
+ 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);
- dwp_file->dbfd = dbfd;
- do_cleanups (cleanups);
+ dwp_file->name = bfd_get_filename (dbfd.get ());
+ dwp_file->dbfd = dbfd.release ();
/* +1: section 0 is unused */
- dwp_file->num_sections = bfd_count_sections (dbfd) + 1;
+ dwp_file->num_sections = bfd_count_sections (dwp_file->dbfd) + 1;
dwp_file->elf_sections =
OBSTACK_CALLOC (&objfile->objfile_obstack,
dwp_file->num_sections, asection *);
- bfd_map_over_sections (dbfd, dwarf2_locate_common_dwp_sections, dwp_file);
+ bfd_map_over_sections (dwp_file->dbfd, dwarf2_locate_common_dwp_sections,
+ dwp_file);
dwp_file->cus = create_dwp_hash_table (dwp_file, 0);
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;
if (dwp_file->version == 2)
- bfd_map_over_sections (dbfd, dwarf2_locate_v2_dwp_sections, dwp_file);
+ bfd_map_over_sections (dwp_file->dbfd, dwarf2_locate_v2_dwp_sections,
+ dwp_file);
dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table (objfile);
dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table (objfile);
*dwo_file_slot = open_and_init_dwo_file (this_unit, dwo_name, comp_dir);
}
/* NOTE: This will be NULL if unable to open the file. */
- dwo_file = *dwo_file_slot;
+ dwo_file = (struct dwo_file *) *dwo_file_slot;
if (dwo_file != NULL)
{
memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu));
find_dwo_cutu.signature = signature;
- dwo_cutu = htab_find (dwo_file->tus, &find_dwo_cutu);
+ dwo_cutu
+ = (struct dwo_unit *) htab_find (dwo_file->tus, &find_dwo_cutu);
}
else if (!is_debug_types && dwo_file->cu)
{
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);
}
static void
free_dwo_file (struct dwo_file *dwo_file, struct objfile *objfile)
{
- int ix;
- struct dwarf2_section_info *section;
/* Note: dbfd is NULL for virtual DWO files. */
gdb_bfd_unref (dwo_file->dbfd);
&& 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;
struct dwarf2_cu *child_origin_cu;
/* We are trying to process concrete instance entries:
- DW_TAG_GNU_call_site DIEs indeed have a DW_AT_abstract_origin tag, but
+ DW_TAG_call_site DIEs indeed have a DW_AT_abstract_origin tag, but
it's not relevant to our analysis here. i.e. detecting DIEs that are
present in the abstract instance but not referenced in the concrete
one. */
- if (child_die->tag == DW_TAG_GNU_call_site)
+ if (child_die->tag == DW_TAG_call_site
+ || child_die->tag == DW_TAG_GNU_call_site)
continue;
/* For each CHILD_DIE, find the corresponding child of
&& 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;
}
/* Ignore functions with missing or invalid low and high pc attributes. */
- if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
+ if (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)
+ <= PC_BOUNDS_INVALID)
{
attr = dwarf2_attr (die, DW_AT_external, cu);
if (!attr || !DW_UNSND (attr))
complaint (&symfile_complaints,
_("cannot get low and high bounds "
"for subprogram DIE at %d"),
- die->offset.sect_off);
+ to_underlying (die->sect_off));
return;
}
attr = dwarf2_attr (die, DW_AT_static_link, cu);
if (attr)
{
- newobj->static_link = obstack_alloc (&objfile->objfile_obstack,
- sizeof (*newobj->static_link));
+ newobj->static_link
+ = XOBNEW (&objfile->objfile_obstack, struct dynamic_prop);
attr_to_dynamic_prop (attr, die, cu, newobj->static_link);
}
/* For C++, set the block's scope. */
if ((cu->language == language_cplus
|| cu->language == language_fortran
- || cu->language == language_d)
+ || cu->language == language_d
+ || cu->language == language_rust)
&& cu->processing_has_namespace_info)
block_set_scope (block, determine_prefix (die, cu),
&objfile->objfile_obstack);
as multiple lexical blocks? Handling children in a sane way would
be nasty. Might be easier to properly extend generic blocks to
describe ranges. */
- if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
- return;
+ switch (dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
+ {
+ case PC_BOUNDS_NOT_PRESENT:
+ /* DW_TAG_lexical_block has no attributes, process its children as if
+ there was no wrapping by that DW_TAG_lexical_block.
+ GCC does no longer produces such DWARF since GCC r224161. */
+ for (child_die = die->child;
+ child_die != NULL && child_die->tag;
+ child_die = sibling_die (child_die))
+ process_die (child_die, cu);
+ return;
+ case PC_BOUNDS_INVALID:
+ return;
+ }
lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
highpc = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
local_using_directives = newobj->local_using_directives;
}
-/* Read in DW_TAG_GNU_call_site and insert it to CU->call_site_htab. */
+/* Read in DW_TAG_call_site and insert it to CU->call_site_htab. */
static void
read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+ attr = dwarf2_attr (die, DW_AT_call_return_pc, cu);
+ if (attr == NULL)
+ {
+ /* This was a pre-DWARF-5 GNU extension alias
+ for DW_AT_call_return_pc. */
+ attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+ }
if (!attr)
{
complaint (&symfile_complaints,
- _("missing DW_AT_low_pc for DW_TAG_GNU_call_site "
+ _("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;
if (*slot != NULL)
{
complaint (&symfile_complaints,
- _("Duplicate PC %s for DW_TAG_GNU_call_site "
+ _("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;
}
for (child_die = die->child; child_die && child_die->tag;
child_die = sibling_die (child_die))
{
- if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+ if (child_die->tag != DW_TAG_call_site_parameter
+ && child_die->tag != DW_TAG_GNU_call_site_parameter)
{
complaint (&symfile_complaints,
- _("Tag %d is not DW_TAG_GNU_call_site_parameter in "
- "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->tag, child_die->offset.sect_off,
+ _("Tag %d is not DW_TAG_call_site_parameter in "
+ "DW_TAG_call_site child DIE 0x%x [in module %s]"),
+ child_die->tag, to_underlying (child_die->sect_off),
objfile_name (objfile));
continue;
}
nparams++;
}
- call_site = obstack_alloc (&objfile->objfile_obstack,
- (sizeof (*call_site)
- + (sizeof (*call_site->parameter)
- * (nparams - 1))));
+ call_site
+ = ((struct call_site *)
+ obstack_alloc (&objfile->objfile_obstack,
+ sizeof (*call_site)
+ + (sizeof (*call_site->parameter) * (nparams - 1))));
*slot = call_site;
memset (call_site, 0, sizeof (*call_site) - sizeof (*call_site->parameter));
call_site->pc = pc;
- if (dwarf2_flag_true_p (die, DW_AT_GNU_tail_call, cu))
+ if (dwarf2_flag_true_p (die, DW_AT_call_tail_call, cu)
+ || dwarf2_flag_true_p (die, DW_AT_GNU_tail_call, cu))
{
struct die_info *func_die;
&& func_die->tag != DW_TAG_subroutine_type;
func_die = func_die->parent);
- /* DW_AT_GNU_all_call_sites is a superset
- of DW_AT_GNU_all_tail_call_sites. */
+ /* DW_AT_call_all_calls is a superset
+ of DW_AT_call_all_tail_calls. */
if (func_die
+ && !dwarf2_flag_true_p (func_die, DW_AT_call_all_calls, cu)
&& !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_call_sites, cu)
+ && !dwarf2_flag_true_p (func_die, DW_AT_call_all_tail_calls, cu)
&& !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_tail_call_sites, cu))
{
/* TYPE_TAIL_CALL_LIST is not interesting in functions where it is
}
else
complaint (&symfile_complaints,
- _("Cannot find function owning DW_TAG_GNU_call_site "
+ _("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));
}
}
- attr = dwarf2_attr (die, DW_AT_GNU_call_site_target, cu);
+ attr = dwarf2_attr (die, DW_AT_call_target, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (die, DW_AT_GNU_call_site_target, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (die, DW_AT_call_origin, cu);
if (attr == NULL)
- attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
+ {
+ /* This was a pre-DWARF-5 GNU extension alias for DW_AT_call_origin. */
+ attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
+ }
SET_FIELD_DWARF_BLOCK (call_site->target, NULL);
if (!attr || (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0))
/* Keep NULL DWARF_BLOCK. */;
target_physname = dwarf2_physname (NULL, target_die, target_cu);
if (target_physname == NULL)
complaint (&symfile_complaints,
- _("DW_AT_GNU_call_site_target target DIE has invalid "
+ _("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);
}
CORE_ADDR lowpc;
/* DW_AT_entry_pc should be preferred. */
- if (!dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu, NULL))
+ if (dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu, NULL)
+ <= PC_BOUNDS_INVALID)
complaint (&symfile_complaints,
- _("DW_AT_GNU_call_site_target target DIE has invalid "
+ _("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);
}
else
complaint (&symfile_complaints,
- _("DW_TAG_GNU_call_site DW_AT_GNU_call_site_target is neither "
+ _("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;
struct call_site_parameter *parameter;
struct attribute *loc, *origin;
- if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+ if (child_die->tag != DW_TAG_call_site_parameter
+ && child_die->tag != DW_TAG_GNU_call_site_parameter)
{
/* Already printed the complaint above. */
continue;
/* DW_AT_location specifies the register number or DW_AT_abstract_origin
specifies DW_TAG_formal_parameter. Value of the data assumed for the
- register is contained in DW_AT_GNU_call_site_value. */
+ register is contained in DW_AT_call_value. */
loc = dwarf2_attr (child_die, DW_AT_location, cu);
- origin = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
+ origin = dwarf2_attr (child_die, DW_AT_call_parameter, cu);
+ if (origin == NULL)
+ {
+ /* This was a pre-DWARF-5 GNU extension alias
+ for DW_AT_call_parameter. */
+ origin = dwarf2_attr (child_die, DW_AT_abstract_origin, 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
therefore cannot be even moved to DW_TAG_partial_unit. */
complaint (&symfile_complaints,
- _("DW_AT_abstract_origin offset is not in CU for "
- "DW_TAG_GNU_call_site child DIE 0x%x "
- "[in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ _("DW_AT_call_parameter offset is not in CU for "
+ "DW_TAG_call_site child DIE 0x%x [in module %s]"),
+ 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_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ "DW_TAG_call_site child DIE 0x%x [in module %s]"),
+ to_underlying (child_die->sect_off), objfile_name (objfile));
continue;
}
else
complaint (&symfile_complaints,
_("Only single DW_OP_reg or DW_OP_fbreg is supported "
"for DW_FORM_block* DW_AT_location is supported for "
- "DW_TAG_GNU_call_site child DIE 0x%x "
+ "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;
}
}
- attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
+ attr = dwarf2_attr (child_die, DW_AT_call_value, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
if (!attr_form_is_block (attr))
{
complaint (&symfile_complaints,
- _("No DW_FORM_block* DW_AT_GNU_call_site_value for "
- "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ _("No DW_FORM_block* DW_AT_call_value for "
+ "DW_TAG_call_site child DIE 0x%x [in module %s]"),
+ to_underlying (child_die->sect_off),
+ objfile_name (objfile));
continue;
}
parameter->value = DW_BLOCK (attr)->data;
parameter->data_value_size = 0;
call_site->parameter_count++;
- attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_data_value, cu);
+ attr = dwarf2_attr (child_die, DW_AT_call_data_value, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_data_value, cu);
if (attr)
{
if (!attr_form_is_block (attr))
complaint (&symfile_complaints,
- _("No DW_FORM_block* DW_AT_GNU_call_site_data_value for "
- "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ _("No DW_FORM_block* DW_AT_call_data_value for "
+ "DW_TAG_call_site child DIE 0x%x [in module %s]"),
+ to_underlying (child_die->sect_off),
+ objfile_name (objfile));
else
{
parameter->data_value = DW_BLOCK (attr)->data;
}
}
-/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
- Return 1 if the attributes are present and valid, otherwise, return 0.
- If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'. */
+/* Call CALLBACK from DW_AT_ranges attribute value OFFSET
+ reading .debug_rnglists.
+ Callback's type should be:
+ void (CORE_ADDR range_beginning, CORE_ADDR range_end)
+ Return true if the attributes are present and valid, otherwise,
+ return false. */
-static int
-dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
- CORE_ADDR *high_return, struct dwarf2_cu *cu,
- struct partial_symtab *ranges_pst)
+template <typename Callback>
+static bool
+dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
+ Callback &&callback)
{
struct objfile *objfile = cu->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
int found_base;
unsigned int dummy;
const gdb_byte *buffer;
- CORE_ADDR marker;
- int low_set;
CORE_ADDR low = 0;
CORE_ADDR high = 0;
CORE_ADDR baseaddr;
+ bool overflow = false;
found_base = cu->base_known;
base = cu->base_address;
- dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
- if (offset >= dwarf2_per_objfile->ranges.size)
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->rnglists);
+ if (offset >= dwarf2_per_objfile->rnglists.size)
{
complaint (&symfile_complaints,
_("Offset %d out of bounds for DW_AT_ranges attribute"),
offset);
- return 0;
+ return false;
}
- buffer = dwarf2_per_objfile->ranges.buffer + offset;
+ buffer = dwarf2_per_objfile->rnglists.buffer + offset;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- /* Read in the largest possible address. */
- marker = read_address (obfd, buffer, cu, &dummy);
- if ((marker & mask) == mask)
+ while (1)
{
- /* If we found the largest possible address, then
- read the base address. */
- base = read_address (obfd, buffer + addr_size, cu, &dummy);
- buffer += 2 * addr_size;
- offset += 2 * addr_size;
- found_base = 1;
+ /* 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;
+
+ if (buffer == buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ const auto rlet = static_cast<enum dwarf_range_list_entry>(*buffer++);
+ switch (rlet)
+ {
+ case DW_RLE_end_of_list:
+ break;
+ case DW_RLE_base_address:
+ if (buffer + cu->header.addr_size > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ base = read_address (obfd, buffer, cu, &bytes_read);
+ found_base = 1;
+ buffer += bytes_read;
+ break;
+ case DW_RLE_start_length:
+ if (buffer + cu->header.addr_size > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ range_beginning = read_address (obfd, buffer, cu, &bytes_read);
+ buffer += bytes_read;
+ range_end = (range_beginning
+ + read_unsigned_leb128 (obfd, buffer, &bytes_read));
+ buffer += bytes_read;
+ if (buffer > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ break;
+ case DW_RLE_offset_pair:
+ range_beginning = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+ buffer += bytes_read;
+ if (buffer > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ range_end = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+ buffer += bytes_read;
+ if (buffer > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ break;
+ case DW_RLE_start_end:
+ if (buffer + 2 * cu->header.addr_size > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ range_beginning = read_address (obfd, buffer, cu, &bytes_read);
+ buffer += bytes_read;
+ range_end = read_address (obfd, buffer, cu, &bytes_read);
+ buffer += bytes_read;
+ break;
+ default:
+ complaint (&symfile_complaints,
+ _("Invalid .debug_rnglists data (no base address)"));
+ return false;
+ }
+ if (rlet == DW_RLE_end_of_list || overflow)
+ break;
+ if (rlet == DW_RLE_base_address)
+ continue;
+
+ if (!found_base)
+ {
+ /* We have no valid base address for the ranges
+ data. */
+ complaint (&symfile_complaints,
+ _("Invalid .debug_rnglists data (no base address)"));
+ return false;
+ }
+
+ if (range_beginning > range_end)
+ {
+ /* Inverted range entries are invalid. */
+ complaint (&symfile_complaints,
+ _("Invalid .debug_rnglists data (inverted range)"));
+ return false;
+ }
+
+ /* Empty range entries have no effect. */
+ if (range_beginning == range_end)
+ continue;
+
+ range_beginning += base;
+ range_end += base;
+
+ /* A not-uncommon case of bad debug info.
+ Don't pollute the addrmap with bad data. */
+ if (range_beginning + baseaddr == 0
+ && !dwarf2_per_objfile->has_section_at_zero)
+ {
+ complaint (&symfile_complaints,
+ _(".debug_rnglists entry has start address of zero"
+ " [in module %s]"), objfile_name (objfile));
+ continue;
+ }
+
+ callback (range_beginning, range_end);
+ }
+
+ if (overflow)
+ {
+ complaint (&symfile_complaints,
+ _("Offset %d is not terminated "
+ "for DW_AT_ranges attribute"),
+ offset);
+ return false;
}
- low_set = 0;
+ return true;
+}
+
+/* Call CALLBACK from DW_AT_ranges attribute value OFFSET reading .debug_ranges.
+ Callback's type should be:
+ void (CORE_ADDR range_beginning, CORE_ADDR range_end)
+ Return 1 if the attributes are present and valid, otherwise, return 0. */
+
+template <typename Callback>
+static int
+dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
+ Callback &&callback)
+{
+ struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct comp_unit_head *cu_header = &cu->header;
+ bfd *obfd = objfile->obfd;
+ unsigned int addr_size = cu_header->addr_size;
+ CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
+ /* Base address selection entry. */
+ CORE_ADDR base;
+ int found_base;
+ unsigned int dummy;
+ const gdb_byte *buffer;
+ CORE_ADDR baseaddr;
+
+ if (cu_header->version >= 5)
+ return dwarf2_rnglists_process (offset, cu, callback);
+
+ found_base = cu->base_known;
+ base = cu->base_address;
+
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
+ if (offset >= dwarf2_per_objfile->ranges.size)
+ {
+ complaint (&symfile_complaints,
+ _("Offset %d out of bounds for DW_AT_ranges attribute"),
+ offset);
+ return 0;
+ }
+ buffer = dwarf2_per_objfile->ranges.buffer + offset;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
the base address. Check for a base address here. */
if ((range_beginning & mask) == mask)
{
- /* If we found the largest possible address, then
- read the base address. */
- base = read_address (obfd, buffer + addr_size, cu, &dummy);
+ /* If we found the largest possible address, then we already
+ have the base address in range_end. */
+ base = range_end;
found_base = 1;
continue;
}
continue;
}
+ callback (range_beginning, range_end);
+ }
+
+ return 1;
+}
+
+/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
+ Return 1 if the attributes are present and valid, otherwise, return 0.
+ If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'. */
+
+static int
+dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
+ CORE_ADDR *high_return, struct dwarf2_cu *cu,
+ struct partial_symtab *ranges_pst)
+{
+ struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ const CORE_ADDR baseaddr = ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ int low_set = 0;
+ CORE_ADDR low = 0;
+ CORE_ADDR high = 0;
+ int retval;
+
+ retval = dwarf2_ranges_process (offset, cu,
+ [&] (CORE_ADDR range_beginning, CORE_ADDR range_end)
+ {
if (ranges_pst != NULL)
{
CORE_ADDR lowpc;
if (range_end > high)
high = range_end;
}
- }
+ });
+ if (!retval)
+ return 0;
if (! low_set)
/* If the first entry is an end-of-list marker, the range
return 1;
}
-/* Get low and high pc attributes from a die. Return 1 if the attributes
- are present and valid, otherwise, return 0. Return -1 if the range is
- discontinuous, i.e. derived from DW_AT_ranges information. */
+/* Get low and high pc attributes from a die. See enum pc_bounds_kind
+ definition for the return value. *LOWPC and *HIGHPC are set iff
+ neither PC_BOUNDS_NOT_PRESENT nor PC_BOUNDS_INVALID are returned. */
-static int
+static enum pc_bounds_kind
dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
CORE_ADDR *highpc, struct dwarf2_cu *cu,
struct partial_symtab *pst)
struct attribute *attr_high;
CORE_ADDR low = 0;
CORE_ADDR high = 0;
- int ret = 0;
+ enum pc_bounds_kind ret;
attr_high = dwarf2_attr (die, DW_AT_high_pc, cu);
if (attr_high)
}
else
/* Found high w/o low attribute. */
- return 0;
+ return PC_BOUNDS_INVALID;
/* Found consecutive range of addresses. */
- ret = 1;
+ ret = PC_BOUNDS_HIGH_LOW;
}
else
{
/* Value of the DW_AT_ranges attribute is the offset in the
.debug_ranges section. */
if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst))
- return 0;
+ return PC_BOUNDS_INVALID;
/* Found discontinuous range of addresses. */
- ret = -1;
+ ret = PC_BOUNDS_RANGES;
}
+ else
+ return PC_BOUNDS_NOT_PRESENT;
}
/* read_partial_die has also the strict LOW < HIGH requirement. */
if (high <= low)
- return 0;
+ return PC_BOUNDS_INVALID;
/* When using the GNU linker, .gnu.linkonce. sections are used to
eliminate duplicate copies of functions and vtables and such.
If this is a discarded function, mark the pc bounds as invalid,
so that GDB will ignore it. */
if (low == 0 && !dwarf2_per_objfile->has_section_at_zero)
- return 0;
+ return PC_BOUNDS_INVALID;
*lowpc = low;
if (highpc)
CORE_ADDR low, high;
struct die_info *child = die->child;
- if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL))
+ if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL) >= PC_BOUNDS_RANGES)
{
- *lowpc = min (*lowpc, low);
- *highpc = max (*highpc, high);
+ *lowpc = std::min (*lowpc, low);
+ *highpc = std::max (*highpc, high);
}
/* If the language does not allow nested subprograms (either inside
CORE_ADDR best_high = (CORE_ADDR) 0;
CORE_ADDR current_low, current_high;
- if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu, NULL))
+ if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu, NULL)
+ >= PC_BOUNDS_RANGES)
{
best_low = current_low;
best_high = current_high;
if (current_low != ((CORE_ADDR) -1))
{
- best_low = min (best_low, current_low);
- best_high = max (best_high, current_high);
+ best_low = std::min (best_low, current_low);
+ best_high = std::max (best_high, current_high);
}
break;
default:
CORE_ADDR base = cu->base_address;
int base_known = cu->base_known;
- dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
- if (offset >= dwarf2_per_objfile->ranges.size)
- {
- complaint (&symfile_complaints,
- _("Offset %lu out of bounds for DW_AT_ranges attribute"),
- offset);
- return;
- }
- buffer = dwarf2_per_objfile->ranges.buffer + offset;
-
- for (;;)
- {
- unsigned int bytes_read;
- CORE_ADDR start, end;
-
- start = read_address (obfd, buffer, cu, &bytes_read);
- buffer += bytes_read;
- end = read_address (obfd, buffer, cu, &bytes_read);
- buffer += bytes_read;
-
- /* Did we find the end of the range list? */
- if (start == 0 && end == 0)
- break;
-
- /* Did we find a base address selection entry? */
- else if ((start & base_select_mask) == base_select_mask)
- {
- base = end;
- base_known = 1;
- }
-
- /* We found an ordinary address range. */
- else
- {
- if (!base_known)
- {
- complaint (&symfile_complaints,
- _("Invalid .debug_ranges data "
- "(no base address)"));
- return;
- }
-
- if (start > end)
- {
- /* Inverted range entries are invalid. */
- complaint (&symfile_complaints,
- _("Invalid .debug_ranges data "
- "(inverted range)"));
- return;
- }
-
- /* Empty range entries have no effect. */
- if (start == end)
- continue;
-
- start += base + baseaddr;
- end += base + baseaddr;
-
- /* A not-uncommon case of bad debug info.
- Don't pollute the addrmap with bad data. */
- if (start == 0 && !dwarf2_per_objfile->has_section_at_zero)
- {
- complaint (&symfile_complaints,
- _(".debug_ranges entry has start address of zero"
- " [in module %s]"), objfile_name (objfile));
- continue;
- }
-
- start = gdbarch_adjust_dwarf2_addr (gdbarch, start);
- end = gdbarch_adjust_dwarf2_addr (gdbarch, end);
- record_block_range (block, start, end - 1);
- }
- }
+ 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);
+ });
}
}
static void
check_producer (struct dwarf2_cu *cu)
{
- const char *cs;
int major, minor;
if (cu->producer == NULL)
- bit_offset - FIELD_BITSIZE (*fp)));
}
}
+ attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
+ if (attr != NULL)
+ SET_FIELD_BITPOS (*fp, (FIELD_BITPOS (*fp)
+ + dwarf2_get_attr_constant_value (attr, 0)));
/* Get name of field. */
fieldname = dwarf2_name (die, cu);
dwarf2_add_typedef (struct field_info *fip, struct die_info *die,
struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
struct typedef_field_list *new_field;
- struct attribute *attr;
struct typedef_field *fp;
- char *fieldname = "";
/* Allocate a new field list entry and link it in. */
new_field = XCNEW (struct typedef_field_list);
unsigned char *pointer;
ALLOCATE_CPLUS_STRUCT_TYPE (type);
- pointer = TYPE_ALLOC (type, num_bytes);
+ pointer = (unsigned char *) TYPE_ALLOC (type, num_bytes);
TYPE_FIELD_VIRTUAL_BITS (type) = pointer;
B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), fip->nbaseclasses);
TYPE_N_BASECLASSES (type) = fip->nbaseclasses;
fnp = &new_fnfield->fnfield;
/* Delay processing of the physname until later. */
- if (cu->language == language_cplus || cu->language == language_java)
+ if (cu->language == language_cplus)
{
add_to_method_list (type, i, flp->length - 1, fieldname,
die, cu);
&& DW_BLOCK (attr)->data[0] == DW_OP_deref_size
&& DW_BLOCK (attr)->data[1] == cu->header.addr_size))
{
- struct dwarf_block blk;
- int offset;
-
- offset = (DW_BLOCK (attr)->data[0] == DW_OP_deref
- ? 1 : 2);
- blk.size = DW_BLOCK (attr)->size - offset;
- blk.data = DW_BLOCK (attr)->data + offset;
fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu);
if ((fnp->voffset % cu->header.addr_size) != 0)
dwarf2_complex_location_expr_complaint ();
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;
}
static const char vptr[] = "_vptr";
static const char vtable[] = "vtable";
- /* Look for the C++ and Java forms of the vtable. */
- if ((cu->language == language_java
- && startswith (name, vtable))
- || (startswith (name, vptr)
- && is_cplus_marker (name[sizeof (vptr) - 1])))
+ /* Look for the C++ form of the vtable. */
+ if (startswith (name, vptr) && is_cplus_marker (name[sizeof (vptr) - 1]))
return 1;
return 0;
if (name != NULL)
{
if (cu->language == language_cplus
- || cu->language == language_java
- || cu->language == language_d)
+ || cu->language == language_d
+ || cu->language == language_rust)
{
const char *full_name = dwarf2_full_name (name, die, cu);
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
- TYPE_LENGTH (type) = DW_UNSND (attr);
+ if (attr_form_is_constant (attr))
+ TYPE_LENGTH (type) = DW_UNSND (attr);
+ else
+ {
+ /* For the moment, dynamic type sizes are not supported
+ by GDB's struct type. The actual size is determined
+ on-demand when resolving the type of a given object,
+ so set the type's length to zero for now. Otherwise,
+ we record an expression as the length, and that expression
+ could lead to a very large value, which could eventually
+ lead to us trying to allocate that much memory when creating
+ a value of that type. */
+ TYPE_LENGTH (type) = 0;
+ }
}
else
{
}
else if (child_die->tag == DW_TAG_subprogram)
{
- /* C++ member function. */
- dwarf2_add_member_fn (&fi, child_die, type, cu);
+ /* Rust doesn't have member functions in the C++ sense.
+ However, it does emit ordinary functions as children
+ of a struct DIE. */
+ if (cu->language == language_rust)
+ read_func_scope (child_die, cu);
+ else
+ {
+ /* C++ member function. */
+ dwarf2_add_member_fn (&fi, child_die, type, cu);
+ }
}
else if (child_die->tag == DW_TAG_inheritance)
{
ALLOCATE_CPLUS_STRUCT_TYPE (type);
TYPE_TYPEDEF_FIELD_ARRAY (type)
- = TYPE_ALLOC (type, sizeof (TYPE_TYPEDEF_FIELD (type, 0)) * i);
+ = ((struct typedef_field *)
+ TYPE_ALLOC (type, sizeof (TYPE_TYPEDEF_FIELD (type, 0)) * i));
TYPE_TYPEDEF_FIELD_COUNT (type) = i;
/* Reverse the list order to keep the debug info elements order. */
}
do_cleanups (back_to);
-
- if (HAVE_CPLUS_STRUCT (type))
- TYPE_CPLUS_REALLY_JAVA (type) = cu->language == language_java;
}
quirk_gcc_member_function_pointer (type, objfile);
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;
}
else
baton->size += DW_BLOCK (member_loc)->size;
- ptr = obstack_alloc (&objfile->objfile_obstack, baton->size);
+ ptr = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, baton->size);
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;
size = (sizeof (struct common_block)
+ (n_entries - 1) * sizeof (struct symbol *));
- common_block = obstack_alloc (&objfile->objfile_obstack, size);
+ common_block
+ = (struct common_block *) obstack_alloc (&objfile->objfile_obstack,
+ size);
memset (common_block->contents, 0, n_entries * sizeof (struct symbol *));
common_block->n_entries = 0;
_("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))
previous_prefix, name, 0, cu);
/* Create the type. */
- type = init_type (TYPE_CODE_NAMESPACE, 0, 0, NULL,
- objfile);
- TYPE_NAME (type) = name;
+ type = init_type (objfile, TYPE_CODE_NAMESPACE, 0, name);
TYPE_TAG_NAME (type) = TYPE_NAME (type);
return set_die_type (die, type, cu);
if (!module_name)
complaint (&symfile_complaints,
_("DW_TAG_module has no name, offset 0x%x"),
- die->offset.sect_off);
- type = init_type (TYPE_CODE_MODULE, 0, 0, module_name, objfile);
+ to_underlying (die->sect_off));
+ type = init_type (objfile, TYPE_CODE_MODULE, 0, module_name);
/* determine_prefix uses TYPE_TAG_NAME. */
TYPE_TAG_NAME (type) = TYPE_NAME (type);
return set_die_type (die, type, cu);
}
-/* 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)
{
if (attr)
TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
else
- {
- TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
-
- /* GCC/43521: In java, the formal parameter
- "this" is sometimes not marked with DW_AT_artificial. */
- if (cu->language == language_java)
- {
- const char *name = dwarf2_name (child_die, cu);
-
- if (name && !strcmp (name, "this"))
- TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 1;
- }
- }
+ TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
arg_type = die_type (child_die, cu);
/* RealView does not mark THIS as const, which the testsuite
struct type *this_type, *target_type;
name = dwarf2_full_name (NULL, die, cu);
- this_type = init_type (TYPE_CODE_TYPEDEF, 0,
- TYPE_FLAG_TARGET_STUB, NULL, objfile);
- TYPE_NAME (this_type) = name;
+ this_type = init_type (objfile, TYPE_CODE_TYPEDEF, 0, name);
+ TYPE_TARGET_STUB (this_type) = 1;
set_die_type (die, this_type, cu);
target_type = die_type (die, cu);
if (target_type != this_type)
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;
}
+/* Allocate a floating-point type of size BITS and name NAME. Pass NAME_HINT
+ (which may be different from NAME) to the architecture back-end to allow
+ it to guess the correct format if necessary. */
+
+static struct type *
+dwarf2_init_float_type (struct objfile *objfile, int bits, const char *name,
+ const char *name_hint)
+{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ const struct floatformat **format;
+ struct type *type;
+
+ format = gdbarch_floatformat_for_type (gdbarch, name_hint, bits);
+ if (format)
+ type = init_float_type (objfile, bits, name, format);
+ else
+ type = init_type (objfile, TYPE_CODE_ERROR, bits / TARGET_CHAR_BIT, name);
+
+ return type;
+}
+
/* Find a representation of a given base type and install
it in the TYPE field of the die. */
struct objfile *objfile = cu->objfile;
struct type *type;
struct attribute *attr;
- int encoding = 0, size = 0;
+ int encoding = 0, bits = 0;
const char *name;
- enum type_code code = TYPE_CODE_INT;
- int type_flags = 0;
- struct type *target_type = NULL;
attr = dwarf2_attr (die, DW_AT_encoding, cu);
if (attr)
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
- size = DW_UNSND (attr);
+ bits = DW_UNSND (attr) * TARGET_CHAR_BIT;
}
name = dwarf2_name (die, cu);
if (!name)
{
case DW_ATE_address:
/* Turn DW_ATE_address into a void * pointer. */
- code = TYPE_CODE_PTR;
- type_flags |= TYPE_FLAG_UNSIGNED;
- target_type = init_type (TYPE_CODE_VOID, 1, 0, NULL, objfile);
+ type = init_type (objfile, TYPE_CODE_VOID, 1, NULL);
+ type = init_pointer_type (objfile, bits, name, type);
break;
case DW_ATE_boolean:
- code = TYPE_CODE_BOOL;
- type_flags |= TYPE_FLAG_UNSIGNED;
+ type = init_boolean_type (objfile, bits, 1, name);
break;
case DW_ATE_complex_float:
- code = TYPE_CODE_COMPLEX;
- target_type = init_type (TYPE_CODE_FLT, size / 2, 0, NULL, objfile);
+ type = dwarf2_init_float_type (objfile, bits / 2, NULL, name);
+ type = init_complex_type (objfile, name, type);
break;
case DW_ATE_decimal_float:
- code = TYPE_CODE_DECFLOAT;
+ type = init_decfloat_type (objfile, bits, name);
break;
case DW_ATE_float:
- code = TYPE_CODE_FLT;
+ type = dwarf2_init_float_type (objfile, bits, name, name);
break;
case DW_ATE_signed:
+ type = init_integer_type (objfile, bits, 0, name);
break;
case DW_ATE_unsigned:
- type_flags |= TYPE_FLAG_UNSIGNED;
if (cu->language == language_fortran
&& name
&& startswith (name, "character("))
- code = TYPE_CODE_CHAR;
+ type = init_character_type (objfile, bits, 1, name);
+ else
+ type = init_integer_type (objfile, bits, 1, name);
break;
case DW_ATE_signed_char:
if (cu->language == language_ada || cu->language == language_m2
|| cu->language == language_pascal
|| cu->language == language_fortran)
- code = TYPE_CODE_CHAR;
+ type = init_character_type (objfile, bits, 0, name);
+ else
+ type = init_integer_type (objfile, bits, 0, name);
break;
case DW_ATE_unsigned_char:
if (cu->language == language_ada || cu->language == language_m2
|| cu->language == language_pascal
- || cu->language == language_fortran)
- code = TYPE_CODE_CHAR;
- type_flags |= TYPE_FLAG_UNSIGNED;
+ || cu->language == language_fortran
+ || cu->language == language_rust)
+ type = init_character_type (objfile, bits, 1, name);
+ else
+ 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);
break;
default:
complaint (&symfile_complaints, _("unsupported DW_AT_encoding: '%s'"),
dwarf_type_encoding_name (encoding));
+ type = init_type (objfile, TYPE_CODE_ERROR,
+ bits / TARGET_CHAR_BIT, name);
break;
}
- type = init_type (code, size, type_flags, NULL, objfile);
- TYPE_NAME (type) = name;
- TYPE_TARGET_TYPE (type) = target_type;
-
if (name && strcmp (name, "char") == 0)
TYPE_NOSIGN (type) = 1;
low_default_is_valid = 1;
break;
case language_d:
- case language_java:
case language_objc:
+ case language_rust:
low.data.const_val = 0;
low_default_is_valid = (cu->header.version >= 4);
break;
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))
the bounds as signed, and thus sign-extend their values, when
the base type is signed. */
negative_mask =
- (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1);
+ -((LONGEST) 1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1));
if (low.kind == PROP_CONST
&& !TYPE_UNSIGNED (base_type) && (low.data.const_val & negative_mask))
low.data.const_val |= negative_mask;
/* For now, we only support the C meaning of an unspecified type: void. */
- type = init_type (TYPE_CODE_VOID, 0, 0, NULL, cu->objfile);
+ type = init_type (cu->objfile, TYPE_CODE_VOID, 0, NULL);
TYPE_NAME (type) = dwarf2_name (die, cu);
return set_die_type (die, type, cu);
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;
abbrev_ptr += 1;
/* now read in declarations */
- abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
- abbrev_ptr += bytes_read;
- abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
- abbrev_ptr += bytes_read;
- while (abbrev_name)
+ for (;;)
{
+ LONGEST implicit_const;
+
+ abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ abbrev_ptr += bytes_read;
+ if (abbrev_form == DW_FORM_implicit_const)
+ {
+ implicit_const = read_signed_leb128 (abfd, abbrev_ptr,
+ &bytes_read);
+ abbrev_ptr += bytes_read;
+ }
+ else
+ {
+ /* Initialize it due to a false compiler warning. */
+ implicit_const = -1;
+ }
+
+ if (abbrev_name == 0)
+ break;
+
if (cur_abbrev->num_attrs == allocated_attrs)
{
allocated_attrs += ATTR_ALLOC_CHUNK;
cur_attrs
- = xrealloc (cur_attrs, (allocated_attrs
- * sizeof (struct attr_abbrev)));
+ = XRESIZEVEC (struct attr_abbrev, cur_attrs, allocated_attrs);
}
cur_attrs[cur_abbrev->num_attrs].name
= (enum dwarf_attribute) abbrev_name;
- cur_attrs[cur_abbrev->num_attrs++].form
+ cur_attrs[cur_abbrev->num_attrs].form
= (enum dwarf_form) abbrev_form;
- abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
- abbrev_ptr += bytes_read;
- abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
- abbrev_ptr += bytes_read;
+ cur_attrs[cur_abbrev->num_attrs].implicit_const = implicit_const;
+ ++cur_abbrev->num_attrs;
}
cur_abbrev->attrs =
static void
abbrev_table_free_cleanup (void *table_ptr)
{
- struct abbrev_table **abbrev_table_ptr = table_ptr;
+ struct abbrev_table **abbrev_table_ptr = (struct abbrev_table **) table_ptr;
if (*abbrev_table_ptr != NULL)
abbrev_table_free (*abbrev_table_ptr);
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. */
static void
dwarf2_free_abbrev_table (void *ptr_to_cu)
{
- struct dwarf2_cu *cu = ptr_to_cu;
+ struct dwarf2_cu *cu = (struct dwarf2_cu *) ptr_to_cu;
if (cu->abbrev_table != NULL)
abbrev_table_free (cu->abbrev_table);
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
else if (building_psymtab)
add_psymbol_to_list (part_die->name, strlen (part_die->name), 0,
VAR_DOMAIN, LOC_CONST,
- (cu->language == language_cplus
- || cu->language == language_java)
+ cu->language == language_cplus
? &objfile->global_psymbols
: &objfile->static_psymbols,
0, cu->language, objfile);
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,
to describe functions' calling conventions.
However, because it's a necessary piece of information in
- Fortran, and because DW_CC_program is the only piece of debugging
- information whose definition refers to a 'main program' at all,
- several compilers have begun marking Fortran main programs with
- DW_CC_program --- even when those functions use the standard
- calling conventions.
-
- So until DWARF specifies a way to provide this information and
- compilers pick up the new representation, we'll support this
- practice. */
+ Fortran, and before DWARF 4 DW_CC_program was the only
+ piece of debugging information whose definition refers to
+ a 'main program' at all, several compilers marked Fortran
+ main programs with DW_CC_program --- even when those
+ functions use the standard calling conventions.
+
+ Although DWARF now specifies a way to provide this
+ information, we support this practice for backward
+ compatibility. */
if (DW_UNSND (&attr) == DW_CC_program
&& cu->language == language_fortran)
- set_objfile_main_name (objfile, part_die->name, language_fortran);
+ part_die->main_subprogram = 1;
break;
case DW_AT_inline:
if (DW_UNSND (&attr) == DW_INL_inlined
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);
}
break;
+ case DW_AT_main_subprogram:
+ part_die->main_subprogram = DW_UNSND (&attr);
+ break;
+
default:
break;
}
_("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;
- lookup_die = htab_find_with_hash (cu->partial_dies, &part_die,
- offset.sect_off);
+ part_die.sect_off = sect_off;
+ lookup_die = ((struct partial_die_info *)
+ htab_find_with_hash (cu->partial_dies, &part_die,
+ 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;
}
if (actual_class_name != NULL)
{
struct_pdi->name
- = obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
- actual_class_name,
- strlen (actual_class_name));
+ = ((const char *)
+ obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
+ actual_class_name,
+ strlen (actual_class_name)));
xfree (actual_class_name);
}
break;
base = demangled;
part_die->name
- = obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
- base, strlen (base));
+ = ((const char *)
+ obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
+ base, strlen (base)));
xfree (demangled);
}
}
static const gdb_byte *
read_attribute_value (const struct die_reader_specs *reader,
struct attribute *attr, unsigned form,
- const gdb_byte *info_ptr)
+ LONGEST implicit_const, const gdb_byte *info_ptr)
{
struct dwarf2_cu *cu = reader->cu;
struct objfile *objfile = cu->objfile;
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;
break;
}
/* FALLTHROUGH */
+ case DW_FORM_line_strp:
+ if (!cu->per_cu->is_dwz)
+ {
+ DW_STRING (attr) = read_indirect_line_string (abfd, info_ptr,
+ cu_header, &bytes_read);
+ DW_STRING_IS_CANONICAL (attr) = 0;
+ info_ptr += bytes_read;
+ break;
+ }
+ /* FALLTHROUGH */
case DW_FORM_GNU_strp_alt:
{
struct dwz_file *dwz = dwarf2_get_dwz_file ();
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;
case DW_FORM_indirect:
form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
- info_ptr = read_attribute_value (reader, attr, form, info_ptr);
+ if (form == DW_FORM_implicit_const)
+ {
+ implicit_const = read_signed_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ }
+ info_ptr = read_attribute_value (reader, attr, form, implicit_const,
+ info_ptr);
+ break;
+ case DW_FORM_implicit_const:
+ DW_SND (attr) = implicit_const;
break;
case DW_FORM_GNU_addr_index:
if (reader->dwo_file == NULL)
const gdb_byte *info_ptr)
{
attr->name = abbrev->name;
- return read_attribute_value (reader, attr, abbrev->form, info_ptr);
+ return read_attribute_value (reader, attr, abbrev->form,
+ abbrev->implicit_const, info_ptr);
}
/* Read dwarf information from a buffer. */
return (const char *) buf;
}
+/* Return pointer to string at section SECT offset STR_OFFSET with error
+ reporting strings FORM_NAME and SECT_NAME. */
+
static const char *
-read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
-{
- dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->str);
- if (dwarf2_per_objfile->str.buffer == NULL)
- error (_("DW_FORM_strp used without .debug_str section [in module %s]"),
- bfd_get_filename (abfd));
- if (str_offset >= dwarf2_per_objfile->str.size)
- error (_("DW_FORM_strp pointing outside of "
- ".debug_str section [in module %s]"),
- bfd_get_filename (abfd));
+read_indirect_string_at_offset_from (bfd *abfd, LONGEST str_offset,
+ struct dwarf2_section_info *sect,
+ const char *form_name,
+ const char *sect_name)
+{
+ dwarf2_read_section (dwarf2_per_objfile->objfile, sect);
+ if (sect->buffer == NULL)
+ error (_("%s used without %s section [in module %s]"),
+ form_name, sect_name, bfd_get_filename (abfd));
+ if (str_offset >= sect->size)
+ error (_("%s pointing outside of %s section [in module %s]"),
+ form_name, sect_name, bfd_get_filename (abfd));
gdb_assert (HOST_CHAR_BIT == 8);
- if (dwarf2_per_objfile->str.buffer[str_offset] == '\0')
+ if (sect->buffer[str_offset] == '\0')
return NULL;
- return (const char *) (dwarf2_per_objfile->str.buffer + str_offset);
+ return (const char *) (sect->buffer + str_offset);
+}
+
+/* Return pointer to string at .debug_str offset STR_OFFSET. */
+
+static const char *
+read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
+{
+ return read_indirect_string_at_offset_from (abfd, str_offset,
+ &dwarf2_per_objfile->str,
+ "DW_FORM_strp", ".debug_str");
+}
+
+/* Return pointer to string at .debug_line_str offset STR_OFFSET. */
+
+static const char *
+read_indirect_line_string_at_offset (bfd *abfd, LONGEST str_offset)
+{
+ return read_indirect_string_at_offset_from (abfd, str_offset,
+ &dwarf2_per_objfile->line_str,
+ "DW_FORM_line_strp",
+ ".debug_line_str");
}
/* Read a string at offset STR_OFFSET in the .debug_str section from
return (const char *) (dwz->str.buffer + str_offset);
}
+/* Return pointer to string at .debug_str offset as read from BUF.
+ BUF is assumed to be in a compilation unit described by CU_HEADER.
+ Return *BYTES_READ_PTR count of bytes read from BUF. */
+
static const char *
read_indirect_string (bfd *abfd, const gdb_byte *buf,
const struct comp_unit_head *cu_header,
return read_indirect_string_at_offset (abfd, str_offset);
}
-static ULONGEST
+/* Return pointer to string at .debug_line_str offset as read from BUF.
+ BUF is assumed to be in a compilation unit described by CU_HEADER.
+ Return *BYTES_READ_PTR count of bytes read from BUF. */
+
+static const char *
+read_indirect_line_string (bfd *abfd, const gdb_byte *buf,
+ const struct comp_unit_head *cu_header,
+ unsigned int *bytes_read_ptr)
+{
+ LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
+
+ return read_indirect_line_string_at_offset (abfd, str_offset);
+}
+
+ULONGEST
read_unsigned_leb128 (bfd *abfd, const gdb_byte *buf,
- unsigned int *bytes_read_ptr)
+ unsigned int *bytes_read_ptr)
{
ULONGEST result;
unsigned int num_read;
- int i, shift;
+ int shift;
unsigned char byte;
result = 0;
shift = 0;
num_read = 0;
- i = 0;
while (1)
{
byte = bfd_get_8 (abfd, buf);
unsigned int *bytes_read_ptr)
{
LONGEST result;
- int i, shift, num_read;
+ int shift, num_read;
unsigned char byte;
result = 0;
shift = 0;
num_read = 0;
- i = 0;
while (1)
{
byte = bfd_get_8 (abfd, buf);
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);
}
case DW_LANG_UPC:
cu->language = language_c;
break;
+ case DW_LANG_Java:
case DW_LANG_C_plus_plus:
case DW_LANG_C_plus_plus_11:
case DW_LANG_C_plus_plus_14:
case DW_LANG_Mips_Assembler:
cu->language = language_asm;
break;
- case DW_LANG_Java:
- cu->language = language_java;
- break;
case DW_LANG_Ada83:
case DW_LANG_Ada95:
cu->language = language_ada;
case DW_LANG_ObjC:
cu->language = language_objc;
break;
+ case DW_LANG_Rust:
+ case DW_LANG_Rust_old:
+ cu->language = language_rust;
+ break;
case DW_LANG_Cobol74:
case DW_LANG_Cobol85:
default:
if (attr != NULL)
{
- if (attr->form == DW_FORM_strp || attr->form == DW_FORM_string
- || attr->form == DW_FORM_GNU_strp_alt)
+ if (attr->form == DW_FORM_strp || attr->form == DW_FORM_line_strp
+ || attr->form == DW_FORM_string || attr->form == DW_FORM_GNU_strp_alt)
str = DW_STRING (attr);
else
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. */
+/* Stub for free_line_header to match void * callback types. */
static void
-free_line_header (struct line_header *lh)
+free_line_header_voidp (void *arg)
{
- if (lh->standard_opcode_lengths)
- xfree (lh->standard_opcode_lengths);
+ struct line_header *lh = (struct line_header *) arg;
- /* 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);
+ delete lh;
+}
- /* Similarly for the include directory names. */
- if (lh->include_dirs)
- xfree (lh->include_dirs);
+void
+line_header::add_include_dir (const char *include_dir)
+{
+ if (dwarf_line_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "Adding dir %zu: %s\n",
+ include_dirs.size () + 1, include_dir);
- xfree (lh);
+ include_dirs.push_back (include_dir);
}
-/* Stub for free_line_header to match void * callback types. */
-
-static void
-free_line_header_voidp (void *arg)
+void
+line_header::add_file_name (const char *name,
+ dir_index d_index,
+ unsigned int mod_time,
+ unsigned int length)
{
- struct line_header *lh = arg;
+ if (dwarf_line_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "Adding file %u: %s\n",
+ (unsigned) file_names.size () + 1, name);
- free_line_header (lh);
+ file_names.emplace_back (name, d_index, mod_time, length);
}
-/* Add an entry to LH's include directory table. */
+/* A convenience function to find the proper .debug_line section for a CU. */
-static void
-add_include_dir (struct line_header *lh, const char *include_dir)
+static struct dwarf2_section_info *
+get_debug_line_section (struct dwarf2_cu *cu)
{
- if (dwarf_line_debug >= 2)
- fprintf_unfiltered (gdb_stdlog, "Adding dir %u: %s\n",
- lh->num_include_dirs + 1, include_dir);
+ struct dwarf2_section_info *section;
- /* Grow the array if necessary. */
- if (lh->include_dirs_size == 0)
+ /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
+ DWO file. */
+ if (cu->dwo_unit && cu->per_cu->is_debug_types)
+ section = &cu->dwo_unit->dwo_file->sections.line;
+ else if (cu->per_cu->is_dwz)
{
- lh->include_dirs_size = 1; /* for testing */
- lh->include_dirs = XNEWVEC (const char *, lh->include_dirs_size);
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+
+ section = &dwz->line;
}
- else if (lh->num_include_dirs >= lh->include_dirs_size)
+ else
+ section = &dwarf2_per_objfile->line;
+
+ return section;
+}
+
+/* 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
+ format. */
+
+static void
+read_formatted_entries (bfd *abfd, const gdb_byte **bufp,
+ struct line_header *lh,
+ const struct comp_unit_head *cu_header,
+ void (*callback) (struct line_header *lh,
+ const char *name,
+ dir_index d_index,
+ unsigned int mod_time,
+ unsigned int length))
+{
+ gdb_byte format_count, formati;
+ ULONGEST data_count, datai;
+ const gdb_byte *buf = *bufp;
+ const gdb_byte *format_header_data;
+ int i;
+ unsigned int bytes_read;
+
+ format_count = read_1_byte (abfd, buf);
+ buf += 1;
+ format_header_data = buf;
+ for (formati = 0; formati < format_count; formati++)
{
- lh->include_dirs_size *= 2;
- lh->include_dirs = XRESIZEVEC (const char *, lh->include_dirs,
- lh->include_dirs_size);
+ read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
}
- lh->include_dirs[lh->num_include_dirs++] = include_dir;
-}
+ data_count = read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ for (datai = 0; datai < data_count; datai++)
+ {
+ const gdb_byte *format = format_header_data;
+ struct file_entry fe;
+
+ for (formati = 0; formati < format_count; formati++)
+ {
+ ULONGEST content_type = read_unsigned_leb128 (abfd, format, &bytes_read);
+ 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:
+ string.emplace (read_direct_string (abfd, buf, &bytes_read));
+ buf += bytes_read;
+ break;
-/* Add an entry to LH's file name table. */
+ case DW_FORM_line_strp:
+ string.emplace (read_indirect_line_string (abfd, buf,
+ cu_header,
+ &bytes_read));
+ buf += bytes_read;
+ break;
-static void
-add_file_name (struct line_header *lh,
- const char *name,
- unsigned int dir_index,
- unsigned int mod_time,
- unsigned int length)
-{
- struct file_entry *fe;
+ case DW_FORM_data1:
+ uint.emplace (read_1_byte (abfd, buf));
+ buf += 1;
+ break;
- if (dwarf_line_debug >= 2)
- fprintf_unfiltered (gdb_stdlog, "Adding file %u: %s\n",
- lh->num_file_names + 1, name);
+ case DW_FORM_data2:
+ uint.emplace (read_2_bytes (abfd, buf));
+ buf += 2;
+ break;
- /* 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 = xrealloc (lh->file_names,
- (lh->file_names_size
- * sizeof (*lh->file_names)));
- }
+ case DW_FORM_data4:
+ uint.emplace (read_4_bytes (abfd, buf));
+ buf += 4;
+ break;
- 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;
-}
+ case DW_FORM_data8:
+ uint.emplace (read_8_bytes (abfd, buf));
+ buf += 8;
+ break;
-/* A convenience function to find the proper .debug_line section for a CU. */
+ case DW_FORM_udata:
+ uint.emplace (read_unsigned_leb128 (abfd, buf, &bytes_read));
+ buf += bytes_read;
+ break;
-static struct dwarf2_section_info *
-get_debug_line_section (struct dwarf2_cu *cu)
-{
- struct dwarf2_section_info *section;
+ case DW_FORM_block:
+ /* It is valid only for DW_LNCT_timestamp which is ignored by
+ current GDB. */
+ break;
+ }
- /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
- DWO file. */
- if (cu->dwo_unit && cu->per_cu->is_debug_types)
- section = &cu->dwo_unit->dwo_file->sections.line;
- else if (cu->per_cu->is_dwz)
- {
- struct dwz_file *dwz = dwarf2_get_dwz_file ();
+ 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));
+ }
+ }
- section = &dwz->line;
+ callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);
}
- else
- section = &dwarf2_per_objfile->line;
- return section;
+ *bufp = buf;
}
/* Read the statement program header starting at OFFSET in
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;
lh->version = read_2_bytes (abfd, line_ptr);
line_ptr += 2;
- if (lh->version > 4)
+ if (lh->version > 5)
{
/* This is a version we don't understand. The format could have
changed in ways we don't handle properly so just punt. */
_("unsupported version in .debug_line section"));
return NULL;
}
+ if (lh->version >= 5)
+ {
+ gdb_byte segment_selector_size;
+
+ /* Skip address size. */
+ read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+
+ segment_selector_size = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ if (segment_selector_size != 0)
+ {
+ complaint (&symfile_complaints,
+ _("unsupported segment selector size %u "
+ "in .debug_line section"),
+ segment_selector_size);
+ return NULL;
+ }
+ }
lh->header_length = read_offset_1 (abfd, line_ptr, offset_size);
line_ptr += offset_size;
lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
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)
line_ptr += 1;
}
- /* Read directory table. */
- while ((cur_dir = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+ if (lh->version >= 5)
{
- line_ptr += bytes_read;
- add_include_dir (lh, cur_dir);
+ /* Read directory table. */
+ 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.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);
+ });
}
- line_ptr += bytes_read;
-
- /* Read file name table. */
- while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+ else
{
- unsigned int dir_index, mod_time, length;
-
- line_ptr += bytes_read;
- 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);
+ /* Read directory table. */
+ while ((cur_dir = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ line_ptr += bytes_read;
+ lh->add_include_dir (cur_dir);
+ }
line_ptr += bytes_read;
- add_file_name (lh, cur_file, dir_index, mod_time, length);
+ /* Read file name table. */
+ while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+ {
+ unsigned int mod_time, length;
+ dir_index d_index;
+
+ 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;
+
+ lh->add_file_name (cur_file, d_index, mod_time, length);
+ }
+ line_ptr += bytes_read;
}
- line_ptr += bytes_read;
lh->statement_program_start = line_ptr;
if (line_ptr > (section->buffer + section->size))
_("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 ();
+
+ /* 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;
- unsigned char op_index;
- unsigned int file;
- unsigned int line;
- CORE_ADDR address;
- int is_stmt;
- unsigned int discriminator;
+ /* 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;
-
- /* Reset the state machine at the start of each sequence. */
- init_lnp_state_machine (&state_machine, &reader_state);
+ /* 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;
- 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;
+ /* Start a subfile for the current file of the state
+ machine. */
+ const file_entry *fe = state_machine.current_file ();
- if (fe->dir_index && lh->include_dirs != NULL)
- dir = lh->include_dirs[fe->dir_index - 1];
-
- 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
- || file_index > cu->line_header->num_file_names)
+ if (cu->line_header != NULL)
+ fe = cu->line_header->file_name_at (file_index);
+ else
+ fe = NULL;
+
+ 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)
if (cu->language == language_fortran && die->parent
&& die->parent->tag == DW_TAG_module
&& cu->producer
- && startswith (cu->producer, "GNU Fortran "))
+ && startswith (cu->producer, "GNU Fortran"))
SYMBOL_ACLASS_INDEX (sym) = LOC_UNRESOLVED;
/* A variable with DW_AT_external is never static,
SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
{
- /* NOTE: carlton/2003-11-10: C++ and Java class symbols shouldn't
+ /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
really ever be static objects: otherwise, if you try
to, say, break of a class's method and you're in a file
which doesn't mention that class, it won't work unless
if (!suppress_add)
{
list_to_add = (cu->list_in_scope == &file_symbols
- && (cu->language == language_cplus
- || cu->language == language_java)
+ && cu->language == language_cplus
? &global_symbols : cu->list_in_scope);
/* The semantics of C++ state that "struct foo {
- ... }" also defines a typedef for "foo". A Java
- class declaration also defines a typedef for the
- class. */
+ ... }" also defines a typedef for "foo". */
if (cu->language == language_cplus
- || cu->language == language_java
|| cu->language == language_ada
- || cu->language == language_d)
+ || cu->language == language_d
+ || cu->language == language_rust)
{
/* The symbol's name is already allocated along
with this objfile, so we don't need to
DW_TAG_class_type, etc. block. */
list_to_add = (cu->list_in_scope == &file_symbols
- && (cu->language == language_cplus
- || cu->language == language_java)
+ && cu->language == language_cplus
? &global_symbols : cu->list_in_scope);
}
break;
*value = l;
else
{
- gdb_byte *bytes = obstack_alloc (obstack, bits / 8);
+ gdb_byte *bytes = (gdb_byte *) obstack_alloc (obstack, bits / 8);
store_unsigned_integer (bytes, bits / 8, byte_order, l);
return bytes;
}
gdb_assert ((*baton)->per_cu);
(*baton)->size = 2 + cu_header->addr_size;
- data = obstack_alloc (obstack, (*baton)->size);
+ data = (gdb_byte *) obstack_alloc (obstack, (*baton)->size);
(*baton)->data = data;
data[0] = DW_OP_addr;
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,
struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- struct comp_unit_head *cu_header = &cu->header;
LONGEST value;
const gdb_byte *bytes;
struct dwarf2_locexpr_baton *baton;
message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
objfile_name (objfile),
- cu->header.offset.sect_off,
- die->offset.sect_off);
- saved = obstack_copy0 (&objfile->objfile_obstack,
- message, strlen (message));
+ to_underlying (cu->header.sect_off),
+ to_underlying (die->sect_off));
+ saved = (char *) obstack_copy0 (&objfile->objfile_obstack,
+ message, strlen (message));
xfree (message);
- return init_type (TYPE_CODE_ERROR, 0, 0, saved, objfile);
+ return init_type (objfile, TYPE_CODE_ERROR, 0, saved);
}
/* Look up the type of DIE in CU using its type attribute ATTR.
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);
if (actual_name_len > die_name_len + 2
&& actual_name[actual_name_len
- die_name_len - 1] == ':')
- name =
- obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
- actual_name,
- actual_name_len - die_name_len - 2);
+ name = (char *) obstack_copy0 (
+ &cu->objfile->per_bfd->storage_obstack,
+ actual_name, actual_name_len - die_name_len - 2);
}
}
xfree (actual_name);
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;
- char *base;
+ const char *base;
if (die->tag != DW_TAG_class_type && die->tag != DW_TAG_interface_type
&& die->tag != DW_TAG_structure_type && die->tag != DW_TAG_union_type)
if (base == NULL || base == DW_STRING (attr) || base[-1] != ':')
return "";
- return obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
- DW_STRING (attr), &base[-1] - DW_STRING (attr));
+ return (char *) obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
+ DW_STRING (attr),
+ &base[-1] - DW_STRING (attr));
}
/* Return the name of the namespace/class that DIE is defined within,
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_java
- && cu->language != language_fortran && cu->language != language_d)
+ if (cu->language != language_cplus
+ && cu->language != language_fortran && cu->language != language_d
+ && cu->language != language_rust)
return "";
retval = anonymous_struct_prefix (die, cu);
if (suffix == NULL || suffix[0] == '\0'
|| prefix == NULL || prefix[0] == '\0')
sep = "";
- else if (cu->language == language_java)
- sep = ".";
else if (cu->language == language_d)
{
/* For D, the 'main' function could be defined in any module, but it
if (obs == NULL)
{
char *retval
- = xmalloc (strlen (prefix) + MAX_SEP_LEN + strlen (suffix) + 1);
+ = ((char *)
+ xmalloc (strlen (prefix) + MAX_SEP_LEN + strlen (suffix) + 1));
strcpy (retval, lead);
strcat (retval, prefix);
{
if (name && cu->language == language_cplus)
{
- char *canon_name = cp_canonicalize_string (name);
+ std::string canon_name = cp_canonicalize_string (name);
- if (canon_name != NULL)
+ if (!canon_name.empty ())
{
- if (strcmp (canon_name, name) != 0)
- name = obstack_copy0 (obstack, canon_name, strlen (canon_name));
- xfree (canon_name);
+ if (canon_name != name)
+ name = (const char *) obstack_copy0 (obstack,
+ canon_name.c_str (),
+ canon_name.length ());
}
}
return DW_STRING (attr);
return CP_ANONYMOUS_NAMESPACE_STR;
- case DW_TAG_subprogram:
- /* Java constructors will all be named "<init>", so return
- the class name when we see this special case. */
- if (cu->language == language_java
- && DW_STRING (attr) != NULL
- && strcmp (DW_STRING (attr), "<init>") == 0)
- {
- struct dwarf2_cu *spec_cu = cu;
- struct die_info *spec_die;
-
- /* GCJ will output '<init>' for Java constructor names.
- For this special case, return the name of the parent class. */
-
- /* GCJ may output subprogram DIEs with AT_specification set.
- If so, use the name of the specified DIE. */
- spec_die = die_specification (die, &spec_cu);
- if (spec_die != NULL)
- return dwarf2_name (spec_die, spec_cu);
-
- do
- {
- die = die->parent;
- if (die->tag == DW_TAG_class_type)
- return dwarf2_name (die, cu);
- }
- while (die->tag != DW_TAG_compile_unit
- && die->tag != DW_TAG_partial_unit);
- }
- break;
-
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_TAG_structure_type:
if (demangled)
{
- char *base;
+ const char *base;
/* FIXME: we already did this for the partial symbol... */
DW_STRING (attr)
- = obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
- demangled, strlen (demangled));
+ = ((const char *)
+ obstack_copy0 (&cu->objfile->per_bfd->storage_obstack,
+ demangled, strlen (demangled)));
DW_STRING_IS_CANONICAL (attr) = 1;
xfree (demangled);
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);
break;
case DW_FORM_string:
case DW_FORM_strp:
+ case DW_FORM_line_strp:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)",
{
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;
- return htab_find_with_hash (target_cu->die_hash, &temp_die, offset.sect_off);
+ temp_die.sect_off = sect_off;
+ return (struct die_info *) htab_find_with_hash (target_cu->die_hash,
+ &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
gdb_byte *result;
*len = TYPE_LENGTH (type);
- result = obstack_alloc (obstack, *len);
+ result = (gdb_byte *) obstack_alloc (obstack, *len);
store_unsigned_integer (result, *len, byte_order, value);
return result;
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);
gdb_byte *tem;
*len = cu->header.addr_size;
- tem = obstack_alloc (obstack, *len);
+ tem = (gdb_byte *) obstack_alloc (obstack, *len);
store_unsigned_integer (tem, *len, byte_order, DW_ADDR (attr));
result = tem;
}
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);
}
follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
struct dwarf2_cu **ref_cu)
{
- struct objfile *objfile = (*ref_cu)->objfile;
struct die_info temp_die;
struct dwarf2_cu *sig_cu;
struct die_info *die;
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;
- die = htab_find_with_hash (sig_cu->die_hash, &temp_die,
- temp_die.offset.sect_off);
+ 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,
+ 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);
}
break;
case DW_OP_GNU_push_tls_address:
+ case DW_OP_form_tls_address:
/* The top of the stack has the offset from the beginning
of the thread control block at which the variable is located. */
/* Nothing should follow this operator, so the top of stack would
{
/* 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, 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);
if (IS_ABSOLUTE_PATH (relative) || comp_dir == NULL)
return relative;
- return reconcat (relative, comp_dir, SLASH_STRING, relative, NULL);
+ return reconcat (relative, comp_dir, SLASH_STRING,
+ relative, (char *) NULL);
}
else
return file_file_name (file, lh);
static char *
copy_string (const char *buf, int len)
{
- char *s = xmalloc (len + 1);
+ char *s = (char *) xmalloc (len + 1);
memcpy (s, buf, len);
s[len] = '\0';
if (argc >= argv_size)
{
argv_size *= 2;
- argv = xrealloc (argv, argv_size * sizeof (*argv));
+ argv = XRESIZEVEC (char *, argv, argv_size);
}
argv[argc++] = copy_string (arg_start, p - arg_start);
bytes += 8;
break;
+ case DW_FORM_data16:
+ bytes += 16;
+ break;
+
case DW_FORM_string:
read_direct_string (abfd, bytes, &bytes_read);
bytes += bytes_read;
unsigned int version, flags;
version = read_2_bytes (abfd, mac_ptr);
- if (version != 4)
+ if (version != 4 && version != 5)
{
complaint (&symfile_complaints,
_("unrecognized version `%d' in .debug_macro section"),
}
/* A helper for dwarf_decode_macros that handles the GNU extensions,
- including DW_MACRO_GNU_transparent_include. */
+ including DW_MACRO_import. */
static void
dwarf_decode_macro_bytes (bfd *abfd,
case 0:
break;
- case DW_MACRO_GNU_define:
- case DW_MACRO_GNU_undef:
- case DW_MACRO_GNU_define_indirect:
- case DW_MACRO_GNU_undef_indirect:
- case DW_MACRO_GNU_define_indirect_alt:
- case DW_MACRO_GNU_undef_indirect_alt:
+ case DW_MACRO_define:
+ case DW_MACRO_undef:
+ case DW_MACRO_define_strp:
+ case DW_MACRO_undef_strp:
+ case DW_MACRO_define_sup:
+ case DW_MACRO_undef_sup:
{
unsigned int bytes_read;
int line;
line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
mac_ptr += bytes_read;
- if (macinfo_type == DW_MACRO_GNU_define
- || macinfo_type == DW_MACRO_GNU_undef)
+ if (macinfo_type == DW_MACRO_define
+ || macinfo_type == DW_MACRO_undef)
{
body = read_direct_string (abfd, mac_ptr, &bytes_read);
mac_ptr += bytes_read;
str_offset = read_offset_1 (abfd, mac_ptr, offset_size);
mac_ptr += offset_size;
- if (macinfo_type == DW_MACRO_GNU_define_indirect_alt
- || macinfo_type == DW_MACRO_GNU_undef_indirect_alt
+ if (macinfo_type == DW_MACRO_define_sup
+ || macinfo_type == DW_MACRO_undef_sup
|| section_is_dwz)
{
struct dwz_file *dwz = dwarf2_get_dwz_file ();
body = read_indirect_string_at_offset (abfd, str_offset);
}
- is_define = (macinfo_type == DW_MACRO_GNU_define
- || macinfo_type == DW_MACRO_GNU_define_indirect
- || macinfo_type == DW_MACRO_GNU_define_indirect_alt);
+ is_define = (macinfo_type == DW_MACRO_define
+ || macinfo_type == DW_MACRO_define_strp
+ || macinfo_type == DW_MACRO_define_sup);
if (! current_file)
{
/* DWARF violation as no main source is present. */
parse_macro_definition (current_file, line, body);
else
{
- gdb_assert (macinfo_type == DW_MACRO_GNU_undef
- || macinfo_type == DW_MACRO_GNU_undef_indirect
- || macinfo_type == DW_MACRO_GNU_undef_indirect_alt);
+ gdb_assert (macinfo_type == DW_MACRO_undef
+ || macinfo_type == DW_MACRO_undef_strp
+ || macinfo_type == DW_MACRO_undef_sup);
macro_undef (current_file, line, body);
}
}
break;
- case DW_MACRO_GNU_start_file:
+ case DW_MACRO_start_file:
{
unsigned int bytes_read;
int line, file;
if (at_commandline)
{
- /* This DW_MACRO_GNU_start_file was executed in the
+ /* This DW_MACRO_start_file was executed in the
pass one. */
at_commandline = 0;
}
}
break;
- case DW_MACRO_GNU_end_file:
+ case DW_MACRO_end_file:
if (! current_file)
complaint (&symfile_complaints,
_("macro debug info has an unmatched "
}
break;
- case DW_MACRO_GNU_transparent_include:
- case DW_MACRO_GNU_transparent_include_alt:
+ case DW_MACRO_import:
+ case DW_MACRO_import_sup:
{
LONGEST offset;
void **slot;
bfd *include_bfd = abfd;
struct dwarf2_section_info *include_section = section;
- struct dwarf2_section_info alt_section;
const gdb_byte *include_mac_end = mac_end;
int is_dwz = section_is_dwz;
const gdb_byte *new_mac_ptr;
offset = read_offset_1 (abfd, mac_ptr, offset_size);
mac_ptr += offset_size;
- if (macinfo_type == DW_MACRO_GNU_transparent_include_alt)
+ if (macinfo_type == DW_MACRO_import_sup)
{
struct dwz_file *dwz = dwarf2_get_dwz_file ();
/* This has actually happened; see
http://sourceware.org/bugzilla/show_bug.cgi?id=13568. */
complaint (&symfile_complaints,
- _("recursive DW_MACRO_GNU_transparent_include in "
+ _("recursive DW_MACRO_import in "
".debug_macro section"));
}
else
if (!section_is_gnu)
{
unsigned int bytes_read;
- int constant;
- constant = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+ /* This reads the constant, but since we don't recognize
+ any vendor extensions, we ignore it. */
+ read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
mac_ptr += bytes_read;
read_direct_string (abfd, mac_ptr, &bytes_read);
mac_ptr += bytes_read;
unsigned int offset_size = cu->header.offset_size;
const gdb_byte *opcode_definitions[256];
struct cleanup *cleanup;
- htab_t include_hash;
void **slot;
struct dwarf2_section_info *section;
const char *section_name;
case 0:
break;
- case DW_MACRO_GNU_define:
- case DW_MACRO_GNU_undef:
+ case DW_MACRO_define:
+ case DW_MACRO_undef:
/* Only skip the data by MAC_PTR. */
{
unsigned int bytes_read;
}
break;
- case DW_MACRO_GNU_start_file:
+ case DW_MACRO_start_file:
{
unsigned int bytes_read;
int line, file;
}
break;
- case DW_MACRO_GNU_end_file:
+ case DW_MACRO_end_file:
/* No data to skip by MAC_PTR. */
break;
- case DW_MACRO_GNU_define_indirect:
- case DW_MACRO_GNU_undef_indirect:
- case DW_MACRO_GNU_define_indirect_alt:
- case DW_MACRO_GNU_undef_indirect_alt:
+ case DW_MACRO_define_strp:
+ case DW_MACRO_undef_strp:
+ case DW_MACRO_define_sup:
+ case DW_MACRO_undef_sup:
{
unsigned int bytes_read;
}
break;
- case DW_MACRO_GNU_transparent_include:
- case DW_MACRO_GNU_transparent_include_alt:
+ case DW_MACRO_import:
+ case DW_MACRO_import_sup:
/* Note that, according to the spec, a transparent include
- chain cannot call DW_MACRO_GNU_start_file. So, we can just
+ chain cannot call DW_MACRO_start_file. So, we can just
skip this opcode. */
mac_ptr += offset_size;
break;
command-line macro definitions/undefinitions. This flag is unset when we
reach the first DW_MACINFO_start_file entry. */
- include_hash = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer,
- NULL, xcalloc, xfree);
- cleanup = make_cleanup_htab_delete (include_hash);
+ htab_up include_hash (htab_create_alloc (1, htab_hash_pointer,
+ htab_eq_pointer,
+ NULL, xcalloc, xfree));
mac_ptr = section->buffer + offset;
- slot = htab_find_slot (include_hash, mac_ptr, INSERT);
+ slot = htab_find_slot (include_hash.get (), mac_ptr, INSERT);
*slot = (void *) mac_ptr;
dwarf_decode_macro_bytes (abfd, mac_ptr, mac_end,
current_file, lh, section,
- section_is_gnu, 0, offset_size, include_hash);
- do_cleanups (cleanup);
+ section_is_gnu, 0, offset_size,
+ include_hash.get ());
}
/* Check if the attribute's form is a DW_FORM_block*
(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)
cu_debug_loc_section (struct dwarf2_cu *cu)
{
if (cu->dwo_unit)
- return &cu->dwo_unit->dwo_file->sections.loc;
- return &dwarf2_per_objfile->loc;
+ {
+ struct dwo_sections *sections = &cu->dwo_unit->dwo_file->sections;
+
+ return cu->header.version >= 5 ? §ions->loclists : §ions->loc;
+ }
+ return (cu->header.version >= 5 ? &dwarf2_per_objfile->loclists
+ : &dwarf2_per_objfile->loc);
}
/* A helper function that fills in a dwarf2_loclist_baton. */
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->objfile->obfd);
+ read_comp_unit_head (cu_headerp, info_ptr, per_cu->section,
+ rcuh_kind::COMPILE);
return cu_headerp;
}
return ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
}
+/* Return DWARF version number of PER_CU. */
+
+short
+dwarf2_version (struct dwarf2_per_cu_data *per_cu)
+{
+ return per_cu->dwarf_version;
+}
+
/* Locate the .debug_info compilation unit from CU's objfile which contains
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;
}
}
static void
free_heap_comp_unit (void *data)
{
- struct dwarf2_cu *cu = data;
+ struct dwarf2_cu *cu = (struct dwarf2_cu *) data;
gdb_assert (cu->per_cu != NULL);
cu->per_cu->cu = NULL;
static void
free_stack_comp_unit (void *data)
{
- struct dwarf2_cu *cu = data;
+ struct dwarf2_cu *cu = (struct dwarf2_cu *) data;
gdb_assert (cu->per_cu != NULL);
cu->per_cu->cu = NULL;
void
dwarf2_free_objfile (struct objfile *objfile)
{
- dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+ dwarf2_per_objfile
+ = (struct dwarf2_per_objfile *) objfile_data (objfile,
+ dwarf2_objfile_data_key);
if (dwarf2_per_objfile == NULL)
return;
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;
};
static hashval_t
per_cu_offset_and_type_hash (const void *item)
{
- const struct dwarf2_per_cu_offset_and_type *ofs = item;
+ 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. */
static int
per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs)
{
- const struct dwarf2_per_cu_offset_and_type *ofs_lhs = item_lhs;
- const struct dwarf2_per_cu_offset_and_type *ofs_rhs = item_rhs;
+ const struct dwarf2_per_cu_offset_and_type *ofs_lhs
+ = (const struct dwarf2_per_cu_offset_and_type *) item_lhs;
+ const struct dwarf2_per_cu_offset_and_type *ofs_rhs
+ = (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
&& !HAVE_GNAT_AUX_INFO (type))
INIT_GNAT_SPECIFIC (type);
+ /* Read DW_AT_allocated and set in type. */
+ attr = dwarf2_attr (die, DW_AT_allocated, cu);
+ if (attr_form_is_block (attr))
+ {
+ if (attr_to_dynamic_prop (attr, die, cu, &prop))
+ add_dyn_prop (DYN_PROP_ALLOCATED, prop, type, objfile);
+ }
+ 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"),
+ to_underlying (die->sect_off));
+ }
+
+ /* Read DW_AT_associated and set in type. */
+ attr = dwarf2_attr (die, DW_AT_associated, cu);
+ if (attr_form_is_block (attr))
+ {
+ if (attr_to_dynamic_prop (attr, die, cu, &prop))
+ add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type, objfile);
+ }
+ 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"),
+ to_underlying (die->sect_off));
+ }
+
/* Read DW_AT_data_location and set in type. */
attr = dwarf2_attr (die, DW_AT_data_location, cu);
if (attr_to_dynamic_prop (attr, die, cu, &prop))
}
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;
- slot = htab_find (dwarf2_per_objfile->die_type_hash, &ofs);
+ ofs.sect_off = sect_off;
+ slot = ((struct dwarf2_per_cu_offset_and_type *)
+ htab_find (dwarf2_per_objfile->die_type_hash, &ofs));
if (slot)
return slot->type;
else
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. */
static hashval_t
partial_die_hash (const void *item)
{
- const struct partial_die_info *part_die = item;
+ 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
static int
partial_die_eq (const void *item_lhs, const void *item_rhs)
{
- const struct partial_die_info *part_die_lhs = item_lhs;
- const struct partial_die_info *part_die_rhs = item_rhs;
+ const struct partial_die_info *part_die_lhs
+ = (const struct partial_die_info *) item_lhs;
+ 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;
static void
dwarf2_per_objfile_free (struct objfile *objfile, void *d)
{
- struct dwarf2_per_objfile *data = d;
+ struct dwarf2_per_objfile *data = (struct dwarf2_per_objfile *) d;
int ix;
/* Make sure we don't accidentally use dwarf2_per_objfile while
static hashval_t
hash_strtab_entry (const void *e)
{
- const struct strtab_entry *entry = e;
+ const struct strtab_entry *entry = (const struct strtab_entry *) e;
return mapped_index_string_hash (INT_MAX, entry->str);
}
static int
eq_strtab_entry (const void *a, const void *b)
{
- const struct strtab_entry *ea = a;
- const struct strtab_entry *eb = b;
+ const struct strtab_entry *ea = (const struct strtab_entry *) a;
+ const struct strtab_entry *eb = (const struct strtab_entry *) b;
return !strcmp (ea->str, eb->str);
}
entry.str = str;
slot = htab_find_slot (table, &entry, INSERT);
if (*slot)
- result = *slot;
+ result = (struct strtab_entry *) *slot;
else
{
result = XNEW (struct strtab_entry);
static hashval_t
hash_symtab_entry (const void *e)
{
- const struct symtab_index_entry *entry = e;
+ const struct symtab_index_entry *entry
+ = (const struct symtab_index_entry *) e;
return iterative_hash (VEC_address (offset_type, entry->cu_indices),
sizeof (offset_type) * VEC_length (offset_type,
entry->cu_indices),
static int
eq_symtab_entry (const void *a, const void *b)
{
- const struct symtab_index_entry *ea = a;
- const struct symtab_index_entry *eb = b;
+ const struct symtab_index_entry *ea = (const struct symtab_index_entry *) a;
+ const struct symtab_index_entry *eb = (const struct symtab_index_entry *) b;
int len = VEC_length (offset_type, ea->cu_indices);
if (len != VEC_length (offset_type, eb->cu_indices))
return 0;
static void
delete_symtab_entry (void *p)
{
- struct symtab_index_entry *entry = p;
+ struct symtab_index_entry *entry = (struct symtab_index_entry *) p;
VEC_free (offset_type, entry->cu_indices);
xfree (entry);
}
static void
cleanup_mapped_symtab (void *p)
{
- struct mapped_symtab *symtab = p;
+ struct mapped_symtab *symtab = (struct mapped_symtab *) p;
/* The contents of the array are freed when the other hash table is
destroyed. */
xfree (symtab->data);
}
else
{
- struct symtab_index_entry *old_entry = *slot;
+ struct symtab_index_entry *old_entry
+ = (struct symtab_index_entry *) *slot;
entry->index_offset = old_entry->index_offset;
entry = old_entry;
}
static hashval_t
hash_psymtab_cu_index (const void *item)
{
- const struct psymtab_cu_index_map *map = item;
+ const struct psymtab_cu_index_map *map
+ = (const struct psymtab_cu_index_map *) item;
return htab_hash_pointer (map->psymtab);
}
static int
eq_psymtab_cu_index (const void *item_lhs, const void *item_rhs)
{
- const struct psymtab_cu_index_map *lhs = item_lhs;
- const struct psymtab_cu_index_map *rhs = item_rhs;
+ const struct psymtab_cu_index_map *lhs
+ = (const struct psymtab_cu_index_map *) item_lhs;
+ const struct psymtab_cu_index_map *rhs
+ = (const struct psymtab_cu_index_map *) item_rhs;
return lhs->psymtab == rhs->psymtab;
}
static int
add_address_entry_worker (void *datap, CORE_ADDR start_addr, void *obj)
{
- struct addrmap_index_data *data = datap;
- struct partial_symtab *pst = obj;
+ struct addrmap_index_data *data = (struct addrmap_index_data *) datap;
+ struct partial_symtab *pst = (struct partial_symtab *) obj;
if (data->previous_valid)
add_address_entry (data->objfile, data->addr_obstack,
{
struct psymtab_cu_index_map find_map, *map;
find_map.psymtab = pst;
- map = htab_find (data->cu_index_htab, &find_map);
+ map = ((struct psymtab_cu_index_map *)
+ htab_find (data->cu_index_htab, &find_map));
gdb_assert (map != NULL);
data->previous_cu_index = map->cu_index;
data->previous_valid = 1;
error (_("couldn't data write to file"));
}
-/* Unlink a file if the argument is not NULL. */
-
-static void
-unlink_if_set (void *p)
-{
- char **filename = p;
- if (*filename)
- unlink (*filename);
-}
-
/* A helper struct used when iterating over debug_types. */
struct signatured_type_index_data
{
static int
write_one_signatured_type (void **slot, void *d)
{
- struct signatured_type_index_data *info = d;
+ struct signatured_type_index_data *info
+ = (struct signatured_type_index_data *) d;
struct signatured_type *entry = (struct signatured_type *) *slot;
struct partial_symtab *psymtab = entry->per_cu.v.psymtab;
gdb_byte val[8];
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);
write_psymtabs_to_index (struct objfile *objfile, const char *dir)
{
struct cleanup *cleanup;
- char *filename, *cleanup_filename;
+ char *filename;
struct obstack contents, addr_obstack, constant_pool, symtab_obstack;
struct obstack cu_list, types_cu_list;
int i;
struct mapped_symtab *symtab;
offset_type val, size_of_contents, total_len;
struct stat st;
- htab_t psyms_seen;
- htab_t cu_index_htab;
struct psymtab_cu_index_map *psymtab_cu_index_map;
if (dwarf2_per_objfile->using_index)
if (!out_file)
error (_("Can't open `%s' for writing"), filename);
- cleanup_filename = filename;
- make_cleanup (unlink_if_set, &cleanup_filename);
+ gdb::unlinker unlink_file (filename);
symtab = create_mapped_symtab ();
make_cleanup (cleanup_mapped_symtab, symtab);
obstack_init (&types_cu_list);
make_cleanup_obstack_free (&types_cu_list);
- psyms_seen = htab_create_alloc (100, htab_hash_pointer, htab_eq_pointer,
- NULL, xcalloc, xfree);
- make_cleanup_htab_delete (psyms_seen);
+ htab_up psyms_seen (htab_create_alloc (100, htab_hash_pointer,
+ htab_eq_pointer,
+ NULL, xcalloc, xfree));
/* While we're scanning CU's create a table that maps a psymtab pointer
(which is what addrmap records) to its index (which is what is recorded
in the index file). This will later be needed to write the address
table. */
- cu_index_htab = htab_create_alloc (100,
- hash_psymtab_cu_index,
- eq_psymtab_cu_index,
- NULL, xcalloc, xfree);
- make_cleanup_htab_delete (cu_index_htab);
+ htab_up cu_index_htab (htab_create_alloc (100,
+ hash_psymtab_cu_index,
+ eq_psymtab_cu_index,
+ NULL, xcalloc, xfree));
psymtab_cu_index_map = XNEWVEC (struct psymtab_cu_index_map,
dwarf2_per_objfile->n_comp_units);
make_cleanup (xfree, psymtab_cu_index_map);
continue;
if (psymtab->user == NULL)
- recursively_write_psymbols (objfile, psymtab, symtab, psyms_seen, i);
+ recursively_write_psymbols (objfile, psymtab, symtab,
+ psyms_seen.get (), i);
map = &psymtab_cu_index_map[i];
map->psymtab = psymtab;
map->cu_index = i;
- slot = htab_find_slot (cu_index_htab, map, INSERT);
+ slot = htab_find_slot (cu_index_htab.get (), map, INSERT);
gdb_assert (slot != NULL);
gdb_assert (*slot == NULL);
*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);
}
/* Dump the address map. */
- write_address_map (objfile, &addr_obstack, cu_index_htab);
+ write_address_map (objfile, &addr_obstack, cu_index_htab.get ());
/* Write out the .debug_type entries, if any. */
if (dwarf2_per_objfile->signatured_types)
sig_data.objfile = objfile;
sig_data.symtab = symtab;
sig_data.types_list = &types_cu_list;
- sig_data.psyms_seen = psyms_seen;
+ sig_data.psyms_seen = psyms_seen.get ();
sig_data.cu_index = dwarf2_per_objfile->n_comp_units;
htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
write_one_signatured_type, &sig_data);
fclose (out_file);
- /* We want to keep the file, so we set cleanup_filename to NULL
- here. See unlink_if_set. */
- cleanup_filename = NULL;
+ /* We want to keep the file. */
+ unlink_file.keep ();
do_cleanups (cleanup);
}
if (stat (objfile_name (objfile), &st) < 0)
continue;
- dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+ dwarf2_per_objfile
+ = (struct dwarf2_per_objfile *) objfile_data (objfile,
+ dwarf2_objfile_data_key);
if (dwarf2_per_objfile)
{