should be moved to the dwarf2_cu structure; for instance the abbrevs
hash table. */
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 */
};
/* The line number information for a compilation unit (found in the
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
#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. */
/* Various complaints about symbol reading that don't abort the process */
-static void
-dwarf2_non_const_array_bound_ignored_complaint (const char *arg1)
-{
- complaint (&symfile_complaints, "non-constant array bounds form '%s' ignored",
- arg1);
-}
-
static void
dwarf2_statement_list_fits_in_line_number_section_complaint (void)
{
static long read_signed_leb128 (bfd *, char *, unsigned int *);
-static void set_cu_language (unsigned int);
+static void set_cu_language (unsigned int, struct dwarf2_cu *);
-static struct attribute *dwarf_attr (struct die_info *, unsigned int);
+static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
+ struct dwarf2_cu *);
-static int die_is_declaration (struct die_info *);
+static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu);
-static struct die_info *die_specification (struct die_info *die);
+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 *determine_prefix_aux (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 char *class_name (struct die_info *die, 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 int dwarf2_get_pc_bounds (struct die_info *,
CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *);
+static void get_scope_pc_bounds (struct die_info *,
+ CORE_ADDR *, CORE_ADDR *,
+ struct dwarf2_cu *);
+
static void dwarf2_add_field (struct field_info *, 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 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 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 *);
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;
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);
&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,
pst->read_symtab_private = (char *)
obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo));
- cu_header_offset = beg_of_comp_unit - dwarf_info_buffer;
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;
}
break;
case DW_TAG_base_type:
+ case DW_TAG_subrange_type:
/* File scope base type definitions are added to the partial
symbol table. */
add_partial_symbol (&pdi, cu, namespace);
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:
case DW_TAG_base_type:
+ case DW_TAG_subrange_type:
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
+ cu->language == language_cplus
? &objfile->static_psymbols
: &objfile->global_psymbols,
- 0, (CORE_ADDR) 0, cu_language, objfile);
+ 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. */
could fix this by only using the demangled name to get the
prefix (but see comment in read_structure_scope). */
+ /* 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;
while (1)
}
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);
}
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 = "";
dwarf2_read_abbrevs (abfd, &cu);
make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs);
+ cu.header.offset = offset;
+
+ cu.list_in_scope = &file_symbols;
+
dies = read_comp_unit (info_ptr, abfd, &cu);
make_cleanup_free_die_list (dies);
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);
/* Do line number decoding in read_file_scope () */
process_die (dies, &cu);
- if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, &cu))
- {
- /* Some compilers don't define a DW_AT_high_pc attribute for
- the compilation unit. If the DW_AT_high_pc is missing,
- synthesize it, by scanning the DIE's below the compilation unit. */
- highpc = 0;
- if (dies->child != NULL)
- {
- child_die = dies->child;
- while (child_die && child_die->tag)
- {
- if (child_die->tag == DW_TAG_subprogram)
- {
- CORE_ADDR low, high;
+ /* Some compilers don't define a DW_AT_high_pc attribute for the
+ compilation unit. If the DW_AT_high_pc is missing, synthesize
+ it, by scanning the DIE's below the compilation unit. */
+ get_scope_pc_bounds (dies, &lowpc, &highpc, &cu);
- if (dwarf2_get_pc_bounds (child_die, &low, &high, &cu))
- {
- highpc = max (highpc, high);
- }
- }
- child_die = sibling_die (child_die);
- }
- }
- }
symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
/* Set symtab language to language from DW_AT_language.
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;
break;
case DW_TAG_base_type:
read_base_type (die, cu);
- if (dwarf_attr (die, DW_AT_name))
+ if (dwarf2_attr (die, DW_AT_name, cu))
{
/* Add a typedef symbol for the base type definition. */
new_symbol (die, die->type, cu);
}
break;
+ case DW_TAG_subrange_type:
+ read_subrange_type (die, cu);
+ if (dwarf2_attr (die, DW_AT_name, cu))
+ {
+ /* Add a typedef symbol for the base type definition. */
+ new_symbol (die, die->type, cu);
+ }
+ break;
case DW_TAG_common_block:
read_common_block (die, cu);
break;
}
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));
- if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
- {
- if (die->child != NULL)
- {
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- if (child_die->tag == DW_TAG_subprogram)
- {
- CORE_ADDR low, high;
-
- if (dwarf2_get_pc_bounds (child_die, &low, &high, cu))
- {
- lowpc = min (lowpc, low);
- highpc = max (highpc, high);
- }
- }
- child_die = sibling_die (child_die);
- }
- }
- }
+ get_scope_pc_bounds (die, &lowpc, &highpc, cu);
/* If we didn't find a lowpc, set it to highpc to avoid complaints
from finish_block. */
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;
return ret;
}
+/* Get the low and high pc's represented by the scope DIE, and store
+ them in *LOWPC and *HIGHPC. If the correct values can't be
+ determined, set *LOWPC to -1 and *HIGHPC to 0. */
+
+static void
+get_scope_pc_bounds (struct die_info *die,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ struct dwarf2_cu *cu)
+{
+ CORE_ADDR best_low = (CORE_ADDR) -1;
+ CORE_ADDR best_high = (CORE_ADDR) 0;
+ CORE_ADDR current_low, current_high;
+
+ if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu))
+ {
+ best_low = current_low;
+ best_high = current_high;
+ }
+ else
+ {
+ struct die_info *child = die->child;
+
+ while (child && child->tag)
+ {
+ switch (child->tag) {
+ case DW_TAG_subprogram:
+ if (dwarf2_get_pc_bounds (child, ¤t_low, ¤t_high, cu))
+ {
+ best_low = min (best_low, current_low);
+ best_high = max (best_high, current_high);
+ }
+ break;
+ case DW_TAG_namespace:
+ /* FIXME: carlton/2004-01-16: Should we do this for
+ DW_TAG_class_type/DW_TAG_structure_type, too? I think
+ that current GCC's always emit the DIEs corresponding
+ to definitions of methods of classes as children of a
+ DW_TAG_compile_unit or DW_TAG_namespace (as opposed to
+ the DIEs giving the declarations, which could be
+ anywhere). But I don't see any reason why the
+ standards says that they have to be there. */
+ get_scope_pc_bounds (child, ¤t_low, ¤t_high, cu);
+
+ if (current_low != ((CORE_ADDR) -1))
+ {
+ best_low = min (best_low, current_low);
+ best_high = max (best_high, current_high);
+ }
+ break;
+ default:
+ /* Ignore. */
+ break;
+ }
+
+ child = sibling_die (child);
+ }
+ }
+
+ *lowpc = best_low;
+ *highpc = best_high;
+}
+
/* Add an aggregate field to the field list. */
static void
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),
/* 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));
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++)
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 */
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);
+ struct die_info *spec_die = die_specification (die, cu);
if (spec_die != NULL)
{
- char *specification_prefix = determine_prefix (spec_die);
+ char *specification_prefix = determine_prefix (spec_die, cu);
processing_current_prefix = specification_prefix;
back_to = make_cleanup (xfree, specification_prefix);
}
{
TYPE_TAG_NAME (type) = obsavestring (name, strlen (name),
&objfile->type_obstack);
- need_to_update_name = (cu_language == language_cplus);
+ need_to_update_name = (cu->language == language_cplus);
}
}
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;
name. */
char *actual_class_name
= class_name_from_physname (dwarf2_linkage_name
- (child_die));
+ (child_die, cu));
if (actual_class_name != NULL
&& strcmp (actual_class_name, name) != 0)
{
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);
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);
}
}
- 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);
}
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);
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;
{
if (child_die->tag == DW_TAG_subrange_type)
{
- unsigned int low, high;
-
- /* Default bounds to an array with unspecified length. */
- low = 0;
- high = -1;
- if (cu_language == language_fortran)
- {
- /* FORTRAN implies a lower bound of 1, if not given. */
- low = 1;
- }
+ read_subrange_type (child_die, cu);
- index_type = die_type (child_die, cu);
- attr = dwarf_attr (child_die, DW_AT_lower_bound);
- if (attr)
- {
- if (attr->form == DW_FORM_sdata)
- {
- low = DW_SND (attr);
- }
- else if (attr->form == DW_FORM_udata
- || attr->form == DW_FORM_data1
- || attr->form == DW_FORM_data2
- || attr->form == DW_FORM_data4
- || attr->form == DW_FORM_data8)
- {
- low = DW_UNSND (attr);
- }
- else
- {
- dwarf2_non_const_array_bound_ignored_complaint
- (dwarf_form_name (attr->form));
- low = 0;
- }
- }
- attr = dwarf_attr (child_die, DW_AT_upper_bound);
- if (attr)
- {
- if (attr->form == DW_FORM_sdata)
- {
- high = DW_SND (attr);
- }
- else if (attr->form == DW_FORM_udata
- || attr->form == DW_FORM_data1
- || attr->form == DW_FORM_data2
- || attr->form == DW_FORM_data4
- || attr->form == DW_FORM_data8)
- {
- high = DW_UNSND (attr);
- }
- else if (attr->form == DW_FORM_block1)
- {
- /* GCC encodes arrays with unspecified or dynamic length
- with a DW_FORM_block1 attribute.
- FIXME: GDB does not yet know how to handle dynamic
- arrays properly, treat them as arrays with unspecified
- length for now.
-
- FIXME: jimb/2003-09-22: GDB does not really know
- how to handle arrays of unspecified length
- either; we just represent them as zero-length
- arrays. Choose an appropriate upper bound given
- the lower bound we've computed above. */
- high = low - 1;
- }
- else
- {
- dwarf2_non_const_array_bound_ignored_complaint
- (dwarf_form_name (attr->form));
- high = 1;
- }
- }
-
- /* Create a range type and save it for array type creation. */
- if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
- {
- range_types = (struct type **)
- xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
- * sizeof (struct type *));
- if (ndim == 0)
- make_cleanup (free_current_contents, &range_types);
- }
- range_types[ndim++] = create_range_type (NULL, index_type, low, high);
+ if (child_die->type != NULL)
+ {
+ /* The range type was succesfully read. Save it for
+ the array type creation. */
+ if ((ndim % DW_FIELD_ALLOC_CHUNK) == 0)
+ {
+ range_types = (struct type **)
+ xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK)
+ * sizeof (struct type *));
+ if (ndim == 0)
+ make_cleanup (free_current_contents, &range_types);
+ }
+ range_types[ndim++] = child_die->type;
+ }
}
child_die = sibling_die (child_die);
}
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;
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
die->type = type;
}
+/* Read the given DW_AT_subrange DIE. */
+
+static void
+read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct type *base_type;
+ struct type *range_type;
+ struct attribute *attr;
+ int low = 0;
+ int high = -1;
+
+ /* If we have already decoded this die, then nothing more to do. */
+ if (die->type)
+ return;
+
+ base_type = die_type (die, cu);
+ if (base_type == NULL)
+ {
+ complaint (&symfile_complaints,
+ "DW_AT_type missing from DW_TAG_subrange_type");
+ return;
+ }
+
+ if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
+ base_type = alloc_type (NULL);
+
+ if (cu->language == language_fortran)
+ {
+ /* FORTRAN implies a lower bound of 1, if not given. */
+ low = 1;
+ }
+
+ attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
+ if (attr)
+ low = dwarf2_get_attr_constant_value (attr, 0);
+
+ attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
+ if (attr)
+ {
+ if (attr->form == DW_FORM_block1)
+ {
+ /* GCC encodes arrays with unspecified or dynamic length
+ with a DW_FORM_block1 attribute.
+ FIXME: GDB does not yet know how to handle dynamic
+ arrays properly, treat them as arrays with unspecified
+ length for now.
+
+ FIXME: jimb/2003-09-22: GDB does not really know
+ how to handle arrays of unspecified length
+ either; we just represent them as zero-length
+ arrays. Choose an appropriate upper bound given
+ the lower bound we've computed above. */
+ high = low - 1;
+ }
+ else
+ high = dwarf2_get_attr_constant_value (attr, 1);
+ }
+
+ range_type = create_range_type (NULL, base_type, low, high);
+
+ attr = dwarf2_attr (die, DW_AT_name, cu);
+ if (attr && DW_STRING (attr))
+ TYPE_NAME (range_type) = DW_STRING (attr);
+
+ attr = dwarf2_attr (die, DW_AT_byte_size, cu);
+ if (attr)
+ TYPE_LENGTH (range_type) = DW_UNSND (attr);
+
+ die->type = range_type;
+}
+
+
/* Read a whole compilation unit into a linked list of dies. */
static struct die_info *
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)
{
}
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);
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
read_structure_scope, 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);
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,
}
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
"::",
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);
}
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_typedef:
read_typedef (die, cu);
break;
+ case DW_TAG_subrange_type:
+ read_subrange_type (die, cu);
+ break;
case DW_TAG_base_type:
read_base_type (die, cu);
break;
do_cleanups (back_to);
}
+/* 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, struct dwarf2_cu *cu)
+{
+ char *prefix = determine_prefix_aux (die, cu);
+
+ return prefix ? prefix : xstrdup ("");
+}
+
/* 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. */
static char *
-determine_prefix (struct die_info *die)
+determine_prefix_aux (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;
}
else
{
- char *parent_prefix = determine_prefix (parent);
+ char *parent_prefix = determine_prefix_aux (parent, cu);
char *retval;
switch (parent->tag) {
int dummy;
retval = typename_concat (parent_prefix,
- namespace_name (parent, &dummy));
+ namespace_name (parent, &dummy, cu));
}
break;
case DW_TAG_class_type:
{
if (parent_prefix != NULL)
{
- const char *parent_name = dwarf2_name (parent);
+ const char *parent_name = dwarf2_name (parent, cu);
if (parent_name != NULL)
- retval = typename_concat (parent_prefix, dwarf2_name (parent));
+ retval = typename_concat (parent_prefix, dwarf2_name (parent, cu));
else
/* FIXME: carlton/2003-11-10: I'm not sure what the
best thing to do here is. */
"<<anonymous class>>");
}
else
- retval = class_name (parent);
+ retval = class_name (parent, cu);
}
break;
default:
by DIE. */
static char *
-class_name (struct die_info *die)
+class_name (struct die_info *die, struct dwarf2_cu *cu)
{
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));
+ return class_name_from_physname (dwarf2_linkage_name (child, cu));
}
- name = dwarf2_name (die);
+ name = dwarf2_name (die, cu);
if (name != NULL)
return xstrdup (name);
else
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,
return result;
}
+/* Return the constant value held by the given attribute. Return -1
+ if the value held by the attribute is not constant. */
+
+static int
+dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
+{
+ if (attr->form == DW_FORM_sdata)
+ return DW_SND (attr);
+ else if (attr->form == DW_FORM_udata
+ || attr->form == DW_FORM_data1
+ || attr->form == DW_FORM_data2
+ || attr->form == DW_FORM_data4
+ || attr->form == DW_FORM_data8)
+ return DW_UNSND (attr);
+ else
+ {
+ complaint (&symfile_complaints, "Attribute value is not a constant (%s)",
+ dwarf_form_name (attr->form));
+ return default_value;
+ }
+}
+
static struct die_info *
follow_die_ref (unsigned int offset)
{
}
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.
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
baton->data = NULL;
}
- SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs;
+ SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
}
}