#include "symtab.h"
#include "gdbtypes.h"
#include "objfiles.h"
-#include "elf/dwarf2.h"
+#include "dwarf2.h"
#include "buildsym.h"
#include "demangle.h"
#include "expression.h"
#include "hashtab.h"
#include "command.h"
#include "gdbcmd.h"
+#include "block.h"
#include "addrmap.h"
#include <fcntl.h>
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;
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 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"
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.
+ This struct exists to abstract away the constant parameters of
+ die reading. */
+
+struct die_reader_specs
+{
+ /* The bfd of this objfile. */
+ bfd* abfd;
+
+ /* The CU of the DIE we are parsing. */
+ struct dwarf2_cu *cu;
+
+ /* Pointer to start of section buffer.
+ This is either the start of .debug_info or .debug_types. */
+ const gdb_byte *buffer;
+};
+
/* The line number information for a compilation unit (found in the
.debug_line section) begins with a "statement program header",
which contains the following information. */
CORE_ADDR lowpc;
CORE_ADDR highpc;
- /* Pointer into the info_buffer pointing at the target of
+ /* Pointer into the info_buffer (or types_buffer) pointing at the target of
DW_AT_sibling, if any. */
gdb_byte *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;
unsigned long unsnd;
long int snd;
CORE_ADDR addr;
+ struct signatured_type *signatured_type;
}
u;
};
/* Abbrev number */
unsigned int abbrev;
- /* Offset in .debug_info section */
+ /* Offset in .debug_info or .debug_types section. */
unsigned int offset;
/* The dies in a compilation unit form an n-ary tree. PARENT
/* 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
int need_pc, struct dwarf2_cu *cu);
static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi,
- gdb_byte *info_ptr,
- bfd *abfd,
- struct dwarf2_cu *cu);
+ gdb_byte *buffer, gdb_byte *info_ptr,
+ bfd *abfd, struct dwarf2_cu *cu);
static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
struct dwarf2_cu *);
-static struct partial_die_info *load_partial_dies (bfd *, gdb_byte *, int,
- struct dwarf2_cu *);
+static struct partial_die_info *load_partial_dies (bfd *,
+ gdb_byte *, gdb_byte *,
+ int, struct dwarf2_cu *);
static gdb_byte *read_partial_die (struct partial_die_info *,
- struct abbrev_info *abbrev, unsigned int,
- bfd *, gdb_byte *, struct dwarf2_cu *);
+ struct abbrev_info *abbrev,
+ unsigned int, bfd *,
+ gdb_byte *, gdb_byte *,
+ struct dwarf2_cu *);
static struct partial_die_info *find_partial_die (unsigned int,
struct dwarf2_cu *);
static void fixup_partial_die (struct partial_die_info *,
struct dwarf2_cu *);
-static gdb_byte *read_full_die (struct die_info **, bfd *, gdb_byte *,
- struct dwarf2_cu *, int *);
-
static gdb_byte *read_attribute (struct attribute *, struct attr_abbrev *,
bfd *, gdb_byte *, struct dwarf2_cu *);
static unsigned int read_4_bytes (bfd *, gdb_byte *);
-static unsigned long read_8_bytes (bfd *, gdb_byte *);
+static ULONGEST read_8_bytes (bfd *, gdb_byte *);
static CORE_ADDR read_address (bfd *, gdb_byte *ptr, struct dwarf2_cu *,
unsigned int *);
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 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 *);
static void read_module (struct die_info *die, struct dwarf2_cu *cu);
+static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
+
static const char *namespace_name (struct die_info *die,
int *is_anonymous, struct dwarf2_cu *);
static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
struct dwarf2_cu *);
-static struct die_info *read_comp_unit (gdb_byte *, bfd *, struct dwarf2_cu *);
+static struct die_info *read_comp_unit (gdb_byte *, struct dwarf2_cu *);
-static struct die_info *read_die_and_children_1 (gdb_byte *info_ptr, bfd *abfd,
- struct dwarf2_cu *,
+static struct die_info *read_die_and_children_1 (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
gdb_byte **new_info_ptr,
struct die_info *parent);
-static struct die_info *read_die_and_children (gdb_byte *info_ptr, bfd *abfd,
- struct dwarf2_cu *,
+static struct die_info *read_die_and_children (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
gdb_byte **new_info_ptr,
struct die_info *parent);
-static struct die_info *read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd,
- struct dwarf2_cu *,
+static struct die_info *read_die_and_siblings (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
gdb_byte **new_info_ptr,
struct die_info *parent);
+static gdb_byte *read_full_die (const struct die_reader_specs *reader,
+ struct die_info **, gdb_byte *,
+ int *);
+
static void process_die (struct die_info *, struct dwarf2_cu *);
static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
static void store_in_ref_table (struct die_info *,
struct dwarf2_cu *);
+static int is_ref_attr (struct attribute *);
+
static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
static int 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 *);
struct symbol *sym,
struct dwarf2_cu *cu);
-static gdb_byte *skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev,
- struct dwarf2_cu *cu);
+static gdb_byte *skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
+ struct abbrev_info *abbrev,
+ struct dwarf2_cu *cu);
static void free_stack_comp_unit (void *);
static struct dwarf2_per_cu_data *dwarf2_find_comp_unit
(unsigned int offset, struct objfile *objfile);
+static struct dwarf2_cu *alloc_one_comp_unit (struct objfile *objfile);
+
static void free_one_comp_unit (void *);
static void free_cached_comp_units (void *);
static void create_all_comp_units (struct objfile *);
-static struct dwarf2_cu *load_full_comp_unit (struct dwarf2_per_cu_data *,
- struct objfile *);
+static void load_full_comp_unit (struct dwarf2_per_cu_data *,
+ struct objfile *);
static void process_full_comp_unit (struct dwarf2_per_cu_data *);
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)
#else
bfd_size_type compressed_size = bfd_get_section_size (sectp);
gdb_byte *compressed_buffer = xmalloc (compressed_size);
+ struct cleanup *cleanup = make_cleanup (xfree, compressed_buffer);
bfd_size_type uncompressed_size;
gdb_byte *uncompressed_buffer;
z_stream strm;
error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
bfd_get_filename (abfd), rc);
- xfree (compressed_buffer);
+ do_cleanups (cleanup);
*outbuf = uncompressed_buffer;
*outsize = uncompressed_size;
#endif
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->types);
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);
return (offset >= bottom && offset < top);
}
-/* Read in the comp unit header information from the debug_info at
- info_ptr. */
+/* Read in the comp unit header information from the debug_info at info_ptr.
+ NOTE: This leaves members offset, first_die_offset to be filled in
+ by the caller. */
static gdb_byte *
read_comp_unit_head (struct comp_unit_head *cu_header,
static gdb_byte *
partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr,
+ gdb_byte *buffer, unsigned int buffer_size,
bfd *abfd)
{
gdb_byte *beg_of_comp_unit = info_ptr;
error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
"(offset 0x%lx + 6) [in module %s]"),
(long) header->abbrev_offset,
- (long) (beg_of_comp_unit - dwarf2_per_objfile->info.buffer),
+ (long) (beg_of_comp_unit - buffer),
bfd_get_filename (abfd));
if (beg_of_comp_unit + header->length + header->initial_length_size
- > dwarf2_per_objfile->info.buffer + dwarf2_per_objfile->info.size)
+ > buffer + buffer_size)
error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
"(offset 0x%lx + 0) [in module %s]"),
(long) header->length,
- (long) (beg_of_comp_unit - dwarf2_per_objfile->info.buffer),
+ (long) (beg_of_comp_unit - buffer),
bfd_get_filename (abfd));
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)
+{
+ unsigned int bytes_read;
+ gdb_byte *initial_types_ptr = types_ptr;
+
+ 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. */
free_line_header (lh);
}
+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;
+}
-/* Build the partial symbol table by doing a quick pass through the
- .debug_info and .debug_abbrev sections. */
+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;
+}
-static void
-dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
+/* 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 = dwarf2_per_objfile->types.buffer;
+ htab_t types_htab;
+
+ 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;
+}
+
+/* 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,
+ either .debug_info or debug_types.
+ INFO_PTR is a pointer to the start of the CU.
+ Returns a pointer to the next CU. */
+
+static gdb_byte *
+process_psymtab_comp_unit (struct objfile *objfile,
+ struct dwarf2_per_cu_data *this_cu,
+ gdb_byte *buffer, gdb_byte *info_ptr,
+ unsigned int buffer_size)
{
- /* 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;
- gdb_byte *beg_of_comp_unit;
+ gdb_byte *beg_of_comp_unit = info_ptr;
struct partial_die_info comp_unit_die;
struct partial_symtab *pst;
- struct cleanup *back_to;
CORE_ADDR baseaddr;
+ struct cleanup *back_to_inner;
+ struct dwarf2_cu cu;
+ struct abbrev_info *abbrev;
+ unsigned int bytes_read;
- info_ptr = dwarf2_per_objfile->info.buffer;
+ memset (&cu, 0, sizeof (cu));
+ cu.objfile = objfile;
+ obstack_init (&cu.comp_unit_obstack);
- /* 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);
+ back_to_inner = make_cleanup (free_stack_comp_unit, &cu);
- create_all_comp_units (objfile);
+ info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr,
+ buffer, buffer_size,
+ abfd);
- objfile->psymtabs_addrmap = addrmap_create_mutable
- (&objfile->objfile_obstack);
+ /* Complete the cu_header. */
+ cu.header.offset = beg_of_comp_unit - buffer;
+ cu.header.first_die_offset = info_ptr - beg_of_comp_unit;
- /* Since the objects we're extracting from .debug_info vary in
- length, only the individual functions to extract them (like
- read_comp_unit_head and load_partial_die) can really know whether
- the buffer is large enough to hold another complete object.
+ cu.list_in_scope = &file_symbols;
- At the moment, they don't actually check that. If .debug_info
- holds just one extra byte after the last compilation unit's dies,
- then read_comp_unit_head will happily read off the end of the
- buffer. read_partial_die is similarly casual. Those functions
- should be fixed.
+ /* Read the abbrevs for this compilation unit into a table. */
+ dwarf2_read_abbrevs (abfd, &cu);
+ make_cleanup (dwarf2_free_abbrev_table, &cu);
- For this loop condition, simply checking whether there's any data
- left at all should be sufficient. */
- while (info_ptr < (dwarf2_per_objfile->info.buffer
- + dwarf2_per_objfile->info.size))
+ /* Read the compilation unit die. */
+ if (this_cu->from_debug_types)
+ info_ptr += 8 /*signature*/ + cu.header.offset_size;
+ 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)
{
- struct cleanup *back_to_inner;
- struct dwarf2_cu cu;
- struct abbrev_info *abbrev;
- unsigned int bytes_read;
- struct dwarf2_per_cu_data *this_cu;
+ /* 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);
+ do_cleanups (back_to_inner);
+ return info_ptr;
+ }
+
+ /* Set the language we're debugging. */
+ set_cu_language (comp_unit_die.language, &cu);
- beg_of_comp_unit = info_ptr;
+ /* Allocate a new partial symbol table structure. */
+ pst = start_psymtab_common (objfile, objfile->section_offsets,
+ comp_unit_die.name ? comp_unit_die.name : "",
+ /* TEXTLOW and TEXTHIGH are set below. */
+ 0,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
- memset (&cu, 0, sizeof (cu));
+ if (comp_unit_die.dirname)
+ pst->dirname = obsavestring (comp_unit_die.dirname,
+ strlen (comp_unit_die.dirname),
+ &objfile->objfile_obstack);
- obstack_init (&cu.comp_unit_obstack);
+ pst->read_symtab_private = (char *) this_cu;
- back_to_inner = make_cleanup (free_stack_comp_unit, &cu);
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- cu.objfile = objfile;
- info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr, abfd);
+ /* Store the function that reads in the rest of the symbol table */
+ pst->read_symtab = dwarf2_psymtab_to_symtab;
- /* Complete the cu_header */
- cu.header.offset = beg_of_comp_unit - dwarf2_per_objfile->info.buffer;
- cu.header.first_die_offset = info_ptr - beg_of_comp_unit;
+ /* 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.list_in_scope = &file_symbols;
+ 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);
+ /* 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 = dwarf2_find_comp_unit (cu.header.offset, objfile);
+ this_cu->psymtab = pst;
- /* 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, info_ptr, &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)
+ /* 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);
+
+ /* 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)
+ {
+ struct partial_die_info *first_die;
+ CORE_ADDR lowpc, highpc;
+
+ lowpc = ((CORE_ADDR) -1);
+ highpc = ((CORE_ADDR) 0);
+
+ 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);
- if (comp_unit_die.tag == DW_TAG_partial_unit)
+ /* If we didn't find a lowpc, set it to highpc to avoid
+ complaints from `maint check'. */
+ if (lowpc == ((CORE_ADDR) -1))
+ lowpc = highpc;
+
+ /* 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)
{
- info_ptr = (beg_of_comp_unit + cu.header.length
- + cu.header.initial_length_size);
- do_cleanups (back_to_inner);
- continue;
+ comp_unit_die.lowpc = lowpc;
+ comp_unit_die.highpc = highpc;
}
+ }
+ pst->textlow = comp_unit_die.lowpc + baseaddr;
+ pst->texthigh = comp_unit_die.highpc + baseaddr;
- /* Set the language we're debugging */
- set_cu_language (comp_unit_die.language, &cu);
+ pst->n_global_syms = objfile->global_psymbols.next -
+ (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms = objfile->static_psymbols.next -
+ (objfile->static_psymbols.list + pst->statics_offset);
+ sort_pst_symbols (pst);
- /* Allocate a new partial symbol table structure */
- pst = start_psymtab_common (objfile, objfile->section_offsets,
- comp_unit_die.name ? comp_unit_die.name : "",
- /* TEXTLOW and TEXTHIGH are set below. */
- 0,
- objfile->global_psymbols.next,
- objfile->static_psymbols.next);
+ /* 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. */
+ if (! this_cu->from_debug_types)
+ free_named_symtabs (pst->filename);
- if (comp_unit_die.dirname)
- pst->dirname = obsavestring (comp_unit_die.dirname,
- strlen (comp_unit_die.dirname),
- &objfile->objfile_obstack);
+ info_ptr = (beg_of_comp_unit + cu.header.length
+ + cu.header.initial_length_size);
- pst->read_symtab_private = (char *) this_cu;
+ 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 if (comp_unit_die.has_stmt_list)
+ {
+ /* 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);
+ }
- baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ do_cleanups (back_to_inner);
- /* Store the function that reads in the rest of the symbol table */
- pst->read_symtab = dwarf2_psymtab_to_symtab;
+ return info_ptr;
+}
- /* 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);
+/* Traversal function for htab_traverse_noresize.
+ Process one .debug_types comp-unit. */
- cu.per_cu = this_cu;
+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;
- /* 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 = &entry->per_cu;
+ this_cu->from_debug_types = 1;
- this_cu->psymtab = pst;
+ process_psymtab_comp_unit (objfile, this_cu,
+ dwarf2_per_objfile->types.buffer,
+ dwarf2_per_objfile->types.buffer + entry->offset,
+ dwarf2_per_objfile->types.size);
- /* 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)
- /* 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);
+ return 1;
+}
- /* 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)
- {
- struct partial_die_info *first_die;
- CORE_ADDR lowpc, highpc;
+/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
+ Build partial symbol tables for the .debug_types comp-units. */
- lowpc = ((CORE_ADDR) -1);
- highpc = ((CORE_ADDR) 0);
+static void
+build_type_psymtabs (struct objfile *objfile)
+{
+ if (! create_debug_types_hash_table (objfile))
+ return;
- first_die = load_partial_dies (abfd, info_ptr, 1, &cu);
+ htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
+ process_type_comp_unit, objfile);
+}
- scan_partial_symbols (first_die, &lowpc, &highpc,
- ! comp_unit_die.has_pc_info, &cu);
+/* Build the partial symbol table by doing a quick pass through the
+ .debug_info and .debug_abbrev sections. */
- /* If we didn't find a lowpc, set it to highpc to avoid
- complaints from `maint check'. */
- if (lowpc == ((CORE_ADDR) -1))
- lowpc = highpc;
+static void
+dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
+{
+ /* 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;
- /* 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)
- {
- comp_unit_die.lowpc = lowpc;
- comp_unit_die.highpc = highpc;
- }
- }
- pst->textlow = comp_unit_die.lowpc + baseaddr;
- pst->texthigh = comp_unit_die.highpc + baseaddr;
+ info_ptr = dwarf2_per_objfile->info.buffer;
- pst->n_global_syms = objfile->global_psymbols.next -
- (objfile->global_psymbols.list + pst->globals_offset);
- pst->n_static_syms = objfile->static_psymbols.next -
- (objfile->static_psymbols.list + pst->statics_offset);
- sort_pst_symbols (pst);
+ /* 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);
- /* 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);
+ build_type_psymtabs (objfile);
- info_ptr = beg_of_comp_unit + cu.header.length
- + cu.header.initial_length_size;
+ create_all_comp_units (objfile);
- if (comp_unit_die.has_stmt_list)
- {
- /* 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);
- }
+ objfile->psymtabs_addrmap =
+ addrmap_create_mutable (&objfile->objfile_obstack);
- do_cleanups (back_to_inner);
+ /* Since the objects we're extracting from .debug_info vary in
+ length, only the individual functions to extract them (like
+ read_comp_unit_head and load_partial_die) can really know whether
+ the buffer is large enough to hold another complete object.
+
+ At the moment, they don't actually check that. If .debug_info
+ holds just one extra byte after the last compilation unit's dies,
+ then read_comp_unit_head will happily read off the end of the
+ buffer. read_partial_die is similarly casual. Those functions
+ should be fixed.
+
+ For this loop condition, simply checking whether there's any data
+ left at all should be sufficient. */
+
+ while (info_ptr < (dwarf2_per_objfile->info.buffer
+ + dwarf2_per_objfile->info.size))
+ {
+ struct dwarf2_per_cu_data *this_cu;
+
+ this_cu = dwarf2_find_comp_unit (info_ptr - dwarf2_per_objfile->info.buffer,
+ objfile);
+
+ info_ptr = process_psymtab_comp_unit (objfile, this_cu,
+ dwarf2_per_objfile->info.buffer,
+ info_ptr,
+ dwarf2_per_objfile->info.size);
}
objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
do_cleanups (back_to);
}
-/* Load the DIEs for a secondary CU into memory. */
+/* Load the partial DIEs for a secondary CU into memory. */
static void
-load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile)
+load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu,
+ struct objfile *objfile)
{
bfd *abfd = objfile->obfd;
gdb_byte *info_ptr, *beg_of_comp_unit;
unsigned int bytes_read;
struct cleanup *back_to;
+ gdb_assert (! this_cu->from_debug_types);
+
info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset;
beg_of_comp_unit = info_ptr;
- cu = xmalloc (sizeof (struct dwarf2_cu));
- memset (cu, 0, sizeof (struct dwarf2_cu));
+ cu = alloc_one_comp_unit (objfile);
- obstack_init (&cu->comp_unit_obstack);
+ /* ??? Missing cleanup for CU? */
- cu->objfile = objfile;
- info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr, abfd);
+ info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr,
+ dwarf2_per_objfile->info.buffer,
+ dwarf2_per_objfile->info.size,
+ abfd);
/* Complete the cu_header. */
- cu->header.offset = beg_of_comp_unit - dwarf2_per_objfile->info.buffer;
+ cu->header.offset = this_cu->offset;
cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
/* Read the abbrevs for this compilation unit into a table. */
/* 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, info_ptr, cu);
+ info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, abfd,
+ dwarf2_per_objfile->info.buffer, info_ptr, cu);
/* 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 = cu->per_cu->type_hash;
+ cu->type_hash = this_cu->type_hash;
/* 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)
- load_partial_dies (abfd, info_ptr, 0, cu);
+ load_partial_dies (abfd, dwarf2_per_objfile->info.buffer, info_ptr, 0, cu);
do_cleanups (back_to);
}
return abbrev;
}
-/* Scan the debug information for CU starting at INFO_PTR. Returns a
- pointer to the end of a series of DIEs, terminated by an empty
+/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER.
+ Returns a pointer to the end of a series of DIEs, terminated by an empty
DIE. Any children of the skipped DIEs will also be skipped. */
static gdb_byte *
-skip_children (gdb_byte *info_ptr, struct dwarf2_cu *cu)
+skip_children (gdb_byte *buffer, gdb_byte *info_ptr, struct dwarf2_cu *cu)
{
struct abbrev_info *abbrev;
unsigned int bytes_read;
if (abbrev == NULL)
return info_ptr + bytes_read;
else
- info_ptr = skip_one_die (info_ptr + bytes_read, abbrev, cu);
+ info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu);
}
}
-/* Scan the debug information for CU starting at INFO_PTR. INFO_PTR
- should point just after the initial uleb128 of a DIE, and the
+/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER.
+ INFO_PTR should point just after the initial uleb128 of a DIE, and the
abbrev corresponding to that skipped uleb128 should be passed in
ABBREV. Returns a pointer to this DIE's sibling, skipping any
children. */
static gdb_byte *
-skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev,
- struct dwarf2_cu *cu)
+skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
+ struct abbrev_info *abbrev, struct dwarf2_cu *cu)
{
unsigned int bytes_read;
struct attribute attr;
if (attr.form == DW_FORM_ref_addr)
complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling"));
else
- return dwarf2_per_objfile->info.buffer
- + dwarf2_get_ref_die_offset (&attr);
+ return buffer + dwarf2_get_ref_die_offset (&attr);
}
/* If it isn't DW_AT_sibling, skip this attribute. */
break;
case DW_FORM_data8:
case DW_FORM_ref8:
+ case DW_FORM_sig8:
info_ptr += 8;
break;
case DW_FORM_string:
}
if (abbrev->has_children)
- return skip_children (info_ptr, cu);
+ return skip_children (buffer, info_ptr, cu);
else
return info_ptr;
}
-/* Locate ORIG_PDI's sibling; INFO_PTR should point to the start of
- the next DIE after ORIG_PDI. */
+/* Locate ORIG_PDI's sibling.
+ INFO_PTR should point to the start of the next DIE after ORIG_PDI
+ in BUFFER. */
static gdb_byte *
-locate_pdi_sibling (struct partial_die_info *orig_pdi, gdb_byte *info_ptr,
+locate_pdi_sibling (struct partial_die_info *orig_pdi,
+ gdb_byte *buffer, gdb_byte *info_ptr,
bfd *abfd, struct dwarf2_cu *cu)
{
/* Do we know the sibling already? */
/* Skip the children the long way. */
- return skip_children (info_ptr, cu);
+ return skip_children (buffer, info_ptr, cu);
}
/* Expand this partial symbol table into a full symbol table. */
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. */
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
do_cleanups (back_to);
}
-/* Load the DIEs associated with PST and PER_CU into memory. */
+/* Load the DIEs associated with PER_CU into memory. */
-static struct dwarf2_cu *
+static void
load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile)
{
bfd *abfd = objfile->obfd;
struct dwarf2_cu *cu;
unsigned int offset;
- gdb_byte *info_ptr;
+ 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;
info_ptr = dwarf2_per_objfile->info.buffer + offset;
+ beg_of_comp_unit = info_ptr;
- cu = xmalloc (sizeof (struct dwarf2_cu));
- memset (cu, 0, sizeof (struct dwarf2_cu));
+ cu = alloc_one_comp_unit (objfile);
/* If an error occurs while loading, release our storage. */
free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
- cu->objfile = objfile;
-
- /* read in the comp_unit header */
+ /* Read in the comp_unit header. */
info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd);
- /* Read the abbrevs for this compilation unit */
+ /* Complete the cu_header. */
+ cu->header.offset = offset;
+ cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
+
+ /* Read the abbrevs for this compilation unit. */
dwarf2_read_abbrevs (abfd, cu);
back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
- cu->header.offset = offset;
-
- cu->per_cu = per_cu;
+ /* Link this compilation unit into the compilation unit tree. */
per_cu->cu = cu;
+ cu->per_cu = per_cu;
cu->type_hash = per_cu->type_hash;
- /* We use this obstack for block values in dwarf_alloc_block. */
- obstack_init (&cu->comp_unit_obstack);
-
- cu->dies = read_comp_unit (info_ptr, abfd, cu);
+ cu->dies = read_comp_unit (info_ptr, cu);
/* We try not to read any attributes in this function, because not
all objfiles needed for references have been loaded yet, and symbol
else
set_cu_language (language_minimal, cu);
+ /* 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
clean it up when finished with it. */
discard_cleanups (free_cu_cleanup);
-
- return cu;
}
/* Generate full symbol information for PST and CU, whose DIEs have
case DW_TAG_compile_unit:
read_file_scope (die, cu);
break;
- case DW_TAG_subprogram:
- read_func_scope (die, cu);
+ case DW_TAG_type_unit:
+ read_type_unit_scope (die, cu);
break;
+ case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
- /* FIXME: These are ignored for now.
- They could be used to set breakpoints on all inlined instances
- of a function and make GDB `next' properly over inlined functions. */
+ read_func_scope (die, cu);
break;
case DW_TAG_lexical_block:
case DW_TAG_try_block:
break;
case DW_TAG_imported_declaration:
case DW_TAG_imported_module:
- /* FIXME: carlton/2002-10-16: Eventually, we should use the
- information contained in these. DW_TAG_imported_declaration
- dies shouldn't have children; DW_TAG_imported_module dies
- shouldn't in the C++ case, but conceivably could in the
- Fortran case. */
processing_has_namespace_info = 1;
- complaint (&symfile_complaints, _("unsupported tag: '%s'"),
- dwarf_tag_name (die->tag));
+ if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
+ || cu->language != language_fortran))
+ complaint (&symfile_complaints, _("Tag '%s' has unexpected children"),
+ dwarf_tag_name (die->tag));
+ read_import_statement (die, cu);
break;
default:
new_symbol (die, NULL, cu);
return name;
}
+/* Read the import statement specified by the given die and record it. */
+
+static void
+read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *import_attr;
+ struct die_info *imported_die;
+ const char *imported_name;
+ const char *imported_name_prefix;
+ const char *import_prefix;
+ char *canonical_name;
+
+ import_attr = dwarf2_attr (die, DW_AT_import, cu);
+ if (import_attr == NULL)
+ {
+ complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
+ dwarf_tag_name (die->tag));
+ return;
+ }
+
+ imported_die = follow_die_ref_or_sig (die, import_attr, &cu);
+ imported_name = dwarf2_name (imported_die, cu);
+ if (imported_name == NULL)
+ {
+ /* GCC bug: https://bugzilla.redhat.com/show_bug.cgi?id=506524
+
+ The import in the following code:
+ namespace A
+ {
+ typedef int B;
+ }
+
+ int main ()
+ {
+ using A::B;
+ B b;
+ return b;
+ }
+
+ ...
+ <2><51>: Abbrev Number: 3 (DW_TAG_imported_declaration)
+ <52> DW_AT_decl_file : 1
+ <53> DW_AT_decl_line : 6
+ <54> DW_AT_import : <0x75>
+ <2><58>: Abbrev Number: 4 (DW_TAG_typedef)
+ <59> DW_AT_name : B
+ <5b> DW_AT_decl_file : 1
+ <5c> DW_AT_decl_line : 2
+ <5d> DW_AT_type : <0x6e>
+ ...
+ <1><75>: Abbrev Number: 7 (DW_TAG_base_type)
+ <76> DW_AT_byte_size : 4
+ <77> DW_AT_encoding : 5 (signed)
+
+ imports the wrong die ( 0x75 instead of 0x58 ).
+ This case will be ignored until the gcc bug is fixed. */
+ return;
+ }
+
+ /* FIXME: dwarf2_name (die); for the local name after import. */
+
+ /* 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);
+
+ if (strlen (imported_name_prefix) > 0)
+ {
+ 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);
+ }
+ else
+ {
+ canonical_name = alloca (strlen (imported_name) + 1);
+ strcpy (canonical_name, imported_name);
+ }
+
+ using_directives = cp_add_using (import_prefix,canonical_name, using_directives);
+}
+
static void
initialize_cu_func_list (struct dwarf2_cu *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;
+ struct line_header *line_header = 0;
+
+ /* 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);
+
+ /* 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);
+
+ /* Process the dies in the type unit. */
+ if (die->child == NULL)
+ {
+ dump_die_for_error (die);
+ error (_("Dwarf Error: Missing children for type unit [in module %s]"),
+ bfd_get_filename (abfd));
+ }
+
+ child_die = die->child;
+
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, cu);
+
+ child_die = sibling_die (child_die);
+ }
+
+ do_cleanups (back_to);
+}
+
static void
add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc,
struct dwarf2_cu *cu)
return;
origin_die = follow_die_ref (die, attr, &cu);
- if (die->tag != origin_die->tag)
+ if (die->tag != origin_die->tag
+ && !(die->tag == DW_TAG_inlined_subroutine
+ && origin_die->tag == DW_TAG_subprogram))
complaint (&symfile_complaints,
_("DIE 0x%x and its abstract origin 0x%x have different tags"),
die->offset, origin_die->offset);
child_die = die->child;
while (child_die && child_die->tag)
{
- attr = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
+ /* For each CHILD_DIE, find the corresponding child of
+ ORIGIN_DIE. If there is more than one layer of
+ DW_AT_abstract_origin, follow them all; there shouldn't be,
+ but GCC versions at least through 4.4 generate this (GCC PR
+ 40573). */
+ struct die_info *child_origin_die = child_die;
+ while (1)
+ {
+ attr = dwarf2_attr (child_origin_die, DW_AT_abstract_origin, cu);
+ if (attr == NULL)
+ break;
+ child_origin_die = follow_die_ref (child_origin_die, attr, &cu);
+ }
+
/* According to DWARF3 3.3.8.2 #3 new entries without their abstract
counterpart may exist. */
- if (attr)
+ if (child_origin_die != child_die)
{
- struct die_info *child_origin_die;
-
- child_origin_die = follow_die_ref (child_die, attr, &cu);
- if (child_die->tag != child_origin_die->tag)
+ if (child_die->tag != child_origin_die->tag
+ && !(child_die->tag == DW_TAG_inlined_subroutine
+ && child_origin_die->tag == DW_TAG_subprogram))
complaint (&symfile_complaints,
_("Child DIE 0x%x and its abstract origin 0x%x have "
"different tags"), child_die->offset,
child_origin_die->offset);
- *offsets_end++ = child_origin_die->offset;
+ if (child_origin_die->parent != origin_die)
+ complaint (&symfile_complaints,
+ _("Child DIE 0x%x and its abstract origin 0x%x have "
+ "different parents"), child_die->offset,
+ child_origin_die->offset);
+ else
+ *offsets_end++ = child_origin_die->offset;
}
child_die = sibling_die (child_die);
}
CORE_ADDR lowpc;
CORE_ADDR highpc;
struct die_info *child_die;
- struct attribute *attr;
+ struct attribute *attr, *call_line, *call_file;
char *name;
CORE_ADDR baseaddr;
struct block *block;
+ int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
+
+ if (inlined_func)
+ {
+ /* If we do not have call site information, we can't show the
+ caller of this inlined function. That's too confusing, so
+ only use the scope for local variables. */
+ call_line = dwarf2_attr (die, DW_AT_call_line, cu);
+ call_file = dwarf2_attr (die, DW_AT_call_file, cu);
+ if (call_line == NULL || call_file == NULL)
+ {
+ read_lexical_block_scope (die, cu);
+ return;
+ }
+ }
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
back to building a containing block's symbol lists. */
local_symbols = new->locals;
param_symbols = new->params;
+ using_directives = new->using_directives;
/* If we've finished processing a top-level function, subsequent
symbols go in the file symbol list. */
dwarf2_record_block_ranges (die, block, baseaddr, cu);
}
local_symbols = new->locals;
+ using_directives = new->using_directives;
}
/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
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);
}
/* 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);
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);
+
name = dwarf2_name (die, cu);
if (name != NULL)
{
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;
arrays with unspecified length. */
if (die->child == NULL)
{
- index_type = builtin_type_int32;
+ index_type = objfile_type (objfile)->builtin_int;
range_type = create_range_type (NULL, index_type, 0, -1);
type = create_array_type (NULL, element_type, range_type);
return set_die_type (die, type, cu);
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;
}
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);
if (is_anonymous)
{
const char *previous_prefix = determine_prefix (die, cu);
- cp_add_using_directive (TYPE_NAME (type),
- strlen (previous_prefix),
- strlen (TYPE_NAME (type)));
+ cp_add_using_directive (previous_prefix, TYPE_NAME (type));
}
}
}
}
- index_type = builtin_type_int32;
+ index_type = objfile_type (objfile)->builtin_int;
range_type = create_range_type (NULL, index_type, 1, length);
char_type = language_string_char_type (cu->language_defn, gdbarch);
type = create_string_type (NULL, char_type, range_type);
struct attribute *attr;
type = die_type (die, cu);
- ftype = make_function_type (type, (struct type **) 0, cu->objfile);
+ ftype = lookup_function_type (type);
/* All functions in C++, Pascal and Java have prototypes. */
attr = dwarf2_attr (die, DW_AT_prototyped, cu);
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;
+ if (cu->per_cu->from_debug_types)
+ reader->buffer = dwarf2_per_objfile->types.buffer;
+ else
+ reader->buffer = dwarf2_per_objfile->info.buffer;
+}
+
/* Read a whole compilation unit into a linked list of dies. */
static struct die_info *
-read_comp_unit (gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *cu)
+read_comp_unit (gdb_byte *info_ptr, struct dwarf2_cu *cu)
{
+ 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,
hashtab_obstack_allocate,
dummy_obstack_deallocate);
- return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL);
+ init_cu_die_reader (&reader_specs, cu);
+
+ return read_die_and_children (&reader_specs, info_ptr, &info_ptr, NULL);
}
/* Main entry point for reading a DIE and all children.
Read the DIE and dump it if requested. */
static struct die_info *
-read_die_and_children (gdb_byte *info_ptr, bfd *abfd,
- struct dwarf2_cu *cu,
+read_die_and_children (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
gdb_byte **new_info_ptr,
struct die_info *parent)
{
- struct die_info *result = read_die_and_children_1 (info_ptr, abfd, cu,
+ struct die_info *result = read_die_and_children_1 (reader, info_ptr,
new_info_ptr, parent);
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);
}
is the parent of the die in question. */
static struct die_info *
-read_die_and_children_1 (gdb_byte *info_ptr, bfd *abfd,
- struct dwarf2_cu *cu,
+read_die_and_children_1 (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
gdb_byte **new_info_ptr,
struct die_info *parent)
{
gdb_byte *cur_ptr;
int has_children;
- cur_ptr = read_full_die (&die, abfd, info_ptr, cu, &has_children);
+ cur_ptr = read_full_die (reader, &die, info_ptr, &has_children);
if (die == NULL)
{
*new_info_ptr = cur_ptr;
return NULL;
}
- store_in_ref_table (die, cu);
+ store_in_ref_table (die, reader->cu);
if (has_children)
- {
- die->child = read_die_and_siblings (cur_ptr, abfd, cu,
- new_info_ptr, die);
- }
+ die->child = read_die_and_siblings (reader, cur_ptr, new_info_ptr, die);
else
{
die->child = NULL;
in read_die_and_children. */
static struct die_info *
-read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd,
- struct dwarf2_cu *cu,
+read_die_and_siblings (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
gdb_byte **new_info_ptr,
struct die_info *parent)
{
while (1)
{
struct die_info *die
- = read_die_and_children_1 (cur_ptr, abfd, cu, &cur_ptr, parent);
+ = read_die_and_children_1 (reader, cur_ptr, &cur_ptr, parent);
if (die == NULL)
{
}
}
+/* Read the die from the .debug_info section buffer. Set DIEP to
+ point to a newly allocated die with its information, except for its
+ child, sibling, and parent fields. Set HAS_CHILDREN to tell
+ whether the die has children or not. */
+
+static gdb_byte *
+read_full_die (const struct die_reader_specs *reader,
+ struct die_info **diep, gdb_byte *info_ptr,
+ int *has_children)
+{
+ unsigned int abbrev_number, bytes_read, i, offset;
+ struct abbrev_info *abbrev;
+ struct die_info *die;
+ struct dwarf2_cu *cu = reader->cu;
+ bfd *abfd = reader->abfd;
+
+ offset = info_ptr - reader->buffer;
+ abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ if (!abbrev_number)
+ {
+ *diep = NULL;
+ *has_children = 0;
+ return info_ptr;
+ }
+
+ 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));
+
+ die = dwarf_alloc_die (cu, abbrev->num_attrs);
+ die->offset = offset;
+ die->tag = abbrev->tag;
+ die->abbrev = abbrev_number;
+
+ die->num_attrs = abbrev->num_attrs;
+
+ for (i = 0; i < abbrev->num_attrs; ++i)
+ info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
+ abfd, info_ptr, cu);
+
+ *diep = die;
+ *has_children = abbrev->has_children;
+ return info_ptr;
+}
+
/* In DWARF version 2, the description of the debugging information is
stored in a separate .debug_abbrev section. Before we read any
dies from a section we read in all abbreviations and install them
/* Load all DIEs that are interesting for partial symbols into memory. */
static struct partial_die_info *
-load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab,
- struct dwarf2_cu *cu)
+load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
+ int building_psymtab, struct dwarf2_cu *cu)
{
struct partial_die_info *part_die;
struct partial_die_info *parent_die, *last_die, *first_die = NULL;
&& abbrev->tag != DW_TAG_member)
{
/* Otherwise we skip to the next sibling, if any. */
- info_ptr = skip_one_die (info_ptr + bytes_read, abbrev, cu);
+ info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu);
continue;
}
- info_ptr = read_partial_die (part_die, abbrev, bytes_read,
- abfd, info_ptr, cu);
+ info_ptr = read_partial_die (part_die, abbrev, bytes_read, abfd,
+ buffer, info_ptr, cu);
/* This two-pass algorithm for processing partial symbols has a
high cost in cache pressure. Thus, handle some simple cases
VAR_DOMAIN, LOC_TYPEDEF,
&cu->objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, cu->objfile);
- info_ptr = locate_pdi_sibling (part_die, info_ptr, abfd, cu);
+ info_ptr = locate_pdi_sibling (part_die, buffer, info_ptr, abfd, cu);
continue;
}
: &cu->objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, cu->objfile);
- info_ptr = locate_pdi_sibling (part_die, info_ptr, abfd, cu);
+ info_ptr = locate_pdi_sibling (part_die, buffer, info_ptr, abfd, cu);
continue;
}
}
/* Otherwise we skip to the next sibling, if any. */
- info_ptr = locate_pdi_sibling (last_die, info_ptr, abfd, cu);
+ info_ptr = locate_pdi_sibling (last_die, buffer, info_ptr, abfd, cu);
/* Back to the top, do it again. */
}
read_partial_die (struct partial_die_info *part_die,
struct abbrev_info *abbrev,
unsigned int abbrev_len, bfd *abfd,
- gdb_byte *info_ptr, struct dwarf2_cu *cu)
+ gdb_byte *buffer, gdb_byte *info_ptr,
+ struct dwarf2_cu *cu)
{
unsigned int bytes_read, i;
struct attribute attr;
memset (part_die, 0, sizeof (struct partial_die_info));
- part_die->offset = info_ptr - dwarf2_per_objfile->info.buffer;
+ part_die->offset = info_ptr - buffer;
info_ptr += abbrev_len;
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:
if (attr.form == DW_FORM_ref_addr)
complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling"));
else
- part_die->sibling = dwarf2_per_objfile->info.buffer
- + dwarf2_get_ref_die_offset (&attr);
+ part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr);
break;
case DW_AT_stmt_list:
part_die->has_stmt_list = 1;
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 == NULL)
{
- load_comp_unit (per_cu, cu->objfile);
+ load_partial_comp_unit (per_cu, cu->objfile);
per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
dwarf2_per_objfile->read_in_chain = per_cu;
}
+ per_cu->cu->header.first_die_offset);
abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu);
info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
- per_cu->cu->objfile->obfd, info_ptr,
+ per_cu->cu->objfile->obfd,
+ dwarf2_per_objfile->info.buffer, info_ptr,
per_cu->cu);
if (comp_unit_die.has_children)
- load_partial_dies (per_cu->cu->objfile->obfd, info_ptr, 0, per_cu->cu);
+ load_partial_dies (per_cu->cu->objfile->obfd,
+ dwarf2_per_objfile->info.buffer, info_ptr,
+ 0, per_cu->cu);
do_cleanups (back_to);
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"),
guess_structure_name (part_die, cu);
}
-/* Read the die from the .debug_info section buffer. Set DIEP to
- point to a newly allocated die with its information, except for its
- child, sibling, and parent fields. Set HAS_CHILDREN to tell
- whether the die has children or not. */
-
-static gdb_byte *
-read_full_die (struct die_info **diep, bfd *abfd, gdb_byte *info_ptr,
- struct dwarf2_cu *cu, int *has_children)
-{
- unsigned int abbrev_number, bytes_read, i, offset;
- struct abbrev_info *abbrev;
- struct die_info *die;
-
- offset = info_ptr - dwarf2_per_objfile->info.buffer;
- abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
- info_ptr += bytes_read;
- if (!abbrev_number)
- {
- *diep = NULL;
- *has_children = 0;
- return info_ptr;
- }
-
- 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));
- }
- die = dwarf_alloc_die (cu, abbrev->num_attrs);
- die->offset = offset;
- die->tag = abbrev->tag;
- die->abbrev = abbrev_number;
-
- die->num_attrs = abbrev->num_attrs;
-
- for (i = 0; i < abbrev->num_attrs; ++i)
- info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
- abfd, info_ptr, cu);
-
- *diep = die;
- *has_children = abbrev->has_children;
- return info_ptr;
-}
-
/* Read an attribute value described by an attribute form. */
static gdb_byte *
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_block:
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));
return bfd_get_signed_32 (abfd, buf);
}
-static unsigned long
+static ULONGEST
read_8_bytes (bfd *abfd, gdb_byte *buf)
{
return bfd_get_64 (abfd, buf);
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. */
/* Return the die giving the specification for DIE, if there is
one. *SPEC_CU is the CU containing DIE on input, and the CU
- containing the return value on output. */
+ containing the return value on output. If there is no
+ specification, but there is an abstract origin, that is
+ returned. */
static struct die_info *
die_specification (struct die_info *die, struct dwarf2_cu **spec_cu)
struct attribute *spec_attr = dwarf2_attr (die, DW_AT_specification,
*spec_cu);
+ if (spec_attr == NULL)
+ spec_attr = dwarf2_attr (die, DW_AT_abstract_origin, *spec_cu);
+
if (spec_attr == NULL)
return NULL;
else
else
{
lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p)
+ if (!decode_for_pst_p && is_stmt)
{
if (last_subfile != current_subfile)
{
record_line (current_subfile, line, addr);
}
}
- basic_block = 1;
+ basic_block = 0;
}
else switch (op_code)
{
else
{
lh->file_names[file - 1].included_p = 1;
- if (!decode_for_pst_p)
+ if (!decode_for_pst_p && is_stmt)
{
if (last_subfile != current_subfile)
{
new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct symbol *sym = NULL;
char *name;
struct attribute *attr = NULL;
struct attribute *attr2 = NULL;
CORE_ADDR baseaddr;
+ int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
SYMBOL_TYPE (sym) = type;
else
SYMBOL_TYPE (sym) = die_type (die, cu);
- attr = dwarf2_attr (die, DW_AT_decl_line, cu);
+ attr = dwarf2_attr (die,
+ inlined_func ? DW_AT_call_line : DW_AT_decl_line,
+ cu);
if (attr)
{
SYMBOL_LINE (sym) = DW_UNSND (attr);
}
- attr = dwarf2_attr (die, DW_AT_decl_file, cu);
+ attr = dwarf2_attr (die,
+ inlined_func ? DW_AT_call_file : DW_AT_decl_file,
+ cu);
if (attr)
{
int file_index = DW_UNSND (attr);
add_symbol_to_list (sym, cu->list_in_scope);
}
break;
+ case DW_TAG_inlined_subroutine:
+ /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
+ finish_block. */
+ SYMBOL_CLASS (sym) = LOC_BLOCK;
+ SYMBOL_INLINED (sym) = 1;
+ /* Do not add the symbol to any lists. It will be found via
+ BLOCK_FUNCTION from the blockvector. */
+ break;
case DW_TAG_variable:
/* Compilation with minimal debug info may result in variables
with missing type entries. Change the misleading `void' type
to something sensible. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
SYMBOL_TYPE (sym)
- = builtin_type (gdbarch)->nodebug_data_symbol;
+ = objfile_type (objfile)->nodebug_data_symbol;
attr = dwarf2_attr (die, DW_AT_const_value, cu);
if (attr)
}
break;
case DW_TAG_formal_parameter:
- SYMBOL_IS_ARGUMENT (sym) = 1;
+ /* If we are inside a function, mark this as an argument. If
+ not, we might be looking at an argument to an inlined function
+ when we do not have enough information to show inlined frames;
+ pretend it's a local variable in that case so that the user can
+ still see it. */
+ if (context_stack_depth > 0
+ && context_stack[context_stack_depth - 1].name != NULL)
+ SYMBOL_IS_ARGUMENT (sym) = 1;
attr = dwarf2_attr (die, DW_AT_location, cu);
if (attr)
{
{
struct objfile *objfile = cu->objfile;
struct comp_unit_head *cu_header = &cu->header;
+ enum bfd_endian byte_order = bfd_big_endian (objfile->obfd) ?
+ BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
struct dwarf_block *blk;
switch (attr->form)
/* 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, DW_ADDR (attr));
SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
break;
case DW_FORM_string:
static struct type *
die_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
struct type *type;
struct attribute *type_attr;
struct die_info *type_die;
if (!type_attr)
{
/* A missing DW_AT_type represents a void type. */
- return builtin_type (gdbarch)->builtin_void;
+ return objfile_type (cu->objfile)->builtin_void;
}
- else
- type_die = follow_die_ref (die, type_attr, &cu);
+
+ type_die = follow_die_ref_or_sig (die, type_attr, &cu);
type = tag_type_to_type (type_die, cu);
if (!type)
type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
if (type_attr)
{
- type_die = follow_die_ref (die, type_attr, &cu);
+ type_die = follow_die_ref_or_sig (die, type_attr, &cu);
type = tag_type_to_type (type_die, cu);
}
if (!type)
break;
case DW_TAG_subprogram:
case DW_TAG_subroutine_type:
+ case DW_TAG_inlined_subroutine:
this_type = read_subroutine_type (die, cu);
break;
case DW_TAG_array_type:
to canonicalize them. */
return DW_STRING (attr);
default:
- if (attr->form != GDB_FORM_cached_string)
+ if (!DW_STRING_IS_CANONICAL (attr))
{
DW_STRING (attr)
= dwarf2_canonicalize_name (DW_STRING (attr), cu,
&cu->objfile->objfile_obstack);
- attr->form = GDB_FORM_cached_string;
+ DW_STRING_IS_CANONICAL (attr) = 1;
}
return DW_STRING (attr);
}
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";
/* 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_ref_addr:
case DW_FORM_addr:
fprintf_unfiltered (f, "address: ");
- fputs_filtered (paddress (DW_ADDR (&die->attrs[i])), f);
+ fputs_filtered (hex_string (DW_ADDR (&die->attrs[i])), f);
break;
case DW_FORM_block2:
case DW_FORM_block4:
case DW_FORM_sdata:
fprintf_unfiltered (f, "constant: %ld", 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]))
*slot = die;
}
-static unsigned int
-dwarf2_get_ref_die_offset (struct attribute *attr)
+static int
+is_ref_attr (struct attribute *attr)
{
- unsigned int result = 0;
-
switch (attr->form)
{
case DW_FORM_ref_addr:
case DW_FORM_ref4:
case DW_FORM_ref8:
case DW_FORM_ref_udata:
- result = DW_ADDR (attr);
- break;
+ return 1;
default:
- complaint (&symfile_complaints,
- _("unsupported die ref attribute form: '%s'"),
- dwarf_form_name (attr->form));
+ return 0;
}
- return result;
+}
+
+static unsigned int
+dwarf2_get_ref_die_offset (struct attribute *attr)
+{
+ if (is_ref_attr (attr))
+ return DW_ADDR (attr);
+
+ complaint (&symfile_complaints,
+ _("unsupported die ref attribute form: '%s'"),
+ dwarf_form_name (attr->form));
+ return 0;
}
/* Return the constant value held by the given attribute. Return -1
}
/* 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;
+
+ /* 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.
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)
}
}
-/* 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,
return this_cu;
}
+/* Malloc space for a dwarf2_cu for OBJFILE and initialize it. */
+
+static struct dwarf2_cu *
+alloc_one_comp_unit (struct objfile *objfile)
+{
+ struct dwarf2_cu *cu = xcalloc (1, sizeof (struct dwarf2_cu));
+ cu->objfile = objfile;
+ obstack_init (&cu->comp_unit_obstack);
+ return cu;
+}
+
/* Release one cached compilation unit, CU. We unlink it from the tree
of compilation units, but we don't remove it from the read_in_chain;
- the caller is responsible for that. */
+ the caller is responsible for that.
+ NOTE: DATA is a void * because this function is also used as a
+ cleanup routine. */
static void
free_one_comp_unit (void *data)
/* 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);
_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\