/* DWARF 2 debugging format support for GDB.
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008, 2009
+ 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
#include "gdbcmd.h"
#include "block.h"
#include "addrmap.h"
+#include "typeprint.h"
+#include "jv-lang.h"
+#include "psympriv.h"
#include <fcntl.h>
#include "gdb_string.h"
#endif
#ifdef HAVE_MMAP
#include <sys/mman.h>
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *) -1)
+#endif
#endif
#if 0
#define _ACTUAL_COMP_UNIT_HEADER_SIZE 11
#endif
-/* .debug_pubnames header
- Because of alignment constraints, this structure has padding and cannot
- be mapped directly onto the beginning of the .debug_info section. */
-typedef struct pubnames_header
- {
- unsigned int length; /* length of the .debug_pubnames
- contribution */
- unsigned char version; /* version number -- 2 for DWARF
- version 2 */
- unsigned int info_offset; /* offset into .debug_info section */
- unsigned int info_size; /* byte size of .debug_info section
- portion */
- }
-_PUBNAMES_HEADER;
-#define _ACTUAL_PUBNAMES_HEADER_SIZE 13
-
-/* .debug_pubnames header
- Because of alignment constraints, this structure has padding and cannot
- be mapped directly onto the beginning of the .debug_info section. */
-typedef struct aranges_header
- {
- unsigned int length; /* byte len of the .debug_aranges
- contribution */
- unsigned short version; /* version number -- 2 for DWARF
- version 2 */
- unsigned int info_offset; /* offset into .debug_info section */
- unsigned char addr_size; /* byte size of an address */
- unsigned char seg_size; /* byte size of segment descriptor */
- }
-_ARANGES_HEADER;
-#define _ACTUAL_ARANGES_HEADER_SIZE 12
-
/* .debug_line statement program prologue
Because of alignment constraints, this structure has padding and cannot
be mapped directly onto the beginning of the .debug_info section. */
gdb_byte *buffer;
bfd_size_type size;
int was_mmapped;
+ /* True if we have tried to read this section. */
+ int readin;
};
struct dwarf2_per_objfile
struct dwarf2_section_info info;
struct dwarf2_section_info abbrev;
struct dwarf2_section_info line;
- struct dwarf2_section_info pubnames;
- struct dwarf2_section_info aranges;
struct dwarf2_section_info loc;
struct dwarf2_section_info macinfo;
struct dwarf2_section_info str;
struct dwarf2_section_info ranges;
+ struct dwarf2_section_info types;
struct dwarf2_section_info frame;
struct dwarf2_section_info eh_frame;
+ /* Back link. */
+ struct objfile *objfile;
+
/* A list of all the compilation units. This is used to locate
the target compilation unit of a particular reference. */
struct dwarf2_per_cu_data **all_comp_units;
they can be freed later. */
struct dwarf2_per_cu_data *read_in_chain;
+ /* A table mapping .debug_types signatures to its signatured_type entry.
+ This is NULL if the .debug_types section hasn't been read in yet. */
+ htab_t signatured_types;
+
/* A flag indicating wether this objfile has a section loaded at a
VMA of 0. */
int has_section_at_zero;
#define INFO_SECTION "debug_info"
#define ABBREV_SECTION "debug_abbrev"
#define LINE_SECTION "debug_line"
-#define PUBNAMES_SECTION "debug_pubnames"
-#define ARANGES_SECTION "debug_aranges"
#define LOC_SECTION "debug_loc"
#define MACINFO_SECTION "debug_macinfo"
#define STR_SECTION "debug_str"
#define RANGES_SECTION "debug_ranges"
+#define TYPES_SECTION "debug_types"
#define FRAME_SECTION "debug_frame"
#define EH_FRAME_SECTION "eh_frame"
/* Hash table holding all the loaded partial DIEs. */
htab_t partial_dies;
- /* `.debug_ranges' offset for this `DW_TAG_compile_unit' DIE. */
- unsigned int ranges_offset;
-
/* Storage for things with the same lifetime as this read-in compilation
unit, including partial DIEs. */
struct obstack comp_unit_obstack;
DIEs for namespaces, we don't need to try to infer them
from mangled names. */
unsigned int has_namespace_info : 1;
-
- /* Field `ranges_offset' is filled in; flag as the value may be zero. */
- unsigned int has_ranges_offset : 1;
};
/* Persistent data held for a compilation unit, even when not
struct dwarf2_per_cu_data
{
- /* The start offset and length of this compilation unit. 2**30-1
+ /* The start offset and length of this compilation unit. 2**29-1
bytes should suffice to store the length of any compilation unit
- if it doesn't, GDB will fall over anyway.
NOTE: Unlike comp_unit_head.length, this length includes
initial_length_size. */
unsigned int offset;
- unsigned int length : 30;
+ unsigned int length : 29;
/* Flag indicating this compilation unit will be read in before
any of the current compilation units are processed. */
hash table and don't find it. */
unsigned int load_all_dies : 1;
+ /* Non-zero if this CU is from .debug_types.
+ Otherwise it's from .debug_info. */
+ unsigned int from_debug_types : 1;
+
/* Set iff currently read in. */
struct dwarf2_cu *cu;
struct partial_symtab *psymtab;
};
+/* Entry in the signatured_types hash table. */
+
+struct signatured_type
+{
+ ULONGEST signature;
+
+ /* Offset in .debug_types of the TU (type_unit) for this type. */
+ unsigned int offset;
+
+ /* Offset in .debug_types of the type defined by this TU. */
+ unsigned int type_offset;
+
+ /* The CU(/TU) of this type. */
+ struct dwarf2_per_cu_data per_cu;
+};
+
/* Struct used to pass misc. parameters to read_die_and_children, et. al.
which are used for both .debug_info and .debug_types dies.
All parameters here are unchanging for the life of the call.
unsigned short version;
unsigned int header_length;
unsigned char minimum_instruction_length;
+ unsigned char maximum_ops_per_instruction;
unsigned char default_is_stmt;
int line_base;
unsigned char line_range;
/* DWARF-2 tag for this DIE. */
ENUM_BITFIELD(dwarf_tag) tag : 16;
- /* Language code associated with this DIE. This is only used
- for the compilation unit DIE. */
- unsigned int language : 8;
-
/* Assorted flags describing the data found in this DIE. */
unsigned int has_children : 1;
unsigned int is_external : 1;
unsigned int is_declaration : 1;
unsigned int has_type : 1;
unsigned int has_specification : 1;
- unsigned int has_stmt_list : 1;
unsigned int has_pc_info : 1;
/* Flag set if the SCOPE field of this structure has been
unsigned int has_byte_size : 1;
/* The name of this DIE. Normally the value of DW_AT_name, but
- sometimes DW_TAG_MIPS_linkage_name or a string computed in some
- other fashion. */
+ sometimes a default name for unnamed DIEs. */
char *name;
- char *dirname;
/* The scope to prepend to our children. This is generally
allocated on the comp_unit_obstack, so will disappear
DW_AT_extension). */
unsigned int spec_offset;
- /* If HAS_STMT_LIST, the offset of the Line Number Information data. */
- unsigned int line_offset;
-
/* Pointers to this DIE's parent, first child, and next sibling,
if any. */
struct partial_die_info *die_parent, *die_child, *die_sibling;
ENUM_BITFIELD(dwarf_form) form : 16;
};
-/* Additional GDB-specific attribute forms. */
-enum
- {
- /* A string which has been updated to GDB's internal
- representation (e.g. converted to canonical form) and does not
- need to be updated again. */
- GDB_FORM_cached_string = 0xff
- };
-
/* Attributes have a name and a value */
struct attribute
{
ENUM_BITFIELD(dwarf_attribute) name : 16;
- ENUM_BITFIELD(dwarf_form) form : 16;
+ ENUM_BITFIELD(dwarf_form) form : 15;
+
+ /* Has DW_STRING already been updated by dwarf2_canonicalize_name? This
+ field should be in u.str (existing only for DW_STRING) but it is kept
+ here for better struct attribute alignment. */
+ unsigned int string_is_canonical : 1;
+
union
{
char *str;
struct dwarf_block *blk;
- unsigned long unsnd;
- long int snd;
+ ULONGEST unsnd;
+ LONGEST snd;
CORE_ADDR addr;
+ struct signatured_type *signatured_type;
}
u;
};
/* Get at parts of an attribute structure */
#define DW_STRING(attr) ((attr)->u.str)
+#define DW_STRING_IS_CANONICAL(attr) ((attr)->string_is_canonical)
#define DW_UNSND(attr) ((attr)->u.unsnd)
#define DW_BLOCK(attr) ((attr)->u.blk)
#define DW_SND(attr) ((attr)->u.snd)
#define DW_ADDR(attr) ((attr)->u.addr)
+#define DW_SIGNATURED_TYPE(attr) ((attr)->u.signatured_type)
/* Blocks are a bunch of untyped bytes. */
struct dwarf_block
#define DW_FIELD_ALLOC_CHUNK 4
#endif
-/* A zeroed version of a partial die for initialization purposes. */
-static struct partial_die_info zeroed_partial_die;
-
/* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
but this would require a corresponding change in unpack_field_as_long
and friends. */
int virtuality;
struct field field;
}
- *fields;
+ *fields, *baseclasses;
- /* Number of fields. */
+ /* Number of fields (including baseclasses). */
int nfields;
/* Number of baseclasses. */
static void dwarf2_locate_sections (bfd *, asection *, void *);
-#if 0
-static void dwarf2_build_psymtabs_easy (struct objfile *, int);
-#endif
-
static void dwarf2_create_include_psymtab (char *, struct partial_symtab *,
struct objfile *);
static void dwarf2_build_include_psymtabs (struct dwarf2_cu *,
- struct partial_die_info *,
+ struct die_info *,
struct partial_symtab *);
-static void dwarf2_build_psymtabs_hard (struct objfile *, int);
+static void dwarf2_build_psymtabs_hard (struct objfile *);
static void scan_partial_symbols (struct partial_die_info *,
CORE_ADDR *, CORE_ADDR *,
static void add_partial_symbol (struct partial_die_info *,
struct dwarf2_cu *);
-static int pdi_needs_namespace (enum dwarf_tag tag);
-
static void add_partial_namespace (struct partial_die_info *pdi,
CORE_ADDR *lowpc, CORE_ADDR *highpc,
int need_pc, struct dwarf2_cu *cu);
static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
struct dwarf2_cu *);
+static struct attribute *dwarf2_attr_no_follow (struct die_info *,
+ unsigned int,
+ struct dwarf2_cu *);
+
static int dwarf2_flag_true_p (struct die_info *die, unsigned name,
struct dwarf2_cu *cu);
static struct type *die_type (struct die_info *, struct dwarf2_cu *);
+static int need_gnat_info (struct dwarf2_cu *);
+
+static struct type *die_descriptive_type (struct die_info *, struct dwarf2_cu *);
+
+static void set_descriptive_type (struct type *, struct die_info *,
+ struct dwarf2_cu *);
+
static struct type *die_containing_type (struct die_info *,
struct dwarf2_cu *);
static void read_file_scope (struct die_info *, struct dwarf2_cu *);
+static void read_type_unit_scope (struct die_info *, struct dwarf2_cu *);
+
static void read_func_scope (struct die_info *, struct dwarf2_cu *);
static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *);
struct dwarf2_cu *, struct partial_symtab *);
static int dwarf2_get_pc_bounds (struct die_info *,
- CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *);
+ 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 process_structure_scope (struct die_info *, struct dwarf2_cu *);
-static const char *determine_class_name (struct die_info *die,
- struct dwarf2_cu *cu);
-
static void read_common_block (struct die_info *, struct dwarf2_cu *);
static void read_namespace (struct die_info *die, struct dwarf2_cu *);
static void process_die (struct die_info *, struct dwarf2_cu *);
-static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
-
static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *,
struct obstack *);
static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
-static int dwarf2_get_attr_constant_value (struct attribute *, int);
+static LONGEST dwarf2_get_attr_constant_value (struct attribute *, int);
+
+static struct die_info *follow_die_ref_or_sig (struct die_info *,
+ struct attribute *,
+ struct dwarf2_cu **);
static struct die_info *follow_die_ref (struct die_info *,
struct attribute *,
struct dwarf2_cu **);
+static struct die_info *follow_die_sig (struct die_info *,
+ struct attribute *,
+ struct dwarf2_cu **);
+
+static void read_signatured_type_at_offset (struct objfile *objfile,
+ unsigned int offset);
+
+static void read_signatured_type (struct objfile *,
+ struct signatured_type *type_sig);
+
/* memory allocation interface */
static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
int
dwarf2_has_info (struct objfile *objfile)
{
- struct dwarf2_per_objfile *data;
+ 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));
- /* Initialize per-objfile state. */
- data = obstack_alloc (&objfile->objfile_obstack, sizeof (*data));
- memset (data, 0, sizeof (*data));
- set_objfile_data (objfile, dwarf2_objfile_data_key, data);
- dwarf2_per_objfile = data;
+ memset (data, 0, sizeof (*data));
+ set_objfile_data (objfile, dwarf2_objfile_data_key, data);
+ dwarf2_per_objfile = data;
- bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL);
- return (data->info.asection != NULL && data->abbrev.asection != NULL);
+ bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL);
+ dwarf2_per_objfile->objfile = objfile;
+ }
+ return (dwarf2_per_objfile->info.asection != NULL
+ && dwarf2_per_objfile->abbrev.asection != NULL);
}
/* When loading sections, we can either look for ".<name>", or for
dwarf2_per_objfile->line.asection = sectp;
dwarf2_per_objfile->line.size = bfd_get_section_size (sectp);
}
- else if (section_is_p (sectp->name, PUBNAMES_SECTION))
- {
- dwarf2_per_objfile->pubnames.asection = sectp;
- dwarf2_per_objfile->pubnames.size = bfd_get_section_size (sectp);
- }
- else if (section_is_p (sectp->name, ARANGES_SECTION))
- {
- dwarf2_per_objfile->aranges.asection = sectp;
- dwarf2_per_objfile->aranges.size = bfd_get_section_size (sectp);
- }
else if (section_is_p (sectp->name, LOC_SECTION))
{
dwarf2_per_objfile->loc.asection = sectp;
else if (section_is_p (sectp->name, EH_FRAME_SECTION))
{
flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
+
if (aflag & SEC_HAS_CONTENTS)
{
dwarf2_per_objfile->eh_frame.asection = sectp;
dwarf2_per_objfile->ranges.asection = sectp;
dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp);
}
+ else if (section_is_p (sectp->name, TYPES_SECTION))
+ {
+ dwarf2_per_objfile->types.asection = sectp;
+ dwarf2_per_objfile->types.size = bfd_get_section_size (sectp);
+ }
if ((bfd_get_section_flags (abfd, sectp) & SEC_LOAD)
&& bfd_section_vma (abfd, sectp) == 0)
gdb_byte *buf, *retbuf;
unsigned char header[4];
+ if (info->readin)
+ return;
info->buffer = NULL;
info->was_mmapped = 0;
+ info->readin = 1;
if (info->asection == NULL || info->size == 0)
return;
{
info->was_mmapped = 1;
info->buffer = retbuf + (sectp->filepos & (pagesize - 1)) ;
+#if HAVE_POSIX_MADVISE
+ posix_madvise (retbuf, map_length, POSIX_MADV_WILLNEED);
+#endif
return;
}
}
http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
We never compress sections in .o files, so we only need to
try this when the section is not compressed. */
- retbuf = symfile_relocate_debug_section (abfd, sectp, buf);
+ retbuf = symfile_relocate_debug_section (objfile, sectp, buf);
if (retbuf != NULL)
{
info->buffer = retbuf;
struct dwarf2_per_objfile *data
= 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
+ return nothing. */
+ if (data == NULL)
+ {
+ *sectp = NULL;
+ *bufp = NULL;
+ *sizep = 0;
+ return;
+ }
if (section_is_p (section_name, EH_FRAME_SECTION))
info = &data->eh_frame;
else if (section_is_p (section_name, FRAME_SECTION))
/* Build a partial symbol table. */
void
-dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
+dwarf2_build_psymtabs (struct objfile *objfile)
{
- dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
- dwarf2_read_section (objfile, &dwarf2_per_objfile->abbrev);
- dwarf2_read_section (objfile, &dwarf2_per_objfile->line);
- dwarf2_read_section (objfile, &dwarf2_per_objfile->str);
- dwarf2_read_section (objfile, &dwarf2_per_objfile->macinfo);
- dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
- dwarf2_read_section (objfile, &dwarf2_per_objfile->loc);
- dwarf2_read_section (objfile, &dwarf2_per_objfile->eh_frame);
- dwarf2_read_section (objfile, &dwarf2_per_objfile->frame);
-
- if (mainline
- || (objfile->global_psymbols.size == 0
- && objfile->static_psymbols.size == 0))
+ if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)
{
init_psymbol_list (objfile, 1024);
}
-#if 0
- if (dwarf_aranges_offset && dwarf_pubnames_offset)
- {
- /* Things are significantly easier if we have .debug_aranges and
- .debug_pubnames sections */
-
- dwarf2_build_psymtabs_easy (objfile, mainline);
- }
- else
-#endif
- /* only test this case for now */
- {
- /* In this case we have to work a bit harder */
- dwarf2_build_psymtabs_hard (objfile, mainline);
- }
-}
-
-#if 0
-/* Build the partial symbol table from the information in the
- .debug_pubnames and .debug_aranges sections. */
-
-static void
-dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline)
-{
- bfd *abfd = objfile->obfd;
- char *aranges_buffer, *pubnames_buffer;
- char *aranges_ptr, *pubnames_ptr;
- unsigned int entry_length, version, info_offset, info_size;
-
- pubnames_buffer = dwarf2_read_section (objfile,
- dwarf_pubnames_section);
- pubnames_ptr = pubnames_buffer;
- while ((pubnames_ptr - pubnames_buffer) < dwarf2_per_objfile->pubnames.size)
- {
- unsigned int bytes_read;
-
- entry_length = read_initial_length (abfd, pubnames_ptr, &bytes_read);
- pubnames_ptr += bytes_read;
- version = read_1_byte (abfd, pubnames_ptr);
- pubnames_ptr += 1;
- info_offset = read_4_bytes (abfd, pubnames_ptr);
- pubnames_ptr += 4;
- info_size = read_4_bytes (abfd, pubnames_ptr);
- pubnames_ptr += 4;
- }
-
- aranges_buffer = dwarf2_read_section (objfile,
- dwarf_aranges_section);
-
+ dwarf2_build_psymtabs_hard (objfile);
}
-#endif
/* Return TRUE if OFFSET is within CU_HEADER. */
unsigned int top = (cu_header->offset
+ cu_header->length
+ cu_header->initial_length_size);
+
return (offset >= bottom && offset < top);
}
info_ptr = read_comp_unit_head (header, info_ptr, abfd);
- if (header->version != 2 && header->version != 3)
+ if (header->version != 2 && header->version != 3 && header->version != 4)
error (_("Dwarf Error: wrong version in compilation unit header "
- "(is %d, should be %d) [in module %s]"), header->version,
- 2, bfd_get_filename (abfd));
+ "(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
+ bfd_get_filename (abfd));
if (header->abbrev_offset >= dwarf2_per_objfile->abbrev.size)
error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
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 gdb_byte *
+read_type_comp_unit_head (struct comp_unit_head *cu_header,
+ ULONGEST *signature,
+ gdb_byte *types_ptr, bfd *abfd)
+{
+ gdb_byte *initial_types_ptr = types_ptr;
+
+ dwarf2_read_section (dwarf2_per_objfile->objfile,
+ &dwarf2_per_objfile->types);
+ cu_header->offset = types_ptr - dwarf2_per_objfile->types.buffer;
+
+ types_ptr = read_comp_unit_head (cu_header, types_ptr, abfd);
+
+ *signature = read_8_bytes (abfd, types_ptr);
+ types_ptr += 8;
+ types_ptr += cu_header->offset_size;
+ cu_header->first_die_offset = types_ptr - initial_types_ptr;
+
+ return types_ptr;
+}
+
/* Allocate a new partial symtab for file named NAME and mark this new
partial symtab as being an include of PST. */
/* Read the Line Number Program data and extract the list of files
included by the source file represented by PST. Build an include
- partial symtab for each of these included files.
-
- This procedure assumes that there *is* a Line Number Program in
- the given CU. Callers should check that PDI->HAS_STMT_LIST is set
- before calling this procedure. */
+ partial symtab for each of these included files. */
static void
dwarf2_build_include_psymtabs (struct dwarf2_cu *cu,
- struct partial_die_info *pdi,
+ struct die_info *die,
struct partial_symtab *pst)
{
struct objfile *objfile = cu->objfile;
bfd *abfd = objfile->obfd;
- struct line_header *lh;
+ struct line_header *lh = NULL;
+ struct attribute *attr;
+
+ attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
+ if (attr)
+ {
+ unsigned int line_offset = DW_UNSND (attr);
- lh = dwarf_decode_line_header (pdi->line_offset, abfd, cu);
+ lh = dwarf_decode_line_header (line_offset, abfd, cu);
+ }
if (lh == NULL)
return; /* No linetable, so no includes. */
free_line_header (lh);
}
-/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
+static hashval_t
+hash_type_signature (const void *item)
+{
+ const struct signatured_type *type_sig = item;
+
+ /* This drops the top 32 bits of the signature, but is ok for a hash. */
+ return type_sig->signature;
+}
+
+static int
+eq_type_signature (const void *item_lhs, const void *item_rhs)
+{
+ const struct signatured_type *lhs = item_lhs;
+ const struct signatured_type *rhs = item_rhs;
+
+ return lhs->signature == rhs->signature;
+}
+
+/* Create the hash table of all entries in the .debug_types section.
+ The result is zero if there is an error (e.g. missing .debug_types section),
+ otherwise non-zero. */
+
+static int
+create_debug_types_hash_table (struct objfile *objfile)
+{
+ gdb_byte *info_ptr;
+ htab_t types_htab;
+
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
+ info_ptr = dwarf2_per_objfile->types.buffer;
+
+ if (info_ptr == NULL)
+ {
+ dwarf2_per_objfile->signatured_types = NULL;
+ return 0;
+ }
+
+ types_htab = htab_create_alloc_ex (41,
+ hash_type_signature,
+ eq_type_signature,
+ NULL,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+
+ if (dwarf2_die_debug)
+ fprintf_unfiltered (gdb_stdlog, "Signatured types:\n");
+
+ while (info_ptr < dwarf2_per_objfile->types.buffer + dwarf2_per_objfile->types.size)
+ {
+ unsigned int offset;
+ unsigned int offset_size;
+ unsigned int type_offset;
+ unsigned int length, initial_length_size;
+ unsigned short version;
+ ULONGEST signature;
+ struct signatured_type *type_sig;
+ void **slot;
+ gdb_byte *ptr = info_ptr;
+
+ offset = ptr - dwarf2_per_objfile->types.buffer;
+
+ /* We need to read the type's signature in order to build the hash
+ table, but we don't need to read anything else just yet. */
+
+ /* Sanity check to ensure entire cu is present. */
+ length = read_initial_length (objfile->obfd, ptr, &initial_length_size);
+ if (ptr + length + initial_length_size
+ > dwarf2_per_objfile->types.buffer + dwarf2_per_objfile->types.size)
+ {
+ complaint (&symfile_complaints,
+ _("debug type entry runs off end of `.debug_types' section, ignored"));
+ break;
+ }
+
+ offset_size = initial_length_size == 4 ? 4 : 8;
+ ptr += initial_length_size;
+ version = bfd_get_16 (objfile->obfd, ptr);
+ ptr += 2;
+ ptr += offset_size; /* abbrev offset */
+ ptr += 1; /* address size */
+ signature = bfd_get_64 (objfile->obfd, ptr);
+ ptr += 8;
+ type_offset = read_offset_1 (objfile->obfd, ptr, offset_size);
+
+ type_sig = obstack_alloc (&objfile->objfile_obstack, sizeof (*type_sig));
+ memset (type_sig, 0, sizeof (*type_sig));
+ type_sig->signature = signature;
+ type_sig->offset = offset;
+ type_sig->type_offset = type_offset;
+
+ slot = htab_find_slot (types_htab, type_sig, INSERT);
+ gdb_assert (slot != NULL);
+ *slot = type_sig;
+
+ if (dwarf2_die_debug)
+ fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n",
+ offset, phex (signature, sizeof (signature)));
+
+ info_ptr = info_ptr + initial_length_size + length;
+ }
+
+ dwarf2_per_objfile->signatured_types = types_htab;
+
+ return 1;
+}
+
+/* Lookup a signature based type.
+ Returns NULL if SIG is not present in the table. */
+
+static struct signatured_type *
+lookup_signatured_type (struct objfile *objfile, ULONGEST sig)
+{
+ struct signatured_type find_entry, *entry;
+
+ if (dwarf2_per_objfile->signatured_types == NULL)
+ {
+ complaint (&symfile_complaints,
+ _("missing `.debug_types' section for DW_FORM_sig8 die"));
+ return 0;
+ }
+
+ find_entry.signature = sig;
+ entry = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
+ return entry;
+}
+
+/* Initialize a die_reader_specs struct from a dwarf2_cu struct. */
+
+static void
+init_cu_die_reader (struct die_reader_specs *reader,
+ struct dwarf2_cu *cu)
+{
+ reader->abfd = cu->objfile->obfd;
+ reader->cu = cu;
+ if (cu->per_cu->from_debug_types)
+ {
+ gdb_assert (dwarf2_per_objfile->types.readin);
+ reader->buffer = dwarf2_per_objfile->types.buffer;
+ }
+ else
+ {
+ gdb_assert (dwarf2_per_objfile->info.readin);
+ reader->buffer = dwarf2_per_objfile->info.buffer;
+ }
+}
+
+/* Find the base address of the compilation unit for range lists and
+ location lists. It will normally be specified by DW_AT_low_pc.
+ In DWARF-3 draft 4, the base address could be overridden by
+ DW_AT_entry_pc. It's been removed, but GCC still uses this for
+ compilation units with discontinuous ranges. */
+
+static void
+dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *attr;
+
+ cu->base_known = 0;
+ cu->base_address = 0;
+
+ attr = dwarf2_attr (die, DW_AT_entry_pc, cu);
+ if (attr)
+ {
+ cu->base_address = DW_ADDR (attr);
+ cu->base_known = 1;
+ }
+ else
+ {
+ attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+ if (attr)
+ {
+ cu->base_address = DW_ADDR (attr);
+ cu->base_known = 1;
+ }
+ }
+}
+
+/* Subroutine of process_type_comp_unit and dwarf2_build_psymtabs_hard
+ to combine the common parts.
Process a compilation unit for a psymtab.
- BUFFER is a pointer to the beginning of the dwarf section buffer.
+ BUFFER is a pointer to the beginning of the dwarf section buffer,
+ either .debug_info or debug_types.
INFO_PTR is a pointer to the start of the CU.
Returns a pointer to the next CU. */
{
bfd *abfd = objfile->obfd;
gdb_byte *beg_of_comp_unit = info_ptr;
- struct partial_die_info comp_unit_die;
+ struct die_info *comp_unit_die;
struct partial_symtab *pst;
CORE_ADDR baseaddr;
struct cleanup *back_to_inner;
struct dwarf2_cu cu;
- struct abbrev_info *abbrev;
- unsigned int bytes_read;
+ int has_children, has_pc_info;
+ struct attribute *attr;
+ CORE_ADDR best_lowpc = 0, best_highpc = 0;
+ struct die_reader_specs reader_specs;
memset (&cu, 0, sizeof (cu));
cu.objfile = objfile;
cu.list_in_scope = &file_symbols;
+ /* If this compilation unit was already read in, free the
+ cached copy in order to read it in again. This is
+ necessary because we skipped some symbols when we first
+ read in the compilation unit (see load_partial_dies).
+ This problem could be avoided, but the benefit is
+ unclear. */
+ if (this_cu->cu != NULL)
+ free_one_cached_comp_unit (this_cu->cu);
+
+ /* Note that this is a pointer to our stack frame, being
+ added to a global data structure. It will be cleaned up
+ in free_stack_comp_unit when we finish with this
+ compilation unit. */
+ this_cu->cu = &cu;
+ cu.per_cu = this_cu;
+
/* Read the abbrevs for this compilation unit into a table. */
dwarf2_read_abbrevs (abfd, &cu);
make_cleanup (dwarf2_free_abbrev_table, &cu);
/* Read the compilation unit die. */
- abbrev = peek_die_abbrev (info_ptr, &bytes_read, &cu);
- info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, abfd,
- buffer, info_ptr, &cu);
+ if (this_cu->from_debug_types)
+ info_ptr += 8 /*signature*/ + cu.header.offset_size;
+ init_cu_die_reader (&reader_specs, &cu);
+ info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr,
+ &has_children);
- if (comp_unit_die.tag == DW_TAG_partial_unit)
+ if (this_cu->from_debug_types)
+ {
+ /* offset,length haven't been set yet for type units. */
+ this_cu->offset = cu.header.offset;
+ this_cu->length = cu.header.length + cu.header.initial_length_size;
+ }
+ else if (comp_unit_die->tag == DW_TAG_partial_unit)
{
info_ptr = (beg_of_comp_unit + cu.header.length
+ cu.header.initial_length_size);
}
/* Set the language we're debugging. */
- set_cu_language (comp_unit_die.language, &cu);
+ attr = dwarf2_attr (comp_unit_die, DW_AT_language, &cu);
+ if (attr)
+ set_cu_language (DW_UNSND (attr), &cu);
+ else
+ set_cu_language (language_minimal, &cu);
/* Allocate a new partial symbol table structure. */
+ attr = dwarf2_attr (comp_unit_die, DW_AT_name, &cu);
pst = start_psymtab_common (objfile, objfile->section_offsets,
- comp_unit_die.name ? comp_unit_die.name : "",
+ (attr != NULL) ? DW_STRING (attr) : "",
/* TEXTLOW and TEXTHIGH are set below. */
0,
objfile->global_psymbols.next,
objfile->static_psymbols.next);
- if (comp_unit_die.dirname)
- pst->dirname = obsavestring (comp_unit_die.dirname,
- strlen (comp_unit_die.dirname),
- &objfile->objfile_obstack);
+ attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, &cu);
+ if (attr != NULL)
+ pst->dirname = DW_STRING (attr);
- pst->read_symtab_private = (char *) this_cu;
+ pst->read_symtab_private = this_cu;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
/* Store the function that reads in the rest of the symbol table */
pst->read_symtab = dwarf2_psymtab_to_symtab;
- /* If this compilation unit was already read in, free the
- cached copy in order to read it in again. This is
- necessary because we skipped some symbols when we first
- read in the compilation unit (see load_partial_dies).
- This problem could be avoided, but the benefit is
- unclear. */
- if (this_cu->cu != NULL)
- free_one_cached_comp_unit (this_cu->cu);
-
- cu.per_cu = this_cu;
-
- /* Note that this is a pointer to our stack frame, being
- added to a global data structure. It will be cleaned up
- in free_stack_comp_unit when we finish with this
- compilation unit. */
- this_cu->cu = &cu;
-
this_cu->psymtab = pst;
+ dwarf2_find_base_address (comp_unit_die, &cu);
+
/* Possibly set the default values of LOWPC and HIGHPC from
`DW_AT_ranges'. */
- if (cu.has_ranges_offset)
- {
- if (dwarf2_ranges_read (cu.ranges_offset, &comp_unit_die.lowpc,
- &comp_unit_die.highpc, &cu, pst))
- comp_unit_die.has_pc_info = 1;
- }
- else if (comp_unit_die.has_pc_info
- && comp_unit_die.lowpc < comp_unit_die.highpc)
+ 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)
/* Store the contiguous range if it is not empty; it can be empty for
CUs with no code. */
addrmap_set_empty (objfile->psymtabs_addrmap,
- comp_unit_die.lowpc + baseaddr,
- comp_unit_die.highpc + baseaddr - 1, pst);
+ best_lowpc + baseaddr,
+ best_highpc + baseaddr - 1, pst);
/* Check if comp unit has_children.
If so, read the rest of the partial symbols from this comp unit.
If not, there's no more debug_info for this comp unit. */
- if (comp_unit_die.has_children)
+ if (has_children)
{
struct partial_die_info *first_die;
CORE_ADDR lowpc, highpc;
first_die = load_partial_dies (abfd, buffer, info_ptr, 1, &cu);
scan_partial_symbols (first_die, &lowpc, &highpc,
- ! comp_unit_die.has_pc_info, &cu);
+ ! has_pc_info, &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 (! comp_unit_die.has_pc_info)
+ if (! has_pc_info)
{
- comp_unit_die.lowpc = lowpc;
- comp_unit_die.highpc = highpc;
+ best_lowpc = lowpc;
+ best_highpc = highpc;
}
}
- pst->textlow = comp_unit_die.lowpc + baseaddr;
- pst->texthigh = comp_unit_die.highpc + baseaddr;
+ pst->textlow = best_lowpc + baseaddr;
+ pst->texthigh = best_highpc + baseaddr;
pst->n_global_syms = objfile->global_psymbols.next -
(objfile->global_psymbols.list + pst->globals_offset);
(objfile->static_psymbols.list + pst->statics_offset);
sort_pst_symbols (pst);
- /* If there is already a psymtab or symtab for a file of this
- name, remove it. (If there is a symtab, more drastic things
- also happen.) This happens in VxWorks. */
- free_named_symtabs (pst->filename);
-
info_ptr = (beg_of_comp_unit + cu.header.length
+ cu.header.initial_length_size);
- if (comp_unit_die.has_stmt_list)
+ if (this_cu->from_debug_types)
+ {
+ /* It's not clear we want to do anything with stmt lists here.
+ Waiting to see what gcc ultimately does. */
+ }
+ else
{
/* Get the list of files included in the current compilation unit,
and build a psymtab for each of them. */
- dwarf2_build_include_psymtabs (&cu, &comp_unit_die, pst);
+ dwarf2_build_include_psymtabs (&cu, comp_unit_die, pst);
}
do_cleanups (back_to_inner);
return info_ptr;
}
+/* Traversal function for htab_traverse_noresize.
+ Process one .debug_types comp-unit. */
+
+static int
+process_type_comp_unit (void **slot, void *info)
+{
+ struct signatured_type *entry = (struct signatured_type *) *slot;
+ struct objfile *objfile = (struct objfile *) info;
+ struct dwarf2_per_cu_data *this_cu;
+
+ this_cu = &entry->per_cu;
+ this_cu->from_debug_types = 1;
+
+ gdb_assert (dwarf2_per_objfile->types.readin);
+ process_psymtab_comp_unit (objfile, this_cu,
+ dwarf2_per_objfile->types.buffer,
+ dwarf2_per_objfile->types.buffer + entry->offset,
+ dwarf2_per_objfile->types.size);
+
+ return 1;
+}
+
+/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
+ Build partial symbol tables for the .debug_types comp-units. */
+
+static void
+build_type_psymtabs (struct objfile *objfile)
+{
+ if (! create_debug_types_hash_table (objfile))
+ return;
+
+ htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
+ process_type_comp_unit, objfile);
+}
+
/* Build the partial symbol table by doing a quick pass through the
.debug_info and .debug_abbrev sections. */
static void
-dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
+dwarf2_build_psymtabs_hard (struct objfile *objfile)
{
- /* Instead of reading this into a big buffer, we should probably use
- mmap() on architectures that support it. (FIXME) */
- bfd *abfd = objfile->obfd;
gdb_byte *info_ptr;
struct cleanup *back_to;
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
info_ptr = dwarf2_per_objfile->info.buffer;
/* Any cached compilation units will be linked by the per-objfile
read_in_chain. Make sure to free them when we're done. */
back_to = make_cleanup (free_cached_comp_units, NULL);
+ build_type_psymtabs (objfile);
+
create_all_comp_units (objfile);
objfile->psymtabs_addrmap =
{
bfd *abfd = objfile->obfd;
gdb_byte *info_ptr, *beg_of_comp_unit;
- struct partial_die_info comp_unit_die;
+ struct die_info *comp_unit_die;
struct dwarf2_cu *cu;
- struct abbrev_info *abbrev;
- unsigned int bytes_read;
struct cleanup *back_to;
+ struct attribute *attr;
+ int has_children;
+ struct die_reader_specs reader_specs;
+
+ gdb_assert (! this_cu->from_debug_types);
+ gdb_assert (dwarf2_per_objfile->info.readin);
info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset;
beg_of_comp_unit = info_ptr;
/* ??? Missing cleanup for CU? */
+ /* Link this compilation unit into the compilation unit tree. */
+ this_cu->cu = cu;
+ cu->per_cu = this_cu;
+ cu->type_hash = this_cu->type_hash;
+
info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr,
dwarf2_per_objfile->info.buffer,
dwarf2_per_objfile->info.size,
back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
/* Read the compilation unit die. */
- abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
- info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, abfd,
- dwarf2_per_objfile->info.buffer, info_ptr, cu);
+ init_cu_die_reader (&reader_specs, cu);
+ info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr,
+ &has_children);
/* Set the language we're debugging. */
- set_cu_language (comp_unit_die.language, cu);
-
- /* Link this compilation unit into the compilation unit tree. */
- this_cu->cu = cu;
- cu->per_cu = this_cu;
- cu->type_hash = this_cu->type_hash;
+ attr = dwarf2_attr (comp_unit_die, DW_AT_language, cu);
+ if (attr)
+ set_cu_language (DW_UNSND (attr), cu);
+ else
+ set_cu_language (language_minimal, cu);
/* Check if comp unit has_children.
If so, read the rest of the partial symbols from this comp unit.
If not, there's no more debug_info for this comp unit. */
- if (comp_unit_die.has_children)
+ if (has_children)
load_partial_dies (abfd, dwarf2_per_objfile->info.buffer, info_ptr, 0, cu);
do_cleanups (back_to);
int n_allocated;
int n_comp_units;
struct dwarf2_per_cu_data **all_comp_units;
- gdb_byte *info_ptr = dwarf2_per_objfile->info.buffer;
+ gdb_byte *info_ptr;
+
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
+ info_ptr = dwarf2_per_objfile->info.buffer;
n_comp_units = 0;
n_allocated = 10;
while (info_ptr < dwarf2_per_objfile->info.buffer + dwarf2_per_objfile->info.size)
{
unsigned int length, initial_length_size;
- gdb_byte *beg_of_comp_unit;
struct dwarf2_per_cu_data *this_cu;
unsigned int offset;
scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
- bfd *abfd = objfile->obfd;
struct partial_die_info *pdi;
/* Now, march along the PDI's, descending into ones which have
grandparent_scope = partial_die_parent_scope (parent, cu);
+ /* GCC 4.0 and 4.1 had a bug (PR c++/28460) where they generated bogus
+ DW_TAG_namespace DIEs with a name of "::" for the global namespace.
+ Work around this problem here. */
+ if (cu->language == language_cplus
+ && parent->tag == DW_TAG_namespace
+ && strcmp (parent->name, "::") == 0
+ && grandparent_scope == NULL)
+ {
+ parent->scope = NULL;
+ parent->scope_set = 1;
+ return NULL;
+ }
+
if (parent->tag == DW_TAG_namespace
|| parent->tag == DW_TAG_structure_type
|| parent->tag == DW_TAG_class_type
|| parent->tag == DW_TAG_interface_type
- || parent->tag == DW_TAG_union_type)
+ || parent->tag == DW_TAG_union_type
+ || parent->tag == DW_TAG_enumeration_type)
{
if (grandparent_scope == NULL)
parent->scope = parent->name;
parent->scope = typename_concat (&cu->comp_unit_obstack, grandparent_scope,
parent->name, cu);
}
- else if (parent->tag == DW_TAG_enumeration_type)
+ else if (parent->tag == DW_TAG_enumerator)
/* Enumerators should not get the name of the enumeration as a prefix. */
parent->scope = grandparent_scope;
else
struct objfile *objfile = cu->objfile;
CORE_ADDR addr = 0;
char *actual_name = NULL;
- const char *my_prefix;
const struct partial_symbol *psym = NULL;
CORE_ADDR baseaddr;
int built_actual_name = 0;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- if (pdi_needs_namespace (pdi->tag))
- {
- actual_name = partial_die_full_name (pdi, cu);
- if (actual_name)
- built_actual_name = 1;
- }
+ actual_name = partial_die_full_name (pdi, cu);
+ if (actual_name)
+ built_actual_name = 1;
if (actual_name == NULL)
actual_name = pdi->name;
/*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
mst_text, objfile); */
psym = add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name,
VAR_DOMAIN, LOC_BLOCK,
&objfile->global_psymbols,
0, pdi->lowpc + baseaddr,
/*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
mst_file_text, objfile); */
psym = add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name,
VAR_DOMAIN, LOC_BLOCK,
&objfile->static_psymbols,
0, pdi->lowpc + baseaddr,
addr = decode_locdesc (pdi->locdesc, cu);
if (pdi->locdesc || pdi->has_type)
psym = add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name,
VAR_DOMAIN, LOC_STATIC,
&objfile->global_psymbols,
0, addr + baseaddr,
/*prim_record_minimal_symbol (actual_name, addr + baseaddr,
mst_file_data, objfile); */
psym = add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name,
VAR_DOMAIN, LOC_STATIC,
&objfile->static_psymbols,
0, addr + baseaddr,
case DW_TAG_base_type:
case DW_TAG_subrange_type:
add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name,
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, objfile);
break;
case DW_TAG_namespace:
add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name,
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->global_psymbols,
0, (CORE_ADDR) 0, cu->language, objfile);
/* NOTE: carlton/2003-10-07: See comment in new_symbol about
static vs. global. */
add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name,
STRUCT_DOMAIN, LOC_TYPEDEF,
(cu->language == language_cplus
|| cu->language == language_java)
break;
case DW_TAG_enumerator:
add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name,
VAR_DOMAIN, LOC_CONST,
(cu->language == language_cplus
|| cu->language == language_java)
break;
}
- /* Check to see if we should scan the name for possible namespace
- info. Only do this if this is C++, if we don't have namespace
- debugging info in the file, if the psym is of an appropriate type
- (otherwise we'll have psym == NULL), and if we actually had a
- mangled name to begin with. */
-
- /* FIXME drow/2004-02-22: Why don't we do this for classes, i.e. the
- cases which do not set PSYM above? */
-
- if (cu->language == language_cplus
- && cu->has_namespace_info == 0
- && psym != NULL
- && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
- cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym),
- objfile);
-
if (built_actual_name)
xfree (actual_name);
}
-/* Determine whether a die of type TAG living in a C++ class or
- namespace needs to have the name of the scope prepended to the
- name listed in the die. */
-
-static int
-pdi_needs_namespace (enum dwarf_tag tag)
-{
- switch (tag)
- {
- case DW_TAG_namespace:
- case DW_TAG_typedef:
- case DW_TAG_class_type:
- case DW_TAG_interface_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_enumerator:
- return 1;
- default:
- return 0;
- }
-}
-
/* Read a partial die corresponding to a namespace; also, add a symbol
corresponding to that namespace to the symbol table. NAMESPACE is
the name of the enclosing namespace. */
CORE_ADDR *lowpc, CORE_ADDR *highpc,
int need_pc, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
-
/* Add a symbol for the namespace. */
add_partial_symbol (pdi, cu);
baseaddr = ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
addrmap_set_empty (objfile->psymtabs_addrmap,
- pdi->lowpc, pdi->highpc - 1,
+ pdi->lowpc + baseaddr,
+ pdi->highpc - 1 + baseaddr,
cu->per_cu->psymtab);
}
if (!pdi->is_declaration)
- add_partial_symbol (pdi, cu);
+ /* Ignore subprogram DIEs that do not have a name, they are
+ illegal. Do not emit a complaint at this point, we will
+ do so when we convert this psymtab into a symtab. */
+ if (pdi->name)
+ add_partial_symbol (pdi, cu);
}
}
could fix this by only using the demangled name to get the
prefix (but see comment in read_structure_type). */
- struct partial_die_info *child_pdi = struct_pdi->die_child;
struct partial_die_info *real_pdi;
/* If this DIE (this DIE's specification, if any) has a parent, then
if (real_pdi->die_parent != NULL)
return;
-
- while (child_pdi != NULL)
- {
- if (child_pdi->tag == DW_TAG_subprogram)
- {
- char *actual_class_name
- = language_class_name_from_physname (cu->language_defn,
- child_pdi->name);
- if (actual_class_name != NULL)
- {
- struct_pdi->name
- = obsavestring (actual_class_name,
- strlen (actual_class_name),
- &cu->comp_unit_obstack);
- xfree (actual_class_name);
- }
- break;
- }
-
- child_pdi = child_pdi->die_sibling;
- }
}
}
add_partial_enumeration (struct partial_die_info *enum_pdi,
struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
- bfd *abfd = objfile->obfd;
struct partial_die_info *pdi;
if (enum_pdi->name != NULL)
skip_attribute:
switch (form)
{
- case DW_FORM_addr:
case DW_FORM_ref_addr:
+ /* In DWARF 2, DW_FORM_ref_addr is address sized; in DWARF 3
+ and later it is offset sized. */
+ if (cu->header.version == 2)
+ info_ptr += cu->header.addr_size;
+ else
+ info_ptr += cu->header.offset_size;
+ break;
+ case DW_FORM_addr:
info_ptr += cu->header.addr_size;
break;
case DW_FORM_data1:
case DW_FORM_flag:
info_ptr += 1;
break;
+ case DW_FORM_flag_present:
+ break;
case DW_FORM_data2:
case DW_FORM_ref2:
info_ptr += 2;
break;
case DW_FORM_data8:
case DW_FORM_ref8:
+ case DW_FORM_sig8:
info_ptr += 8;
break;
case DW_FORM_string:
read_string (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
break;
+ case DW_FORM_sec_offset:
case DW_FORM_strp:
info_ptr += cu->header.offset_size;
break;
+ case DW_FORM_exprloc:
case DW_FORM_block:
info_ptr += read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
struct dwarf2_per_objfile *dpo_backlink
= objfile_data (pst->objfile->separate_debug_objfile_backlink,
dwarf2_objfile_data_key);
+
dwarf2_per_objfile->has_section_at_zero
= dpo_backlink->has_section_at_zero;
}
dwarf2_queue_tail->next = item;
dwarf2_queue_tail = item;
-
- /* Either PER_CU is the CU we want to process, or we're following a reference
- pointing into PER_CU. Either way, we need its DIEs now. */
- load_full_comp_unit (item->per_cu, objfile);
- item->per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
- dwarf2_per_objfile->read_in_chain = item->per_cu;
}
/* Process the queue. */
psymtab_to_symtab_1 (pst->dependencies[i]);
}
- per_cu = (struct dwarf2_per_cu_data *) pst->read_symtab_private;
+ per_cu = pst->read_symtab_private;
if (per_cu == NULL)
{
queue_comp_unit (per_cu, pst->objfile);
+ if (per_cu->from_debug_types)
+ read_signatured_type_at_offset (pst->objfile, per_cu->offset);
+ else
+ load_full_comp_unit (per_cu, pst->objfile);
+
process_queue (pst->objfile);
/* Age the cache, releasing compilation units that have not
gdb_byte *info_ptr, *beg_of_comp_unit;
struct cleanup *back_to, *free_cu_cleanup;
struct attribute *attr;
- CORE_ADDR baseaddr;
+
+ gdb_assert (! per_cu->from_debug_types);
/* Set local variables from the partial symbol table info. */
offset = per_cu->offset;
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
info_ptr = dwarf2_per_objfile->info.buffer + offset;
beg_of_comp_unit = info_ptr;
else
set_cu_language (language_minimal, cu);
+ /* Similarly, if we do not read the producer, we can not apply
+ producer-specific interpretation. */
+ attr = dwarf2_attr (cu->dies, DW_AT_producer, cu);
+ if (attr)
+ cu->producer = DW_STRING (attr);
+
+ /* Link this CU into read_in_chain. */
+ per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+ dwarf2_per_objfile->read_in_chain = per_cu;
+
do_cleanups (back_to);
/* We've successfully allocated this compilation unit. Let our caller
struct partial_symtab *pst = per_cu->psymtab;
struct dwarf2_cu *cu = per_cu->cu;
struct objfile *objfile = pst->objfile;
- bfd *abfd = objfile->obfd;
CORE_ADDR lowpc, highpc;
struct symtab *symtab;
struct cleanup *back_to;
- struct attribute *attr;
CORE_ADDR baseaddr;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
cu->list_in_scope = &file_symbols;
- /* Find the base address of the compilation unit for range lists and
- location lists. It will normally be specified by DW_AT_low_pc.
- In DWARF-3 draft 4, the base address could be overridden by
- DW_AT_entry_pc. It's been removed, but GCC still uses this for
- compilation units with discontinuous ranges. */
-
- cu->base_known = 0;
- cu->base_address = 0;
-
- attr = dwarf2_attr (cu->dies, DW_AT_entry_pc, cu);
- if (attr)
- {
- cu->base_address = DW_ADDR (attr);
- cu->base_known = 1;
- }
- else
- {
- attr = dwarf2_attr (cu->dies, DW_AT_low_pc, cu);
- if (attr)
- {
- cu->base_address = DW_ADDR (attr);
- cu->base_known = 1;
- }
- }
+ dwarf2_find_base_address (cu->dies, cu);
/* Do line number decoding in read_file_scope () */
process_die (cu->dies, cu);
case DW_TAG_compile_unit:
read_file_scope (die, cu);
break;
+ case DW_TAG_type_unit:
+ read_type_unit_scope (die, cu);
+ break;
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
read_func_scope (die, cu);
case DW_TAG_base_type:
case DW_TAG_subrange_type:
case DW_TAG_typedef:
+ case DW_TAG_const_type:
+ case DW_TAG_volatile_type:
/* Add a typedef symbol for the type definition, if it has a
DW_AT_name. */
new_symbol (die, read_type_die (die, cu), cu);
}
}
+/* A helper function for dwarf2_compute_name which determines whether DIE
+ needs to have the name of the scope prepended to the name listed in the
+ die. */
+
+static int
+die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *attr;
+
+ switch (die->tag)
+ {
+ case DW_TAG_namespace:
+ case DW_TAG_typedef:
+ case DW_TAG_class_type:
+ case DW_TAG_interface_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_enumerator:
+ case DW_TAG_subprogram:
+ case DW_TAG_member:
+ return 1;
+
+ case DW_TAG_variable:
+ /* We only need to prefix "globally" visible variables. These include
+ any variable marked with DW_AT_external or any variable that
+ lives in a namespace. [Variables in anonymous namespaces
+ require prefixing, but they are not DW_AT_external.] */
+
+ if (dwarf2_attr (die, DW_AT_specification, cu))
+ {
+ struct dwarf2_cu *spec_cu = cu;
+
+ return die_needs_namespace (die_specification (die, &spec_cu),
+ spec_cu);
+ }
+
+ attr = dwarf2_attr (die, DW_AT_external, cu);
+ if (attr == NULL && die->parent->tag != DW_TAG_namespace)
+ return 0;
+ /* A variable in a lexical block of some kind does not need a
+ namespace, even though in C++ such variables may be external
+ and have a mangled name. */
+ if (die->parent->tag == DW_TAG_lexical_block
+ || die->parent->tag == DW_TAG_try_block
+ || die->parent->tag == DW_TAG_catch_block
+ || die->parent->tag == DW_TAG_subprogram)
+ return 0;
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/* 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) and return type (Java).
+
+ For Ada, return the DIE's linkage name rather than the fully qualified
+ name. PHYSNAME is ignored..
+
+ The result is allocated on the objfile_obstack and canonicalized. */
+
+static const char *
+dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
+ int physname)
+{
+ if (name == NULL)
+ name = dwarf2_name (die, cu);
+
+ /* These are the only languages we know how to qualify names in. */
+ if (name != NULL
+ && (cu->language == language_cplus || cu->language == language_java))
+ {
+ if (die_needs_namespace (die, cu))
+ {
+ long length;
+ char *prefix;
+ struct ui_file *buf;
+
+ prefix = determine_prefix (die, cu);
+ buf = mem_fileopen ();
+ if (*prefix != '\0')
+ {
+ char *prefixed_name = typename_concat (NULL, prefix, name, cu);
+
+ fputs_unfiltered (prefixed_name, buf);
+ xfree (prefixed_name);
+ }
+ else
+ fputs_unfiltered (name ? name : "", buf);
+
+ /* For Java and C++ methods, append formal parameter type
+ information, if PHYSNAME. */
+
+ if (physname && die->tag == DW_TAG_subprogram
+ && (cu->language == language_cplus
+ || cu->language == language_java))
+ {
+ struct type *type = read_type_die (die, cu);
+
+ c_type_print_args (type, buf, 0, cu->language);
+
+ 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);
+ }
+ else if (cu->language == language_cplus)
+ {
+ if (TYPE_NFIELDS (type) > 0
+ && TYPE_FIELD_ARTIFICIAL (type, 0)
+ && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0))))
+ fputs_unfiltered (" const", buf);
+ }
+ }
+
+ name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+ &length);
+ ui_file_delete (buf);
+
+ if (cu->language == language_cplus)
+ {
+ char *cname
+ = dwarf2_canonicalize_name (name, cu,
+ &cu->objfile->objfile_obstack);
+
+ if (cname != NULL)
+ name = cname;
+ }
+ }
+ }
+ else if (cu->language == language_ada)
+ {
+ /* For Ada unit, we prefer the linkage name over the name, as
+ the former contains the exported name, which the user expects
+ 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;
+
+ 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))
+ name = DW_STRING (attr);
+ }
+
+ return name;
+}
+
/* Return the fully qualified name of DIE, based on its DW_AT_name.
If scope qualifiers are appropriate they will be added. The result
will be allocated on the objfile_obstack, or NULL if the DIE does
- not have a 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). */
static const char *
-dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu)
+dwarf2_full_name (char *name, struct die_info *die, struct dwarf2_cu *cu)
{
- struct attribute *attr;
- char *prefix, *name;
- struct ui_file *buf = NULL;
+ return dwarf2_compute_name (name, die, cu, 0);
+}
- name = dwarf2_name (die, cu);
- if (!name)
- return NULL;
+/* Construct a physname for the given DIE in CU. NAME may either be
+ from a previous call to dwarf2_name or NULL. The result will be
+ allocated on the objfile_objstack or NULL if the DIE does not have a
+ name.
- /* These are the only languages we know how to qualify names in. */
- if (cu->language != language_cplus
- && cu->language != language_java)
- return name;
-
- /* If no prefix is necessary for this type of DIE, return the
- unqualified name. The other three tags listed could be handled
- in pdi_needs_namespace, but that requires broader changes. */
- if (!pdi_needs_namespace (die->tag)
- && die->tag != DW_TAG_subprogram
- && die->tag != DW_TAG_variable
- && die->tag != DW_TAG_member)
- return name;
-
- prefix = determine_prefix (die, cu);
- if (*prefix != '\0')
- name = typename_concat (&cu->objfile->objfile_obstack, prefix,
- name, cu);
+ The output string will be canonicalized (if C++/Java). */
- return name;
+static const char *
+dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
+{
+ return dwarf2_compute_name (name, die, cu, 1);
}
/* Read the import statement specified by the given die and record it. */
{
struct attribute *import_attr;
struct die_info *imported_die;
+ struct dwarf2_cu *imported_cu;
const char *imported_name;
const char *imported_name_prefix;
+ const char *canonical_name;
+ const char *import_alias;
+ const char *imported_declaration = NULL;
const char *import_prefix;
- char *canonical_name;
+
+ char *temp;
import_attr = dwarf2_attr (die, DW_AT_import, cu);
if (import_attr == NULL)
return;
}
- imported_die = follow_die_ref (die, import_attr, &cu);
- imported_name = dwarf2_name (imported_die, cu);
+ imported_cu = cu;
+ imported_die = follow_die_ref_or_sig (die, import_attr, &imported_cu);
+ imported_name = dwarf2_name (imported_die, imported_cu);
if (imported_name == NULL)
{
/* GCC bug: https://bugzilla.redhat.com/show_bug.cgi?id=506524
return;
}
- /* FIXME: dwarf2_name (die); for the local name after import. */
+ /* Figure out the local name after import. */
+ import_alias = dwarf2_name (die, cu);
/* Figure out where the statement is being imported to. */
import_prefix = determine_prefix (die, cu);
/* Figure out what the scope of the imported die is and prepend it
to the name of the imported die. */
- imported_name_prefix = determine_prefix (imported_die, cu);
+ imported_name_prefix = determine_prefix (imported_die, imported_cu);
- if (strlen (imported_name_prefix) > 0)
+ if (imported_die->tag != DW_TAG_namespace)
{
- canonical_name = alloca (strlen (imported_name_prefix) + 2 + strlen (imported_name) + 1);
- strcpy (canonical_name, imported_name_prefix);
- strcat (canonical_name, "::");
- strcat (canonical_name, imported_name);
+ imported_declaration = imported_name;
+ canonical_name = imported_name_prefix;
}
- else
+ else if (strlen (imported_name_prefix) > 0)
{
- canonical_name = alloca (strlen (imported_name) + 1);
- strcpy (canonical_name, imported_name);
+ temp = alloca (strlen (imported_name_prefix)
+ + 2 + strlen (imported_name) + 1);
+ strcpy (temp, imported_name_prefix);
+ strcat (temp, "::");
+ strcat (temp, imported_name);
+ canonical_name = temp;
}
+ else
+ canonical_name = imported_name;
- using_directives = cp_add_using (import_prefix,canonical_name, using_directives);
+ cp_add_using_directive (import_prefix,
+ canonical_name,
+ import_alias,
+ imported_declaration,
+ &cu->objfile->objfile_obstack);
}
static void
read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- struct comp_unit_head *cu_header = &cu->header;
struct cleanup *back_to = make_cleanup (null_cleanup, 0);
CORE_ADDR lowpc = ((CORE_ADDR) -1);
CORE_ADDR highpc = ((CORE_ADDR) 0);
attr = dwarf2_attr (die, DW_AT_language, cu);
if (attr)
- {
- set_cu_language (DW_UNSND (attr), cu);
- }
+ {
+ set_cu_language (DW_UNSND (attr), cu);
+ }
+
+ attr = dwarf2_attr (die, DW_AT_producer, cu);
+ if (attr)
+ cu->producer = DW_STRING (attr);
+
+ /* We assume that we're processing GCC output. */
+ processing_gcc_compilation = 2;
+
+ processing_has_namespace_info = 0;
+
+ start_symtab (name, comp_dir, lowpc);
+ record_debugformat ("DWARF 2");
+ record_producer (cu->producer);
+
+ initialize_cu_func_list (cu);
+
+ /* Decode line number information if present. We do this before
+ processing child DIEs, so that the line header table is available
+ for DW_AT_decl_file. */
+ attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
+ if (attr)
+ {
+ unsigned int line_offset = DW_UNSND (attr);
+ line_header = dwarf_decode_line_header (line_offset, abfd, cu);
+ if (line_header)
+ {
+ cu->line_header = line_header;
+ make_cleanup (free_cu_line_header, cu);
+ dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL);
+ }
+ }
+
+ /* Process all dies in compilation unit. */
+ if (die->child != NULL)
+ {
+ child_die = die->child;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, cu);
+ child_die = sibling_die (child_die);
+ }
+ }
+
+ /* Decode macro information, if present. Dwarf 2 macro information
+ 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_macro_info, cu);
+ if (attr && line_header)
+ {
+ unsigned int macro_offset = DW_UNSND (attr);
+
+ dwarf_decode_macros (line_header, macro_offset,
+ comp_dir, abfd, cu);
+ }
+ do_cleanups (back_to);
+}
+
+/* For TUs we want to skip the first top level sibling if it's not the
+ actual type being defined by this TU. In this case the first top
+ level sibling is there to provide context only. */
+
+static void
+read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = cu->objfile;
+ struct cleanup *back_to = make_cleanup (null_cleanup, 0);
+ CORE_ADDR lowpc;
+ struct attribute *attr;
+ char *name = NULL;
+ char *comp_dir = NULL;
+ struct die_info *child_die;
+ bfd *abfd = objfile->obfd;
+
+ /* start_symtab needs a low pc, but we don't really have one.
+ Do what read_file_scope would do in the absence of such info. */
+ lowpc = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ /* 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);
+
+ attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
+ if (attr)
+ comp_dir = DW_STRING (attr);
+ else if (name != NULL && IS_ABSOLUTE_PATH (name))
+ {
+ comp_dir = ldirname (name);
+ if (comp_dir != NULL)
+ make_cleanup (xfree, comp_dir);
+ }
+
+ if (name == NULL)
+ name = "<unknown>";
+
+ attr = dwarf2_attr (die, DW_AT_language, cu);
+ if (attr)
+ set_cu_language (DW_UNSND (attr), cu);
+ /* This isn't technically needed today. It is done for symmetry
+ with read_file_scope. */
attr = dwarf2_attr (die, DW_AT_producer, cu);
if (attr)
cu->producer = DW_STRING (attr);
record_debugformat ("DWARF 2");
record_producer (cu->producer);
- initialize_cu_func_list (cu);
-
- /* Decode line number information if present. We do this before
- processing child DIEs, so that the line header table is available
- for DW_AT_decl_file. */
- attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
- if (attr)
+ /* Process the dies in the type unit. */
+ if (die->child == NULL)
{
- unsigned int line_offset = DW_UNSND (attr);
- line_header = dwarf_decode_line_header (line_offset, abfd, cu);
- if (line_header)
- {
- cu->line_header = line_header;
- make_cleanup (free_cu_line_header, cu);
- dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL);
- }
+ dump_die_for_error (die);
+ error (_("Dwarf Error: Missing children for type unit [in module %s]"),
+ bfd_get_filename (abfd));
}
- /* Process all dies in compilation unit. */
- if (die->child != NULL)
- {
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- process_die (child_die, cu);
- child_die = sibling_die (child_die);
- }
- }
+ child_die = die->child;
- /* Decode macro information, if present. Dwarf 2 macro information
- 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_macro_info, cu);
- if (attr && line_header)
+ while (child_die && child_die->tag)
{
- unsigned int macro_offset = DW_UNSND (attr);
- dwarf_decode_macros (line_header, macro_offset,
- comp_dir, abfd, cu);
+ process_die (child_die, cu);
+
+ child_die = sibling_die (child_die);
}
+
do_cleanups (back_to);
}
but GCC versions at least through 4.4 generate this (GCC PR
40573). */
struct die_info *child_origin_die = child_die;
+
while (1)
{
attr = dwarf2_attr (child_origin_die, DW_AT_abstract_origin, cu);
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- name = dwarf2_linkage_name (die, cu);
+ name = dwarf2_name (die, cu);
- /* Ignore functions with missing or empty names and functions with
- missing or invalid low and high pc attributes. */
- if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
- return;
+ /* Ignore functions with missing or empty names. These are actually
+ illegal according to the DWARF standard. */
+ if (name == NULL)
+ {
+ complaint (&symfile_complaints,
+ _("missing name for subprogram DIE at %d"), die->offset);
+ return;
+ }
+
+ /* Ignore functions with missing or invalid low and high pc attributes. */
+ if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
+ {
+ complaint (&symfile_complaints,
+ _("cannot get low and high bounds for subprogram DIE at %d"),
+ die->offset);
+ return;
+ }
lowpc += baseaddr;
highpc += baseaddr;
inherit_abstract_dies (die, cu);
+ /* If we have a DW_AT_specification, we might need to import using
+ directives from the context of the specification DIE. See the
+ comment in determine_prefix. */
+ if (cu->language == language_cplus
+ && dwarf2_attr (die, DW_AT_specification, cu))
+ {
+ struct dwarf2_cu *spec_cu = cu;
+ struct die_info *spec_die = die_specification (die, &spec_cu);
+
+ while (spec_die)
+ {
+ child_die = spec_die->child;
+ while (child_die && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_imported_module)
+ process_die (child_die, spec_cu);
+ child_die = sibling_die (child_die);
+ }
+
+ /* In some cases, GCC generates specification DIEs that
+ themselves contain DW_AT_specification attributes. */
+ spec_die = die_specification (spec_die, &spec_cu);
+ }
+ }
+
new = pop_context ();
/* Make a block for the local symbols within. */
block = finish_block (new->name, &local_symbols, new->old_blocks,
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))
+ if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL))
return;
lowpc += baseaddr;
highpc += baseaddr;
}
new = pop_context ();
- if (local_symbols != NULL)
+ if (local_symbols != NULL || using_directives != NULL)
{
struct block *block
= finish_block (0, &local_symbols, new->old_blocks, new->start_addr,
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,
discontinuous, i.e. derived from DW_AT_ranges information. */
static int
dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
- CORE_ADDR *highpc, struct dwarf2_cu *cu)
+ CORE_ADDR *highpc, struct dwarf2_cu *cu,
+ struct partial_symtab *pst)
{
struct attribute *attr;
CORE_ADDR low = 0;
{
/* Value of the DW_AT_ranges attribute is the offset in the
.debug_ranges section. */
- if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, NULL))
+ if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, pst))
return 0;
/* Found discontinuous range of addresses. */
ret = -1;
CORE_ADDR low, high;
struct die_info *child = die->child;
- if (dwarf2_get_pc_bounds (die, &low, &high, cu))
+ if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL))
{
*lowpc = min (*lowpc, low);
*highpc = max (*highpc, high);
CORE_ADDR best_high = (CORE_ADDR) 0;
CORE_ADDR current_low, current_high;
- if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu))
+ if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu, NULL))
{
best_low = current_low;
best_high = current_high;
if (attr)
{
CORE_ADDR high = DW_ADDR (attr);
+
attr = dwarf2_attr (die, DW_AT_low_pc, cu);
if (attr)
{
CORE_ADDR low = DW_ADDR (attr);
+
record_block_range (block, baseaddr + low, baseaddr + high - 1);
}
}
CORE_ADDR base = cu->base_address;
int base_known = cu->base_known;
+ gdb_assert (dwarf2_per_objfile->ranges.readin);
if (offset >= dwarf2_per_objfile->ranges.size)
{
complaint (&symfile_complaints,
new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield));
make_cleanup (xfree, new_field);
memset (new_field, 0, sizeof (struct nextfield));
- new_field->next = fip->fields;
- fip->fields = new_field;
+
+ if (die->tag == DW_TAG_inheritance)
+ {
+ new_field->next = fip->baseclasses;
+ fip->baseclasses = new_field;
+ }
+ else
+ {
+ new_field->next = fip->fields;
+ fip->fields = new_field;
+ }
fip->nfields++;
/* Handle accessibility and virtuality of field.
attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
if (attr)
{
- int byte_offset;
+ int byte_offset = 0;
if (attr_form_is_section_offset (attr))
- {
- dwarf2_complex_location_expr_complaint ();
- byte_offset = 0;
- }
+ dwarf2_complex_location_expr_complaint ();
else if (attr_form_is_constant (attr))
byte_offset = dwarf2_get_attr_constant_value (attr, 0);
- else
+ else if (attr_form_is_block (attr))
byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+ else
+ dwarf2_complex_location_expr_complaint ();
SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
}
pointer or virtual base class pointer) to private. */
if (dwarf2_attr (die, DW_AT_artificial, cu))
{
+ FIELD_ARTIFICIAL (*fp) = 1;
new_field->accessibility = DW_ACCESS_private;
fip->non_public_fields = 1;
}
return;
/* Get physical name. */
- physname = dwarf2_linkage_name (die, cu);
+ physname = (char *) dwarf2_physname (fieldname, die, cu);
/* The name is already allocated along with this objfile, so we don't
need to duplicate it for the type. */
/* C++ base class field. */
attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
if (attr)
- SET_FIELD_BITPOS (*fp, decode_locdesc (DW_BLOCK (attr), cu)
- * bits_per_byte);
+ {
+ int byte_offset = 0;
+
+ if (attr_form_is_section_offset (attr))
+ dwarf2_complex_location_expr_complaint ();
+ else if (attr_form_is_constant (attr))
+ byte_offset = dwarf2_get_attr_constant_value (attr, 0);
+ else if (attr_form_is_block (attr))
+ byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+ else
+ dwarf2_complex_location_expr_complaint ();
+
+ SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte);
+ }
FIELD_BITSIZE (*fp) = 0;
FIELD_TYPE (*fp) = die_type (die, cu);
FIELD_NAME (*fp) = type_name_no_tag (fp->type);
TYPE_ALLOC (type, sizeof (struct field) * nfields);
memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields);
- if (fip->non_public_fields)
+ if (fip->non_public_fields && cu->language != language_ada)
{
ALLOCATE_CPLUS_STRUCT_TYPE (type);
/* If the type has baseclasses, allocate and clear a bit vector for
TYPE_FIELD_VIRTUAL_BITS. */
- if (fip->nbaseclasses)
+ if (fip->nbaseclasses && cu->language != language_ada)
{
int num_bytes = B_BYTES (fip->nbaseclasses);
unsigned char *pointer;
up in the same order in the array in which they were added to the list. */
while (nfields-- > 0)
{
- TYPE_FIELD (type, nfields) = fip->fields->field;
- switch (fip->fields->accessibility)
+ struct nextfield *fieldp;
+
+ if (fip->fields)
+ {
+ fieldp = fip->fields;
+ fip->fields = fieldp->next;
+ }
+ else
+ {
+ fieldp = fip->baseclasses;
+ fip->baseclasses = fieldp->next;
+ }
+
+ TYPE_FIELD (type, nfields) = fieldp->field;
+ switch (fieldp->accessibility)
{
case DW_ACCESS_private:
- SET_TYPE_FIELD_PRIVATE (type, nfields);
+ if (cu->language != language_ada)
+ SET_TYPE_FIELD_PRIVATE (type, nfields);
break;
case DW_ACCESS_protected:
- SET_TYPE_FIELD_PROTECTED (type, nfields);
+ if (cu->language != language_ada)
+ SET_TYPE_FIELD_PROTECTED (type, nfields);
break;
case DW_ACCESS_public:
/* Unknown accessibility. Complain and treat it as public. */
{
complaint (&symfile_complaints, _("unsupported accessibility %d"),
- fip->fields->accessibility);
+ fieldp->accessibility);
}
break;
}
if (nfields < fip->nbaseclasses)
{
- switch (fip->fields->virtuality)
+ switch (fieldp->virtuality)
{
case DW_VIRTUALITY_virtual:
case DW_VIRTUALITY_pure_virtual:
+ if (cu->language == language_ada)
+ error ("unexpected virtuality in component of Ada type");
SET_TYPE_FIELD_VIRTUAL (type, nfields);
break;
}
}
- fip->fields = fip->fields->next;
}
}
struct nextfnfield *new_fnfield;
struct type *this_type;
+ if (cu->language == language_ada)
+ error ("unexpected member function in Ada type");
+
/* Get name of member function. */
fieldname = dwarf2_name (die, cu);
if (fieldname == NULL)
return;
/* Get the mangled name. */
- physname = dwarf2_linkage_name (die, cu);
+ physname = (char *) dwarf2_physname (fieldname, die, cu);
/* Look up member function name in fieldlist. */
for (i = 0; i < fip->nfnfields; i++)
if (attr && DW_UNSND (attr) != 0)
fnp->is_artificial = 1;
- /* Get index in virtual function table if it is a virtual member function. */
+ /* Get index in virtual function table if it is a virtual member
+ function. For GCC, this is an offset in the appropriate
+ virtual table, as specified by DW_AT_containing_type. For
+ everyone else, it is an expression to be evaluated relative
+ to the object address. */
+
attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu);
- if (attr)
+ if (attr && fnp->fcontext)
{
/* Support the .debug_loc offsets */
if (attr_form_is_block (attr))
dwarf2_invalid_attrib_class_complaint ("DW_AT_vtable_elem_location",
fieldname);
}
- }
+ }
+ else if (attr)
+ {
+ /* We only support trivial expressions here. This hack will work
+ for v3 classes, which always start with the vtable pointer. */
+ if (attr_form_is_block (attr) && DW_BLOCK (attr)->size > 0
+ && DW_BLOCK (attr)->data[0] == DW_OP_deref)
+ {
+ struct dwarf_block blk;
+
+ blk.size = DW_BLOCK (attr)->size - 1;
+ blk.data = DW_BLOCK (attr)->data + 1;
+ fnp->voffset = decode_locdesc (&blk, cu);
+ if ((fnp->voffset % cu->header.addr_size) != 0)
+ dwarf2_complex_location_expr_complaint ();
+ else
+ fnp->voffset /= cu->header.addr_size;
+ fnp->voffset += 2;
+ fnp->fcontext = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (this_type, 0));
+ }
+ else
+ dwarf2_complex_location_expr_complaint ();
+ }
+ else
+ {
+ attr = dwarf2_attr (die, DW_AT_virtuality, cu);
+ if (attr && DW_UNSND (attr))
+ {
+ /* GCC does this, as of 2008-08-25; PR debug/37237. */
+ complaint (&symfile_complaints,
+ _("Member function \"%s\" (offset %d) is virtual but the vtable offset is not specified"),
+ fieldname, die->offset);
+ TYPE_CPLUS_DYNAMIC (type) = 1;
+ }
+ }
}
/* Create the vector of member function fields, and attach it to the type. */
int total_length = 0;
int i;
+ if (cu->language == language_ada)
+ error ("unexpected member functions in Ada type");
+
ALLOCATE_CPLUS_STRUCT_TYPE (type);
TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * fip->nfnfields);
}
/* GCC outputs unnamed structures that are really pointers to member
- functions, with the ABI-specified layout. If DIE (from CU) describes
- such a structure, set its type, and return nonzero. Otherwise return
- zero.
+ functions, with the ABI-specified layout. If TYPE describes
+ such a structure, smash it into a member function type.
GCC shouldn't do this; it should just output pointer to member DIEs.
This is GCC PR debug/28767. */
-static struct type *
-quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu)
+static void
+quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
{
- struct objfile *objfile = cu->objfile;
- struct type *type;
- struct die_info *pfn_die, *delta_die;
- struct attribute *pfn_name, *delta_name;
- struct type *pfn_type, *domain_type;
+ struct type *pfn_type, *domain_type, *new_type;
/* Check for a structure with no name and two children. */
- if (die->tag != DW_TAG_structure_type
- || dwarf2_attr (die, DW_AT_name, cu) != NULL
- || die->child == NULL
- || die->child->sibling == NULL
- || (die->child->sibling->sibling != NULL
- && die->child->sibling->sibling->tag != DW_TAG_padding))
- return NULL;
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2)
+ return;
/* Check for __pfn and __delta members. */
- pfn_die = die->child;
- pfn_name = dwarf2_attr (pfn_die, DW_AT_name, cu);
- if (pfn_die->tag != DW_TAG_member
- || pfn_name == NULL
- || DW_STRING (pfn_name) == NULL
- || strcmp ("__pfn", DW_STRING (pfn_name)) != 0)
- return NULL;
-
- delta_die = pfn_die->sibling;
- delta_name = dwarf2_attr (delta_die, DW_AT_name, cu);
- if (delta_die->tag != DW_TAG_member
- || delta_name == NULL
- || DW_STRING (delta_name) == NULL
- || strcmp ("__delta", DW_STRING (delta_name)) != 0)
- return NULL;
+ if (TYPE_FIELD_NAME (type, 0) == NULL
+ || strcmp (TYPE_FIELD_NAME (type, 0), "__pfn") != 0
+ || TYPE_FIELD_NAME (type, 1) == NULL
+ || strcmp (TYPE_FIELD_NAME (type, 1), "__delta") != 0)
+ return;
/* Find the type of the method. */
- pfn_type = die_type (pfn_die, cu);
+ pfn_type = TYPE_FIELD_TYPE (type, 0);
if (pfn_type == NULL
|| TYPE_CODE (pfn_type) != TYPE_CODE_PTR
|| TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC)
- return NULL;
+ return;
/* Look for the "this" argument. */
pfn_type = TYPE_TARGET_TYPE (pfn_type);
if (TYPE_NFIELDS (pfn_type) == 0
+ /* || TYPE_FIELD_TYPE (pfn_type, 0) == NULL */
|| TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
- return NULL;
+ return;
domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
- type = alloc_type (objfile);
- smash_to_method_type (type, domain_type, TYPE_TARGET_TYPE (pfn_type),
+ new_type = alloc_type (objfile);
+ smash_to_method_type (new_type, domain_type, TYPE_TARGET_TYPE (pfn_type),
TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
TYPE_VARARGS (pfn_type));
- type = lookup_methodptr_type (type);
- return set_die_type (die, type, cu);
+ smash_to_methodptr_type (type, new_type);
}
/* Called when we find the DIE that starts a structure or union scope
char *name;
struct cleanup *back_to = make_cleanup (null_cleanup, 0);
- type = quirk_gcc_member_function_pointer (die, cu);
- if (type)
- return type;
+ /* If the definition of this type lives in .debug_types, read that type.
+ Don't follow DW_AT_specification though, that will take us back up
+ the chain and we want to go down. */
+ attr = dwarf2_attr_no_follow (die, DW_AT_signature, cu);
+ if (attr)
+ {
+ struct dwarf2_cu *type_cu = cu;
+ struct die_info *type_die = follow_die_ref_or_sig (die, attr, &type_cu);
+
+ /* We could just recurse on read_structure_type, but we need to call
+ get_die_type to ensure only one type for this DIE is created.
+ This is important, for example, because for c++ classes we need
+ TYPE_NAME set which is only done by new_symbol. Blech. */
+ type = read_type_die (type_die, type_cu);
+ return set_die_type (die, type, cu);
+ }
type = alloc_type (objfile);
INIT_CPLUS_SPECIFIC (type);
if (cu->language == language_cplus
|| cu->language == language_java)
{
- const char *new_prefix = determine_class_name (die, cu);
- TYPE_TAG_NAME (type) = (char *) new_prefix;
+ TYPE_TAG_NAME (type) = (char *) dwarf2_full_name (name, die, cu);
+ if (die->tag == DW_TAG_structure_type
+ || die->tag == DW_TAG_class_type)
+ TYPE_NAME (type) = TYPE_TAG_NAME (type);
}
else
{
/* The name is already allocated along with this objfile, so
we don't need to duplicate it for the type. */
- TYPE_TAG_NAME (type) = name;
+ TYPE_TAG_NAME (type) = (char *) name;
+ if (die->tag == DW_TAG_class_type)
+ TYPE_NAME (type) = TYPE_TAG_NAME (type);
}
}
}
else
{
- /* FIXME: TYPE_CODE_CLASS is currently defined to TYPE_CODE_STRUCT
- in gdbtypes.h. */
TYPE_CODE (type) = TYPE_CODE_CLASS;
}
+ if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
+ TYPE_DECLARED_CLASS (type) = 1;
+
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
TYPE_STUB_SUPPORTED (type) = 1;
if (die_is_declaration (die, cu))
TYPE_STUB (type) = 1;
+ else if (attr == NULL && die->child == NULL
+ && producer_is_realview (cu->producer))
+ /* RealView does not output the required DW_AT_declaration
+ on incomplete types. */
+ TYPE_STUB (type) = 1;
+
+ set_descriptive_type (type, die, cu);
/* We need to add the type field to the die immediately so we don't
infinitely recurse when dealing with pointers to the structure
/* Get the type which refers to the base class (possibly this
class itself) which contains the vtable pointer for the current
- class from the DW_AT_containing_type attribute. */
+ class from the DW_AT_containing_type attribute. This use of
+ DW_AT_containing_type is a GNU extension. */
if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
{
}
}
+ quirk_gcc_member_function_pointer (type, cu->objfile);
+
do_cleanups (back_to);
return type;
}
static void
process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
struct die_info *child_die = die->child;
struct type *this_type;
struct attribute *attr;
const char *name;
+ /* If the definition of this type lives in .debug_types, read that type.
+ Don't follow DW_AT_specification though, that will take us back up
+ the chain and we want to go down. */
+ attr = dwarf2_attr_no_follow (die, DW_AT_signature, cu);
+ if (attr)
+ {
+ struct dwarf2_cu *type_cu = cu;
+ struct die_info *type_die = follow_die_ref_or_sig (die, attr, &type_cu);
+
+ type = read_type_die (type_die, type_cu);
+ return set_die_type (die, type, cu);
+ }
+
type = alloc_type (objfile);
TYPE_CODE (type) = TYPE_CODE_ENUM;
- name = dwarf2_full_name (die, cu);
+ name = dwarf2_full_name (NULL, die, cu);
if (name != NULL)
TYPE_TAG_NAME (type) = (char *) name;
return set_die_type (die, type, cu);
}
-/* Determine the name of the type represented by DIE, which should be
- a named C++ or Java compound type. Return the name in question,
- allocated on the objfile obstack. */
-
-static const char *
-determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
-{
- const char *new_prefix = NULL;
-
- /* If we don't have namespace debug info, guess the name by trying
- to demangle the names of members, just like we did in
- guess_structure_name. */
- if (!processing_has_namespace_info)
- {
- struct die_info *child;
-
- for (child = die->child;
- child != NULL && child->tag != 0;
- child = sibling_die (child))
- {
- if (child->tag == DW_TAG_subprogram)
- {
- char *phys_prefix
- = language_class_name_from_physname (cu->language_defn,
- dwarf2_linkage_name
- (child, cu));
-
- if (phys_prefix != NULL)
- {
- new_prefix
- = obsavestring (phys_prefix, strlen (phys_prefix),
- &cu->objfile->objfile_obstack);
- xfree (phys_prefix);
- break;
- }
- }
- }
- }
-
- if (new_prefix == NULL)
- new_prefix = dwarf2_full_name (die, cu);
-
- return new_prefix;
-}
-
/* Given a pointer to a die which begins an enumeration, process all
the dies that define the members of the enumeration, and create the
symbol for the enumeration type.
static void
process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
struct die_info *child_die;
struct field *fields;
struct symbol *sym;
if (child_die->tag == DW_TAG_subrange_type)
{
struct type *child_type = read_type_die (child_die, cu);
+
if (child_type != NULL)
{
/* The range type was succesfully read. Save it for
if (read_array_order (die, cu) == DW_ORD_col_major)
{
int i = 0;
+
while (i < ndim)
type = create_array_type (NULL, type, range_types[i++]);
}
if (name)
TYPE_NAME (type) = name;
+ set_descriptive_type (type, die, cu);
+
do_cleanups (back_to);
/* Install the type in the die. */
version checking.
*/
- if (cu->language == language_fortran &&
- cu->producer && strstr (cu->producer, "GNU F77"))
+ if (cu->language == language_fortran
+ && cu->producer && strstr (cu->producer, "GNU F77"))
{
return DW_ORD_row_major;
}
read_set_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct type *set_type = create_set_type (NULL, die_type (die, cu));
+ struct attribute *attr = dwarf2_attr (die, DW_AT_byte_size, cu);
+ if (attr)
+ TYPE_LENGTH (set_type) = DW_UNSND (attr);
return set_die_type (die, set_type, cu);
}
attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
if (attr)
{
- SYMBOL_VALUE_ADDRESS (sym) =
- base + decode_locdesc (DW_BLOCK (attr), cu);
+ CORE_ADDR byte_offset = 0;
+
+ if (attr_form_is_section_offset (attr))
+ dwarf2_complex_location_expr_complaint ();
+ else if (attr_form_is_constant (attr))
+ byte_offset = dwarf2_get_attr_constant_value (attr, 0);
+ else if (attr_form_is_block (attr))
+ byte_offset = decode_locdesc (DW_BLOCK (attr), cu);
+ else
+ dwarf2_complex_location_expr_complaint ();
+
+ SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset;
add_symbol_to_list (sym, &global_symbols);
}
child_die = sibling_die (child_die);
{
struct die_info *ext_die;
struct dwarf2_cu *ext_cu = cu;
+
ext_die = dwarf2_extension (die, &ext_cu);
type = read_type_die (ext_die, ext_cu);
return set_die_type (die, type, cu);
TYPE_NAME (type) = (char *) name;
TYPE_TAG_NAME (type) = TYPE_NAME (type);
- set_die_type (die, type, cu);
-
- return type;
+ return set_die_type (die, type, cu);
}
/* Read a C++ namespace. */
if (is_anonymous)
{
const char *previous_prefix = determine_prefix (die, cu);
- cp_add_using_directive (previous_prefix, TYPE_NAME (type));
+
+ cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
+ NULL, &objfile->objfile_obstack);
}
}
{
complaint (&symfile_complaints, _("invalid pointer size %d"), byte_size);
}
- else {
- /* Should we also complain about unhandled address classes? */
- }
+ else
+ {
+ /* Should we also complain about unhandled address classes? */
+ }
}
TYPE_LENGTH (type) = byte_size;
static struct type *
read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
struct type *type;
struct type *to_type;
struct type *domain;
|| cu->language == language_java
|| cu->language == language_pascal)
TYPE_PROTOTYPED (ftype) = 1;
+ else if (producer_is_realview (cu->producer))
+ /* RealView does not emit DW_AT_prototyped. We can not
+ distinguish prototyped and unprototyped functions; default to
+ prototyped, since that is more common in modern code (and
+ RealView warns about unprototyped functions). */
+ TYPE_PROTOTYPED (ftype) = 1;
/* Store the calling convention in the type if it's available in
the subroutine die. Otherwise set the calling convention to
the default value DW_CC_normal. */
attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
TYPE_CALLING_CONVENTION (ftype) = attr ? DW_UNSND (attr) : DW_CC_normal;
+
+ /* We need to add the subroutine type to the die immediately so
+ we don't infinitely recurse when dealing with parameters
+ declared as the same subroutine type. */
+ set_die_type (die, ftype, cu);
if (die->child != NULL)
{
+ struct type *void_type = objfile_type (cu->objfile)->builtin_void;
struct die_info *child_die;
- int nparams = 0;
- int iparams = 0;
+ int nparams, iparams;
/* Count the number of parameters.
FIXME: GDB currently ignores vararg functions, but knows about
vararg member functions. */
+ nparams = 0;
child_die = die->child;
while (child_die && child_die->tag)
{
TYPE_FIELDS (ftype) = (struct field *)
TYPE_ZALLOC (ftype, nparams * sizeof (struct field));
+ /* TYPE_FIELD_TYPE must never be NULL. Pre-fill the array to ensure it
+ even if we error out during the parameters reading below. */
+ for (iparams = 0; iparams < nparams; iparams++)
+ TYPE_FIELD_TYPE (ftype, iparams) = void_type;
+
+ iparams = 0;
child_die = die->child;
while (child_die && child_die->tag)
{
if (attr)
TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
else
- TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
+ {
+ 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_TYPE (ftype, iparams) = die_type (child_die, cu);
iparams++;
}
}
}
- return set_die_type (die, ftype, cu);
+ return ftype;
}
static struct type *
read_typedef (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- struct attribute *attr;
const char *name = NULL;
struct type *this_type;
- name = dwarf2_full_name (die, cu);
+ 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) = (char *) name;
struct type *base_type;
struct type *range_type;
struct attribute *attr;
- int low = 0;
- int high = -1;
+ LONGEST low = 0;
+ LONGEST high = -1;
char *name;
+ LONGEST negative_mask;
base_type = die_type (die, cu);
if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
high = dwarf2_get_attr_constant_value (attr, 1);
}
+ negative_mask =
+ (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1);
+ if (!TYPE_UNSIGNED (base_type) && (low & negative_mask))
+ low |= negative_mask;
+ if (!TYPE_UNSIGNED (base_type) && (high & negative_mask))
+ high |= negative_mask;
+
range_type = create_range_type (NULL, base_type, low, high);
+ /* Mark arrays with dynamic length at least as an array of unspecified
+ length. GDB could check the boundary but before it gets implemented at
+ least allow accessing the array elements. */
+ if (attr && attr->form == DW_FORM_block1)
+ TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
+
name = dwarf2_name (die, cu);
if (name)
TYPE_NAME (range_type) = name;
if (attr)
TYPE_LENGTH (range_type) = DW_UNSND (attr);
+ set_descriptive_type (range_type, die, cu);
+
return set_die_type (die, range_type, cu);
}
die_hash (const void *item)
{
const struct die_info *die = item;
+
return die->offset;
}
{
const struct die_info *die_lhs = item_lhs;
const struct die_info *die_rhs = item_rhs;
- return die_lhs->offset == die_rhs->offset;
-}
-
-/* Initialize a die_reader_specs struct from a dwarf2_cu struct. */
-static void
-init_cu_die_reader (struct die_reader_specs *reader,
- struct dwarf2_cu *cu)
-{
- reader->abfd = cu->objfile->obfd;
- reader->cu = cu;
- reader->buffer = dwarf2_per_objfile->info.buffer;
+ return die_lhs->offset == die_rhs->offset;
}
/* Read a whole compilation unit into a linked list of dies. */
{
struct die_reader_specs reader_specs;
+ gdb_assert (cu->die_hash == NULL);
cu->die_hash
= htab_create_alloc_ex (cu->header.length / 12,
die_hash,
if (dwarf2_die_debug)
{
- fprintf_unfiltered (gdb_stdlog, "Read die from .debug_info:\n");
+ fprintf_unfiltered (gdb_stdlog,
+ "\nRead die from %s of %s:\n",
+ reader->buffer == dwarf2_per_objfile->info.buffer
+ ? ".debug_info"
+ : reader->buffer == dwarf2_per_objfile->types.buffer
+ ? ".debug_types"
+ : "unknown section",
+ reader->abfd->filename);
dump_die (result, dwarf2_die_debug);
}
store_in_ref_table (die, reader->cu);
if (has_children)
- {
- die->child = read_die_and_siblings (reader, cur_ptr, new_info_ptr, die);
- }
+ die->child = read_die_and_siblings (reader, cur_ptr, new_info_ptr, die);
else
{
die->child = NULL;
abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
if (!abbrev)
- {
- error (_("Dwarf Error: could not find abbrev number %d [in module %s]"),
- abbrev_number,
- bfd_get_filename (abfd));
- }
+ error (_("Dwarf Error: could not find abbrev number %d [in module %s]"),
+ abbrev_number,
+ bfd_get_filename (abfd));
+
die = dwarf_alloc_die (cu, abbrev->num_attrs);
die->offset = offset;
die->tag = abbrev->tag;
memset (cu->dwarf2_abbrevs, 0,
ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
+ dwarf2_read_section (dwarf2_per_objfile->objfile,
+ &dwarf2_per_objfile->abbrev);
abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset;
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
|| part_die->tag == DW_TAG_subrange_type))
{
if (building_psymtab && part_die->name != NULL)
- add_psymbol_to_list (part_die->name, strlen (part_die->name),
+ add_psymbol_to_list (part_die->name, strlen (part_die->name), 0,
VAR_DOMAIN, LOC_TYPEDEF,
&cu->objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, cu->objfile);
if (part_die->name == NULL)
complaint (&symfile_complaints, _("malformed enumerator DIE ignored"));
else if (building_psymtab)
- add_psymbol_to_list (part_die->name, strlen (part_die->name),
+ add_psymbol_to_list (part_die->name, strlen (part_die->name), 0,
VAR_DOMAIN, LOC_CONST,
(cu->language == language_cplus
|| cu->language == language_java)
gdb_byte *buffer, gdb_byte *info_ptr,
struct dwarf2_cu *cu)
{
- unsigned int bytes_read, i;
+ unsigned int i;
struct attribute attr;
int has_low_pc_attr = 0;
int has_high_pc_attr = 0;
- CORE_ADDR base_address = 0;
- enum
- {
- base_address_none,
- base_address_low_pc,
- /* Overrides BASE_ADDRESS_LOW_PC. */
- base_address_entry_pc
- }
- base_address_type = base_address_none;
memset (part_die, 0, sizeof (struct partial_die_info));
switch (part_die->tag)
{
case DW_TAG_compile_unit:
+ case DW_TAG_type_unit:
/* Compilation units have a DW_AT_name that is a filename, not
a source language identifier. */
case DW_TAG_enumeration_type:
default:
part_die->name
= dwarf2_canonicalize_name (DW_STRING (&attr), cu,
- &cu->comp_unit_obstack);
+ &cu->objfile->objfile_obstack);
break;
}
break;
- case DW_AT_comp_dir:
- if (part_die->dirname == NULL)
- part_die->dirname = DW_STRING (&attr);
- break;
+ case DW_AT_linkage_name:
case DW_AT_MIPS_linkage_name:
- part_die->name = DW_STRING (&attr);
+ /* Note that both forms of linkage name might appear. We
+ assume they will be the same, and we only store the last
+ one we see. */
+ if (cu->language == language_ada)
+ part_die->name = DW_STRING (&attr);
break;
case DW_AT_low_pc:
has_low_pc_attr = 1;
part_die->lowpc = DW_ADDR (&attr);
- if (part_die->tag == DW_TAG_compile_unit
- && base_address_type < base_address_low_pc)
- {
- base_address = DW_ADDR (&attr);
- base_address_type = base_address_low_pc;
- }
break;
case DW_AT_high_pc:
has_high_pc_attr = 1;
part_die->highpc = DW_ADDR (&attr);
break;
- case DW_AT_entry_pc:
- if (part_die->tag == DW_TAG_compile_unit
- && base_address_type < base_address_entry_pc)
- {
- base_address = DW_ADDR (&attr);
- base_address_type = base_address_entry_pc;
- }
- break;
- case DW_AT_ranges:
- if (part_die->tag == DW_TAG_compile_unit)
- {
- cu->ranges_offset = DW_UNSND (&attr);
- cu->has_ranges_offset = 1;
- }
- break;
case DW_AT_location:
/* Support the .debug_loc offsets */
if (attr_form_is_block (&attr))
"partial symbol information");
}
break;
- case DW_AT_language:
- part_die->language = DW_UNSND (&attr);
- break;
case DW_AT_external:
part_die->is_external = DW_UNSND (&attr);
break;
else
part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr);
break;
- case DW_AT_stmt_list:
- part_die->has_stmt_list = 1;
- part_die->line_offset = DW_UNSND (&attr);
- break;
case DW_AT_byte_size:
part_die->has_byte_size = 1;
break;
|| dwarf2_per_objfile->has_section_at_zero))
part_die->has_pc_info = 1;
- if (base_address_type != base_address_none && !cu->base_known)
- {
- gdb_assert (part_die->tag == DW_TAG_compile_unit);
- cu->base_known = 1;
- cu->base_address = base_address;
- }
-
return info_ptr;
}
return lookup_die;
}
-/* Find a partial DIE at OFFSET, which may or may not be in CU. */
+/* Find a partial DIE at OFFSET, which may or may not be in CU,
+ except in the case of .debug_types DIEs which do not reference
+ outside their CU (they do however referencing other types via
+ DW_FORM_sig8). */
static struct partial_die_info *
find_partial_die (unsigned int offset, struct dwarf2_cu *cu)
struct dwarf2_per_cu_data *per_cu = NULL;
struct partial_die_info *pd = NULL;
+ if (cu->per_cu->from_debug_types)
+ {
+ pd = find_partial_die_in_comp_unit (offset, cu);
+ if (pd != NULL)
+ return pd;
+ goto not_found;
+ }
+
if (offset_in_cu_p (&cu->header, offset))
{
pd = find_partial_die_in_comp_unit (offset, cu);
if (per_cu->cu->dwarf2_abbrevs == NULL)
{
dwarf2_read_abbrevs (per_cu->cu->objfile->obfd, per_cu->cu);
- back_to = make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
+ make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
}
info_ptr = (dwarf2_per_objfile->info.buffer
+ per_cu->cu->header.offset
pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
}
+ not_found:
+
if (pd == NULL)
internal_error (__FILE__, __LINE__,
_("could not find partial DIE 0x%x in cache [from module %s]\n"),
attr->form = form;
switch (form)
{
+ case DW_FORM_ref_addr:
+ if (cu->header.version == 2)
+ DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read);
+ else
+ DW_ADDR (attr) = read_offset (abfd, info_ptr, &cu->header, &bytes_read);
+ info_ptr += bytes_read;
+ break;
case DW_FORM_addr:
- case DW_FORM_ref_addr:
DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read);
info_ptr += bytes_read;
break;
DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
info_ptr += 8;
break;
+ case DW_FORM_sec_offset:
+ DW_UNSND (attr) = read_offset (abfd, info_ptr, &cu->header, &bytes_read);
+ info_ptr += bytes_read;
+ break;
case DW_FORM_string:
DW_STRING (attr) = read_string (abfd, info_ptr, &bytes_read);
+ DW_STRING_IS_CANONICAL (attr) = 0;
info_ptr += bytes_read;
break;
case DW_FORM_strp:
DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
&bytes_read);
+ DW_STRING_IS_CANONICAL (attr) = 0;
info_ptr += bytes_read;
break;
+ case DW_FORM_exprloc:
case DW_FORM_block:
blk = dwarf_alloc_block (cu);
blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
DW_UNSND (attr) = read_1_byte (abfd, info_ptr);
info_ptr += 1;
break;
+ case DW_FORM_flag_present:
+ DW_UNSND (attr) = 1;
+ break;
case DW_FORM_sdata:
DW_SND (attr) = read_signed_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
DW_ADDR (attr) = cu->header.offset + read_8_bytes (abfd, info_ptr);
info_ptr += 8;
break;
+ case DW_FORM_sig8:
+ /* Convert the signature to something we can record in DW_UNSND
+ for later lookup.
+ NOTE: This is NULL if the type wasn't found. */
+ DW_SIGNATURED_TYPE (attr) =
+ lookup_signatured_type (cu->objfile, read_8_bytes (abfd, info_ptr));
+ info_ptr += 8;
+ break;
case DW_FORM_ref_udata:
DW_ADDR (attr) = (cu->header.offset
+ read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
{
complaint
(&symfile_complaints,
- _("Suspicious DW_AT_byte_size value treated as zero instead of 0x%lx"),
- DW_UNSND (attr));
+ _("Suspicious DW_AT_byte_size value treated as zero instead of %s"),
+ hex_string (DW_UNSND (attr)));
DW_UNSND (attr) = 0;
}
unsigned int *bytes_read)
{
LONGEST offset = read_offset_1 (abfd, buf, cu_header->offset_size);
+
*bytes_read = cu_header->offset_size;
return offset;
}
{
LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
+ 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]"),
case DW_LANG_C_plus_plus:
cu->language = language_cplus;
break;
+ case DW_LANG_D:
+ cu->language = language_d;
+ break;
case DW_LANG_Fortran77:
case DW_LANG_Fortran90:
case DW_LANG_Fortran95:
return NULL;
}
+/* Return the named attribute or NULL if not there,
+ but do not follow DW_AT_specification, etc.
+ This is for use in contexts where we're reading .debug_types dies.
+ Following DW_AT_specification, DW_AT_abstract_origin will take us
+ back up the chain, and we want to go down. */
+
+static struct attribute *
+dwarf2_attr_no_follow (struct die_info *die, unsigned int name,
+ struct dwarf2_cu *cu)
+{
+ unsigned int i;
+
+ for (i = 0; i < die->num_attrs; ++i)
+ if (die->attrs[i].name == name)
+ return &die->attrs[i];
+
+ return NULL;
+}
+
/* 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 attributes. */
+ DW_FORM_flag or DW_FORM_flag_present attributes. */
static int
dwarf2_flag_true_p (struct die_info *die, unsigned name, struct dwarf2_cu *cu)
int i;
char *cur_dir, *cur_file;
+ dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->line);
if (dwarf2_per_objfile->line.buffer == NULL)
{
complaint (&symfile_complaints, _("missing .debug_line section"));
line_ptr += offset_size;
lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
line_ptr += 1;
+ if (lh->version >= 4)
+ {
+ lh->maximum_ops_per_instruction = read_1_byte (abfd, line_ptr);
+ line_ptr += 1;
+ }
+ else
+ lh->maximum_ops_per_instruction = 1;
+
+ if (lh->maximum_ops_per_instruction == 0)
+ {
+ lh->maximum_ops_per_instruction = 1;
+ complaint (&symfile_complaints,
+ _("invalid maximum_ops_per_instruction in `.debug_line' section"));
+ }
+
lh->default_is_stmt = read_1_byte (abfd, line_ptr);
line_ptr += 1;
lh->line_base = read_1_signed_byte (abfd, line_ptr);
int basic_block = 0;
int end_sequence = 0;
CORE_ADDR addr;
+ unsigned char op_index = 0;
if (!decode_for_pst_p && lh->num_file_names >= file)
{
{
/* Special operand. */
adj_opcode = op_code - lh->opcode_base;
- address += (adj_opcode / lh->line_range)
- * lh->minimum_instruction_length;
+ address += (((op_index + (adj_opcode / lh->line_range))
+ / lh->maximum_ops_per_instruction)
+ * lh->minimum_instruction_length);
+ op_index = ((op_index + (adj_opcode / lh->line_range))
+ % lh->maximum_ops_per_instruction);
line += lh->line_base + (adj_opcode % lh->line_range);
if (lh->num_file_names < file || file == 0)
dwarf2_debug_line_missing_file_complaint ();
- else
+ /* 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)
break;
case DW_LNE_set_address:
address = read_address (abfd, line_ptr, cu, &bytes_read);
+ op_index = 0;
line_ptr += bytes_read;
address += baseaddr;
break;
basic_block = 0;
break;
case DW_LNS_advance_pc:
- address += lh->minimum_instruction_length
- * read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
- line_ptr += bytes_read;
+ {
+ CORE_ADDR adjust
+ = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+
+ address += (((op_index + adjust)
+ / lh->maximum_ops_per_instruction)
+ * lh->minimum_instruction_length);
+ op_index = ((op_index + adjust)
+ % lh->maximum_ops_per_instruction);
+ line_ptr += bytes_read;
+ }
break;
case DW_LNS_advance_line:
line += read_signed_leb128 (abfd, line_ptr, &bytes_read);
instruction length since special opcode 255 would have
scaled the the increment. */
case DW_LNS_const_add_pc:
- address += (lh->minimum_instruction_length
- * ((255 - lh->opcode_base) / lh->line_range));
+ {
+ CORE_ADDR adjust = (255 - lh->opcode_base) / lh->line_range;
+
+ address += (((op_index + adjust)
+ / lh->maximum_ops_per_instruction)
+ * lh->minimum_instruction_length);
+ op_index = ((op_index + adjust)
+ % lh->maximum_ops_per_instruction);
+ }
break;
case DW_LNS_fixed_advance_pc:
address += read_2_bytes (abfd, line_ptr);
+ op_index = 0;
line_ptr += 2;
break;
default:
for (i = 0; i < lh->num_file_names; i++)
{
char *dir = NULL;
+
fe = &lh->file_names[i];
if (fe->dir_index)
dir = lh->include_dirs[fe->dir_index - 1];
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- if (die->tag != DW_TAG_namespace)
- name = dwarf2_linkage_name (die, cu);
- else
- name = TYPE_NAME (type);
-
+ name = dwarf2_name (die, cu);
if (name)
{
+ const char *linkagename;
+
sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
OBJSTAT (objfile, n_syms++);
/* Cache this symbol's name and the name's demangled form (if any). */
SYMBOL_LANGUAGE (sym) = cu->language;
- SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
+ linkagename = dwarf2_physname (name, die, cu);
+ SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile);
/* Default assumptions.
Use the passed type or decode it from the die. */
if (attr)
{
int file_index = DW_UNSND (attr);
+
if (cu->line_header == NULL
|| file_index > cu->line_header->num_file_names)
complaint (&symfile_complaints,
else if (file_index > 0)
{
struct file_entry *fe;
+
fe = &cu->line_header->file_names[file_index - 1];
SYMBOL_SYMTAB (sym) = fe->symtab;
}
var_decode_location (attr, sym, cu);
attr2 = dwarf2_attr (die, DW_AT_external, cu);
if (attr2 && (DW_UNSND (attr2) != 0))
- add_symbol_to_list (sym, &global_symbols);
+ {
+ struct pending **list_to_add;
+
+ /* A variable with DW_AT_external is never static,
+ but it may be block-scoped. */
+ list_to_add = (cu->list_in_scope == &file_symbols
+ ? &global_symbols : cu->list_in_scope);
+ add_symbol_to_list (sym, list_to_add);
+ }
else
add_symbol_to_list (sym, cu->list_in_scope);
}
if (attr2 && (DW_UNSND (attr2) != 0)
&& dwarf2_attr (die, DW_AT_type, cu) != NULL)
{
+ struct pending **list_to_add;
+
+ /* A variable with DW_AT_external is never static, but it
+ may be block-scoped. */
+ list_to_add = (cu->list_in_scope == &file_symbols
+ ? &global_symbols : cu->list_in_scope);
+
SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
- add_symbol_to_list (sym, cu->list_in_scope);
+ add_symbol_to_list (sym, list_to_add);
}
else if (!die_is_declaration (die, cu))
{
{
dwarf2_const_value (attr, sym, cu);
}
+ attr = dwarf2_attr (die, DW_AT_variable_parameter, cu);
+ if (attr && DW_UNSND (attr))
+ {
+ struct type *ref_type;
+
+ ref_type = lookup_reference_type (SYMBOL_TYPE (sym));
+ SYMBOL_TYPE (sym) = ref_type;
+ }
+
add_symbol_to_list (sym, cu->list_in_scope);
break;
case DW_TAG_unspecified_parameters:
}
break;
case DW_TAG_typedef:
- SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_full_name (die, cu);
+ SYMBOL_LINKAGE_NAME (sym)
+ = (char *) dwarf2_full_name (name, die, cu);
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
add_symbol_to_list (sym, cu->list_in_scope);
break;
case DW_TAG_base_type:
case DW_TAG_subrange_type:
+ case DW_TAG_const_type:
+ case DW_TAG_volatile_type:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
add_symbol_to_list (sym, cu->list_in_scope);
break;
case DW_TAG_enumerator:
- SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_full_name (die, cu);
+ SYMBOL_LINKAGE_NAME (sym)
+ = (char *) dwarf2_full_name (name, die, cu);
attr = dwarf2_attr (die, DW_AT_const_value, cu);
if (attr)
{
/* For the benefit of old versions of GCC, check for anonymous
namespaces based on the demangled name. */
if (!processing_has_namespace_info
- && cu->language == language_cplus
- && dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu) != NULL)
+ && cu->language == language_cplus)
cp_scan_for_anonymous_namespaces (sym);
}
return (sym);
/* NOTE: cagney/2003-05-09: In-lined store_address call with
it's body - store_unsigned_integer. */
store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size,
- DW_ADDR (attr), byte_order);
+ byte_order, DW_ADDR (attr));
SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
break;
case DW_FORM_string:
case DW_FORM_block2:
case DW_FORM_block4:
case DW_FORM_block:
+ case DW_FORM_exprloc:
blk = DW_BLOCK (attr);
if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != blk->size)
dwarf2_const_value_length_mismatch_complaint (SYMBOL_PRINT_NAME (sym),
static struct type *
die_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct type *type;
struct attribute *type_attr;
struct die_info *type_die;
/* A missing DW_AT_type represents a void type. */
return objfile_type (cu->objfile)->builtin_void;
}
- else
- type_die = follow_die_ref (die, type_attr, &cu);
- type = tag_type_to_type (type_die, cu);
- if (!type)
+ type_die = follow_die_ref_or_sig (die, type_attr, &cu);
+
+ return tag_type_to_type (type_die, cu);
+}
+
+/* True iff CU's producer generates GNAT Ada auxiliary information
+ that allows to find parallel types through that information instead
+ of having to do expensive parallel lookups by type name. */
+
+static int
+need_gnat_info (struct dwarf2_cu *cu)
+{
+ /* FIXME: brobecker/2010-10-12: As of now, only the AdaCore version
+ of GNAT produces this auxiliary information, without any indication
+ that it is produced. Part of enhancing the FSF version of GNAT
+ to produce that information will be to put in place an indicator
+ that we can use in order to determine whether the descriptive type
+ info is available or not. One suggestion that has been made is
+ to use a new attribute, attached to the CU die. For now, assume
+ that the descriptive type info is not available. */
+ return 0;
+}
+
+
+/* Return the auxiliary type of the die in question using its
+ DW_AT_GNAT_descriptive_type attribute. Returns NULL if the
+ attribute is not present. */
+
+static struct type *
+die_descriptive_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *type_attr;
+ struct die_info *type_die;
+
+ type_attr = dwarf2_attr (die, DW_AT_GNAT_descriptive_type, cu);
+ if (!type_attr)
+ return NULL;
+
+ type_die = follow_die_ref (die, type_attr, &cu);
+ return tag_type_to_type (type_die, cu);
+}
+
+/* If DIE has a descriptive_type attribute, then set the TYPE's
+ descriptive type accordingly. */
+
+static void
+set_descriptive_type (struct type *type, struct die_info *die,
+ struct dwarf2_cu *cu)
+{
+ struct type *descriptive_type = die_descriptive_type (die, cu);
+
+ if (descriptive_type)
{
- dump_die_for_error (type_die);
- error (_("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]"),
- cu->objfile->name);
+ ALLOCATE_GNAT_AUX_TYPE (type);
+ TYPE_DESCRIPTIVE_TYPE (type) = descriptive_type;
}
- return type;
}
/* Return the containing type of the die in question using its
static struct type *
die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct type *type = NULL;
struct attribute *type_attr;
- struct die_info *type_die = NULL;
+ struct die_info *type_die;
type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
- if (type_attr)
- {
- type_die = follow_die_ref (die, type_attr, &cu);
- type = tag_type_to_type (type_die, cu);
- }
- if (!type)
- {
- if (type_die)
- dump_die_for_error (type_die);
- error (_("Dwarf Error: Problem turning containing type into gdb type [in module %s]"),
- cu->objfile->name);
- }
- return type;
+ if (!type_attr)
+ error (_("Dwarf Error: Problem turning containing type into gdb type "
+ "[in module %s]"), cu->objfile->name);
+
+ type_die = follow_die_ref_or_sig (die, type_attr, &cu);
+ return tag_type_to_type (type_die, cu);
}
static struct type *
{
case DW_TAG_namespace:
parent_type = read_type_die (parent, cu);
+ /* GCC 4.0 and 4.1 had a bug (PR c++/28460) where they generated bogus
+ DW_TAG_namespace DIEs with a name of "::" for the global namespace.
+ Work around this problem here. */
+ if (cu->language == language_cplus
+ && strcmp (TYPE_TAG_NAME (parent_type), "::") == 0)
+ return "";
/* We give a name to even anonymous namespaces. */
return TYPE_TAG_NAME (parent_type);
case DW_TAG_class_type:
if (obs == NULL)
{
char *retval = xmalloc (strlen (prefix) + MAX_SEP_LEN + strlen (suffix) + 1);
+
strcpy (retval, prefix);
strcat (retval, sep);
strcat (retval, suffix);
else
{
/* We have an obstack. */
- return obconcat (obs, prefix, sep, suffix);
+ return obconcat (obs, prefix, sep, suffix, (char *) NULL);
}
}
return die->sibling;
}
-/* Get linkage name of a die, return NULL if not found. */
-
-static char *
-dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
-{
- struct attribute *attr;
-
- attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
- if (attr && DW_STRING (attr))
- return DW_STRING (attr);
- return dwarf2_name (die, cu);
-}
-
/* Get name of a die, return NULL if not found. */
static char *
/* These tags always have simple identifiers already; no need
to canonicalize them. */
return DW_STRING (attr);
- default:
- if (attr->form != GDB_FORM_cached_string)
+
+ 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)
{
- DW_STRING (attr)
- = dwarf2_canonicalize_name (DW_STRING (attr), cu,
- &cu->objfile->objfile_obstack);
- attr->form = GDB_FORM_cached_string;
+ 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 suprogram 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);
}
- return DW_STRING (attr);
+ break;
+
+ case DW_TAG_class_type:
+ case DW_TAG_interface_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ /* Some GCC versions emit spurious DW_AT_name attributes for unnamed
+ structures or unions. These were of the form "._%d" in GCC 4.1,
+ or simply "<anonymous struct>" or "<anonymous union>" in GCC 4.3
+ and GCC 4.4. We work around this problem by ignoring these. */
+ if (strncmp (DW_STRING (attr), "._", 2) == 0
+ || strncmp (DW_STRING (attr), "<anonymous", 10) == 0)
+ return NULL;
+ break;
+
+ default:
+ break;
+ }
+
+ if (!DW_STRING_IS_CANONICAL (attr))
+ {
+ DW_STRING (attr)
+ = dwarf2_canonicalize_name (DW_STRING (attr), cu,
+ &cu->objfile->objfile_obstack);
+ DW_STRING_IS_CANONICAL (attr) = 1;
}
+ return DW_STRING (attr);
}
/* Return the die that this die in an extension of, or NULL if there
return "DW_TAG_condition";
case DW_TAG_shared_type:
return "DW_TAG_shared_type";
+ case DW_TAG_type_unit:
+ return "DW_TAG_type_unit";
case DW_TAG_MIPS_loop:
return "DW_TAG_MIPS_loop";
case DW_TAG_HP_array_descriptor:
return "DW_AT_pure";
case DW_AT_recursive:
return "DW_AT_recursive";
+ /* DWARF 4 values. */
+ case DW_AT_signature:
+ return "DW_AT_signature";
+ case DW_AT_linkage_name:
+ return "DW_AT_linkage_name";
/* SGI/MIPS extensions. */
#ifdef MIPS /* collides with DW_AT_HP_block_index */
case DW_AT_MIPS_fde:
return "DW_FORM_ref_udata";
case DW_FORM_indirect:
return "DW_FORM_indirect";
- case GDB_FORM_cached_string:
- return "GDB_FORM_cached_string";
+ case DW_FORM_sec_offset:
+ return "DW_FORM_sec_offset";
+ case DW_FORM_exprloc:
+ return "DW_FORM_exprloc";
+ case DW_FORM_flag_present:
+ return "DW_FORM_flag_present";
+ case DW_FORM_sig8:
+ return "DW_FORM_sig8";
default:
return "DW_FORM_<unknown>";
}
case DW_FORM_block1:
fprintf_unfiltered (f, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
break;
+ case DW_FORM_exprloc:
+ fprintf_unfiltered (f, "expression: size %u",
+ DW_BLOCK (&die->attrs[i])->size);
+ break;
case DW_FORM_ref1:
case DW_FORM_ref2:
case DW_FORM_ref4:
case DW_FORM_data8:
case DW_FORM_udata:
case DW_FORM_sdata:
- fprintf_unfiltered (f, "constant: %ld", DW_UNSND (&die->attrs[i]));
+ fprintf_unfiltered (f, "constant: %s",
+ pulongest (DW_UNSND (&die->attrs[i])));
+ break;
+ case DW_FORM_sec_offset:
+ fprintf_unfiltered (f, "section offset: %s",
+ pulongest (DW_UNSND (&die->attrs[i])));
+ break;
+ case DW_FORM_sig8:
+ if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL)
+ fprintf_unfiltered (f, "signatured type, offset: 0x%x",
+ DW_SIGNATURED_TYPE (&die->attrs[i])->offset);
+ else
+ fprintf_unfiltered (f, "signatured type, offset: unknown");
break;
case DW_FORM_string:
case DW_FORM_strp:
- case GDB_FORM_cached_string:
- fprintf_unfiltered (f, "string: \"%s\"",
+ fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)",
DW_STRING (&die->attrs[i])
- ? DW_STRING (&die->attrs[i]) : "");
+ ? DW_STRING (&die->attrs[i]) : "",
+ DW_STRING_IS_CANONICAL (&die->attrs[i]) ? "is" : "not");
break;
case DW_FORM_flag:
if (DW_UNSND (&die->attrs[i]))
else
fprintf_unfiltered (f, "flag: FALSE");
break;
+ case DW_FORM_flag_present:
+ fprintf_unfiltered (f, "flag: TRUE");
+ break;
case DW_FORM_indirect:
/* the reader will have reduced the indirect form to
the "base form" so this form should not occur */
return 0;
}
-/* Return the constant value held by the given attribute. Return -1
- if the value held by the attribute is not constant. */
+/* Return the constant value held by ATTR. Return DEFAULT_VALUE if
+ * the value held by the attribute is not constant. */
-static int
+static LONGEST
dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
{
if (attr->form == DW_FORM_sdata)
}
/* THIS_CU has a reference to PER_CU. If necessary, load the new compilation
- unit and add it to our queue. */
+ unit and add it to our queue.
+ The result is non-zero if PER_CU was queued, otherwise the result is zero
+ meaning either PER_CU is already queued or it is already loaded. */
-static void
+static int
maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
struct dwarf2_per_cu_data *per_cu)
{
/* If it's already on the queue, we have nothing to do. */
if (per_cu->queued)
- return;
+ return 0;
/* If the compilation unit is already loaded, just mark it as
used. */
if (per_cu->cu != NULL)
{
per_cu->cu->last_used = 0;
- return;
+ return 0;
}
/* Add it to the queue. */
queue_comp_unit (per_cu, this_cu->objfile);
+
+ return 1;
+}
+
+/* Follow reference or signature attribute ATTR of SRC_DIE.
+ On entry *REF_CU is the CU of SRC_DIE.
+ On exit *REF_CU is the CU of the result. */
+
+static struct die_info *
+follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr,
+ struct dwarf2_cu **ref_cu)
+{
+ struct die_info *die;
+
+ if (is_ref_attr (attr))
+ die = follow_die_ref (src_die, attr, ref_cu);
+ else if (attr->form == DW_FORM_sig8)
+ die = follow_die_sig (src_die, attr, ref_cu);
+ else
+ {
+ dump_die_for_error (src_die);
+ error (_("Dwarf Error: Expected reference attribute [in module %s]"),
+ (*ref_cu)->objfile->name);
+ }
+
+ return die;
}
/* Follow reference attribute ATTR of SRC_DIE.
struct die_info temp_die;
struct dwarf2_cu *target_cu, *cu = *ref_cu;
+ gdb_assert (cu->per_cu != NULL);
+
offset = dwarf2_get_ref_die_offset (attr);
- if (! offset_in_cu_p (&cu->header, offset))
+ if (cu->per_cu->from_debug_types)
+ {
+ /* .debug_types CUs cannot reference anything outside their CU.
+ If they need to, they have to reference a signatured type via
+ DW_FORM_sig8. */
+ if (! offset_in_cu_p (&cu->header, offset))
+ goto not_found;
+ target_cu = cu;
+ }
+ else if (! offset_in_cu_p (&cu->header, offset))
{
struct dwarf2_per_cu_data *per_cu;
+
per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
/* If necessary, add it to the queue and load its DIEs. */
- maybe_queue_comp_unit (cu, per_cu);
+ if (maybe_queue_comp_unit (cu, per_cu))
+ load_full_comp_unit (per_cu, cu->objfile);
target_cu = per_cu->cu;
}
if (die)
return die;
- error (_("Dwarf Error: Cannot find DIE at 0x%lx referenced from DIE "
- "at 0x%lx [in module %s]"),
- (long) offset, (long) src_die->offset, cu->objfile->name);
+ not_found:
+
+ error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
+ "at 0x%x [in module %s]"),
+ offset, src_die->offset, cu->objfile->name);
+}
+
+/* Follow the signature attribute ATTR in SRC_DIE.
+ On entry *REF_CU is the CU of SRC_DIE.
+ On exit *REF_CU is the CU of the result. */
+
+static struct die_info *
+follow_die_sig (struct die_info *src_die, struct attribute *attr,
+ struct dwarf2_cu **ref_cu)
+{
+ struct objfile *objfile = (*ref_cu)->objfile;
+ struct die_info temp_die;
+ struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr);
+ struct dwarf2_cu *sig_cu;
+ struct die_info *die;
+
+ /* sig_type will be NULL if the signatured type is missing from
+ the debug info. */
+ if (sig_type == NULL)
+ error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
+ "at 0x%x [in module %s]"),
+ src_die->offset, objfile->name);
+
+ /* If necessary, add it to the queue and load its DIEs. */
+
+ if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu))
+ read_signatured_type (objfile, sig_type);
+
+ gdb_assert (sig_type->per_cu.cu != NULL);
+
+ sig_cu = sig_type->per_cu.cu;
+ temp_die.offset = sig_cu->header.offset + sig_type->type_offset;
+ die = htab_find_with_hash (sig_cu->die_hash, &temp_die, temp_die.offset);
+ if (die)
+ {
+ *ref_cu = sig_cu;
+ return die;
+ }
+
+ error (_("Dwarf Error: Cannot find signatured DIE at 0x%x referenced from DIE "
+ "at 0x%x [in module %s]"),
+ sig_type->type_offset, src_die->offset, objfile->name);
+}
+
+/* Given an offset of a signatured type, return its signatured_type. */
+
+static struct signatured_type *
+lookup_signatured_type_at_offset (struct objfile *objfile, unsigned int offset)
+{
+ gdb_byte *info_ptr = dwarf2_per_objfile->types.buffer + offset;
+ unsigned int length, initial_length_size;
+ unsigned int sig_offset;
+ struct signatured_type find_entry, *type_sig;
+
+ length = read_initial_length (objfile->obfd, info_ptr, &initial_length_size);
+ sig_offset = (initial_length_size
+ + 2 /*version*/
+ + (initial_length_size == 4 ? 4 : 8) /*debug_abbrev_offset*/
+ + 1 /*address_size*/);
+ find_entry.signature = bfd_get_64 (objfile->obfd, info_ptr + sig_offset);
+ type_sig = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
+
+ /* This is only used to lookup previously recorded types.
+ If we didn't find it, it's our bug. */
+ gdb_assert (type_sig != NULL);
+ gdb_assert (offset == type_sig->offset);
+
+ return type_sig;
+}
+
+/* Read in signatured type at OFFSET and build its CU and die(s). */
+
+static void
+read_signatured_type_at_offset (struct objfile *objfile,
+ unsigned int offset)
+{
+ struct signatured_type *type_sig;
+
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
+
+ /* We have the section offset, but we need the signature to do the
+ hash table lookup. */
+ type_sig = lookup_signatured_type_at_offset (objfile, offset);
+
+ gdb_assert (type_sig->per_cu.cu == NULL);
+
+ read_signatured_type (objfile, type_sig);
+
+ gdb_assert (type_sig->per_cu.cu != NULL);
+}
+
+/* Read in a signatured type and build its CU and DIEs. */
+
+static void
+read_signatured_type (struct objfile *objfile,
+ struct signatured_type *type_sig)
+{
+ gdb_byte *types_ptr = dwarf2_per_objfile->types.buffer + type_sig->offset;
+ struct die_reader_specs reader_specs;
+ struct dwarf2_cu *cu;
+ ULONGEST signature;
+ struct cleanup *back_to, *free_cu_cleanup;
+ struct attribute *attr;
+
+ gdb_assert (type_sig->per_cu.cu == NULL);
+
+ cu = xmalloc (sizeof (struct dwarf2_cu));
+ memset (cu, 0, sizeof (struct dwarf2_cu));
+ obstack_init (&cu->comp_unit_obstack);
+ cu->objfile = objfile;
+ type_sig->per_cu.cu = cu;
+ cu->per_cu = &type_sig->per_cu;
+
+ /* If an error occurs while loading, release our storage. */
+ free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
+
+ types_ptr = read_type_comp_unit_head (&cu->header, &signature,
+ types_ptr, objfile->obfd);
+ gdb_assert (signature == type_sig->signature);
+
+ cu->die_hash
+ = htab_create_alloc_ex (cu->header.length / 12,
+ die_hash,
+ die_eq,
+ NULL,
+ &cu->comp_unit_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+
+ dwarf2_read_abbrevs (cu->objfile->obfd, cu);
+ back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
+
+ init_cu_die_reader (&reader_specs, cu);
+
+ cu->dies = read_die_and_children (&reader_specs, types_ptr, &types_ptr,
+ NULL /*parent*/);
+
+ /* We try not to read any attributes in this function, because not
+ all objfiles needed for references have been loaded yet, and symbol
+ table processing isn't initialized. But we have to set the CU language,
+ or we won't be able to build types correctly. */
+ attr = dwarf2_attr (cu->dies, DW_AT_language, cu);
+ if (attr)
+ set_cu_language (DW_UNSND (attr), cu);
+ else
+ set_cu_language (language_minimal, cu);
+
+ do_cleanups (back_to);
+
+ /* We've successfully allocated this compilation unit. Let our caller
+ clean it up when finished with it. */
+ discard_cleanups (free_cu_cleanup);
+
+ type_sig->per_cu.cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+ dwarf2_per_objfile->read_in_chain = &type_sig->per_cu;
}
/* Decode simple location descriptions.
decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- struct comp_unit_head *cu_header = &cu->header;
int i;
int size = blk->size;
gdb_byte *data = blk->data;
record the macro definitions made in the file, even if we
won't be able to find the file by name. */
char fake_name[80];
+
sprintf (fake_name, "<bad macro file number %d>", file);
complaint (&symfile_complaints,
copy_string (const char *buf, int len)
{
char *s = xmalloc (len + 1);
+
memcpy (s, buf, len);
s[len] = '\0';
-
return s;
}
enum dwarf_macinfo_record_type macinfo_type;
int at_commandline;
+ dwarf2_read_section (dwarf2_per_objfile->objfile,
+ &dwarf2_per_objfile->macinfo);
if (dwarf2_per_objfile->macinfo.buffer == NULL)
{
complaint (&symfile_complaints, _("missing .debug_macinfo section"));
complaint (&symfile_complaints,
_("debug info with no main source gives macro %s "
"on line %d: %s"),
- macinfo_type ==
- DW_MACINFO_define ? _("definition") : macinfo_type ==
- DW_MACINFO_undef ? _("undefinition") :
- "something-or-other", line, body);
+ macinfo_type == DW_MACINFO_define ?
+ _("definition") :
+ macinfo_type == DW_MACINFO_undef ?
+ _("undefinition") :
+ _("something-or-other"), line, body);
break;
}
if ((line == 0 && !at_commandline) || (line != 0 && at_commandline))
complaint (&symfile_complaints,
_("debug info gives %s macro %s with %s line %d: %s"),
at_commandline ? _("command-line") : _("in-file"),
- macinfo_type ==
- DW_MACINFO_define ? _("definition") : macinfo_type ==
- DW_MACINFO_undef ? _("undefinition") :
- "something-or-other",
+ macinfo_type == DW_MACINFO_define ?
+ _("definition") :
+ macinfo_type == DW_MACINFO_undef ?
+ _("undefinition") :
+ _("something-or-other"),
line == 0 ? _("zero") : _("non-zero"), line, body);
if (macinfo_type == DW_MACINFO_define)
attr->form == DW_FORM_block1
|| attr->form == DW_FORM_block2
|| attr->form == DW_FORM_block4
- || attr->form == DW_FORM_block);
+ || attr->form == DW_FORM_block
+ || attr->form == DW_FORM_exprloc);
}
/* Return non-zero if ATTR's value is a section offset --- classes
attr_form_is_section_offset (struct attribute *attr)
{
return (attr->form == DW_FORM_data4
- || attr->form == DW_FORM_data8);
+ || attr->form == DW_FORM_data8
+ || attr->form == DW_FORM_sec_offset);
}
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
+ dwarf2_read_section (dwarf2_per_objfile->objfile,
+ &dwarf2_per_objfile->loc);
+
/* We don't know how long the location list is, but make sure we
don't run off the edge of the section. */
baton->size = dwarf2_per_objfile->loc.size - DW_UNSND (attr);
struct dwarf2_per_objfile *per_objfile
= objfile_data (objfile, dwarf2_objfile_data_key);
gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset;
-
struct comp_unit_head cu_header;
+
memset (&cu_header, 0, sizeof cu_header);
read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
return cu_header.addr_size;
}
}
-/* Locate the compilation unit from CU's objfile which contains the
- DIE at OFFSET. Raises an error on failure. */
+/* Locate the .debug_info compilation unit from CU's objfile which contains
+ the DIE at OFFSET. Raises an error on failure. */
static struct dwarf2_per_cu_data *
dwarf2_find_containing_comp_unit (unsigned int offset,
while (high > low)
{
int mid = low + (high - low) / 2;
+
if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset)
high = mid;
else
dwarf2_find_comp_unit (unsigned int offset, struct objfile *objfile)
{
struct dwarf2_per_cu_data *this_cu;
+
this_cu = dwarf2_find_containing_comp_unit (offset, objfile);
if (this_cu->offset != offset)
error (_("no compilation unit with offset %u."), offset);
offset_and_type_hash (const void *item)
{
const struct dwarf2_offset_and_type *ofs = item;
+
return ofs->offset;
}
{
const struct dwarf2_offset_and_type *ofs_lhs = item_lhs;
const struct dwarf2_offset_and_type *ofs_rhs = item_rhs;
+
return ofs_lhs->offset == ofs_rhs->offset;
}
{
struct dwarf2_offset_and_type **slot, ofs;
+ /* For Ada types, make sure that the gnat-specific data is always
+ initialized (if not already set). There are a few types where
+ we should not be doing so, because the type-specific area is
+ already used to hold some other piece of info (eg: TYPE_CODE_FLT
+ where the type-specific area is used to store the floatformat).
+ But this is not a problem, because the gnat-specific information
+ is actually not needed for these types. */
+ if (need_gnat_info (cu)
+ && TYPE_CODE (type) != TYPE_CODE_FUNC
+ && TYPE_CODE (type) != TYPE_CODE_FLT
+ && !HAVE_GNAT_AUX_INFO (type))
+ INIT_GNAT_SPECIFIC (type);
+
if (cu->type_hash == NULL)
{
gdb_assert (cu->per_cu != NULL);
partial_die_hash (const void *item)
{
const struct partial_die_info *part_die = item;
+
return part_die->offset;
}
{
const struct partial_die_info *part_die_lhs = item_lhs;
const struct partial_die_info *part_die_rhs = item_rhs;
+
return part_die_lhs->offset == part_die_rhs->offset;
}
intptr_t begin = (intptr_t) info->buffer;
intptr_t map_begin = begin & ~(pagesize - 1);
size_t map_length = info->size + begin - map_begin;
+
gdb_assert (munmap ((void *) map_begin, map_length) == 0);
#else
/* Without HAVE_MMAP, we should never be here to begin with. */
/* munmap debug sections for OBJFILE, if necessary. */
static void
-dwarf2_per_objfile_cleanup (struct objfile *objfile, void *d)
+dwarf2_per_objfile_free (struct objfile *objfile, void *d)
{
struct dwarf2_per_objfile *data = d;
+
munmap_section_buffer (&data->info);
munmap_section_buffer (&data->abbrev);
munmap_section_buffer (&data->line);
_initialize_dwarf2_read (void)
{
dwarf2_objfile_data_key
- = register_objfile_data_with_cleanup (dwarf2_per_objfile_cleanup);
+ = 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\