#include "bfd.h"
#include "symtab.h"
#include "gdbtypes.h"
-#include "symfile.h"
#include "objfiles.h"
#include "elf/dwarf2.h"
#include "buildsym.h"
#include "gdb_assert.h"
#include <sys/types.h>
+/* A note on memory usage for this file.
+
+ At the present time, this code reads the debug info sections into
+ the objfile's objfile_obstack. A definite improvement for startup
+ time, on platforms which do not emit relocations for debug
+ sections, would be to use mmap instead. The object's complete
+ debug information is loaded into memory, partly to simplify
+ absolute DIE references.
+
+ Whether using obstacks or mmap, the sections should remain loaded
+ until the objfile is released, and pointers into the section data
+ can be used for any other data associated to the objfile (symbol
+ names, type names, location expressions to name a few). */
+
#ifndef DWARF2_REG_TO_REGNUM
#define DWARF2_REG_TO_REGNUM(REG) (REG)
#endif
struct comp_unit_head *next;
- /* DWARF abbreviation table associated with this compilation unit */
-
- struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
-
/* Base address of this compilation unit. */
CORE_ADDR base_address;
/* The header of the compilation unit.
FIXME drow/2003-11-10: Some of the things from the comp_unit_head
- should be moved to the dwarf2_cu structure; for instance the abbrevs
- hash table. */
+ should logically be moved to the dwarf2_cu structure. */
struct comp_unit_head header;
+
+ struct function_range *first_fn, *last_fn, *cached_fn;
+
+ /* The language we are debugging. */
+ enum language language;
+ const struct language_defn *language_defn;
+
+ /* The generic symbol table building routines have separate lists for
+ file scope symbols and all all other scopes (local scopes). So
+ we need to select the right one to pass to add_symbol_to_list().
+ We do it by keeping a pointer to the correct list in list_in_scope.
+
+ FIXME: The original dwarf code just treated the file scope as the
+ first local scope, and all other local scopes as nested local
+ scopes, and worked fine. Check to see if we really need to
+ distinguish these in buildsym.c. */
+ struct pending **list_in_scope;
+
+ /* Maintain an array of referenced fundamental types for the current
+ compilation unit being read. For DWARF version 1, we have to construct
+ the fundamental types on the fly, since no information about the
+ fundamental types is supplied. Each such fundamental type is created by
+ calling a language dependent routine to create the type, and then a
+ pointer to that type is then placed in the array at the index specified
+ by it's FT_<TYPENAME> value. The array has a fixed size set by the
+ FT_NUM_MEMBERS compile time constant, which is the number of predefined
+ fundamental types gdb knows how to construct. */
+ struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */
+
+ /* DWARF abbreviation table associated with this compilation unit. */
+ struct abbrev_info **dwarf2_abbrevs;
+
+ /* Storage for the abbrev table. */
+ struct obstack abbrev_obstack;
};
/* The line number information for a compilation unit (found in the
{
unsigned int number; /* number identifying abbrev */
enum dwarf_tag tag; /* dwarf tag */
- int has_children; /* boolean */
- unsigned int num_attrs; /* number of attributes */
+ unsigned short has_children; /* boolean */
+ unsigned short num_attrs; /* number of attributes */
struct attr_abbrev *attrs; /* an array of attribute descriptions */
struct abbrev_info *next; /* next in chain */
};
struct function_range *next;
};
-static struct function_range *cu_first_fn, *cu_last_fn, *cu_cached_fn;
-
/* Get at parts of an attribute structure */
#define DW_STRING(attr) ((attr)->u.str)
/* Obstack for allocating temporary storage used during symbol reading. */
static struct obstack dwarf2_tmp_obstack;
-/* Offset to the first byte of the current compilation unit header,
- for resolving relative reference dies. */
-static unsigned int cu_header_offset;
-
/* Allocate fields for structs, unions and enums in this size. */
#ifndef DW_FIELD_ALLOC_CHUNK
#define DW_FIELD_ALLOC_CHUNK 4
#endif
-/* The language we are debugging. */
-static enum language cu_language;
-static const struct language_defn *cu_language_defn;
-
/* Actually data from the sections. */
static char *dwarf_info_buffer;
static char *dwarf_abbrev_buffer;
/* A zeroed version of a partial die for initialization purposes. */
static struct partial_die_info zeroed_partial_die;
-/* The generic symbol table building routines have separate lists for
- file scope symbols and all all other scopes (local scopes). So
- we need to select the right one to pass to add_symbol_to_list().
- We do it by keeping a pointer to the correct list in list_in_scope.
-
- FIXME: The original dwarf code just treated the file scope as the first
- local scope, and all other local scopes as nested local scopes, and worked
- fine. Check to see if we really need to distinguish these
- in buildsym.c. */
-static struct pending **list_in_scope = &file_symbols;
-
/* FIXME: decode_locdesc sets these variables to describe the location
to the caller. These ought to be a structure or something. If
none of the flags are set, the object lives at the address returned
decode_locdesc's return value is
the register number. */
-/* This value is added to each symbol value. FIXME: Generalize to
- the section_offsets structure used by dbxread (once this is done,
- pass the appropriate section number to end_symtab). */
-static CORE_ADDR baseaddr; /* Add to each symbol value */
-
/* We put a pointer to this structure in the read_symtab_private field
of the psymtab.
- The complete dwarf information for an objfile is kept in the
- psymbol_obstack, so that absolute die references can be handled.
+
Most of the information in this structure is related to an entire
- object file and could be passed via the sym_private field of the objfile.
- It is however conceivable that dwarf2 might not be the only type
- of symbols read from an object file. */
+ object file and could be passed via the sym_private field of the
+ objfile. It is possible to have both dwarf2 and some other form
+ of debug symbols in one object file. */
struct dwarf2_pinfo
{
#define DWARF_LOC_BUFFER(p) (PST_PRIVATE(p)->dwarf_loc_buffer)
#define DWARF_LOC_SIZE(p) (PST_PRIVATE(p)->dwarf_loc_size)
-/* Maintain an array of referenced fundamental types for the current
- compilation unit being read. For DWARF version 1, we have to construct
- the fundamental types on the fly, since no information about the
- fundamental types is supplied. Each such fundamental type is created by
- calling a language dependent routine to create the type, and then a
- pointer to that type is then placed in the array at the index specified
- by it's FT_<TYPENAME> value. The array has a fixed size set by the
- FT_NUM_MEMBERS compile time constant, which is the number of predefined
- fundamental types gdb knows how to construct. */
-static struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */
-
/* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
but this would require a corresponding change in unpack_field_as_long
and friends. */
static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
-static void dwarf2_empty_abbrev_table (void *);
+static void dwarf2_free_abbrev_table (void *);
static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
struct dwarf2_cu *);
static long read_signed_leb128 (bfd *, char *, unsigned int *);
-static void set_cu_language (unsigned int);
+static char *skip_leb128 (bfd *, char *);
-static struct attribute *dwarf_attr (struct die_info *, unsigned int);
+static void set_cu_language (unsigned int, struct dwarf2_cu *);
-static int die_is_declaration (struct die_info *);
+static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
+ struct dwarf2_cu *);
-static struct die_info *die_specification (struct die_info *die);
+static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu);
+
+static struct die_info *die_specification (struct die_info *die,
+ struct dwarf2_cu *);
static void free_line_header (struct line_header *lh);
static void read_type_die (struct die_info *, struct dwarf2_cu *);
-static char *determine_prefix (struct die_info *die);
+static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
static char *typename_concat (const char *prefix, const char *suffix);
-static char *class_name (struct die_info *die);
-
static void read_typedef (struct die_info *, struct dwarf2_cu *);
static void read_base_type (struct die_info *, struct dwarf2_cu *);
static void dwarf2_attach_fn_fields_to_type (struct field_info *,
struct type *, struct dwarf2_cu *);
-static void read_structure_scope (struct die_info *, 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 void read_common_block (struct die_info *, struct dwarf2_cu *);
static void read_namespace (struct die_info *die, struct dwarf2_cu *);
static const char *namespace_name (struct die_info *die,
- int *is_anonymous);
+ int *is_anonymous, struct dwarf2_cu *);
-static void read_enumeration (struct die_info *, 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 struct type *dwarf_base_type (int, int, struct dwarf2_cu *);
static void process_die (struct die_info *, struct dwarf2_cu *);
-static char *dwarf2_linkage_name (struct die_info *);
+static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
-static char *dwarf2_name (struct die_info *die);
+static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
-static struct die_info *dwarf2_extension (struct die_info *die);
+static struct die_info *dwarf2_extension (struct die_info *die,
+ struct dwarf2_cu *);
static char *dwarf_tag_name (unsigned int);
static void dwarf2_empty_hash_tables (void);
-static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+static unsigned int dwarf2_get_ref_die_offset (struct attribute *,
+ struct dwarf2_cu *);
static int dwarf2_get_attr_constant_value (struct attribute *, int);
static struct die_info *follow_die_ref (unsigned int);
-static struct type *dwarf2_fundamental_type (struct objfile *, int);
+static struct type *dwarf2_fundamental_type (struct objfile *, int,
+ struct dwarf2_cu *);
/* memory allocation interface */
static struct dwarf_block *dwarf_alloc_block (void);
-static struct abbrev_info *dwarf_alloc_abbrev (void);
+static struct abbrev_info *dwarf_alloc_abbrev (struct dwarf2_cu *);
static struct die_info *dwarf_alloc_die (void);
-static void initialize_cu_func_list (void);
+static void initialize_cu_func_list (struct dwarf2_cu *);
-static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
+static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR,
+ struct dwarf2_cu *);
static void dwarf_decode_macros (struct line_header *, unsigned int,
char *, bfd *, struct dwarf2_cu *);
dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu);
+static char *skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
+ 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. */
struct partial_die_info comp_unit_die;
struct partial_symtab *pst;
struct cleanup *back_to;
- CORE_ADDR lowpc, highpc;
+ CORE_ADDR lowpc, highpc, baseaddr;
info_ptr = dwarf_info_buffer;
abbrev_ptr = dwarf_abbrev_buffer;
left at all should be sufficient. */
while (info_ptr < dwarf_info_buffer + dwarf_info_size)
{
+ struct cleanup *back_to_inner;
struct dwarf2_cu cu;
beg_of_comp_unit = info_ptr;
cu.header.first_die_ptr = info_ptr;
cu.header.cu_head_ptr = beg_of_comp_unit;
+ cu.list_in_scope = &file_symbols;
+
/* Read the abbrevs for this compilation unit into a table */
dwarf2_read_abbrevs (abfd, &cu);
- make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
+ back_to_inner = make_cleanup (dwarf2_free_abbrev_table, &cu);
/* Read the compilation unit die */
info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr,
&cu);
/* Set the language we're debugging */
- set_cu_language (comp_unit_die.language);
+ set_cu_language (comp_unit_die.language, &cu);
/* Allocate a new partial symbol table structure */
pst = start_psymtab_common (objfile, objfile->section_offsets,
objfile->static_psymbols.next);
pst->read_symtab_private = (char *)
- obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
- cu_header_offset = beg_of_comp_unit - dwarf_info_buffer;
+ obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo));
DWARF_INFO_BUFFER (pst) = dwarf_info_buffer;
DWARF_INFO_OFFSET (pst) = beg_of_comp_unit - dwarf_info_buffer;
DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
info_ptr = beg_of_comp_unit + cu.header.length
+ cu.header.initial_length_size;
+
+ do_cleanups (back_to_inner);
}
do_cleanups (back_to);
}
CORE_ADDR addr = 0;
char *actual_name = pdi->name;
const struct partial_symbol *psym = NULL;
+ CORE_ADDR baseaddr;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
/* If we're not in the global namespace and if the namespace name
isn't encoded in a mangled actual_name, add it. */
VAR_DOMAIN, LOC_BLOCK,
&objfile->global_psymbols,
0, pdi->lowpc + baseaddr,
- cu_language, objfile);
+ cu->language, objfile);
}
else
{
VAR_DOMAIN, LOC_BLOCK,
&objfile->static_psymbols,
0, pdi->lowpc + baseaddr,
- cu_language, objfile);
+ cu->language, objfile);
}
break;
case DW_TAG_variable:
VAR_DOMAIN, LOC_STATIC,
&objfile->global_psymbols,
0, addr + baseaddr,
- cu_language, objfile);
+ cu->language, objfile);
}
else
{
VAR_DOMAIN, LOC_STATIC,
&objfile->static_psymbols,
0, addr + baseaddr,
- cu_language, objfile);
+ cu->language, objfile);
}
break;
case DW_TAG_typedef:
add_psymbol_to_list (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
- 0, (CORE_ADDR) 0, cu_language, objfile);
+ 0, (CORE_ADDR) 0, cu->language, objfile);
break;
case DW_TAG_class_type:
case DW_TAG_structure_type:
return;
add_psymbol_to_list (actual_name, strlen (actual_name),
STRUCT_DOMAIN, LOC_TYPEDEF,
- cu_language == language_cplus
+ cu->language == language_cplus
? &objfile->global_psymbols
: &objfile->static_psymbols,
- 0, (CORE_ADDR) 0, cu_language, objfile);
+ 0, (CORE_ADDR) 0, cu->language, objfile);
- if (cu_language == language_cplus)
+ if (cu->language == language_cplus)
{
/* For C++, 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);
+ 0, (CORE_ADDR) 0, cu->language, objfile);
}
break;
case DW_TAG_enumerator:
add_psymbol_to_list (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_CONST,
- cu_language == language_cplus
- ? &objfile->static_psymbols
- : &objfile->global_psymbols,
- 0, (CORE_ADDR) 0, cu_language, objfile);
+ cu->language == language_cplus
+ ? &objfile->global_psymbols
+ : &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu->language, objfile);
break;
default:
break;
(otherwise we'll have psym == NULL), and if we actually had a
mangled name to begin with. */
- if (cu_language == language_cplus
+ if (cu->language == language_cplus
&& namespace == NULL
&& psym != NULL
&& SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
add_psymbol_to_list (full_name, strlen (full_name),
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->global_psymbols,
- 0, 0, cu_language, objfile);
+ 0, 0, cu->language, objfile);
/* Now scan partial symbols in that namespace. */
bfd *abfd = cu->objfile->obfd;
char *actual_class_name = NULL;
- if (cu_language == language_cplus
- && namespace == NULL
+ if (cu->language == language_cplus
+ && (namespace == NULL || namespace[0] == '\0')
&& struct_pdi->name != NULL
&& struct_pdi->has_children)
{
- /* We don't have namespace debugging information, so see if we
- can figure out if this structure lives in a namespace. Look
+ /* See if we can figure out if the class lives in a namespace
+ (or is nested within another class.) We do this by looking
for a member function; its demangled name will contain
namespace info, if there is any. */
what template types look like, because the demangler
frequently doesn't give the same name as the debug info. We
could fix this by only using the demangled name to get the
- prefix (but see comment in read_structure_scope). */
+ prefix (but see comment in read_structure_type). */
+
+ /* FIXME: carlton/2004-01-23: If NAMESPACE equals "", we have
+ the appropriate debug information, so it would be nice to be
+ able to avoid this hack. But NAMESPACE may not be the
+ namespace where this class was defined: NAMESPACE reflects
+ where STRUCT_PDI occurs in the tree of dies, but because of
+ DW_AT_specification, that may not actually tell us where the
+ class is defined. (See the comment in read_func_scope for an
+ example of how this could occur.)
+
+ Unfortunately, our current partial symtab data structures are
+ completely unable to deal with DW_AT_specification. So, for
+ now, the best thing to do is to get nesting information from
+ places other than the tree structure of dies if there's any
+ chance that a DW_AT_specification is involved. :-( */
char *next_child = info_ptr;
}
add_partial_symbol (struct_pdi, cu, namespace);
- xfree(actual_class_name);
+ xfree (actual_class_name);
return locate_pdi_sibling (struct_pdi, info_ptr, abfd, cu);
}
return info_ptr;
}
-/* Locate ORIG_PDI's sibling; INFO_PTR should point to the next DIE
- after ORIG_PDI. */
+/* Read the initial uleb128 in the die at INFO_PTR in compilation unit CU.
+ Return the corresponding abbrev, or NULL if the number is zero (indicating
+ an empty DIE). In either case *BYTES_READ will be set to the length of
+ the initial number. */
+
+static struct abbrev_info *
+peek_die_abbrev (char *info_ptr, int *bytes_read, struct dwarf2_cu *cu)
+{
+ bfd *abfd = cu->objfile->obfd;
+ unsigned int abbrev_number;
+ struct abbrev_info *abbrev;
+
+ abbrev_number = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
+
+ if (abbrev_number == 0)
+ return NULL;
+
+ abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
+ if (!abbrev)
+ {
+ error ("Dwarf Error: Could not find abbrev number %d [in module %s]", abbrev_number,
+ bfd_get_filename (abfd));
+ }
+
+ 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
+ DIE. Any children of the skipped DIEs will also be skipped. */
+
+static char *
+skip_children (char *info_ptr, struct dwarf2_cu *cu)
+{
+ struct abbrev_info *abbrev;
+ unsigned int bytes_read;
+
+ while (1)
+ {
+ abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
+ if (abbrev == NULL)
+ return info_ptr + bytes_read;
+ else
+ info_ptr = skip_one_die (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
+ abbrev corresponding to that skipped uleb128 should be passed in
+ ABBREV. Returns a pointer to this DIE's sibling, skipping any
+ children. */
+
+static char *
+skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
+ struct dwarf2_cu *cu)
+{
+ unsigned int bytes_read;
+ struct attribute attr;
+ bfd *abfd = cu->objfile->obfd;
+ unsigned int form, i;
+
+ for (i = 0; i < abbrev->num_attrs; i++)
+ {
+ /* The only abbrev we care about is DW_AT_sibling. */
+ if (abbrev->attrs[i].name == DW_AT_sibling)
+ {
+ read_attribute (&attr, &abbrev->attrs[i],
+ abfd, info_ptr, cu);
+ if (attr.form == DW_FORM_ref_addr)
+ complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
+ else
+ return dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr, cu);
+ }
+
+ /* If it isn't DW_AT_sibling, skip this attribute. */
+ form = abbrev->attrs[i].form;
+ skip_attribute:
+ switch (form)
+ {
+ case DW_FORM_addr:
+ case DW_FORM_ref_addr:
+ info_ptr += cu->header.addr_size;
+ break;
+ case DW_FORM_data1:
+ case DW_FORM_ref1:
+ case DW_FORM_flag:
+ info_ptr += 1;
+ break;
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ info_ptr += 2;
+ break;
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ info_ptr += 4;
+ break;
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ info_ptr += 8;
+ break;
+ case DW_FORM_string:
+ read_string (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_strp:
+ info_ptr += cu->header.offset_size;
+ break;
+ case DW_FORM_block:
+ info_ptr += read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_block1:
+ info_ptr += 1 + read_1_byte (abfd, info_ptr);
+ break;
+ case DW_FORM_block2:
+ info_ptr += 2 + read_2_bytes (abfd, info_ptr);
+ break;
+ case DW_FORM_block4:
+ info_ptr += 4 + read_4_bytes (abfd, info_ptr);
+ break;
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ info_ptr = skip_leb128 (abfd, info_ptr);
+ break;
+ case DW_FORM_indirect:
+ form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ /* We need to continue parsing from here, so just go back to
+ the top. */
+ goto skip_attribute;
+
+ default:
+ error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]",
+ dwarf_form_name (form),
+ bfd_get_filename (abfd));
+ }
+ }
+
+ if (abbrev->has_children)
+ return skip_children (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. */
static char *
locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr,
if (!orig_pdi->has_children)
return info_ptr;
- /* Okay, we don't know the sibling, but we have children that we
- want to skip. So read children until we run into one without a
- tag; return whatever follows it. */
+ /* Skip the children the long way. */
- while (1)
- {
- struct partial_die_info pdi;
-
- info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu);
-
- if (pdi.tag == 0)
- return info_ptr;
- else
- info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu);
- }
+ return skip_children (info_ptr, cu);
}
/* Expand this partial symbol table into a full symbol table. */
struct symtab *symtab;
struct cleanup *back_to;
struct attribute *attr;
+ CORE_ADDR baseaddr;
/* Set local variables from the partial symbol table info. */
offset = DWARF_INFO_OFFSET (pst);
dwarf_ranges_size = DWARF_RANGES_SIZE (pst);
dwarf_loc_buffer = DWARF_LOC_BUFFER (pst);
dwarf_loc_size = DWARF_LOC_SIZE (pst);
- baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
- cu_header_offset = offset;
info_ptr = dwarf_info_buffer + offset;
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
/* We're in the global namespace. */
processing_current_prefix = "";
/* Read the abbrevs for this compilation unit */
dwarf2_read_abbrevs (abfd, &cu);
- make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
+ make_cleanup (dwarf2_free_abbrev_table, &cu);
+
+ cu.header.offset = offset;
+
+ cu.list_in_scope = &file_symbols;
dies = read_comp_unit (info_ptr, abfd, &cu);
cu.header.base_known = 0;
cu.header.base_address = 0;
- attr = dwarf_attr (dies, DW_AT_entry_pc);
+ attr = dwarf2_attr (dies, DW_AT_entry_pc, &cu);
if (attr)
{
cu.header.base_address = DW_ADDR (attr);
}
else
{
- attr = dwarf_attr (dies, DW_AT_low_pc);
+ attr = dwarf2_attr (dies, DW_AT_low_pc, &cu);
if (attr)
{
cu.header.base_address = DW_ADDR (attr);
If the compilation is from a C file generated by language preprocessors,
do not set the language if it was already deduced by start_subfile. */
if (symtab != NULL
- && !(cu_language == language_c && symtab->language != language_c))
+ && !(cu.language == language_c && symtab->language != language_c))
{
- symtab->language = cu_language;
+ symtab->language = cu.language;
}
pst->symtab = symtab;
pst->readin = 1;
case DW_TAG_class_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
- read_structure_scope (die, cu);
+ read_structure_type (die, cu);
+ process_structure_scope (die, cu);
break;
case DW_TAG_enumeration_type:
- read_enumeration (die, cu);
+ 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. */
case DW_TAG_subroutine_type:
read_subroutine_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);
- if (dwarf_attr (die, DW_AT_name))
- {
- /* Add a typedef symbol for the base type definition. */
- new_symbol (die, die->type, 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);
- if (dwarf_attr (die, DW_AT_name))
- {
- /* Add a typedef symbol for the base type definition. */
- new_symbol (die, die->type, 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_common_block:
read_common_block (die, cu);
}
static void
-initialize_cu_func_list (void)
+initialize_cu_func_list (struct dwarf2_cu *cu)
{
- cu_first_fn = cu_last_fn = cu_cached_fn = NULL;
+ cu->first_fn = cu->last_fn = cu->cached_fn = NULL;
}
static void
struct die_info *child_die;
bfd *abfd = objfile->obfd;
struct line_header *line_header = 0;
+ CORE_ADDR baseaddr;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
get_scope_pc_bounds (die, &lowpc, &highpc, cu);
lowpc += baseaddr;
highpc += baseaddr;
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr)
{
name = DW_STRING (attr);
}
- attr = dwarf_attr (die, DW_AT_comp_dir);
+ attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
if (attr)
{
comp_dir = DW_STRING (attr);
objfile->ei.deprecated_entry_file_highpc = highpc;
}
- attr = dwarf_attr (die, DW_AT_language);
+ attr = dwarf2_attr (die, DW_AT_language, cu);
if (attr)
{
- set_cu_language (DW_UNSND (attr));
+ set_cu_language (DW_UNSND (attr), cu);
}
/* We assume that we're processing GCC output. */
/* The compilation unit may be in a different language or objfile,
zero out all remembered fundamental types. */
- memset (ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
+ memset (cu->ftypes, 0, FT_NUM_MEMBERS * sizeof (struct type *));
start_symtab (name, comp_dir, lowpc);
record_debugformat ("DWARF 2");
- initialize_cu_func_list ();
+ initialize_cu_func_list (cu);
/* Process all dies in compilation unit. */
if (die->child != NULL)
}
/* Decode line number information if present. */
- attr = dwarf_attr (die, DW_AT_stmt_list);
+ attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
if (attr)
{
unsigned int line_offset = DW_UNSND (attr);
refers to information in the line number info statement program
header, so we can only read it if we've read the header
successfully. */
- attr = dwarf_attr (die, DW_AT_macro_info);
+ attr = dwarf2_attr (die, DW_AT_macro_info, cu);
if (attr && line_header)
{
unsigned int macro_offset = DW_UNSND (attr);
}
static void
-add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
+add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc,
+ struct dwarf2_cu *cu)
{
struct function_range *thisfn;
thisfn->seen_line = 0;
thisfn->next = NULL;
- if (cu_last_fn == NULL)
- cu_first_fn = thisfn;
+ if (cu->last_fn == NULL)
+ cu->first_fn = thisfn;
else
- cu_last_fn->next = thisfn;
+ cu->last_fn->next = thisfn;
- cu_last_fn = thisfn;
+ cu->last_fn = thisfn;
}
static void
struct die_info *child_die;
struct attribute *attr;
char *name;
+ const char *previous_prefix = processing_current_prefix;
+ struct cleanup *back_to = NULL;
+ CORE_ADDR baseaddr;
- name = dwarf2_linkage_name (die);
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ name = dwarf2_linkage_name (die, cu);
/* Ignore functions with missing or empty names and functions with
missing or invalid low and high pc attributes. */
if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
return;
+ if (cu->language == language_cplus)
+ {
+ struct die_info *spec_die = die_specification (die, cu);
+
+ /* NOTE: carlton/2004-01-23: We have to be careful in the
+ presence of DW_AT_specification. For example, with GCC 3.4,
+ given the code
+
+ namespace N {
+ void foo() {
+ // Definition of N::foo.
+ }
+ }
+
+ then we'll have a tree of DIEs like this:
+
+ 1: DW_TAG_compile_unit
+ 2: DW_TAG_namespace // N
+ 3: DW_TAG_subprogram // declaration of N::foo
+ 4: DW_TAG_subprogram // definition of N::foo
+ DW_AT_specification // refers to die #3
+
+ Thus, when processing die #4, we have to pretend that we're
+ in the context of its DW_AT_specification, namely the contex
+ of die #3. */
+
+ if (spec_die != NULL)
+ {
+ char *specification_prefix = determine_prefix (spec_die, cu);
+ processing_current_prefix = specification_prefix;
+ back_to = make_cleanup (xfree, specification_prefix);
+ }
+ }
+
lowpc += baseaddr;
highpc += baseaddr;
/* Record the function range for dwarf_decode_lines. */
- add_to_cu_func_list (name, lowpc, highpc);
+ add_to_cu_func_list (name, lowpc, highpc, cu);
if (objfile->ei.entry_point >= lowpc &&
objfile->ei.entry_point < highpc)
/* If there is a location expression for DW_AT_frame_base, record
it. */
- attr = dwarf_attr (die, DW_AT_frame_base);
+ attr = dwarf2_attr (die, DW_AT_frame_base, cu);
if (attr)
+ /* FIXME: cagney/2004-01-26: The DW_AT_frame_base's location
+ expression is being recorded directly in the function's symbol
+ and not in a separate frame-base object. I guess this hack is
+ to avoid adding some sort of frame-base adjunct/annex to the
+ function's symbol :-(. The problem with doing this is that it
+ results in a function symbol with a location expression that
+ has nothing to do with the location of the function, ouch! The
+ relationship should be: a function's symbol has-a frame base; a
+ frame-base has-a location expression. */
dwarf2_symbol_mark_computed (attr, new->name, cu);
- list_in_scope = &local_symbols;
+ cu->list_in_scope = &local_symbols;
if (die->child != NULL)
{
/* If we've finished processing a top-level function, subsequent
symbols go in the file symbol list. */
if (outermost_context_p ())
- list_in_scope = &file_symbols;
+ cu->list_in_scope = &file_symbols;
+
+ processing_current_prefix = previous_prefix;
+ if (back_to != NULL)
+ do_cleanups (back_to);
}
/* Process all the DIES contained within a lexical block scope. Start
struct context_stack *new;
CORE_ADDR lowpc, highpc;
struct die_info *child_die;
+ CORE_ADDR baseaddr;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
/* Ignore blocks with missing or invalid low and high pc attributes. */
/* ??? Perhaps consider discontiguous blocks defined by DW_AT_ranges
CORE_ADDR high = 0;
int ret = 0;
- attr = dwarf_attr (die, DW_AT_high_pc);
+ attr = dwarf2_attr (die, DW_AT_high_pc, cu);
if (attr)
{
high = DW_ADDR (attr);
- attr = dwarf_attr (die, DW_AT_low_pc);
+ attr = dwarf2_attr (die, DW_AT_low_pc, cu);
if (attr)
low = DW_ADDR (attr);
else
}
else
{
- attr = dwarf_attr (die, DW_AT_ranges);
+ attr = dwarf2_attr (die, DW_AT_ranges, cu);
if (attr != NULL)
{
unsigned int addr_size = cu_header->addr_size;
new_field->accessibility = DW_ACCESS_private;
new_field->virtuality = DW_VIRTUALITY_none;
- attr = dwarf_attr (die, DW_AT_accessibility);
+ attr = dwarf2_attr (die, DW_AT_accessibility, cu);
if (attr)
new_field->accessibility = DW_UNSND (attr);
if (new_field->accessibility != DW_ACCESS_public)
fip->non_public_fields = 1;
- attr = dwarf_attr (die, DW_AT_virtuality);
+ attr = dwarf2_attr (die, DW_AT_virtuality, cu);
if (attr)
new_field->virtuality = DW_UNSND (attr);
fp = &new_field->field;
- if (die->tag == DW_TAG_member && ! die_is_declaration (die))
+ if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
{
/* Data member other than a C++ static data member. */
FIELD_STATIC_KIND (*fp) = 0;
/* Get bit size of field (zero if none). */
- attr = dwarf_attr (die, DW_AT_bit_size);
+ attr = dwarf2_attr (die, DW_AT_bit_size, cu);
if (attr)
{
FIELD_BITSIZE (*fp) = DW_UNSND (attr);
}
/* Get bit offset of field. */
- attr = dwarf_attr (die, DW_AT_data_member_location);
+ attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
if (attr)
{
FIELD_BITPOS (*fp) =
}
else
FIELD_BITPOS (*fp) = 0;
- attr = dwarf_attr (die, DW_AT_bit_offset);
+ attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
if (attr)
{
if (BITS_BIG_ENDIAN)
int anonymous_size;
int bit_offset = DW_UNSND (attr);
- attr = dwarf_attr (die, DW_AT_byte_size);
+ attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
/* The size of the anonymous object containing
}
/* Get name of field. */
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
fieldname = DW_STRING (attr);
- fp->name = obsavestring (fieldname, strlen (fieldname),
- &objfile->type_obstack);
+
+ /* The name is already allocated along with this objfile, so we don't
+ need to duplicate it for the type. */
+ fp->name = fieldname;
/* Change accessibility for artificial fields (e.g. virtual table
pointer or virtual base class pointer) to private. */
- if (dwarf_attr (die, DW_AT_artificial))
+ if (dwarf2_attr (die, DW_AT_artificial, cu))
{
new_field->accessibility = DW_ACCESS_private;
fip->non_public_fields = 1;
char *physname;
/* Get name of field. */
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
fieldname = DW_STRING (attr);
else
return;
/* Get physical name. */
- physname = dwarf2_linkage_name (die);
+ physname = dwarf2_linkage_name (die, cu);
- SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname),
- &objfile->type_obstack));
+ /* The name is already allocated along with this objfile, so we don't
+ need to duplicate it for the type. */
+ SET_FIELD_PHYSNAME (*fp, physname ? physname : "");
FIELD_TYPE (*fp) = die_type (die, cu);
- FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname),
- &objfile->type_obstack);
+ FIELD_NAME (*fp) = fieldname;
}
else if (die->tag == DW_TAG_inheritance)
{
/* C++ base class field. */
- attr = dwarf_attr (die, DW_AT_data_member_location);
+ attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
if (attr)
FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), cu)
* bits_per_byte);
struct nextfnfield *new_fnfield;
/* Get name of member function. */
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
fieldname = DW_STRING (attr);
else
return;
/* Get the mangled name. */
- physname = dwarf2_linkage_name (die);
+ physname = dwarf2_linkage_name (die, cu);
/* Look up member function name in fieldlist. */
for (i = 0; i < fip->nfnfields; i++)
/* Fill in the member function field info. */
fnp = &new_fnfield->fnfield;
- fnp->physname = obsavestring (physname, strlen (physname),
- &objfile->type_obstack);
+ /* The name is already allocated along with this objfile, so we don't
+ 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)
{
physname);
/* Get fcontext from DW_AT_containing_type if present. */
- if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+ if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
fnp->fcontext = die_containing_type (die, cu);
/* dwarf2 doesn't have stubbed physical names, so the setting of is_const
and is_volatile is irrelevant, as it is needed by gdb_mangle_name only. */
/* Get accessibility. */
- attr = dwarf_attr (die, DW_AT_accessibility);
+ attr = dwarf2_attr (die, DW_AT_accessibility, cu);
if (attr)
{
switch (DW_UNSND (attr))
}
/* Check for artificial methods. */
- attr = dwarf_attr (die, DW_AT_artificial);
+ attr = dwarf2_attr (die, DW_AT_artificial, cu);
if (attr && DW_UNSND (attr) != 0)
fnp->is_artificial = 1;
/* Get index in virtual function table if it is a virtual member function. */
- attr = dwarf_attr (die, DW_AT_vtable_elem_location);
+ attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu);
if (attr)
{
/* Support the .debug_loc offsets */
suppresses creating a symbol table entry itself). */
static void
-read_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
+read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct type *type;
struct attribute *attr;
- const char *name = NULL;
const char *previous_prefix = processing_current_prefix;
struct cleanup *back_to = NULL;
- /* This says whether or not we want to try to update the structure's
- name to include enclosing namespace/class information, if
- any. */
- int need_to_update_name = 0;
+
+ if (die->type)
+ return;
type = alloc_type (objfile);
INIT_CPLUS_SPECIFIC (type);
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
{
- name = DW_STRING (attr);
-
- if (cu_language == language_cplus)
+ if (cu->language == language_cplus)
{
- struct die_info *spec_die = die_specification (die);
-
- if (spec_die != NULL)
- {
- char *specification_prefix = determine_prefix (spec_die);
- processing_current_prefix = specification_prefix;
- back_to = make_cleanup (xfree, specification_prefix);
- }
- }
-
- if (processing_has_namespace_info)
- {
- /* FIXME: carlton/2003-11-10: This variable exists only for
- const-correctness reasons. When I tried to change
- TYPE_TAG_NAME to be a const char *, I ran into a cascade
- of changes which would have forced decode_line_1 to take
- a const char **. */
- char *new_prefix = obconcat (&objfile->type_obstack,
- processing_current_prefix,
- processing_current_prefix[0] == '\0'
- ? "" : "::",
- name);
- TYPE_TAG_NAME (type) = new_prefix;
+ char *new_prefix = determine_class_name (die, cu);
+ TYPE_TAG_NAME (type) = obsavestring (new_prefix,
+ strlen (new_prefix),
+ &objfile->objfile_obstack);
+ back_to = make_cleanup (xfree, new_prefix);
processing_current_prefix = new_prefix;
}
else
{
- TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
- &objfile->type_obstack);
- need_to_update_name = (cu_language == language_cplus);
+ /* The name is already allocated along with this objfile, so
+ we don't need to duplicate it for the type. */
+ TYPE_TAG_NAME (type) = DW_STRING (attr);
}
}
TYPE_CODE (type) = TYPE_CODE_CLASS;
}
- attr = dwarf_attr (die, DW_AT_byte_size);
+ attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
TYPE_LENGTH (type) = DW_UNSND (attr);
type within the structure itself. */
die->type = type;
- if (die->child != NULL && ! die_is_declaration (die))
+ if (die->child != NULL && ! die_is_declaration (die, cu))
{
struct field_info fi;
struct die_info *child_die;
else if (child_die->tag == DW_TAG_subprogram)
{
/* C++ member function. */
- process_die (child_die, cu);
+ read_type_die (child_die, cu);
dwarf2_add_member_fn (&fi, child_die, type, cu);
- if (need_to_update_name)
- {
- /* The demangled names of member functions contain
- information about enclosing namespaces/classes,
- if any. */
-
- /* FIXME: carlton/2003-11-10: The excessive
- demangling here is a bit wasteful, as is the
- memory usage for names. */
-
- /* NOTE: carlton/2003-11-10: As commented in
- add_partial_structure, the demangler sometimes
- prints the type info in a different form from the
- debug info. We could solve this by using the
- demangled name to get the prefix; if doing so,
- however, we'd need to be careful when reading a
- class that's nested inside a template class.
- That would also cause problems when trying to
- determine RTTI information, since we use the
- demangler to determine the appropriate class
- name. */
- char *actual_class_name
- = class_name_from_physname (dwarf2_linkage_name
- (child_die));
- if (actual_class_name != NULL
- && strcmp (actual_class_name, name) != 0)
- {
- TYPE_TAG_NAME (type)
- = obsavestring (actual_class_name,
- strlen (actual_class_name),
- &objfile->type_obstack);
- }
- xfree (actual_class_name);
- need_to_update_name = 0;
- }
}
else if (child_die->tag == DW_TAG_inheritance)
{
/* C++ base class field. */
dwarf2_add_field (&fi, child_die, cu);
}
- else
- {
- process_die (child_die, cu);
- }
child_die = sibling_die (child_die);
}
class itself) which contains the vtable pointer for the current
class from the DW_AT_containing_type attribute. */
- if (dwarf_attr (die, DW_AT_containing_type) != NULL)
+ if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
{
struct type *t = die_containing_type (die, cu);
}
}
- new_symbol (die, type, cu);
-
do_cleanups (back_to);
}
else
do_cleanups (back_to);
}
-/* Given a pointer to a die which begins an enumeration, process all
- the dies that define the members of the enumeration.
+static void
+process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = cu->objfile;
+ const char *previous_prefix = processing_current_prefix;
+ struct die_info *child_die = die->child;
- This will be much nicer in draft 6 of the DWARF spec when our
- members will be dies instead squished into the DW_AT_element_list
- attribute.
+ if (TYPE_TAG_NAME (die->type) != NULL)
+ processing_current_prefix = TYPE_TAG_NAME (die->type);
- NOTE: We reverse the order of the element list. */
+ /* 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
+ for a class that has, as a child, a die giving a definition for a
+ nested class. So we have to process our children even if the
+ current die is a declaration. Normally, of course, a declaration
+ won't have any children at all. */
+
+ while (child_die != NULL && child_die->tag)
+ {
+ if (child_die->tag == DW_TAG_member
+ || child_die->tag == DW_TAG_variable
+ || child_die->tag == DW_TAG_inheritance)
+ {
+ /* Do nothing. */
+ }
+ else
+ process_die (child_die, cu);
+
+ child_die = sibling_die (child_die);
+ }
+
+ if (die->child != NULL && ! die_is_declaration (die, cu))
+ new_symbol (die, die->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
-read_enumeration (struct die_info *die, struct dwarf2_cu *cu)
+read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- struct die_info *child_die;
struct type *type;
- struct field *fields;
struct attribute *attr;
- struct symbol *sym;
- int num_fields;
- int unsigned_enum = 1;
+
+ if (die->type)
+ return;
type = alloc_type (objfile);
TYPE_CODE (type) = TYPE_CODE_ENUM;
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
{
- const char *name = DW_STRING (attr);
+ char *name = DW_STRING (attr);
if (processing_has_namespace_info)
{
- TYPE_TAG_NAME (type) = obconcat (&objfile->type_obstack,
+ TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
processing_current_prefix,
processing_current_prefix[0] == '\0'
? "" : "::",
}
else
{
- TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
- &objfile->type_obstack);
+ /* The name is already allocated along with this objfile, so
+ we don't need to duplicate it for the type. */
+ TYPE_TAG_NAME (type) = name;
}
}
- attr = dwarf_attr (die, DW_AT_byte_size);
+ attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
TYPE_LENGTH (type) = DW_UNSND (attr);
TYPE_LENGTH (type) = 0;
}
+ die->type = type;
+}
+
+/* Determine the name of the type represented by DIE, which should be
+ a named C++ compound type. Return the name in question; the caller
+ is responsible for xfree()'ing it. */
+
+static char *
+determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct cleanup *back_to = NULL;
+ struct die_info *spec_die = die_specification (die, cu);
+ char *new_prefix = NULL;
+
+ /* If this is the definition of a class that is declared by another
+ die, then processing_current_prefix may not be accurate; see
+ read_func_scope for a similar example. */
+ if (spec_die != NULL)
+ {
+ char *specification_prefix = determine_prefix (spec_die, cu);
+ processing_current_prefix = specification_prefix;
+ back_to = make_cleanup (xfree, specification_prefix);
+ }
+
+ /* If we don't have namespace debug info, guess the name by trying
+ to demangle the names of members, just like we did in
+ add_partial_structure. */
+ if (!processing_has_namespace_info)
+ {
+ struct die_info *child;
+
+ for (child = die->child;
+ child != NULL && child->tag != 0;
+ child = sibling_die (child))
+ {
+ if (child->tag == DW_TAG_subprogram)
+ {
+ new_prefix = class_name_from_physname (dwarf2_linkage_name
+ (child, cu));
+
+ if (new_prefix != NULL)
+ break;
+ }
+ }
+ }
+
+ if (new_prefix == NULL)
+ {
+ const char *name = dwarf2_name (die, cu);
+ new_prefix = typename_concat (processing_current_prefix,
+ name ? name : "<<anonymous>>");
+ }
+
+ if (back_to != NULL)
+ do_cleanups (back_to);
+
+ return new_prefix;
+}
+
+/* Given a pointer to a die which begins an enumeration, process all
+ the dies that define the members of the enumeration, and create the
+ symbol for the enumeration type.
+
+ NOTE: We reverse the order of the element list. */
+
+static void
+process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = cu->objfile;
+ struct die_info *child_die;
+ struct field *fields;
+ struct attribute *attr;
+ struct symbol *sym;
+ int num_fields;
+ int unsigned_enum = 1;
+
num_fields = 0;
fields = NULL;
if (die->child != NULL)
}
else
{
- attr = dwarf_attr (child_die, DW_AT_name);
+ attr = dwarf2_attr (child_die, DW_AT_name, cu);
if (attr)
{
- sym = new_symbol (child_die, type, cu);
+ sym = new_symbol (child_die, die->type, cu);
if (SYMBOL_VALUE (sym) < 0)
unsigned_enum = 0;
if (num_fields)
{
- TYPE_NFIELDS (type) = num_fields;
- TYPE_FIELDS (type) = (struct field *)
- TYPE_ALLOC (type, sizeof (struct field) * num_fields);
- memcpy (TYPE_FIELDS (type), 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,
sizeof (struct field) * num_fields);
xfree (fields);
}
if (unsigned_enum)
- TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+ TYPE_FLAGS (die->type) |= TYPE_FLAG_UNSIGNED;
}
- die->type = type;
- new_symbol (die, type, cu);
+
+ new_symbol (die, die->type, cu);
}
/* Extract all information from a DW_TAG_array_type DIE and put it in
arrays with unspecified length. */
if (die->child == NULL)
{
- index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+ index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
range_type = create_range_type (NULL, index_type, 0, -1);
die->type = create_array_type (NULL, element_type, range_type);
return;
custom vendor extension. The main difference between a regular
array and the vector variant is that vectors are passed by value
to functions. */
- attr = dwarf_attr (die, DW_AT_GNU_vector);
+ attr = dwarf2_attr (die, DW_AT_GNU_vector, cu);
if (attr)
TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
struct symbol *sym;
CORE_ADDR base = (CORE_ADDR) 0;
- attr = dwarf_attr (die, DW_AT_location);
+ attr = dwarf2_attr (die, DW_AT_location, cu);
if (attr)
{
/* Support the .debug_loc offsets */
while (child_die && child_die->tag)
{
sym = new_symbol (child_die, NULL, cu);
- attr = dwarf_attr (child_die, DW_AT_data_member_location);
+ attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu);
if (attr)
{
SYMBOL_VALUE_ADDRESS (sym) =
int is_anonymous;
struct die_info *current_die;
- name = namespace_name (die, &is_anonymous);
+ name = namespace_name (die, &is_anonymous, cu);
/* Now build the name of the current namespace. */
before. Also, add a using directive if it's an anonymous
namespace. */
- if (dwarf2_extension (die) == NULL)
+ if (dwarf2_extension (die, cu) == NULL)
{
struct type *type;
TYPE_TAG_NAME (type) = TYPE_NAME (type);
new_symbol (die, type, cu);
+ die->type = type;
if (is_anonymous)
cp_add_using_directive (processing_current_prefix,
namespace. */
static const char *
-namespace_name (struct die_info *die, int *is_anonymous)
+namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu)
{
struct die_info *current_die;
const char *name = NULL;
for (current_die = die;
current_die != NULL;
- current_die = dwarf2_extension (die))
+ current_die = dwarf2_extension (die, cu))
{
- name = dwarf2_name (current_die);
+ name = dwarf2_name (current_die, cu);
if (name != NULL)
break;
}
type = lookup_pointer_type (die_type (die, cu));
- attr_byte_size = dwarf_attr (die, DW_AT_byte_size);
+ attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr_byte_size)
byte_size = DW_UNSND (attr_byte_size);
else
byte_size = cu_header->addr_size;
- attr_address_class = dwarf_attr (die, DW_AT_address_class);
+ attr_address_class = dwarf2_attr (die, DW_AT_address_class, cu);
if (attr_address_class)
addr_class = DW_UNSND (attr_address_class);
else
}
type = lookup_reference_type (die_type (die, cu));
- attr = dwarf_attr (die, DW_AT_byte_size);
+ attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
TYPE_LENGTH (type) = DW_UNSND (attr);
return;
}
- attr = dwarf_attr (die, DW_AT_string_length);
+ attr = dwarf2_attr (die, DW_AT_string_length, cu);
if (attr)
{
length = DW_UNSND (attr);
else
{
/* check for the DW_AT_byte_size attribute */
- attr = dwarf_attr (die, DW_AT_byte_size);
+ attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
length = DW_UNSND (attr);
length = 1;
}
}
- index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
+ index_type = dwarf2_fundamental_type (objfile, FT_INTEGER, cu);
range_type = create_range_type (NULL, index_type, 1, length);
- if (cu_language == language_fortran)
+ if (cu->language == language_fortran)
{
/* Need to create a unique string type for bounds
information */
}
else
{
- char_type = dwarf2_fundamental_type (objfile, FT_CHAR);
+ char_type = dwarf2_fundamental_type (objfile, FT_CHAR, cu);
type = create_string_type (char_type, range_type);
}
die->type = type;
ftype = lookup_function_type (type);
/* All functions in C++ have prototypes. */
- attr = dwarf_attr (die, DW_AT_prototyped);
+ attr = dwarf2_attr (die, DW_AT_prototyped, cu);
if ((attr && (DW_UNSND (attr) != 0))
- || cu_language == language_cplus)
+ || cu->language == language_cplus)
TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
if (die->child != NULL)
parameter for non-static member functions (which is the
this pointer) as artificial. We pass this information
to dwarf2_add_member_fn via TYPE_FIELD_ARTIFICIAL. */
- attr = dwarf_attr (child_die, DW_AT_artificial);
+ attr = dwarf2_attr (child_die, DW_AT_artificial, cu);
if (attr)
TYPE_FIELD_ARTIFICIAL (ftype, iparams) = DW_UNSND (attr);
else
if (!die->type)
{
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
{
name = DW_STRING (attr);
return;
}
- attr = dwarf_attr (die, DW_AT_encoding);
+ attr = dwarf2_attr (die, DW_AT_encoding, cu);
if (attr)
{
encoding = DW_UNSND (attr);
}
- attr = dwarf_attr (die, DW_AT_byte_size);
+ attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
size = DW_UNSND (attr);
}
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
{
enum type_code code = TYPE_CODE_INT;
}
type = init_type (code, size, type_flags, DW_STRING (attr), objfile);
if (encoding == DW_ATE_address)
- TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID);
+ TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID,
+ cu);
else if (encoding == DW_ATE_complex_float)
{
if (size == 32)
TYPE_TARGET_TYPE (type)
- = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT);
+ = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT, cu);
else if (size == 16)
TYPE_TARGET_TYPE (type)
- = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+ = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
else if (size == 8)
TYPE_TARGET_TYPE (type)
- = dwarf2_fundamental_type (objfile, FT_FLOAT);
+ = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
}
}
else
if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
base_type = alloc_type (NULL);
- if (cu_language == language_fortran)
+ if (cu->language == language_fortran)
{
/* FORTRAN implies a lower bound of 1, if not given. */
low = 1;
}
- attr = dwarf_attr (die, DW_AT_lower_bound);
+ attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
if (attr)
low = dwarf2_get_attr_constant_value (attr, 0);
- attr = dwarf_attr (die, DW_AT_upper_bound);
+ attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
if (attr)
{
if (attr->form == DW_FORM_block1)
range_type = create_range_type (NULL, base_type, low, high);
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
TYPE_NAME (range_type) = DW_STRING (attr);
- attr = dwarf_attr (die, DW_AT_byte_size);
+ attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
TYPE_LENGTH (range_type) = DW_UNSND (attr);
/* Read the contents of the section at OFFSET and of size SIZE from the
- object file specified by OBJFILE into the psymbol_obstack and return it. */
+ object file specified by OBJFILE into the objfile_obstack and return it. */
char *
dwarf2_read_section (struct objfile *objfile, asection *sectp)
if (size == 0)
return NULL;
- buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size);
+ buf = (char *) obstack_alloc (&objfile->objfile_obstack, size);
retbuf
= (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf);
if (retbuf != NULL)
struct abbrev_info *cur_abbrev;
unsigned int abbrev_number, bytes_read, abbrev_name;
unsigned int abbrev_form, hash_number;
+ struct attr_abbrev *cur_attrs;
+ unsigned int allocated_attrs;
/* Initialize dwarf2 abbrevs */
- memset (cu_header->dwarf2_abbrevs, 0,
- ABBREV_HASH_SIZE*sizeof (struct abbrev_info *));
+ obstack_init (&cu->abbrev_obstack);
+ cu->dwarf2_abbrevs = obstack_alloc (&cu->abbrev_obstack,
+ (ABBREV_HASH_SIZE
+ * sizeof (struct abbrev_info *)));
+ memset (cu->dwarf2_abbrevs, 0,
+ ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
abbrev_ptr = dwarf_abbrev_buffer + cu_header->abbrev_offset;
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
+ allocated_attrs = ATTR_ALLOC_CHUNK;
+ cur_attrs = xmalloc (allocated_attrs * sizeof (struct attr_abbrev));
+
/* loop until we reach an abbrev number of 0 */
while (abbrev_number)
{
- cur_abbrev = dwarf_alloc_abbrev ();
+ cur_abbrev = dwarf_alloc_abbrev (cu);
/* read in abbrev header */
cur_abbrev->number = abbrev_number;
abbrev_ptr += bytes_read;
while (abbrev_name)
{
- if ((cur_abbrev->num_attrs % ATTR_ALLOC_CHUNK) == 0)
+ if (cur_abbrev->num_attrs == allocated_attrs)
{
- cur_abbrev->attrs = (struct attr_abbrev *)
- xrealloc (cur_abbrev->attrs,
- (cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK)
- * sizeof (struct attr_abbrev));
+ allocated_attrs += ATTR_ALLOC_CHUNK;
+ cur_attrs
+ = xrealloc (cur_attrs, (allocated_attrs
+ * sizeof (struct attr_abbrev)));
}
- cur_abbrev->attrs[cur_abbrev->num_attrs].name = abbrev_name;
- cur_abbrev->attrs[cur_abbrev->num_attrs++].form = abbrev_form;
+ cur_attrs[cur_abbrev->num_attrs].name = abbrev_name;
+ cur_attrs[cur_abbrev->num_attrs++].form = abbrev_form;
abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
}
+ cur_abbrev->attrs = obstack_alloc (&cu->abbrev_obstack,
+ (cur_abbrev->num_attrs
+ * sizeof (struct attr_abbrev)));
+ memcpy (cur_abbrev->attrs, cur_attrs,
+ cur_abbrev->num_attrs * sizeof (struct attr_abbrev));
+
hash_number = abbrev_number % ABBREV_HASH_SIZE;
- cur_abbrev->next = cu_header->dwarf2_abbrevs[hash_number];
- cu_header->dwarf2_abbrevs[hash_number] = cur_abbrev;
+ cur_abbrev->next = cu->dwarf2_abbrevs[hash_number];
+ cu->dwarf2_abbrevs[hash_number] = cur_abbrev;
/* Get next abbreviation.
Under Irix6 the abbreviations for a compilation unit are not
if (dwarf2_lookup_abbrev (abbrev_number, cu) != NULL)
break;
}
+
+ xfree (cur_attrs);
}
-/* Empty the abbrev table for a new compilation unit. */
+/* Release the memory used by the abbrev table for a compilation unit. */
static void
-dwarf2_empty_abbrev_table (void *ptr_to_abbrevs_table)
+dwarf2_free_abbrev_table (void *ptr_to_cu)
{
- int i;
- struct abbrev_info *abbrev, *next;
- struct abbrev_info **abbrevs;
+ struct dwarf2_cu *cu = ptr_to_cu;
- abbrevs = (struct abbrev_info **)ptr_to_abbrevs_table;
-
- for (i = 0; i < ABBREV_HASH_SIZE; ++i)
- {
- next = NULL;
- abbrev = abbrevs[i];
- while (abbrev)
- {
- next = abbrev->next;
- xfree (abbrev->attrs);
- xfree (abbrev);
- abbrev = next;
- }
- abbrevs[i] = NULL;
- }
+ obstack_free (&cu->abbrev_obstack, NULL);
+ cu->dwarf2_abbrevs = NULL;
}
/* Lookup an abbrev_info structure in the abbrev hash table. */
static struct abbrev_info *
dwarf2_lookup_abbrev (unsigned int number, struct dwarf2_cu *cu)
{
- struct comp_unit_head *cu_header = &cu->header;
unsigned int hash_number;
struct abbrev_info *abbrev;
hash_number = number % ABBREV_HASH_SIZE;
- abbrev = cu_header->dwarf2_abbrevs[hash_number];
+ abbrev = cu->dwarf2_abbrevs[hash_number];
while (abbrev)
{
complaint (&symfile_complaints, "ignoring absolute DW_AT_sibling");
else
part_die->sibling =
- dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr);
+ dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr, cu);
break;
default:
break;
struct partial_die_info spec_die;
char *spec_ptr;
- spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr);
+ spec_ptr = dwarf_info_buffer
+ + dwarf2_get_ref_die_offset (&spec_attr, cu);
read_partial_die (&spec_die, abfd, spec_ptr, cu);
if (spec_die.name)
{
return result;
}
+/* Return a pointer to just past the end of an LEB128 number in BUF. */
+
+static char *
+skip_leb128 (bfd *abfd, char *buf)
+{
+ int byte;
+
+ while (1)
+ {
+ byte = bfd_get_8 (abfd, (bfd_byte *) buf);
+ buf++;
+ if ((byte & 128) == 0)
+ return buf;
+ }
+}
+
static void
-set_cu_language (unsigned int lang)
+set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
{
switch (lang)
{
case DW_LANG_C89:
case DW_LANG_C:
- cu_language = language_c;
+ cu->language = language_c;
break;
case DW_LANG_C_plus_plus:
- cu_language = language_cplus;
+ cu->language = language_cplus;
break;
case DW_LANG_Fortran77:
case DW_LANG_Fortran90:
case DW_LANG_Fortran95:
- cu_language = language_fortran;
+ cu->language = language_fortran;
break;
case DW_LANG_Mips_Assembler:
- cu_language = language_asm;
+ cu->language = language_asm;
break;
case DW_LANG_Java:
- cu_language = language_java;
+ cu->language = language_java;
break;
case DW_LANG_Ada83:
case DW_LANG_Ada95:
case DW_LANG_Pascal83:
case DW_LANG_Modula2:
default:
- cu_language = language_minimal;
+ cu->language = language_minimal;
break;
}
- cu_language_defn = language_def (cu_language);
+ cu->language_defn = language_def (cu->language);
}
/* Return the named attribute or NULL if not there. */
static struct attribute *
-dwarf_attr (struct die_info *die, unsigned int name)
+dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
{
unsigned int i;
struct attribute *spec = NULL;
if (spec)
{
struct die_info *ref_die =
- follow_die_ref (dwarf2_get_ref_die_offset (spec));
+ follow_die_ref (dwarf2_get_ref_die_offset (spec, cu));
if (ref_die)
- return dwarf_attr (ref_die, name);
+ return dwarf2_attr (ref_die, name, cu);
}
return NULL;
}
static int
-die_is_declaration (struct die_info *die)
+die_is_declaration (struct die_info *die, struct dwarf2_cu *cu)
{
- return (dwarf_attr (die, DW_AT_declaration)
- && ! dwarf_attr (die, DW_AT_specification));
+ return (dwarf2_attr (die, DW_AT_declaration, cu)
+ && ! dwarf2_attr (die, DW_AT_specification, cu));
}
/* Return the die giving the specification for DIE, if there is
one. */
static struct die_info *
-die_specification (struct die_info *die)
+die_specification (struct die_info *die, struct dwarf2_cu *cu)
{
- struct attribute *spec_attr = dwarf_attr (die, DW_AT_specification);
+ struct attribute *spec_attr = dwarf2_attr (die, DW_AT_specification, cu);
if (spec_attr == NULL)
return NULL;
else
- return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr));
+ return follow_die_ref (dwarf2_get_ref_die_offset (spec_attr, cu));
}
/* Free the line_header structure *LH, and any arrays and strings it
addresses passed to record_line. */
static CORE_ADDR
-check_cu_functions (CORE_ADDR address)
+check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu)
{
struct function_range *fn;
/* Find the function_range containing address. */
- if (!cu_first_fn)
+ if (!cu->first_fn)
return address;
- if (!cu_cached_fn)
- cu_cached_fn = cu_first_fn;
+ if (!cu->cached_fn)
+ cu->cached_fn = cu->first_fn;
- fn = cu_cached_fn;
+ fn = cu->cached_fn;
while (fn)
if (fn->lowpc <= address && fn->highpc > address)
goto found;
else
fn = fn->next;
- fn = cu_first_fn;
- while (fn && fn != cu_cached_fn)
+ fn = cu->first_fn;
+ while (fn && fn != cu->cached_fn)
if (fn->lowpc <= address && fn->highpc > address)
goto found;
else
char *line_end;
unsigned int bytes_read;
unsigned char op_code, extended_op, adj_opcode;
+ CORE_ADDR baseaddr;
+ struct objfile *objfile = cu->objfile;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
line_ptr = lh->statement_program_start;
line_end = lh->statement_program_end;
line += lh->line_base + (adj_opcode % lh->line_range);
/* append row to matrix using current values */
record_line (current_subfile, line,
- check_cu_functions (address));
+ check_cu_functions (address, cu));
basic_block = 1;
}
else switch (op_code)
break;
case DW_LNS_copy:
record_line (current_subfile, line,
- check_cu_functions (address));
+ check_cu_functions (address, cu));
basic_block = 0;
break;
case DW_LNS_advance_pc:
char *name;
struct attribute *attr = NULL;
struct attribute *attr2 = NULL;
+ CORE_ADDR baseaddr;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
if (die->tag != DW_TAG_namespace)
- name = dwarf2_linkage_name (die);
+ name = dwarf2_linkage_name (die, cu);
else
name = TYPE_NAME (type);
if (name)
{
- sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+ sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
sizeof (struct symbol));
OBJSTAT (objfile, n_syms++);
memset (sym, 0, sizeof (struct symbol));
/* Cache this symbol's name and the name's demangled form (if any). */
- SYMBOL_LANGUAGE (sym) = cu_language;
+ SYMBOL_LANGUAGE (sym) = cu->language;
SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
/* Default assumptions.
SYMBOL_TYPE (sym) = type;
else
SYMBOL_TYPE (sym) = die_type (die, cu);
- attr = dwarf_attr (die, DW_AT_decl_line);
+ attr = dwarf2_attr (die, DW_AT_decl_line, cu);
if (attr)
{
SYMBOL_LINE (sym) = DW_UNSND (attr);
switch (die->tag)
{
case DW_TAG_label:
- attr = dwarf_attr (die, DW_AT_low_pc);
+ attr = dwarf2_attr (die, DW_AT_low_pc, cu);
if (attr)
{
SYMBOL_VALUE_ADDRESS (sym) = DW_ADDR (attr) + baseaddr;
/* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
finish_block. */
SYMBOL_CLASS (sym) = LOC_BLOCK;
- attr2 = dwarf_attr (die, DW_AT_external);
+ attr2 = dwarf2_attr (die, DW_AT_external, cu);
if (attr2 && (DW_UNSND (attr2) != 0))
{
add_symbol_to_list (sym, &global_symbols);
}
else
{
- add_symbol_to_list (sym, list_in_scope);
+ add_symbol_to_list (sym, cu->list_in_scope);
}
break;
case DW_TAG_variable:
TARGET_INT_BIT / HOST_CHAR_BIT, 0,
"<variable, no debug info>",
objfile);
- attr = dwarf_attr (die, DW_AT_const_value);
+ attr = dwarf2_attr (die, DW_AT_const_value, cu);
if (attr)
{
dwarf2_const_value (attr, sym, cu);
- attr2 = dwarf_attr (die, DW_AT_external);
+ attr2 = dwarf2_attr (die, DW_AT_external, cu);
if (attr2 && (DW_UNSND (attr2) != 0))
add_symbol_to_list (sym, &global_symbols);
else
- add_symbol_to_list (sym, list_in_scope);
+ add_symbol_to_list (sym, cu->list_in_scope);
break;
}
- attr = dwarf_attr (die, DW_AT_location);
+ attr = dwarf2_attr (die, DW_AT_location, cu);
if (attr)
{
var_decode_location (attr, sym, cu);
- attr2 = dwarf_attr (die, DW_AT_external);
+ attr2 = dwarf2_attr (die, DW_AT_external, cu);
if (attr2 && (DW_UNSND (attr2) != 0))
add_symbol_to_list (sym, &global_symbols);
else
- add_symbol_to_list (sym, list_in_scope);
+ add_symbol_to_list (sym, cu->list_in_scope);
}
else
{
The address of the variable will then be determined from
the minimal symbol table whenever the variable is
referenced. */
- attr2 = dwarf_attr (die, DW_AT_external);
+ attr2 = dwarf2_attr (die, DW_AT_external, cu);
if (attr2 && (DW_UNSND (attr2) != 0)
- && dwarf_attr (die, DW_AT_type) != NULL)
+ && dwarf2_attr (die, DW_AT_type, cu) != NULL)
{
SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
add_symbol_to_list (sym, &global_symbols);
}
break;
case DW_TAG_formal_parameter:
- attr = dwarf_attr (die, DW_AT_location);
+ attr = dwarf2_attr (die, DW_AT_location, cu);
if (attr)
{
var_decode_location (attr, sym, cu);
if (SYMBOL_CLASS (sym) == LOC_COMPUTED)
SYMBOL_CLASS (sym) = LOC_COMPUTED_ARG;
}
- attr = dwarf_attr (die, DW_AT_const_value);
+ attr = dwarf2_attr (die, DW_AT_const_value, cu);
if (attr)
{
dwarf2_const_value (attr, sym, cu);
}
- add_symbol_to_list (sym, list_in_scope);
+ add_symbol_to_list (sym, cu->list_in_scope);
break;
case DW_TAG_unspecified_parameters:
/* From varargs functions; gdb doesn't seem to have any
/* Make sure that the symbol includes appropriate enclosing
classes/namespaces in its name. These are calculated in
- read_structure_scope, and the correct name is saved in
+ read_structure_type, and the correct name is saved in
the type. */
- if (cu_language == language_cplus)
+ if (cu->language == language_cplus)
{
struct type *type = SYMBOL_TYPE (sym);
{
/* FIXME: carlton/2003-11-10: Should this use
SYMBOL_SET_NAMES instead? (The same problem also
- arises a further down in the function.) */
- SYMBOL_LINKAGE_NAME (sym)
- = obsavestring (TYPE_TAG_NAME (type),
- strlen (TYPE_TAG_NAME (type)),
- &objfile->symbol_obstack);
+ arises further down in this function.) */
+ /* The type's name is already allocated along with
+ this objfile, so we don't need to duplicate it
+ for the symbol. */
+ SYMBOL_LINKAGE_NAME (sym) = TYPE_TAG_NAME (type);
}
}
struct pending **list_to_add;
- list_to_add = (list_in_scope == &file_symbols
- && cu_language == language_cplus
- ? &global_symbols : list_in_scope);
+ list_to_add = (cu->list_in_scope == &file_symbols
+ && cu->language == language_cplus
+ ? &global_symbols : cu->list_in_scope);
add_symbol_to_list (sym, list_to_add);
/* The semantics of C++ state that "struct foo { ... }" also
defines a typedef for "foo". Synthesize a typedef symbol so
that "ptype foo" works as expected. */
- if (cu_language == language_cplus)
+ if (cu->language == language_cplus)
{
struct symbol *typedef_sym = (struct symbol *)
- obstack_alloc (&objfile->symbol_obstack,
+ 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)) =
- obsavestring (SYMBOL_NATURAL_NAME (sym),
- strlen (SYMBOL_NATURAL_NAME (sym)),
- &objfile->type_obstack);
+ TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NATURAL_NAME (sym);
add_symbol_to_list (typedef_sym, list_to_add);
}
}
if (processing_has_namespace_info
&& processing_current_prefix[0] != '\0')
{
- SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->symbol_obstack,
+ SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
processing_current_prefix,
"::",
name);
}
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
- add_symbol_to_list (sym, list_in_scope);
+ add_symbol_to_list (sym, cu->list_in_scope);
break;
case DW_TAG_base_type:
case DW_TAG_subrange_type:
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
- add_symbol_to_list (sym, list_in_scope);
+ add_symbol_to_list (sym, cu->list_in_scope);
break;
case DW_TAG_enumerator:
if (processing_has_namespace_info
&& processing_current_prefix[0] != '\0')
{
- SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->symbol_obstack,
+ SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
processing_current_prefix,
"::",
name);
}
- attr = dwarf_attr (die, DW_AT_const_value);
+ attr = dwarf2_attr (die, DW_AT_const_value, cu);
if (attr)
{
dwarf2_const_value (attr, sym, cu);
struct pending **list_to_add;
- list_to_add = (list_in_scope == &file_symbols
- && cu_language == language_cplus
- ? &global_symbols : list_in_scope);
+ list_to_add = (cu->list_in_scope == &file_symbols
+ && cu->language == language_cplus
+ ? &global_symbols : cu->list_in_scope);
add_symbol_to_list (sym, list_to_add);
}
TYPE_LENGTH (SYMBOL_TYPE
(sym)));
SYMBOL_VALUE_BYTES (sym) = (char *)
- obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size);
+ obstack_alloc (&objfile->objfile_obstack, cu_header->addr_size);
/* 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,
TYPE_LENGTH (SYMBOL_TYPE
(sym)));
SYMBOL_VALUE_BYTES (sym) = (char *)
- obstack_alloc (&objfile->symbol_obstack, blk->size);
+ obstack_alloc (&objfile->objfile_obstack, blk->size);
memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size);
SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
break;
struct die_info *type_die;
unsigned int ref;
- type_attr = dwarf_attr (die, DW_AT_type);
+ type_attr = dwarf2_attr (die, DW_AT_type, cu);
if (!type_attr)
{
/* A missing DW_AT_type represents a void type. */
- return dwarf2_fundamental_type (cu->objfile, FT_VOID);
+ return dwarf2_fundamental_type (cu->objfile, FT_VOID, cu);
}
else
{
- ref = dwarf2_get_ref_die_offset (type_attr);
+ ref = dwarf2_get_ref_die_offset (type_attr, cu);
type_die = follow_die_ref (ref);
if (!type_die)
{
struct die_info *type_die = NULL;
unsigned int ref;
- type_attr = dwarf_attr (die, DW_AT_containing_type);
+ type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
if (type_attr)
{
- ref = dwarf2_get_ref_die_offset (type_attr);
+ ref = dwarf2_get_ref_die_offset (type_attr, cu);
type_die = follow_die_ref (ref);
if (!type_die)
{
static void
read_type_die (struct die_info *die, struct dwarf2_cu *cu)
{
- char *prefix = determine_prefix (die);
+ char *prefix = determine_prefix (die, cu);
const char *old_prefix = processing_current_prefix;
struct cleanup *back_to = make_cleanup (xfree, prefix);
processing_current_prefix = prefix;
case DW_TAG_class_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
- read_structure_scope (die, cu);
+ read_structure_type (die, cu);
break;
case DW_TAG_enumeration_type:
- read_enumeration (die, cu);
+ read_enumeration_type (die, cu);
break;
case DW_TAG_subprogram:
case DW_TAG_subroutine_type:
do_cleanups (back_to);
}
-/* Return the name of the namespace/class that DIE is defined
- within, or NULL if we can't tell. The caller should xfree the
- result. */
+/* Return the name of the namespace/class that DIE is defined within,
+ or "" if we can't tell. The caller should xfree the result. */
+
+/* NOTE: carlton/2004-01-23: See read_func_scope (and the comment
+ therein) for an example of how to use this function to deal with
+ DW_AT_specification. */
static char *
-determine_prefix (struct die_info *die)
+determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
{
struct die_info *parent;
- if (cu_language != language_cplus)
+ if (cu->language != language_cplus)
return NULL;
parent = die->parent;
if (parent == NULL)
{
- return (processing_has_namespace_info ? xstrdup ("") : NULL);
+ return xstrdup ("");
}
else
{
- char *parent_prefix = determine_prefix (parent);
- char *retval;
-
switch (parent->tag) {
case DW_TAG_namespace:
{
- int dummy;
-
- retval = typename_concat (parent_prefix,
- namespace_name (parent, &dummy));
+ /* FIXME: carlton/2004-03-05: Should I follow extension dies
+ before doing this check? */
+ if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
+ {
+ return xstrdup (TYPE_TAG_NAME (parent->type));
+ }
+ else
+ {
+ int dummy;
+ char *parent_prefix = determine_prefix (parent, cu);
+ char *retval = typename_concat (parent_prefix,
+ namespace_name (parent, &dummy,
+ cu));
+ xfree (parent_prefix);
+ return retval;
+ }
}
break;
case DW_TAG_class_type:
case DW_TAG_structure_type:
{
- if (parent_prefix != NULL)
+ if (parent->type != NULL && TYPE_TAG_NAME (parent->type) != NULL)
{
- const char *parent_name = dwarf2_name (parent);
-
- if (parent_name != NULL)
- retval = typename_concat (parent_prefix, dwarf2_name (parent));
- else
- /* FIXME: carlton/2003-11-10: I'm not sure what the
- best thing to do here is. */
- retval = typename_concat (parent_prefix,
- "<<anonymous class>>");
+ return xstrdup (TYPE_TAG_NAME (parent->type));
}
else
- retval = class_name (parent);
+ {
+ const char *old_prefix = processing_current_prefix;
+ char *new_prefix = determine_prefix (parent, cu);
+ char *retval;
+
+ processing_current_prefix = new_prefix;
+ retval = determine_class_name (parent, cu);
+ processing_current_prefix = old_prefix;
+
+ xfree (new_prefix);
+ return retval;
+ }
}
- break;
default:
- retval = parent_prefix;
- break;
+ return determine_prefix (parent, cu);
}
-
- if (retval != parent_prefix)
- xfree (parent_prefix);
- return retval;
}
}
}
}
-/* Return a newly-allocated string giving the name of the class given
- by DIE. */
-
-static char *
-class_name (struct die_info *die)
-{
- struct die_info *child;
- const char *name;
-
- for (child = die->child; child != NULL; child = sibling_die (child))
- {
- if (child->tag == DW_TAG_subprogram)
- return class_name_from_physname (dwarf2_linkage_name (child));
- }
-
- name = dwarf2_name (die);
- if (name != NULL)
- return xstrdup (name);
- else
- return xstrdup ("");
-}
-
static struct type *
dwarf_base_type (int encoding, int size, struct dwarf2_cu *cu)
{
switch (encoding)
{
case DW_ATE_address:
- type = dwarf2_fundamental_type (objfile, FT_VOID);
+ type = dwarf2_fundamental_type (objfile, FT_VOID, cu);
return type;
case DW_ATE_boolean:
- type = dwarf2_fundamental_type (objfile, FT_BOOLEAN);
+ type = dwarf2_fundamental_type (objfile, FT_BOOLEAN, cu);
return type;
case DW_ATE_complex_float:
if (size == 16)
{
- type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX);
+ type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_COMPLEX, cu);
}
else
{
- type = dwarf2_fundamental_type (objfile, FT_COMPLEX);
+ type = dwarf2_fundamental_type (objfile, FT_COMPLEX, cu);
}
return type;
case DW_ATE_float:
if (size == 8)
{
- type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+ type = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT, cu);
}
else
{
- type = dwarf2_fundamental_type (objfile, FT_FLOAT);
+ type = dwarf2_fundamental_type (objfile, FT_FLOAT, cu);
}
return type;
case DW_ATE_signed:
switch (size)
{
case 1:
- type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu);
break;
case 2:
- type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT);
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_SHORT, cu);
break;
default:
case 4:
- type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu);
break;
}
return type;
case DW_ATE_signed_char:
- type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR);
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_CHAR, cu);
return type;
case DW_ATE_unsigned:
switch (size)
{
case 1:
- type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu);
break;
case 2:
- type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT);
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_SHORT, cu);
break;
default:
case 4:
- type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER);
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_INTEGER, cu);
break;
}
return type;
case DW_ATE_unsigned_char:
- type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR);
+ type = dwarf2_fundamental_type (objfile, FT_UNSIGNED_CHAR, cu);
return type;
default:
- type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER);
+ type = dwarf2_fundamental_type (objfile, FT_SIGNED_INTEGER, cu);
return type;
}
}
/* Get linkage name of a die, return NULL if not found. */
static char *
-dwarf2_linkage_name (struct die_info *die)
+dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
- attr = dwarf_attr (die, DW_AT_MIPS_linkage_name);
+ attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
if (attr && DW_STRING (attr))
return DW_STRING (attr);
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
return DW_STRING (attr);
return NULL;
/* Get name of a die, return NULL if not found. */
static char *
-dwarf2_name (struct die_info *die)
+dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
- attr = dwarf_attr (die, DW_AT_name);
+ attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
return DW_STRING (attr);
return NULL;
is none. */
static struct die_info *
-dwarf2_extension (struct die_info *die)
+dwarf2_extension (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
struct die_info *extension_die;
unsigned int ref;
- attr = dwarf_attr (die, DW_AT_extension);
+ attr = dwarf2_attr (die, DW_AT_extension, cu);
if (attr == NULL)
return NULL;
- ref = dwarf2_get_ref_die_offset (attr);
+ ref = dwarf2_get_ref_die_offset (attr, cu);
extension_die = follow_die_ref (ref);
if (!extension_die)
{
}
static unsigned int
-dwarf2_get_ref_die_offset (struct attribute *attr)
+dwarf2_get_ref_die_offset (struct attribute *attr, struct dwarf2_cu *cu)
{
unsigned int result = 0;
case DW_FORM_ref4:
case DW_FORM_ref8:
case DW_FORM_ref_udata:
- result = cu_header_offset + DW_UNSND (attr);
+ result = cu->header.offset + DW_UNSND (attr);
break;
default:
complaint (&symfile_complaints,
}
static struct type *
-dwarf2_fundamental_type (struct objfile *objfile, int typeid)
+dwarf2_fundamental_type (struct objfile *objfile, int typeid,
+ struct dwarf2_cu *cu)
{
if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
{
one is not found, create and install one appropriate for the
current language and the current target machine. */
- if (ftypes[typeid] == NULL)
+ if (cu->ftypes[typeid] == NULL)
{
- ftypes[typeid] = cu_language_defn->la_fund_type (objfile, typeid);
+ cu->ftypes[typeid] = cu->language_defn->la_fund_type (objfile, typeid);
}
- return (ftypes[typeid]);
+ return (cu->ftypes[typeid]);
}
/* Decode simple location descriptions.
}
static struct abbrev_info *
-dwarf_alloc_abbrev (void)
+dwarf_alloc_abbrev (struct dwarf2_cu *cu)
{
struct abbrev_info *abbrev;
- abbrev = (struct abbrev_info *) xmalloc (sizeof (struct abbrev_info));
+ abbrev = (struct abbrev_info *)
+ obstack_alloc (&cu->abbrev_obstack, sizeof (struct abbrev_info));
memset (abbrev, 0, sizeof (struct abbrev_info));
return (abbrev);
}
/* We don't create a macro table for this compilation unit
at all until we actually get a filename. */
if (! pending_macros)
- pending_macros = new_macro_table (&objfile->symbol_obstack,
+ pending_macros = new_macro_table (&objfile->objfile_obstack,
objfile->macro_cache);
if (! current_file)
{
struct dwarf2_loclist_baton *baton;
- baton = obstack_alloc (&cu->objfile->symbol_obstack,
+ baton = obstack_alloc (&cu->objfile->objfile_obstack,
sizeof (struct dwarf2_loclist_baton));
baton->objfile = cu->objfile;
complaint (&symfile_complaints,
"Location list used without specifying the CU base address.");
- SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_loclist_funcs;
+ SYMBOL_OPS (sym) = &dwarf2_loclist_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
else
{
struct dwarf2_locexpr_baton *baton;
- baton = obstack_alloc (&cu->objfile->symbol_obstack,
+ baton = obstack_alloc (&cu->objfile->objfile_obstack,
sizeof (struct dwarf2_locexpr_baton));
baton->objfile = cu->objfile;
baton->data = NULL;
}
- SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs;
+ SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
}