X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=ffc76c85875afd285c1cd0400d12f980c3553c93;hb=57adceea83e0151a5eafc4e6f670c5606053ac44;hp=8edbd869669292e99c2322caf806ba8acb566729;hpb=57349743d5a73b60ce32e5aa38ad3ebc0b361e8a;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 8edbd86966..ffc76c8587 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1,5 +1,6 @@ /* DWARF 2 debugging format support for GDB. - Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, + 2004 Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, @@ -30,7 +31,6 @@ #include "bfd.h" #include "symtab.h" #include "gdbtypes.h" -#include "symfile.h" #include "objfiles.h" #include "elf/dwarf2.h" #include "buildsym.h" @@ -38,15 +38,32 @@ #include "expression.h" #include "filenames.h" /* for DOSish file names */ #include "macrotab.h" - #include "language.h" #include "complaints.h" #include "bcache.h" +#include "dwarf2expr.h" +#include "dwarf2loc.h" +#include "cp-support.h" + #include #include "gdb_string.h" #include "gdb_assert.h" #include +/* 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 @@ -125,17 +142,6 @@ _STATEMENT_PROLOGUE; /* offsets and sizes of debugging sections */ -static file_ptr dwarf_info_offset; -static file_ptr dwarf_abbrev_offset; -static file_ptr dwarf_line_offset; -static file_ptr dwarf_pubnames_offset; -static file_ptr dwarf_aranges_offset; -static file_ptr dwarf_loc_offset; -static file_ptr dwarf_macinfo_offset; -static file_ptr dwarf_str_offset; -file_ptr dwarf_frame_offset; -file_ptr dwarf_eh_frame_offset; - static unsigned int dwarf_info_size; static unsigned int dwarf_abbrev_size; static unsigned int dwarf_line_size; @@ -144,9 +150,22 @@ static unsigned int dwarf_aranges_size; static unsigned int dwarf_loc_size; static unsigned int dwarf_macinfo_size; static unsigned int dwarf_str_size; +static unsigned int dwarf_ranges_size; unsigned int dwarf_frame_size; unsigned int dwarf_eh_frame_size; +static asection *dwarf_info_section; +static asection *dwarf_abbrev_section; +static asection *dwarf_line_section; +static asection *dwarf_pubnames_section; +static asection *dwarf_aranges_section; +static asection *dwarf_loc_section; +static asection *dwarf_macinfo_section; +static asection *dwarf_str_section; +static asection *dwarf_ranges_section; +asection *dwarf_frame_section; +asection *dwarf_eh_frame_section; + /* names of the debugging sections */ #define INFO_SECTION ".debug_info" @@ -157,6 +176,7 @@ unsigned int dwarf_eh_frame_size; #define LOC_SECTION ".debug_loc" #define MACINFO_SECTION ".debug_macinfo" #define STR_SECTION ".debug_str" +#define RANGES_SECTION ".debug_ranges" #define FRAME_SECTION ".debug_frame" #define EH_FRAME_SECTION ".eh_frame" @@ -199,11 +219,62 @@ struct comp_unit_head struct comp_unit_head *next; - /* DWARF abbreviation table associated with this compilation unit */ + /* Base address of this compilation unit. */ + + CORE_ADDR base_address; + + /* Non-zero if base_address has been set. */ - struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE]; + int base_known; }; +/* Internal state when decoding a particular compilation unit. */ +struct dwarf2_cu +{ + /* The objfile containing this compilation unit. */ + struct objfile *objfile; + + /* The header of the compilation unit. + + FIXME drow/2003-11-10: Some of the things from the comp_unit_head + 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_ 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 .debug_line section) begins with a "statement program header", which contains the following information. */ @@ -273,8 +344,8 @@ struct abbrev_info { 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 */ }; @@ -289,13 +360,21 @@ struct attr_abbrev struct die_info { enum dwarf_tag tag; /* Tag indicating type of die */ - unsigned short has_children; /* Does the die have children */ unsigned int abbrev; /* Abbrev number */ unsigned int offset; /* Offset in .debug_info section */ unsigned int num_attrs; /* Number of attributes */ struct attribute *attrs; /* An array of attributes */ struct die_info *next_ref; /* Next die in ref hash table */ - struct die_info *next; /* Next die in linked list */ + + /* The dies in a compilation unit form an n-ary tree. PARENT + points to this die's parent; CHILD points to the first child of + this node; and all the children of a given node are chained + together via their SIBLING fields, terminated by a die whose + tag is zero. */ + struct die_info *child; /* Its first child, if any. */ + struct die_info *sibling; /* Its next sibling, if any. */ + struct die_info *parent; /* Its parent, if any. */ + struct type *type; /* Cached type information */ }; @@ -323,8 +402,6 @@ struct function_range 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) @@ -354,84 +431,39 @@ static struct die_info *die_ref_table[REF_HASH_SIZE]; /* 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; static char *dwarf_line_buffer; static char *dwarf_str_buffer; static char *dwarf_macinfo_buffer; +static char *dwarf_ranges_buffer; +static char *dwarf_loc_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 by decode_locdesc. */ -static int optimized_out; /* No ops in location in expression, - so object was optimized out. */ static int isreg; /* Object lives in register. decode_locdesc's return value is the register number. */ -static int offreg; /* Object's address is the sum of the - register specified by basereg, plus - the offset returned. */ -static int basereg; /* See `offreg'. */ -static int isderef; /* Value described by flags above is - the address of a pointer to the object. */ -static int islocal; /* Variable is at the returned offset - from the frame start, but there's - no identified frame pointer for - this function, so we can't say - which register it's relative to; - use LOC_LOCAL. */ - -/* DW_AT_frame_base values for the current function. - frame_base_reg is -1 if DW_AT_frame_base is missing, otherwise it - contains the register number for the frame register. - frame_base_offset is the offset from the frame register to the - virtual stack frame. */ -static int frame_base_reg; -static CORE_ADDR frame_base_offset; - -/* 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 { @@ -475,6 +507,21 @@ struct dwarf2_pinfo unsigned int dwarf_macinfo_size; + /* Pointer to start of dwarf ranges buffer for the objfile. */ + + char *dwarf_ranges_buffer; + + /* Size of dwarf ranges buffer for the objfile. */ + + unsigned int dwarf_ranges_size; + + /* Pointer to start of dwarf locations buffer for the objfile. */ + + char *dwarf_loc_buffer; + + /* Size of dwarf locations buffer for the objfile. */ + + unsigned int dwarf_loc_size; }; #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private) @@ -488,17 +535,10 @@ struct dwarf2_pinfo #define DWARF_STR_SIZE(p) (PST_PRIVATE(p)->dwarf_str_size) #define DWARF_MACINFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_macinfo_buffer) #define DWARF_MACINFO_SIZE(p) (PST_PRIVATE(p)->dwarf_macinfo_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_ 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 */ +#define DWARF_RANGES_BUFFER(p) (PST_PRIVATE(p)->dwarf_ranges_buffer) +#define DWARF_RANGES_SIZE(p) (PST_PRIVATE(p)->dwarf_ranges_size) +#define DWARF_LOC_BUFFER(p) (PST_PRIVATE(p)->dwarf_loc_buffer) +#define DWARF_LOC_SIZE(p) (PST_PRIVATE(p)->dwarf_loc_size) /* 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 @@ -555,138 +595,53 @@ struct field_info /* Various complaints about symbol reading that don't abort the process */ -static struct complaint dwarf2_const_ignored = -{ - "type qualifier 'const' ignored", 0, 0 -}; -static struct complaint dwarf2_volatile_ignored = -{ - "type qualifier 'volatile' ignored", 0, 0 -}; -static struct complaint dwarf2_non_const_array_bound_ignored = -{ - "non-constant array bounds form '%s' ignored", 0, 0 -}; -static struct complaint dwarf2_missing_line_number_section = -{ - "missing .debug_line section", 0, 0 -}; -static struct complaint dwarf2_statement_list_fits_in_line_number_section = -{ - "statement list doesn't fit in .debug_line section", 0, 0 -}; -static struct complaint dwarf2_mangled_line_number_section = -{ - "mangled .debug_line section", 0, 0 -}; -static struct complaint dwarf2_unsupported_die_ref_attr = -{ - "unsupported die ref attribute form: '%s'", 0, 0 -}; -static struct complaint dwarf2_unsupported_stack_op = -{ - "unsupported stack op: '%s'", 0, 0 -}; -static struct complaint dwarf2_complex_location_expr = -{ - "location expression too complex", 0, 0 -}; -static struct complaint dwarf2_unsupported_tag = -{ - "unsupported tag: '%s'", 0, 0 -}; -static struct complaint dwarf2_unsupported_at_encoding = -{ - "unsupported DW_AT_encoding: '%s'", 0, 0 -}; -static struct complaint dwarf2_unsupported_at_frame_base = -{ - "unsupported DW_AT_frame_base for function '%s'", 0, 0 -}; -static struct complaint dwarf2_unexpected_tag = -{ - "unexepected tag in read_type_die: '%s'", 0, 0 -}; -static struct complaint dwarf2_missing_at_frame_base = -{ - "DW_AT_frame_base missing for DW_OP_fbreg", 0, 0 -}; -static struct complaint dwarf2_bad_static_member_name = -{ - "unrecognized static data member name '%s'", 0, 0 -}; -static struct complaint dwarf2_unsupported_accessibility = -{ - "unsupported accessibility %d", 0, 0 -}; -static struct complaint dwarf2_bad_member_name_complaint = -{ - "cannot extract member name from '%s'", 0, 0 -}; -static struct complaint dwarf2_missing_member_fn_type_complaint = -{ - "member function type missing for '%s'", 0, 0 -}; -static struct complaint dwarf2_vtbl_not_found_complaint = -{ - "virtual function table pointer not found when defining class '%s'", 0, 0 -}; -static struct complaint dwarf2_absolute_sibling_complaint = -{ - "ignoring absolute DW_AT_sibling", 0, 0 -}; -static struct complaint dwarf2_const_value_length_mismatch = -{ - "const value length mismatch for '%s', got %d, expected %d", 0, 0 -}; -static struct complaint dwarf2_unsupported_const_value_attr = -{ - "unsupported const value attribute form: '%s'", 0, 0 -}; -static struct complaint dwarf2_misplaced_line_number = -{ - "misplaced first line number at 0x%lx for '%s'", 0, 0 -}; -static struct complaint dwarf2_line_header_too_long = -{ - "line number info header doesn't fit in `.debug_line' section", 0, 0 -}; -static struct complaint dwarf2_missing_macinfo_section = -{ - "missing .debug_macinfo section", 0, 0 -}; -static struct complaint dwarf2_macros_too_long = -{ - "macro info runs off end of `.debug_macinfo' section", 0, 0 -}; -static struct complaint dwarf2_macros_not_terminated = +static void +dwarf2_statement_list_fits_in_line_number_section_complaint (void) { - "no terminating 0-type entry for macros in `.debug_macinfo' section", 0, 0 -}; -static struct complaint dwarf2_macro_outside_file = + complaint (&symfile_complaints, + "statement list doesn't fit in .debug_line section"); +} + +static void +dwarf2_complex_location_expr_complaint (void) { - "debug info gives macro %s outside of any file: %s", 0, 0 -}; -static struct complaint dwarf2_macro_unmatched_end_file = + complaint (&symfile_complaints, "location expression too complex"); +} + +static void +dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2, + int arg3) { - "macro debug info has an unmatched `close_file' directive", 0, 0 -}; -static struct complaint dwarf2_macro_malformed_definition = + complaint (&symfile_complaints, + "const value length mismatch for '%s', got %d, expected %d", arg1, + arg2, arg3); +} + +static void +dwarf2_macros_too_long_complaint (void) { - "macro debug info contains a malformed macro definition:\n`%s'", 0, 0 -}; -static struct complaint dwarf2_macro_spaces_in_definition = + complaint (&symfile_complaints, + "macro info runs off end of `.debug_macinfo' section"); +} + +static void +dwarf2_macro_malformed_definition_complaint (const char *arg1) { - "macro definition contains spaces in formal argument list:\n`%s'", 0, 0 -}; -static struct complaint dwarf2_invalid_attrib_class = + complaint (&symfile_complaints, + "macro debug info contains a malformed macro definition:\n`%s'", + arg1); +} + +static void +dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2) { - "invalid attribute class or form for '%s' in '%s'", 0, 0 -}; + complaint (&symfile_complaints, + "invalid attribute class or form for '%s' in '%s'", arg1, arg2); +} /* local function prototypes */ -static void dwarf2_locate_sections (bfd *, asection *, PTR); +static void dwarf2_locate_sections (bfd *, asection *, void *); #if 0 static void dwarf2_build_psymtabs_easy (struct objfile *, int); @@ -694,38 +649,60 @@ static void dwarf2_build_psymtabs_easy (struct objfile *, int); static void dwarf2_build_psymtabs_hard (struct objfile *, int); -static char *scan_partial_symbols (char *, struct objfile *, - CORE_ADDR *, CORE_ADDR *, - const struct comp_unit_head *); +static char *scan_partial_symbols (char *, CORE_ADDR *, CORE_ADDR *, + struct dwarf2_cu *, + const char *namespace); + +static void add_partial_symbol (struct partial_die_info *, struct dwarf2_cu *, + const char *namespace); + +static int pdi_needs_namespace (enum dwarf_tag tag, const char *namespace); + +static char *add_partial_namespace (struct partial_die_info *pdi, + char *info_ptr, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu, + const char *namespace); + +static char *add_partial_structure (struct partial_die_info *struct_pdi, + char *info_ptr, + struct dwarf2_cu *cu, + const char *namespace); + +static char *add_partial_enumeration (struct partial_die_info *enum_pdi, + char *info_ptr, + struct dwarf2_cu *cu, + const char *namespace); -static void add_partial_symbol (struct partial_die_info *, struct objfile *, - const struct comp_unit_head *); +static char *locate_pdi_sibling (struct partial_die_info *orig_pdi, + char *info_ptr, + bfd *abfd, + struct dwarf2_cu *cu); static void dwarf2_psymtab_to_symtab (struct partial_symtab *); static void psymtab_to_symtab_1 (struct partial_symtab *); -char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int); +char *dwarf2_read_section (struct objfile *, asection *); -static void dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header); +static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu); -static void dwarf2_empty_abbrev_table (PTR); +static void dwarf2_free_abbrev_table (void *); static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int, - const struct comp_unit_head *cu_header); + struct dwarf2_cu *); static char *read_partial_die (struct partial_die_info *, - bfd *, char *, - const struct comp_unit_head *); + bfd *, char *, struct dwarf2_cu *); static char *read_full_die (struct die_info **, bfd *, char *, - const struct comp_unit_head *); + struct dwarf2_cu *, int *); static char *read_attribute (struct attribute *, struct attr_abbrev *, - bfd *, char *, const struct comp_unit_head *); + bfd *, char *, struct dwarf2_cu *); static char *read_attribute_value (struct attribute *, unsigned, - bfd *, char *, const struct comp_unit_head *); + bfd *, char *, struct dwarf2_cu *); static unsigned int read_1_byte (bfd *, char *); @@ -737,7 +714,7 @@ static unsigned int read_4_bytes (bfd *, char *); static unsigned long read_8_bytes (bfd *, char *); -static CORE_ADDR read_address (bfd *, char *ptr, const struct comp_unit_head *, +static CORE_ADDR read_address (bfd *, char *ptr, struct dwarf2_cu *, int *bytes_read); static LONGEST read_initial_length (bfd *, char *, @@ -757,129 +734,148 @@ static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *); 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 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 struct line_header *(dwarf_decode_line_header (unsigned int offset, - bfd *abfd, - const struct comp_unit_head *cu_header)); + bfd *abfd, struct dwarf2_cu *cu)); static void dwarf_decode_lines (struct line_header *, char *, bfd *, - const struct comp_unit_head *); + struct dwarf2_cu *); static void dwarf2_start_subfile (char *, char *); static struct symbol *new_symbol (struct die_info *, struct type *, - struct objfile *, const struct comp_unit_head *); + struct dwarf2_cu *); static void dwarf2_const_value (struct attribute *, struct symbol *, - struct objfile *, const struct comp_unit_head *); + struct dwarf2_cu *); static void dwarf2_const_value_data (struct attribute *attr, struct symbol *sym, int bits); -static struct type *die_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static struct type *die_type (struct die_info *, struct dwarf2_cu *); -static struct type *die_containing_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static struct type *die_containing_type (struct die_info *, + struct dwarf2_cu *); #if 0 static struct type *type_at_offset (unsigned int, struct objfile *); #endif -static struct type *tag_type_to_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static struct type *tag_type_to_type (struct die_info *, struct dwarf2_cu *); + +static void read_type_die (struct die_info *, struct dwarf2_cu *); + +static char *determine_prefix (struct die_info *die, struct dwarf2_cu *); -static void read_type_die (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static char *determine_prefix_aux (struct die_info *die, struct dwarf2_cu *); -static void read_typedef (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static char *typename_concat (const char *prefix, const char *suffix); -static void read_base_type (struct die_info *, struct objfile *); +static char *class_name (struct die_info *die, struct dwarf2_cu *); -static void read_file_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_typedef (struct die_info *, struct dwarf2_cu *); -static void read_func_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_base_type (struct die_info *, struct dwarf2_cu *); -static void read_lexical_block_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_subrange_type (struct die_info *die, struct dwarf2_cu *cu); + +static void read_file_scope (struct die_info *, struct dwarf2_cu *); + +static void read_func_scope (struct die_info *, struct dwarf2_cu *); + +static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *); static int dwarf2_get_pc_bounds (struct die_info *, - CORE_ADDR *, CORE_ADDR *, struct objfile *); + 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 objfile *, const struct comp_unit_head *); + struct dwarf2_cu *); static void dwarf2_attach_fields_to_type (struct field_info *, - struct type *, struct objfile *); + struct type *, struct dwarf2_cu *); static void dwarf2_add_member_fn (struct field_info *, struct die_info *, struct type *, - struct objfile *objfile, - const struct comp_unit_head *); + struct dwarf2_cu *); static void dwarf2_attach_fn_fields_to_type (struct field_info *, - struct type *, struct objfile *); + struct type *, struct dwarf2_cu *); -static void read_structure_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_structure_scope (struct die_info *, struct dwarf2_cu *); -static void read_common_block (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_common_block (struct die_info *, struct dwarf2_cu *); -static void read_enumeration (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_namespace (struct die_info *die, struct dwarf2_cu *); -static struct type *dwarf_base_type (int, int, struct objfile *); +static const char *namespace_name (struct die_info *die, + int *is_anonymous, struct dwarf2_cu *); -static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *, - const struct comp_unit_head *); +static void read_enumeration (struct die_info *, struct dwarf2_cu *); -static void read_array_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static struct type *dwarf_base_type (int, int, struct dwarf2_cu *); -static void read_tag_pointer_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *); -static void read_tag_ptr_to_member_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_array_type (struct die_info *, struct dwarf2_cu *); -static void read_tag_reference_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_tag_pointer_type (struct die_info *, struct dwarf2_cu *); -static void read_tag_const_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_tag_ptr_to_member_type (struct die_info *, + struct dwarf2_cu *); -static void read_tag_volatile_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_tag_reference_type (struct die_info *, struct dwarf2_cu *); -static void read_tag_string_type (struct die_info *, struct objfile *); +static void read_tag_const_type (struct die_info *, struct dwarf2_cu *); -static void read_subroutine_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_tag_volatile_type (struct die_info *, struct dwarf2_cu *); -static struct die_info *read_comp_unit (char *, bfd *, - const struct comp_unit_head *); +static void read_tag_string_type (struct die_info *, struct dwarf2_cu *); + +static void read_subroutine_type (struct die_info *, struct dwarf2_cu *); + +static struct die_info *read_comp_unit (char *, bfd *, struct dwarf2_cu *); + +static struct die_info *read_die_and_children (char *info_ptr, bfd *abfd, + struct dwarf2_cu *, + char **new_info_ptr, + struct die_info *parent); + +static struct die_info *read_die_and_siblings (char *info_ptr, bfd *abfd, + struct dwarf2_cu *, + char **new_info_ptr, + struct die_info *parent); static void free_die_list (struct die_info *); static struct cleanup *make_cleanup_free_die_list (struct die_info *); -static void process_die (struct die_info *, struct objfile *, - const struct comp_unit_head *); +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, struct dwarf2_cu *); + +static struct die_info *dwarf2_extension (struct die_info *die, + struct dwarf2_cu *); static char *dwarf_tag_name (unsigned int); @@ -909,54 +905,61 @@ static void store_in_ref_table (unsigned int, struct die_info *); 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 void dwarf2_free_tmp_obstack (PTR); +static void dwarf2_free_tmp_obstack (void *); 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 *, const struct comp_unit_head *, - struct objfile *); + char *, bfd *, struct dwarf2_cu *); static int attr_form_is_block (struct attribute *); +static void +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. */ int dwarf2_has_info (bfd *abfd) { - dwarf_info_offset = 0; - dwarf_abbrev_offset = 0; - dwarf_line_offset = 0; - dwarf_str_offset = 0; - dwarf_macinfo_offset = 0; - dwarf_frame_offset = 0; - dwarf_eh_frame_offset = 0; + dwarf_info_section = 0; + dwarf_abbrev_section = 0; + dwarf_line_section = 0; + dwarf_str_section = 0; + dwarf_macinfo_section = 0; + dwarf_frame_section = 0; + dwarf_eh_frame_section = 0; + dwarf_ranges_section = 0; + dwarf_loc_section = 0; + bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL); - if (dwarf_info_offset && dwarf_abbrev_offset) - { - return 1; - } - else - { - return 0; - } + return (dwarf_info_section != NULL && dwarf_abbrev_section != NULL); } /* This function is mapped across the sections and remembers the @@ -964,57 +967,66 @@ dwarf2_has_info (bfd *abfd) in. */ static void -dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, PTR ignore_ptr) +dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr) { - if (STREQ (sectp->name, INFO_SECTION)) + if (strcmp (sectp->name, INFO_SECTION) == 0) { - dwarf_info_offset = sectp->filepos; dwarf_info_size = bfd_get_section_size_before_reloc (sectp); + dwarf_info_section = sectp; } - else if (STREQ (sectp->name, ABBREV_SECTION)) + else if (strcmp (sectp->name, ABBREV_SECTION) == 0) { - dwarf_abbrev_offset = sectp->filepos; dwarf_abbrev_size = bfd_get_section_size_before_reloc (sectp); + dwarf_abbrev_section = sectp; } - else if (STREQ (sectp->name, LINE_SECTION)) + else if (strcmp (sectp->name, LINE_SECTION) == 0) { - dwarf_line_offset = sectp->filepos; dwarf_line_size = bfd_get_section_size_before_reloc (sectp); + dwarf_line_section = sectp; } - else if (STREQ (sectp->name, PUBNAMES_SECTION)) + else if (strcmp (sectp->name, PUBNAMES_SECTION) == 0) { - dwarf_pubnames_offset = sectp->filepos; dwarf_pubnames_size = bfd_get_section_size_before_reloc (sectp); + dwarf_pubnames_section = sectp; } - else if (STREQ (sectp->name, ARANGES_SECTION)) + else if (strcmp (sectp->name, ARANGES_SECTION) == 0) { - dwarf_aranges_offset = sectp->filepos; dwarf_aranges_size = bfd_get_section_size_before_reloc (sectp); + dwarf_aranges_section = sectp; } - else if (STREQ (sectp->name, LOC_SECTION)) + else if (strcmp (sectp->name, LOC_SECTION) == 0) { - dwarf_loc_offset = sectp->filepos; dwarf_loc_size = bfd_get_section_size_before_reloc (sectp); + dwarf_loc_section = sectp; } - else if (STREQ (sectp->name, MACINFO_SECTION)) + else if (strcmp (sectp->name, MACINFO_SECTION) == 0) { - dwarf_macinfo_offset = sectp->filepos; dwarf_macinfo_size = bfd_get_section_size_before_reloc (sectp); + dwarf_macinfo_section = sectp; } - else if (STREQ (sectp->name, STR_SECTION)) + else if (strcmp (sectp->name, STR_SECTION) == 0) { - dwarf_str_offset = sectp->filepos; dwarf_str_size = bfd_get_section_size_before_reloc (sectp); + dwarf_str_section = sectp; } - else if (STREQ (sectp->name, FRAME_SECTION)) + else if (strcmp (sectp->name, FRAME_SECTION) == 0) { - dwarf_frame_offset = sectp->filepos; dwarf_frame_size = bfd_get_section_size_before_reloc (sectp); + dwarf_frame_section = sectp; + } + else if (strcmp (sectp->name, EH_FRAME_SECTION) == 0) + { + flagword aflag = bfd_get_section_flags (ignore_abfd, sectp); + if (aflag & SEC_HAS_CONTENTS) + { + dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp); + dwarf_eh_frame_section = sectp; + } } - else if (STREQ (sectp->name, EH_FRAME_SECTION)) + else if (strcmp (sectp->name, RANGES_SECTION) == 0) { - dwarf_eh_frame_offset = sectp->filepos; - dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp); + dwarf_ranges_size = bfd_get_section_size_before_reloc (sectp); + dwarf_ranges_section = sectp; } } @@ -1026,34 +1038,35 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline) /* We definitely need the .debug_info and .debug_abbrev sections */ - dwarf_info_buffer = dwarf2_read_section (objfile, - dwarf_info_offset, - dwarf_info_size); - dwarf_abbrev_buffer = dwarf2_read_section (objfile, - dwarf_abbrev_offset, - dwarf_abbrev_size); - - if (dwarf_line_offset) - dwarf_line_buffer = dwarf2_read_section (objfile, - dwarf_line_offset, - dwarf_line_size); + dwarf_info_buffer = dwarf2_read_section (objfile, dwarf_info_section); + dwarf_abbrev_buffer = dwarf2_read_section (objfile, dwarf_abbrev_section); + + if (dwarf_line_section) + dwarf_line_buffer = dwarf2_read_section (objfile, dwarf_line_section); else dwarf_line_buffer = NULL; - if (dwarf_str_offset) - dwarf_str_buffer = dwarf2_read_section (objfile, - dwarf_str_offset, - dwarf_str_size); + if (dwarf_str_section) + dwarf_str_buffer = dwarf2_read_section (objfile, dwarf_str_section); else dwarf_str_buffer = NULL; - if (dwarf_macinfo_offset) + if (dwarf_macinfo_section) dwarf_macinfo_buffer = dwarf2_read_section (objfile, - dwarf_macinfo_offset, - dwarf_macinfo_size); + dwarf_macinfo_section); else dwarf_macinfo_buffer = NULL; + if (dwarf_ranges_section) + dwarf_ranges_buffer = dwarf2_read_section (objfile, dwarf_ranges_section); + else + dwarf_ranges_buffer = NULL; + + if (dwarf_loc_section) + dwarf_loc_buffer = dwarf2_read_section (objfile, dwarf_loc_section); + else + dwarf_loc_buffer = NULL; + if (mainline || (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)) @@ -1091,8 +1104,7 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) unsigned int entry_length, version, info_offset, info_size; pubnames_buffer = dwarf2_read_section (objfile, - dwarf_pubnames_offset, - dwarf_pubnames_size); + dwarf_pubnames_section); pubnames_ptr = pubnames_buffer; while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size) { @@ -1111,8 +1123,7 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) } aranges_buffer = dwarf2_read_section (objfile, - dwarf_aranges_offset, - dwarf_aranges_size); + dwarf_aranges_section); } #endif @@ -1158,7 +1169,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) 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; @@ -1209,45 +1220,52 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) left at all should be sufficient. */ while (info_ptr < dwarf_info_buffer + dwarf_info_size) { - struct comp_unit_head cu_header; + struct cleanup *back_to_inner; + struct dwarf2_cu cu; beg_of_comp_unit = info_ptr; - info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd); - if (cu_header.version != 2) + cu.objfile = objfile; + info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd); + + if (cu.header.version != 2) { - error ("Dwarf Error: wrong version in compilation unit header."); + error ("Dwarf Error: wrong version in compilation unit header (is %d, should be %d) [in module %s]", cu.header.version, 2, bfd_get_filename (abfd)); return; } - if (cu_header.abbrev_offset >= dwarf_abbrev_size) + if (cu.header.abbrev_offset >= dwarf_abbrev_size) { - error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6).", - (long) cu_header.abbrev_offset, - (long) (beg_of_comp_unit - dwarf_info_buffer)); + error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6) [in module %s]", + (long) cu.header.abbrev_offset, + (long) (beg_of_comp_unit - dwarf_info_buffer), + bfd_get_filename (abfd)); return; } - if (beg_of_comp_unit + cu_header.length + cu_header.initial_length_size + if (beg_of_comp_unit + cu.header.length + cu.header.initial_length_size > dwarf_info_buffer + dwarf_info_size) { - error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0).", - (long) cu_header.length, - (long) (beg_of_comp_unit - dwarf_info_buffer)); + error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0) [in module %s]", + (long) cu.header.length, + (long) (beg_of_comp_unit - dwarf_info_buffer), + bfd_get_filename (abfd)); return; } /* Complete the cu_header */ - cu_header.offset = beg_of_comp_unit - dwarf_info_buffer; - cu_header.first_die_ptr = info_ptr; - cu_header.cu_head_ptr = beg_of_comp_unit; + cu.header.offset = beg_of_comp_unit - dwarf_info_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_header); - make_cleanup (dwarf2_empty_abbrev_table, cu_header.dwarf2_abbrevs); + dwarf2_read_abbrevs (abfd, &cu); + 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_header); + &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, @@ -1257,8 +1275,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) 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; @@ -1269,6 +1286,10 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) DWARF_STR_SIZE (pst) = dwarf_str_size; DWARF_MACINFO_BUFFER (pst) = dwarf_macinfo_buffer; DWARF_MACINFO_SIZE (pst) = dwarf_macinfo_size; + DWARF_RANGES_BUFFER (pst) = dwarf_ranges_buffer; + DWARF_RANGES_SIZE (pst) = dwarf_ranges_size; + DWARF_LOC_BUFFER (pst) = dwarf_loc_buffer; + DWARF_LOC_SIZE (pst) = dwarf_loc_size; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); /* Store the function that reads in the rest of the symbol table */ @@ -1279,9 +1300,17 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) If not, there's no more debug_info for this comp unit. */ if (comp_unit_die.has_children) { - info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc, - &cu_header); + lowpc = ((CORE_ADDR) -1); + highpc = ((CORE_ADDR) 0); + info_ptr = scan_partial_symbols (info_ptr, &lowpc, &highpc, + &cu, NULL); + + /* If we didn't find a lowpc, set it to highpc to avoid + complaints from `maint check'. */ + if (lowpc == ((CORE_ADDR) -1)) + lowpc = highpc; + /* If the compilation unit didn't have an explicit address range, then use the information extracted from its child dies. */ if (! comp_unit_die.has_pc_info) @@ -1304,38 +1333,48 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) also happen.) This happens in VxWorks. */ free_named_symtabs (pst->filename); - info_ptr = beg_of_comp_unit + cu_header.length - + cu_header.initial_length_size; + info_ptr = beg_of_comp_unit + cu.header.length + + cu.header.initial_length_size; + + do_cleanups (back_to_inner); } do_cleanups (back_to); } -/* Read in all interesting dies to the end of the compilation unit. */ +/* Read in all interesting dies to the end of the compilation unit or + to the end of the current namespace. NAMESPACE is NULL if we + haven't yet encountered any DW_TAG_namespace entries; otherwise, + it's the name of the current namespace. In particular, it's the + empty string if we're currently in the global namespace but have + previously encountered a DW_TAG_namespace. */ static char * -scan_partial_symbols (char *info_ptr, struct objfile *objfile, - CORE_ADDR *lowpc, CORE_ADDR *highpc, - const struct comp_unit_head *cu_header) +scan_partial_symbols (char *info_ptr, CORE_ADDR *lowpc, + CORE_ADDR *highpc, struct dwarf2_cu *cu, + const char *namespace) { + struct objfile *objfile = cu->objfile; bfd *abfd = objfile->obfd; struct partial_die_info pdi; - /* This function is called after we've read in the comp_unit_die in - order to read its children. We start the nesting level at 1 since - we have pushed 1 level down in order to read the comp unit's children. - The comp unit itself is at level 0, so we stop reading when we pop - back to that level. */ + /* Now, march along the PDI's, descending into ones which have + interesting children but skipping the children of the other ones, + until we reach the end of the compilation unit. */ - int nesting_level = 1; + while (1) + { + /* This flag tells whether or not info_ptr has gotten updated + inside the loop. */ + int info_ptr_updated = 0; - *lowpc = ((CORE_ADDR) -1); - *highpc = ((CORE_ADDR) 0); + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu); - while (nesting_level) - { - info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header); + /* Anonymous namespaces have no name but have interesting + children, so we need to look at them. Ditto for anonymous + enums. */ - if (pdi.name) + if (pdi.name != NULL || pdi.tag == DW_TAG_namespace + || pdi.tag == DW_TAG_enumeration_type) { switch (pdi.tag) { @@ -1350,95 +1389,121 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile, { *highpc = pdi.highpc; } - if ((pdi.is_external || nesting_level == 1) - && !pdi.is_declaration) + if (!pdi.is_declaration) { - add_partial_symbol (&pdi, objfile, cu_header); + add_partial_symbol (&pdi, cu, namespace); } } break; case DW_TAG_variable: case DW_TAG_typedef: + case DW_TAG_union_type: + if (!pdi.is_declaration) + { + add_partial_symbol (&pdi, cu, namespace); + } + break; case DW_TAG_class_type: case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_enumeration_type: - if ((pdi.is_external || nesting_level == 1) - && !pdi.is_declaration) + if (!pdi.is_declaration) { - add_partial_symbol (&pdi, objfile, cu_header); + info_ptr = add_partial_structure (&pdi, info_ptr, cu, + namespace); + info_ptr_updated = 1; } break; - case DW_TAG_enumerator: - /* File scope enumerators are added to the partial symbol - table. */ - if (nesting_level == 2) - add_partial_symbol (&pdi, objfile, cu_header); + case DW_TAG_enumeration_type: + if (!pdi.is_declaration) + { + info_ptr = add_partial_enumeration (&pdi, info_ptr, cu, + namespace); + info_ptr_updated = 1; + } break; case DW_TAG_base_type: + case DW_TAG_subrange_type: /* File scope base type definitions are added to the partial symbol table. */ - if (nesting_level == 1) - add_partial_symbol (&pdi, objfile, cu_header); + add_partial_symbol (&pdi, cu, namespace); + break; + case DW_TAG_namespace: + /* We've hit a DW_TAG_namespace entry, so we know this + file has been compiled using a compiler that + generates them; update NAMESPACE to reflect that. */ + if (namespace == NULL) + namespace = ""; + info_ptr = add_partial_namespace (&pdi, info_ptr, lowpc, highpc, + cu, namespace); + info_ptr_updated = 1; break; default: break; } } - /* If the die has a sibling, skip to the sibling. - Do not skip enumeration types, we want to record their - enumerators. */ - if (pdi.sibling && pdi.tag != DW_TAG_enumeration_type) - { - info_ptr = pdi.sibling; - } - else if (pdi.has_children) - { - /* Die has children, but the optional DW_AT_sibling attribute - is missing. */ - nesting_level++; - } - if (pdi.tag == 0) - { - nesting_level--; - } + break; + + /* If the die has a sibling, skip to the sibling, unless another + function has already updated info_ptr for us. */ + + /* NOTE: carlton/2003-06-16: This is a bit hackish, but whether + or not we want to update this depends on enough stuff (not + only pdi.tag but also whether or not pdi.name is NULL) that + this seems like the easiest way to handle the issue. */ + + if (!info_ptr_updated) + info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu); } - /* If we didn't find a lowpc, set it to highpc to avoid complaints - from `maint check'. */ - if (*lowpc == ((CORE_ADDR) -1)) - *lowpc = *highpc; return info_ptr; } static void -add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, - const struct comp_unit_head *cu_header) +add_partial_symbol (struct partial_die_info *pdi, + struct dwarf2_cu *cu, const char *namespace) { + struct objfile *objfile = cu->objfile; 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. */ + + if (pdi_needs_namespace (pdi->tag, namespace)) + { + actual_name = alloca (strlen (pdi->name) + 2 + strlen (namespace) + 1); + strcpy (actual_name, namespace); + strcat (actual_name, "::"); + strcat (actual_name, pdi->name); + } switch (pdi->tag) { case DW_TAG_subprogram: if (pdi->is_external) { - /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr, + /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr, mst_text, objfile); */ - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_BLOCK, - &objfile->global_psymbols, - 0, pdi->lowpc + baseaddr, cu_language, objfile); + psym = add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_BLOCK, + &objfile->global_psymbols, + 0, pdi->lowpc + baseaddr, + cu->language, objfile); } else { - /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr, + /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr, mst_file_text, objfile); */ - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_BLOCK, - &objfile->static_psymbols, - 0, pdi->lowpc + baseaddr, cu_language, objfile); + psym = add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_BLOCK, + &objfile->static_psymbols, + 0, pdi->lowpc + baseaddr, + cu->language, objfile); } break; case DW_TAG_variable: @@ -1458,33 +1523,36 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, table building. */ if (pdi->locdesc) - addr = decode_locdesc (pdi->locdesc, objfile, cu_header); + addr = decode_locdesc (pdi->locdesc, cu); if (pdi->locdesc || pdi->has_type) - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_STATIC, - &objfile->global_psymbols, - 0, addr + baseaddr, cu_language, objfile); + psym = add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_STATIC, + &objfile->global_psymbols, + 0, addr + baseaddr, + cu->language, objfile); } else { /* Static Variable. Skip symbols without location descriptors. */ if (pdi->locdesc == NULL) return; - addr = decode_locdesc (pdi->locdesc, objfile, cu_header); - /*prim_record_minimal_symbol (pdi->name, addr + baseaddr, + addr = decode_locdesc (pdi->locdesc, cu); + /*prim_record_minimal_symbol (actual_name, addr + baseaddr, mst_file_data, objfile); */ - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_STATIC, - &objfile->static_psymbols, - 0, addr + baseaddr, cu_language, objfile); + psym = add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_STATIC, + &objfile->static_psymbols, + 0, addr + baseaddr, + cu->language, objfile); } break; case DW_TAG_typedef: case DW_TAG_base_type: - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_TYPEDEF, + 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: @@ -1492,31 +1560,382 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, case DW_TAG_enumeration_type: /* Skip aggregate types without children, these are external references. */ + /* NOTE: carlton/2003-10-07: See comment in new_symbol about + static vs. global. */ if (pdi->has_children == 0) return; - add_psymbol_to_list (pdi->name, strlen (pdi->name), - STRUCT_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu_language, objfile); - - if (cu_language == language_cplus) + add_psymbol_to_list (actual_name, strlen (actual_name), + STRUCT_DOMAIN, LOC_TYPEDEF, + cu->language == language_cplus + ? &objfile->global_psymbols + : &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); + + if (cu->language == language_cplus) { /* For C++, these implicitly act as typedefs as well. */ - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_TYPEDEF, - &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu_language, objfile); + add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_TYPEDEF, + &objfile->global_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); } break; case DW_TAG_enumerator: - add_psymbol_to_list (pdi->name, strlen (pdi->name), - VAR_NAMESPACE, LOC_CONST, - &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu_language, objfile); + add_psymbol_to_list (actual_name, strlen (actual_name), + VAR_DOMAIN, LOC_CONST, + cu->language == language_cplus + ? &objfile->global_psymbols + : &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); break; default: break; } + + /* Check to see if we should scan the name for possible namespace + info. Only do this if this is C++, if we don't have namespace + debugging info in the file, if the psym is of an appropriate type + (otherwise we'll have psym == NULL), and if we actually had a + mangled name to begin with. */ + + if (cu->language == language_cplus + && namespace == NULL + && psym != NULL + && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL) + cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym), + objfile); +} + +/* Determine whether a die of type TAG living in the C++ namespace + NAMESPACE needs to have the name of the namespace prepended to the + name listed in the die. */ + +static int +pdi_needs_namespace (enum dwarf_tag tag, const char *namespace) +{ + if (namespace == NULL || namespace[0] == '\0') + return 0; + + switch (tag) + { + case DW_TAG_typedef: + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + case DW_TAG_enumerator: + return 1; + default: + return 0; + } +} + +/* Read a partial die corresponding to a namespace; also, add a symbol + corresponding to that namespace to the symbol table. NAMESPACE is + the name of the enclosing namespace. */ + +static char * +add_partial_namespace (struct partial_die_info *pdi, char *info_ptr, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu, const char *namespace) +{ + struct objfile *objfile = cu->objfile; + const char *new_name = pdi->name; + char *full_name; + + /* Calculate the full name of the namespace that we just entered. */ + + if (new_name == NULL) + new_name = "(anonymous namespace)"; + full_name = alloca (strlen (namespace) + 2 + strlen (new_name) + 1); + strcpy (full_name, namespace); + if (*namespace != '\0') + strcat (full_name, "::"); + strcat (full_name, new_name); + + /* FIXME: carlton/2003-10-07: We can't just replace this by a call + to add_partial_symbol, because we don't have a way to pass in the + full name to that function; that might be a flaw in + add_partial_symbol's interface. */ + + add_psymbol_to_list (full_name, strlen (full_name), + VAR_DOMAIN, LOC_TYPEDEF, + &objfile->global_psymbols, + 0, 0, cu->language, objfile); + + /* Now scan partial symbols in that namespace. */ + + if (pdi->has_children) + info_ptr = scan_partial_symbols (info_ptr, lowpc, highpc, cu, full_name); + + return info_ptr; +} + +/* Read a partial die corresponding to a class or structure. */ + +static char * +add_partial_structure (struct partial_die_info *struct_pdi, char *info_ptr, + struct dwarf2_cu *cu, + const char *namespace) +{ + bfd *abfd = cu->objfile->obfd; + char *actual_class_name = NULL; + + if (cu->language == language_cplus + && (namespace == NULL || namespace[0] == '\0') + && struct_pdi->name != NULL + && struct_pdi->has_children) + { + /* 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. */ + + /* NOTE: carlton/2003-10-07: Getting the info this way changes + 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). */ + + /* 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) + { + struct partial_die_info child_pdi; + + next_child = read_partial_die (&child_pdi, abfd, next_child, + cu); + if (!child_pdi.tag) + break; + if (child_pdi.tag == DW_TAG_subprogram) + { + actual_class_name = class_name_from_physname (child_pdi.name); + if (actual_class_name != NULL) + struct_pdi->name = actual_class_name; + break; + } + else + { + next_child = locate_pdi_sibling (&child_pdi, next_child, + abfd, cu); + } + } + } + + add_partial_symbol (struct_pdi, cu, namespace); + xfree (actual_class_name); + + return locate_pdi_sibling (struct_pdi, info_ptr, abfd, cu); +} + +/* Read a partial die corresponding to an enumeration type. */ + +static char * +add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr, + struct dwarf2_cu *cu, const char *namespace) +{ + struct objfile *objfile = cu->objfile; + bfd *abfd = objfile->obfd; + struct partial_die_info pdi; + + if (enum_pdi->name != NULL) + add_partial_symbol (enum_pdi, cu, namespace); + + while (1) + { + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu); + if (pdi.tag == 0) + break; + if (pdi.tag != DW_TAG_enumerator || pdi.name == NULL) + complaint (&symfile_complaints, "malformed enumerator DIE ignored"); + else + add_partial_symbol (&pdi, cu, namespace); + } + + return info_ptr; +} + +/* 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, + bfd *abfd, struct dwarf2_cu *cu) +{ + /* Do we know the sibling already? */ + + if (orig_pdi->sibling) + return orig_pdi->sibling; + + /* Are there any children to deal with? */ + + if (!orig_pdi->has_children) + return info_ptr; + + /* Skip the children the long way. */ + + return skip_children (info_ptr, cu); } /* Expand this partial symbol table into a full symbol table. */ @@ -1553,7 +1972,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) { struct objfile *objfile = pst->objfile; bfd *abfd = objfile->obfd; - struct comp_unit_head cu_header; + struct dwarf2_cu cu; struct die_info *dies; unsigned long offset; CORE_ADDR lowpc, highpc; @@ -1561,6 +1980,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) char *info_ptr; 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); @@ -1573,9 +1994,15 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) dwarf_str_size = DWARF_STR_SIZE (pst); dwarf_macinfo_buffer = DWARF_MACINFO_BUFFER (pst); dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst); - baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile)); - cu_header_offset = offset; + dwarf_ranges_buffer = DWARF_RANGES_BUFFER (pst); + dwarf_ranges_size = DWARF_RANGES_SIZE (pst); + dwarf_loc_buffer = DWARF_LOC_BUFFER (pst); + dwarf_loc_size = DWARF_LOC_SIZE (pst); info_ptr = dwarf_info_buffer + offset; + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + /* We're in the global namespace. */ + processing_current_prefix = ""; obstack_init (&dwarf2_tmp_obstack); back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL); @@ -1583,57 +2010,68 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) buildsym_init (); make_cleanup (really_free_pendings, NULL); + cu.objfile = objfile; + /* read in the comp_unit header */ - info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd); + info_ptr = read_comp_unit_head (&cu.header, info_ptr, abfd); /* Read the abbrevs for this compilation unit */ - dwarf2_read_abbrevs (abfd, &cu_header); - make_cleanup (dwarf2_empty_abbrev_table, cu_header.dwarf2_abbrevs); + dwarf2_read_abbrevs (abfd, &cu); + make_cleanup (dwarf2_free_abbrev_table, &cu); + + cu.header.offset = offset; - dies = read_comp_unit (info_ptr, abfd, &cu_header); + cu.list_in_scope = &file_symbols; + + dies = read_comp_unit (info_ptr, abfd, &cu); make_cleanup_free_die_list (dies); - /* Do line number decoding in read_file_scope () */ - process_die (dies, objfile, &cu_header); + /* Find the base address of the compilation unit for range lists and + location lists. It will normally be specified by DW_AT_low_pc. + In DWARF-3 draft 4, the base address could be overridden by + DW_AT_entry_pc. It's been removed, but GCC still uses this for + compilation units with discontinuous ranges. */ - if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile)) + cu.header.base_known = 0; + cu.header.base_address = 0; + + attr = dwarf2_attr (dies, DW_AT_entry_pc, &cu); + if (attr) + { + cu.header.base_address = DW_ADDR (attr); + cu.header.base_known = 1; + } + else { - /* 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->has_children) + attr = dwarf2_attr (dies, DW_AT_low_pc, &cu); + if (attr) { - child_die = dies->next; - 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, objfile)) - { - highpc = max (highpc, high); - } - } - child_die = sibling_die (child_die); - } + cu.header.base_address = DW_ADDR (attr); + cu.header.base_known = 1; } } + + /* Do line number decoding in read_file_scope () */ + process_die (dies, &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. */ + get_scope_pc_bounds (dies, &lowpc, &highpc, &cu); + 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; - sort_symtab_syms (pst->symtab); do_cleanups (back_to); } @@ -1641,19 +2079,18 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) /* Process a die and its children. */ static void -process_die (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +process_die (struct die_info *die, struct dwarf2_cu *cu) { switch (die->tag) { case DW_TAG_padding: break; case DW_TAG_compile_unit: - read_file_scope (die, objfile, cu_header); + read_file_scope (die, cu); break; case DW_TAG_subprogram: - read_subroutine_type (die, objfile, cu_header); - read_func_scope (die, objfile, cu_header); + read_subroutine_type (die, cu); + read_func_scope (die, cu); break; case DW_TAG_inlined_subroutine: /* FIXME: These are ignored for now. @@ -1661,63 +2098,89 @@ process_die (struct die_info *die, struct objfile *objfile, of a function and make GDB `next' properly over inlined functions. */ break; case DW_TAG_lexical_block: - read_lexical_block_scope (die, objfile, cu_header); + case DW_TAG_try_block: + case DW_TAG_catch_block: + read_lexical_block_scope (die, cu); break; case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: - read_structure_scope (die, objfile, cu_header); + read_structure_scope (die, cu); break; case DW_TAG_enumeration_type: - read_enumeration (die, objfile, cu_header); + read_enumeration (die, cu); break; case DW_TAG_subroutine_type: - read_subroutine_type (die, objfile, cu_header); + read_subroutine_type (die, cu); break; case DW_TAG_array_type: - read_array_type (die, objfile, cu_header); + read_array_type (die, cu); break; case DW_TAG_pointer_type: - read_tag_pointer_type (die, objfile, cu_header); + read_tag_pointer_type (die, cu); break; case DW_TAG_ptr_to_member_type: - read_tag_ptr_to_member_type (die, objfile, cu_header); + read_tag_ptr_to_member_type (die, cu); break; case DW_TAG_reference_type: - read_tag_reference_type (die, objfile, cu_header); + read_tag_reference_type (die, cu); break; case DW_TAG_string_type: - read_tag_string_type (die, objfile); + read_tag_string_type (die, cu); break; case DW_TAG_base_type: - read_base_type (die, objfile); - if (dwarf_attr (die, DW_AT_name)) + read_base_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, objfile, cu_header); + 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, objfile, cu_header); + read_common_block (die, cu); break; case DW_TAG_common_inclusion: break; + case DW_TAG_namespace: + processing_has_namespace_info = 1; + read_namespace (die, cu); + break; + case DW_TAG_imported_declaration: + case DW_TAG_imported_module: + /* FIXME: carlton/2002-10-16: Eventually, we should use the + information contained in these. DW_TAG_imported_declaration + dies shouldn't have children; DW_TAG_imported_module dies + shouldn't in the C++ case, but conceivably could in the + Fortran case, so we'll have to replace this gdb_assert if + Fortran compilers start generating that info. */ + processing_has_namespace_info = 1; + gdb_assert (die->child == NULL); + break; default: - new_symbol (die, NULL, objfile, cu_header); + new_symbol (die, NULL, 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 -read_file_scope (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_file_scope (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; struct cleanup *back_to = make_cleanup (null_cleanup, 0); CORE_ADDR lowpc = ((CORE_ADDR) -1); CORE_ADDR highpc = ((CORE_ADDR) 0); @@ -1727,28 +2190,11 @@ read_file_scope (struct die_info *die, struct objfile *objfile, 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, objfile)) - { - if (die->has_children) - { - child_die = die->next; - 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, objfile)) - { - 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. */ @@ -1757,12 +2203,12 @@ read_file_scope (struct die_info *die, struct objfile *objfile, 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); @@ -1780,14 +2226,14 @@ read_file_scope (struct die_info *die, struct objfile *objfile, if (objfile->ei.entry_point >= lowpc && objfile->ei.entry_point < highpc) { - objfile->ei.entry_file_lowpc = lowpc; - objfile->ei.entry_file_highpc = highpc; + objfile->ei.deprecated_entry_file_lowpc = lowpc; + 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. */ @@ -1802,36 +2248,35 @@ read_file_scope (struct die_info *die, struct objfile *objfile, /* 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->has_children) + if (die->child != NULL) { - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { - process_die (child_die, objfile, cu_header); + process_die (child_die, cu); child_die = sibling_die (child_die); } } /* 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); - line_header = dwarf_decode_line_header (line_offset, - abfd, cu_header); + line_header = dwarf_decode_line_header (line_offset, abfd, cu); if (line_header) { make_cleanup ((make_cleanup_ftype *) free_line_header, (void *) line_header); - dwarf_decode_lines (line_header, comp_dir, abfd, cu_header); + dwarf_decode_lines (line_header, comp_dir, abfd, cu); } } @@ -1839,18 +2284,19 @@ read_file_scope (struct die_info *die, struct objfile *objfile, 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); dwarf_decode_macros (line_header, macro_offset, - comp_dir, abfd, cu_header, objfile); + comp_dir, abfd, cu); } do_cleanups (back_to); } 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; @@ -1862,37 +2308,76 @@ add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc) 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 -read_func_scope (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_func_scope (struct die_info *die, struct dwarf2_cu *cu) { - register struct context_stack *new; + struct objfile *objfile = cu->objfile; + struct context_stack *new; CORE_ADDR lowpc; CORE_ADDR highpc; 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, objfile)) + 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) @@ -1901,54 +2386,32 @@ read_func_scope (struct die_info *die, struct objfile *objfile, objfile->ei.entry_func_highpc = highpc; } - /* Decode DW_AT_frame_base location descriptor if present, keep result - for DW_OP_fbreg operands in decode_locdesc. */ - frame_base_reg = -1; - frame_base_offset = 0; - attr = dwarf_attr (die, DW_AT_frame_base); - if (attr) - { - CORE_ADDR addr; - - /* Support the .debug_loc offsets */ - if (attr_form_is_block (attr)) - { - addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); - } - else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) - { - complain (&dwarf2_complex_location_expr); - addr = 0; - } - else - { - complain (&dwarf2_invalid_attrib_class, "DW_AT_frame_base", name); - addr = 0; - } - - if (isderef) - complain (&dwarf2_unsupported_at_frame_base, name); - else if (isreg) - frame_base_reg = addr; - else if (offreg) - { - frame_base_reg = basereg; - frame_base_offset = addr; - } - else - complain (&dwarf2_unsupported_at_frame_base, name); - } - new = push_context (0, lowpc); - new->name = new_symbol (die, die->type, objfile, cu_header); - list_in_scope = &local_symbols; + new->name = new_symbol (die, die->type, cu); - if (die->has_children) - { - child_die = die->next; + /* If there is a location expression for DW_AT_frame_base, record + it. */ + 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); + + cu->list_in_scope = &local_symbols; + + if (die->child != NULL) + { + child_die = die->child; while (child_die && child_die->tag) { - process_die (child_die, objfile, cu_header); + process_die (child_die, cu); child_die = sibling_die (child_die); } } @@ -1957,33 +2420,55 @@ read_func_scope (struct die_info *die, struct objfile *objfile, /* Make a block for the local symbols within. */ finish_block (new->name, &local_symbols, new->old_blocks, lowpc, highpc, objfile); - list_in_scope = &file_symbols; + + /* In C++, we can have functions nested inside functions (e.g., when + a function declares a class that has methods). This means that + when we finish processing a function scope, we may need to go + back to building a containing block's symbol lists. */ + local_symbols = new->locals; + param_symbols = new->params; + + /* If we've finished processing a top-level function, subsequent + symbols go in the file symbol list. */ + if (outermost_context_p ()) + 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 a new scope, process the dies, and then close the scope. */ static void -read_lexical_block_scope (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) { - register struct context_stack *new; + struct objfile *objfile = cu->objfile; + 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. */ - if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile)) + /* ??? Perhaps consider discontiguous blocks defined by DW_AT_ranges + as multiple lexical blocks? Handling children in a sane way would + be nasty. Might be easier to properly extend generic blocks to + describe ranges. */ + if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu)) return; lowpc += baseaddr; highpc += baseaddr; push_context (0, lowpc); - if (die->has_children) + if (die->child != NULL) { - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { - process_die (child_die, objfile, cu_header); + process_die (child_die, cu); child_die = sibling_die (child_die); } } @@ -1997,27 +2482,145 @@ read_lexical_block_scope (struct die_info *die, struct objfile *objfile, local_symbols = new->locals; } -/* Get low and high pc attributes from a die. - Return 1 if the attributes are present and valid, otherwise, return 0. */ - +/* Get low and high pc attributes from a die. Return 1 if the attributes + are present and valid, otherwise, return 0. Return -1 if the range is + discontinuous, i.e. derived from DW_AT_ranges information. */ static int -dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, CORE_ADDR *highpc, - struct objfile *objfile) +dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, + CORE_ADDR *highpc, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; struct attribute *attr; - CORE_ADDR low; - CORE_ADDR high; + bfd *obfd = objfile->obfd; + CORE_ADDR low = 0; + CORE_ADDR high = 0; + int ret = 0; - attr = dwarf_attr (die, DW_AT_low_pc); - if (attr) - low = DW_ADDR (attr); - else - return 0; - attr = dwarf_attr (die, DW_AT_high_pc); + attr = dwarf2_attr (die, DW_AT_high_pc, cu); if (attr) - high = DW_ADDR (attr); + { + high = DW_ADDR (attr); + attr = dwarf2_attr (die, DW_AT_low_pc, cu); + if (attr) + low = DW_ADDR (attr); + else + /* Found high w/o low attribute. */ + return 0; + + /* Found consecutive range of addresses. */ + ret = 1; + } else - return 0; + { + attr = dwarf2_attr (die, DW_AT_ranges, cu); + if (attr != NULL) + { + unsigned int addr_size = cu_header->addr_size; + CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); + /* Value of the DW_AT_ranges attribute is the offset in the + .debug_ranges section. */ + unsigned int offset = DW_UNSND (attr); + /* Base address selection entry. */ + CORE_ADDR base; + int found_base; + int dummy; + char *buffer; + CORE_ADDR marker; + int low_set; + + found_base = cu_header->base_known; + base = cu_header->base_address; + + if (offset >= dwarf_ranges_size) + { + complaint (&symfile_complaints, + "Offset %d out of bounds for DW_AT_ranges attribute", + offset); + return 0; + } + buffer = dwarf_ranges_buffer + offset; + + /* Read in the largest possible address. */ + marker = read_address (obfd, buffer, cu, &dummy); + if ((marker & mask) == mask) + { + /* If we found the largest possible address, then + read the base address. */ + base = read_address (obfd, buffer + addr_size, cu, &dummy); + buffer += 2 * addr_size; + offset += 2 * addr_size; + found_base = 1; + } + + low_set = 0; + + while (1) + { + CORE_ADDR range_beginning, range_end; + + range_beginning = read_address (obfd, buffer, cu, &dummy); + buffer += addr_size; + range_end = read_address (obfd, buffer, cu, &dummy); + buffer += addr_size; + offset += 2 * addr_size; + + /* An end of list marker is a pair of zero addresses. */ + if (range_beginning == 0 && range_end == 0) + /* Found the end of list entry. */ + break; + + /* Each base address selection entry is a pair of 2 values. + The first is the largest possible address, the second is + the base address. Check for a base address here. */ + if ((range_beginning & mask) == mask) + { + /* If we found the largest possible address, then + read the base address. */ + base = read_address (obfd, buffer + addr_size, cu, &dummy); + found_base = 1; + continue; + } + + if (!found_base) + { + /* We have no valid base address for the ranges + data. */ + complaint (&symfile_complaints, + "Invalid .debug_ranges data (no base address)"); + return 0; + } + + range_beginning += base; + range_end += base; + + /* FIXME: This is recording everything as a low-high + segment of consecutive addresses. We should have a + data structure for discontiguous block ranges + instead. */ + if (! low_set) + { + low = range_beginning; + high = range_end; + low_set = 1; + } + else + { + if (range_beginning < low) + low = range_beginning; + if (range_end > high) + high = range_end; + } + } + + if (! low_set) + /* If the first entry is an end-of-list marker, the range + describes an empty scope, i.e. no instructions. */ + return 0; + + ret = -1; + } + } if (high < low) return 0; @@ -2030,21 +2633,83 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, CORE_ADDR *highpc, labels are not in the output, so the relocs get a value of 0. If this is a discarded function, mark the pc bounds as invalid, so that GDB will ignore it. */ - if (low == 0 && (bfd_get_file_flags (objfile->obfd) & HAS_RELOC) == 0) + if (low == 0 && (bfd_get_file_flags (obfd) & HAS_RELOC) == 0) return 0; *lowpc = low; *highpc = high; - return 1; + 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 dwarf2_add_field (struct field_info *fip, struct die_info *die, - struct objfile *objfile, - const struct comp_unit_head *cu_header) -{ + struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; struct nextfield *new_field; struct attribute *attr; struct field *fp; @@ -2067,23 +2732,28 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, 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) + + if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu)) { + /* Data member other than a C++ static data member. */ + /* Get type of field. */ - fp->type = die_type (die, objfile, cu_header); + fp->type = die_type (die, cu); + + 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); @@ -2094,15 +2764,15 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, } /* 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) = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header) * bits_per_byte; + decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte; } 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) @@ -2125,7 +2795,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, 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 @@ -2147,50 +2817,59 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, } /* 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; } } - else if (die->tag == DW_TAG_variable) + else if (die->tag == DW_TAG_member || die->tag == DW_TAG_variable) { + /* C++ static member. */ + + /* NOTE: carlton/2002-11-05: It should be a DW_TAG_member that + is a declaration, but all versions of G++ as of this writing + (so through at least 3.2.1) incorrectly generate + DW_TAG_variable tags. */ + char *physname; - /* C++ static member. - Get name of field. */ - attr = dwarf_attr (die, DW_AT_name); + /* Get name of field. */ + 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)); - FIELD_TYPE (*fp) = die_type (die, objfile, cu_header); - FIELD_NAME (*fp) = 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. */ + SET_FIELD_PHYSNAME (*fp, physname ? physname : ""); + FIELD_TYPE (*fp) = die_type (die, cu); + 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), objfile, cu_header) + FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte); FIELD_BITSIZE (*fp) = 0; - FIELD_TYPE (*fp) = die_type (die, objfile, cu_header); + FIELD_STATIC_KIND (*fp) = 0; + FIELD_TYPE (*fp) = die_type (die, cu); FIELD_NAME (*fp) = type_name_no_tag (fp->type); fip->nbaseclasses++; } @@ -2200,7 +2879,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, static void dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, - struct objfile *objfile) + struct dwarf2_cu *cu) { int nfields = fip->nfields; @@ -2264,8 +2943,8 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, default: /* Unknown accessibility. Complain and treat it as public. */ { - complain (&dwarf2_unsupported_accessibility, - fip->fields->accessibility); + complaint (&symfile_complaints, "unsupported accessibility %d", + fip->fields->accessibility); } break; } @@ -2287,9 +2966,9 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, static void dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, - struct type *type, struct objfile *objfile, - const struct comp_unit_head *cu_header) + struct type *type, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct attribute *attr; struct fnfieldlist *flp; int i; @@ -2299,19 +2978,19 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, 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++) { - if (STREQ (fip->fnfieldlists[i].name, fieldname)) + if (strcmp (fip->fnfieldlists[i].name, fieldname) == 0) break; } @@ -2347,12 +3026,12 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, /* 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) { - struct type *return_type = TYPE_TARGET_TYPE (die->type); int nparams = TYPE_NFIELDS (die->type); /* TYPE is the domain of this method, and DIE->TYPE is the type @@ -2373,17 +3052,18 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, fnp->voffset = VOFFSET_STATIC; } else - complain (&dwarf2_missing_member_fn_type_complaint, physname); + complaint (&symfile_complaints, "member function type missing for '%s'", + physname); /* Get fcontext from DW_AT_containing_type if present. */ - if (dwarf_attr (die, DW_AT_containing_type) != NULL) - fnp->fcontext = die_containing_type (die, objfile, cu_header); + 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)) @@ -2398,27 +3078,27 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, } /* 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 */ if (attr_form_is_block (attr)) { - fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2; + fnp->voffset = decode_locdesc (DW_BLOCK (attr), cu) + 2; } else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) { - complain (&dwarf2_complex_location_expr); + dwarf2_complex_location_expr_complaint (); } else { - complain (&dwarf2_invalid_attrib_class, "DW_AT_vtable_elem_location", - fieldname); + dwarf2_invalid_attrib_class_complaint ("DW_AT_vtable_elem_location", + fieldname); } } } @@ -2427,7 +3107,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, static void dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type, - struct objfile *objfile) + struct dwarf2_cu *cu) { struct fnfieldlist *flp; int total_length = 0; @@ -2474,21 +3154,61 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type, suppresses creating a symbol table entry itself). */ static void -read_structure_scope (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_structure_scope (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct type *type; struct attribute *attr; + 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; 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)) { - TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr), - strlen (DW_STRING (attr)), - &objfile->type_obstack); + name = DW_STRING (attr); + + if (cu->language == language_cplus) + { + struct die_info *spec_die = die_specification (die, cu); + + 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 (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->objfile_obstack, + processing_current_prefix, + processing_current_prefix[0] == '\0' + ? "" : "::", + name); + TYPE_TAG_NAME (type) = new_prefix; + processing_current_prefix = new_prefix; + } + else + { + /* The name is already allocated along with this objfile, so + we don't need to duplicate it for the type. */ + TYPE_TAG_NAME (type) = name; + need_to_update_name = (cu->language == language_cplus); + } } if (die->tag == DW_TAG_structure_type) @@ -2506,7 +3226,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, 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); @@ -2521,7 +3241,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, type within the structure itself. */ die->type = type; - if (die->has_children && ! die_is_declaration (die)) + if (die->child != NULL && ! die_is_declaration (die, cu)) { struct field_info fi; struct die_info *child_die; @@ -2529,51 +3249,87 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, memset (&fi, 0, sizeof (struct field_info)); - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { - if (child_die->tag == DW_TAG_member) + if (child_die->tag == DW_TAG_member + || child_die->tag == DW_TAG_variable) { - dwarf2_add_field (&fi, child_die, objfile, cu_header); - } - else if (child_die->tag == DW_TAG_variable) - { - /* C++ static member. */ - dwarf2_add_field (&fi, child_die, objfile, cu_header); + /* NOTE: carlton/2002-11-05: A C++ static data member + should be a DW_TAG_member that is a declaration, but + all versions of G++ as of this writing (so through at + least 3.2.1) incorrectly generate DW_TAG_variable + tags for them instead. */ + dwarf2_add_field (&fi, child_die, cu); } else if (child_die->tag == DW_TAG_subprogram) { /* C++ member function. */ - process_die (child_die, objfile, cu_header); - dwarf2_add_member_fn (&fi, child_die, type, objfile, cu_header); + process_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, cu)); + if (actual_class_name != NULL + && strcmp (actual_class_name, name) != 0) + { + TYPE_TAG_NAME (type) + = obsavestring (actual_class_name, + strlen (actual_class_name), + &objfile->objfile_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, objfile, cu_header); + dwarf2_add_field (&fi, child_die, cu); } else { - process_die (child_die, objfile, cu_header); + process_die (child_die, cu); } child_die = sibling_die (child_die); } /* Attach fields and member functions to the type. */ if (fi.nfields) - dwarf2_attach_fields_to_type (&fi, type, objfile); + dwarf2_attach_fields_to_type (&fi, type, cu); if (fi.nfnfields) { - dwarf2_attach_fn_fields_to_type (&fi, type, objfile); + dwarf2_attach_fn_fields_to_type (&fi, type, cu); /* Get the type which refers to the base class (possibly this class itself) which contains the vtable pointer for the current class from the DW_AT_containing_type attribute. */ - 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, objfile, cu_header); + struct type *t = die_containing_type (die, cu); TYPE_VPTR_BASETYPE (type) = t; if (type == t) @@ -2589,7 +3345,9 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, { char *fieldname = TYPE_FIELD_NAME (t, i); - if (STREQN (fieldname, vptr_name, strlen (vptr_name) - 1) + if ((strncmp (fieldname, vptr_name, + strlen (vptr_name) - 1) + == 0) && is_cplus_marker (fieldname[strlen (vptr_name)])) { TYPE_VPTR_FIELDNO (type) = i; @@ -2599,8 +3357,10 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, /* Complain if virtual function table field not found. */ if (i < TYPE_N_BASECLASSES (t)) - complain (&dwarf2_vtbl_not_found_complaint, - TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : ""); + complaint (&symfile_complaints, + "virtual function table pointer not found when defining class '%s'", + TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : + ""); } else { @@ -2609,7 +3369,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, } } - new_symbol (die, type, objfile, cu_header); + new_symbol (die, type, cu); do_cleanups (back_to); } @@ -2618,6 +3378,10 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, /* No children, must be stub. */ TYPE_FLAGS (type) |= TYPE_FLAG_STUB; } + + processing_current_prefix = previous_prefix; + if (back_to != NULL) + do_cleanups (back_to); } /* Given a pointer to a die which begins an enumeration, process all @@ -2630,9 +3394,9 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, NOTE: We reverse the order of the element list. */ static void -read_enumeration (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_enumeration (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct die_info *child_die; struct type *type; struct field *fields; @@ -2644,15 +3408,28 @@ read_enumeration (struct die_info *die, struct objfile *objfile, 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)) { - TYPE_TAG_NAME (type) = obsavestring (DW_STRING (attr), - strlen (DW_STRING (attr)), - &objfile->type_obstack); + char *name = DW_STRING (attr); + + if (processing_has_namespace_info) + { + TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack, + processing_current_prefix, + processing_current_prefix[0] == '\0' + ? "" : "::", + name); + } + else + { + /* The name is already allocated along with this objfile, so + we don't need to duplicate it for the type. */ + TYPE_TAG_NAME (type) = name; + } } - 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); @@ -2664,21 +3441,21 @@ read_enumeration (struct die_info *die, struct objfile *objfile, num_fields = 0; fields = NULL; - if (die->has_children) + if (die->child != NULL) { - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { if (child_die->tag != DW_TAG_enumerator) { - process_die (child_die, objfile, cu_header); + process_die (child_die, cu); } 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, objfile, cu_header); + sym = new_symbol (child_die, type, cu); if (SYMBOL_VALUE (sym) < 0) unsigned_enum = 0; @@ -2690,10 +3467,11 @@ read_enumeration (struct die_info *die, struct objfile *objfile, * sizeof (struct field)); } - FIELD_NAME (fields[num_fields]) = SYMBOL_NAME (sym); + FIELD_NAME (fields[num_fields]) = DEPRECATED_SYMBOL_NAME (sym); FIELD_TYPE (fields[num_fields]) = NULL; FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym); FIELD_BITSIZE (fields[num_fields]) = 0; + FIELD_STATIC_KIND (fields[num_fields]) = 0; num_fields++; } @@ -2715,7 +3493,7 @@ read_enumeration (struct die_info *die, struct objfile *objfile, TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED; } die->type = type; - new_symbol (die, type, objfile, cu_header); + new_symbol (die, type, cu); } /* Extract all information from a DW_TAG_array_type DIE and put it in @@ -2723,9 +3501,9 @@ read_enumeration (struct die_info *die, struct objfile *objfile, arrays. */ static void -read_array_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_array_type (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct die_info *child_die; struct type *type = NULL; struct type *element_type, *range_type, *index_type; @@ -2740,110 +3518,40 @@ read_array_type (struct die_info *die, struct objfile *objfile, return; } - element_type = die_type (die, objfile, cu_header); + element_type = die_type (die, cu); /* Irix 6.2 native cc creates array types without children for arrays with unspecified length. */ - if (die->has_children == 0) + 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; } back_to = make_cleanup (null_cleanup, NULL); - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { 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, objfile, cu_header); - 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 - { - complain (&dwarf2_non_const_array_bound_ignored, - dwarf_form_name (attr->form)); -#ifdef FORTRAN_HACK - die->type = lookup_pointer_type (element_type); - return; -#else - low = 0; -#endif - } - } - 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. */ - high = -1; - } - else - { - complain (&dwarf2_non_const_array_bound_ignored, - dwarf_form_name (attr->form)); -#ifdef FORTRAN_HACK - die->type = lookup_pointer_type (element_type); - return; -#else - high = 1; -#endif - } - } - - /* 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); } @@ -2860,7 +3568,7 @@ read_array_type (struct die_info *die, struct objfile *objfile, 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; @@ -2873,43 +3581,42 @@ read_array_type (struct die_info *die, struct objfile *objfile, /* First cut: install each common block member as a global variable. */ static void -read_common_block (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_common_block (struct die_info *die, struct dwarf2_cu *cu) { struct die_info *child_die; struct attribute *attr; 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 */ if (attr_form_is_block (attr)) { - base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + base = decode_locdesc (DW_BLOCK (attr), cu); } else if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) { - complain (&dwarf2_complex_location_expr); + dwarf2_complex_location_expr_complaint (); } else { - complain (&dwarf2_invalid_attrib_class, "DW_AT_location", - "common block member"); + dwarf2_invalid_attrib_class_complaint ("DW_AT_location", + "common block member"); } } - if (die->has_children) + if (die->child != NULL) { - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { - sym = new_symbol (child_die, NULL, objfile, cu_header); - attr = dwarf_attr (child_die, DW_AT_data_member_location); + sym = new_symbol (child_die, NULL, cu); + attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu); if (attr) { SYMBOL_VALUE_ADDRESS (sym) = - base + decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + base + decode_locdesc (DW_BLOCK (attr), cu); add_symbol_to_list (sym, &global_symbols); } child_die = sibling_die (child_die); @@ -2917,31 +3624,159 @@ read_common_block (struct die_info *die, struct objfile *objfile, } } +/* Read a C++ namespace. */ + +static void +read_namespace (struct die_info *die, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + const char *previous_prefix = processing_current_prefix; + const char *name; + int is_anonymous; + struct die_info *current_die; + + name = namespace_name (die, &is_anonymous, cu); + + /* Now build the name of the current namespace. */ + + if (previous_prefix[0] == '\0') + { + processing_current_prefix = name; + } + else + { + /* We need temp_name around because processing_current_prefix + is a const char *. */ + char *temp_name = alloca (strlen (previous_prefix) + + 2 + strlen(name) + 1); + strcpy (temp_name, previous_prefix); + strcat (temp_name, "::"); + strcat (temp_name, name); + + processing_current_prefix = temp_name; + } + + /* Add a symbol associated to this if we haven't seen the namespace + before. Also, add a using directive if it's an anonymous + namespace. */ + + if (dwarf2_extension (die, cu) == NULL) + { + struct type *type; + + /* FIXME: carlton/2003-06-27: Once GDB is more const-correct, + this cast will hopefully become unnecessary. */ + type = init_type (TYPE_CODE_NAMESPACE, 0, 0, + (char *) processing_current_prefix, + objfile); + TYPE_TAG_NAME (type) = TYPE_NAME (type); + + new_symbol (die, type, cu); + + if (is_anonymous) + cp_add_using_directive (processing_current_prefix, + strlen (previous_prefix), + strlen (processing_current_prefix)); + } + + if (die->child != NULL) + { + struct die_info *child_die = die->child; + + while (child_die && child_die->tag) + { + process_die (child_die, cu); + child_die = sibling_die (child_die); + } + } + + processing_current_prefix = previous_prefix; +} + +/* Return the name of the namespace represented by DIE. Set + *IS_ANONYMOUS to tell whether or not the namespace is an anonymous + namespace. */ + +static const char * +namespace_name (struct die_info *die, int *is_anonymous, struct dwarf2_cu *cu) +{ + struct die_info *current_die; + const char *name = NULL; + + /* Loop through the extensions until we find a name. */ + + for (current_die = die; + current_die != NULL; + current_die = dwarf2_extension (die, cu)) + { + name = dwarf2_name (current_die, cu); + if (name != NULL) + break; + } + + /* Is it an anonymous namespace? */ + + *is_anonymous = (name == NULL); + if (*is_anonymous) + name = "(anonymous namespace)"; + + return name; +} + /* Extract all information from a DW_TAG_pointer_type DIE and add to the user defined type vector. */ static void -read_tag_pointer_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu) { + struct comp_unit_head *cu_header = &cu->header; struct type *type; - struct attribute *attr; + struct attribute *attr_byte_size; + struct attribute *attr_address_class; + int byte_size, addr_class; if (die->type) { return; } - type = lookup_pointer_type (die_type (die, objfile, cu_header)); - attr = dwarf_attr (die, DW_AT_byte_size); - if (attr) - { - TYPE_LENGTH (type) = DW_UNSND (attr); - } + type = lookup_pointer_type (die_type (die, cu)); + + 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 = dwarf2_attr (die, DW_AT_address_class, cu); + if (attr_address_class) + addr_class = DW_UNSND (attr_address_class); else + addr_class = DW_ADDR_none; + + /* If the pointer size or address class is different than the + default, create a type variant marked as such and set the + length accordingly. */ + if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none) { - TYPE_LENGTH (type) = cu_header->addr_size; + if (ADDRESS_CLASS_TYPE_FLAGS_P ()) + { + int type_flags; + + type_flags = ADDRESS_CLASS_TYPE_FLAGS (byte_size, addr_class); + gdb_assert ((type_flags & ~TYPE_FLAG_ADDRESS_CLASS_ALL) == 0); + type = make_type_with_address_space (type, type_flags); + } + else if (TYPE_LENGTH (type) != byte_size) + { + complaint (&symfile_complaints, "invalid pointer size %d", byte_size); + } + else { + /* Should we also complain about unhandled address classes? */ + } } + + TYPE_LENGTH (type) = byte_size; die->type = type; } @@ -2949,9 +3784,9 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile, the user defined type vector. */ static void -read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct type *type; struct type *to_type; struct type *domain; @@ -2962,8 +3797,8 @@ read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile, } type = alloc_type (objfile); - to_type = die_type (die, objfile, cu_header); - domain = die_containing_type (die, objfile, cu_header); + to_type = die_type (die, cu); + domain = die_containing_type (die, cu); smash_to_member_type (type, domain, to_type); die->type = type; @@ -2973,9 +3808,9 @@ read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile, the user defined type vector. */ static void -read_tag_reference_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu) { + struct comp_unit_head *cu_header = &cu->header; struct type *type; struct attribute *attr; @@ -2984,8 +3819,8 @@ read_tag_reference_type (struct die_info *die, struct objfile *objfile, return; } - type = lookup_reference_type (die_type (die, objfile, cu_header)); - attr = dwarf_attr (die, DW_AT_byte_size); + type = lookup_reference_type (die_type (die, cu)); + attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) { TYPE_LENGTH (type) = DW_UNSND (attr); @@ -2998,8 +3833,7 @@ read_tag_reference_type (struct die_info *die, struct objfile *objfile, } static void -read_tag_const_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *base_type; @@ -3008,13 +3842,12 @@ read_tag_const_type (struct die_info *die, struct objfile *objfile, return; } - base_type = die_type (die, objfile, cu_header); + base_type = die_type (die, cu); die->type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0); } static void -read_tag_volatile_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *base_type; @@ -3023,7 +3856,7 @@ read_tag_volatile_type (struct die_info *die, struct objfile *objfile, return; } - base_type = die_type (die, objfile, cu_header); + base_type = die_type (die, cu); die->type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0); } @@ -3033,8 +3866,9 @@ read_tag_volatile_type (struct die_info *die, struct objfile *objfile, attribute to reference it. */ static void -read_tag_string_type (struct die_info *die, struct objfile *objfile) +read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct type *type, *range_type, *index_type, *char_type; struct attribute *attr; unsigned int length; @@ -3044,7 +3878,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) return; } - attr = dwarf_attr (die, DW_AT_string_length); + attr = dwarf2_attr (die, DW_AT_string_length, cu); if (attr) { length = DW_UNSND (attr); @@ -3052,7 +3886,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) 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); @@ -3062,9 +3896,9 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) 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 */ @@ -3072,7 +3906,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) } 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; @@ -3090,8 +3924,7 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile) */ static void -read_subroutine_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *type; /* Type that this function returns */ struct type *ftype; /* Function that returns above type */ @@ -3102,16 +3935,16 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile, { return; } - type = die_type (die, objfile, cu_header); + type = die_type (die, cu); 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->has_children) + if (die->child != NULL) { struct die_info *child_die; int nparams = 0; @@ -3120,7 +3953,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile, /* Count the number of parameters. FIXME: GDB currently ignores vararg functions, but knows about vararg member functions. */ - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { if (child_die->tag == DW_TAG_formal_parameter) @@ -3135,7 +3968,7 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile, TYPE_FIELDS (ftype) = (struct field *) TYPE_ALLOC (ftype, nparams * sizeof (struct field)); - child_die = die->next; + child_die = die->child; while (child_die && child_die->tag) { if (child_die->tag == DW_TAG_formal_parameter) @@ -3145,13 +3978,12 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile, 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 TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0; - TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, objfile, - cu_header); + TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, cu); iparams++; } child_die = sibling_die (child_die); @@ -3162,21 +3994,21 @@ read_subroutine_type (struct die_info *die, struct objfile *objfile, } static void -read_typedef (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_typedef (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct attribute *attr; char *name = NULL; 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); } die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile); - TYPE_TARGET_TYPE (die->type) = die_type (die, objfile, cu_header); + TYPE_TARGET_TYPE (die->type) = die_type (die, cu); } } @@ -3184,8 +4016,9 @@ read_typedef (struct die_info *die, struct objfile *objfile, it in the TYPE field of the die. */ static void -read_base_type (struct die_info *die, struct objfile *objfile) +read_base_type (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct type *type; struct attribute *attr; int encoding = 0, size = 0; @@ -3196,17 +4029,17 @@ read_base_type (struct die_info *die, struct objfile *objfile) 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; @@ -3237,79 +4070,193 @@ read_base_type (struct die_info *die, struct objfile *objfile) type_flags |= TYPE_FLAG_UNSIGNED; break; default: - complain (&dwarf2_unsupported_at_encoding, - dwarf_type_encoding_name (encoding)); + complaint (&symfile_complaints, "unsupported DW_AT_encoding: '%s'", + dwarf_type_encoding_name (encoding)); break; } 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 { - type = dwarf_base_type (encoding, size, objfile); + type = dwarf_base_type (encoding, size, cu); } 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 * -read_comp_unit (char *info_ptr, bfd *abfd, - const struct comp_unit_head *cu_header) +read_comp_unit (char *info_ptr, bfd *abfd, struct dwarf2_cu *cu) { - struct die_info *first_die, *last_die, *die; - char *cur_ptr; - int nesting_level; - /* Reset die reference table; we are building new ones now. */ dwarf2_empty_hash_tables (); + return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL); +} + +/* Read a single die and all its descendents. Set the die's sibling + field to NULL; set other fields in the die correctly, and set all + of the descendents' fields correctly. Set *NEW_INFO_PTR to the + location of the info_ptr after reading all of those dies. PARENT + is the parent of the die in question. */ + +static struct die_info * +read_die_and_children (char *info_ptr, bfd *abfd, + struct dwarf2_cu *cu, + char **new_info_ptr, + struct die_info *parent) +{ + struct die_info *die; + char *cur_ptr; + int has_children; + + cur_ptr = read_full_die (&die, abfd, info_ptr, cu, &has_children); + store_in_ref_table (die->offset, die); + + if (has_children) + { + die->child = read_die_and_siblings (cur_ptr, abfd, cu, + new_info_ptr, die); + } + else + { + die->child = NULL; + *new_info_ptr = cur_ptr; + } + + die->sibling = NULL; + die->parent = parent; + return die; +} + +/* Read a die, all of its descendents, and all of its siblings; set + all of the fields of all of the dies correctly. Arguments are as + in read_die_and_children. */ + +static struct die_info * +read_die_and_siblings (char *info_ptr, bfd *abfd, + struct dwarf2_cu *cu, + char **new_info_ptr, + struct die_info *parent) +{ + struct die_info *first_die, *last_sibling; + char *cur_ptr; + cur_ptr = info_ptr; - nesting_level = 0; - first_die = last_die = NULL; - do + first_die = last_sibling = NULL; + + while (1) { - cur_ptr = read_full_die (&die, abfd, cur_ptr, cu_header); - if (die->has_children) + struct die_info *die + = read_die_and_children (cur_ptr, abfd, cu, &cur_ptr, parent); + + if (!first_die) { - nesting_level++; + first_die = die; } - if (die->tag == 0) + else { - nesting_level--; + last_sibling->sibling = die; } - die->next = NULL; - - /* Enter die in reference hash table */ - store_in_ref_table (die->offset, die); - - if (!first_die) + if (die->tag == 0) { - first_die = last_die = die; + *new_info_ptr = cur_ptr; + return first_die; } else { - last_die->next = die; - last_die = die; + last_sibling = die; } } - while (nesting_level > 0); - return first_die; } /* Free a linked list of dies. */ @@ -3322,7 +4269,9 @@ free_die_list (struct die_info *dies) die = dies; while (die) { - next = die->next; + if (die->child != NULL) + free_die_list (die->child); + next = die->sibling; xfree (die->attrs); xfree (die); die = next; @@ -3343,26 +4292,29 @@ make_cleanup_free_die_list (struct die_info *dies) /* 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, file_ptr offset, - unsigned int size) +dwarf2_read_section (struct objfile *objfile, asection *sectp) { bfd *abfd = objfile->obfd; - char *buf; + char *buf, *retbuf; + bfd_size_type size = bfd_get_section_size_before_reloc (sectp); if (size == 0) return NULL; - buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size); - if ((bfd_seek (abfd, offset, SEEK_SET) != 0) || - (bfd_bread (buf, size, abfd) != size)) - { - buf = NULL; - error ("Dwarf Error: Can't read DWARF data from '%s'", - bfd_get_filename (abfd)); - } + buf = (char *) obstack_alloc (&objfile->objfile_obstack, size); + retbuf + = (char *) symfile_relocate_debug_section (abfd, sectp, (bfd_byte *) buf); + if (retbuf != NULL) + return retbuf; + + if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 + || bfd_bread (buf, size, abfd) != size) + error ("Dwarf Error: Can't read DWARF data from '%s'", + bfd_get_filename (abfd)); + return buf; } @@ -3372,25 +4324,35 @@ dwarf2_read_section (struct objfile *objfile, file_ptr offset, in a hash table. */ static void -dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header) +dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) { + struct comp_unit_head *cu_header = &cu->header; char *abbrev_ptr; 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; @@ -3406,24 +4368,30 @@ dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header) 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 @@ -3437,48 +4405,34 @@ dwarf2_read_abbrevs (bfd *abfd, struct comp_unit_head *cu_header) break; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; - if (dwarf2_lookup_abbrev (abbrev_number, cu_header) != NULL) + 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. */ -/* ARGSUSED */ static void -dwarf2_empty_abbrev_table (PTR 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, const struct comp_unit_head *cu_header) +dwarf2_lookup_abbrev (unsigned int number, struct dwarf2_cu *cu) { 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) { @@ -3494,7 +4448,7 @@ dwarf2_lookup_abbrev (unsigned int number, const struct comp_unit_head *cu_heade static char * read_partial_die (struct partial_die_info *part_die, bfd *abfd, - char *info_ptr, const struct comp_unit_head *cu_header) + char *info_ptr, struct dwarf2_cu *cu) { unsigned int abbrev_number, bytes_read, i; struct abbrev_info *abbrev; @@ -3510,10 +4464,11 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, if (!abbrev_number) return info_ptr; - abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header); + abbrev = dwarf2_lookup_abbrev (abbrev_number, cu); if (!abbrev) { - error ("Dwarf Error: Could not find abbrev number %d.", abbrev_number); + error ("Dwarf Error: Could not find abbrev number %d [in module %s]", abbrev_number, + bfd_get_filename (abfd)); } part_die->offset = info_ptr - dwarf_info_buffer; part_die->tag = abbrev->tag; @@ -3522,8 +4477,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, for (i = 0; i < abbrev->num_attrs; ++i) { - info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, - info_ptr, cu_header); + info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, info_ptr, cu); /* Store the data if it is of an attribute we want to keep in a partial symbol table. */ @@ -3554,12 +4508,12 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, } else if (attr.form == DW_FORM_data4 || attr.form == DW_FORM_data8) { - complain (&dwarf2_complex_location_expr); + dwarf2_complex_location_expr_complaint (); } else { - complain (&dwarf2_invalid_attrib_class, "DW_AT_location", - "partial symbol information"); + dwarf2_invalid_attrib_class_complaint ("DW_AT_location", + "partial symbol information"); } break; case DW_AT_language: @@ -3583,10 +4537,10 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, /* Ignore absolute siblings, they might point outside of the current compile unit. */ if (attr.form == DW_FORM_ref_addr) - complain (&dwarf2_absolute_sibling_complaint); + 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; @@ -3600,10 +4554,10 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, { struct partial_die_info spec_die; char *spec_ptr; - int dummy; - spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr); - read_partial_die (&spec_die, abfd, spec_ptr, cu_header); + 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) { part_die->name = spec_die.name; @@ -3630,12 +4584,14 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, return info_ptr; } -/* Read the die from the .debug_info section buffer. And set diep to - point to a newly allocated die with its information. */ +/* Read the die from the .debug_info section buffer. Set DIEP to + point to a newly allocated die with its information, except for its + child, sibling, and parent fields. Set HAS_CHILDREN to tell + whether the die has children or not. */ static char * read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr, - const struct comp_unit_head *cu_header) + struct dwarf2_cu *cu, int *has_children) { unsigned int abbrev_number, bytes_read, i, offset; struct abbrev_info *abbrev; @@ -3651,18 +4607,20 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr, die->abbrev = abbrev_number; die->type = NULL; *diep = die; + *has_children = 0; return info_ptr; } - abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header); + abbrev = dwarf2_lookup_abbrev (abbrev_number, cu); if (!abbrev) { - error ("Dwarf Error: could not find abbrev number %d.", abbrev_number); + error ("Dwarf Error: could not find abbrev number %d [in module %s]", + abbrev_number, + bfd_get_filename (abfd)); } die = dwarf_alloc_die (); die->offset = offset; die->tag = abbrev->tag; - die->has_children = abbrev->has_children; die->abbrev = abbrev_number; die->type = NULL; @@ -3673,10 +4631,11 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr, for (i = 0; i < abbrev->num_attrs; ++i) { info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i], - abfd, info_ptr, cu_header); + abfd, info_ptr, cu); } *diep = die; + *has_children = abbrev->has_children; return info_ptr; } @@ -3684,9 +4643,10 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr, static char * read_attribute_value (struct attribute *attr, unsigned form, - bfd *abfd, char *info_ptr, - const struct comp_unit_head *cu_header) + bfd *abfd, char *info_ptr, + struct dwarf2_cu *cu) { + struct comp_unit_head *cu_header = &cu->header; unsigned int bytes_read; struct dwarf_block *blk; @@ -3695,7 +4655,7 @@ read_attribute_value (struct attribute *attr, unsigned form, { case DW_FORM_addr: case DW_FORM_ref_addr: - DW_ADDR (attr) = read_address (abfd, info_ptr, cu_header, &bytes_read); + DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read); info_ptr += bytes_read; break; case DW_FORM_block2: @@ -3790,11 +4750,12 @@ read_attribute_value (struct attribute *attr, unsigned form, case DW_FORM_indirect: form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; - info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu_header); + info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu); break; default: - error ("Dwarf Error: Cannot handle %s in DWARF reader.", - dwarf_form_name (form)); + error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]", + dwarf_form_name (form), + bfd_get_filename (abfd)); } return info_ptr; } @@ -3803,11 +4764,10 @@ read_attribute_value (struct attribute *attr, unsigned form, static char * read_attribute (struct attribute *attr, struct attr_abbrev *abbrev, - bfd *abfd, char *info_ptr, - const struct comp_unit_head *cu_header) + bfd *abfd, char *info_ptr, struct dwarf2_cu *cu) { attr->name = abbrev->name; - return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu_header); + return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu); } /* read dwarf information from a buffer */ @@ -3855,9 +4815,9 @@ read_8_bytes (bfd *abfd, char *buf) } static CORE_ADDR -read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, - int *bytes_read) +read_address (bfd *abfd, char *buf, struct dwarf2_cu *cu, int *bytes_read) { + struct comp_unit_head *cu_header = &cu->header; CORE_ADDR retval = 0; if (cu_header->signed_addr_p) @@ -3875,7 +4835,8 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, break; default: internal_error (__FILE__, __LINE__, - "read_address: bad switch, signed"); + "read_address: bad switch, signed [in module %s]", + bfd_get_filename (abfd)); } } else @@ -3893,7 +4854,8 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, break; default: internal_error (__FILE__, __LINE__, - "read_address: bad switch, unsigned"); + "read_address: bad switch, unsigned [in module %s]", + bfd_get_filename (abfd)); } } @@ -4008,7 +4970,8 @@ read_offset (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, break; default: internal_error (__FILE__, __LINE__, - "read_offset: bad switch"); + "read_offset: bad switch [in module %s]", + bfd_get_filename (abfd)); } return retval; @@ -4050,12 +5013,14 @@ read_indirect_string (bfd *abfd, char *buf, if (dwarf_str_buffer == NULL) { - error ("DW_FORM_strp used without .debug_str section"); + error ("DW_FORM_strp used without .debug_str section [in module %s]", + bfd_get_filename (abfd)); return NULL; } if (str_offset >= dwarf_str_size) { - error ("DW_FORM_strp pointing outside of .debug_str section"); + error ("DW_FORM_strp pointing outside of .debug_str section [in module %s]", + bfd_get_filename (abfd)); return NULL; } gdb_assert (HOST_CHAR_BIT == 8); @@ -4124,28 +5089,44 @@ read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr) 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: @@ -4154,16 +5135,16 @@ set_cu_language (unsigned int lang) case DW_LANG_Pascal83: case DW_LANG_Modula2: default: - cu_language = language_unknown; + 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; @@ -4181,22 +5162,35 @@ dwarf_attr (struct die_info *die, unsigned int name) 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, struct dwarf2_cu *cu) +{ + 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, cu)); +} /* Free the line_header structure *LH, and any arrays and strings it refers to. */ @@ -4284,7 +5278,7 @@ add_file_name (struct line_header *lh, freed. */ static struct line_header * dwarf_decode_line_header (unsigned int offset, bfd *abfd, - const struct comp_unit_head *cu_header) + struct dwarf2_cu *cu) { struct cleanup *back_to; struct line_header *lh; @@ -4295,7 +5289,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, if (dwarf_line_buffer == NULL) { - complain (&dwarf2_missing_line_number_section); + complaint (&symfile_complaints, "missing .debug_line section"); return 0; } @@ -4303,7 +5297,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, could be 12 bytes long, but we're just going to fudge that. */ if (offset + 4 >= dwarf_line_size) { - complain (&dwarf2_statement_list_fits_in_line_number_section); + dwarf2_statement_list_fits_in_line_number_section_complaint (); return 0; } @@ -4319,13 +5313,13 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, line_ptr += bytes_read; if (line_ptr + lh->total_length > dwarf_line_buffer + dwarf_line_size) { - complain (&dwarf2_statement_list_fits_in_line_number_section); + dwarf2_statement_list_fits_in_line_number_section_complaint (); return 0; } lh->statement_program_end = line_ptr + lh->total_length; lh->version = read_2_bytes (abfd, line_ptr); line_ptr += 2; - lh->header_length = read_offset (abfd, line_ptr, cu_header, &bytes_read); + lh->header_length = read_offset (abfd, line_ptr, &cu->header, &bytes_read); line_ptr += bytes_read; lh->minimum_instruction_length = read_1_byte (abfd, line_ptr); line_ptr += 1; @@ -4374,7 +5368,8 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, lh->statement_program_start = line_ptr; if (line_ptr > dwarf_line_buffer + dwarf_line_size) - complain (&dwarf2_line_header_too_long); + complaint (&symfile_complaints, + "line number info header doesn't fit in `.debug_line' section"); discard_cleanups (back_to); return lh; @@ -4388,26 +5383,26 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, 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 @@ -4419,8 +5414,9 @@ check_cu_functions (CORE_ADDR address) if (fn->seen_line) return address; if (address != fn->lowpc) - complain (&dwarf2_misplaced_line_number, - (unsigned long) address, fn->name); + complaint (&symfile_complaints, + "misplaced first line number at 0x%lx for '%s'", + (unsigned long) address, fn->name); fn->seen_line = 1; return fn->lowpc; } @@ -4431,13 +5427,16 @@ check_cu_functions (CORE_ADDR address) static void dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, - const struct comp_unit_head *cu_header) + struct dwarf2_cu *cu) { char *line_ptr; char *line_end; - unsigned int i, bytes_read; - char *cur_dir; + 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; @@ -4482,8 +5481,8 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, * lh->minimum_instruction_length; line += lh->line_base + (adj_opcode % lh->line_range); /* append row to matrix using current values */ - address = check_cu_functions (address); - record_line (current_subfile, line, address); + record_line (current_subfile, line, + check_cu_functions (address, cu)); basic_block = 1; } else switch (op_code) @@ -4499,7 +5498,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, record_line (current_subfile, 0, address); break; case DW_LNE_set_address: - address = read_address (abfd, line_ptr, cu_header, &bytes_read); + address = read_address (abfd, line_ptr, cu, &bytes_read); line_ptr += bytes_read; address += baseaddr; break; @@ -4523,13 +5522,14 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, } break; default: - complain (&dwarf2_mangled_line_number_section); + complaint (&symfile_complaints, + "mangled .debug_line section"); return; } break; case DW_LNS_copy: - address = check_cu_functions (address); - record_line (current_subfile, line, address); + record_line (current_subfile, line, + check_cu_functions (address, cu)); basic_block = 0; break; case DW_LNS_advance_pc: @@ -4640,6 +5640,62 @@ dwarf2_start_subfile (char *filename, char *dirname) start_subfile (filename, dirname); } +static void +var_decode_location (struct attribute *attr, struct symbol *sym, + struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; + + /* NOTE drow/2003-01-30: There used to be a comment and some special + code here to turn a symbol with DW_AT_external and a + SYMBOL_VALUE_ADDRESS of 0 into a LOC_UNRESOLVED symbol. This was + necessary for platforms (maybe Alpha, certainly PowerPC GNU/Linux + with some versions of binutils) where shared libraries could have + relocations against symbols in their debug information - the + minimal symbol would have the right address, but the debug info + would not. It's no longer necessary, because we will explicitly + apply relocations when we read in the debug information now. */ + + /* A DW_AT_location attribute with no contents indicates that a + variable has been optimized away. */ + if (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0) + { + SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; + return; + } + + /* Handle one degenerate form of location expression specially, to + preserve GDB's previous behavior when section offsets are + specified. If this is just a DW_OP_addr then mark this symbol + as LOC_STATIC. */ + + if (attr_form_is_block (attr) + && DW_BLOCK (attr)->size == 1 + cu_header->addr_size + && DW_BLOCK (attr)->data[0] == DW_OP_addr) + { + int dummy; + + SYMBOL_VALUE_ADDRESS (sym) = + read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy); + fixup_symbol_section (sym, objfile); + SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, + SYMBOL_SECTION (sym)); + SYMBOL_CLASS (sym) = LOC_STATIC; + return; + } + + /* NOTE drow/2002-01-30: It might be worthwhile to have a static + expression evaluator, and use LOC_COMPUTED only when necessary + (i.e. when the value of a register or memory location is + referenced, or a thread-local block, etc.). Then again, it might + not be worthwhile. I'm assuming that it isn't unless performance + or memory numbers show me otherwise. */ + + dwarf2_symbol_mark_computed (attr, sym, cu); + SYMBOL_CLASS (sym) = LOC_COMPUTED; +} + /* Given a pointer to a DWARF information entry, figure out if we need to make a symbol table entry for it, and if so, create a new entry and return a pointer to it. @@ -4647,51 +5703,50 @@ dwarf2_start_subfile (char *filename, char *dirname) used the passed type. */ static struct symbol * -new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, - const struct comp_unit_head *cu_header) +new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct symbol *sym = NULL; char *name; struct attribute *attr = NULL; struct attribute *attr2 = NULL; - CORE_ADDR addr = 0; + CORE_ADDR baseaddr; + + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + if (die->tag != DW_TAG_namespace) + name = dwarf2_linkage_name (die, cu); + else + name = TYPE_NAME (type); - name = dwarf2_linkage_name (die); 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)); - SYMBOL_NAME (sym) = obsavestring (name, strlen (name), - &objfile->symbol_obstack); + + /* Cache this symbol's name and the name's demangled form (if any). */ + SYMBOL_LANGUAGE (sym) = cu->language; + SYMBOL_SET_NAMES (sym, name, strlen (name), objfile); /* Default assumptions. Use the passed type or decode it from the die. */ - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; SYMBOL_CLASS (sym) = LOC_STATIC; if (type != NULL) SYMBOL_TYPE (sym) = type; else - SYMBOL_TYPE (sym) = die_type (die, objfile, cu_header); - attr = dwarf_attr (die, DW_AT_decl_line); + SYMBOL_TYPE (sym) = die_type (die, cu); + attr = dwarf2_attr (die, DW_AT_decl_line, cu); if (attr) { SYMBOL_LINE (sym) = DW_UNSND (attr); } - - /* If this symbol is from a C++ compilation, then attempt to - cache the demangled form for future reference. This is a - typical time versus space tradeoff, that was decided in favor - of time because it sped up C++ symbol lookups by a factor of - about 20. */ - - SYMBOL_LANGUAGE (sym) = cu_language; - SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack); 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; @@ -4702,14 +5757,14 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, /* 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: @@ -4721,107 +5776,26 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, TARGET_INT_BIT / HOST_CHAR_BIT, 0, "", 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, objfile, cu_header); - attr2 = dwarf_attr (die, DW_AT_external); + dwarf2_const_value (attr, sym, cu); + 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) { - attr2 = dwarf_attr (die, DW_AT_external); + var_decode_location (attr, sym, cu); + attr2 = dwarf2_attr (die, DW_AT_external, cu); if (attr2 && (DW_UNSND (attr2) != 0)) - { - /* Support the .debug_loc offsets */ - if (attr_form_is_block (attr)) - { - SYMBOL_VALUE_ADDRESS (sym) = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header); - } - else if (attr->form == DW_FORM_data4 - || attr->form == DW_FORM_data8) - { - complain (&dwarf2_complex_location_expr); - } - else - { - complain (&dwarf2_invalid_attrib_class, "DW_AT_location", - "external variable"); - } - add_symbol_to_list (sym, &global_symbols); - - /* In shared libraries the address of the variable - in the location descriptor might still be relocatable, - so its value could be zero. - Enter the symbol as a LOC_UNRESOLVED symbol, if its - value is zero, the address of the variable will then - be determined from the minimal symbol table whenever - the variable is referenced. */ - if (SYMBOL_VALUE_ADDRESS (sym)) - { - fixup_symbol_section (sym, objfile); - SYMBOL_VALUE_ADDRESS (sym) += - ANOFFSET (objfile->section_offsets, - SYMBOL_SECTION (sym)); - SYMBOL_CLASS (sym) = LOC_STATIC; - } - else - SYMBOL_CLASS (sym) = LOC_UNRESOLVED; - } + add_symbol_to_list (sym, &global_symbols); else - { - /* Support the .debug_loc offsets */ - if (attr_form_is_block (attr)) - { - SYMBOL_VALUE (sym) = addr = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header); - } - else if (attr->form == DW_FORM_data4 - || attr->form == DW_FORM_data8) - { - complain (&dwarf2_complex_location_expr); - } - else - { - complain (&dwarf2_invalid_attrib_class, "DW_AT_location", - "external variable"); - addr = 0; - } - add_symbol_to_list (sym, list_in_scope); - if (optimized_out) - { - SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT; - } - else if (isreg) - { - SYMBOL_CLASS (sym) = LOC_REGISTER; - SYMBOL_VALUE (sym) = - DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym)); - } - else if (offreg) - { - SYMBOL_CLASS (sym) = LOC_BASEREG; - SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); - } - else if (islocal) - { - SYMBOL_CLASS (sym) = LOC_LOCAL; - } - else - { - fixup_symbol_section (sym, objfile); - SYMBOL_VALUE_ADDRESS (sym) = - addr + ANOFFSET (objfile->section_offsets, - SYMBOL_SECTION (sym)); - SYMBOL_CLASS (sym) = LOC_STATIC; - } - } + add_symbol_to_list (sym, cu->list_in_scope); } else { @@ -4831,9 +5805,9 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, 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); @@ -4841,42 +5815,20 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, } break; case DW_TAG_formal_parameter: - attr = dwarf_attr (die, DW_AT_location); + attr = dwarf2_attr (die, DW_AT_location, cu); if (attr) { - SYMBOL_VALUE (sym) = - decode_locdesc (DW_BLOCK (attr), objfile, cu_header); - if (isreg) - { - SYMBOL_CLASS (sym) = LOC_REGPARM; - SYMBOL_VALUE (sym) = - DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym)); - } - else if (offreg) - { - if (isderef) - { - if (basereg != frame_base_reg) - complain (&dwarf2_complex_location_expr); - SYMBOL_CLASS (sym) = LOC_REF_ARG; - } - else - { - SYMBOL_CLASS (sym) = LOC_BASEREG_ARG; - SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); - } - } - else - { - SYMBOL_CLASS (sym) = LOC_ARG; - } + var_decode_location (attr, sym, cu); + /* FIXME drow/2003-07-31: Is LOC_COMPUTED_ARG necessary? */ + if (SYMBOL_CLASS (sym) == LOC_COMPUTED) + SYMBOL_CLASS (sym) = LOC_COMPUTED_ARG; } - attr = dwarf_attr (die, DW_AT_const_value); + attr = dwarf2_attr (die, DW_AT_const_value, cu); if (attr) { - dwarf2_const_value (attr, sym, objfile, cu_header); + 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 @@ -4888,47 +5840,122 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, case DW_TAG_union_type: case DW_TAG_enumeration_type: SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE; - add_symbol_to_list (sym, list_in_scope); + SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; + + /* 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 + the type. */ - /* 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, - sizeof (struct symbol)); - *typedef_sym = *sym; - SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE; - if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) - TYPE_NAME (SYMBOL_TYPE (sym)) = - obsavestring (SYMBOL_NAME (sym), - strlen (SYMBOL_NAME (sym)), - &objfile->type_obstack); - add_symbol_to_list (typedef_sym, list_in_scope); + struct type *type = SYMBOL_TYPE (sym); + + if (TYPE_TAG_NAME (type) != NULL) + { + /* FIXME: carlton/2003-11-10: Should this use + SYMBOL_SET_NAMES instead? (The same problem also + 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); + } } + + { + /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't + really ever be static objects: otherwise, if you try + to, say, break of a class's method and you're in a file + which doesn't mention that class, it won't work unless + the check for all static symbols in lookup_symbol_aux + saves you. See the OtherFileClass tests in + gdb.c++/namespace.exp. */ + + struct pending **list_to_add; + + 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) + { + struct symbol *typedef_sym = (struct symbol *) + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct symbol)); + *typedef_sym = *sym; + SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN; + /* The symbol's name is already allocated along with + this objfile, so we don't need to duplicate it for + the type. */ + if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) + TYPE_NAME (SYMBOL_TYPE (sym)) = SYMBOL_NATURAL_NAME (sym); + add_symbol_to_list (typedef_sym, list_to_add); + } + } break; case DW_TAG_typedef: + if (processing_has_namespace_info + && processing_current_prefix[0] != '\0') + { + 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, cu->list_in_scope); + break; case DW_TAG_base_type: + case DW_TAG_subrange_type: SYMBOL_CLASS (sym) = LOC_TYPEDEF; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, list_in_scope); + SYMBOL_DOMAIN (sym) = VAR_DOMAIN; + add_symbol_to_list (sym, cu->list_in_scope); break; case DW_TAG_enumerator: - attr = dwarf_attr (die, DW_AT_const_value); + if (processing_has_namespace_info + && processing_current_prefix[0] != '\0') + { + SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack, + processing_current_prefix, + "::", + name); + } + attr = dwarf2_attr (die, DW_AT_const_value, cu); if (attr) { - dwarf2_const_value (attr, sym, objfile, cu_header); + dwarf2_const_value (attr, sym, cu); } - add_symbol_to_list (sym, list_in_scope); + { + /* NOTE: carlton/2003-11-10: See comment above in the + DW_TAG_class_type, etc. block. */ + + struct pending **list_to_add; + + 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); + } + break; + case DW_TAG_namespace: + SYMBOL_CLASS (sym) = LOC_TYPEDEF; + add_symbol_to_list (sym, &global_symbols); break; default: /* Not a tag we recognize. Hopefully we aren't processing trash data, but since we must specifically ignore things we don't recognize, there is nothing else we should do at this point. */ - complain (&dwarf2_unsupported_tag, dwarf_tag_name (die->tag)); + complaint (&symfile_complaints, "unsupported tag: '%s'", + dwarf_tag_name (die->tag)); break; } } @@ -4939,21 +5966,26 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, static void dwarf2_const_value (struct attribute *attr, struct symbol *sym, - struct objfile *objfile, - const struct comp_unit_head *cu_header) + struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; struct dwarf_block *blk; switch (attr->form) { case DW_FORM_addr: if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != cu_header->addr_size) - complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym), - cu_header->addr_size, TYPE_LENGTH (SYMBOL_TYPE (sym))); + dwarf2_const_value_length_mismatch_complaint (DEPRECATED_SYMBOL_NAME (sym), + cu_header->addr_size, + TYPE_LENGTH (SYMBOL_TYPE + (sym))); SYMBOL_VALUE_BYTES (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size); - store_address (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size, - DW_ADDR (attr)); + 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, + DW_ADDR (attr)); SYMBOL_CLASS (sym) = LOC_CONST_BYTES; break; case DW_FORM_block1: @@ -4962,10 +5994,12 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym, case DW_FORM_block: blk = DW_BLOCK (attr); if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != blk->size) - complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym), - blk->size, TYPE_LENGTH (SYMBOL_TYPE (sym))); + dwarf2_const_value_length_mismatch_complaint (DEPRECATED_SYMBOL_NAME (sym), + blk->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; @@ -4999,8 +6033,9 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym, break; default: - complain (&dwarf2_unsupported_const_value_attr, - dwarf_form_name (attr->form)); + complaint (&symfile_complaints, + "unsupported const value attribute form: '%s'", + dwarf_form_name (attr->form)); SYMBOL_VALUE (sym) = 0; SYMBOL_CLASS (sym) = LOC_CONST; break; @@ -5033,35 +6068,36 @@ dwarf2_const_value_data (struct attribute *attr, /* Return the type of the die in question using its DW_AT_type attribute. */ static struct type * -die_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +die_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *type; struct attribute *type_attr; 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 (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) { - error ("Dwarf Error: Cannot find referent at offset %d.", ref); + error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", + ref, cu->objfile->name); return NULL; } } - type = tag_type_to_type (type_die, objfile, cu_header); + type = tag_type_to_type (type_die, cu); if (!type) { dump_die (type_die); - error ("Dwarf Error: Problem turning type die at offset into gdb type."); + error ("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]", + cu->objfile->name); } return type; } @@ -5070,38 +6106,39 @@ die_type (struct die_info *die, struct objfile *objfile, DW_AT_containing_type attribute. */ static struct type * -die_containing_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +die_containing_type (struct die_info *die, struct dwarf2_cu *cu) { struct type *type = NULL; struct attribute *type_attr; struct die_info *type_die = NULL; 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) { - error ("Dwarf Error: Cannot find referent at offset %d.", ref); + error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", ref, + cu->objfile->name); return NULL; } - type = tag_type_to_type (type_die, objfile, cu_header); + type = tag_type_to_type (type_die, cu); } if (!type) { if (type_die) dump_die (type_die); - error ("Dwarf Error: Problem turning containing type into gdb type."); + error ("Dwarf Error: Problem turning containing type into gdb type [in module %s]", + cu->objfile->name); } return type; } #if 0 static struct type * -type_at_offset (unsigned int offset, struct objfile *objfile) +type_at_offset (unsigned int offset, struct dwarf2_cu *cu) { struct die_info *die; struct type *type; @@ -5112,14 +6149,13 @@ type_at_offset (unsigned int offset, struct objfile *objfile) error ("Dwarf Error: Cannot find type referent at offset %d.", offset); return NULL; } - type = tag_type_to_type (die, objfile); + type = tag_type_to_type (die, cu); return type; } #endif static struct type * -tag_type_to_type (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +tag_type_to_type (struct die_info *die, struct dwarf2_cu *cu) { if (die->type) { @@ -5127,139 +6163,273 @@ tag_type_to_type (struct die_info *die, struct objfile *objfile, } else { - read_type_die (die, objfile, cu_header); + read_type_die (die, cu); if (!die->type) { dump_die (die); - error ("Dwarf Error: Cannot find type of die."); + error ("Dwarf Error: Cannot find type of die [in module %s]", + cu->objfile->name); } return die->type; } } static void -read_type_die (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) +read_type_die (struct die_info *die, struct dwarf2_cu *cu) { + char *prefix = determine_prefix (die, cu); + const char *old_prefix = processing_current_prefix; + struct cleanup *back_to = make_cleanup (xfree, prefix); + processing_current_prefix = prefix; + switch (die->tag) { case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: - read_structure_scope (die, objfile, cu_header); + read_structure_scope (die, cu); break; case DW_TAG_enumeration_type: - read_enumeration (die, objfile, cu_header); + read_enumeration (die, cu); break; case DW_TAG_subprogram: case DW_TAG_subroutine_type: - read_subroutine_type (die, objfile, cu_header); + read_subroutine_type (die, cu); break; case DW_TAG_array_type: - read_array_type (die, objfile, cu_header); + read_array_type (die, cu); break; case DW_TAG_pointer_type: - read_tag_pointer_type (die, objfile, cu_header); + read_tag_pointer_type (die, cu); break; case DW_TAG_ptr_to_member_type: - read_tag_ptr_to_member_type (die, objfile, cu_header); + read_tag_ptr_to_member_type (die, cu); break; case DW_TAG_reference_type: - read_tag_reference_type (die, objfile, cu_header); + read_tag_reference_type (die, cu); break; case DW_TAG_const_type: - read_tag_const_type (die, objfile, cu_header); + read_tag_const_type (die, cu); break; case DW_TAG_volatile_type: - read_tag_volatile_type (die, objfile, cu_header); + read_tag_volatile_type (die, cu); break; case DW_TAG_string_type: - read_tag_string_type (die, objfile); + read_tag_string_type (die, cu); break; case DW_TAG_typedef: - read_typedef (die, objfile, cu_header); + 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, objfile); + read_base_type (die, cu); break; default: - complain (&dwarf2_unexpected_tag, dwarf_tag_name (die->tag)); + complaint (&symfile_complaints, "unexepected tag in read_type_die: '%s'", + dwarf_tag_name (die->tag)); break; } + + processing_current_prefix = old_prefix; + 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_aux (struct die_info *die, struct dwarf2_cu *cu) +{ + struct die_info *parent; + + if (cu->language != language_cplus) + return NULL; + + parent = die->parent; + + if (parent == NULL) + { + return (processing_has_namespace_info ? xstrdup ("") : NULL); + } + else + { + char *parent_prefix = determine_prefix_aux (parent, cu); + char *retval; + + switch (parent->tag) { + case DW_TAG_namespace: + { + int dummy; + + retval = typename_concat (parent_prefix, + namespace_name (parent, &dummy, cu)); + } + break; + case DW_TAG_class_type: + case DW_TAG_structure_type: + { + if (parent_prefix != NULL) + { + const char *parent_name = dwarf2_name (parent, cu); + + if (parent_name != NULL) + 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. */ + retval = typename_concat (parent_prefix, + "<>"); + } + else + retval = class_name (parent, cu); + } + break; + default: + retval = parent_prefix; + break; + } + + if (retval != parent_prefix) + xfree (parent_prefix); + return retval; + } +} + +/* Return a newly-allocated string formed by concatenating PREFIX, + "::", and SUFFIX, except that if PREFIX is NULL or the empty + string, just return a copy of SUFFIX. */ + +static char * +typename_concat (const char *prefix, const char *suffix) +{ + if (prefix == NULL || prefix[0] == '\0') + return xstrdup (suffix); + else + { + char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1); + + strcpy (retval, prefix); + strcat (retval, "::"); + strcat (retval, suffix); + + 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 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, cu)); + } + + name = dwarf2_name (die, cu); + if (name != NULL) + return xstrdup (name); + else + return xstrdup (""); } static struct type * -dwarf_base_type (int encoding, int size, struct objfile *objfile) +dwarf_base_type (int encoding, int size, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; + /* FIXME - this should not produce a new (struct type *) every time. It should cache base types. */ struct type *type; 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; } } @@ -5302,65 +6472,66 @@ copy_die (struct die_info *old_die) static struct die_info * sibling_die (struct die_info *die) { - int nesting_level = 0; - - if (!die->has_children) - { - if (die->next && (die->next->tag == 0)) - { - return NULL; - } - else - { - return die->next; - } - } - else - { - do - { - if (die->has_children) - { - nesting_level++; - } - if (die->tag == 0) - { - nesting_level--; - } - die = die->next; - } - while (nesting_level); - if (die && (die->tag == 0)) - { - return NULL; - } - else - { - return die; - } - } + return die->sibling; } /* 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 = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) return DW_STRING (attr); - attr = dwarf_attr (die, DW_AT_name); + return NULL; +} + +/* Get name of a die, return NULL if not found. */ + +static char * +dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) +{ + struct attribute *attr; + + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) return DW_STRING (attr); return NULL; } +/* Return the die that this die in an extension of, or NULL if there + is none. */ + +static struct die_info * +dwarf2_extension (struct die_info *die, struct dwarf2_cu *cu) +{ + struct attribute *attr; + struct die_info *extension_die; + unsigned int ref; + + attr = dwarf2_attr (die, DW_AT_extension, cu); + if (attr == NULL) + return NULL; + + ref = dwarf2_get_ref_die_offset (attr, cu); + extension_die = follow_die_ref (ref); + if (!extension_die) + { + error ("Dwarf Error: Cannot find referent at offset %d.", ref); + } + + return extension_die; +} + /* Convert a DIE tag into its string name. */ static char * -dwarf_tag_name (register unsigned tag) +dwarf_tag_name (unsigned tag) { switch (tag) { @@ -5460,6 +6631,22 @@ dwarf_tag_name (register unsigned tag) return "DW_TAG_variable"; case DW_TAG_volatile_type: return "DW_TAG_volatile_type"; + case DW_TAG_dwarf_procedure: + return "DW_TAG_dwarf_procedure"; + case DW_TAG_restrict_type: + return "DW_TAG_restrict_type"; + case DW_TAG_interface_type: + return "DW_TAG_interface_type"; + case DW_TAG_namespace: + return "DW_TAG_namespace"; + case DW_TAG_imported_module: + return "DW_TAG_imported_module"; + case DW_TAG_unspecified_type: + return "DW_TAG_unspecified_type"; + case DW_TAG_partial_unit: + return "DW_TAG_partial_unit"; + case DW_TAG_imported_unit: + return "DW_TAG_imported_unit"; case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop"; case DW_TAG_format_label: @@ -5476,7 +6663,7 @@ dwarf_tag_name (register unsigned tag) /* Convert a DWARF attribute code into its string name. */ static char * -dwarf_attr_name (register unsigned attr) +dwarf_attr_name (unsigned attr) { switch (attr) { @@ -5604,7 +6791,30 @@ dwarf_attr_name (register unsigned attr) return "DW_AT_virtuality"; case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location"; - + case DW_AT_allocated: + return "DW_AT_allocated"; + case DW_AT_associated: + return "DW_AT_associated"; + case DW_AT_data_location: + return "DW_AT_data_location"; + case DW_AT_stride: + return "DW_AT_stride"; + case DW_AT_entry_pc: + return "DW_AT_entry_pc"; + case DW_AT_use_UTF8: + return "DW_AT_use_UTF8"; + case DW_AT_extension: + return "DW_AT_extension"; + case DW_AT_ranges: + return "DW_AT_ranges"; + case DW_AT_trampoline: + return "DW_AT_trampoline"; + case DW_AT_call_column: + return "DW_AT_call_column"; + case DW_AT_call_file: + return "DW_AT_call_file"; + case DW_AT_call_line: + return "DW_AT_call_line"; #ifdef MIPS case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; @@ -5618,9 +6828,9 @@ dwarf_attr_name (register unsigned attr) return "DW_AT_MIPS_loop_unroll_factor"; case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth"; +#endif case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name"; -#endif case DW_AT_sf_names: return "DW_AT_sf_names"; @@ -5644,7 +6854,7 @@ dwarf_attr_name (register unsigned attr) /* Convert a DWARF value form code into its string name. */ static char * -dwarf_form_name (register unsigned form) +dwarf_form_name (unsigned form) { switch (form) { @@ -5698,7 +6908,7 @@ dwarf_form_name (register unsigned form) /* Convert a DWARF stack opcode into its string name. */ static char * -dwarf_stack_op_name (register unsigned op) +dwarf_stack_op_name (unsigned op) { switch (op) { @@ -6021,7 +7231,7 @@ dwarf_bool_name (unsigned mybool) /* Convert a DWARF type code into its string name. */ static char * -dwarf_type_encoding_name (register unsigned enc) +dwarf_type_encoding_name (unsigned enc) { switch (enc) { @@ -6041,6 +7251,8 @@ dwarf_type_encoding_name (register unsigned enc) return "DW_ATE_unsigned"; case DW_ATE_unsigned_char: return "DW_ATE_unsigned_char"; + case DW_ATE_imaginary_float: + return "DW_ATE_imaginary_float"; default: return "DW_ATE_"; } @@ -6050,7 +7262,7 @@ dwarf_type_encoding_name (register unsigned enc) #if 0 static char * -dwarf_cfi_name (register unsigned cfi_opc) +dwarf_cfi_name (unsigned cfi_opc) { switch (cfi_opc) { @@ -6129,7 +7341,7 @@ dump_die (struct die_info *die) fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n", dwarf_tag_name (die->tag), die->abbrev, die->offset); fprintf_unfiltered (gdb_stderr, "\thas children: %s\n", - dwarf_bool_name (die->has_children)); + dwarf_bool_name (die->child != NULL)); fprintf_unfiltered (gdb_stderr, "\tattributes:\n"); for (i = 0; i < die->num_attrs; ++i) @@ -6192,7 +7404,10 @@ dump_die_list (struct die_info *die) while (die) { dump_die (die); - die = die->next; + if (die->child != NULL) + dump_die_list (die->child); + if (die->sibling != NULL) + dump_die_list (die->sibling); } } @@ -6216,7 +7431,7 @@ dwarf2_empty_hash_tables (void) } 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; @@ -6230,14 +7445,38 @@ dwarf2_get_ref_die_offset (struct attribute *attr) 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: - complain (&dwarf2_unsupported_die_ref_attr, dwarf_form_name (attr->form)); + complaint (&symfile_complaints, + "unsupported die ref attribute form: '%s'", + dwarf_form_name (attr->form)); } 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) { @@ -6258,58 +7497,57 @@ 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) { - error ("Dwarf Error: internal error - invalid fundamental type id %d.", - typeid); + error ("Dwarf Error: internal error - invalid fundamental type id %d [in module %s]", + typeid, objfile->name); } /* Look for this particular type in the fundamental type vector. If 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. Given a pointer to a dwarf block that defines a location, compute the location and return the value. - FIXME: This is a kludge until we figure out a better - way to handle the location descriptions. - Gdb's design does not mesh well with the DWARF2 notion of a location - computing interpreter, which is a shame because the flexibility goes unused. - FIXME: Implement more operations as necessary. + NOTE drow/2003-11-18: This function is called in two situations + now: for the address of static or global variables (partial symbols + only) and for offsets into structures which are expected to be + (more or less) constant. The partial symbol case should go away, + and only the constant case should remain. That will let this + function complain more accurately. A few special modes are allowed + without complaint for global variables (for instance, global + register values and thread-local values). A location description containing no operations indicates that the - object is optimized out. The global optimized_out flag is set for - those, the return value is meaningless. + object is optimized out. The return value is 0 for that case. + FIXME drow/2003-11-16: No callers check for this case any more; soon all + callers will only want a very basic result and this can become a + complaint. When the result is a register number, the global isreg flag is set, otherwise it is cleared. - When the result is a base register offset, the global offreg flag is set - and the register number is returned in basereg, otherwise it is cleared. - - When the DW_OP_fbreg operation is encountered without a corresponding - DW_AT_frame_base attribute, the global islocal flag is set. - Hopefully the machine dependent code knows how to set up a virtual - frame pointer for the local references. - Note that stack[0] is unused except as a default error return. Note that stack overflow is not yet handled. */ static CORE_ADDR -decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, - const struct comp_unit_head *cu_header) +decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; int i; int size = blk->size; char *data = blk->data; @@ -6322,14 +7560,9 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, stacki = 0; stack[stacki] = 0; isreg = 0; - offreg = 0; - isderef = 0; - islocal = 0; - optimized_out = 1; while (i < size) { - optimized_out = 0; op = data[i++]; switch (op) { @@ -6402,6 +7635,8 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, case DW_OP_reg31: isreg = 1; stack[++stacki] = op - DW_OP_reg0; + if (i < size) + dwarf2_complex_location_expr_complaint (); break; case DW_OP_regx: @@ -6409,73 +7644,13 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read); i += bytes_read; stack[++stacki] = unsnd; - break; - - case DW_OP_breg0: - case DW_OP_breg1: - case DW_OP_breg2: - case DW_OP_breg3: - case DW_OP_breg4: - case DW_OP_breg5: - case DW_OP_breg6: - case DW_OP_breg7: - case DW_OP_breg8: - case DW_OP_breg9: - case DW_OP_breg10: - case DW_OP_breg11: - case DW_OP_breg12: - case DW_OP_breg13: - case DW_OP_breg14: - case DW_OP_breg15: - case DW_OP_breg16: - case DW_OP_breg17: - case DW_OP_breg18: - case DW_OP_breg19: - case DW_OP_breg20: - case DW_OP_breg21: - case DW_OP_breg22: - case DW_OP_breg23: - case DW_OP_breg24: - case DW_OP_breg25: - case DW_OP_breg26: - case DW_OP_breg27: - case DW_OP_breg28: - case DW_OP_breg29: - case DW_OP_breg30: - case DW_OP_breg31: - offreg = 1; - basereg = op - DW_OP_breg0; - stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read); - i += bytes_read; - break; - - case DW_OP_bregx: - offreg = 1; - basereg = read_unsigned_leb128 (NULL, (data + i), &bytes_read); - i += bytes_read; - stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read); - i += bytes_read; - break; - - case DW_OP_fbreg: - stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read); - i += bytes_read; - if (frame_base_reg >= 0) - { - offreg = 1; - basereg = frame_base_reg; - stack[stacki] += frame_base_offset; - } - else - { - complain (&dwarf2_missing_at_frame_base); - islocal = 1; - } + if (i < size) + dwarf2_complex_location_expr_complaint (); break; case DW_OP_addr: stack[++stacki] = read_address (objfile->obfd, &data[i], - cu_header, &bytes_read); + cu, &bytes_read); i += bytes_read; break; @@ -6541,15 +7716,28 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, break; case DW_OP_deref: - isderef = 1; /* If we're not the last op, then we definitely can't encode - this using GDB's address_class enum. */ + this using GDB's address_class enum. This is valid for partial + global symbols, although the variable's address will be bogus + in the psymtab. */ if (i < size) - complain (&dwarf2_complex_location_expr); + dwarf2_complex_location_expr_complaint (); break; + case DW_OP_GNU_push_tls_address: + /* The top of the stack has the offset from the beginning + of the thread control block at which the variable is located. */ + /* Nothing should follow this operator, so the top of stack would + be returned. */ + /* This is valid for partial global symbols, but the variable's + address will be bogus in the psymtab. */ + if (i < size) + dwarf2_complex_location_expr_complaint (); + break; + default: - complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name (op)); + complaint (&symfile_complaints, "unsupported stack op: '%s'", + dwarf_stack_op_name (op)); return (stack[stacki]); } } @@ -6558,9 +7746,8 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, /* memory allocation interface */ -/* ARGSUSED */ static void -dwarf2_free_tmp_obstack (PTR ignore) +dwarf2_free_tmp_obstack (void *ignore) { obstack_free (&dwarf2_tmp_obstack, NULL); } @@ -6576,11 +7763,12 @@ dwarf_alloc_block (void) } 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); } @@ -6648,7 +7836,7 @@ macro_start_file (int file, int line, /* 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) @@ -6682,7 +7870,9 @@ consume_improper_spaces (const char *p, const char *body) { if (*p == ' ') { - complain (&dwarf2_macro_spaces_in_definition, body); + complaint (&symfile_complaints, + "macro definition contains spaces in formal argument list:\n`%s'", + body); while (*p == ' ') p++; @@ -6740,7 +7930,7 @@ parse_macro_definition (struct macro_source_file *file, int line, replacement = body + name_len + 1; else { - complain (&dwarf2_macro_malformed_definition, body); + dwarf2_macro_malformed_definition_complaint (body); replacement = body + name_len; } @@ -6770,8 +7960,7 @@ parse_macro_definition (struct macro_source_file *file, int line, p++; if (! *p || p == arg_start) - complain (&dwarf2_macro_malformed_definition, - body); + dwarf2_macro_malformed_definition_complaint (body); else { /* Make sure argv has room for the new argument. */ @@ -6807,18 +7996,18 @@ parse_macro_definition (struct macro_source_file *file, int line, else if (*p == '\0') { /* Complain, but do define it. */ - complain (&dwarf2_macro_malformed_definition, body); + dwarf2_macro_malformed_definition_complaint (body); macro_define_function (file, line, name, argc, (const char **) argv, p); } else /* Just complain. */ - complain (&dwarf2_macro_malformed_definition, body); + dwarf2_macro_malformed_definition_complaint (body); } else /* Just complain. */ - complain (&dwarf2_macro_malformed_definition, body); + dwarf2_macro_malformed_definition_complaint (body); xfree (name); { @@ -6830,22 +8019,21 @@ parse_macro_definition (struct macro_source_file *file, int line, xfree (argv); } else - complain (&dwarf2_macro_malformed_definition, body); + dwarf2_macro_malformed_definition_complaint (body); } static void dwarf_decode_macros (struct line_header *lh, unsigned int offset, char *comp_dir, bfd *abfd, - const struct comp_unit_head *cu_header, - struct objfile *objfile) + struct dwarf2_cu *cu) { char *mac_ptr, *mac_end; struct macro_source_file *current_file = 0; if (dwarf_macinfo_buffer == NULL) { - complain (&dwarf2_missing_macinfo_section); + complaint (&symfile_complaints, "missing .debug_macinfo section"); return; } @@ -6859,7 +8047,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, /* Do we at least have room for a macinfo type byte? */ if (mac_ptr >= mac_end) { - complain (&dwarf2_macros_too_long); + dwarf2_macros_too_long_complaint (); return; } @@ -6886,11 +8074,12 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, mac_ptr += bytes_read; if (! current_file) - complain (&dwarf2_macro_outside_file, - macinfo_type == DW_MACINFO_define ? "definition" : - macinfo_type == DW_MACINFO_undef ? "undefinition" : - "something-or-other", - body); + complaint (&symfile_complaints, + "debug info gives macro %s outside of any file: %s", + macinfo_type == + DW_MACINFO_define ? "definition" : macinfo_type == + DW_MACINFO_undef ? "undefinition" : + "something-or-other", body); else { if (macinfo_type == DW_MACINFO_define) @@ -6913,13 +8102,14 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, current_file = macro_start_file (file, line, current_file, comp_dir, - lh, objfile); + lh, cu->objfile); } break; case DW_MACINFO_end_file: if (! current_file) - complain (&dwarf2_macro_unmatched_end_file); + complaint (&symfile_complaints, + "macro debug info has an unmatched `close_file' directive"); else { current_file = current_file->included_by; @@ -6935,7 +8125,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, /* Do we at least have room for a macinfo type byte? */ if (mac_ptr >= mac_end) { - complain (&dwarf2_macros_too_long); + dwarf2_macros_too_long_complaint (); return; } @@ -6943,7 +8133,8 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, a look-ahead. */ next_type = read_1_byte (abfd, mac_ptr); if (next_type != 0) - complain (&dwarf2_macros_not_terminated); + complaint (&symfile_complaints, + "no terminating 0-type entry for macros in `.debug_macinfo' section"); return; } @@ -6979,3 +8170,58 @@ attr_form_is_block (struct attribute *attr) || attr->form == DW_FORM_block4 || attr->form == DW_FORM_block); } + +static void +dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, + struct dwarf2_cu *cu) +{ + if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) + { + struct dwarf2_loclist_baton *baton; + + baton = obstack_alloc (&cu->objfile->objfile_obstack, + sizeof (struct dwarf2_loclist_baton)); + baton->objfile = cu->objfile; + + /* We don't know how long the location list is, but make sure we + don't run off the edge of the section. */ + baton->size = dwarf_loc_size - DW_UNSND (attr); + baton->data = dwarf_loc_buffer + DW_UNSND (attr); + baton->base_address = cu->header.base_address; + if (cu->header.base_known == 0) + complaint (&symfile_complaints, + "Location list used without specifying the CU base address."); + + SYMBOL_OPS (sym) = &dwarf2_loclist_funcs; + SYMBOL_LOCATION_BATON (sym) = baton; + } + else + { + struct dwarf2_locexpr_baton *baton; + + baton = obstack_alloc (&cu->objfile->objfile_obstack, + sizeof (struct dwarf2_locexpr_baton)); + baton->objfile = cu->objfile; + + if (attr_form_is_block (attr)) + { + /* Note that we're just copying the block's data pointer + here, not the actual data. We're still pointing into the + dwarf_info_buffer for SYM's objfile; right now we never + release that buffer, but when we do clean up properly + this may need to change. */ + baton->size = DW_BLOCK (attr)->size; + baton->data = DW_BLOCK (attr)->data; + } + else + { + dwarf2_invalid_attrib_class_complaint ("location description", + SYMBOL_NATURAL_NAME (sym)); + baton->size = 0; + baton->data = NULL; + } + + SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs; + SYMBOL_LOCATION_BATON (sym) = baton; + } +}