/* 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 <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;
};
typedef struct dwarf2_per_cu_data *dwarf2_per_cu_ptr;
DEF_VEC_P (dwarf2_per_cu_ptr);
+struct tu_stats
+{
+ int nr_uniq_abbrev_tables;
+ int nr_symtabs;
+ int nr_symtab_sharers;
+ int nr_stmt_less_type_units;
+ int nr_all_type_units_reallocs;
+};
+
/* Collection of data recorded per objfile.
This hangs off of dwarf2_objfile_data_key. */
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;
/* Type unit statistics, to see how well the scaling improvements
are doing. */
- struct tu_stats
- {
- int nr_uniq_abbrev_tables;
- int nr_symtabs;
- int nr_symtab_sharers;
- int nr_stmt_less_type_units;
- int nr_all_type_units_reallocs;
- } tu_stats;
+ struct tu_stats tu_stats;
/* A chain of compilation units that are currently read in, so that
they can be freed later. */
{ ".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" },
/* 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;
/* 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;
+
+ /* 64-bit signature of this type unit - it is valid only for
+ UNIT_TYPE DW_UT_type. */
+ ULONGEST signature;
+
+ /* For types, offset in the type's DIE of the type defined by this TU. */
+ cu_offset type_offset_in_tu;
};
/* Type used for delaying computation of method physnames.
sect_offset offset;
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 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;
int has_children,
void *data);
+struct file_entry
+{
+ const char *name;
+ unsigned int dir_index;
+ unsigned int mod_time;
+ unsigned int length;
+ /* Non-zero if referenced by the Line Number Program. */
+ int included_p;
+ /* The associated symbol table, if any. */
+ struct symtab *symtab;
+};
+
/* The line number information for a compilation unit (found in the
.debug_line section) begins with a "statement program header",
which contains the following information. */
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
- {
- 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_names;
+ struct file_entry *file_names;
/* The start and end of the statement program following this
header. These point into dwarf2_per_objfile->line_buffer. */
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;
/* Flag set if the DIE has a byte_size attribute. */
unsigned int has_byte_size : 1;
+ /* Flag set if the DIE has a DW_AT_const_value attribute. */
+ unsigned int has_const_value : 1;
+
/* Flag set if any of the DIE's children are template arguments. */
unsigned int has_template_arguments : 1;
{
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. */
and friends. */
static int bits_per_byte = 8;
+struct nextfield
+{
+ struct nextfield *next;
+ int accessibility;
+ int virtuality;
+ struct field field;
+};
+
+struct nextfnfield
+{
+ struct nextfnfield *next;
+ struct fn_field fnfield;
+};
+
+struct fnfieldlist
+{
+ const char *name;
+ int length;
+ struct nextfnfield *head;
+};
+
+struct typedef_field_list
+{
+ struct typedef_field field;
+ struct typedef_field_list *next;
+};
+
/* The routines that read and process dies for a C struct or C++ class
pass lists of data member fields and lists of member function fields
in an instance of a field_info structure, as defined below. */
struct field_info
{
/* List of data member and baseclasses fields. */
- struct nextfield
- {
- struct nextfield *next;
- int accessibility;
- int virtuality;
- struct field field;
- }
- *fields, *baseclasses;
+ struct nextfield *fields, *baseclasses;
/* Number of fields (including baseclasses). */
int nfields;
/* Member function fields array, entries are allocated in the order they
are encountered in the object file. */
- struct nextfnfield
- {
- struct nextfnfield *next;
- struct fn_field fnfield;
- }
- *fnfields;
+ struct nextfnfield *fnfields;
/* Member function fieldlist array, contains name of possibly overloaded
member function, number of overloaded member functions and a pointer
to the head of the member function field chain. */
- struct fnfieldlist
- {
- const char *name;
- int length;
- struct nextfnfield *head;
- }
- *fnfieldlists;
+ struct fnfieldlist *fnfieldlists;
/* Number of entries in the fnfieldlists array. */
int nfnfields;
/* typedefs defined inside this class. TYPEDEF_FIELD_LIST contains head of
a NULL terminated list of TYPEDEF_FIELD_LIST_COUNT elements. */
- struct typedef_field_list
- {
- struct typedef_field field;
- struct typedef_field_list *next;
- }
- *typedef_field_list;
+ struct typedef_field_list *typedef_field_list;
unsigned typedef_field_list_count;
};
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 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 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 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_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
&& 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;
/* 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;
}
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
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);
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);
}
&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;
gdb_assert (slot != NULL);
find_file_and_directory (comp_unit_die, cu, &name, &comp_dir);
qfn->num_file_names = lh->num_file_names;
- qfn->file_names = obstack_alloc (&objfile->objfile_obstack,
- lh->num_file_names * sizeof (char *));
+ qfn->file_names =
+ XOBNEWVEC (&objfile->objfile_obstack, const char *, lh->num_file_names);
for (i = 0; i < lh->num_file_names; ++i)
qfn->file_names[i] = file_full_name (i + 1, lh, comp_dir);
qfn->real_names = NULL;
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_map_matching_symbols (struct objfile *objfile,
- const char * name, domain_enum namespace,
+ const char * name, domain_enum domain,
int global,
int (*callback) (struct block *,
struct symbol *, void *),
static void
dw2_expand_symtabs_matching
(struct objfile *objfile,
- expand_symtabs_file_matcher_ftype *file_matcher,
- expand_symtabs_symbol_matcher_ftype *symbol_matcher,
- 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
per_cu = dw2_get_cutu (cu_index);
if (file_matcher == NULL || per_cu->v.quick->mark)
- dw2_instantiate_symtab (per_cu);
+ {
+ int symtab_was_null =
+ (per_cu->v.quick->compunit_symtab == NULL);
+
+ dw2_instantiate_symtab (per_cu);
+
+ if (expansion_notify != NULL
+ && symtab_was_null
+ && per_cu->v.quick->compunit_symtab != NULL)
+ {
+ 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
void
dwarf2_build_psymtabs (struct objfile *objfile)
{
- volatile struct gdb_exception except;
if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)
{
init_psymbol_list (objfile, 1024);
}
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
/* 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)
+ {
+ exception_print (gdb_stderr, except);
}
- if (except.reason < 0)
- exception_print (gdb_stderr, except);
+ END_CATCH
}
/* Return the total length of the CU described by HEADER. */
}
/* 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;
+ 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_offset.sect_off = 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_offset_in_tu.cu_off = type_offset;
+ if (cu_header->type_offset_in_tu.cu_off != 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
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);
-
- /* 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;
{
bfd *abfd = get_section_bfd_owner (section);
const gdb_byte *info_ptr;
- unsigned int length, initial_length_size, offset_size;
+ unsigned int initial_length_size, offset_size;
sect_offset abbrev_offset;
+ uint16_t version;
dwarf2_read_section (dwarf2_per_objfile->objfile, section);
info_ptr = section->buffer + offset.sect_off;
- length = read_initial_length (abfd, info_ptr, &initial_length_size);
+ read_initial_length (abfd, info_ptr, &initial_length_size);
offset_size = initial_length_size == 4 ? 4 : 8;
- info_ptr += initial_length_size + 2 /*version*/;
+ 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;
+ }
+
abbrev_offset.sect_off = read_offset_1 (abfd, info_ptr, offset_size);
return abbrev_offset;
}
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;
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 can't set abfd until now because the section may be empty or
- not present, in which case the bfd is unknown. */
- abfd = get_section_bfd_owner (section);
+ /* We don't use init_cutu_and_read_dies_simple, or some such, here
+ because we don't need to read any dies: the signature is in the
+ header. */
- /* We don't use init_cutu_and_read_dies_simple, or some such, here
- because we don't need to read any dies: the signature is in the
- header. */
+ end_ptr = info_ptr + section->size;
+ while (info_ptr < end_ptr)
+ {
+ sect_offset offset;
+ struct signatured_type *sig_type;
+ struct dwo_unit *dwo_tu;
+ void **slot;
+ const gdb_byte *ptr = info_ptr;
+ struct comp_unit_head header;
+ unsigned int length;
- end_ptr = info_ptr + section->size;
- while (info_ptr < end_ptr)
- {
- sect_offset offset;
- cu_offset type_offset_in_tu;
- ULONGEST signature;
- struct signatured_type *sig_type;
- struct dwo_unit *dwo_tu;
- void **slot;
- const gdb_byte *ptr = info_ptr;
- struct comp_unit_head header;
- unsigned int length;
+ offset.sect_off = ptr - section->buffer;
- offset.sect_off = ptr - section->buffer;
+ /* Initialize it due to a false compiler warning. */
+ header.signature = -1;
+ header.type_offset_in_tu.cu_off = -1;
- /* We need to read the type's signature in order to build the hash
- table, but we don't need anything else just yet. */
+ /* We need to read the type's signature in order to build the hash
+ table, but we don't need anything else just yet. */
- ptr = read_and_check_type_unit_head (&header, section,
- abbrev_section, ptr,
- &signature, &type_offset_in_tu);
+ ptr = read_and_check_comp_unit_head (&header, section,
+ abbrev_section, ptr, section_kind);
- length = get_cu_length (&header);
+ length = get_cu_length (&header);
- /* Skip dummy type units. */
- if (ptr >= info_ptr + length
- || peek_abbrev_code (abfd, ptr) == 0)
- {
- info_ptr += length;
- continue;
- }
+ /* Skip dummy type units. */
+ if (ptr >= info_ptr + length
+ || peek_abbrev_code (abfd, ptr) == 0
+ || header.unit_type != DW_UT_type)
+ {
+ info_ptr += length;
+ continue;
+ }
- if (types_htab == NULL)
- {
- if (dwo_file)
- types_htab = allocate_dwo_unit_table (objfile);
- else
- types_htab = allocate_signatured_type_table (objfile);
- }
+ if (types_htab == NULL)
+ {
+ if (dwo_file)
+ types_htab = allocate_dwo_unit_table (objfile);
+ else
+ types_htab = allocate_signatured_type_table (objfile);
+ }
+
+ if (dwo_file)
+ {
+ sig_type = NULL;
+ dwo_tu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwo_unit);
+ dwo_tu->dwo_file = dwo_file;
+ dwo_tu->signature = header.signature;
+ dwo_tu->type_offset_in_tu = header.type_offset_in_tu;
+ dwo_tu->section = section;
+ dwo_tu->offset = offset;
+ 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_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;
+ }
+
+ 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;
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_offset = dup_tu->offset;
}
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_offset = dup_tu->per_cu.offset;
}
- 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"),
+ offset.sect_off, dup_offset.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",
+ offset.sect_off,
+ hex_string (header.signature));
- dup_offset = dup_tu->offset;
- }
- else
- {
- const struct signatured_type *dup_tu = *slot;
+ info_ptr += length;
+ }
+}
- dup_offset = dup_tu->per_cu.offset;
- }
+/* Create the hash table of all entries in the .debug_types
+ (or .debug_types.dwo) section(s).
+ If reading a DWO file, then DWO_FILE is a pointer to the DWO file object,
+ otherwise it is NULL.
- complaint (&symfile_complaints,
- _("debug type entry at offset 0x%x is duplicate to"
- " the entry at offset 0x%x, signature %s"),
- offset.sect_off, dup_offset.sect_off,
- hex_string (signature));
- }
- *slot = dwo_file ? (void *) dwo_tu : (void *) sig_type;
+ The result is a pointer to the hash table or NULL if there are no types.
- if (dwarf2_read_debug > 1)
- fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature %s\n",
- offset.sect_off,
- hex_string (signature));
+ Note: This function processes DWO files only, not DWP files. */
- info_ptr += length;
- }
- }
+static void
+create_debug_types_hash_table (struct dwo_file *dwo_file,
+ VEC (dwarf2_section_info_def) *types,
+ htab_t &types_htab)
+{
+ int ix;
+ struct dwarf2_section_info *section;
+
+ 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;
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;
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),
+ hex_string (cu->header.signature),
dwo_unit->offset.sect_off,
bfd_get_filename (abfd));
}
/* 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_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. */
{
info_ptr = read_and_check_comp_unit_head (&cu->header, section,
dwo_abbrev_section,
- info_ptr, 0);
+ info_ptr, rcuh_kind::COMPILE);
gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
/* For DWOs coming from DWP files, we don't know the CU length
until now. */
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);
{
/* 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);
{
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->signature == cu->header.signature);
gdb_assert (sig_type->type_offset_in_tu.cu_off
- == type_offset_in_tu.cu_off);
+ == cu->header.type_offset_in_tu.cu_off);
gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
/* LENGTH has not been set yet for type units if we're
/* 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;
+
+ 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->length == get_cu_length (&cu->header));
+ this_cu->dwarf_version = cu->header.version;
}
}
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);
begin_info_ptr = info_ptr = section->buffer + this_cu->offset.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);
}
&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
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);
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;
+ 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;
unsigned int aoff = (*a)->abbrev_offset.sect_off;
unsigned int boff = (*b)->abbrev_offset.sect_off;
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
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));
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->length = length + initial_length_size;
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)
/* 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.
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;
die = follow_die_ref (NULL, &attr, &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
{
- /* Static Variable. Skip symbols without location descriptors. */
- if (pdi->d.locdesc == NULL)
+ int has_loc = pdi->d.locdesc != NULL;
+
+ /* Static Variable. Skip symbols whose value we cannot know (those
+ without location descriptors or constant values). */
+ if (!has_loc && !pdi->has_const_value)
{
xfree (built_actual_name);
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, addr + baseaddr,
+ has_loc ? addr + baseaddr : (CORE_ADDR) 0,
cu->language, objfile);
}
break;
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;
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++)
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;
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;
}
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;
}
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
if (attr != NULL)
{
struct dwarf2_per_cu_data *per_cu;
- struct symtab *imported_symtab;
sect_offset offset;
int is_dwz;
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)
{
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;
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;
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);
}
static void
free_cu_line_header (void *arg)
{
- struct dwarf2_cu *cu = arg;
+ struct dwarf2_cu *cu = (struct dwarf2_cu *) arg;
free_line_header (cu->line_header);
cu->line_header = NULL;
find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
const char **name, const char **comp_dir)
{
- struct attribute *attr;
-
- *name = NULL;
- *comp_dir = NULL;
-
/* 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);
- }
+ *name = dwarf2_string_attr (die, DW_AT_name, cu);
+ *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 (*comp_dir == NULL
+ && producer_is_gcc_lt_4_3 (cu) && *name != NULL
+ && IS_ABSOLUTE_PATH (*name))
{
char *d = ldirname (*name);
{
/* Irix 6.2 native cc prepends <machine>.: to the compilation
directory, get rid of it. */
- char *cp = strchr (*comp_dir, ':');
+ const char *cp = strchr (*comp_dir, ':');
if (cp && cp != *comp_dir && cp[-1] == '.' && cp[1] == '/')
*comp_dir = cp + 1;
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;
}
}
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));
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);
}
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 compunit_symtab *cust = dwarf2_start_symtab (cu, "", NULL, 0);
+ /* Note: We don't assign tu_group->compunit_symtab yet because we're
+ still initializing it, and our caller (a few levels up)
+ process_full_type_unit still needs to know if this is the first
+ time. */
+
tu_group->num_symtabs = lh->num_file_names;
tu_group->symtabs = XNEWVEC (struct symtab *, lh->num_file_names);
const char *dir = NULL;
struct file_entry *fe = &lh->file_names[i];
- if (fe->dir_index)
+ if (fe->dir_index && lh->include_dirs != NULL)
dir = lh->include_dirs[fe->dir_index - 1];
dwarf2_start_subfile (fe->name, dir);
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;
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;
dwo_unit->offset = offset;
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));
}
{
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),
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;
+ struct cleanup *cleanups = make_cleanup (null_cleanup, 0);
/* 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. */
+ if (objfile->separate_debug_objfile_backlink != NULL)
+ {
+ struct objfile *backlink = objfile->separate_debug_objfile_backlink;
+ const char *backlink_basename = lbasename (backlink->original_name);
+ char *debug_dirname = ldirname (objfile->original_name);
+
+ make_cleanup (xfree, debug_dirname);
+ dwp_name = xstrprintf ("%s%s%s.dwp", debug_dirname,
+ SLASH_STRING, backlink_basename);
+ }
+ else
+ dwp_name = xstrprintf ("%s.dwp", objfile->original_name);
+ make_cleanup (xfree, dwp_name);
+
+ gdb_bfd_ref_ptr dbfd (open_dwp_file (dwp_name));
if (dbfd == NULL
&& strcmp (objfile->original_name, objfile_name (objfile)) != 0)
{
if (dbfd == NULL)
{
- if (dwarf2_read_debug)
+ if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name);
do_cleanups (cleanups);
return NULL;
}
dwp_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_file);
- dwp_file->name = bfd_get_filename (dbfd);
- dwp_file->dbfd = dbfd;
+ dwp_file->name = bfd_get_filename (dbfd.get ());
+ dwp_file->dbfd = dbfd.release ();
do_cleanups (cleanups);
/* +1: section 0 is unused */
- dwp_file->num_sections = bfd_count_sections (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);
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));
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);
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,
else
*offsets_end++ = child_origin_die->offset;
}
- child_die = sibling_die (child_die);
}
qsort (offsets, offsets_end - offsets, sizeof (*offsets),
unsigned_int_compar);
{
struct objfile *objfile = cu->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- struct context_stack *new;
+ struct context_stack *newobj;
CORE_ADDR lowpc;
CORE_ADDR highpc;
struct die_info *child_die;
}
/* 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))
}
}
- new = push_context (0, lowpc);
- new->name = new_symbol_full (die, read_type_die (die, cu), cu,
+ newobj = push_context (0, lowpc);
+ newobj->name = new_symbol_full (die, read_type_die (die, cu), cu,
(struct symbol *) templ_func);
/* If there is a location expression for DW_AT_frame_base, record
it. */
attr = dwarf2_attr (die, DW_AT_frame_base, cu);
if (attr)
- dwarf2_symbol_mark_computed (attr, new->name, cu, 1);
+ 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;
}
}
- new = pop_context ();
+ newobj = pop_context ();
/* Make a block for the local symbols within. */
- block = finish_block (new->name, &local_symbols, new->old_blocks,
- lowpc, highpc);
+ block = finish_block (newobj->name, &local_symbols, newobj->old_blocks,
+ 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);
/* If we have address ranges, record them. */
dwarf2_record_block_ranges (die, block, baseaddr, cu);
- gdbarch_make_symbol_special (gdbarch, new->name, objfile);
+ gdbarch_make_symbol_special (gdbarch, newobj->name, objfile);
/* Attach template arguments to function. */
if (! VEC_empty (symbolp, template_args))
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 *)));
a function declares a class that has methods). This means that
when we finish processing a function scope, we may need to go
back to building a containing block's symbol lists. */
- local_symbols = new->locals;
- using_directives = new->using_directives;
+ local_symbols = newobj->locals;
+ local_using_directives = newobj->local_using_directives;
/* If we've finished processing a top-level function, subsequent
symbols go in the file symbol list. */
{
struct objfile *objfile = cu->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- struct context_stack *new;
+ struct context_stack *newobj;
CORE_ADDR lowpc, highpc;
struct die_info *child_die;
CORE_ADDR baseaddr;
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);
}
}
- new = pop_context ();
+ 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, new->old_blocks, new->start_addr,
- highpc);
+ = finish_block (0, &local_symbols, newobj->old_blocks, NULL,
+ newobj->start_addr, highpc);
/* Note that recording ranges after traversing children, as we
do here, means that recording a parent's ranges entails
to do. */
dwarf2_record_block_ranges (die, block, baseaddr, cu);
}
- local_symbols = new->locals;
- using_directives = new->using_directives;
+ local_symbols = newobj->locals;
+ 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));
return;
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,
objfile_name (objfile));
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]"),
+ _("Tag %d is not DW_TAG_call_site_parameter in "
+ "DW_TAG_call_site child DIE 0x%x [in module %s]"),
child_die->tag, child_die->offset.sect_off,
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));
}
}
- 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_abstract_origin, cu);
+ attr = dwarf2_attr (die, DW_AT_call_origin, cu);
+ if (attr == NULL)
+ {
+ /* 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));
else
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));
else
}
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));
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;
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]"),
+ _("DW_AT_call_parameter offset is not in CU for "
+ "DW_TAG_call_site child DIE 0x%x [in module %s]"),
child_die->offset.sect_off, objfile_name (objfile));
continue;
}
{
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_location for "
- "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
+ "DW_TAG_call_site child DIE 0x%x [in module %s]"),
child_die->offset.sect_off, objfile_name (objfile));
continue;
}
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));
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]"),
+ _("No DW_FORM_block* DW_AT_call_value for "
+ "DW_TAG_call_site child DIE 0x%x [in module %s]"),
child_die->offset.sect_off, objfile_name (objfile));
continue;
}
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]"),
+ _("No DW_FORM_block* DW_AT_call_data_value for "
+ "DW_TAG_call_site child DIE 0x%x [in module %s]"),
child_die->offset.sect_off, objfile_name (objfile));
else
{
}
}
-/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
- Return 1 if the attributes are present and valid, otherwise, return 0.
- If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'. */
+/* Call CALLBACK from DW_AT_ranges attribute value OFFSET
+ reading .debug_rnglists.
+ Callback's type should be:
+ void (CORE_ADDR range_beginning, CORE_ADDR range_end)
+ Return true if the attributes are present and valid, otherwise,
+ return false. */
-static int
-dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
- CORE_ADDR *high_return, struct dwarf2_cu *cu,
- struct partial_symtab *ranges_pst)
+template <typename Callback>
+static bool
+dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
+ Callback &&callback)
{
struct objfile *objfile = cu->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
int found_base;
unsigned int dummy;
const gdb_byte *buffer;
- CORE_ADDR marker;
- int low_set;
CORE_ADDR low = 0;
CORE_ADDR high = 0;
CORE_ADDR baseaddr;
+ bool overflow = false;
found_base = cu->base_known;
base = cu->base_address;
- dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
- if (offset >= dwarf2_per_objfile->ranges.size)
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->rnglists);
+ if (offset >= dwarf2_per_objfile->rnglists.size)
{
complaint (&symfile_complaints,
_("Offset %d out of bounds for DW_AT_ranges attribute"),
offset);
- return 0;
+ return false;
}
- buffer = dwarf2_per_objfile->ranges.buffer + offset;
+ buffer = dwarf2_per_objfile->rnglists.buffer + offset;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- /* Read in the largest possible address. */
- marker = read_address (obfd, buffer, cu, &dummy);
- if ((marker & mask) == mask)
+ while (1)
{
- /* If we found the largest possible address, then
- read the base address. */
- base = read_address (obfd, buffer + addr_size, cu, &dummy);
- buffer += 2 * addr_size;
- offset += 2 * addr_size;
- found_base = 1;
+ /* Initialize it due to a false compiler warning. */
+ CORE_ADDR range_beginning = 0, range_end = 0;
+ const gdb_byte *buf_end = (dwarf2_per_objfile->rnglists.buffer
+ + dwarf2_per_objfile->rnglists.size);
+ unsigned int bytes_read;
+
+ if (buffer == buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ const auto rlet = static_cast<enum dwarf_range_list_entry>(*buffer++);
+ switch (rlet)
+ {
+ case DW_RLE_end_of_list:
+ break;
+ case DW_RLE_base_address:
+ if (buffer + cu->header.addr_size > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ base = read_address (obfd, buffer, cu, &bytes_read);
+ found_base = 1;
+ buffer += bytes_read;
+ break;
+ case DW_RLE_start_length:
+ if (buffer + cu->header.addr_size > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ range_beginning = read_address (obfd, buffer, cu, &bytes_read);
+ buffer += bytes_read;
+ range_end = (range_beginning
+ + read_unsigned_leb128 (obfd, buffer, &bytes_read));
+ buffer += bytes_read;
+ if (buffer > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ break;
+ case DW_RLE_offset_pair:
+ range_beginning = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+ buffer += bytes_read;
+ if (buffer > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ range_end = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+ buffer += bytes_read;
+ if (buffer > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ break;
+ case DW_RLE_start_end:
+ if (buffer + 2 * cu->header.addr_size > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ range_beginning = read_address (obfd, buffer, cu, &bytes_read);
+ buffer += bytes_read;
+ range_end = read_address (obfd, buffer, cu, &bytes_read);
+ buffer += bytes_read;
+ break;
+ default:
+ complaint (&symfile_complaints,
+ _("Invalid .debug_rnglists data (no base address)"));
+ return false;
+ }
+ if (rlet == DW_RLE_end_of_list || overflow)
+ break;
+ if (rlet == DW_RLE_base_address)
+ continue;
+
+ if (!found_base)
+ {
+ /* We have no valid base address for the ranges
+ data. */
+ complaint (&symfile_complaints,
+ _("Invalid .debug_rnglists data (no base address)"));
+ return false;
+ }
+
+ if (range_beginning > range_end)
+ {
+ /* Inverted range entries are invalid. */
+ complaint (&symfile_complaints,
+ _("Invalid .debug_rnglists data (inverted range)"));
+ return false;
+ }
+
+ /* Empty range entries have no effect. */
+ if (range_beginning == range_end)
+ continue;
+
+ range_beginning += base;
+ range_end += base;
+
+ /* A not-uncommon case of bad debug info.
+ Don't pollute the addrmap with bad data. */
+ if (range_beginning + baseaddr == 0
+ && !dwarf2_per_objfile->has_section_at_zero)
+ {
+ complaint (&symfile_complaints,
+ _(".debug_rnglists entry has start address of zero"
+ " [in module %s]"), objfile_name (objfile));
+ continue;
+ }
+
+ callback (range_beginning, range_end);
}
- low_set = 0;
+ if (overflow)
+ {
+ complaint (&symfile_complaints,
+ _("Offset %d is not terminated "
+ "for DW_AT_ranges attribute"),
+ offset);
+ return false;
+ }
+
+ return true;
+}
+
+/* Call CALLBACK from DW_AT_ranges attribute value OFFSET reading .debug_ranges.
+ Callback's type should be:
+ void (CORE_ADDR range_beginning, CORE_ADDR range_end)
+ Return 1 if the attributes are present and valid, otherwise, return 0. */
+
+template <typename Callback>
+static int
+dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
+ Callback &&callback)
+{
+ struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct comp_unit_head *cu_header = &cu->header;
+ bfd *obfd = objfile->obfd;
+ unsigned int addr_size = cu_header->addr_size;
+ CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
+ /* Base address selection entry. */
+ CORE_ADDR base;
+ int found_base;
+ unsigned int dummy;
+ const gdb_byte *buffer;
+ CORE_ADDR baseaddr;
+
+ if (cu_header->version >= 5)
+ return dwarf2_rnglists_process (offset, cu, callback);
+
+ found_base = cu->base_known;
+ base = cu->base_address;
+
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
+ if (offset >= dwarf2_per_objfile->ranges.size)
+ {
+ complaint (&symfile_complaints,
+ _("Offset %d out of bounds for DW_AT_ranges attribute"),
+ offset);
+ return 0;
+ }
+ buffer = dwarf2_per_objfile->ranges.buffer + offset;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
the base address. Check for a base address here. */
if ((range_beginning & mask) == mask)
{
- /* If we found the largest possible address, then
- read the base address. */
- base = read_address (obfd, buffer + addr_size, cu, &dummy);
+ /* If we found the largest possible address, then we already
+ have the base address in range_end. */
+ base = range_end;
found_base = 1;
continue;
}
continue;
}
+ callback (range_beginning, range_end);
+ }
+
+ return 1;
+}
+
+/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
+ Return 1 if the attributes are present and valid, otherwise, return 0.
+ If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'. */
+
+static int
+dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
+ CORE_ADDR *high_return, struct dwarf2_cu *cu,
+ struct partial_symtab *ranges_pst)
+{
+ struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ const CORE_ADDR baseaddr = ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ int low_set = 0;
+ CORE_ADDR low = 0;
+ CORE_ADDR high = 0;
+ int retval;
+
+ retval = dwarf2_ranges_process (offset, cu,
+ [&] (CORE_ADDR range_beginning, CORE_ADDR range_end)
+ {
if (ranges_pst != NULL)
{
CORE_ADDR lowpc;
if (range_end > high)
high = range_end;
}
- }
+ });
+ if (!retval)
+ return 0;
if (! low_set)
/* If the first entry is an end-of-list marker, the range
return 1;
}
-/* Get low and high pc attributes from a die. Return 1 if the attributes
- are present and valid, otherwise, return 0. Return -1 if the range is
- discontinuous, i.e. derived from DW_AT_ranges information. */
+/* Get low and high pc attributes from a die. See enum pc_bounds_kind
+ definition for the return value. *LOWPC and *HIGHPC are set iff
+ neither PC_BOUNDS_NOT_PRESENT nor PC_BOUNDS_INVALID are returned. */
-static int
+static enum pc_bounds_kind
dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
CORE_ADDR *highpc, struct dwarf2_cu *cu,
struct partial_symtab *pst)
struct attribute *attr_high;
CORE_ADDR low = 0;
CORE_ADDR high = 0;
- int ret = 0;
+ enum pc_bounds_kind ret;
attr_high = dwarf2_attr (die, DW_AT_high_pc, cu);
if (attr_high)
}
else
/* Found high w/o low attribute. */
- return 0;
+ return PC_BOUNDS_INVALID;
/* Found consecutive range of addresses. */
- ret = 1;
+ ret = PC_BOUNDS_HIGH_LOW;
}
else
{
/* Value of the DW_AT_ranges attribute is the offset in the
.debug_ranges section. */
if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst))
- return 0;
+ return PC_BOUNDS_INVALID;
/* Found discontinuous range of addresses. */
- ret = -1;
+ ret = PC_BOUNDS_RANGES;
}
+ else
+ return PC_BOUNDS_NOT_PRESENT;
}
/* read_partial_die has also the strict LOW < HIGH requirement. */
if (high <= low)
- return 0;
+ return PC_BOUNDS_INVALID;
/* When using the GNU linker, .gnu.linkonce. sections are used to
eliminate duplicate copies of functions and vtables and such.
If this is a discarded function, mark the pc bounds as invalid,
so that GDB will ignore it. */
if (low == 0 && !dwarf2_per_objfile->has_section_at_zero)
- return 0;
+ return PC_BOUNDS_INVALID;
*lowpc = low;
if (highpc)
CORE_ADDR low, high;
struct die_info *child = die->child;
- if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL))
+ if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL) >= PC_BOUNDS_RANGES)
{
- *lowpc = min (*lowpc, low);
- *highpc = max (*highpc, high);
+ *lowpc = std::min (*lowpc, low);
+ *highpc = std::max (*highpc, high);
}
/* If the language does not allow nested subprograms (either inside
CORE_ADDR best_high = (CORE_ADDR) 0;
CORE_ADDR current_low, current_high;
- if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu, NULL))
+ if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu, NULL)
+ >= PC_BOUNDS_RANGES)
{
best_low = current_low;
best_high = current_high;
if (current_low != ((CORE_ADDR) -1))
{
- best_low = min (best_low, current_low);
- best_high = max (best_high, current_high);
+ best_low = std::min (best_low, current_low);
+ best_high = std::max (best_high, current_high);
}
break;
default:
CORE_ADDR base = cu->base_address;
int base_known = cu->base_known;
- dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
- if (offset >= dwarf2_per_objfile->ranges.size)
- {
- complaint (&symfile_complaints,
- _("Offset %lu out of bounds for DW_AT_ranges attribute"),
- offset);
- return;
- }
- buffer = dwarf2_per_objfile->ranges.buffer + offset;
-
- for (;;)
- {
- unsigned int bytes_read;
- CORE_ADDR start, end;
-
- start = read_address (obfd, buffer, cu, &bytes_read);
- buffer += bytes_read;
- end = read_address (obfd, buffer, cu, &bytes_read);
- buffer += bytes_read;
-
- /* Did we find the end of the range list? */
- if (start == 0 && end == 0)
- break;
-
- /* Did we find a base address selection entry? */
- else if ((start & base_select_mask) == base_select_mask)
- {
- base = end;
- base_known = 1;
- }
-
- /* We found an ordinary address range. */
- else
- {
- if (!base_known)
- {
- complaint (&symfile_complaints,
- _("Invalid .debug_ranges data "
- "(no base address)"));
- return;
- }
-
- if (start > end)
- {
- /* Inverted range entries are invalid. */
- complaint (&symfile_complaints,
- _("Invalid .debug_ranges data "
- "(inverted range)"));
- return;
- }
-
- /* Empty range entries have no effect. */
- if (start == end)
- continue;
-
- start += base + baseaddr;
- end += base + baseaddr;
-
- /* A not-uncommon case of bad debug info.
- Don't pollute the addrmap with bad data. */
- if (start == 0 && !dwarf2_per_objfile->has_section_at_zero)
- {
- complaint (&symfile_complaints,
- _(".debug_ranges entry has start address of zero"
- " [in module %s]"), objfile_name (objfile));
- continue;
- }
-
- start = gdbarch_adjust_dwarf2_addr (gdbarch, start);
- end = gdbarch_adjust_dwarf2_addr (gdbarch, end);
- record_block_range (block, start, end - 1);
- }
- }
+ dwarf2_ranges_process (offset, cu,
+ [&] (CORE_ADDR start, CORE_ADDR end)
+ {
+ start += baseaddr;
+ end += baseaddr;
+ start = gdbarch_adjust_dwarf2_addr (gdbarch, start);
+ end = gdbarch_adjust_dwarf2_addr (gdbarch, end);
+ record_block_range (block, start, end - 1);
+ });
}
}
static void
check_producer (struct dwarf2_cu *cu)
{
- const char *cs;
int major, minor;
if (cu->producer == NULL)
combination. gcc-4.5.x -gdwarf-4 binaries have DW_AT_accessibility
interpreted incorrectly by GDB now - GCC PR debug/48229. */
}
- else if ((major = producer_is_gcc (cu->producer, &minor)) > 0)
+ else if (producer_is_gcc (cu->producer, &major, &minor))
{
cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
}
- else if (strncmp (cu->producer, "Intel(R) C", strlen ("Intel(R) C")) == 0)
+ else if (startswith (cu->producer, "Intel(R) C"))
cu->producer_is_icc = 1;
else
{
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;
dwarf2_is_constructor (struct die_info *die, struct dwarf2_cu *cu)
{
const char *fieldname;
- const char *typename;
+ const char *type_name;
int len;
if (die->parent == NULL)
return 0;
fieldname = dwarf2_name (die, cu);
- typename = dwarf2_name (die->parent, cu);
- if (fieldname == NULL || typename == NULL)
+ type_name = dwarf2_name (die->parent, cu);
+ if (fieldname == NULL || type_name == NULL)
return 0;
len = strlen (fieldname);
- return (strncmp (fieldname, typename, len) == 0
- && (typename[len] == '\0' || typename[len] == '<'));
+ return (strncmp (fieldname, type_name, len) == 0
+ && (type_name[len] == '\0' || type_name[len] == '<'));
}
/* Add a member function to the proper fieldlist. */
/* 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 ();
dwarf2_complex_location_expr_complaint ();
if (!fnp->fcontext)
- fnp->fcontext = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (this_type, 0));
+ {
+ /* If there is no `this' field and no DW_AT_containing_type,
+ we cannot actually find a base class context for the
+ vtable! */
+ if (TYPE_NFIELDS (this_type) == 0
+ || !TYPE_FIELD_ARTIFICIAL (this_type, 0))
+ {
+ complaint (&symfile_complaints,
+ _("cannot determine context for virtual member "
+ "function \"%s\" (offset %d)"),
+ fieldname, die->offset.sect_off);
+ }
+ else
+ {
+ fnp->fcontext
+ = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (this_type, 0));
+ }
+ }
}
else if (attr_form_is_section_offset (attr))
{
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
- && strncmp (name, vtable, sizeof (vtable) - 1) == 0)
- || (strncmp (name, vptr, sizeof (vptr) - 1) == 0
- && 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;
static void
quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
{
- struct type *pfn_type, *domain_type, *new_type;
+ struct type *pfn_type, *self_type, *new_type;
/* Check for a structure with no name and two children. */
if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2)
|| TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
return;
- domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
+ self_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
new_type = alloc_type (objfile);
- smash_to_method_type (new_type, domain_type, TYPE_TARGET_TYPE (pfn_type),
+ smash_to_method_type (new_type, self_type, TYPE_TARGET_TYPE (pfn_type),
TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
TYPE_VARARGS (pfn_type));
smash_to_methodptr_type (type, new_type);
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)
{
struct type *t = die_containing_type (die, cu);
- TYPE_VPTR_BASETYPE (type) = t;
+ set_type_vptr_basetype (type, t);
if (type == t)
{
int i;
if (is_vtable_name (fieldname, cu))
{
- TYPE_VPTR_FIELDNO (type) = i;
+ set_type_vptr_fieldno (type, i);
break;
}
}
}
else
{
- TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (t);
+ set_type_vptr_fieldno (type, TYPE_VPTR_FIELDNO (t));
}
}
else if (cu->producer
- && strncmp (cu->producer,
- "IBM(R) XL C/C++ Advanced Edition", 32) == 0)
+ && startswith (cu->producer, "IBM(R) XL C/C++ Advanced Edition"))
{
/* The IBM XLC compiler does not provide direct indication
of the containing type, but the vtable pointer is
{
if (strcmp (TYPE_FIELD_NAME (type, i), "__vfp") == 0)
{
- TYPE_VPTR_FIELDNO (type) = i;
- TYPE_VPTR_BASETYPE (type) = type;
+ set_type_vptr_fieldno (type, i);
+ set_type_vptr_basetype (type, type);
break;
}
}
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);
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;
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;
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);
}
}
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);
+ type = init_type (objfile, TYPE_CODE_MODULE, 0, module_name);
/* determine_prefix uses TYPE_TAG_NAME. */
TYPE_TAG_NAME (type) = TYPE_NAME (type);
current_die != NULL;
current_die = dwarf2_extension (die, &cu))
{
- name = dwarf2_name (current_die, cu);
+ /* We don't use dwarf2_name here so that we can detect the absence
+ of a name -> anonymous namespace. */
+ name = dwarf2_string_attr (die, DW_AT_name, cu);
+
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)
{
return set_die_type (die, cv_type, cu);
}
+/* Handle DW_TAG_atomic_type. */
+
+static struct type *
+read_tag_atomic_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct type *base_type, *cv_type;
+
+ base_type = die_type (die, cu);
+
+ /* The die_type call above may have already set the type for this DIE. */
+ cv_type = get_die_type (die, cu);
+ if (cv_type)
+ return cv_type;
+
+ cv_type = make_atomic_type (base_type);
+ return set_die_type (die, cv_type, cu);
+}
+
/* Extract all information from a DW_TAG_string_type DIE and add to
the user defined type vector. It isn't really a user defined type,
but it behaves like one, with other DIE's using an AT_user_def_type
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)
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
- && strncmp (name, "character(", sizeof ("character(") - 1) == 0)
- code = TYPE_CODE_CHAR;
+ && startswith (name, "character("))
+ type = init_character_type (objfile, bits, 1, name);
+ else
+ type = init_integer_type (objfile, bits, 1, name);
break;
case DW_ATE_signed_char:
if (cu->language == language_ada || cu->language == language_m2
|| cu->language == language_pascal
|| cu->language == language_fortran)
- code = TYPE_CODE_CHAR;
+ type = init_character_type (objfile, bits, 0, name);
+ else
+ type = init_integer_type (objfile, bits, 0, name);
break;
case DW_ATE_unsigned_char:
if (cu->language == language_ada || cu->language == language_m2
|| cu->language == language_pascal
- || cu->language == language_fortran)
- code = TYPE_CODE_CHAR;
- type_flags |= TYPE_FLAG_UNSIGNED;
+ || cu->language == language_fortran
+ || cu->language == language_rust)
+ type = init_character_type (objfile, bits, 1, name);
+ else
+ type = init_integer_type (objfile, bits, 1, name);
break;
case DW_ATE_UTF:
/* We just treat this as an integer and then recognize the
type by name elsewhere. */
+ type = init_integer_type (objfile, bits, 0, name);
break;
default:
complaint (&symfile_complaints, _("unsupported DW_AT_encoding: '%s'"),
dwarf_type_encoding_name (encoding));
+ type = init_type (objfile, TYPE_CODE_ERROR,
+ bits / TARGET_CHAR_BIT, name);
break;
}
- type = init_type (code, size, type_flags, NULL, objfile);
- TYPE_NAME (type) = name;
- TYPE_TARGET_TYPE (type) = target_type;
-
if (name && strcmp (name, "char") == 0)
TYPE_NOSIGN (type) = 1;
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;
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;
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;
}
abbrev_table = XNEW (struct abbrev_table);
abbrev_table->offset = offset;
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 *));
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);
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;
}
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;
*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
case DW_AT_byte_size:
part_die->has_byte_size = 1;
break;
+ case DW_AT_const_value:
+ part_die->has_const_value = 1;
+ break;
case DW_AT_calling_convention:
/* DWARF doesn't provide a way to identify a program's source-level
entry point. DW_AT_calling_convention attributes are only meant
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
}
break;
+ case DW_AT_main_subprogram:
+ part_die->main_subprogram = DW_UNSND (&attr);
+ break;
+
default:
break;
}
struct partial_die_info part_die;
part_die.offset = offset;
- lookup_die = htab_find_with_hash (cu->partial_dies, &part_die,
- offset.sect_off);
+ lookup_die = ((struct partial_die_info *)
+ htab_find_with_hash (cu->partial_dies, &part_die,
+ offset.sect_off));
return lookup_die;
}
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 ();
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);
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_Fortran77:
case DW_LANG_Fortran90:
case DW_LANG_Fortran95:
+ case DW_LANG_Fortran03:
+ case DW_LANG_Fortran08:
cu->language = language_fortran;
break;
case DW_LANG_Go:
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), die->offset.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. */
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);
}
static void
add_include_dir (struct line_header *lh, const char *include_dir)
{
+ if (dwarf_line_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "Adding dir %u: %s\n",
+ lh->num_include_dirs + 1, include_dir);
+
/* Grow the array if necessary. */
if (lh->include_dirs_size == 0)
{
lh->include_dirs_size = 1; /* for testing */
- lh->include_dirs = xmalloc (lh->include_dirs_size
- * sizeof (*lh->include_dirs));
+ lh->include_dirs = XNEWVEC (const char *, lh->include_dirs_size);
}
else if (lh->num_include_dirs >= lh->include_dirs_size)
{
lh->include_dirs_size *= 2;
- lh->include_dirs = xrealloc (lh->include_dirs,
- (lh->include_dirs_size
- * sizeof (*lh->include_dirs)));
+ lh->include_dirs = XRESIZEVEC (const char *, lh->include_dirs,
+ lh->include_dirs_size);
}
lh->include_dirs[lh->num_include_dirs++] = include_dir;
{
struct file_entry *fe;
+ if (dwarf_line_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "Adding file %u: %s\n",
+ lh->num_file_names + 1, name);
+
/* Grow the array if necessary. */
if (lh->file_names_size == 0)
{
lh->file_names_size = 1; /* for testing */
- lh->file_names = xmalloc (lh->file_names_size
- * sizeof (*lh->file_names));
+ lh->file_names = XNEWVEC (struct file_entry, lh->file_names_size);
}
else if (lh->num_file_names >= lh->file_names_size)
{
lh->file_names_size *= 2;
- lh->file_names = xrealloc (lh->file_names,
- (lh->file_names_size
- * sizeof (*lh->file_names)));
+ lh->file_names
+ = XRESIZEVEC (struct file_entry, lh->file_names, lh->file_names_size);
}
fe = &lh->file_names[lh->num_file_names++];
fe->symtab = NULL;
}
-/* 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)
+{
+ struct dwarf2_section_info *section;
+
+ /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
+ DWO file. */
+ if (cu->dwo_unit && cu->per_cu->is_debug_types)
+ section = &cu->dwo_unit->dwo_file->sections.line;
+ else if (cu->per_cu->is_dwz)
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+
+ section = &dwz->line;
+ }
+ else
+ section = &dwarf2_per_objfile->line;
+
+ return section;
+}
+
+/* Forwarding function for read_formatted_entries. */
+
+static void
+add_include_dir_stub (struct line_header *lh, const char *name,
+ unsigned int dir_index, unsigned int mod_time,
+ unsigned int length)
+{
+ add_include_dir (lh, name);
+}
+
+/* Read directory or file name entry format, starting with byte of
+ format count entries, ULEB128 pairs of entry formats, ULEB128 of
+ entries count and the entries themselves in the described entry
+ 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,
+ unsigned int dir_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;
+
+ memset (&fe, 0, sizeof (fe));
+
+ for (formati = 0; formati < format_count; formati++)
+ {
+ ULONGEST content_type, form;
+ const char *string_trash;
+ const char **stringp = &string_trash;
+ unsigned int uint_trash, *uintp = &uint_trash;
+
+ content_type = read_unsigned_leb128 (abfd, format, &bytes_read);
+ format += bytes_read;
+ switch (content_type)
+ {
+ case DW_LNCT_path:
+ stringp = &fe.name;
+ break;
+ case DW_LNCT_directory_index:
+ uintp = &fe.dir_index;
+ break;
+ case DW_LNCT_timestamp:
+ uintp = &fe.mod_time;
+ break;
+ case DW_LNCT_size:
+ uintp = &fe.length;
+ break;
+ case DW_LNCT_MD5:
+ break;
+ default:
+ complaint (&symfile_complaints,
+ _("Unknown format content type %s"),
+ pulongest (content_type));
+ }
+
+ form = read_unsigned_leb128 (abfd, format, &bytes_read);
+ format += bytes_read;
+ switch (form)
+ {
+ case DW_FORM_string:
+ *stringp = read_direct_string (abfd, buf, &bytes_read);
+ buf += bytes_read;
+ break;
+
+ case DW_FORM_line_strp:
+ *stringp = read_indirect_line_string (abfd, buf, cu_header, &bytes_read);
+ buf += bytes_read;
+ break;
-static struct dwarf2_section_info *
-get_debug_line_section (struct dwarf2_cu *cu)
-{
- struct dwarf2_section_info *section;
+ case DW_FORM_data1:
+ *uintp = read_1_byte (abfd, buf);
+ buf += 1;
+ break;
- /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
- DWO file. */
- if (cu->dwo_unit && cu->per_cu->is_debug_types)
- section = &cu->dwo_unit->dwo_file->sections.line;
- else if (cu->per_cu->is_dwz)
- {
- struct dwz_file *dwz = dwarf2_get_dwz_file ();
+ case DW_FORM_data2:
+ *uintp = read_2_bytes (abfd, buf);
+ buf += 2;
+ break;
- section = &dwz->line;
+ case DW_FORM_data4:
+ *uintp = read_4_bytes (abfd, buf);
+ buf += 4;
+ break;
+
+ case DW_FORM_data8:
+ *uintp = read_8_bytes (abfd, buf);
+ buf += 8;
+ break;
+
+ case DW_FORM_udata:
+ *uintp = 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;
+ }
+ }
+
+ callback (lh, fe.name, fe.dir_index, fe.mod_time, fe.length);
}
- else
- section = &dwarf2_per_objfile->line;
- return section;
+ *bufp = buf;
}
/* Read the statement program header starting at OFFSET in
return 0;
}
- lh = xmalloc (sizeof (*lh));
+ lh = XNEW (struct line_header);
memset (lh, 0, sizeof (*lh));
back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
(void *) lh);
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 = XNEWVEC (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);
- }
- line_ptr += bytes_read;
+ /* Read directory table. */
+ read_formatted_entries (abfd, &line_ptr, lh, &cu->header,
+ add_include_dir_stub);
- /* Read file name table. */
- while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
+ /* Read file name table. */
+ read_formatted_entries (abfd, &line_ptr, lh, &cu->header, add_file_name);
+ }
+ 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;
+ add_include_dir (lh, 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 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);
+ line_ptr += bytes_read;
+
+ add_file_name (lh, cur_file, dir_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))
char *copied_name = NULL;
int file_is_pst;
- if (fe.dir_index)
+ if (fe.dir_index && lh->include_dirs != NULL)
dir_name = lh->include_dirs[fe.dir_index - 1];
if (!IS_ABSOLUTE_PATH (include_name)
return include_name;
}
+/* State machine to track the state of the line number program. */
+
+typedef struct
+{
+ /* These are part of the standard DWARF line number state machine. */
+
+ unsigned char op_index;
+ unsigned int file;
+ unsigned int line;
+ CORE_ADDR address;
+ int is_stmt;
+ unsigned int discriminator;
+
+ /* Additional bits of state we need to track. */
+
+ /* The last file that we called dwarf2_start_subfile for.
+ This is only used for TLLs. */
+ unsigned int last_file;
+ /* The last file a line number was recorded for. */
+ struct subfile *last_subfile;
+
+ /* The function to call to record a line. */
+ record_line_ftype *record_line;
+
+ /* The last line number that was recorded, used to coalesce
+ consecutive entries for the same line. This can happen, for
+ example, when discriminators are present. PR 17276. */
+ unsigned int last_line;
+ int line_has_non_zero_discriminator;
+} lnp_state_machine;
+
+/* There's a lot of static state to pass to dwarf_record_line.
+ This keeps it all together. */
+
+typedef struct
+{
+ /* The gdbarch. */
+ struct gdbarch *gdbarch;
+
+ /* The line number header. */
+ struct line_header *line_header;
+
+ /* Non-zero if we're recording lines.
+ Otherwise we're building partial symtabs and are just interested in
+ finding include files mentioned by the line number program. */
+ int record_lines_p;
+} lnp_reader_state;
+
/* Ignore this record_line request. */
static void
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);
+}
+
+/* Record the line in STATE.
+ END_SEQUENCE is non-zero if we're processing the end of a sequence. */
+
+static void
+dwarf_record_line (lnp_reader_state *reader, lnp_state_machine *state,
+ int end_sequence)
+{
+ const struct line_header *lh = reader->line_header;
+ unsigned int file, line, discriminator;
+ int is_stmt;
+
+ file = state->file;
+ line = state->line;
+ is_stmt = state->is_stmt;
+ discriminator = state->discriminator;
+
+ if (dwarf_line_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Processing actual line %u: file %u,"
+ " address %s, is_stmt %u, discrim %u\n",
+ line, file,
+ paddress (reader->gdbarch, state->address),
+ is_stmt, discriminator);
+ }
+
+ if (file == 0 || file - 1 >= lh->num_file_names)
+ dwarf2_debug_line_missing_file_complaint ();
+ /* For now we ignore lines not starting on an instruction boundary.
+ But not when processing end_sequence for compatibility with the
+ previous version of the code. */
+ else if (state->op_index == 0 || end_sequence)
+ {
+ lh->file_names[file - 1].included_p = 1;
+ if (reader->record_lines_p && is_stmt)
+ {
+ if (state->last_subfile != current_subfile || end_sequence)
+ {
+ dwarf_finish_line (reader->gdbarch, state->last_subfile,
+ state->address, state->record_line);
+ }
+
+ if (!end_sequence)
+ {
+ if (dwarf_record_line_p (line, state->last_line,
+ state->line_has_non_zero_discriminator,
+ state->last_subfile))
+ {
+ dwarf_record_line_1 (reader->gdbarch, current_subfile,
+ line, state->address,
+ state->record_line);
+ }
+ state->last_subfile = current_subfile;
+ state->last_line = line;
+ }
+ }
+ }
+}
+
+/* Initialize STATE for the start of a line number program. */
+
+static void
+init_lnp_state_machine (lnp_state_machine *state,
+ const lnp_reader_state *reader)
+{
+ memset (state, 0, sizeof (*state));
+
+ /* Just starting, there is no "last file". */
+ state->last_file = 0;
+ state->last_subfile = NULL;
+
+ state->record_line = record_line;
+
+ state->last_line = 0;
+ state->line_has_non_zero_discriminator = 0;
+
+ /* Initialize these according to the DWARF spec. */
+ state->op_index = 0;
+ state->file = 1;
+ state->line = 1;
+ /* Call `gdbarch_adjust_dwarf2_line' on the initial 0 address as if there
+ was a line entry for it so that the backend has a chance to adjust it
+ and also record it in case it needs it. This is currently used by MIPS
+ code, cf. `mips_adjust_dwarf2_line'. */
+ state->address = gdbarch_adjust_dwarf2_line (reader->gdbarch, 0, 0);
+ state->is_stmt = reader->line_header->default_is_stmt;
+ state->discriminator = 0;
+}
+
+/* Check address and if invalid nop-out the rest of the lines in this
+ sequence. */
+
+static void
+check_line_address (struct dwarf2_cu *cu, lnp_state_machine *state,
+ const gdb_byte *line_ptr,
+ CORE_ADDR lowpc, CORE_ADDR address)
+{
+ /* 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));
+ state->record_line = noop_record_line;
+ /* Note: sm.record_line 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;
+ /* Non-zero if we're recording line info (as opposed to building partial
+ symtabs). */
+ int record_lines_p = !decode_for_pst_p;
+ /* A collection of things we need to pass to dwarf_record_line. */
+ lnp_reader_state reader_state;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
line_ptr = lh->statement_program_start;
line_end = lh->statement_program_end;
+ reader_state.gdbarch = gdbarch;
+ reader_state.line_header = lh;
+ reader_state.record_lines_p = record_lines_p;
+
/* Read the statement sequences until there's nothing left. */
while (line_ptr < line_end)
{
- /* 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;
+ /* The DWARF line number program state machine. */
+ lnp_state_machine state_machine;
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)
+
+ /* Reset the state machine at the start of each sequence. */
+ init_lnp_state_machine (&state_machine, &reader_state);
+
+ if (record_lines_p && lh->num_file_names >= state_machine.file)
{
/* 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];
+ struct file_entry *fe = &lh->file_names[state_machine.file - 1];
const char *dir = NULL;
- if (fe->dir_index)
+ if (fe->dir_index && lh->include_dirs != NULL)
dir = lh->include_dirs[fe->dir_index - 1];
dwarf2_start_subfile (fe->name, dir);
}
/* 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)
{
int line_delta;
adj_opcode = op_code - lh->opcode_base;
- addr_adj = (((op_index + (adj_opcode / lh->line_range))
+ addr_adj = (((state_machine.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);
+ state_machine.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = ((state_machine.op_index
+ + (adj_opcode / lh->line_range))
+ % lh->maximum_ops_per_instruction);
line_delta = lh->line_base + (adj_opcode % lh->line_range);
- line += line_delta;
+ state_machine.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.line_has_non_zero_discriminator
+ = state_machine.discriminator != 0;
+
+ dwarf_record_line (&reader_state, &state_machine, 0);
+ state_machine.discriminator = 0;
}
else switch (op_code)
{
switch (extended_op)
{
case DW_LNE_end_sequence:
- p_record_line = record_line;
+ state_machine.record_line = record_line;
end_sequence = 1;
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);
- op_index = 0;
- line_ptr += bytes_read;
- address += baseaddr;
- address = gdbarch_adjust_dwarf2_line (gdbarch, address, 0);
+ line_ptr += bytes_read;
+ check_line_address (cu, &state_machine, line_ptr,
+ lowpc, address);
+ state_machine.op_index = 0;
+ address += baseaddr;
+ state_machine.address
+ = gdbarch_adjust_dwarf2_line (gdbarch, address, 0);
+ }
break;
case DW_LNE_define_file:
{
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;
+ state_machine.discriminator
+ = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ state_machine.line_has_non_zero_discriminator
+ |= state_machine.discriminator != 0;
line_ptr += bytes_read;
break;
default:
}
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;
+ dwarf_record_line (&reader_state, &state_machine, 0);
+ state_machine.discriminator = 0;
break;
case DW_LNS_advance_pc:
{
= read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
CORE_ADDR addr_adj;
- addr_adj = (((op_index + adjust)
+ addr_adj = (((state_machine.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.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = ((state_machine.op_index + adjust)
+ % lh->maximum_ops_per_instruction);
line_ptr += bytes_read;
}
break;
int line_delta
= read_signed_leb128 (abfd, line_ptr, &bytes_read);
- line += line_delta;
+ state_machine.line += line_delta;
if (line_delta != 0)
- line_has_non_zero_discriminator = discriminator != 0;
+ state_machine.line_has_non_zero_discriminator
+ = state_machine.discriminator != 0;
line_ptr += bytes_read;
}
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);
- }
- }
- }
+ {
+ /* The arrays lh->include_dirs and lh->file_names are
+ 0-based, but the directory and file name numbers in
+ the statement program are 1-based. */
+ struct file_entry *fe;
+ const char *dir = NULL;
+
+ state_machine.file = read_unsigned_leb128 (abfd, line_ptr,
+ &bytes_read);
+ line_ptr += bytes_read;
+ if (state_machine.file == 0
+ || state_machine.file - 1 >= lh->num_file_names)
+ dwarf2_debug_line_missing_file_complaint ();
+ else
+ {
+ fe = &lh->file_names[state_machine.file - 1];
+ if (fe->dir_index && lh->include_dirs != NULL)
+ dir = lh->include_dirs[fe->dir_index - 1];
+ if (record_lines_p)
+ {
+ state_machine.last_subfile = current_subfile;
+ state_machine.line_has_non_zero_discriminator
+ = state_machine.discriminator != 0;
+ dwarf2_start_subfile (fe->name, dir);
+ }
+ }
+ }
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.is_stmt = (!state_machine.is_stmt);
break;
case DW_LNS_set_basic_block:
break;
CORE_ADDR adjust = (255 - lh->opcode_base) / lh->line_range;
CORE_ADDR addr_adj;
- addr_adj = (((op_index + adjust)
+ addr_adj = (((state_machine.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.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = ((state_machine.op_index + adjust)
+ % lh->maximum_ops_per_instruction);
}
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;
+ state_machine.address
+ += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
+ state_machine.op_index = 0;
line_ptr += 2;
}
break;
}
}
}
- 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). */
+ dwarf_record_line (&reader_state, &state_machine, 1);
}
}
struct file_entry *fe;
fe = &lh->file_names[i];
- if (fe->dir_index)
+ if (fe->dir_index && lh->include_dirs != NULL)
dir = lh->include_dirs[fe->dir_index - 1];
dwarf2_start_subfile (fe->name, dir);
if (cu->language == language_fortran && die->parent
&& die->parent->tag == DW_TAG_module
&& cu->producer
- && strncmp (cu->producer, "GNU Fortran ", 12) == 0)
+ && 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;
objfile_name (objfile),
cu->header.offset.sect_off,
die->offset.sect_off);
- saved = obstack_copy0 (&objfile->objfile_obstack,
- message, strlen (message));
+ 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.
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);
case DW_TAG_module:
this_type = read_module_type (die, cu);
break;
+ case DW_TAG_atomic_type:
+ this_type = read_tag_atomic_type (die, cu);
+ break;
default:
complaint (&symfile_complaints,
_("unexpected tag in read_type_die: '%s'"),
{
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);
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 type *parent_type;
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 name;
}
-/* Get name of a die, return NULL if not found. */
+/* Get name of a die, return NULL if not found.
+ Anonymous namespaces are converted to their magic string. */
static const char *
dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_name, cu);
if ((!attr || !DW_STRING (attr))
+ && die->tag != DW_TAG_namespace
&& die->tag != DW_TAG_class_type
&& die->tag != DW_TAG_interface_type
&& die->tag != DW_TAG_structure_type
to canonicalize them. */
return DW_STRING (attr);
- 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_namespace:
+ if (attr != NULL && DW_STRING (attr) != NULL)
+ return DW_STRING (attr);
+ return CP_ANONYMOUS_NAMESPACE_STR;
case DW_TAG_class_type:
case DW_TAG_interface_type:
or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
and GCC 4.4. We work around this problem by ignoring these. */
if (attr && DW_STRING (attr)
- && (strncmp (DW_STRING (attr), "._", 2) == 0
- || strncmp (DW_STRING (attr), "<anonymous", 10) == 0))
+ && (startswith (DW_STRING (attr), "._")
+ || startswith (DW_STRING (attr), "<anonymous")))
return NULL;
/* GCC might emit a nameless typedef that has a linkage name. See
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);
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)",
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));
*ref_cu = target_cu;
temp_die.offset = offset;
- return htab_find_with_hash (target_cu->die_hash, &temp_die, offset.sect_off);
+ return (struct die_info *) htab_find_with_hash (target_cu->die_hash,
+ &temp_die, offset.sect_off);
}
/* Follow reference attribute ATTR of SRC_DIE.
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"),
+ offset.sect_off, objfile_name (per_cu->objfile));
+ }
die = follow_die_offset (offset, per_cu->is_dwz, &cu);
if (!die)
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;
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"),
+ offset.sect_off, objfile_name (per_cu->objfile));
+ }
die = follow_die_offset (offset, per_cu->is_dwz, &cu);
if (!die)
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 offset,
+ 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 (offset, 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. */
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;
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);
+ die = (struct die_info *) htab_find_with_hash (sig_cu->die_hash, &temp_die,
+ temp_die.offset.sect_off);
if (die)
{
/* For .gdb_index version 7 keep track of included TUs.
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 *
{
struct file_entry *fe = &lh->file_names[file - 1];
- if (IS_ABSOLUTE_PATH (fe->name) || fe->dir_index == 0)
+ if (IS_ABSOLUTE_PATH (fe->name) || fe->dir_index == 0
+ || lh->include_dirs == NULL)
return xstrdup (fe->name);
return concat (lh->include_dirs[fe->dir_index - 1], SLASH_STRING,
- fe->name, NULL);
+ fe->name, (char *) NULL);
}
else
{
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);
info_ptr = per_cu->section->buffer + per_cu->offset.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. */
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;
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;
}
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);
if (need_gnat_info (cu)
&& TYPE_CODE (type) != TYPE_CODE_FUNC
&& TYPE_CODE (type) != TYPE_CODE_FLT
+ && TYPE_CODE (type) != TYPE_CODE_METHODPTR
+ && TYPE_CODE (type) != TYPE_CODE_MEMBERPTR
+ && TYPE_CODE (type) != TYPE_CODE_METHOD
&& !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"),
+ die->offset.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"),
+ die->offset.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))
- {
- TYPE_DATA_LOCATION (type)
- = obstack_alloc (&objfile->objfile_obstack, sizeof (prop));
- *TYPE_DATA_LOCATION (type) = prop;
- }
+ add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type, objfile);
if (dwarf2_per_objfile->die_type_hash == NULL)
{
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));
+ *slot = XOBNEW (&objfile->objfile_obstack,
+ struct dwarf2_per_cu_offset_and_type);
**slot = ofs;
return type;
}
ofs.per_cu = per_cu;
ofs.offset = offset;
- slot = htab_find (dwarf2_per_objfile->die_type_hash, &ofs);
+ slot = ((struct dwarf2_per_cu_offset_and_type *)
+ htab_find (dwarf2_per_objfile->die_type_hash, &ofs));
if (slot)
return slot->type;
else
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;
}
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;
}
-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];
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;
}
/* 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)
{
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ERROR)
+ TRY
{
write_psymtabs_to_index (objfile, arg);
}
- if (except.reason < 0)
- exception_fprintf (gdb_stderr, except,
- _("Error while writing index for `%s': "),
- objfile_name (objfile));
+ CATCH (except, RETURN_MASK_ERROR)
+ {
+ exception_fprintf (gdb_stderr, except,
+ _("Error while writing index for `%s': "),
+ objfile_name (objfile));
+ }
+ END_CATCH
}
}
}
\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."), _("\