X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=46c3cf4ed7e28df2c43dde5c75ed72b7dc18ff92;hb=649e03f6e4b94665f1a74e2238a862f28097946a;hp=a7435cc4ddd35de8547e6e7b404d9c4e4107d817;hpb=627b3ba2d386befaf2d1bd97bd780ac1218dd399;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index a7435cc4dd..46c3cf4ed7 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, 2003 + 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" @@ -128,18 +128,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; -static file_ptr dwarf_ranges_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; @@ -230,6 +218,48 @@ struct comp_unit_head 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 be moved to the dwarf2_cu structure; for instance the abbrevs + hash table. */ + struct comp_unit_head header; + + struct function_range *first_fn, *last_fn, *cached_fn; + + /* The language we are debugging. */ + enum language language; + const struct language_defn *language_defn; + + /* The generic symbol table building routines have separate lists for + file scope symbols and all all other scopes (local scopes). So + we need to select the right one to pass to add_symbol_to_list(). + We do it by keeping a pointer to the correct list in list_in_scope. + + FIXME: The original dwarf code just treated the file scope as the + first local scope, and all other local scopes as nested local + scopes, and worked fine. Check to see if we really need to + distinguish these in buildsym.c. */ + struct pending **list_in_scope; + + /* Maintain an array of referenced fundamental types for the current + compilation unit being read. For DWARF version 1, we have to construct + the fundamental types on the fly, since no information about the + fundamental types is supplied. Each such fundamental type is created by + calling a language dependent routine to create the type, and then a + pointer to that type is then placed in the array at the index specified + by it's FT_ value. The array has a fixed size set by the + FT_NUM_MEMBERS compile time constant, which is the number of predefined + fundamental types gdb knows how to construct. */ + struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */ +}; + /* The line number information for a compilation unit (found in the .debug_line section) begins with a "statement program header", which contains the following information. */ @@ -315,13 +345,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 */ }; @@ -349,8 +387,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) @@ -380,19 +416,11 @@ 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; @@ -405,57 +433,19 @@ 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. + objfile_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 @@ -536,17 +526,6 @@ struct dwarf2_pinfo #define DWARF_LOC_BUFFER(p) (PST_PRIVATE(p)->dwarf_loc_buffer) #define DWARF_LOC_SIZE(p) (PST_PRIVATE(p)->dwarf_loc_size) -/* Maintain an array of referenced fundamental types for the current - compilation unit being read. For DWARF version 1, we have to construct - the fundamental types on the fly, since no information about the - fundamental types is supplied. Each such fundamental type is created by - calling a language dependent routine to create the type, and then a - pointer to that type is then placed in the array at the index specified - by it's FT_ value. The array has a fixed size set by the - FT_NUM_MEMBERS compile time constant, which is the number of predefined - fundamental types gdb knows how to construct. */ -static struct type *ftypes[FT_NUM_MEMBERS]; /* Fundamental types */ - /* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte, but this would require a corresponding change in unpack_field_as_long and friends. */ @@ -602,13 +581,6 @@ struct field_info /* Various complaints about symbol reading that don't abort the process */ -static void -dwarf2_non_const_array_bound_ignored_complaint (const char *arg1) -{ - complaint (&symfile_complaints, "non-constant array bounds form '%s' ignored", - arg1); -} - static void dwarf2_statement_list_fits_in_line_number_section_complaint (void) { @@ -622,13 +594,6 @@ dwarf2_complex_location_expr_complaint (void) complaint (&symfile_complaints, "location expression too complex"); } -static void -dwarf2_unsupported_at_frame_base_complaint (const char *arg1) -{ - complaint (&symfile_complaints, - "unsupported DW_AT_frame_base for function '%s'", arg1); -} - static void dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2, int arg3) @@ -670,59 +635,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 objfile *, - const struct comp_unit_head *, +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, - struct objfile *objfile, CORE_ADDR *lowpc, CORE_ADDR *highpc, - const struct comp_unit_head *cu_header, + 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 objfile *objfile, - const struct comp_unit_head *cu_header, + struct dwarf2_cu *cu, const char *namespace); static char *locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr, bfd *abfd, - const struct comp_unit_head *cu_header); + 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, - asection *); +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 (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 *); @@ -734,7 +700,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 *, @@ -754,137 +720,146 @@ 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 void set_cu_language (unsigned int, struct dwarf2_cu *); + +static struct attribute *dwarf2_attr (struct die_info *, unsigned int, + struct dwarf2_cu *); -static struct attribute *dwarf_attr (struct die_info *, unsigned int); +static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu); -static int die_is_declaration (struct die_info *); +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 objfile *, - const struct comp_unit_head *); +static void read_type_die (struct die_info *, struct dwarf2_cu *); -static void read_typedef (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static char *determine_prefix (struct die_info *die, struct dwarf2_cu *); -static void read_base_type (struct die_info *, struct objfile *); +static char *determine_prefix_aux (struct die_info *die, struct dwarf2_cu *); -static void read_file_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static char *typename_concat (const char *prefix, const char *suffix); -static void read_func_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static char *class_name (struct die_info *die, struct dwarf2_cu *); -static void read_lexical_block_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_typedef (struct die_info *, struct dwarf2_cu *); + +static void read_base_type (struct die_info *, struct dwarf2_cu *); + +static void read_subrange_type (struct die_info *die, struct dwarf2_cu *cu); + +static void read_file_scope (struct die_info *, struct dwarf2_cu *); + +static void read_func_scope (struct die_info *, struct dwarf2_cu *); + +static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *); static int dwarf2_get_pc_bounds (struct die_info *, - CORE_ADDR *, CORE_ADDR *, struct objfile *, - const struct comp_unit_head *); + 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 dwarf2_cu *); + +static void read_common_block (struct die_info *, struct dwarf2_cu *); -static void read_structure_scope (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_namespace (struct die_info *die, struct dwarf2_cu *); -static void read_common_block (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static const char *namespace_name (struct die_info *die, + int *is_anonymous, struct dwarf2_cu *); -static void read_namespace (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header); +static void read_enumeration (struct die_info *, struct dwarf2_cu *); -static void read_enumeration (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static struct type *dwarf_base_type (int, int, struct dwarf2_cu *); -static struct type *dwarf_base_type (int, int, struct objfile *); +static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *); -static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *, - const struct comp_unit_head *); +static void read_array_type (struct die_info *, struct dwarf2_cu *); -static void read_array_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_pointer_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_ptr_to_member_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_reference_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static void read_tag_const_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_volatile_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_string_type (struct die_info *, struct dwarf2_cu *); -static void read_tag_string_type (struct die_info *, struct objfile *); +static void read_subroutine_type (struct die_info *, struct dwarf2_cu *); -static void read_subroutine_type (struct die_info *, struct objfile *, - const struct comp_unit_head *); +static struct die_info *read_comp_unit (char *, bfd *, struct dwarf2_cu *); -static struct die_info *read_comp_unit (char *, bfd *, - const struct comp_unit_head *); +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); +static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *); -static struct die_info *dwarf2_extension (struct die_info *die); +static struct die_info *dwarf2_extension (struct die_info *die, + struct dwarf2_cu *); static char *dwarf_tag_name (unsigned int); @@ -914,11 +889,15 @@ 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 */ @@ -930,20 +909,19 @@ static struct abbrev_info *dwarf_alloc_abbrev (void); 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, - const struct comp_unit_head *, - struct objfile *objfile); + 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. */ @@ -951,25 +929,18 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, 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_ranges_offset = 0; - dwarf_loc_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 @@ -979,73 +950,62 @@ dwarf2_has_info (bfd *abfd) static void 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 (STREQ (sectp->name, EH_FRAME_SECTION)) + 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_offset = sectp->filepos; dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp); dwarf_eh_frame_section = sectp; } } - else if (STREQ (sectp->name, RANGES_SECTION)) + else if (strcmp (sectp->name, RANGES_SECTION) == 0) { - dwarf_ranges_offset = sectp->filepos; dwarf_ranges_size = bfd_get_section_size_before_reloc (sectp); dwarf_ranges_section = sectp; } @@ -1059,52 +1019,32 @@ 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_info_section); - dwarf_abbrev_buffer = dwarf2_read_section (objfile, - dwarf_abbrev_offset, - dwarf_abbrev_size, - dwarf_abbrev_section); - - if (dwarf_line_offset) - dwarf_line_buffer = dwarf2_read_section (objfile, - dwarf_line_offset, - dwarf_line_size, - dwarf_line_section); + 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, - dwarf_str_section); + 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_offset) - dwarf_ranges_buffer = dwarf2_read_section (objfile, - dwarf_ranges_offset, - dwarf_ranges_size, - dwarf_ranges_section); + if (dwarf_ranges_section) + dwarf_ranges_buffer = dwarf2_read_section (objfile, dwarf_ranges_section); else dwarf_ranges_buffer = NULL; - if (dwarf_loc_offset) - dwarf_loc_buffer = dwarf2_read_section (objfile, - dwarf_loc_offset, - dwarf_loc_size, - dwarf_loc_section); + if (dwarf_loc_section) + dwarf_loc_buffer = dwarf2_read_section (objfile, dwarf_loc_section); else dwarf_loc_buffer = NULL; @@ -1145,8 +1085,6 @@ 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) @@ -1166,8 +1104,6 @@ dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) } aranges_buffer = dwarf2_read_section (objfile, - dwarf_aranges_offset, - dwarf_aranges_size, dwarf_aranges_section); } @@ -1214,7 +1150,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; @@ -1265,47 +1201,51 @@ 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 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 (is %d, should be %d) [in module %s]", cu_header.version, 2, bfd_get_filename (abfd)); + 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) [in module %s]", - (long) cu_header.abbrev_offset, + (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) [in module %s]", - (long) cu_header.length, + (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); + make_cleanup (dwarf2_empty_abbrev_table, cu.header.dwarf2_abbrevs); /* 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, @@ -1315,8 +1255,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; @@ -1344,8 +1283,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) lowpc = ((CORE_ADDR) -1); highpc = ((CORE_ADDR) 0); - info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc, - &cu_header, NULL); + 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'. */ @@ -1374,8 +1313,8 @@ 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); } @@ -1388,11 +1327,11 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) 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; @@ -1406,7 +1345,7 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile, inside the loop. */ int info_ptr_updated = 0; - info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header); + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu); /* Anonymous namespaces have no name but have interesting children, so we need to look at them. Ditto for anonymous @@ -1430,33 +1369,40 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile, } if (!pdi.is_declaration) { - add_partial_symbol (&pdi, objfile, cu_header, namespace); + 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: if (!pdi.is_declaration) { - add_partial_symbol (&pdi, objfile, cu_header, namespace); + info_ptr = add_partial_structure (&pdi, info_ptr, cu, + namespace); + info_ptr_updated = 1; } break; case DW_TAG_enumeration_type: if (!pdi.is_declaration) { - info_ptr = add_partial_enumeration (&pdi, info_ptr, - objfile, cu_header, + 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. */ - add_partial_symbol (&pdi, objfile, cu_header, namespace); + add_partial_symbol (&pdi, cu, namespace); break; case DW_TAG_namespace: /* We've hit a DW_TAG_namespace entry, so we know this @@ -1464,9 +1410,8 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile, generates them; update NAMESPACE to reflect that. */ if (namespace == NULL) namespace = ""; - info_ptr = add_partial_namespace (&pdi, info_ptr, objfile, - lowpc, highpc, cu_header, - namespace); + info_ptr = add_partial_namespace (&pdi, info_ptr, lowpc, highpc, + cu, namespace); info_ptr_updated = 1; break; default: @@ -1486,42 +1431,57 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile, this seems like the easiest way to handle the issue. */ if (!info_ptr_updated) - info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu_header); + info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu); } return info_ptr; } static void -add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, - const struct comp_unit_head *cu_header, - const char *namespace) +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); */ - psym = add_psymbol_to_list (pdi->name, strlen (pdi->name), + psym = add_psymbol_to_list (actual_name, strlen (actual_name), VAR_DOMAIN, LOC_BLOCK, &objfile->global_psymbols, 0, pdi->lowpc + baseaddr, - cu_language, objfile); + 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); */ - psym = add_psymbol_to_list (pdi->name, strlen (pdi->name), + psym = add_psymbol_to_list (actual_name, strlen (actual_name), VAR_DOMAIN, LOC_BLOCK, &objfile->static_psymbols, 0, pdi->lowpc + baseaddr, - cu_language, objfile); + cu->language, objfile); } break; case DW_TAG_variable: @@ -1541,35 +1501,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) - psym = add_psymbol_to_list (pdi->name, strlen (pdi->name), + psym = add_psymbol_to_list (actual_name, strlen (actual_name), VAR_DOMAIN, LOC_STATIC, &objfile->global_psymbols, 0, addr + baseaddr, - cu_language, objfile); + 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); */ - psym = add_psymbol_to_list (pdi->name, strlen (pdi->name), + psym = add_psymbol_to_list (actual_name, strlen (actual_name), VAR_DOMAIN, LOC_STATIC, &objfile->static_psymbols, 0, addr + baseaddr, - cu_language, objfile); + cu->language, objfile); } break; case DW_TAG_typedef: case DW_TAG_base_type: - add_psymbol_to_list (pdi->name, strlen (pdi->name), + 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: @@ -1577,27 +1538,33 @@ 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), + add_psymbol_to_list (actual_name, strlen (actual_name), STRUCT_DOMAIN, LOC_TYPEDEF, - &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu_language, objfile); + cu->language == language_cplus + ? &objfile->global_psymbols + : &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); - if (cu_language == language_cplus) + if (cu->language == language_cplus) { /* For C++, these implicitly act as typedefs as well. */ - add_psymbol_to_list (pdi->name, strlen (pdi->name), + add_psymbol_to_list (actual_name, strlen (actual_name), VAR_DOMAIN, LOC_TYPEDEF, - &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu_language, objfile); + &objfile->global_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); } break; case DW_TAG_enumerator: - add_psymbol_to_list (pdi->name, strlen (pdi->name), + add_psymbol_to_list (actual_name, strlen (actual_name), VAR_DOMAIN, LOC_CONST, - &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu_language, objfile); + cu->language == language_cplus + ? &objfile->global_psymbols + : &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); break; default: break; @@ -1609,7 +1576,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, (otherwise we'll have psym == NULL), and if we actually had a mangled name to begin with. */ - if (cu_language == language_cplus + if (cu->language == language_cplus && namespace == NULL && psym != NULL && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL) @@ -1617,22 +1584,45 @@ add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, 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, - struct objfile *objfile, CORE_ADDR *lowpc, CORE_ADDR *highpc, - const struct comp_unit_head *cu_header, - const char *namespace) + struct dwarf2_cu *cu, const char *namespace) { - /* Calculate the full name of the namespace that we just entered. */ - + 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); @@ -1641,48 +1631,118 @@ add_partial_namespace (struct partial_die_info *pdi, char *info_ptr, strcat (full_name, "::"); strcat (full_name, new_name); - /* FIXME: carlton/2003-06-27: Once we build qualified names for more - symbols than just namespaces, we should replace this by a call to - add_partial_symbol. */ + /* 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); + 0, 0, cu->language, objfile); /* Now scan partial symbols in that namespace. */ if (pdi->has_children) - info_ptr = scan_partial_symbols (info_ptr, objfile, - lowpc, highpc, - cu_header, full_name); + 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 objfile *objfile, - const struct comp_unit_head *cu_header, - const char *namespace) + 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, objfile, cu_header, namespace); + add_partial_symbol (enum_pdi, cu, namespace); while (1) { - info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header); + 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, objfile, cu_header, namespace); + add_partial_symbol (&pdi, cu, namespace); } return info_ptr; @@ -1693,7 +1753,7 @@ add_partial_enumeration (struct partial_die_info *enum_pdi, char *info_ptr, static char * locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr, - bfd *abfd, const struct comp_unit_head *cu_header) + bfd *abfd, struct dwarf2_cu *cu) { /* Do we know the sibling already? */ @@ -1713,12 +1773,12 @@ locate_pdi_sibling (struct partial_die_info *orig_pdi, char *info_ptr, { struct partial_die_info pdi; - info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header); + info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu); if (pdi.tag == 0) return info_ptr; else - info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu_header); + info_ptr = locate_pdi_sibling (&pdi, info_ptr, abfd, cu); } } @@ -1756,7 +1816,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; @@ -1765,6 +1825,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) 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); @@ -1781,9 +1842,11 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) dwarf_ranges_size = DWARF_RANGES_SIZE (pst); dwarf_loc_buffer = DWARF_LOC_BUFFER (pst); dwarf_loc_size = DWARF_LOC_SIZE (pst); - baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile)); - cu_header_offset = offset; info_ptr = dwarf_info_buffer + offset; + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + /* We're in the global namespace. */ + processing_current_prefix = ""; obstack_init (&dwarf2_tmp_obstack); back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL); @@ -1791,14 +1854,20 @@ 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_empty_abbrev_table, cu.header.dwarf2_abbrevs); + + 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); @@ -1808,62 +1877,42 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) DW_AT_entry_pc. It's been removed, but GCC still uses this for compilation units with discontinuous ranges. */ - cu_header.base_known = 0; - cu_header.base_address = 0; + cu.header.base_known = 0; + cu.header.base_address = 0; - attr = dwarf_attr (dies, DW_AT_entry_pc); + attr = dwarf2_attr (dies, DW_AT_entry_pc, &cu); if (attr) { - cu_header.base_address = DW_ADDR (attr); - cu_header.base_known = 1; + cu.header.base_address = DW_ADDR (attr); + cu.header.base_known = 1; } else { - attr = dwarf_attr (dies, DW_AT_low_pc); + attr = dwarf2_attr (dies, DW_AT_low_pc, &cu); if (attr) { - cu_header.base_address = DW_ADDR (attr); - cu_header.base_known = 1; + cu.header.base_address = DW_ADDR (attr); + cu.header.base_known = 1; } } /* Do line number decoding in read_file_scope () */ - process_die (dies, objfile, &cu_header); + process_die (dies, &cu); - if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile, &cu_header)) - { - /* 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) - { - child_die = dies->next; - while (child_die && child_die->tag) - { - if (child_die->tag == DW_TAG_subprogram) - { - CORE_ADDR low, high; + /* Some compilers don't define a DW_AT_high_pc attribute for the + compilation unit. If the DW_AT_high_pc is missing, synthesize + it, by scanning the DIE's below the compilation unit. */ + get_scope_pc_bounds (dies, &lowpc, &highpc, &cu); - if (dwarf2_get_pc_bounds (child_die, &low, &high, - objfile, &cu_header)) - { - highpc = max (highpc, high); - } - } - child_die = sibling_die (child_die); - } - } - } symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile)); /* Set symtab language to language from DW_AT_language. If the compilation is from a C file generated by language preprocessors, do not set the language if it was already deduced by start_subfile. */ if (symtab != NULL - && !(cu_language == language_c && symtab->language != language_c)) + && !(cu.language == language_c && symtab->language != language_c)) { - symtab->language = cu_language; + symtab->language = cu.language; } pst->symtab = symtab; pst->readin = 1; @@ -1874,19 +1923,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. @@ -1896,54 +1944,58 @@ process_die (struct die_info *die, struct objfile *objfile, case DW_TAG_lexical_block: case DW_TAG_try_block: case DW_TAG_catch_block: - read_lexical_block_scope (die, objfile, cu_header); + 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: - if (!processing_has_namespace_info) - { - processing_has_namespace_info = 1; - processing_current_namespace = ""; - } - read_namespace (die, objfile, cu_header); + processing_has_namespace_info = 1; + read_namespace (die, cu); break; case DW_TAG_imported_declaration: case DW_TAG_imported_module: @@ -1953,29 +2005,26 @@ process_die (struct die_info *die, struct objfile *objfile, 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. */ - if (!processing_has_namespace_info) - { - processing_has_namespace_info = 1; - processing_current_namespace = ""; - } - gdb_assert (!die->has_children); + 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); @@ -1985,29 +2034,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, cu_header)) - { - 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, cu_header)) - { - 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. */ @@ -2016,12 +2047,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); @@ -2043,10 +2074,10 @@ read_file_scope (struct die_info *die, struct objfile *objfile, 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. */ @@ -2061,36 +2092,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); } } @@ -2098,18 +2128,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; @@ -2121,37 +2152,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, cu_header)) + 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) @@ -2160,61 +2230,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) - { - dwarf2_complex_location_expr_complaint (); - addr = 0; - } - else - { - dwarf2_invalid_attrib_class_complaint ("DW_AT_frame_base", name); - addr = 0; - } - - if (isderef) - dwarf2_unsupported_at_frame_base_complaint (name); - else if (isreg) - frame_base_reg = addr; - else if (offreg) - { - frame_base_reg = basereg; - frame_base_offset = addr; - } - else - dwarf2_unsupported_at_frame_base_complaint (name); - } - new = push_context (0, lowpc); - new->name = new_symbol (die, die->type, objfile, cu_header); + new->name = new_symbol (die, die->type, cu); - /* If there was a location expression for DW_AT_frame_base above, - record it. We still need to decode it above because not all - symbols use location expressions exclusively. */ + /* If there is a location expression for DW_AT_frame_base, record + it. */ + attr = dwarf2_attr (die, DW_AT_frame_base, cu); if (attr) - dwarf2_symbol_mark_computed (attr, new->name, cu_header, objfile); - - list_in_scope = &local_symbols; - - if (die->has_children) - { - child_die = die->next; + /* 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); } } @@ -2234,37 +2275,44 @@ read_func_scope (struct die_info *die, struct objfile *objfile, /* If we've finished processing a top-level function, subsequent symbols go in the file symbol list. */ if (outermost_context_p ()) - list_in_scope = &file_symbols; + cu->list_in_scope = &file_symbols; + + processing_current_prefix = previous_prefix; + if (back_to != NULL) + do_cleanups (back_to); } /* Process all the DIES contained within a lexical block scope. Start 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. */ /* ??? 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, objfile, cu_header)) + 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); } } @@ -2283,20 +2331,21 @@ read_lexical_block_scope (struct die_info *die, struct objfile *objfile, 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, - const struct comp_unit_head *cu_header) + CORE_ADDR *highpc, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; + struct comp_unit_head *cu_header = &cu->header; struct attribute *attr; bfd *obfd = objfile->obfd; CORE_ADDR low = 0; CORE_ADDR high = 0; int ret = 0; - attr = dwarf_attr (die, DW_AT_high_pc); + attr = dwarf2_attr (die, DW_AT_high_pc, cu); if (attr) { high = DW_ADDR (attr); - attr = dwarf_attr (die, DW_AT_low_pc); + attr = dwarf2_attr (die, DW_AT_low_pc, cu); if (attr) low = DW_ADDR (attr); else @@ -2308,35 +2357,41 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, } else { - attr = dwarf_attr (die, DW_AT_ranges); + attr = dwarf2_attr (die, DW_AT_ranges, cu); if (attr != NULL) { unsigned int addr_size = cu_header->addr_size; CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1)); /* Value of the DW_AT_ranges attribute is the offset in the - .debug_renges section. */ + .debug_ranges section. */ unsigned int offset = DW_UNSND (attr); /* Base address selection entry. */ CORE_ADDR base; int found_base; int dummy; - unsigned int i; 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_header, &dummy); + 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_header, &dummy); + base = read_address (obfd, buffer + addr_size, cu, &dummy); buffer += 2 * addr_size; offset += 2 * addr_size; found_base = 1; @@ -2348,10 +2403,9 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, { CORE_ADDR range_beginning, range_end; - range_beginning = read_address (obfd, buffer, - cu_header, &dummy); + range_beginning = read_address (obfd, buffer, cu, &dummy); buffer += addr_size; - range_end = read_address (obfd, buffer, cu_header, &dummy); + range_end = read_address (obfd, buffer, cu, &dummy); buffer += addr_size; offset += 2 * addr_size; @@ -2367,8 +2421,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, { /* If we found the largest possible address, then read the base address. */ - base = read_address (obfd, buffer + addr_size, - cu_header, &dummy); + base = read_address (obfd, buffer + addr_size, cu, &dummy); found_base = 1; continue; } @@ -2432,13 +2485,75 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, 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; @@ -2461,28 +2576,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 && ! die_is_declaration (die)) + 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); @@ -2493,15 +2608,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) @@ -2524,7 +2639,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 @@ -2546,15 +2661,15 @@ 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); + &objfile->objfile_obstack); /* 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; @@ -2572,31 +2687,31 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, char *physname; /* Get name of field. */ - attr = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) fieldname = DW_STRING (attr); else return; /* Get physical name. */ - physname = dwarf2_linkage_name (die); + physname = dwarf2_linkage_name (die, cu); SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname), - &objfile->type_obstack)); - FIELD_TYPE (*fp) = die_type (die, objfile, cu_header); + &objfile->objfile_obstack)); + FIELD_TYPE (*fp) = die_type (die, cu); FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname), - &objfile->type_obstack); + &objfile->objfile_obstack); } else if (die->tag == DW_TAG_inheritance) { /* C++ base class field. */ - attr = dwarf_attr (die, DW_AT_data_member_location); + attr = dwarf2_attr (die, DW_AT_data_member_location, cu); if (attr) - FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), cu) * bits_per_byte); FIELD_BITSIZE (*fp) = 0; FIELD_STATIC_KIND (*fp) = 0; - FIELD_TYPE (*fp) = die_type (die, objfile, cu_header); + FIELD_TYPE (*fp) = die_type (die, cu); FIELD_NAME (*fp) = type_name_no_tag (fp->type); fip->nbaseclasses++; } @@ -2606,7 +2721,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; @@ -2693,9 +2808,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; @@ -2705,19 +2820,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; } @@ -2754,11 +2869,10 @@ 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); + &objfile->objfile_obstack); 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 @@ -2783,14 +2897,14 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, 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)) @@ -2805,18 +2919,18 @@ 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) { @@ -2834,7 +2948,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; @@ -2881,21 +2995,60 @@ 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; + const char *name = NULL; + const char *previous_prefix = processing_current_prefix; + struct cleanup *back_to = NULL; + /* This says whether or not we want to try to update the structure's + name to include enclosing namespace/class information, if + any. */ + int need_to_update_name = 0; 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 + { + TYPE_TAG_NAME (type) = obsavestring (name, strlen (name), + &objfile->objfile_obstack); + need_to_update_name = (cu->language == language_cplus); + } } if (die->tag == DW_TAG_structure_type) @@ -2913,7 +3066,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); @@ -2928,7 +3081,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; @@ -2936,7 +3089,7 @@ 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) { @@ -2948,40 +3101,75 @@ read_structure_scope (struct die_info *die, struct objfile *objfile, 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, objfile, cu_header); + 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) @@ -2997,7 +3185,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; @@ -3019,7 +3209,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); } @@ -3028,6 +3218,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 @@ -3040,9 +3234,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; @@ -3054,15 +3248,27 @@ 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); + const 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 + { + TYPE_TAG_NAME (type) = obsavestring (name, strlen (name), + &objfile->objfile_obstack); + } } - 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); @@ -3074,21 +3280,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; @@ -3126,7 +3332,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 @@ -3134,9 +3340,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; @@ -3151,110 +3357,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; - } - - 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 - { - dwarf2_non_const_array_bound_ignored_complaint - (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 - { - dwarf2_non_const_array_bound_ignored_complaint - (dwarf_form_name (attr->form)); -#ifdef FORTRAN_HACK - die->type = lookup_pointer_type (element_type); - return; -#else - high = 1; -#endif - } - } + read_subrange_type (child_die, cu); - /* 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); } @@ -3271,7 +3407,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; @@ -3284,21 +3420,20 @@ 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) { @@ -3310,17 +3445,17 @@ read_common_block (struct die_info *die, struct objfile *objfile, "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); @@ -3330,95 +3465,110 @@ read_common_block (struct die_info *die, struct objfile *objfile, /* Read a C++ namespace. */ -static void -read_namespace (struct die_info *die, struct objfile *objfile, - const struct comp_unit_head *cu_header) -{ - const char *previous_namespace = processing_current_namespace; - const char *name = NULL; - int is_anonymous; - struct die_info *current_die; - - /* Loop through the extensions until we find a name. */ - - for (current_die = die; - current_die != NULL; - current_die = dwarf2_extension (die)) - { - name = dwarf2_name (current_die); - if (name != NULL) - break; - } - - /* Is it an anonymous 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; - is_anonymous = (name == NULL); - if (is_anonymous) - name = "(anonymous namespace)"; + name = namespace_name (die, &is_anonymous, cu); /* Now build the name of the current namespace. */ - if (previous_namespace[0] == '\0') + if (previous_prefix[0] == '\0') { - processing_current_namespace = name; + processing_current_prefix = name; } else { - /* We need temp_name around because processing_current_namespace + /* We need temp_name around because processing_current_prefix is a const char *. */ - char *temp_name = alloca (strlen (previous_namespace) + char *temp_name = alloca (strlen (previous_prefix) + 2 + strlen(name) + 1); - strcpy (temp_name, previous_namespace); + strcpy (temp_name, previous_prefix); strcat (temp_name, "::"); strcat (temp_name, name); - processing_current_namespace = temp_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) == NULL) + 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_namespace, + (char *) processing_current_prefix, objfile); TYPE_TAG_NAME (type) = TYPE_NAME (type); - new_symbol (die, type, objfile, cu_header); + new_symbol (die, type, cu); if (is_anonymous) - cp_add_using_directive (processing_current_namespace, - strlen (previous_namespace), - strlen (processing_current_namespace)); + cp_add_using_directive (processing_current_prefix, + strlen (previous_prefix), + strlen (processing_current_prefix)); } - if (die->has_children) + if (die->child != NULL) { - struct die_info *child_die = die->next; + struct die_info *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); } } - processing_current_namespace = previous_namespace; + 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_byte_size; struct attribute *attr_address_class; @@ -3429,15 +3579,15 @@ read_tag_pointer_type (struct die_info *die, struct objfile *objfile, return; } - type = lookup_pointer_type (die_type (die, objfile, cu_header)); + type = lookup_pointer_type (die_type (die, cu)); - attr_byte_size = dwarf_attr (die, DW_AT_byte_size); + attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr_byte_size) byte_size = DW_UNSND (attr_byte_size); else byte_size = cu_header->addr_size; - attr_address_class = dwarf_attr (die, DW_AT_address_class); + attr_address_class = dwarf2_attr (die, DW_AT_address_class, cu); if (attr_address_class) addr_class = DW_UNSND (attr_address_class); else @@ -3473,9 +3623,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; @@ -3486,8 +3636,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; @@ -3497,9 +3647,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; @@ -3508,8 +3658,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); @@ -3522,8 +3672,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; @@ -3532,13 +3681,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; @@ -3547,7 +3695,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); } @@ -3557,8 +3705,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; @@ -3568,7 +3717,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); @@ -3576,7 +3725,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); @@ -3586,9 +3735,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 */ @@ -3596,7 +3745,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; @@ -3614,8 +3763,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 */ @@ -3626,16 +3774,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; @@ -3644,7 +3792,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) @@ -3659,7 +3807,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) @@ -3669,13 +3817,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); @@ -3686,21 +3833,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); } } @@ -3708,8 +3855,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; @@ -3720,17 +3868,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; @@ -3767,73 +3915,187 @@ read_base_type (struct die_info *die, struct objfile *objfile) } 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. */ @@ -3846,7 +4108,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; @@ -3867,31 +4131,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, asection *sectp) +dwarf2_read_section (struct objfile *objfile, asection *sectp) { bfd *abfd = objfile->obfd; 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); + 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, 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)); - } + 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; } @@ -3901,8 +4163,9 @@ 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; @@ -3966,14 +4229,13 @@ 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; } } /* Empty the abbrev table for a new compilation unit. */ -/* ARGSUSED */ static void dwarf2_empty_abbrev_table (void *ptr_to_abbrevs_table) { @@ -4001,8 +4263,9 @@ dwarf2_empty_abbrev_table (void *ptr_to_abbrevs_table) /* 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) { + struct comp_unit_head *cu_header = &cu->header; unsigned int hash_number; struct abbrev_info *abbrev; @@ -4023,7 +4286,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; @@ -4039,7 +4302,7 @@ 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 [in module %s]", abbrev_number, @@ -4052,8 +4315,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. */ @@ -4116,7 +4378,7 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd, 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; @@ -4130,10 +4392,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; @@ -4160,12 +4422,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; @@ -4181,19 +4445,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 [in module %s]", abbrev_number, - bfd_get_filename (abfd)); + 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; @@ -4204,10 +4469,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; } @@ -4215,9 +4481,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; @@ -4226,7 +4493,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: @@ -4321,7 +4588,7 @@ 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 [in module %s]", @@ -4335,11 +4602,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 */ @@ -4387,9 +4653,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) @@ -4662,27 +4928,27 @@ read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr) } 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: @@ -4691,16 +4957,16 @@ set_cu_language (unsigned int lang) case DW_LANG_Pascal83: case DW_LANG_Modula2: default: - cu_language = language_minimal; + cu->language = language_minimal; break; } - cu_language_defn = language_def (cu_language); + cu->language_defn = language_def (cu->language); } /* Return the named attribute or NULL if not there. */ static struct attribute * -dwarf_attr (struct die_info *die, unsigned int name) +dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu) { unsigned int i; struct attribute *spec = NULL; @@ -4718,22 +4984,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. */ @@ -4821,7 +5100,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; @@ -4862,7 +5141,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, 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; @@ -4926,26 +5205,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 @@ -4970,13 +5249,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; @@ -5022,7 +5304,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, line += lh->line_base + (adj_opcode % lh->line_range); /* append row to matrix using current values */ record_line (current_subfile, line, - check_cu_functions (address)); + check_cu_functions (address, cu)); basic_block = 1; } else switch (op_code) @@ -5038,7 +5320,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; @@ -5069,7 +5351,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, break; case DW_LNS_copy: record_line (current_subfile, line, - check_cu_functions (address)); + check_cu_functions (address, cu)); basic_block = 0; break; case DW_LNS_advance_pc: @@ -5182,9 +5464,11 @@ dwarf2_start_subfile (char *filename, char *dirname) static void var_decode_location (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; + /* 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 @@ -5215,8 +5499,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym, int dummy; SYMBOL_VALUE_ADDRESS (sym) = - read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu_header, - &dummy); + 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)); @@ -5231,7 +5514,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym, 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_header, objfile); + dwarf2_symbol_mark_computed (attr, sym, cu); SYMBOL_CLASS (sym) = LOC_COMPUTED; } @@ -5242,29 +5525,31 @@ var_decode_location (struct attribute *attr, struct symbol *sym, 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); + name = dwarf2_linkage_name (die, cu); else name = TYPE_NAME (type); if (name) { - sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, + sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); OBJSTAT (objfile, n_syms++); memset (sym, 0, sizeof (struct symbol)); /* Cache this symbol's name and the name's demangled form (if any). */ - SYMBOL_LANGUAGE (sym) = cu_language; + SYMBOL_LANGUAGE (sym) = cu->language; SYMBOL_SET_NAMES (sym, name, strlen (name), objfile); /* Default assumptions. @@ -5274,8 +5559,8 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, 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); @@ -5283,7 +5568,7 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, 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; @@ -5294,14 +5579,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: @@ -5313,26 +5598,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) { - var_decode_location (attr, sym, objfile, cu_header); - 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)) add_symbol_to_list (sym, &global_symbols); else - add_symbol_to_list (sym, list_in_scope); + add_symbol_to_list (sym, cu->list_in_scope); } else { @@ -5342,9 +5627,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); @@ -5352,20 +5637,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) { - var_decode_location (attr, sym, objfile, cu_header); + 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 @@ -5378,39 +5663,109 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, case DW_TAG_enumeration_type: SYMBOL_CLASS (sym) = LOC_TYPEDEF; SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; - add_symbol_to_list (sym, list_in_scope); - /* 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) + /* 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. */ + + if (cu->language == language_cplus) { - struct symbol *typedef_sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); - *typedef_sym = *sym; - SYMBOL_DOMAIN (typedef_sym) = VAR_DOMAIN; - if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) - TYPE_NAME (SYMBOL_TYPE (sym)) = - obsavestring (DEPRECATED_SYMBOL_NAME (sym), - strlen (DEPRECATED_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 a further down in the function.) */ + SYMBOL_LINKAGE_NAME (sym) + = obsavestring (TYPE_TAG_NAME (type), + strlen (TYPE_TAG_NAME (type)), + &objfile->objfile_obstack); + } } + + { + /* 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; + if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) + TYPE_NAME (SYMBOL_TYPE (sym)) = + obsavestring (SYMBOL_NATURAL_NAME (sym), + strlen (SYMBOL_NATURAL_NAME (sym)), + &objfile->objfile_obstack); + 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_DOMAIN (sym) = VAR_DOMAIN; - add_symbol_to_list (sym, list_in_scope); + add_symbol_to_list (sym, cu->list_in_scope); break; case DW_TAG_enumerator: - 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; @@ -5433,9 +5788,10 @@ 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) @@ -5447,7 +5803,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym, TYPE_LENGTH (SYMBOL_TYPE (sym))); SYMBOL_VALUE_BYTES (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size); + obstack_alloc (&objfile->objfile_obstack, cu_header->addr_size); /* NOTE: cagney/2003-05-09: In-lined store_address call with it's body - store_unsigned_integer. */ store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size, @@ -5465,7 +5821,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym, 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; @@ -5534,37 +5890,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 [in module %s]", - ref, objfile->name); + 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 [in module %s]", - objfile->name); + cu->objfile->name); } return type; } @@ -5573,40 +5928,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 [in module %s]", ref, - objfile->name); + 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 [in module %s]", - objfile->name); + 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; @@ -5617,14 +5971,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) { @@ -5632,141 +5985,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 [in module %s]", - objfile->name); + 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: 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; } } @@ -5809,56 +6294,20 @@ 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 = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) return DW_STRING (attr); return NULL; @@ -5867,11 +6316,11 @@ dwarf2_linkage_name (struct die_info *die) /* Get name of a die, return NULL if not found. */ static char * -dwarf2_name (struct die_info *die) +dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) { struct attribute *attr; - attr = dwarf_attr (die, DW_AT_name); + attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) return DW_STRING (attr); return NULL; @@ -5881,17 +6330,17 @@ dwarf2_name (struct die_info *die) is none. */ static struct die_info * -dwarf2_extension (struct die_info *die) +dwarf2_extension (struct die_info *die, struct dwarf2_cu *cu) { struct attribute *attr; struct die_info *extension_die; unsigned int ref; - attr = dwarf_attr (die, DW_AT_extension); + attr = dwarf2_attr (die, DW_AT_extension, cu); if (attr == NULL) return NULL; - ref = dwarf2_get_ref_die_offset (attr); + ref = dwarf2_get_ref_die_offset (attr, cu); extension_die = follow_die_ref (ref); if (!extension_die) { @@ -5904,7 +6353,7 @@ dwarf2_extension (struct die_info *die) /* Convert a DIE tag into its string name. */ static char * -dwarf_tag_name (register unsigned tag) +dwarf_tag_name (unsigned tag) { switch (tag) { @@ -6036,7 +6485,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) { @@ -6227,7 +6676,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) { @@ -6281,7 +6730,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) { @@ -6604,7 +7053,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) { @@ -6635,7 +7084,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) { @@ -6714,7 +7163,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) @@ -6777,7 +7226,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); } } @@ -6801,7 +7253,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; @@ -6815,7 +7267,7 @@ 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: complaint (&symfile_complaints, @@ -6825,6 +7277,28 @@ dwarf2_get_ref_die_offset (struct attribute *attr) 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) { @@ -6845,7 +7319,8 @@ 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) { @@ -6857,46 +7332,44 @@ dwarf2_fundamental_type (struct objfile *objfile, int typeid) 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; @@ -6909,14 +7382,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) { @@ -6989,6 +7457,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: @@ -6996,74 +7466,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 - { - complaint (&symfile_complaints, - "DW_AT_frame_base missing for DW_OP_fbreg"); - 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; @@ -7129,9 +7538,10 @@ 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) dwarf2_complex_location_expr_complaint (); break; @@ -7141,6 +7551,8 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, 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; @@ -7156,7 +7568,6 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, /* memory allocation interface */ -/* ARGSUSED */ static void dwarf2_free_tmp_obstack (void *ignore) { @@ -7246,7 +7657,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) @@ -7436,8 +7847,7 @@ parse_macro_definition (struct macro_source_file *file, int line, 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; @@ -7513,7 +7923,7 @@ 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; @@ -7584,36 +7994,35 @@ attr_form_is_block (struct attribute *attr) static void dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, - const struct comp_unit_head *cu_header, - struct objfile *objfile) + struct dwarf2_cu *cu) { if (attr->form == DW_FORM_data4 || attr->form == DW_FORM_data8) { struct dwarf2_loclist_baton *baton; - baton = obstack_alloc (&objfile->symbol_obstack, + baton = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (struct dwarf2_loclist_baton)); - baton->objfile = objfile; + 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) + 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_LOCATION_FUNCS (sym) = &dwarf2_loclist_funcs; + SYMBOL_OPS (sym) = &dwarf2_loclist_funcs; SYMBOL_LOCATION_BATON (sym) = baton; } else { struct dwarf2_locexpr_baton *baton; - baton = obstack_alloc (&objfile->symbol_obstack, + baton = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (struct dwarf2_locexpr_baton)); - baton->objfile = objfile; + baton->objfile = cu->objfile; if (attr_form_is_block (attr)) { @@ -7633,7 +8042,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, baton->data = NULL; } - SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs; + SYMBOL_OPS (sym) = &dwarf2_locexpr_funcs; SYMBOL_LOCATION_BATON (sym) = baton; } }