/* 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 "source.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);
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.
- This is in contrast to the low level DIE reading of dwarf2_die_debug. */
-static unsigned int dwarf2_read_debug = 0;
+ This is in contrast to the low level DIE reading of dwarf_die_debug. */
+static unsigned int dwarf_read_debug = 0;
/* When non-zero, dump DIEs after they are read in. */
-static unsigned int dwarf2_die_debug = 0;
+static unsigned int dwarf_die_debug = 0;
+
+/* When non-zero, dump line number entries as they are read in. */
+static unsigned int dwarf_line_debug = 0;
/* When non-zero, cross-check physname against demangler. */
static int check_physname = 0;
union
{
/* If this is a real section, the bfd section. */
- asection *asection;
+ asection *section;
/* If this is a virtual section, pointer to the containing ("real")
section. */
struct dwarf2_section_info *containing_section;
/* True if we have tried to read this section. */
char readin;
/* True if this is a virtual section, False otherwise.
- This specifies which of s.asection and s.containing_section to use. */
+ This specifies which of s.section and s.containing_section to use. */
char is_virtual;
};
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 dwarf2_section_info *section;
/* Set to non-NULL iff this CU is currently loaded. When it gets freed out
- of the CU cache it gets reset to NULL again. */
+ of the CU cache it gets reset to NULL again. This is left as NULL for
+ dummy CUs (a CU header, but nothing else). */
struct dwarf2_cu *cu;
/* The corresponding objfile.
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;
- int included_p; /* Non-zero if referenced by the Line Number Program. */
- struct symtab *symtab; /* The associated symbol table, if any. */
+ 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 {};
};
/* 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
compilation units. Set this to zero to disable caching. Cache
sizes of up to at least twenty will improve startup time for
typical inter-CU-reference binaries, at an obvious memory cost. */
-static int dwarf2_max_cache_age = 5;
+static int dwarf_max_cache_age = 5;
static void
-show_dwarf2_max_cache_age (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
+show_dwarf_max_cache_age (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
{
fprintf_filtered (file, _("The upper bound on the age of cached "
- "dwarf2 compilation units is %s.\n"),
+ "DWARF compilation units is %s.\n"),
value);
}
\f
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 attribute *dwarf2_attr_no_follow (struct die_info *,
unsigned int);
+static const char *dwarf2_string_attr (struct die_info *die, unsigned int name,
+ struct dwarf2_cu *cu);
+
static int dwarf2_flag_true_p (struct die_info *die, unsigned name,
struct dwarf2_cu *cu);
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 void read_module (struct die_info *die, struct dwarf2_cu *cu);
+static struct using_direct **using_directives (enum language);
+
static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
static int read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu);
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 void read_signatured_type (struct signatured_type *);
+static int attr_to_dynamic_prop (const struct attribute *attr,
+ struct die_info *die, struct dwarf2_cu *cu,
+ struct dynamic_prop *prop);
+
/* memory allocation interface */
static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
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. */
struct dwarf2_per_objfile *data
- = obstack_alloc (&objfile->objfile_obstack, sizeof (*data));
+ = XOBNEW (&objfile->objfile_obstack, struct dwarf2_per_objfile);
memset (data, 0, sizeof (*data));
set_objfile_data (objfile, dwarf2_objfile_data_key, data);
dwarf2_per_objfile->objfile = objfile;
}
return (!dwarf2_per_objfile->info.is_virtual
- && dwarf2_per_objfile->info.s.asection != NULL
+ && dwarf2_per_objfile->info.s.section != NULL
&& !dwarf2_per_objfile->abbrev.is_virtual
- && dwarf2_per_objfile->abbrev.s.asection != NULL);
+ && dwarf2_per_objfile->abbrev.s.section != NULL);
}
/* Return the containing section of virtual section SECTION. */
section = get_containing_section (section);
gdb_assert (!section->is_virtual);
}
- return section->s.asection->owner;
+ return section->s.section->owner;
}
/* Return the bfd section of SECTION.
section = get_containing_section (section);
gdb_assert (!section->is_virtual);
}
- return section->s.asection;
+ return section->s.section;
}
/* Return the name of SECTION. */
}
else if (section_is_p (sectp->name, &names->info))
{
- dwarf2_per_objfile->info.s.asection = sectp;
+ dwarf2_per_objfile->info.s.section = sectp;
dwarf2_per_objfile->info.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->abbrev))
{
- dwarf2_per_objfile->abbrev.s.asection = sectp;
+ dwarf2_per_objfile->abbrev.s.section = sectp;
dwarf2_per_objfile->abbrev.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->line))
{
- dwarf2_per_objfile->line.s.asection = sectp;
+ dwarf2_per_objfile->line.s.section = sectp;
dwarf2_per_objfile->line.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->loc))
{
- dwarf2_per_objfile->loc.s.asection = sectp;
+ 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.asection = sectp;
+ dwarf2_per_objfile->macinfo.s.section = sectp;
dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->macro))
{
- dwarf2_per_objfile->macro.s.asection = sectp;
+ dwarf2_per_objfile->macro.s.section = sectp;
dwarf2_per_objfile->macro.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->str))
{
- dwarf2_per_objfile->str.s.asection = 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.asection = sectp;
+ dwarf2_per_objfile->addr.s.section = sectp;
dwarf2_per_objfile->addr.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->frame))
{
- dwarf2_per_objfile->frame.s.asection = sectp;
+ dwarf2_per_objfile->frame.s.section = sectp;
dwarf2_per_objfile->frame.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->eh_frame))
{
- dwarf2_per_objfile->eh_frame.s.asection = sectp;
+ dwarf2_per_objfile->eh_frame.s.section = sectp;
dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->ranges))
{
- dwarf2_per_objfile->ranges.s.asection = 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;
memset (&type_section, 0, sizeof (type_section));
- type_section.s.asection = sectp;
+ type_section.s.section = sectp;
type_section.size = bfd_get_section_size (sectp);
VEC_safe_push (dwarf2_section_info_def, dwarf2_per_objfile->types,
}
else if (section_is_p (sectp->name, &names->gdb_index))
{
- dwarf2_per_objfile->gdb_index.s.asection = sectp;
+ dwarf2_per_objfile->gdb_index.s.section = sectp;
dwarf2_per_objfile->gdb_index.size = bfd_get_section_size (sectp);
}
- if ((bfd_get_section_flags (abfd, sectp) & SEC_LOAD)
+ if ((bfd_get_section_flags (abfd, sectp) & (SEC_LOAD | SEC_ALLOC))
&& bfd_section_vma (abfd, sectp) == 0)
dwarf2_per_objfile->has_section_at_zero = 1;
}
{
if (section->is_virtual)
return section->size == 0;
- return section->s.asection == NULL || section->size == 0;
+ return section->s.section == NULL || section->size == 0;
}
/* Read the contents of the section INFO.
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). */
if (section_is_p (sectp->name, &dwarf2_elf_names.abbrev))
{
- dwz_file->abbrev.s.asection = sectp;
+ dwz_file->abbrev.s.section = sectp;
dwz_file->abbrev.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &dwarf2_elf_names.info))
{
- dwz_file->info.s.asection = sectp;
+ dwz_file->info.s.section = sectp;
dwz_file->info.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &dwarf2_elf_names.str))
{
- dwz_file->str.s.asection = sectp;
+ dwz_file->str.s.section = sectp;
dwz_file->str.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &dwarf2_elf_names.line))
{
- dwz_file->line.s.asection = sectp;
+ dwz_file->line.s.section = sectp;
dwz_file->line.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &dwarf2_elf_names.macro))
{
- dwz_file->macro.s.asection = sectp;
+ dwz_file->macro.s.section = sectp;
dwz_file->macro.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &dwarf2_elf_names.gdb_index))
{
- dwz_file->gdb_index.s.asection = sectp;
+ dwz_file->gdb_index.s.section = sectp;
dwz_file->gdb_index.size = bfd_get_section_size (sectp);
}
}
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)
else
load_full_comp_unit (per_cu, language_minimal);
- gdb_assert (per_cu->cu != NULL);
+ if (per_cu->cu == NULL)
+ return; /* Dummy CU. */
dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
}
that may badly handle TUs, load all the TUs in that DWO as well.
http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */
if (!per_cu->is_debug_types
+ && per_cu->cu != NULL
&& per_cu->cu->dwo_unit != NULL
&& dwarf2_per_objfile->index_table != NULL
&& dwarf2_per_objfile->index_table->version <= 7
if (!per_cu->v.quick->compunit_symtab)
{
struct cleanup *back_to = make_cleanup (free_cached_comp_units, NULL);
- increment_reading_symtab ();
+ scoped_restore decrementer = increment_reading_symtab ();
dw2_do_instantiate_symtab (per_cu);
process_cu_includes ();
do_cleanups (back_to);
for (i = 0; i < n_elements; i += 2)
{
- struct dwarf2_per_cu_data *the_cu;
- ULONGEST offset, length;
-
gdb_static_assert (sizeof (ULONGEST) >= 8);
- offset = extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE);
- length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
+
+ sect_offset sect_off
+ = (sect_offset) extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE);
+ ULONGEST length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
cu_list += 2 * 8;
- the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwarf2_per_cu_data);
- the_cu->offset.sect_off = offset;
+ dwarf2_per_cu_data *the_cu
+ = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwarf2_per_cu_data);
+ the_cu->sect_off = sect_off;
the_cu->length = length;
the_cu->objfile = objfile;
the_cu->section = section;
struct dwz_file *dwz;
dwarf2_per_objfile->n_comp_units = (cu_list_elements + dwz_elements) / 2;
- dwarf2_per_objfile->all_comp_units
- = obstack_alloc (&objfile->objfile_obstack,
- dwarf2_per_objfile->n_comp_units
- * sizeof (struct dwarf2_per_cu_data *));
+ dwarf2_per_objfile->all_comp_units =
+ XOBNEWVEC (&objfile->objfile_obstack, struct dwarf2_per_cu_data *,
+ dwarf2_per_objfile->n_comp_units);
create_cus_from_index_list (objfile, cu_list, cu_list_elements,
&dwarf2_per_objfile->info, 0, 0);
dwarf2_per_objfile->n_type_units
= dwarf2_per_objfile->n_allocated_type_units
= elements / 3;
- dwarf2_per_objfile->all_type_units
- = xmalloc (dwarf2_per_objfile->n_type_units
- * sizeof (struct signatured_type *));
+ dwarf2_per_objfile->all_type_units =
+ XNEWVEC (struct signatured_type *, dwarf2_per_objfile->n_type_units);
sig_types_hash = allocate_signatured_type_table (objfile);
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_fortran
+ || current_language->la_language == language_d)
{
/* NAME is already canonical. Drop any qualifiers as .gdb_index does
not contain any. */
create_addrmap_from_index (objfile, &local_map);
- map = obstack_alloc (&objfile->objfile_obstack, sizeof (struct mapped_index));
+ map = XOBNEW (&objfile->objfile_obstack, struct mapped_index);
*map = local_map;
dwarf2_per_objfile->index_table = map;
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;
}
return;
}
- qfn = obstack_alloc (&objfile->objfile_obstack, sizeof (*qfn));
+ 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->file_names = obstack_alloc (&objfile->objfile_obstack,
- lh->num_file_names * sizeof (char *));
- for (i = 0; i < lh->num_file_names; ++i)
- qfn->file_names[i] = file_full_name (i + 1, lh, comp_dir);
+ qfn->num_file_names = lh->file_names.size ();
+ qfn->file_names =
+ 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. */
while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
{
- struct symbol *sym = NULL;
+ struct symbol *sym, *with_opaque = NULL;
struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu);
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
+ sym = block_find_symbol (block, name, domain,
+ block_find_non_opaque_type_preferred,
+ &with_opaque);
+
/* Some caution must be observed with overloaded functions
and methods, since the index will not contain any overload
information (but NAME might contain it). */
- sym = block_lookup_symbol (block, name, domain);
-
- if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
- {
- if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
- return stab;
- stab_best = stab;
- }
+ if (sym != NULL
+ && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
+ return stab;
+ if (with_opaque != NULL
+ && strcmp_iw (SYMBOL_SEARCH_NAME (with_opaque), name) == 0)
+ stab_best = stab;
/* Keep looking through other CUs. */
}
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. */
struct quick_file_names *file_data;
void **slot;
+ QUIT;
+
per_cu->v.quick->mark = 0;
/* We only need to look at symtabs not already expanded. */
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)
offset_type *vec, vec_len, vec_idx;
int global_seen = 0;
+ QUIT;
+
if (index->symbol_table[idx] == 0 && index->symbol_table[idx + 1] == 0)
continue;
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
subpst->dirname = pst->dirname;
}
- subpst->section_offsets = pst->section_offsets;
subpst->textlow = 0;
subpst->texthigh = 0;
- subpst->dependencies = (struct partial_symtab **)
- obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct partial_symtab *));
+ subpst->dependencies
+ = XOBNEW (&objfile->objfile_obstack, struct partial_symtab *);
subpst->dependencies[0] = pst;
subpst->number_of_dependencies = 1;
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 (dwarf2_read_debug)
- fprintf_unfiltered (gdb_stdlog, "Reading .debug_types%s for %s:\n",
- dwo_file ? ".dwo" : "",
+ if (dwarf_read_debug)
+ 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 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;
- /* 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);
+ sect_offset sect_off = (sect_offset) (ptr - section->buffer);
- /* 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. */
+ /* Initialize it due to a false compiler warning. */
+ header.signature = -1;
+ header.type_cu_offset_in_tu = (cu_offset) -1;
- 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;
+ /* We need to read the type's signature in order to build the hash
+ table, but we don't need anything else just yet. */
- offset.sect_off = ptr - section->buffer;
+ ptr = read_and_check_comp_unit_head (&header, section,
+ abbrev_section, ptr, section_kind);
- /* We need to read the type's signature in order to build the hash
- table, but we don't need anything else just yet. */
+ length = get_cu_length (&header);
- ptr = read_and_check_type_unit_head (&header, section,
- abbrev_section, ptr,
- &signature, &type_offset_in_tu);
+ /* 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;
+ }
- length = get_cu_length (&header);
+ if (types_htab == NULL)
+ {
+ if (dwo_file)
+ types_htab = allocate_dwo_unit_table (objfile);
+ else
+ types_htab = allocate_signatured_type_table (objfile);
+ }
- /* Skip dummy type units. */
- if (ptr >= info_ptr + length
- || peek_abbrev_code (abfd, ptr) == 0)
- {
- info_ptr += length;
- continue;
- }
+ 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;
+ }
- if (types_htab == NULL)
- {
- if (dwo_file)
- types_htab = allocate_dwo_unit_table (objfile);
- else
- types_htab = allocate_signatured_type_table (objfile);
- }
+ 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.
+
+ Note: This function processes DWO files only, not DWP files. */
- if (dwarf2_read_debug > 1)
- fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature %s\n",
- offset.sect_off,
- hex_string (signature));
+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;
- info_ptr += length;
- }
- }
+ if (VEC_empty (dwarf2_section_info_def, types))
+ return;
- return types_htab;
+ 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_type_units
= dwarf2_per_objfile->n_allocated_type_units
= htab_elements (types_htab);
- dwarf2_per_objfile->all_type_units
- = xmalloc (dwarf2_per_objfile->n_type_units
- * sizeof (struct signatured_type *));
+ dwarf2_per_objfile->all_type_units =
+ XNEWVEC (struct signatured_type *, dwarf2_per_objfile->n_type_units);
iter = &dwarf2_per_objfile->all_type_units[0];
htab_traverse_noresize (types_htab, add_signatured_type_cu_to_table, &iter);
gdb_assert (iter - &dwarf2_per_objfile->all_type_units[0]
dwarf2_per_objfile->n_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;
}
}
else if (stub_comp_dir != NULL)
{
/* Reconstruct the comp_dir attribute to simplify the code below. */
- comp_dir = (struct attribute *)
- obstack_alloc (&cu->comp_unit_obstack, sizeof (*comp_dir));
+ comp_dir = XOBNEW (&cu->comp_unit_obstack, struct attribute);
comp_dir->name = DW_AT_comp_dir;
comp_dir->form = DW_FORM_string;
DW_STRING_IS_CANONICAL (comp_dir) = 0;
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);
comp_unit_die->attrs[i++] = *comp_dir;
comp_unit_die->num_attrs += num_extra_attrs;
- if (dwarf2_die_debug)
+ if (dwarf_die_debug)
{
fprintf_unfiltered (gdb_stdlog,
"Read die from %s@0x%x of %s:\n",
get_section_name (section),
(unsigned) (begin_info_ptr - section->buffer),
bfd_get_filename (abfd));
- dump_die (comp_unit_die, dwarf2_die_debug);
+ dump_die (comp_unit_die, dwarf_die_debug);
}
/* Save the comp_dir attribute. If there is no DWP file then we'll read
gdb_assert (cu != NULL);
/* Yeah, we look dwo_name up again, but it simplifies the code. */
- attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu);
- gdb_assert (attr != NULL);
- dwo_name = DW_STRING (attr);
- comp_dir = NULL;
- attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
- if (attr)
- comp_dir = DW_STRING (attr);
+ dwo_name = dwarf2_string_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu);
+ comp_dir = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
if (this_cu->is_debug_types)
{
{
/* If !use_existing_cu, this_cu->cu must be NULL. */
gdb_assert (this_cu->cu == NULL);
- cu = xmalloc (sizeof (*cu));
+ cu = XNEW (struct dwarf2_cu);
init_one_comp_unit (cu, this_cu);
/* If an error occurs while loading, release our storage. */
free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu);
before we can reread the DWO file (this only applies to CUs, not TUs). */
int rereading_dwo_cu = 0;
- if (dwarf2_die_debug)
+ 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);
{
/* If !use_existing_cu, this_cu->cu must be NULL. */
gdb_assert (this_cu->cu == NULL);
- cu = xmalloc (sizeof (*cu));
+ cu = XNEW (struct dwarf2_cu);
init_one_comp_unit (cu, this_cu);
/* If an error occurs while loading, release our storage. */
free_cu_cleanup = make_cleanup (free_heap_comp_unit, 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)
struct die_info *comp_unit_die;
int has_children;
- if (dwarf2_die_debug)
+ 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;
struct objfile *objfile = per_cu->objfile;
struct partial_symtab *pst;
- pst = start_psymtab_common (objfile, objfile->section_offsets,
- name, 0,
+ pst = start_psymtab_common (objfile, name, 0,
objfile->global_psymbols.next,
objfile->static_psymbols.next);
struct objfile *objfile = cu->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct dwarf2_per_cu_data *per_cu = cu->per_cu;
- struct attribute *attr;
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;
cu->list_in_scope = &file_symbols;
/* Allocate a new partial symbol table structure. */
- attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
- if (attr == NULL || !DW_STRING (attr))
+ filename = dwarf2_string_attr (comp_unit_die, DW_AT_name, cu);
+ if (filename == NULL)
filename = "";
- else
- filename = DW_STRING (attr);
pst = create_partial_symtab (per_cu, filename);
/* This must be done before calling dwarf2_build_include_psymtabs. */
- attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
- if (attr != NULL)
- pst->dirname = DW_STRING (attr);
+ pst->dirname = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
/* 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;
pst->textlow = gdbarch_adjust_dwarf2_addr (gdbarch, best_lowpc + baseaddr);
pst->texthigh = gdbarch_adjust_dwarf2_addr (gdbarch, best_highpc + baseaddr);
- pst->n_global_syms = objfile->global_psymbols.next -
- (objfile->global_psymbols.list + pst->globals_offset);
- pst->n_static_syms = objfile->static_psymbols.next -
- (objfile->static_psymbols.list + pst->statics_offset);
- sort_pst_symbols (objfile, pst);
+ end_psymtab_common (objfile, pst);
if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs))
{
/* Fill in 'dependencies' here; we fill in 'users' in a
post-pass. */
pst->number_of_dependencies = len;
- pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
- len * sizeof (struct symtab *));
+ pst->dependencies =
+ XOBNEWVEC (&objfile->objfile_obstack, struct partial_symtab *, len);
for (i = 0;
VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
i, iter);
and build a psymtab for each of them. */
dwarf2_build_include_psymtabs (cu, comp_unit_die, pst);
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
struct gdbarch *gdbarch = get_objfile_arch (objfile);
"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);
highpc = (CORE_ADDR) 0;
scan_partial_symbols (first_die, &lowpc, &highpc, 0, cu);
- pst->n_global_syms = objfile->global_psymbols.next -
- (objfile->global_psymbols.list + pst->globals_offset);
- pst->n_static_syms = objfile->static_psymbols.next -
- (objfile->static_psymbols.list + pst->statics_offset);
- sort_pst_symbols (objfile, pst);
+ end_psymtab_common (objfile, pst);
}
/* Struct used to sort TUs by their abbreviation table offset. */
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. */
[IWBN if DWO skeletons had DW_AT_stmt_list]
call FUNC */
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, "Building type unit groups ...\n");
/* Sort in a separate table to maintain the order of all_type_units
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)
{
gdb_assert (IS_TYPE_UNIT_GROUP (per_cu));
pst->number_of_dependencies = len;
- pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
- len * sizeof (struct psymtab *));
+ pst->dependencies =
+ XOBNEWVEC (&objfile->objfile_obstack, struct partial_symtab *, len);
for (i = 0;
VEC_iterate (sig_type_ptr, tu_group->tus, i, iter);
++i)
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;
}
struct obstack temp_obstack;
int i;
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "Building psymtabs of objfile %s ...\n",
objfile_name (objfile));
build_type_psymtab_dependencies, NULL);
}
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
print_tu_stats ();
set_partial_user (objfile);
do_cleanups (back_to);
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, "Done building psymtabs of %s\n",
objfile_name (objfile));
}
const gdb_byte *info_ptr;
bfd *abfd = get_section_bfd_owner (section);
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, "Reading %s for %s\n",
get_section_name (section),
get_section_file_name (section));
{
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. */
length = read_initial_length (abfd, info_ptr, &initial_length_size);
/* Save the compilation unit for later lookup. */
- this_cu = obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct dwarf2_per_cu_data));
+ 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;
n_comp_units = 0;
n_allocated = 10;
- all_comp_units = xmalloc (n_allocated
- * sizeof (struct dwarf2_per_cu_data *));
+ all_comp_units = XNEWVEC (struct dwarf2_per_cu_data *, n_allocated);
read_comp_units_from_section (objfile, &dwarf2_per_objfile->info, 0,
&n_allocated, &n_comp_units, &all_comp_units);
&n_allocated, &n_comp_units,
&all_comp_units);
- dwarf2_per_objfile->all_comp_units
- = obstack_alloc (&objfile->objfile_obstack,
- n_comp_units * sizeof (struct dwarf2_per_cu_data *));
+ dwarf2_per_objfile->all_comp_units = XOBNEWVEC (&objfile->objfile_obstack,
+ struct dwarf2_per_cu_data *,
+ n_comp_units);
memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units,
n_comp_units * sizeof (struct dwarf2_per_cu_data *));
xfree (all_comp_units);
{
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,
&objfile->global_psymbols,
- 0, addr, cu->language, objfile);
+ addr, cu->language, objfile);
}
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,
- 0, addr, cu->language, objfile);
+ 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:
{
list = &objfile->static_psymbols;
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC,
- list, 0, 0, cu->language, objfile);
+ list, 0, cu->language, objfile);
}
break;
case DW_TAG_variable:
built_actual_name != NULL,
VAR_DOMAIN, LOC_STATIC,
&objfile->global_psymbols,
- 0, addr + baseaddr,
+ addr + baseaddr,
cu->language, objfile);
}
else
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,
&objfile->static_psymbols,
- 0,
has_loc ? addr + baseaddr : (CORE_ADDR) 0,
cu->language, objfile);
}
built_actual_name != NULL,
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
- 0, (CORE_ADDR) 0, cu->language, objfile);
+ 0, cu->language, objfile);
break;
case DW_TAG_imported_declaration:
case DW_TAG_namespace:
built_actual_name != NULL,
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->global_psymbols,
- 0, (CORE_ADDR) 0, cu->language, objfile);
+ 0, cu->language, objfile);
break;
case DW_TAG_module:
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
MODULE_DOMAIN, LOC_TYPEDEF,
&objfile->global_psymbols,
- 0, (CORE_ADDR) 0, cu->language, objfile);
+ 0, cu->language, objfile);
break;
case DW_TAG_class_type:
case DW_TAG_interface_type:
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, (CORE_ADDR) 0, cu->language, objfile);
+ 0, cu->language, objfile);
break;
case DW_TAG_enumerator:
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
VAR_DOMAIN, LOC_CONST,
- (cu->language == language_cplus
- || cu->language == language_java)
+ cu->language == language_cplus
? &objfile->global_psymbols
: &objfile->static_psymbols,
- 0, (CORE_ADDR) 0, cu->language, objfile);
+ 0, cu->language, objfile);
break;
default:
break;
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;
struct dwarf2_queue_item *item;
per_cu->queued = 1;
- item = xmalloc (sizeof (*item));
+ item = XNEW (struct dwarf2_queue_item);
item->per_cu = per_cu;
item->pretend_language = pretend_language;
item->next = NULL;
{
struct dwarf2_queue_item *item, *next_item;
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog,
"Expanding one or more symtabs of objfile %s ...\n",
may load a new CU, adding it to the end of the queue. */
for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item)
{
- if (dwarf2_per_objfile->using_index
- ? !item->per_cu->v.quick->compunit_symtab
- : (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin))
+ if ((dwarf2_per_objfile->using_index
+ ? !item->per_cu->v.quick->compunit_symtab
+ : (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin))
+ /* Skip dummy CUs. */
+ && item->per_cu->cu != NULL)
{
struct dwarf2_per_cu_data *per_cu = item->per_cu;
unsigned int debug_print_threshold;
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;
}
- if (dwarf2_read_debug >= debug_print_threshold)
+ if (dwarf_read_debug >= debug_print_threshold)
fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
if (per_cu->is_debug_types)
else
process_full_comp_unit (per_cu, item->pretend_language);
- if (dwarf2_read_debug >= debug_print_threshold)
+ if (dwarf_read_debug >= debug_print_threshold)
fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
}
dwarf2_queue_tail = NULL;
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "Done expanding symtabs of %s.\n",
objfile_name (dwarf2_per_objfile->objfile));
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);
/* Now we have a transitive closure of all the included symtabs. */
len = VEC_length (compunit_symtab_ptr, result_symtabs);
cust->includes
- = obstack_alloc (&dwarf2_per_objfile->objfile->objfile_obstack,
- (len + 1) * sizeof (struct symtab *));
+ = XOBNEWVEC (&dwarf2_per_objfile->objfile->objfile_obstack,
+ struct compunit_symtab *, len + 1);
for (ix = 0;
VEC_iterate (compunit_symtab_ptr, result_symtabs, ix,
compunit_symtab_iter);
compilation is from a C file generated by language preprocessors, do
not set the language if it was already deduced by start_subfile. */
if (!(cu->language == language_c
- && COMPUNIT_FILETABS (cust)->language != language_c))
+ && COMPUNIT_FILETABS (cust)->language != language_unknown))
COMPUNIT_FILETABS (cust)->language = cu->language;
/* GCC-4.0 has started to support -fvar-tracking. GCC-3.x still can
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;
case DW_TAG_enumeration_type:
case DW_TAG_enumerator:
case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
case DW_TAG_member:
case DW_TAG_imported_declaration:
return 1;
}
}
-/* 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. */
- struct attribute *attr;
+ const char *linkage_name;
- attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
- if (attr == NULL)
- attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
- if (attr && DW_STRING (attr))
- return DW_STRING (attr);
+ 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_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;
back_to = make_cleanup (null_cleanup, NULL);
- attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
- if (!attr)
- attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
+ mangled = dwarf2_string_attr (die, DW_AT_linkage_name, cu);
+ 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 (attr && DW_STRING (attr))
+ if (mangled != NULL)
{
char *demangled;
- mangled = DW_STRING (attr);
-
/* Use DMGL_RET_DROP for C++ template functions to suppress their return
type. It is easier for GDB users to search for such functions as
`name(params)' than `long name(params)'. In such case the minimal
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
return 0;
}
+/* Return the using directives repository (global or local?) to use in the
+ current context for LANGUAGE.
+
+ For Ada, imported declarations can materialize renamings, which *may* be
+ global. However it is impossible (for now?) in DWARF to distinguish
+ "external" imported declarations and "static" ones. As all imported
+ declarations seem to be static in all other languages, make them all CU-wide
+ global only in Ada. */
+
+static struct using_direct **
+using_directives (enum language language)
+{
+ if (language == language_ada && context_stack_depth == 0)
+ return &global_using_directives;
+ else
+ return &local_using_directives;
+}
+
/* Read the import statement specified by the given die and record it. */
static void
}
else if (strlen (imported_name_prefix) > 0)
canonical_name = obconcat (&objfile->objfile_obstack,
- imported_name_prefix, "::", imported_name,
- (char *) NULL);
+ imported_name_prefix,
+ (cu->language == language_d ? "." : "::"),
+ imported_name, (char *) NULL);
else
canonical_name = imported_name;
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;
}
process_die (child_die, cu);
}
- cp_add_using_directive (import_prefix,
- canonical_name,
- import_alias,
- imported_declaration,
- excludes,
- 0,
- &objfile->objfile_obstack);
+ add_using_directive (using_directives (cu->language),
+ import_prefix,
+ canonical_name,
+ import_alias,
+ imported_declaration,
+ excludes,
+ 0,
+ &objfile->objfile_obstack);
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)
{
- struct attribute *attr;
-
- *name = NULL;
- *comp_dir = NULL;
+ file_and_directory res;
/* Find the filename. Do not use dwarf2_name here, since the filename
is not a source language identifier. */
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr)
- {
- *name = DW_STRING (attr);
- }
+ res.name = dwarf2_string_attr (die, DW_AT_name, cu);
+ res.comp_dir = dwarf2_string_attr (die, DW_AT_comp_dir, cu);
- attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
- if (attr)
- *comp_dir = DW_STRING (attr);
- else if (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. */
- for (i = 0; i < lh->num_file_names; ++i)
+ tu_group->num_symtabs = lh->file_names.size ();
+ tu_group->symtabs = XNEWVEC (struct symtab *, lh->file_names.size ());
+
+ 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)
- 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 (dwarf2_read_debug)
+ 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 (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
get_section_name (section),
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,
if (section_is_p (sectp->name, &names->abbrev_dwo))
{
/* There can be only one. */
- if (sections->abbrev.s.asection != NULL)
+ if (sections->abbrev.s.section != NULL)
return 0;
- sections->abbrev.s.asection = sectp;
+ sections->abbrev.s.section = sectp;
sections->abbrev.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->info_dwo)
|| section_is_p (sectp->name, &names->types_dwo))
{
/* There can be only one. */
- if (sections->info_or_types.s.asection != NULL)
+ if (sections->info_or_types.s.section != NULL)
return 0;
- sections->info_or_types.s.asection = sectp;
+ sections->info_or_types.s.section = sectp;
sections->info_or_types.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->line_dwo))
{
/* There can be only one. */
- if (sections->line.s.asection != NULL)
+ if (sections->line.s.section != NULL)
return 0;
- sections->line.s.asection = sectp;
+ sections->line.s.section = sectp;
sections->line.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->loc_dwo))
{
/* There can be only one. */
- if (sections->loc.s.asection != NULL)
+ if (sections->loc.s.section != NULL)
return 0;
- sections->loc.s.asection = sectp;
+ sections->loc.s.section = sectp;
sections->loc.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->macinfo_dwo))
{
/* There can be only one. */
- if (sections->macinfo.s.asection != NULL)
+ if (sections->macinfo.s.section != NULL)
return 0;
- sections->macinfo.s.asection = sectp;
+ sections->macinfo.s.section = sectp;
sections->macinfo.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->macro_dwo))
{
/* There can be only one. */
- if (sections->macro.s.asection != NULL)
+ if (sections->macro.s.section != NULL)
return 0;
- sections->macro.s.asection = sectp;
+ sections->macro.s.section = sectp;
sections->macro.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->str_offsets_dwo))
{
/* There can be only one. */
- if (sections->str_offsets.s.asection != NULL)
+ if (sections->str_offsets.s.section != NULL)
return 0;
- sections->str_offsets.s.asection = sectp;
+ sections->str_offsets.s.section = sectp;
sections->str_offsets.size = bfd_get_section_size (sectp);
}
else
struct virtual_v1_dwo_sections sections;
void **dwo_file_slot;
char *virtual_dwo_name;
- struct dwarf2_section_info *cutu;
struct cleanup *cleanups;
int i;
gdb_assert (dwp_file->version == 1);
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "Reading %s %s/%s in DWP V1 file: %s\n",
kind,
/* Create one if necessary. */
if (*dwo_file_slot == NULL)
{
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
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;
}
else
{
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
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);
dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = signature;
- dwo_unit->section = obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct dwarf2_section_info));
+ dwo_unit->section =
+ XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
*dwo_unit->section = sections.info_or_types;
/* dwo_unit->{offset,length,type_offset_in_tu} are set later. */
struct virtual_v2_dwo_sections sections;
void **dwo_file_slot;
char *virtual_dwo_name;
- struct dwarf2_section_info *cutu;
struct cleanup *cleanups;
int i;
gdb_assert (dwp_file->version == 2);
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "Reading %s %s/%s in DWP V2 file: %s\n",
kind,
/* Create one if necessary. */
if (*dwo_file_slot == NULL)
{
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
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,
}
else
{
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
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);
dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = signature;
- dwo_unit->section = obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct dwarf2_section_info));
+ dwo_unit->section =
+ XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
*dwo_unit->section = create_dwp_v2_section (is_debug_types
? &dwp_file->sections.types
: &dwp_file->sections.info,
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))
{
- dwo_sections->abbrev.s.asection = sectp;
+ dwo_sections->abbrev.s.section = sectp;
dwo_sections->abbrev.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->info_dwo))
{
- dwo_sections->info.s.asection = sectp;
+ dwo_sections->info.s.section = sectp;
dwo_sections->info.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->line_dwo))
{
- dwo_sections->line.s.asection = sectp;
+ dwo_sections->line.s.section = sectp;
dwo_sections->line.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->loc_dwo))
{
- dwo_sections->loc.s.asection = sectp;
+ dwo_sections->loc.s.section = sectp;
dwo_sections->loc.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->macinfo_dwo))
{
- dwo_sections->macinfo.s.asection = sectp;
+ dwo_sections->macinfo.s.section = sectp;
dwo_sections->macinfo.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->macro_dwo))
{
- dwo_sections->macro.s.asection = sectp;
+ dwo_sections->macro.s.section = sectp;
dwo_sections->macro.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->str_dwo))
{
- dwo_sections->str.s.asection = sectp;
+ dwo_sections->str.s.section = sectp;
dwo_sections->str.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->str_offsets_dwo))
{
- dwo_sections->str_offsets.s.asection = sectp;
+ dwo_sections->str_offsets.s.section = sectp;
dwo_sections->str_offsets.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->types_dwo))
struct dwarf2_section_info type_section;
memset (&type_section, 0, sizeof (type_section));
- type_section.s.asection = sectp;
+ type_section.s.section = sectp;
type_section.size = bfd_get_section_size (sectp);
VEC_safe_push (dwarf2_section_info_def, dwo_sections->types,
&type_section);
{
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 (dwarf2_read_debug)
+ if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, "DWO file not found: %s\n", dwo_name);
return NULL;
}
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);
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, "DWO file found: %s\n", dwo_name);
return dwo_file;
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;
/* Look for specific sections that we need. */
if (section_is_p (sectp->name, &names->str_dwo))
{
- dwp_file->sections.str.s.asection = sectp;
+ dwp_file->sections.str.s.section = sectp;
dwp_file->sections.str.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->cu_index))
{
- dwp_file->sections.cu_index.s.asection = sectp;
+ dwp_file->sections.cu_index.s.section = sectp;
dwp_file->sections.cu_index.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->tu_index))
{
- dwp_file->sections.tu_index.s.asection = sectp;
+ dwp_file->sections.tu_index.s.section = sectp;
dwp_file->sections.tu_index.size = bfd_get_section_size (sectp);
}
}
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;
/* Look for specific sections that we need. */
if (section_is_p (sectp->name, &names->abbrev_dwo))
{
- dwp_file->sections.abbrev.s.asection = sectp;
+ dwp_file->sections.abbrev.s.section = sectp;
dwp_file->sections.abbrev.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->info_dwo))
{
- dwp_file->sections.info.s.asection = sectp;
+ dwp_file->sections.info.s.section = sectp;
dwp_file->sections.info.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->line_dwo))
{
- dwp_file->sections.line.s.asection = sectp;
+ dwp_file->sections.line.s.section = sectp;
dwp_file->sections.line.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->loc_dwo))
{
- dwp_file->sections.loc.s.asection = sectp;
+ dwp_file->sections.loc.s.section = sectp;
dwp_file->sections.loc.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->macinfo_dwo))
{
- dwp_file->sections.macinfo.s.asection = sectp;
+ dwp_file->sections.macinfo.s.section = sectp;
dwp_file->sections.macinfo.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->macro_dwo))
{
- dwp_file->sections.macro.s.asection = sectp;
+ dwp_file->sections.macro.s.section = sectp;
dwp_file->sections.macro.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->str_offsets_dwo))
{
- dwp_file->sections.str_offsets.s.asection = sectp;
+ dwp_file->sections.str_offsets.s.section = sectp;
dwp_file->sections.str_offsets.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->types_dwo))
{
- dwp_file->sections.types.s.asection = sectp;
+ dwp_file->sections.types.s.section = sectp;
dwp_file->sections.types.size = bfd_get_section_size (sectp);
}
}
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 (dwarf2_read_debug)
- fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name);
- do_cleanups (cleanups);
+ if (dwarf_read_debug)
+ 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);
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "DWP file found: %s\n", dwp_file->name);
fprintf_unfiltered (gdb_stdlog,
if (dwo_cutu != NULL)
{
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog,
"Virtual DWO %s %s found: @%s\n",
*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)
{
if (dwo_cutu != NULL)
{
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "DWO %s %s(%s) found: @%s\n",
kind, dwo_name, hex_string (signature),
someone deleted the DWO/DWP file, or the search path isn't set up
correctly to find the file. */
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "DWO %s %s(%s) not found\n",
kind, dwo_name, hex_string (signature));
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;
child_die = sibling_die (child_die);
die_children_count++;
}
- offsets = xmalloc (sizeof (*offsets) * die_children_count);
+ offsets = XNEWVEC (sect_offset, die_children_count);
cleanups = make_cleanup (xfree, offsets);
offsets_end = offsets;
- child_die = die->child;
- while (child_die && child_die->tag)
+ for (child_die = die->child;
+ child_die && child_die->tag;
+ child_die = sibling_die (child_die))
{
+ struct die_info *child_origin_die;
+ struct dwarf2_cu *child_origin_cu;
+
+ /* We are trying to process concrete instance entries:
+ 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_call_site
+ || child_die->tag == DW_TAG_GNU_call_site)
+ continue;
+
/* For each CHILD_DIE, find the corresponding child of
ORIGIN_DIE. If there is more than one layer of
DW_AT_abstract_origin, follow them all; there shouldn't be,
but GCC versions at least through 4.4 generate this (GCC PR
40573). */
- struct die_info *child_origin_die = child_die;
- struct dwarf2_cu *child_origin_cu = cu;
-
+ child_origin_die = child_die;
+ child_origin_cu = cu;
while (1)
{
attr = dwarf2_attr (child_origin_die, DW_AT_abstract_origin,
&& 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;
}
- child_die = sibling_die (child_die);
}
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;
}
if (attr)
dwarf2_symbol_mark_computed (attr, newobj->name, cu, 1);
+ /* If there is a location for the static link, record it. */
+ newobj->static_link = NULL;
+ attr = dwarf2_attr (die, DW_AT_static_link, cu);
+ if (attr)
+ {
+ newobj->static_link
+ = XOBNEW (&objfile->objfile_obstack, struct dynamic_prop);
+ attr_to_dynamic_prop (attr, die, cu, newobj->static_link);
+ }
+
cu->list_in_scope = &local_symbols;
if (die->child != NULL)
newobj = pop_context ();
/* Make a block for the local symbols within. */
block = finish_block (newobj->name, &local_symbols, newobj->old_blocks,
- lowpc, highpc);
+ newobj->static_link, lowpc, highpc);
/* For C++, set the block's scope. */
- if ((cu->language == language_cplus || cu->language == language_fortran)
+ if ((cu->language == language_cplus
+ || cu->language == language_fortran
+ || cu->language == language_d
+ || cu->language == language_rust)
&& cu->processing_has_namespace_info)
block_set_scope (block, determine_prefix (die, cu),
&objfile->objfile_obstack);
templ_func->n_template_arguments = VEC_length (symbolp, template_args);
templ_func->template_arguments
- = obstack_alloc (&objfile->objfile_obstack,
- (templ_func->n_template_arguments
- * sizeof (struct symbol *)));
+ = XOBNEWVEC (&objfile->objfile_obstack, struct symbol *,
+ templ_func->n_template_arguments);
memcpy (templ_func->template_arguments,
VEC_address (symbolp, template_args),
(templ_func->n_template_arguments * sizeof (struct symbol *)));
when we finish processing a function scope, we may need to go
back to building a containing block's symbol lists. */
local_symbols = newobj->locals;
- using_directives = newobj->using_directives;
+ local_using_directives = newobj->local_using_directives;
/* If we've finished processing a top-level function, subsequent
symbols go in the file symbol list. */
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);
child_die = sibling_die (child_die);
}
}
+ inherit_abstract_dies (die, cu);
newobj = pop_context ();
- if (local_symbols != NULL || using_directives != NULL)
+ if (local_symbols != NULL || local_using_directives != NULL)
{
struct block *block
- = finish_block (0, &local_symbols, newobj->old_blocks,
+ = finish_block (0, &local_symbols, newobj->old_blocks, NULL,
newobj->start_addr, highpc);
/* Note that recording ranges after traversing children, as we
dwarf2_record_block_ranges (die, block, baseaddr, cu);
}
local_symbols = newobj->locals;
- using_directives = newobj->using_directives;
+ 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. */;
{
struct dwarf2_locexpr_baton *dlbaton;
- dlbaton = obstack_alloc (&objfile->objfile_obstack, sizeof (*dlbaton));
+ dlbaton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
dlbaton->data = DW_BLOCK (attr)->data;
dlbaton->size = DW_BLOCK (attr)->size;
dlbaton->per_cu = cu->per_cu;
gdb_assert (target_cu->objfile == objfile);
if (die_is_declaration (target_die, target_cu))
{
- const char *target_physname = NULL;
- struct attribute *target_attr;
+ const char *target_physname;
/* Prefer the mangled name; otherwise compute the demangled one. */
- target_attr = dwarf2_attr (target_die, DW_AT_linkage_name, target_cu);
- if (target_attr == NULL)
- target_attr = dwarf2_attr (target_die, DW_AT_MIPS_linkage_name,
- target_cu);
- if (target_attr != NULL && DW_STRING (target_attr) != NULL)
- target_physname = DW_STRING (target_attr);
- else
+ target_physname = dwarf2_string_attr (target_die,
+ DW_AT_linkage_name,
+ target_cu);
+ if (target_physname == NULL)
+ target_physname = dwarf2_string_attr (target_die,
+ DW_AT_MIPS_linkage_name,
+ target_cu);
+ if (target_physname == NULL)
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;
- }
- buffer = dwarf2_per_objfile->ranges.buffer + offset;
-
- /* Read in the largest possible address. */
- marker = read_address (obfd, buffer, cu, &dummy);
- if ((marker & mask) == mask)
- {
- /* 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;
+ return false;
}
-
- low_set = 0;
+ buffer = dwarf2_per_objfile->rnglists.buffer + offset;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
while (1)
{
- CORE_ADDR range_beginning, range_end;
-
- range_beginning = read_address (obfd, buffer, cu, &dummy);
- buffer += addr_size;
- range_end = read_address (obfd, buffer, cu, &dummy);
- buffer += addr_size;
- offset += 2 * addr_size;
-
- /* An end of list marker is a pair of zero addresses. */
- if (range_beginning == 0 && range_end == 0)
- /* Found the end of list entry. */
- break;
+ /* 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;
- /* Each base address selection entry is a pair of 2 values.
- The first is the largest possible address, the second is
- the base address. Check for a base address here. */
- if ((range_beginning & mask) == mask)
+ if (buffer == buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ const auto rlet = static_cast<enum dwarf_range_list_entry>(*buffer++);
+ switch (rlet)
{
- /* If we found the largest possible address, then
- read the base address. */
- base = read_address (obfd, buffer + addr_size, cu, &dummy);
+ 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;
- continue;
+ 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_ranges data (no base address)"));
- return 0;
+ _("Invalid .debug_rnglists data (no base address)"));
+ return false;
}
if (range_beginning > range_end)
{
/* Inverted range entries are invalid. */
complaint (&symfile_complaints,
- _("Invalid .debug_ranges data (inverted range)"));
- return 0;
+ _("Invalid .debug_rnglists data (inverted range)"));
+ return false;
}
/* Empty range entries have no effect. */
&& !dwarf2_per_objfile->has_section_at_zero)
{
complaint (&symfile_complaints,
- _(".debug_ranges entry has start address of zero"
+ _(".debug_rnglists entry has start address of zero"
" [in module %s]"), objfile_name (objfile));
continue;
}
- if (ranges_pst != NULL)
- {
- CORE_ADDR lowpc;
- CORE_ADDR highpc;
-
- lowpc = gdbarch_adjust_dwarf2_addr (gdbarch,
- range_beginning + baseaddr);
- highpc = gdbarch_adjust_dwarf2_addr (gdbarch,
- range_end + baseaddr);
- addrmap_set_empty (objfile->psymtabs_addrmap, lowpc, highpc - 1,
- ranges_pst);
- }
-
- /* FIXME: This is recording everything as a low-high
- segment of consecutive addresses. We should have a
- data structure for discontiguous block ranges
- instead. */
- if (! low_set)
- {
- low = range_beginning;
- high = range_end;
- low_set = 1;
- }
- else
- {
- if (range_beginning < low)
- low = range_beginning;
- if (range_end > high)
- high = range_end;
- }
+ callback (range_beginning, range_end);
}
- if (! low_set)
- /* If the first entry is an end-of-list marker, the range
- describes an empty scope, i.e. no instructions. */
- return 0;
+ if (overflow)
+ {
+ complaint (&symfile_complaints,
+ _("Offset %d is not terminated "
+ "for DW_AT_ranges attribute"),
+ offset);
+ return false;
+ }
- if (low_return)
- *low_return = low;
- if (high_return)
- *high_return = high;
- return 1;
+ return true;
}
-/* 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. */
+/* 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_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
- CORE_ADDR *highpc, struct dwarf2_cu *cu,
- struct partial_symtab *pst)
+dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
+ Callback &&callback)
{
- struct attribute *attr;
+ 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));
+
+ while (1)
+ {
+ CORE_ADDR range_beginning, range_end;
+
+ range_beginning = read_address (obfd, buffer, cu, &dummy);
+ buffer += addr_size;
+ range_end = read_address (obfd, buffer, cu, &dummy);
+ buffer += addr_size;
+ offset += 2 * addr_size;
+
+ /* An end of list marker is a pair of zero addresses. */
+ if (range_beginning == 0 && range_end == 0)
+ /* Found the end of list entry. */
+ break;
+
+ /* Each base address selection entry is a pair of 2 values.
+ The first is the largest possible address, the second is
+ the base address. Check for a base address here. */
+ if ((range_beginning & mask) == mask)
+ {
+ /* If we found the largest possible address, then we already
+ have the base address in range_end. */
+ base = range_end;
+ found_base = 1;
+ continue;
+ }
+
+ if (!found_base)
+ {
+ /* We have no valid base address for the ranges
+ data. */
+ complaint (&symfile_complaints,
+ _("Invalid .debug_ranges data (no base address)"));
+ return 0;
+ }
+
+ if (range_beginning > range_end)
+ {
+ /* Inverted range entries are invalid. */
+ complaint (&symfile_complaints,
+ _("Invalid .debug_ranges data (inverted range)"));
+ return 0;
+ }
+
+ /* 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_ranges entry has start address of zero"
+ " [in module %s]"), objfile_name (objfile));
+ 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;
+ CORE_ADDR highpc;
+
+ lowpc = gdbarch_adjust_dwarf2_addr (gdbarch,
+ range_beginning + baseaddr);
+ highpc = gdbarch_adjust_dwarf2_addr (gdbarch,
+ range_end + baseaddr);
+ addrmap_set_empty (objfile->psymtabs_addrmap, lowpc, highpc - 1,
+ ranges_pst);
+ }
+
+ /* FIXME: This is recording everything as a low-high
+ segment of consecutive addresses. We should have a
+ data structure for discontiguous block ranges
+ instead. */
+ if (! low_set)
+ {
+ low = range_beginning;
+ high = range_end;
+ low_set = 1;
+ }
+ else
+ {
+ if (range_beginning < low)
+ low = range_beginning;
+ 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
+ describes an empty scope, i.e. no instructions. */
+ return 0;
+
+ if (low_return)
+ *low_return = low;
+ if (high_return)
+ *high_return = high;
+ return 1;
+}
+
+/* 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 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;
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)
const char *fieldname = "";
/* Allocate a new field list entry and link it in. */
- new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield));
+ new_field = XNEW (struct nextfield);
make_cleanup (xfree, new_field);
memset (new_field, 0, sizeof (struct nextfield));
- 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 = xzalloc (sizeof (*new_field));
+ new_field = XCNEW (struct typedef_field_list);
make_cleanup (xfree, new_field);
gdb_assert (die->tag == DW_TAG_typedef);
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;
/* Create a new member function field and chain it to the field list
entry. */
- new_fnfield = (struct nextfnfield *) xmalloc (sizeof (struct nextfnfield));
+ new_fnfield = XNEW (struct nextfnfield);
make_cleanup (xfree, new_fnfield);
memset (new_fnfield, 0, sizeof (struct nextfnfield));
new_fnfield->next = flp->head;
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);
/* Get accessibility. */
attr = dwarf2_attr (die, DW_AT_accessibility, cu);
if (attr)
- accessibility = DW_UNSND (attr);
+ accessibility = (enum dwarf_access_attribute) DW_UNSND (attr);
else
accessibility = dwarf2_default_access_attribute (die, cu);
switch (accessibility)
&& 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_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)
{
TYPE_N_TEMPLATE_ARGUMENTS (type)
= VEC_length (symbolp, template_args);
TYPE_TEMPLATE_ARGUMENTS (type)
- = obstack_alloc (&objfile->objfile_obstack,
- (TYPE_N_TEMPLATE_ARGUMENTS (type)
- * sizeof (struct symbol *)));
+ = XOBNEWVEC (&objfile->objfile_obstack,
+ struct symbol *,
+ TYPE_N_TEMPLATE_ARGUMENTS (type));
memcpy (TYPE_TEMPLATE_ARGUMENTS (type),
VEC_address (symbolp, template_args),
(TYPE_N_TEMPLATE_ARGUMENTS (type)
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;
}
attr = dwarf2_attr (die, DW_AT_ordering, cu);
- if (attr) return DW_SND (attr);
+ if (attr)
+ return (enum dwarf_array_dim_ordering) DW_SND (attr);
/* GNU F77 is a special case, as at 08/2004 array type info is the
opposite order to the dwarf2 specification, but data is still
gdb_assert (attr_form_is_block (member_loc)
|| attr_form_is_constant (member_loc));
- baton = obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct dwarf2_locexpr_baton));
+ baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
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);
}
-/* Read a C++ namespace. */
+/* Read a namespace scope. */
static void
read_namespace (struct die_info *die, struct dwarf2_cu *cu)
{
const char *previous_prefix = determine_prefix (die, cu);
- cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
- NULL, NULL, 0, &objfile->objfile_obstack);
+ add_using_directive (using_directives (cu->language),
+ previous_prefix, TYPE_NAME (type), NULL,
+ NULL, NULL, 0, &objfile->objfile_obstack);
}
}
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);
{
/* We don't use dwarf2_name here so that we can detect the absence
of a name -> anonymous namespace. */
- struct attribute *attr = dwarf2_attr (die, DW_AT_name, cu);
+ name = dwarf2_string_attr (die, DW_AT_name, cu);
- if (attr != NULL)
- name = DW_STRING (attr);
if (name != NULL)
break;
}
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. */
+ {
+ gdbarch *arch = get_objfile_arch (objfile);
+
+ if (bits == 16)
+ type = builtin_type (arch)->builtin_char16;
+ else if (bits == 32)
+ type = builtin_type (arch)->builtin_char32;
+ else
+ {
+ complaint (&symfile_complaints,
+ _("unsupported DW_ATE_UTF bit size: '%d'"),
+ bits);
+ type = init_integer_type (objfile, bits, 1, name);
+ }
+ return set_die_type (die, type, cu);
+ }
break;
default:
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;
if (attr_form_is_block (attr))
{
- baton = obstack_alloc (obstack, sizeof (*baton));
+ baton = XOBNEW (obstack, struct dwarf2_property_baton);
baton->referenced_type = NULL;
baton->locexpr.per_cu = cu->per_cu;
baton->locexpr.size = DW_BLOCK (attr)->size;
case DW_AT_location:
if (attr_form_is_section_offset (target_attr))
{
- baton = obstack_alloc (obstack, sizeof (*baton));
+ baton = XOBNEW (obstack, struct dwarf2_property_baton);
baton->referenced_type = die_type (target_die, target_cu);
fill_in_loclist_baton (cu, &baton->loclist, target_attr);
prop->data.baton = baton;
}
else if (attr_form_is_block (target_attr))
{
- baton = obstack_alloc (obstack, sizeof (*baton));
+ baton = XOBNEW (obstack, struct dwarf2_property_baton);
baton->referenced_type = die_type (target_die, target_cu);
baton->locexpr.per_cu = cu->per_cu;
baton->locexpr.size = DW_BLOCK (target_attr)->size;
&offset))
return 0;
- baton = obstack_alloc (obstack, sizeof (*baton));
- baton->referenced_type = get_die_type (target_die->parent,
- target_cu);
+ baton = XOBNEW (obstack, struct dwarf2_property_baton);
+ baton->referenced_type = read_type_die (target_die->parent,
+ target_cu);
baton->offset_info.offset = offset;
baton->offset_info.type = die_type (target_die, target_cu);
prop->data.baton = baton;
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);
struct die_info *die = read_die_and_siblings_1 (reader, info_ptr,
new_info_ptr, parent);
- if (dwarf2_die_debug)
+ if (dwarf_die_debug)
{
fprintf_unfiltered (gdb_stdlog,
"Read die from %s@0x%x of %s:\n",
get_section_name (reader->die_section),
(unsigned) (info_ptr - reader->die_section->buffer),
bfd_get_filename (reader->abfd));
- dump_die (die, dwarf2_die_debug);
+ dump_die (die, dwarf_die_debug);
}
return die;
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;
result = read_full_die_1 (reader, diep, info_ptr, has_children, 0);
- if (dwarf2_die_debug)
+ if (dwarf_die_debug)
{
fprintf_unfiltered (gdb_stdlog,
"Read die from %s@0x%x of %s:\n",
get_section_name (reader->die_section),
(unsigned) (info_ptr - reader->die_section->buffer),
bfd_get_filename (reader->abfd));
- dump_die (*diep, dwarf2_die_debug);
+ dump_die (*diep, dwarf_die_debug);
}
return result;
{
struct abbrev_info *abbrev;
- abbrev = (struct abbrev_info *)
- obstack_alloc (&abbrev_table->abbrev_obstack, sizeof (struct abbrev_info));
+ abbrev = XOBNEW (&abbrev_table->abbrev_obstack, struct abbrev_info);
memset (abbrev, 0, sizeof (struct abbrev_info));
+
return abbrev;
}
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 = obstack_alloc (&abbrev_table->abbrev_obstack,
- (ABBREV_HASH_SIZE
- * sizeof (struct abbrev_info *)));
+ abbrev_table->abbrevs =
+ XOBNEWVEC (&abbrev_table->abbrev_obstack, struct abbrev_info *,
+ ABBREV_HASH_SIZE);
memset (abbrev_table->abbrevs, 0,
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;
allocated_attrs = ATTR_ALLOC_CHUNK;
- cur_attrs = xmalloc (allocated_attrs * sizeof (struct attr_abbrev));
+ cur_attrs = XNEWVEC (struct attr_abbrev, allocated_attrs);
/* Loop until we reach an abbrev number of 0. */
while (abbrev_number)
/* read in abbrev header */
cur_abbrev->number = abbrev_number;
- cur_abbrev->tag = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+ cur_abbrev->tag
+ = (enum dwarf_tag) read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr);
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 = abbrev_name;
- cur_attrs[cur_abbrev->num_attrs++].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].name
+ = (enum dwarf_attribute) abbrev_name;
+ cur_attrs[cur_abbrev->num_attrs].form
+ = (enum dwarf_form) abbrev_form;
+ cur_attrs[cur_abbrev->num_attrs].implicit_const = implicit_const;
+ ++cur_abbrev->num_attrs;
}
- cur_abbrev->attrs = obstack_alloc (&abbrev_table->abbrev_obstack,
- (cur_abbrev->num_attrs
- * sizeof (struct attr_abbrev)));
+ cur_abbrev->attrs =
+ XOBNEWVEC (&abbrev_table->abbrev_obstack, struct attr_abbrev,
+ cur_abbrev->num_attrs);
memcpy (cur_abbrev->attrs, cur_attrs,
cur_abbrev->num_attrs * sizeof (struct attr_abbrev));
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);
hashtab_obstack_allocate,
dummy_obstack_deallocate);
- part_die = obstack_alloc (&cu->comp_unit_obstack,
- sizeof (struct partial_die_info));
+ part_die = XOBNEW (&cu->comp_unit_obstack, struct partial_die_info);
while (1)
{
add_psymbol_to_list (part_die->name, strlen (part_die->name), 0,
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
- 0, (CORE_ADDR) 0, cu->language, objfile);
+ 0, cu->language, objfile);
info_ptr = locate_pdi_sibling (reader, part_die, info_ptr);
continue;
}
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, (CORE_ADDR) 0, cu->language, objfile);
+ 0, cu->language, objfile);
info_ptr = locate_pdi_sibling (reader, part_die, info_ptr);
continue;
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;
}
- part_die = obstack_alloc (&cu->comp_unit_obstack,
- sizeof (struct partial_die_info));
+ part_die = XOBNEW (&cu->comp_unit_obstack, struct partial_die_info);
/* For some DIEs we want to follow their children (if any). For C
we have no reason to follow the children of structures; for other
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;
unsigned int bytes_read;
struct dwarf_block *blk;
- attr->form = form;
+ attr->form = (enum dwarf_form) form;
switch (form)
{
case DW_FORM_ref_addr:
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:
return NULL;
}
+/* Return the string associated with a string-typed attribute, or NULL if it
+ is either not found or is of an incorrect type. */
+
+static const char *
+dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
+{
+ struct attribute *attr;
+ const char *str = NULL;
+
+ attr = dwarf2_attr (die, name, cu);
+
+ if (attr != NULL)
+ {
+ 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), to_underlying (die->sect_off),
+ objfile_name (cu->objfile));
+ }
+
+ return str;
+}
+
/* Return non-zero iff the attribute NAME is defined for the given DIE,
and holds a non-zero value. This function should only be used for
DW_FORM_flag or DW_FORM_flag_present attributes. */
return follow_die_ref (die, spec_attr, spec_cu);
}
-/* Free the line_header structure *LH, and any arrays and strings it
- refers to.
- NOTE: This is also used as a "cleanup" function. */
-
-static void
-free_line_header (struct line_header *lh)
-{
- if (lh->standard_opcode_lengths)
- xfree (lh->standard_opcode_lengths);
-
- /* Remember that all the lh->file_names[i].name pointers are
- pointers into debug_line_buffer, and don't need to be freed. */
- if (lh->file_names)
- xfree (lh->file_names);
-
- /* Similarly for the include directory names. */
- if (lh->include_dirs)
- xfree (lh->include_dirs);
-
- xfree (lh);
-}
-
/* Stub for free_line_header to match void * callback types. */
static void
free_line_header_voidp (void *arg)
{
- struct line_header *lh = arg;
+ struct line_header *lh = (struct line_header *) arg;
- free_line_header (lh);
+ delete lh;
}
-/* Add an entry to LH's include directory table. */
-
-static void
-add_include_dir (struct line_header *lh, const char *include_dir)
+void
+line_header::add_include_dir (const char *include_dir)
{
- /* Grow the array if necessary. */
- if (lh->include_dirs_size == 0)
- {
- lh->include_dirs_size = 1; /* for testing */
- lh->include_dirs = xmalloc (lh->include_dirs_size
- * sizeof (*lh->include_dirs));
- }
- else if (lh->num_include_dirs >= lh->include_dirs_size)
- {
- lh->include_dirs_size *= 2;
- lh->include_dirs = xrealloc (lh->include_dirs,
- (lh->include_dirs_size
- * sizeof (*lh->include_dirs)));
- }
+ if (dwarf_line_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "Adding dir %zu: %s\n",
+ include_dirs.size () + 1, include_dir);
- lh->include_dirs[lh->num_include_dirs++] = include_dir;
+ include_dirs.push_back (include_dir);
}
-/* Add an entry to LH's file name table. */
-
-static void
-add_file_name (struct line_header *lh,
- const char *name,
- unsigned int dir_index,
- unsigned int mod_time,
- unsigned int length)
+void
+line_header::add_file_name (const char *name,
+ dir_index d_index,
+ unsigned int mod_time,
+ unsigned int length)
{
- struct file_entry *fe;
-
- /* Grow the array if necessary. */
- if (lh->file_names_size == 0)
- {
- lh->file_names_size = 1; /* for testing */
- lh->file_names = xmalloc (lh->file_names_size
- * sizeof (*lh->file_names));
- }
- 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)));
- }
+ if (dwarf_line_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "Adding file %u: %s\n",
+ (unsigned) file_names.size () + 1, name);
- fe = &lh->file_names[lh->num_file_names++];
- fe->name = name;
- fe->dir_index = dir_index;
- fe->mod_time = mod_time;
- fe->length = length;
- fe->included_p = 0;
- fe->symtab = NULL;
+ file_names.emplace_back (name, d_index, mod_time, length);
}
-/* A convenience function to find the proper .debug_line section for a
- CU. */
+/* A convenience function to find the proper .debug_line section for a CU. */
static struct dwarf2_section_info *
get_debug_line_section (struct dwarf2_cu *cu)
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++)
+ {
+ read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ read_unsigned_leb128 (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ }
+
+ 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;
+
+ case DW_FORM_line_strp:
+ string.emplace (read_indirect_line_string (abfd, buf,
+ cu_header,
+ &bytes_read));
+ buf += bytes_read;
+ break;
+
+ case DW_FORM_data1:
+ uint.emplace (read_1_byte (abfd, buf));
+ buf += 1;
+ break;
+
+ case DW_FORM_data2:
+ uint.emplace (read_2_bytes (abfd, buf));
+ buf += 2;
+ break;
+
+ case DW_FORM_data4:
+ uint.emplace (read_4_bytes (abfd, buf));
+ buf += 4;
+ break;
+
+ case DW_FORM_data8:
+ uint.emplace (read_8_bytes (abfd, buf));
+ buf += 8;
+ break;
+
+ case DW_FORM_udata:
+ uint.emplace (read_unsigned_leb128 (abfd, buf, &bytes_read));
+ buf += bytes_read;
+ break;
+
+ case DW_FORM_block:
+ /* It is valid only for DW_LNCT_timestamp which is ignored by
+ current GDB. */
+ break;
+ }
+
+ switch (content_type)
+ {
+ case DW_LNCT_path:
+ if (string.has_value ())
+ fe.name = *string;
+ break;
+ case DW_LNCT_directory_index:
+ if (uint.has_value ())
+ fe.d_index = (dir_index) *uint;
+ break;
+ case DW_LNCT_timestamp:
+ if (uint.has_value ())
+ fe.mod_time = *uint;
+ break;
+ case DW_LNCT_size:
+ if (uint.has_value ())
+ fe.length = *uint;
+ break;
+ case DW_LNCT_MD5:
+ break;
+ default:
+ complaint (&symfile_complaints,
+ _("Unknown format content type %s"),
+ pulongest (content_type));
+ }
+ }
+
+ callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);
+ }
+
+ *bufp = buf;
+}
+
/* Read the statement program header starting at OFFSET in
.debug_line, or .debug_line.dwo. Return a pointer
to a struct line_header, allocated using xmalloc.
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 = xmalloc (sizeof (*lh));
- 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
- = xmalloc (lh->opcode_base * sizeof (lh->standard_opcode_lengths[0]));
+ 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)
- 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))
psymtab does not contain COMP_DIR (to match the
corresponding symtab(s)).
- Example:
+ Example:
+
+ bash$ cd /tmp
+ bash$ gcc -g ./hello.c
+ include_name = "hello.c"
+ dir_name = "."
+ DW_AT_comp_dir = comp_dir = "/tmp"
+ DW_AT_name = "./hello.c"
+
+ */
+
+ if (dir_name != NULL)
+ {
+ char *tem = concat (dir_name, SLASH_STRING,
+ include_name, (char *)NULL);
+
+ make_cleanup (xfree, tem);
+ include_name = tem;
+ include_name_to_compare = include_name;
+ }
+ if (!IS_ABSOLUTE_PATH (include_name) && comp_dir != NULL)
+ {
+ char *tem = concat (comp_dir, SLASH_STRING,
+ include_name, (char *)NULL);
+
+ make_cleanup (xfree, tem);
+ include_name_to_compare = tem;
+ }
+ }
+
+ pst_filename = pst->filename;
+ if (!IS_ABSOLUTE_PATH (pst_filename) && pst->dirname != NULL)
+ {
+ copied_name = concat (pst->dirname, SLASH_STRING,
+ pst_filename, (char *)NULL);
+ pst_filename = copied_name;
+ }
+
+ file_is_pst = FILENAME_CMP (include_name_to_compare, pst_filename) == 0;
+
+ if (copied_name != NULL)
+ xfree (copied_name);
+
+ if (file_is_pst)
+ return NULL;
+ return include_name;
+}
+
+/* State machine to track the state of the line number program. */
+
+class lnp_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;
- bash$ cd /tmp
- bash$ gcc -g ./hello.c
- include_name = "hello.c"
- dir_name = "."
- DW_AT_comp_dir = comp_dir = "/tmp"
- DW_AT_name = "./hello.c"
+ /* True if we're recording lines.
+ Otherwise we're building partial symtabs and are just interested in
+ finding include files mentioned by the line number program. */
+ bool m_record_lines_p;
- */
+ /* The line number header. */
+ line_header *m_line_header;
- if (dir_name != NULL)
- {
- char *tem = concat (dir_name, SLASH_STRING,
- include_name, (char *)NULL);
+ /* These are part of the standard DWARF line number state machine,
+ and initialized according to the DWARF spec. */
- make_cleanup (xfree, tem);
- include_name = tem;
- include_name_to_compare = include_name;
- }
- if (!IS_ABSOLUTE_PATH (include_name) && comp_dir != NULL)
- {
- char *tem = concat (comp_dir, SLASH_STRING,
- include_name, (char *)NULL);
+ 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;
- make_cleanup (xfree, tem);
- include_name_to_compare = tem;
- }
- }
+ /* These are initialized in the constructor. */
- pst_filename = pst->filename;
- if (!IS_ABSOLUTE_PATH (pst_filename) && pst->dirname != NULL)
+ 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 m_last_file = 0;
+ /* The last file a line number was recorded for. */
+ struct subfile *m_last_subfile = NULL;
+
+ /* The function to call to record a line. */
+ record_line_ftype *m_record_line_callback = NULL;
+
+ /* 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 m_last_line = 0;
+ bool m_line_has_non_zero_discriminator = false;
+};
+
+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);
+}
+
+void
+lnp_state_machine::handle_special_opcode (unsigned char op_code)
+{
+ 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);
+
+ 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;
+}
+
+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)
{
- copied_name = concat (pst->dirname, SLASH_STRING,
- pst_filename, (char *)NULL);
- pst_filename = copied_name;
+ 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);
}
+}
- file_is_pst = FILENAME_CMP (include_name_to_compare, pst_filename) == 0;
+void
+lnp_state_machine::handle_const_add_pc ()
+{
+ CORE_ADDR adjust
+ = (255 - m_line_header->opcode_base) / m_line_header->line_range;
- if (copied_name != NULL)
- xfree (copied_name);
+ CORE_ADDR addr_adj
+ = (((m_op_index + adjust)
+ / m_line_header->maximum_ops_per_instruction)
+ * m_line_header->minimum_instruction_length);
- if (file_is_pst)
- return NULL;
- return include_name;
+ 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. */
in the line table of subfile SUBFILE. */
static void
-dwarf_record_line (struct gdbarch *gdbarch, struct subfile *subfile,
- unsigned int line, CORE_ADDR address,
- record_line_ftype p_record_line)
+dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
+ unsigned int line, CORE_ADDR address,
+ record_line_ftype p_record_line)
{
CORE_ADDR addr = gdbarch_addr_bits_remove (gdbarch, address);
+ if (dwarf_line_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Recording line %u, file %s, address %s\n",
+ line, lbasename (subfile->name),
+ paddress (gdbarch, address));
+ }
+
(*p_record_line) (subfile, line, addr);
}
/* Subroutine of dwarf_decode_lines_1 to simplify it.
Mark the end of a set of line number records.
- The arguments are the same as for dwarf_record_line.
+ The arguments are the same as for dwarf_record_line_1.
If SUBFILE is NULL the request is ignored. */
static void
dwarf_finish_line (struct gdbarch *gdbarch, struct subfile *subfile,
CORE_ADDR address, record_line_ftype p_record_line)
{
- if (subfile != NULL)
- dwarf_record_line (gdbarch, subfile, 0, address, p_record_line);
+ if (subfile == NULL)
+ return;
+
+ if (dwarf_line_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Finishing current line, file %s, address %s\n",
+ lbasename (subfile->name),
+ paddress (gdbarch, address));
+ }
+
+ dwarf_record_line_1 (gdbarch, subfile, 0, address, p_record_line);
+}
+
+void
+lnp_state_machine::record_line (bool end_sequence)
+{
+ if (dwarf_line_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Processing actual line %u: file %u,"
+ " address %s, is_stmt %u, discrim %u\n",
+ m_line, to_underlying (m_file),
+ paddress (m_gdbarch, m_address),
+ m_is_stmt, m_discriminator);
+ }
+
+ 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 (m_op_index == 0 || end_sequence)
+ {
+ fe->included_p = 1;
+ if (m_record_lines_p && m_is_stmt)
+ {
+ if (m_last_subfile != current_subfile || end_sequence)
+ {
+ dwarf_finish_line (m_gdbarch, m_last_subfile,
+ m_address, m_record_line_callback);
+ }
+
+ if (!end_sequence)
+ {
+ if (dwarf_record_line_p (m_line, m_last_line,
+ m_line_has_non_zero_discriminator,
+ m_last_subfile))
+ {
+ dwarf_record_line_1 (m_gdbarch, current_subfile,
+ m_line, m_address,
+ m_record_line_callback);
+ }
+ m_last_subfile = current_subfile;
+ m_last_line = m_line;
+ }
+ }
+ }
+}
+
+lnp_state_machine::lnp_state_machine (gdbarch *arch, line_header *lh,
+ bool record_lines_p)
+{
+ m_gdbarch = arch;
+ m_record_lines_p = record_lines_p;
+ m_line_header = lh;
+
+ m_record_line_callback = ::record_line;
+
+ /* 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'. */
+ m_address = gdbarch_adjust_dwarf2_line (arch, 0, 0);
+ m_is_stmt = lh->default_is_stmt;
+ m_discriminator = 0;
+}
+
+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
+ values of zero to preserve GDB's previous behaviour which is to
+ handle the specific case of a function being GC'd by the linker. */
+
+ if (address == 0 && address < lowpc)
+ {
+ /* This line table is for a function which has been
+ GCd by the linker. Ignore it. PR gdb/12528 */
+
+ struct objfile *objfile = cu->objfile;
+ long line_offset = line_ptr - get_debug_line_section (cu)->buffer;
+
+ complaint (&symfile_complaints,
+ _(".debug_line address at offset 0x%lx is 0 [in module %s]"),
+ line_offset, objfile_name (objfile));
+ m_record_line_callback = noop_record_line;
+ /* Note: record_line_callback is left as noop_record_line until
+ we see DW_LNE_end_sequence. */
+ }
}
/* Subroutine of dwarf_decode_lines to simplify it.
- Process the line number information in LH. */
+ Process the line number information in LH.
+ If DECODE_FOR_PST_P is non-zero, all we do is process the line number
+ program in order to set included_p for every referenced header. */
static void
dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
struct objfile *objfile = cu->objfile;
bfd *abfd = objfile->obfd;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- struct subfile *last_subfile = NULL;
- void (*p_record_line) (struct subfile *subfile, int line, CORE_ADDR pc)
- = record_line;
+ /* 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));
/* Read the statement sequences until there's nothing left. */
while (line_ptr < line_end)
{
- /* State machine registers. 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'. */
- CORE_ADDR address = gdbarch_adjust_dwarf2_line (gdbarch, 0, 0);
- unsigned int file = 1;
- unsigned int line = 1;
- int is_stmt = lh->default_is_stmt;
- int end_sequence = 0;
- unsigned char op_index = 0;
- unsigned int discriminator = 0;
- /* 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 = 0;
- int line_has_non_zero_discriminator = 0;
-
- if (!decode_for_pst_p && lh->num_file_names >= file)
- {
- /* 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[file - 1];
- const char *dir = NULL;
+ /* 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 (fe->dir_index)
- dir = lh->include_dirs[fe->dir_index - 1];
+ if (record_lines_p)
+ {
+ /* Start a subfile for the current file of the state
+ machine. */
+ const file_entry *fe = state_machine.current_file ();
- dwarf2_start_subfile (fe->name, dir);
+ if (fe != NULL)
+ dwarf2_start_subfile (fe->name, fe->include_dir (lh));
}
/* Decode the table. */
- while (!end_sequence)
+ while (line_ptr < line_end && !end_sequence)
{
op_code = read_1_byte (abfd, line_ptr);
line_ptr += 1;
- if (line_ptr > line_end)
- {
- dwarf2_debug_line_missing_end_sequence_complaint ();
- break;
- }
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 = (((op_index + (adj_opcode / lh->line_range))
- / lh->maximum_ops_per_instruction)
- * lh->minimum_instruction_length);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = ((op_index + (adj_opcode / lh->line_range))
- % lh->maximum_ops_per_instruction);
- line_delta = lh->line_base + (adj_opcode % lh->line_range);
- line += line_delta;
- if (line_delta != 0)
- line_has_non_zero_discriminator = discriminator != 0;
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- /* For now we ignore lines not starting on an
- instruction boundary. */
- else if (op_index == 0)
- {
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p && is_stmt)
- {
- if (last_subfile != current_subfile)
- {
- dwarf_finish_line (gdbarch, last_subfile,
- address, p_record_line);
- }
- if (dwarf_record_line_p (line, last_line,
- line_has_non_zero_discriminator,
- last_subfile))
- {
- dwarf_record_line (gdbarch, current_subfile,
- line, address, p_record_line);
- }
- last_subfile = current_subfile;
- last_line = line;
- }
- }
- discriminator = 0;
+ state_machine.handle_special_opcode (op_code);
}
else switch (op_code)
{
switch (extended_op)
{
case DW_LNE_end_sequence:
- p_record_line = record_line;
- end_sequence = 1;
+ state_machine.handle_end_sequence ();
+ end_sequence = true;
break;
case DW_LNE_set_address:
- address = read_address (abfd, line_ptr, cu, &bytes_read);
-
- /* If address < lowpc then it's not a usable value, it's
- outside the pc range of the CU. However, we restrict
- the test to only address values of zero to preserve
- GDB's previous behaviour which is to handle the specific
- case of a function being GC'd by the linker. */
- if (address == 0 && address < lowpc)
- {
- /* This line table is for a function which has been
- GCd by the linker. Ignore it. PR gdb/12528 */
-
- long line_offset
- = line_ptr - get_debug_line_section (cu)->buffer;
-
- complaint (&symfile_complaints,
- _(".debug_line address at offset 0x%lx is 0 "
- "[in module %s]"),
- line_offset, objfile_name (objfile));
- p_record_line = noop_record_line;
- /* Note: p_record_line is left as noop_record_line
- until we see DW_LNE_end_sequence. */
- }
+ {
+ CORE_ADDR address
+ = read_address (abfd, line_ptr, cu, &bytes_read);
+ line_ptr += bytes_read;
- op_index = 0;
- line_ptr += bytes_read;
- address += baseaddr;
- 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. */
- discriminator = read_unsigned_leb128 (abfd, line_ptr,
- &bytes_read);
- line_has_non_zero_discriminator |= 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:
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- else
- {
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p && is_stmt)
- {
- if (last_subfile != current_subfile)
- {
- dwarf_finish_line (gdbarch, last_subfile,
- address, p_record_line);
- }
- if (dwarf_record_line_p (line, last_line,
- line_has_non_zero_discriminator,
- last_subfile))
- {
- dwarf_record_line (gdbarch, current_subfile,
- line, address, p_record_line);
- }
- last_subfile = current_subfile;
- last_line = line;
- }
- }
- 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 = (((op_index + adjust)
- / lh->maximum_ops_per_instruction)
- * lh->minimum_instruction_length);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = ((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);
-
- line += line_delta;
- if (line_delta != 0)
- line_has_non_zero_discriminator = 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;
-
- file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
- line_ptr += bytes_read;
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- else
- {
- fe = &lh->file_names[file - 1];
- if (fe->dir_index)
- dir = lh->include_dirs[fe->dir_index - 1];
- if (!decode_for_pst_p)
- {
- last_subfile = current_subfile;
- line_has_non_zero_discriminator = discriminator != 0;
- dwarf2_start_subfile (fe->name, dir);
- }
- }
- }
+ {
+ file_name_index file
+ = (file_name_index) read_unsigned_leb128 (abfd, line_ptr,
+ &bytes_read);
+ line_ptr += bytes_read;
+
+ state_machine.handle_set_file (file);
+ }
break;
case DW_LNS_set_column:
(void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
break;
case DW_LNS_negate_stmt:
- is_stmt = (!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 = (((op_index + adjust)
- / lh->maximum_ops_per_instruction)
- * lh->minimum_instruction_length);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- op_index = ((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);
- address += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- 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:
}
}
}
- if (lh->num_file_names < file || file == 0)
- dwarf2_debug_line_missing_file_complaint ();
- else
- {
- lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p)
- {
- dwarf_finish_line (gdbarch, current_subfile, address,
- p_record_line);
- }
- }
+
+ if (!end_sequence)
+ dwarf2_debug_line_missing_end_sequence_complaint ();
+
+ /* 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). */
+ 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)
- dir = lh->include_dirs[fe->dir_index - 1];
- dwarf2_start_subfile (fe->name, dir);
+ dwarf2_start_subfile (fe.name, fe.include_dir (lh));
if (current_subfile->symtab == NULL)
{
current_subfile->symtab
= allocate_symtab (cust, current_subfile->name);
}
- fe->symtab = current_subfile->symtab;
+ fe.symtab = current_subfile->symtab;
}
}
}
cu);
if (attr)
{
- int file_index = DW_UNSND (attr);
+ file_name_index file_index = (file_name_index) DW_UNSND (attr);
+ struct file_entry *fe;
+
+ if (cu->line_header != NULL)
+ fe = cu->line_header->file_name_at (file_index);
+ else
+ fe = NULL;
- if (cu->line_header == NULL
- || file_index > cu->line_header->num_file_names)
+ if (fe == NULL)
complaint (&symfile_complaints,
_("file index out of range"));
- else if (file_index > 0)
- {
- struct file_entry *fe;
-
- fe = &cu->line_header->file_names[file_index - 1];
- symbol_set_symtab (sym, fe->symtab);
- }
+ else
+ symbol_set_symtab (sym, fe->symtab);
}
switch (die->tag)
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_ada
+ || 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;
}
/* Symbols of this form are reasonably rare, so we just
piggyback on the existing location code rather than writing
a new implementation of symbol_computed_ops. */
- *baton = obstack_alloc (obstack, sizeof (struct dwarf2_locexpr_baton));
+ *baton = XOBNEW (obstack, struct dwarf2_locexpr_baton);
(*baton)->per_cu = cu->per_cu;
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 (child->tag == DW_TAG_subprogram)
{
- struct attribute *attr;
+ const char *linkage_name;
- attr = dwarf2_attr (child, DW_AT_linkage_name, cu);
- if (attr == NULL)
- attr = dwarf2_attr (child, DW_AT_MIPS_linkage_name, cu);
- if (attr != NULL)
+ linkage_name = dwarf2_string_attr (child, DW_AT_linkage_name, cu);
+ if (linkage_name == NULL)
+ linkage_name = dwarf2_string_attr (child, DW_AT_MIPS_linkage_name,
+ cu);
+ if (linkage_name != NULL)
{
char *actual_name
= language_class_name_from_physname (cu->language_defn,
- DW_STRING (attr));
+ linkage_name);
char *name = NULL;
if (actual_name != NULL)
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)
return NULL;
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr != NULL && DW_STRING (attr) != NULL)
+ if (dwarf2_string_attr (die, DW_AT_name, cu) != NULL)
return NULL;
attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
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)
+ 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
+ should never be prefixed. */
+ if (strcmp (suffix, "D main") == 0)
+ {
+ prefix = "";
+ sep = "";
+ }
+ else
+ sep = ".";
+ }
else if (cu->language == language_fortran && physname)
{
/* This is gfortran specific mangling. Normally DW_AT_linkage_name or
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)
if (per_cu->cu == NULL)
load_cu (per_cu);
cu = per_cu->cu;
+ if (cu == NULL)
+ {
+ /* 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"),
+ 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)
if (per_cu->cu == NULL)
load_cu (per_cu);
cu = per_cu->cu;
+ if (cu == NULL)
+ {
+ /* 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"),
+ 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
static struct dwarf_block *
dwarf_alloc_block (struct dwarf2_cu *cu)
{
- struct dwarf_block *blk;
-
- blk = (struct dwarf_block *)
- obstack_alloc (&cu->comp_unit_obstack, sizeof (struct dwarf_block));
- return (blk);
+ return XOBNEW (&cu->comp_unit_obstack, struct dwarf_block);
}
static struct die_info *
{
/* 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)
- 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';
char *name = copy_string (body, p - body);
int argc = 0;
int argv_size = 1;
- char **argv = xmalloc (argv_size * sizeof (*argv));
+ char **argv = XNEWVEC (char *, argv_size);
p++;
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;
for (i = 0; i < arg; ++i)
{
- mac_ptr = skip_form_bytes (abfd, mac_ptr, mac_end, defn[i], offset_size,
+ mac_ptr = skip_form_bytes (abfd, mac_ptr, mac_end,
+ (enum dwarf_form) defn[i], offset_size,
section);
if (mac_ptr == NULL)
{
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,
break;
}
- macinfo_type = read_1_byte (abfd, mac_ptr);
+ macinfo_type = (enum dwarf_macro_record_type) read_1_byte (abfd, mac_ptr);
mac_ptr++;
/* Note that we rely on the fact that the corresponding GNU and
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 "
/* We don't increment mac_ptr here, so this is just
a look-ahead. */
- next_type = read_1_byte (abfd, mac_ptr);
+ next_type
+ = (enum dwarf_macro_record_type) read_1_byte (abfd,
+ mac_ptr);
if (next_type != 0)
complaint (&symfile_complaints,
_("no terminating 0-type entry for "
}
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;
break;
}
- macinfo_type = read_1_byte (abfd, mac_ptr);
+ macinfo_type = (enum dwarf_macro_record_type) read_1_byte (abfd, mac_ptr);
mac_ptr++;
/* Note that we rely on the fact that the corresponding GNU and
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. */
{
struct dwarf2_loclist_baton *baton;
- baton = obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct dwarf2_loclist_baton));
+ baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_loclist_baton);
fill_in_loclist_baton (cu, baton, attr);
{
struct dwarf2_locexpr_baton *baton;
- baton = obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct dwarf2_locexpr_baton));
+ baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
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;
}
}
cu->language_defn = language_def (cu->language);
}
- attr = dwarf2_attr (comp_unit_die, DW_AT_producer, cu);
- if (attr)
- cu->producer = DW_STRING (attr);
+ cu->producer = dwarf2_string_attr (comp_unit_die, DW_AT_producer, cu);
}
/* Release one cached compilation unit, CU. We unlink it from the tree
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;
while (per_cu != NULL)
{
per_cu->cu->last_used ++;
- if (per_cu->cu->last_used <= dwarf2_max_cache_age)
+ if (per_cu->cu->last_used <= dwarf_max_cache_age)
dwarf2_mark (per_cu->cu);
per_cu = per_cu->cu->read_in_chain;
}
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);
- *slot = obstack_alloc (&objfile->objfile_obstack, sizeof (**slot));
+ 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_dwarf2_cmdlist;
-static struct cmd_list_element *show_dwarf2_cmdlist;
+static struct cmd_list_element *set_dwarf_cmdlist;
+static struct cmd_list_element *show_dwarf_cmdlist;
static void
-set_dwarf2_cmd (char *args, int from_tty)
+set_dwarf_cmd (char *args, int from_tty)
{
- help_list (set_dwarf2_cmdlist, "maintenance set dwarf2 ", all_commands,
+ help_list (set_dwarf_cmdlist, "maintenance set dwarf ", all_commands,
gdb_stdout);
}
static void
-show_dwarf2_cmd (char *args, int from_tty)
+show_dwarf_cmd (char *args, int from_tty)
{
- cmd_show_list (show_dwarf2_cmdlist, from_tty, "");
+ cmd_show_list (show_dwarf_cmdlist, from_tty, "");
}
/* Free data associated with OBJFILE, if necessary. */
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);
- psymtab_cu_index_map = (struct psymtab_cu_index_map *)
- xmalloc (sizeof (struct psymtab_cu_index_map)
- * dwarf2_per_objfile->n_comp_units);
+ 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);
/* The CU list is already sorted, so we don't need to do additional
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)
{
\f
-int dwarf2_always_disassemble;
+int dwarf_always_disassemble;
static void
-show_dwarf2_always_disassemble (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
+show_dwarf_always_disassemble (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
{
fprintf_filtered (file,
_("Whether to always disassemble "
dwarf2_objfile_data_key
= register_objfile_data_with_cleanup (NULL, dwarf2_per_objfile_free);
- add_prefix_cmd ("dwarf2", class_maintenance, set_dwarf2_cmd, _("\
-Set DWARF 2 specific variables.\n\
-Configure DWARF 2 variables such as the cache size"),
- &set_dwarf2_cmdlist, "maintenance set dwarf2 ",
+ add_prefix_cmd ("dwarf", class_maintenance, set_dwarf_cmd, _("\
+Set DWARF specific variables.\n\
+Configure DWARF variables such as the cache size"),
+ &set_dwarf_cmdlist, "maintenance set dwarf ",
0/*allow-unknown*/, &maintenance_set_cmdlist);
- add_prefix_cmd ("dwarf2", class_maintenance, show_dwarf2_cmd, _("\
-Show DWARF 2 specific variables\n\
-Show DWARF 2 variables such as the cache size"),
- &show_dwarf2_cmdlist, "maintenance show dwarf2 ",
+ add_prefix_cmd ("dwarf", class_maintenance, show_dwarf_cmd, _("\
+Show DWARF specific variables\n\
+Show DWARF variables such as the cache size"),
+ &show_dwarf_cmdlist, "maintenance show dwarf ",
0/*allow-unknown*/, &maintenance_show_cmdlist);
add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
- &dwarf2_max_cache_age, _("\
-Set the upper bound on the age of cached dwarf2 compilation units."), _("\
-Show the upper bound on the age of cached dwarf2 compilation units."), _("\
+ &dwarf_max_cache_age, _("\
+Set the upper bound on the age of cached DWARF compilation units."), _("\
+Show the upper bound on the age of cached DWARF compilation units."), _("\
A higher limit means that cached compilation units will be stored\n\
in memory longer, and more total memory will be used. Zero disables\n\
caching, which can slow down startup."),
NULL,
- show_dwarf2_max_cache_age,
- &set_dwarf2_cmdlist,
- &show_dwarf2_cmdlist);
+ show_dwarf_max_cache_age,
+ &set_dwarf_cmdlist,
+ &show_dwarf_cmdlist);
add_setshow_boolean_cmd ("always-disassemble", class_obscure,
- &dwarf2_always_disassemble, _("\
+ &dwarf_always_disassemble, _("\
Set whether `info address' always disassembles DWARF expressions."), _("\
Show whether `info address' always disassembles DWARF expressions."), _("\
When enabled, DWARF expressions are always printed in an assembly-like\n\
syntax. When disabled, expressions will be printed in a more\n\
conversational style, when possible."),
NULL,
- show_dwarf2_always_disassemble,
- &set_dwarf2_cmdlist,
- &show_dwarf2_cmdlist);
-
- add_setshow_zuinteger_cmd ("dwarf2-read", no_class, &dwarf2_read_debug, _("\
-Set debugging of the dwarf2 reader."), _("\
-Show debugging of the dwarf2 reader."), _("\
-When enabled (non-zero), debugging messages are printed during dwarf2\n\
+ show_dwarf_always_disassemble,
+ &set_dwarf_cmdlist,
+ &show_dwarf_cmdlist);
+
+ add_setshow_zuinteger_cmd ("dwarf-read", no_class, &dwarf_read_debug, _("\
+Set debugging of the DWARF reader."), _("\
+Show debugging of the DWARF reader."), _("\
+When enabled (non-zero), debugging messages are printed during DWARF\n\
reading and symtab expansion. A value of 1 (one) provides basic\n\
information. A value greater than 1 provides more verbose information."),
NULL,
NULL,
&setdebuglist, &showdebuglist);
- add_setshow_zuinteger_cmd ("dwarf2-die", no_class, &dwarf2_die_debug, _("\
-Set debugging of the dwarf2 DIE reader."), _("\
-Show debugging of the dwarf2 DIE reader."), _("\
+ add_setshow_zuinteger_cmd ("dwarf-die", no_class, &dwarf_die_debug, _("\
+Set debugging of the DWARF DIE reader."), _("\
+Show debugging of the DWARF DIE reader."), _("\
When enabled (non-zero), DIEs are dumped after they are read in.\n\
The value is the maximum depth to print."),
NULL,
NULL,
&setdebuglist, &showdebuglist);
+ add_setshow_zuinteger_cmd ("dwarf-line", no_class, &dwarf_line_debug, _("\
+Set debugging of the dwarf line reader."), _("\
+Show debugging of the dwarf line reader."), _("\
+When enabled (non-zero), line number entries are dumped as they are read in.\n\
+A value of 1 (one) provides basic information.\n\
+A value greater than 1 provides more verbose information."),
+ NULL,
+ NULL,
+ &setdebuglist, &showdebuglist);
+
add_setshow_boolean_cmd ("check-physname", no_class, &check_physname, _("\
Set cross-checking of \"physname\" code against demangler."), _("\
Show cross-checking of \"physname\" code against demangler."), _("\