#include "hashtab.h"
#include "command.h"
#include "gdbcmd.h"
+#include "addrmap.h"
#include <fcntl.h>
#include "gdb_string.h"
#include "gdb_assert.h"
#include <sys/types.h>
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
/* A note on memory usage for this file.
/* names of the debugging sections */
-#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 FRAME_SECTION ".debug_frame"
-#define EH_FRAME_SECTION ".eh_frame"
+/* Note that if the debugging section has been compressed, it might
+ have a name like .zdebug_info. */
+
+#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 FRAME_SECTION "debug_frame"
+#define EH_FRAME_SECTION "eh_frame"
/* local data types */
/* Hash table holding all the loaded partial DIEs. */
htab_t partial_dies;
+ /* `.debug_ranges' offset for this `DW_TAG_compile_unit' DIE. */
+ unsigned long ranges_offset;
+
/* Storage for things with the same lifetime as this read-in compilation
unit, including partial DIEs. */
struct obstack comp_unit_obstack;
/* Backchain to our per_cu entry if the tree has been built. */
struct dwarf2_per_cu_data *per_cu;
+ /* Pointer to the die -> type map. Although it is stored
+ permanently in per_cu, we copy it here to avoid double
+ indirection. */
+ htab_t type_hash;
+
/* How many compilation units ago was this CU last referenced? */
int last_used;
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 die_info *child; /* Its first child, if any. */
struct die_info *sibling; /* Its next sibling, if any. */
struct die_info *parent; /* Its parent, if any. */
-
- struct type *type; /* Cached type information */
};
/* Attributes have a name and a value */
static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *);
-static void read_type_die (struct die_info *, struct dwarf2_cu *);
+static struct type *read_type_die (struct die_info *, struct dwarf2_cu *);
static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
const char *suffix,
struct dwarf2_cu *);
-static void read_typedef (struct die_info *, struct dwarf2_cu *);
-
-static void read_base_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_subrange_type (struct die_info *die, struct dwarf2_cu *cu);
-
static void read_file_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 int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
+ struct dwarf2_cu *, struct partial_symtab *);
+
static int dwarf2_get_pc_bounds (struct die_info *,
CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *);
static void dwarf2_attach_fn_fields_to_type (struct field_info *,
struct type *, struct dwarf2_cu *);
-static void read_structure_type (struct die_info *, struct dwarf2_cu *);
-
static void process_structure_scope (struct die_info *, struct dwarf2_cu *);
static char *determine_class_name (struct die_info *die, struct dwarf2_cu *cu);
static const char *namespace_name (struct die_info *die,
int *is_anonymous, struct dwarf2_cu *);
-static void read_enumeration_type (struct die_info *, struct dwarf2_cu *);
-
static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *);
static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
-static void read_array_type (struct die_info *, struct dwarf2_cu *);
-
static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
struct dwarf2_cu *);
-static void read_tag_pointer_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_tag_ptr_to_member_type (struct die_info *,
- struct dwarf2_cu *);
-
-static void read_tag_reference_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_tag_const_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_tag_volatile_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_tag_string_type (struct die_info *, struct dwarf2_cu *);
-
-static void read_subroutine_type (struct die_info *, struct dwarf2_cu *);
-
static struct die_info *read_comp_unit (gdb_byte *, bfd *, struct dwarf2_cu *);
static struct die_info *read_die_and_children (gdb_byte *info_ptr, bfd *abfd,
static void free_one_cached_comp_unit (void *);
-static void set_die_type (struct die_info *, struct type *,
- struct dwarf2_cu *);
-
-static void reset_die_and_siblings_types (struct die_info *,
- struct dwarf2_cu *);
+static struct type *set_die_type (struct die_info *, struct type *,
+ struct dwarf2_cu *);
static void create_all_comp_units (struct objfile *);
static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
-static void read_set_type (struct die_info *, struct dwarf2_cu *);
-
+static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
/* Try to locate the sections we need for DWARF 2 debugging
information and return true if we have enough to do something. */
return (dwarf_info_section != NULL && dwarf_abbrev_section != NULL);
}
+/* When loading sections, we can either look for ".<name>", or for
+ * ".z<name>", which indicates a compressed section. */
+
+static int
+section_is_p (asection *sectp, const char *name)
+{
+ return ((sectp->name[0] == '.'
+ && strcmp (sectp->name + 1, name) == 0)
+ || (sectp->name[0] == '.' && sectp->name[1] == 'z'
+ && strcmp (sectp->name + 2, name) == 0));
+}
+
/* This function is mapped across the sections and remembers the
offset and size of each of the debugging sections we are interested
in. */
static void
dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
{
- if (strcmp (sectp->name, INFO_SECTION) == 0)
+ if (section_is_p (sectp, INFO_SECTION))
{
dwarf2_per_objfile->info_size = bfd_get_section_size (sectp);
dwarf_info_section = sectp;
}
- else if (strcmp (sectp->name, ABBREV_SECTION) == 0)
+ else if (section_is_p (sectp, ABBREV_SECTION))
{
dwarf2_per_objfile->abbrev_size = bfd_get_section_size (sectp);
dwarf_abbrev_section = sectp;
}
- else if (strcmp (sectp->name, LINE_SECTION) == 0)
+ else if (section_is_p (sectp, LINE_SECTION))
{
dwarf2_per_objfile->line_size = bfd_get_section_size (sectp);
dwarf_line_section = sectp;
}
- else if (strcmp (sectp->name, PUBNAMES_SECTION) == 0)
+ else if (section_is_p (sectp, PUBNAMES_SECTION))
{
dwarf2_per_objfile->pubnames_size = bfd_get_section_size (sectp);
dwarf_pubnames_section = sectp;
}
- else if (strcmp (sectp->name, ARANGES_SECTION) == 0)
+ else if (section_is_p (sectp, ARANGES_SECTION))
{
dwarf2_per_objfile->aranges_size = bfd_get_section_size (sectp);
dwarf_aranges_section = sectp;
}
- else if (strcmp (sectp->name, LOC_SECTION) == 0)
+ else if (section_is_p (sectp, LOC_SECTION))
{
dwarf2_per_objfile->loc_size = bfd_get_section_size (sectp);
dwarf_loc_section = sectp;
}
- else if (strcmp (sectp->name, MACINFO_SECTION) == 0)
+ else if (section_is_p (sectp, MACINFO_SECTION))
{
dwarf2_per_objfile->macinfo_size = bfd_get_section_size (sectp);
dwarf_macinfo_section = sectp;
}
- else if (strcmp (sectp->name, STR_SECTION) == 0)
+ else if (section_is_p (sectp, STR_SECTION))
{
dwarf2_per_objfile->str_size = bfd_get_section_size (sectp);
dwarf_str_section = sectp;
}
- else if (strcmp (sectp->name, FRAME_SECTION) == 0)
+ else if (section_is_p (sectp, FRAME_SECTION))
{
dwarf2_per_objfile->frame_size = bfd_get_section_size (sectp);
dwarf_frame_section = sectp;
}
- else if (strcmp (sectp->name, EH_FRAME_SECTION) == 0)
+ else if (section_is_p (sectp, EH_FRAME_SECTION))
{
flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
if (aflag & SEC_HAS_CONTENTS)
dwarf_eh_frame_section = sectp;
}
}
- else if (strcmp (sectp->name, RANGES_SECTION) == 0)
+ else if (section_is_p (sectp, RANGES_SECTION))
{
dwarf2_per_objfile->ranges_size = bfd_get_section_size (sectp);
dwarf_ranges_section = sectp;
dwarf2_per_objfile->has_section_at_zero = 1;
}
+/* This function is called after decompressing a section, so
+ dwarf2_per_objfile can record its new, uncompressed size. */
+
+static void
+dwarf2_resize_section (asection *sectp, bfd_size_type new_size)
+{
+ if (section_is_p (sectp, INFO_SECTION))
+ dwarf2_per_objfile->info_size = new_size;
+ else if (section_is_p (sectp, ABBREV_SECTION))
+ dwarf2_per_objfile->abbrev_size = new_size;
+ else if (section_is_p (sectp, LINE_SECTION))
+ dwarf2_per_objfile->line_size = new_size;
+ else if (section_is_p (sectp, PUBNAMES_SECTION))
+ dwarf2_per_objfile->pubnames_size = new_size;
+ else if (section_is_p (sectp, ARANGES_SECTION))
+ dwarf2_per_objfile->aranges_size = new_size;
+ else if (section_is_p (sectp, LOC_SECTION))
+ dwarf2_per_objfile->loc_size = new_size;
+ else if (section_is_p (sectp, MACINFO_SECTION))
+ dwarf2_per_objfile->macinfo_size = new_size;
+ else if (section_is_p (sectp, STR_SECTION))
+ dwarf2_per_objfile->str_size = new_size;
+ else if (section_is_p (sectp, FRAME_SECTION))
+ dwarf2_per_objfile->frame_size = new_size;
+ else if (section_is_p (sectp, EH_FRAME_SECTION))
+ dwarf2_per_objfile->eh_frame_size = new_size;
+ else if (section_is_p (sectp, RANGES_SECTION))
+ dwarf2_per_objfile->ranges_size = new_size;
+ else
+ internal_error (__FILE__, __LINE__,
+ _("dwarf2_resize_section: missing section_is_p check: %s"),
+ sectp->name);
+}
+
/* Build a partial symbol table. */
void
create_all_comp_units (objfile);
+ objfile->psymtabs_addrmap = addrmap_create_mutable
+ (&objfile->objfile_obstack);
+
/* 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
/* Allocate a new partial symbol table structure */
pst = start_psymtab_common (objfile, objfile->section_offsets,
comp_unit_die.name ? comp_unit_die.name : "",
- comp_unit_die.lowpc,
+ /* TEXTLOW and TEXTHIGH are set below. */
+ 0,
objfile->global_psymbols.next,
objfile->static_psymbols.next);
this_cu->psymtab = pst;
+ /* 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;
+ }
+
/* 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. */
pst->textlow = comp_unit_die.lowpc + baseaddr;
pst->texthigh = comp_unit_die.highpc + baseaddr;
+ /* Store the contiguous range; `DW_AT_ranges' range is stored above. The
+ range can be also empty for CUs with no code. */
+ if (!cu.has_ranges_offset && pst->textlow < pst->texthigh)
+ addrmap_set_empty (objfile->psymtabs_addrmap, pst->textlow,
+ pst->texthigh - 1, pst);
+
pst->n_global_syms = objfile->global_psymbols.next -
(objfile->global_psymbols.list + pst->globals_offset);
pst->n_static_syms = objfile->static_psymbols.next -
do_cleanups (back_to_inner);
}
+
+ objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
+ &objfile->objfile_obstack);
+
do_cleanups (back_to);
}
/* 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;
/* Check if comp unit has_children.
If so, read the rest of the partial symbols from this comp unit.
switch (pdi->tag)
{
case DW_TAG_subprogram:
- if (pdi->is_external)
+ if (pdi->is_external || cu->language == language_ada)
{
+ /* brobecker/2007-12-26: Normally, only "external" DIEs are part
+ of the global scope. But in Ada, we want to be able to access
+ nested procedures globally. So all Ada subprograms are stored
+ in the global scope. */
/*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
mst_text, objfile); */
psym = add_psymbol_to_list (actual_name, strlen (actual_name),
: &objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, objfile);
- if (cu->language == language_cplus
- || cu->language == language_java
- || cu->language == language_ada)
- {
- /* For C++ and Java, these implicitly act as typedefs as well. */
- add_psymbol_to_list (actual_name, strlen (actual_name),
- VAR_DOMAIN, LOC_TYPEDEF,
- &objfile->global_psymbols,
- 0, (CORE_ADDR) 0, cu->language, objfile);
- }
break;
case DW_TAG_enumerator:
add_psymbol_to_list (actual_name, strlen (actual_name),
item->per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
dwarf2_per_objfile->read_in_chain = item->per_cu;
-
- /* If this compilation unit has already had full symbols created,
- reset the TYPE fields in each DIE. */
- if (item->per_cu->type_hash)
- reset_die_and_siblings_types (item->per_cu->cu->dies,
- item->per_cu->cu);
}
/* Now everything left on the queue needs to be read in. Process
cu->per_cu = per_cu;
per_cu->cu = 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);
read_file_scope (die, cu);
break;
case DW_TAG_subprogram:
- read_subroutine_type (die, cu);
read_func_scope (die, cu);
break;
case DW_TAG_inlined_subroutine:
case DW_TAG_interface_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
- read_structure_type (die, cu);
process_structure_scope (die, cu);
break;
case DW_TAG_enumeration_type:
- read_enumeration_type (die, cu);
process_enumeration_scope (die, cu);
break;
- /* FIXME drow/2004-03-14: These initialize die->type, but do not create
- a symbol or process any children. Therefore it doesn't do anything
- that won't be done on-demand by read_type_die. */
+ /* These dies have a type, but processing them does not create
+ a symbol or recurse to process the children. Therefore we can
+ read them on-demand through read_type_die. */
case DW_TAG_subroutine_type:
- read_subroutine_type (die, cu);
- break;
case DW_TAG_set_type:
- read_set_type (die, cu);
- break;
case DW_TAG_array_type:
- read_array_type (die, cu);
- break;
case DW_TAG_pointer_type:
- read_tag_pointer_type (die, cu);
- break;
case DW_TAG_ptr_to_member_type:
- read_tag_ptr_to_member_type (die, cu);
- break;
case DW_TAG_reference_type:
- read_tag_reference_type (die, cu);
- break;
case DW_TAG_string_type:
- read_tag_string_type (die, cu);
break;
- /* END FIXME */
case DW_TAG_base_type:
- read_base_type (die, cu);
- /* Add a typedef symbol for the type definition, if it has a
- DW_AT_name. */
- new_symbol (die, die->type, cu);
- break;
case DW_TAG_subrange_type:
- read_subrange_type (die, cu);
/* Add a typedef symbol for the type definition, if it has a
DW_AT_name. */
- new_symbol (die, die->type, cu);
+ new_symbol (die, read_type_die (die, cu), cu);
break;
case DW_TAG_common_block:
read_common_block (die, cu);
add_to_cu_func_list (name, lowpc, highpc, cu);
new = push_context (0, lowpc);
- new->name = new_symbol (die, die->type, cu);
+ new->name = new_symbol (die, read_type_die (die, cu), cu);
/* If there is a location expression for DW_AT_frame_base, record
it. */
}
/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
- Return 1 if the attributes are present and valid, otherwise, return 0. */
+ Return 1 if the attributes are present and valid, otherwise, return 0.
+ If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'. */
static int
dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
- CORE_ADDR *high_return, struct dwarf2_cu *cu)
+ CORE_ADDR *high_return, struct dwarf2_cu *cu,
+ struct partial_symtab *ranges_pst)
{
struct objfile *objfile = cu->objfile;
struct comp_unit_head *cu_header = &cu->header;
int low_set;
CORE_ADDR low = 0;
CORE_ADDR high = 0;
+ CORE_ADDR baseaddr;
found_base = cu_header->base_known;
base = cu_header->base_address;
low_set = 0;
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
while (1)
{
CORE_ADDR range_beginning, range_end;
range_beginning += base;
range_end += base;
+ if (ranges_pst != NULL && range_beginning < range_end)
+ addrmap_set_empty (objfile->psymtabs_addrmap,
+ range_beginning + baseaddr, range_end - 1 + baseaddr,
+ ranges_pst);
+
/* FIXME: This is recording everything as a low-high
segment of consecutive addresses. We should have a
data structure for discontiguous block ranges
{
/* 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))
+ if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, NULL))
return 0;
/* Found discontinuous range of addresses. */
ret = -1;
struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct nextfield *new_field;
struct attribute *attr;
struct field *fp;
attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
if (attr)
{
- if (BITS_BIG_ENDIAN)
+ if (gdbarch_bits_big_endian (gdbarch))
{
/* For big endian bits, the DW_AT_bit_offset gives the
additional bit offset from the MSB of the containing
char *fieldname;
char *physname;
struct nextfnfield *new_fnfield;
+ struct type *this_type;
/* Get name of member function. */
fieldname = dwarf2_name (die, cu);
need to duplicate it for the type. */
fnp->physname = physname ? physname : "";
fnp->type = alloc_type (objfile);
- if (die->type && TYPE_CODE (die->type) == TYPE_CODE_FUNC)
+ this_type = read_type_die (die, cu);
+ if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
{
- int nparams = TYPE_NFIELDS (die->type);
+ int nparams = TYPE_NFIELDS (this_type);
- /* TYPE is the domain of this method, and DIE->TYPE is the type
+ /* TYPE is the domain of this method, and THIS_TYPE is the type
of the method itself (TYPE_CODE_METHOD). */
smash_to_method_type (fnp->type, type,
- TYPE_TARGET_TYPE (die->type),
- TYPE_FIELDS (die->type),
- TYPE_NFIELDS (die->type),
- TYPE_VARARGS (die->type));
+ TYPE_TARGET_TYPE (this_type),
+ TYPE_FIELDS (this_type),
+ TYPE_NFIELDS (this_type),
+ TYPE_VARARGS (this_type));
/* Handle static member functions.
Dwarf2 has no clean way to discern C++ static and non-static
parameter for non-static member functions (which is the
this pointer) as artificial. We obtain this information
from read_subroutine_type via TYPE_FIELD_ARTIFICIAL. */
- if (nparams == 0 || TYPE_FIELD_ARTIFICIAL (die->type, 0) == 0)
+ if (nparams == 0 || TYPE_FIELD_ARTIFICIAL (this_type, 0) == 0)
fnp->voffset = VOFFSET_STATIC;
}
else
GCC shouldn't do this; it should just output pointer to member DIEs.
This is GCC PR debug/28767. */
-static int
+static struct type *
quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
|| die->child->sibling == NULL
|| (die->child->sibling->sibling != NULL
&& die->child->sibling->sibling->tag != DW_TAG_padding))
- return 0;
+ return NULL;
/* Check for __pfn and __delta members. */
pfn_die = die->child;
|| pfn_name == NULL
|| DW_STRING (pfn_name) == NULL
|| strcmp ("__pfn", DW_STRING (pfn_name)) != 0)
- return 0;
+ return NULL;
delta_die = pfn_die->sibling;
delta_name = dwarf2_attr (delta_die, DW_AT_name, cu);
|| delta_name == NULL
|| DW_STRING (delta_name) == NULL
|| strcmp ("__delta", DW_STRING (delta_name)) != 0)
- return 0;
+ return NULL;
/* Find the type of the method. */
pfn_type = die_type (pfn_die, cu);
if (pfn_type == NULL
|| TYPE_CODE (pfn_type) != TYPE_CODE_PTR
|| TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC)
- return 0;
+ return NULL;
/* Look for the "this" argument. */
pfn_type = TYPE_TARGET_TYPE (pfn_type);
if (TYPE_NFIELDS (pfn_type) == 0
|| TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
- return 0;
+ return NULL;
domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
type = alloc_type (objfile);
TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
TYPE_VARARGS (pfn_type));
type = lookup_methodptr_type (type);
- set_die_type (die, type, cu);
-
- return 1;
+ return set_die_type (die, type, cu);
}
/* Called when we find the DIE that starts a structure or union scope
checking about whether the struct/union is anonymous or not (and
suppresses creating a symbol table entry itself). */
-static void
+static struct type *
read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct cleanup *back_to = NULL;
char *name;
- if (die->type)
- return;
-
- if (quirk_gcc_member_function_pointer (die, cu))
- return;
+ type = quirk_gcc_member_function_pointer (die, cu);
+ if (type)
+ return type;
type = alloc_type (objfile);
INIT_CPLUS_SPECIFIC (type);
else if (child_die->tag == DW_TAG_subprogram)
{
/* C++ member function. */
- read_type_die (child_die, cu);
dwarf2_add_member_fn (&fi, child_die, type, cu);
}
else if (child_die->tag == DW_TAG_inheritance)
processing_current_prefix = previous_prefix;
if (back_to != NULL)
do_cleanups (back_to);
+
+ return type;
}
static void
struct objfile *objfile = cu->objfile;
const char *previous_prefix = processing_current_prefix;
struct die_info *child_die = die->child;
+ struct type *this_type;
- if (TYPE_TAG_NAME (die->type) != NULL)
- processing_current_prefix = TYPE_TAG_NAME (die->type);
+ this_type = get_die_type (die, cu);
+ if (this_type == NULL)
+ this_type = read_structure_type (die, cu);
+ if (TYPE_TAG_NAME (this_type) != NULL)
+ processing_current_prefix = TYPE_TAG_NAME (this_type);
/* NOTE: carlton/2004-03-16: GCC 3.4 (or at least one of its
snapshots) has been known to create a die giving a declaration
attribute, and a declaration attribute. */
if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL
|| !die_is_declaration (die, cu))
- new_symbol (die, die->type, cu);
+ new_symbol (die, this_type, cu);
processing_current_prefix = previous_prefix;
}
/* Given a DW_AT_enumeration_type die, set its type. We do not
complete the type's fields yet, or create any symbols. */
-static void
+static struct type *
read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct attribute *attr;
char *name;
- if (die->type)
- return;
-
type = alloc_type (objfile);
TYPE_CODE (type) = TYPE_CODE_ENUM;
if (die_is_declaration (die, cu))
TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
- set_die_type (die, type, cu);
+ return set_die_type (die, type, cu);
}
/* Determine the name of the type represented by DIE, which should be
int num_fields;
int unsigned_enum = 1;
char *name;
+ struct type *this_type;
num_fields = 0;
fields = NULL;
+ this_type = get_die_type (die, cu);
+ if (this_type == NULL)
+ this_type = read_enumeration_type (die, cu);
if (die->child != NULL)
{
child_die = die->child;
name = dwarf2_name (child_die, cu);
if (name)
{
- sym = new_symbol (child_die, die->type, cu);
+ sym = new_symbol (child_die, this_type, cu);
if (SYMBOL_VALUE (sym) < 0)
unsigned_enum = 0;
if (num_fields)
{
- TYPE_NFIELDS (die->type) = num_fields;
- TYPE_FIELDS (die->type) = (struct field *)
- TYPE_ALLOC (die->type, sizeof (struct field) * num_fields);
- memcpy (TYPE_FIELDS (die->type), fields,
+ TYPE_NFIELDS (this_type) = num_fields;
+ TYPE_FIELDS (this_type) = (struct field *)
+ TYPE_ALLOC (this_type, sizeof (struct field) * num_fields);
+ memcpy (TYPE_FIELDS (this_type), fields,
sizeof (struct field) * num_fields);
xfree (fields);
}
if (unsigned_enum)
- TYPE_FLAGS (die->type) |= TYPE_FLAG_UNSIGNED;
+ TYPE_FLAGS (this_type) |= TYPE_FLAG_UNSIGNED;
}
- new_symbol (die, die->type, cu);
+ new_symbol (die, this_type, cu);
}
/* Extract all information from a DW_TAG_array_type DIE and put it in
the DIE's type field. For now, this only handles one dimensional
arrays. */
-static void
+static struct type *
read_array_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct cleanup *back_to;
char *name;
- /* Return if we've already decoded this type. */
- if (die->type)
- {
- return;
- }
-
element_type = die_type (die, cu);
/* Irix 6.2 native cc creates array types without children for
{
index_type = builtin_type_int32;
range_type = create_range_type (NULL, index_type, 0, -1);
- set_die_type (die, create_array_type (NULL, element_type, range_type),
- cu);
- return;
+ type = create_array_type (NULL, element_type, range_type);
+ return set_die_type (die, type, cu);
}
back_to = make_cleanup (null_cleanup, NULL);
{
if (child_die->tag == DW_TAG_subrange_type)
{
- read_subrange_type (child_die, cu);
-
- if (child_die->type != NULL)
+ struct type *child_type = read_type_die (child_die, cu);
+ if (child_type != NULL)
{
/* The range type was succesfully read. Save it for
the array type creation. */
if (ndim == 0)
make_cleanup (free_current_contents, &range_types);
}
- range_types[ndim++] = child_die->type;
+ range_types[ndim++] = child_type;
}
}
child_die = sibling_die (child_die);
do_cleanups (back_to);
/* Install the type in the die. */
- set_die_type (die, type, cu);
+ return set_die_type (die, type, cu);
}
static enum dwarf_array_dim_ordering
/* Extract all information from a DW_TAG_set_type DIE and put it in
the DIE's type field. */
-static void
+static struct type *
read_set_type (struct die_info *die, struct dwarf2_cu *cu)
{
- if (die->type == NULL)
- die->type = create_set_type ((struct type *) NULL, die_type (die, cu));
+ struct type *set_type = create_set_type (NULL, die_type (die, cu));
+
+ return set_die_type (die, set_type, cu);
}
/* First cut: install each common block member as a global variable. */
/* Extract all information from a DW_TAG_pointer_type DIE and add to
the user defined type vector. */
-static void
+static struct type *
read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
{
+ struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
struct comp_unit_head *cu_header = &cu->header;
struct type *type;
struct attribute *attr_byte_size;
struct attribute *attr_address_class;
int byte_size, addr_class;
- if (die->type)
- {
- return;
- }
-
type = lookup_pointer_type (die_type (die, cu));
attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu);
length accordingly. */
if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none)
{
- if (gdbarch_address_class_type_flags_p (current_gdbarch))
+ if (gdbarch_address_class_type_flags_p (gdbarch))
{
int type_flags;
type_flags = gdbarch_address_class_type_flags
- (current_gdbarch, byte_size, addr_class);
+ (gdbarch, byte_size, addr_class);
gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0);
type = make_type_with_address_space (type, type_flags);
}
}
TYPE_LENGTH (type) = byte_size;
- set_die_type (die, type, cu);
+ return set_die_type (die, type, cu);
}
/* Extract all information from a DW_TAG_ptr_to_member_type DIE and add to
the user defined type vector. */
-static void
+static struct type *
read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct type *to_type;
struct type *domain;
- if (die->type)
- {
- return;
- }
-
to_type = die_type (die, cu);
domain = die_containing_type (die, cu);
else
type = lookup_memberptr_type (to_type, domain);
- set_die_type (die, type, cu);
+ return set_die_type (die, type, cu);
}
/* Extract all information from a DW_TAG_reference_type DIE and add to
the user defined type vector. */
-static void
+static struct type *
read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct comp_unit_head *cu_header = &cu->header;
struct type *type;
struct attribute *attr;
- if (die->type)
- {
- return;
- }
-
type = lookup_reference_type (die_type (die, cu));
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
TYPE_LENGTH (type) = cu_header->addr_size;
}
- set_die_type (die, type, cu);
+ return set_die_type (die, type, cu);
}
-static void
+static struct type *
read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct type *base_type;
-
- if (die->type)
- {
- return;
- }
+ struct type *base_type, *cv_type;
base_type = die_type (die, cu);
- set_die_type (die, make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0),
- cu);
+ cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
+ return set_die_type (die, cv_type, cu);
}
-static void
+static struct type *
read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct type *base_type;
-
- if (die->type)
- {
- return;
- }
+ struct type *base_type, *cv_type;
base_type = die_type (die, cu);
- set_die_type (die, make_cv_type (TYPE_CONST (base_type), 1, base_type, 0),
- cu);
+ cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
+ return set_die_type (die, cv_type, cu);
}
/* Extract all information from a DW_TAG_string_type DIE and add to
but it behaves like one, with other DIE's using an AT_user_def_type
attribute to reference it. */
-static void
+static struct type *
read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct attribute *attr;
unsigned int length;
- if (die->type)
- {
- return;
- }
-
attr = dwarf2_attr (die, DW_AT_string_length, cu);
if (attr)
{
range_type = create_range_type (NULL, index_type, 1, length);
type = create_string_type (NULL, range_type);
- set_die_type (die, type, cu);
+ return set_die_type (die, type, cu);
}
/* Handle DIES due to C code like:
('funcp' generates a DW_TAG_subroutine_type DIE)
*/
-static void
+static struct type *
read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct type *type; /* Type that this function returns */
struct type *ftype; /* Function that returns above type */
struct attribute *attr;
- /* Decode the type that this subroutine returns */
- if (die->type)
- {
- return;
- }
type = die_type (die, cu);
ftype = make_function_type (type, (struct type **) 0);
|| cu->language == language_pascal)
TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
+ /* 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;
+
if (die->child != NULL)
{
struct die_info *child_die;
}
}
- set_die_type (die, ftype, cu);
+ return set_die_type (die, ftype, cu);
}
-static void
+static struct type *
read_typedef (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct attribute *attr;
char *name = NULL;
+ struct type *this_type;
- if (!die->type)
- {
- name = dwarf2_name (die, cu);
- set_die_type (die, init_type (TYPE_CODE_TYPEDEF, 0,
- TYPE_FLAG_TARGET_STUB, name, objfile),
- cu);
- TYPE_TARGET_TYPE (die->type) = die_type (die, cu);
- }
+ name = dwarf2_name (die, cu);
+ this_type = init_type (TYPE_CODE_TYPEDEF, 0,
+ TYPE_FLAG_TARGET_STUB, name, objfile);
+ set_die_type (die, this_type, cu);
+ TYPE_TARGET_TYPE (this_type) = die_type (die, cu);
+ return this_type;
}
/* Find a representation of a given base type and install
it in the TYPE field of the die. */
-static void
+static struct type *
read_base_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
int type_flags = 0;
struct type *target_type = NULL;
- /* If we've already decoded this die, this is a no-op. */
- if (die->type)
- {
- return;
- }
-
attr = dwarf2_attr (die, DW_AT_encoding, cu);
if (attr)
{
type = init_type (code, size, type_flags, name, objfile);
TYPE_TARGET_TYPE (type) = target_type;
- set_die_type (die, type, cu);
+ return set_die_type (die, type, cu);
}
/* Read the given DW_AT_subrange DIE. */
-static void
+static struct type *
read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
{
+ struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
struct type *base_type;
struct type *range_type;
struct attribute *attr;
int high = -1;
char *name;
- /* If we have already decoded this die, then nothing more to do. */
- if (die->type)
- return;
-
base_type = die_type (die, cu);
if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
{
complaint (&symfile_complaints,
_("DW_AT_type missing from DW_TAG_subrange_type"));
base_type
- = init_type (TYPE_CODE_INT, gdbarch_addr_bit (current_gdbarch) / 8,
+ = init_type (TYPE_CODE_INT, gdbarch_addr_bit (gdbarch) / 8,
0, NULL, cu->objfile);
}
if (attr)
TYPE_LENGTH (range_type) = DW_UNSND (attr);
- set_die_type (die, range_type, cu);
+ return set_die_type (die, range_type, cu);
}
-static void
+static struct type *
read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct type *type;
- if (die->type)
- return;
-
/* For now, we only support the C meaning of an unspecified type: void. */
type = init_type (TYPE_CODE_VOID, 0, 0, dwarf2_name (die, cu),
cu->objfile);
- set_die_type (die, type, cu);
+ return set_die_type (die, type, cu);
}
/* Read a whole compilation unit into a linked list of dies. */
}
}
+/* Decompress a section that was compressed using zlib. Store the
+ decompressed buffer, and its size, in OUTBUF and OUTSIZE. */
+
+static void
+zlib_decompress_section (struct objfile *objfile, asection *sectp,
+ gdb_byte **outbuf, bfd_size_type *outsize)
+{
+ bfd *abfd = objfile->obfd;
+#ifndef HAVE_ZLIB_H
+ error (_("Support for zlib-compressed DWARF data (from '%s') "
+ "is disabled in this copy of GDB"),
+ bfd_get_filename (abfd));
+#else
+ bfd_size_type compressed_size = bfd_get_section_size (sectp);
+ gdb_byte *compressed_buffer = xmalloc (compressed_size);
+ bfd_size_type uncompressed_size;
+ gdb_byte *uncompressed_buffer;
+ z_stream strm;
+ int rc;
+ int header_size = 12;
+
+ if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
+ || bfd_bread (compressed_buffer, compressed_size, abfd) != compressed_size)
+ error (_("Dwarf Error: Can't read DWARF data from '%s'"),
+ bfd_get_filename (abfd));
+
+ /* Read the zlib header. In this case, it should be "ZLIB" followed
+ by the uncompressed section size, 8 bytes in big-endian order. */
+ if (compressed_size < header_size
+ || strncmp (compressed_buffer, "ZLIB", 4) != 0)
+ error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"),
+ bfd_get_filename (abfd));
+ uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
+ uncompressed_size += compressed_buffer[11];
+
+ /* It is possible the section consists of several compressed
+ buffers concatenated together, so we uncompress in a loop. */
+ strm.zalloc = NULL;
+ strm.zfree = NULL;
+ strm.opaque = NULL;
+ strm.avail_in = compressed_size - header_size;
+ strm.next_in = (Bytef*) compressed_buffer + header_size;
+ strm.avail_out = uncompressed_size;
+ uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack,
+ uncompressed_size);
+ rc = inflateInit (&strm);
+ while (strm.avail_in > 0)
+ {
+ if (rc != Z_OK)
+ error (_("Dwarf Error: setting up DWARF uncompression in '%s': %d"),
+ bfd_get_filename (abfd), rc);
+ strm.next_out = ((Bytef*) uncompressed_buffer
+ + (uncompressed_size - strm.avail_out));
+ rc = inflate (&strm, Z_FINISH);
+ if (rc != Z_STREAM_END)
+ error (_("Dwarf Error: zlib error uncompressing from '%s': %d"),
+ bfd_get_filename (abfd), rc);
+ rc = inflateReset (&strm);
+ }
+ rc = inflateEnd (&strm);
+ if (rc != Z_OK
+ || strm.avail_out != 0)
+ error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
+ bfd_get_filename (abfd), rc);
+
+ xfree (compressed_buffer);
+ *outbuf = uncompressed_buffer;
+ *outsize = uncompressed_size;
+#endif
+}
+
+
/* Read the contents of the section at OFFSET and of size SIZE from the
- object file specified by OBJFILE into the objfile_obstack and return it. */
+ object file specified by OBJFILE into the objfile_obstack and return it.
+ If the section is compressed, uncompress it before returning. */
gdb_byte *
dwarf2_read_section (struct objfile *objfile, asection *sectp)
bfd *abfd = objfile->obfd;
gdb_byte *buf, *retbuf;
bfd_size_type size = bfd_get_section_size (sectp);
+ unsigned char header[4];
if (size == 0)
return NULL;
+ /* Check if the file has a 4-byte header indicating compression. */
+ if (size > sizeof (header)
+ && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
+ && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
+ {
+ /* Upon decompression, update the buffer and its size. */
+ if (strncmp (header, "ZLIB", sizeof (header)) == 0)
+ {
+ zlib_decompress_section (objfile, sectp, &buf, &size);
+ dwarf2_resize_section (sectp, size);
+ return buf;
+ }
+ }
+
+ /* If we get here, we are a normal, not-compressed section. */
buf = obstack_alloc (&objfile->objfile_obstack, size);
+ /* When debugging .o files, we may need to apply relocations; see
+ 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);
if (retbuf != NULL)
return retbuf;
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));
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 (dwarf2_ranges_read (DW_UNSND (&attr), &part_die->lowpc,
- &part_die->highpc, cu))
- has_low_pc_attr = has_high_pc_attr = 1;
+ 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 */
&& (part_die->lowpc != 0
|| dwarf2_per_objfile->has_section_at_zero))
part_die->has_pc_info = 1;
+
+ if (base_address_type != base_address_none && !cu->header.base_known)
+ {
+ gdb_assert (part_die->tag == DW_TAG_compile_unit);
+ cu->header.base_known = 1;
+ cu->header.base_address = base_address;
+ }
+
return info_ptr;
}
die = dwarf_alloc_die ();
die->tag = 0;
die->abbrev = abbrev_number;
- die->type = NULL;
*diep = die;
*has_children = 0;
return info_ptr;
die->offset = offset;
die->tag = abbrev->tag;
die->abbrev = abbrev_number;
- die->type = NULL;
die->num_attrs = abbrev->num_attrs;
die->attrs = (struct attribute *)
case DW_LANG_Pascal83:
cu->language = language_pascal;
break;
+ case DW_LANG_ObjC:
+ cu->language = language_objc;
+ break;
case DW_LANG_Cobol74:
case DW_LANG_Cobol85:
default:
SYMBOL_VALUE_ADDRESS (sym) =
read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy);
+ SYMBOL_CLASS (sym) = LOC_STATIC;
fixup_symbol_section (sym, objfile);
SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
SYMBOL_SECTION (sym));
- SYMBOL_CLASS (sym) = LOC_STATIC;
return;
}
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;
finish_block. */
SYMBOL_CLASS (sym) = LOC_BLOCK;
attr2 = dwarf2_attr (die, DW_AT_external, cu);
- if (attr2 && (DW_UNSND (attr2) != 0))
+ if ((attr2 && (DW_UNSND (attr2) != 0))
+ || cu->language == language_ada)
{
+ /* Subprograms marked external are stored as a global symbol.
+ Ada subprograms, whether marked external or not, are always
+ stored as a global symbol, because we want to be able to
+ access them globally. For instance, we want to be able
+ to break on a nested subprogram without having to
+ specify the context. */
add_symbol_to_list (sym, &global_symbols);
}
else
to something sensible. */
if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
SYMBOL_TYPE (sym)
- = builtin_type (current_gdbarch)->nodebug_data_symbol;
+ = builtin_type (gdbarch)->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;
attr = dwarf2_attr (die, DW_AT_location, cu);
if (attr)
{
var_decode_location (attr, sym, cu);
- /* FIXME drow/2003-07-31: Is LOC_COMPUTED_ARG necessary? */
- if (SYMBOL_CLASS (sym) == LOC_COMPUTED)
- SYMBOL_CLASS (sym) = LOC_COMPUTED_ARG;
}
attr = dwarf2_attr (die, DW_AT_const_value, cu);
if (attr)
/* The semantics of C++ state that "struct foo { ... }" also
defines a typedef for "foo". A Java class declaration also
- defines a typedef for the class. Synthesize a typedef symbol
- so that "ptype foo" works as expected. */
+ defines a typedef for the class. */
if (cu->language == language_cplus
|| cu->language == language_java
|| cu->language == language_ada)
{
- struct symbol *typedef_sym = (struct symbol *)
- obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct symbol));
- *typedef_sym = *sym;
- SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN;
/* The symbol's name is already allocated along with
this objfile, so we don't need to duplicate it for
the type. */
if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_SEARCH_NAME (sym);
- add_symbol_to_list (typedef_sym, list_to_add);
}
}
break;
DW_ADDR (attr));
SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
break;
+ case DW_FORM_strp:
+ /* DW_STRING is already allocated on the obstack, point directly
+ to it. */
+ SYMBOL_VALUE_BYTES (sym) = (gdb_byte *) DW_STRING (attr);
+ SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+ break;
case DW_FORM_block1:
case DW_FORM_block2:
case DW_FORM_block4:
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 (current_gdbarch)->builtin_void;
+ return builtin_type (gdbarch)->builtin_void;
}
else
type_die = follow_die_ref (die, type_attr, cu);
static struct type *
tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu)
{
- if (die->type)
- {
- return die->type;
- }
- else
+ struct type *this_type;
+
+ this_type = read_type_die (die, cu);
+ if (!this_type)
{
- read_type_die (die, cu);
- if (!die->type)
- {
- dump_die (die);
- error (_("Dwarf Error: Cannot find type of die [in module %s]"),
- cu->objfile->name);
- }
- return die->type;
+ dump_die (die);
+ error (_("Dwarf Error: Cannot find type of die [in module %s]"),
+ cu->objfile->name);
}
+ return this_type;
}
-static void
+static struct type *
read_type_die (struct die_info *die, struct dwarf2_cu *cu)
{
- char *prefix = determine_prefix (die, cu);
- const char *old_prefix = processing_current_prefix;
- struct cleanup *back_to = make_cleanup (xfree, prefix);
+ char *prefix;
+ const char *old_prefix;
+ struct cleanup *back_to;
+ struct type *this_type;
+
+ this_type = get_die_type (die, cu);
+ if (this_type)
+ return this_type;
+
+ prefix = determine_prefix (die, cu);
+ old_prefix = processing_current_prefix;
+ back_to = make_cleanup (xfree, prefix);
processing_current_prefix = prefix;
-
+
switch (die->tag)
{
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
- read_structure_type (die, cu);
+ this_type = read_structure_type (die, cu);
break;
case DW_TAG_enumeration_type:
- read_enumeration_type (die, cu);
+ this_type = read_enumeration_type (die, cu);
break;
case DW_TAG_subprogram:
case DW_TAG_subroutine_type:
- read_subroutine_type (die, cu);
+ this_type = read_subroutine_type (die, cu);
break;
case DW_TAG_array_type:
- read_array_type (die, cu);
+ this_type = read_array_type (die, cu);
break;
case DW_TAG_set_type:
- read_set_type (die, cu);
+ this_type = read_set_type (die, cu);
break;
case DW_TAG_pointer_type:
- read_tag_pointer_type (die, cu);
+ this_type = read_tag_pointer_type (die, cu);
break;
case DW_TAG_ptr_to_member_type:
- read_tag_ptr_to_member_type (die, cu);
+ this_type = read_tag_ptr_to_member_type (die, cu);
break;
case DW_TAG_reference_type:
- read_tag_reference_type (die, cu);
+ this_type = read_tag_reference_type (die, cu);
break;
case DW_TAG_const_type:
- read_tag_const_type (die, cu);
+ this_type = read_tag_const_type (die, cu);
break;
case DW_TAG_volatile_type:
- read_tag_volatile_type (die, cu);
+ this_type = read_tag_volatile_type (die, cu);
break;
case DW_TAG_string_type:
- read_tag_string_type (die, cu);
+ this_type = read_tag_string_type (die, cu);
break;
case DW_TAG_typedef:
- read_typedef (die, cu);
+ this_type = read_typedef (die, cu);
break;
case DW_TAG_subrange_type:
- read_subrange_type (die, cu);
+ this_type = read_subrange_type (die, cu);
break;
case DW_TAG_base_type:
- read_base_type (die, cu);
+ this_type = read_base_type (die, cu);
break;
case DW_TAG_unspecified_type:
- read_unspecified_type (die, cu);
+ this_type = read_unspecified_type (die, cu);
break;
default:
complaint (&symfile_complaints, _("unexpected tag in read_type_die: '%s'"),
processing_current_prefix = old_prefix;
do_cleanups (back_to);
+ return this_type;
}
/* Return the name of the namespace/class that DIE is defined within,
{
/* FIXME: carlton/2004-03-05: Should I follow extension dies
before doing this check? */
- if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
+ struct type *parent_type = get_die_type (parent, cu);
+ if (parent_type != NULL && TYPE_TAG_NAME (parent_type) != NULL)
{
- return xstrdup (TYPE_TAG_NAME (parent->type));
+ return xstrdup (TYPE_TAG_NAME (parent_type));
}
else
{
case DW_TAG_interface_type:
case DW_TAG_structure_type:
{
- if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
+ struct type *parent_type = get_die_type (parent, cu);
+ if (parent_type != NULL && TYPE_TAG_NAME (parent_type) != NULL)
{
- return xstrdup (TYPE_TAG_NAME (parent->type));
+ return xstrdup (TYPE_TAG_NAME (parent_type));
}
else
{
new_die->has_children = old_die->has_children;
new_die->abbrev = old_die->abbrev;
new_die->offset = old_die->offset;
- new_die->type = NULL;
num_attrs = old_die->num_attrs;
new_die->num_attrs = num_attrs;
dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
-
- /* Save the master objfile, so that we can report and look up the
- correct file containing this variable. */
- if (objfile->separate_debug_objfile_backlink)
- objfile = objfile->separate_debug_objfile_backlink;
-
if (attr_form_is_section_offset (attr)
/* ".debug_loc" may not exist at all, or the offset may be outside
the section. If so, fall through to the complaint in the
baton = obstack_alloc (&cu->objfile->objfile_obstack,
sizeof (struct dwarf2_loclist_baton));
- baton->objfile = objfile;
+ baton->per_cu = cu->per_cu;
+ gdb_assert (baton->per_cu);
/* We don't know how long the location list is, but make sure we
don't run off the edge of the section. */
baton = obstack_alloc (&cu->objfile->objfile_obstack,
sizeof (struct dwarf2_locexpr_baton));
- baton->objfile = objfile;
+ baton->per_cu = cu->per_cu;
+ gdb_assert (baton->per_cu);
if (attr_form_is_block (attr))
{
}
}
+/* Return the OBJFILE associated with the compilation unit CU. */
+
+struct objfile *
+dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *per_cu)
+{
+ struct objfile *objfile = per_cu->psymtab->objfile;
+
+ /* Return the master objfile, so that we can report and look up the
+ correct file containing this variable. */
+ if (objfile->separate_debug_objfile_backlink)
+ objfile = objfile->separate_debug_objfile_backlink;
+
+ return objfile;
+}
+
+/* Return the address size given in the compilation unit header for CU. */
+
+CORE_ADDR
+dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
+{
+ if (per_cu->cu)
+ return per_cu->cu->header.addr_size;
+ else
+ {
+ /* If the CU is not currently read in, we re-read its header. */
+ struct objfile *objfile = per_cu->psymtab->objfile;
+ 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. */
}
/* Set the type associated with DIE to TYPE. Save it in CU's hash
- table if necessary. */
+ table if necessary. For convenience, return TYPE. */
-static void
+static struct type *
set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
{
struct dwarf2_offset_and_type **slot, ofs;
- die->type = type;
-
- if (cu->per_cu == NULL)
- return;
-
- if (cu->per_cu->type_hash == NULL)
- cu->per_cu->type_hash
- = htab_create_alloc_ex (cu->header.length / 24,
- offset_and_type_hash,
- offset_and_type_eq,
- NULL,
- &cu->objfile->objfile_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
+ if (cu->type_hash == NULL)
+ {
+ gdb_assert (cu->per_cu != NULL);
+ cu->per_cu->type_hash
+ = htab_create_alloc_ex (cu->header.length / 24,
+ offset_and_type_hash,
+ offset_and_type_eq,
+ NULL,
+ &cu->objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+ cu->type_hash = cu->per_cu->type_hash;
+ }
ofs.offset = die->offset;
ofs.type = type;
slot = (struct dwarf2_offset_and_type **)
- htab_find_slot_with_hash (cu->per_cu->type_hash, &ofs, ofs.offset, INSERT);
+ htab_find_slot_with_hash (cu->type_hash, &ofs, ofs.offset, INSERT);
*slot = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (**slot));
**slot = ofs;
+ return type;
}
-/* Find the type for DIE in TYPE_HASH, or return NULL if DIE does not
- have a saved type. */
+/* Find the type for DIE in CU's type_hash, or return NULL if DIE does
+ not have a saved type. */
static struct type *
-get_die_type (struct die_info *die, htab_t type_hash)
+get_die_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct dwarf2_offset_and_type *slot, ofs;
+ htab_t type_hash = cu->type_hash;
+
+ if (type_hash == NULL)
+ return NULL;
ofs.offset = die->offset;
slot = htab_find_with_hash (type_hash, &ofs, ofs.offset);
return NULL;
}
-/* Restore the types of the DIE tree starting at START_DIE from the hash
- table saved in CU. */
-
-static void
-reset_die_and_siblings_types (struct die_info *start_die, struct dwarf2_cu *cu)
-{
- struct die_info *die;
-
- if (cu->per_cu->type_hash == NULL)
- return;
-
- for (die = start_die; die != NULL; die = die->sibling)
- {
- die->type = get_die_type (die, cu->per_cu->type_hash);
- if (die->child != NULL)
- reset_die_and_siblings_types (die->child, cu);
- }
-}
-
/* Set the mark field in CU and in every other compilation unit in the
cache that we must keep because we are keeping CU. */