X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=3d9902c799994738fc8c6fc387a767cec5ccf6c6;hb=9733f989bbfcefd612a9712683eeebff74329bf4;hp=b6162d4bb918e277b59bb5d4e51eeaaa59ef96fb;hpb=1e9c814fb93ece8958aec6810e4e2e3c3859aa1a;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index b6162d4bb9..3d9902c799 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 Free Software Foundation, Inc. + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, Inc. with support from Florida State University (under contract @@ -8,25 +9,25 @@ based on Fred Fish's (Cygnus Support) implementation of DWARF 1 support in dwarfread.c -This file is part of GDB. + This file is part of GDB. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or (at -your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at + your option) any later version. -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #include "defs.h" #include "bfd.h" -#include "elf-bfd.h" #include "symtab.h" #include "gdbtypes.h" #include "symfile.h" @@ -35,14 +36,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "buildsym.h" #include "demangle.h" #include "expression.h" +#include "filenames.h" /* for DOSish file names */ + #include "language.h" #include "complaints.h" - +#include "bcache.h" #include #include "gdb_string.h" #include -/* .debug_info header for a compilation unit +#ifndef DWARF2_REG_TO_REGNUM +#define DWARF2_REG_TO_REGNUM(REG) (REG) +#endif + +#if 0 +/* .debug_info header for a compilation unit Because of alignment constraints, this structure has padding and cannot be mapped directly onto the beginning of the .debug_info section. */ typedef struct comp_unit_header @@ -56,6 +64,7 @@ typedef struct comp_unit_header } _COMP_UNIT_HEADER; #define _ACTUAL_COMP_UNIT_HEADER_SIZE 11 +#endif /* .debug_pubnames header Because of alignment constraints, this structure has padding and cannot @@ -145,13 +154,18 @@ static unsigned int dwarf_str_size; /* local data types */ -/* The data in a compilation unit header looks like this. */ +/* The data in a compilation unit header, after target2host + translation, looks like this. */ struct comp_unit_head { - unsigned int length; + unsigned long length; short version; unsigned int abbrev_offset; unsigned char addr_size; + unsigned char signed_addr_p; + unsigned int offset_size; /* size of file offsets; either 4 or 8 */ + unsigned int initial_length_size; /* size of the length field; either + 4 or 12 */ }; /* The data in the .debug_line statement prologue looks like this. */ @@ -207,15 +221,15 @@ struct attr_abbrev /* This data structure holds a complete die structure. */ 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 */ - struct type *type; /* Cached type information */ + 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 */ + struct type *type; /* Cached type information */ }; /* Attributes have a name and a value */ @@ -227,8 +241,8 @@ struct attribute { char *str; struct dwarf_block *blk; - unsigned int unsnd; - int snd; + unsigned long unsnd; + long int snd; CORE_ADDR addr; } u; @@ -302,13 +316,28 @@ static struct partial_die_info zeroed_partial_die; in buildsym.c. */ static struct pending **list_in_scope = &file_symbols; -/* FIXME: The following variables pass additional information from - decode_locdesc to the caller. */ -static int optimized_out; /* Kludge to identify optimized out variables */ -static int isreg; /* Kludge to identify register variables */ -static int offreg; /* Kludge to identify basereg references */ -static int basereg; /* Which base register is it relative to? */ -static int islocal; /* Kludge to identify local variables */ +/* 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 @@ -318,7 +347,7 @@ static int islocal; /* Kludge to identify local variables */ static int frame_base_reg; static CORE_ADDR frame_base_offset; -/* This value is added to each symbol value. FIXME: Generalize to +/* 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 */ @@ -333,27 +362,27 @@ static CORE_ADDR baseaddr; /* Add to each symbol value */ of symbols read from an object file. */ struct dwarf2_pinfo -{ - /* Pointer to start of dwarf info buffer for the objfile. */ + { + /* Pointer to start of dwarf info buffer for the objfile. */ - char *dwarf_info_buffer; + char *dwarf_info_buffer; - /* Offset in dwarf_info_buffer for this compilation unit. */ + /* Offset in dwarf_info_buffer for this compilation unit. */ - unsigned long dwarf_info_offset; + unsigned long dwarf_info_offset; - /* Pointer to start of dwarf abbreviation buffer for the objfile. */ + /* Pointer to start of dwarf abbreviation buffer for the objfile. */ - char *dwarf_abbrev_buffer; + char *dwarf_abbrev_buffer; - /* Size of dwarf abbreviation section for the objfile. */ + /* Size of dwarf abbreviation section for the objfile. */ - unsigned int dwarf_abbrev_size; + unsigned int dwarf_abbrev_size; - /* Pointer to start of dwarf line buffer for the objfile. */ + /* Pointer to start of dwarf line buffer for the objfile. */ - char *dwarf_line_buffer; -}; + char *dwarf_line_buffer; + }; #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private) #define DWARF_INFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_info_buffer) @@ -382,46 +411,49 @@ static int bits_per_byte = 8; pass lists of data member fields and lists of member function fields in an instance of a field_info structure, as defined below. */ struct field_info -{ - /* List of data member and baseclasses fields. */ - struct nextfield - { - struct nextfield *next; - int accessibility; - int virtuality; - struct field field; - } *fields; + { + /* List of data member and baseclasses fields. */ + struct nextfield + { + struct nextfield *next; + int accessibility; + int virtuality; + struct field field; + } + *fields; - /* Number of fields. */ - int nfields; + /* Number of fields. */ + int nfields; - /* Number of baseclasses. */ - int nbaseclasses; + /* Number of baseclasses. */ + int nbaseclasses; - /* Set if the accesibility of one of the fields is not public. */ - int non_public_fields; + /* Set if the accesibility of one of the fields is not public. */ + int non_public_fields; - /* Member function fields array, entries are allocated in the order they - are encountered in the object file. */ - struct nextfnfield - { - struct nextfnfield *next; - struct fn_field fnfield; - } *fnfields; + /* Member function fields array, entries are allocated in the order they + are encountered in the object file. */ + struct nextfnfield + { + struct nextfnfield *next; + struct fn_field fnfield; + } + *fnfields; - /* Member function fieldlist array, contains name of possibly overloaded - member function, number of overloaded member functions and a pointer - to the head of the member function field chain. */ - struct fnfieldlist - { - char *name; - int length; - struct nextfnfield *head; - } *fnfieldlists; + /* Member function fieldlist array, contains name of possibly overloaded + member function, number of overloaded member functions and a pointer + to the head of the member function field chain. */ + struct fnfieldlist + { + char *name; + int length; + struct nextfnfield *head; + } + *fnfieldlists; - /* Number of entries in the fnfieldlists array. */ - int nfnfields; -}; + /* Number of entries in the fnfieldlists array. */ + int nfnfields; + }; /* FIXME: Kludge to mark a varargs function type for C++ member function argument processing. */ @@ -464,6 +496,10 @@ static struct complaint dwarf2_unsupported_stack_op = { "unsupported stack op: '%s'", 0, 0 }; +static struct complaint dwarf2_complex_location_expr = +{ + "location expression too complex", 0, 0 +}; static struct complaint dwarf2_unsupported_tag = { "unsupported tag: '%s'", 0, 0 @@ -517,238 +553,240 @@ static struct complaint dwarf2_unsupported_const_value_attr = "unsupported const value attribute form: '%s'", 0, 0 }; -/* Remember the addr_size read from the dwarf. - If a target expects to link compilation units with differing address - sizes, gdb needs to be sure that the appropriate size is here for - whatever scope is currently getting read. */ -static int address_size; - -/* Some elf32 object file formats while linked for a 32 bit address - space contain debug information that has assumed 64 bit - addresses. Eg 64 bit MIPS target produced by GCC/GAS/LD where the - symbol table contains 32bit address values while its .debug_info - section contains 64 bit address values. - ADDRESS_SIGNIFICANT_SIZE specifies the number significant bits in - the ADDRESS_SIZE bytes read from the file */ -static int address_significant_size; - /* Externals references. */ extern int info_verbose; /* From main.c; nonzero => verbose */ /* local function prototypes */ -static void dwarf2_locate_sections PARAMS ((bfd *, asection *, PTR)); +static void dwarf2_locate_sections (bfd *, asection *, PTR); #if 0 -static void dwarf2_build_psymtabs_easy PARAMS ((struct objfile *, - struct section_offsets *, - int)); +static void dwarf2_build_psymtabs_easy (struct objfile *, int); #endif -static void dwarf2_build_psymtabs_hard PARAMS ((struct objfile *, - struct section_offsets *, - 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 void add_partial_symbol (struct partial_die_info *, struct objfile *, + const struct comp_unit_head *); + +static void dwarf2_psymtab_to_symtab (struct partial_symtab *); + +static void psymtab_to_symtab_1 (struct partial_symtab *); -static char *scan_partial_symbols PARAMS ((char *, struct objfile *, - CORE_ADDR *, CORE_ADDR *)); +static char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int); -static void add_partial_symbol PARAMS ((struct partial_die_info *, - struct objfile *)); +static void dwarf2_read_abbrevs (bfd *, unsigned int); -static void dwarf2_psymtab_to_symtab PARAMS ((struct partial_symtab *)); +static void dwarf2_empty_abbrev_table (PTR); -static void psymtab_to_symtab_1 PARAMS ((struct partial_symtab *)); +static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int); -static char *dwarf2_read_section PARAMS ((struct objfile *, file_ptr, - unsigned int)); +static char *read_partial_die (struct partial_die_info *, + bfd *, char *, int *, + const struct comp_unit_head *); -static void dwarf2_read_abbrevs PARAMS ((bfd *, unsigned int)); +static char *read_full_die (struct die_info **, bfd *, char *, + const struct comp_unit_head *); -static void dwarf2_empty_abbrev_table PARAMS ((PTR)); +static char *read_attribute (struct attribute *, struct attr_abbrev *, + bfd *, char *, const struct comp_unit_head *); -static struct abbrev_info *dwarf2_lookup_abbrev PARAMS ((unsigned int)); +static unsigned int read_1_byte (bfd *, char *); -static char *read_partial_die PARAMS ((struct partial_die_info *, - bfd *, char *, int *)); +static int read_1_signed_byte (bfd *, char *); -static char *read_full_die PARAMS ((struct die_info **, bfd *, char *)); +static unsigned int read_2_bytes (bfd *, char *); -static char *read_attribute PARAMS ((struct attribute *, struct attr_abbrev *, - bfd *, char *)); +static unsigned int read_4_bytes (bfd *, char *); -static unsigned int read_1_byte PARAMS ((bfd *, char *)); +static unsigned long read_8_bytes (bfd *, char *); -static int read_1_signed_byte PARAMS ((bfd *, char *)); +static CORE_ADDR read_address (bfd *, char *ptr, const struct comp_unit_head *, + int *bytes_read); -static unsigned int read_2_bytes PARAMS ((bfd *, char *)); +static LONGEST read_initial_length (bfd *, char *, + struct comp_unit_head *, int *bytes_read); -static unsigned int read_4_bytes PARAMS ((bfd *, char *)); +static LONGEST read_offset (bfd *, char *, const struct comp_unit_head *, + int *bytes_read); -static unsigned int read_8_bytes PARAMS ((bfd *, char *)); +static char *read_n_bytes (bfd *, char *, unsigned int); -static CORE_ADDR read_address PARAMS ((bfd *, char *)); +static char *read_string (bfd *, char *, unsigned int *); -static char *read_n_bytes PARAMS ((bfd *, char *, unsigned int)); +static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *); -static char *read_string PARAMS ((bfd *, char *, unsigned int *)); +static long read_signed_leb128 (bfd *, char *, unsigned int *); -static unsigned int read_unsigned_leb128 PARAMS ((bfd *, char *, - unsigned int *)); +static void set_cu_language (unsigned int); -static int read_signed_leb128 PARAMS ((bfd *, char *, unsigned int *)); +static struct attribute *dwarf_attr (struct die_info *, unsigned int); -static void set_cu_language PARAMS ((unsigned int)); +static int die_is_declaration (struct die_info *); -static struct attribute *dwarf_attr PARAMS ((struct die_info *, - unsigned int)); +static void dwarf_decode_lines (unsigned int, char *, bfd *, + const struct comp_unit_head *); -static void dwarf_decode_lines PARAMS ((unsigned int, char *, bfd *)); +static void dwarf2_start_subfile (char *, char *); -static void dwarf2_start_subfile PARAMS ((char *, char *)); +static struct symbol *new_symbol (struct die_info *, struct type *, + struct objfile *, const struct comp_unit_head *); -static struct symbol *new_symbol PARAMS ((struct die_info *, struct type *, - struct objfile *)); +static void dwarf2_const_value (struct attribute *, struct symbol *, + struct objfile *, const struct comp_unit_head *); -static void dwarf2_const_value PARAMS ((struct attribute *, struct symbol *, - struct objfile *)); +static void dwarf2_const_value_data (struct attribute *attr, + struct symbol *sym, + int bits); -static struct type *die_type PARAMS ((struct die_info *, struct objfile *)); +static struct type *die_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static struct type *die_containing_type PARAMS ((struct die_info *, - struct objfile *)); +static struct type *die_containing_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); #if 0 -static struct type *type_at_offset PARAMS ((unsigned int, struct objfile *)); +static struct type *type_at_offset (unsigned int, struct objfile *); #endif -static struct type *tag_type_to_type PARAMS ((struct die_info *, - struct objfile *)); +static struct type *tag_type_to_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_type_die PARAMS ((struct die_info *, struct objfile *)); +static void read_type_die (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_typedef PARAMS ((struct die_info *, struct objfile *)); +static void read_typedef (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_base_type PARAMS ((struct die_info *, struct objfile *)); +static void read_base_type (struct die_info *, struct objfile *); -static void read_file_scope PARAMS ((struct die_info *, struct objfile *)); +static void read_file_scope (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_func_scope PARAMS ((struct die_info *, struct objfile *)); +static void read_func_scope (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_lexical_block_scope PARAMS ((struct die_info *, - struct objfile *)); +static void read_lexical_block_scope (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static int dwarf2_get_pc_bounds PARAMS ((struct die_info *, - CORE_ADDR *, CORE_ADDR *, - struct objfile *)); +static int dwarf2_get_pc_bounds (struct die_info *, + CORE_ADDR *, CORE_ADDR *, struct objfile *); -static void dwarf2_add_field PARAMS ((struct field_info *, struct die_info *, - struct objfile *)); +static void dwarf2_add_field (struct field_info *, struct die_info *, + struct objfile *, const struct comp_unit_head *); -static void dwarf2_attach_fields_to_type PARAMS ((struct field_info *, - struct type *, - struct objfile *)); +static void dwarf2_attach_fields_to_type (struct field_info *, + struct type *, struct objfile *); -static char *skip_member_fn_name PARAMS ((char *)); +static void dwarf2_add_member_fn (struct field_info *, + struct die_info *, struct type *, + struct objfile *objfile, + const struct comp_unit_head *); -static void dwarf2_add_member_fn PARAMS ((struct field_info *, - struct die_info *, struct type *, - struct objfile *objfile)); +static void dwarf2_attach_fn_fields_to_type (struct field_info *, + struct type *, struct objfile *); -static void dwarf2_attach_fn_fields_to_type PARAMS ((struct field_info *, - struct type *, - struct objfile *)); +static void read_structure_scope (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_structure_scope PARAMS ((struct die_info *, struct objfile *)); +static void read_common_block (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_common_block PARAMS ((struct die_info *, struct objfile *)); +static void read_enumeration (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_enumeration PARAMS ((struct die_info *, struct objfile *)); +static struct type *dwarf_base_type (int, int, struct objfile *); -static struct type *dwarf_base_type PARAMS ((int, int, struct objfile *)); +static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *, + const struct comp_unit_head *); -static CORE_ADDR decode_locdesc PARAMS ((struct dwarf_block *, - struct objfile *)); +static void read_array_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_array_type PARAMS ((struct die_info *, struct objfile *)); +static void read_tag_pointer_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_tag_pointer_type PARAMS ((struct die_info *, - struct objfile *)); +static void read_tag_ptr_to_member_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_tag_ptr_to_member_type PARAMS ((struct die_info *, - struct objfile *)); +static void read_tag_reference_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_tag_reference_type PARAMS ((struct die_info *, - struct objfile *)); +static void read_tag_const_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_tag_const_type PARAMS ((struct die_info *, struct objfile *)); +static void read_tag_volatile_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_tag_volatile_type PARAMS ((struct die_info *, - struct objfile *)); +static void read_tag_string_type (struct die_info *, struct objfile *); -static void read_tag_string_type PARAMS ((struct die_info *, - struct objfile *)); +static void read_subroutine_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_subroutine_type PARAMS ((struct die_info *, - struct objfile *)); +struct die_info *read_comp_unit (char *, bfd *, const struct comp_unit_head *); -struct die_info *read_comp_unit PARAMS ((char *, bfd *)); +static void free_die_list (struct die_info *); -static void free_die_list PARAMS ((struct die_info *)); +static struct cleanup *make_cleanup_free_die_list (struct die_info *); -static void process_die PARAMS ((struct die_info *, struct objfile *)); +static void process_die (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static char *dwarf2_linkage_name PARAMS ((struct die_info *)); +static char *dwarf2_linkage_name (struct die_info *); -static char *dwarf_tag_name PARAMS ((unsigned int)); +static char *dwarf_tag_name (unsigned int); -static char *dwarf_attr_name PARAMS ((unsigned int)); +static char *dwarf_attr_name (unsigned int); -static char *dwarf_form_name PARAMS ((unsigned int)); +static char *dwarf_form_name (unsigned int); -static char *dwarf_stack_op_name PARAMS ((unsigned int)); +static char *dwarf_stack_op_name (unsigned int); -static char *dwarf_bool_name PARAMS ((unsigned int)); +static char *dwarf_bool_name (unsigned int); -static char *dwarf_type_encoding_name PARAMS ((unsigned int)); +static char *dwarf_type_encoding_name (unsigned int); #if 0 -static char *dwarf_cfi_name PARAMS ((unsigned int)); +static char *dwarf_cfi_name (unsigned int); -struct die_info *copy_die PARAMS ((struct die_info *)); +struct die_info *copy_die (struct die_info *); #endif -struct die_info *sibling_die PARAMS ((struct die_info *)); +struct die_info *sibling_die (struct die_info *); -void dump_die PARAMS ((struct die_info *)); +void dump_die (struct die_info *); -void dump_die_list PARAMS ((struct die_info *)); +void dump_die_list (struct die_info *); -void store_in_ref_table PARAMS ((unsigned int, struct die_info *)); +void store_in_ref_table (unsigned int, struct die_info *); -static void dwarf2_empty_die_ref_table PARAMS ((void)); +static void dwarf2_empty_hash_tables (void); -static unsigned int dwarf2_get_ref_die_offset PARAMS ((struct attribute *)); +static unsigned int dwarf2_get_ref_die_offset (struct attribute *); -struct die_info *follow_die_ref PARAMS ((unsigned int)); +struct die_info *follow_die_ref (unsigned int); -static struct type *dwarf2_fundamental_type PARAMS ((struct objfile *, int)); +static struct type *dwarf2_fundamental_type (struct objfile *, int); /* memory allocation interface */ -static void dwarf2_free_tmp_obstack PARAMS ((PTR)); +static void dwarf2_free_tmp_obstack (PTR); -static struct dwarf_block *dwarf_alloc_block PARAMS ((void)); +static struct dwarf_block *dwarf_alloc_block (void); -static struct abbrev_info *dwarf_alloc_abbrev PARAMS ((void)); +static struct abbrev_info *dwarf_alloc_abbrev (void); -static struct die_info *dwarf_alloc_die PARAMS ((void)); +static struct die_info *dwarf_alloc_die (void); /* Try to locate the sections we need for DWARF 2 debugging information and return true if we have enough to do something. */ int -dwarf2_has_info (abfd) - bfd *abfd; +dwarf2_has_info (bfd *abfd) { dwarf_info_offset = dwarf_abbrev_offset = dwarf_line_offset = 0; bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL); @@ -767,10 +805,7 @@ dwarf2_has_info (abfd) in. */ static void -dwarf2_locate_sections (ignore_abfd, sectp, ignore_ptr) - bfd *ignore_abfd; - asection *sectp; - PTR ignore_ptr; +dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, PTR ignore_ptr) { if (STREQ (sectp->name, INFO_SECTION)) { @@ -817,10 +852,7 @@ dwarf2_locate_sections (ignore_abfd, sectp, ignore_ptr) /* Build a partial symbol table. */ void -dwarf2_build_psymtabs (objfile, section_offsets, mainline) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; +dwarf2_build_psymtabs (struct objfile *objfile, int mainline) { /* We definitely need the .debug_info and .debug_abbrev sections */ @@ -844,17 +876,17 @@ dwarf2_build_psymtabs (objfile, section_offsets, mainline) #if 0 if (dwarf_aranges_offset && dwarf_pubnames_offset) { - /* Things are significanlty easier if we have .debug_aranges and + /* Things are significantly easier if we have .debug_aranges and .debug_pubnames sections */ - dwarf2_build_psymtabs_easy (objfile, section_offsets, mainline); + dwarf2_build_psymtabs_easy (objfile, mainline); } else #endif /* only test this case for now */ - { + { /* In this case we have to work a bit harder */ - dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline); + dwarf2_build_psymtabs_hard (objfile, mainline); } } @@ -863,10 +895,7 @@ dwarf2_build_psymtabs (objfile, section_offsets, mainline) .debug_pubnames and .debug_aranges sections. */ static void -dwarf2_build_psymtabs_easy (objfile, section_offsets, mainline) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; +dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) { bfd *abfd = objfile->obfd; char *aranges_buffer, *pubnames_buffer; @@ -879,8 +908,12 @@ dwarf2_build_psymtabs_easy (objfile, section_offsets, mainline) pubnames_ptr = pubnames_buffer; while ((pubnames_ptr - pubnames_buffer) < dwarf_pubnames_size) { - entry_length = read_4_bytes (abfd, pubnames_ptr); - pubnames_ptr += 4; + struct comp_unit_head cu_header; + int bytes_read; + + entry_length = read_initial_length (abfd, pubnames_ptr, &cu_header, + &bytes_read); + pubnames_ptr += bytes_read; version = read_1_byte (abfd, pubnames_ptr); pubnames_ptr += 1; info_offset = read_4_bytes (abfd, pubnames_ptr); @@ -896,30 +929,50 @@ dwarf2_build_psymtabs_easy (objfile, section_offsets, mainline) } #endif +/* Read in the comp unit header information from the debug_info at + info_ptr. */ + +static char * +read_comp_unit_head (struct comp_unit_head *cu_header, + char *info_ptr, bfd *abfd) +{ + int signed_addr; + int bytes_read; + cu_header->length = read_initial_length (abfd, info_ptr, cu_header, + &bytes_read); + info_ptr += bytes_read; + cu_header->version = read_2_bytes (abfd, info_ptr); + info_ptr += 2; + cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header, + &bytes_read); + info_ptr += bytes_read; + cu_header->addr_size = read_1_byte (abfd, info_ptr); + info_ptr += 1; + signed_addr = bfd_get_sign_extend_vma (abfd); + if (signed_addr < 0) + internal_error (__FILE__, __LINE__, + "read_comp_unit_head: dwarf from non elf file"); + cu_header->signed_addr_p = signed_addr; + return info_ptr; +} + /* Build the partial symbol table by doing a quick pass through the .debug_info and .debug_abbrev sections. */ static void -dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline) - struct objfile *objfile; - struct section_offsets *section_offsets; - int mainline; +dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) { /* Instead of reading this into a big buffer, we should probably use mmap() on architectures that support it. (FIXME) */ bfd *abfd = objfile->obfd; char *info_ptr, *abbrev_ptr; char *beg_of_comp_unit; - struct comp_unit_head cu_header; struct partial_die_info comp_unit_die; struct partial_symtab *pst; struct cleanup *back_to; int comp_unit_has_pc_info; CORE_ADDR lowpc, highpc; - /* Number of bytes of any addresses that are signficant */ - address_significant_size = get_elf_backend_data (abfd)->s->arch_size / 8; - info_ptr = dwarf_info_buffer; abbrev_ptr = dwarf_abbrev_buffer; @@ -927,18 +980,11 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline) back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL); while ((unsigned int) (info_ptr - dwarf_info_buffer) - + ((info_ptr - dwarf_info_buffer) % 4) < dwarf_info_size) + + ((info_ptr - dwarf_info_buffer) % 4) < dwarf_info_size) { + struct comp_unit_head cu_header; beg_of_comp_unit = info_ptr; - cu_header.length = read_4_bytes (abfd, info_ptr); - info_ptr += 4; - cu_header.version = read_2_bytes (abfd, info_ptr); - info_ptr += 2; - cu_header.abbrev_offset = read_4_bytes (abfd, info_ptr); - info_ptr += 4; - cu_header.addr_size = read_1_byte (abfd, info_ptr); - info_ptr += 1; - address_size = cu_header.addr_size; + info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd); if (cu_header.version != 2) { @@ -952,7 +998,7 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline) (long) (beg_of_comp_unit - dwarf_info_buffer)); return; } - if (beg_of_comp_unit + cu_header.length + 4 + 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).", @@ -960,27 +1006,20 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline) (long) (beg_of_comp_unit - dwarf_info_buffer)); return; } - if (address_size < address_significant_size) - { - error ("Dwarf Error: bad address size (%ld) in compilation unit header (offset 0x%lx + 11).", - (long) cu_header.addr_size, - (long) (beg_of_comp_unit - dwarf_info_buffer)); - } - /* Read the abbrevs for this compilation unit into a table */ dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset); make_cleanup (dwarf2_empty_abbrev_table, NULL); /* Read the compilation unit die */ - info_ptr = read_partial_die (&comp_unit_die, abfd, - info_ptr, &comp_unit_has_pc_info); + info_ptr = read_partial_die (&comp_unit_die, abfd, info_ptr, + &comp_unit_has_pc_info, &cu_header); /* Set the language we're debugging */ set_cu_language (comp_unit_die.language); /* Allocate a new partial symbol table structure */ - pst = start_psymtab_common (objfile, section_offsets, - comp_unit_die.name ? comp_unit_die.name : "", + pst = start_psymtab_common (objfile, objfile->section_offsets, + comp_unit_die.name ? comp_unit_die.name : "", comp_unit_die.lowpc, objfile->global_psymbols.next, objfile->static_psymbols.next); @@ -988,12 +1027,12 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline) pst->read_symtab_private = (char *) obstack_alloc (&objfile->psymbol_obstack, sizeof (struct dwarf2_pinfo)); cu_header_offset = beg_of_comp_unit - dwarf_info_buffer; - DWARF_INFO_BUFFER(pst) = dwarf_info_buffer; - DWARF_INFO_OFFSET(pst) = beg_of_comp_unit - dwarf_info_buffer; - DWARF_ABBREV_BUFFER(pst) = dwarf_abbrev_buffer; - DWARF_ABBREV_SIZE(pst) = dwarf_abbrev_size; - DWARF_LINE_BUFFER(pst) = dwarf_line_buffer; - baseaddr = ANOFFSET (section_offsets, 0); + 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; + DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size; + DWARF_LINE_BUFFER (pst) = dwarf_line_buffer; + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); /* Store the function that reads in the rest of the symbol table */ pst->read_symtab = dwarf2_psymtab_to_symtab; @@ -1002,16 +1041,19 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline) If so, read the rest of the partial symbols from this comp unit. If not, there's no more debug_info for this comp unit. */ if (comp_unit_die.has_children) - info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc); - - /* If the compilation unit didn't have an explicit address range, - then use the information extracted from its child dies. */ - if (!comp_unit_has_pc_info) { - comp_unit_die.lowpc = lowpc; - comp_unit_die.highpc = highpc; - } - pst->textlow = comp_unit_die.lowpc + baseaddr; + info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc, + &cu_header); + + /* If the compilation unit didn't have an explicit address range, + then use the information extracted from its child dies. */ + if (!comp_unit_has_pc_info) + { + comp_unit_die.lowpc = lowpc; + comp_unit_die.highpc = highpc; + } + } + pst->textlow = comp_unit_die.lowpc + baseaddr; pst->texthigh = comp_unit_die.highpc + baseaddr; pst->n_global_syms = objfile->global_psymbols.next - @@ -1025,7 +1067,8 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline) also happen.) This happens in VxWorks. */ free_named_symtabs (pst->filename); - info_ptr = beg_of_comp_unit + cu_header.length + 4; + info_ptr = beg_of_comp_unit + cu_header.length + + cu_header.initial_length_size; } do_cleanups (back_to); } @@ -1033,11 +1076,9 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline) /* Read in all interesting dies to the end of the compilation unit. */ static char * -scan_partial_symbols (info_ptr, objfile, lowpc, highpc) - char *info_ptr; - struct objfile *objfile; - CORE_ADDR *lowpc; - CORE_ADDR *highpc; +scan_partial_symbols (char *info_ptr, struct objfile *objfile, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + const struct comp_unit_head *cu_header) { bfd *abfd = objfile->obfd; struct partial_die_info pdi; @@ -1050,13 +1091,14 @@ scan_partial_symbols (info_ptr, objfile, lowpc, highpc) int nesting_level = 1; int has_pc_info; - - *lowpc = ((CORE_ADDR) -1); + + *lowpc = ((CORE_ADDR) -1); *highpc = ((CORE_ADDR) 0); while (nesting_level) { - info_ptr = read_partial_die (&pdi, abfd, info_ptr, &has_pc_info); + info_ptr = read_partial_die (&pdi, abfd, info_ptr, + &has_pc_info, cu_header); if (pdi.name) { @@ -1076,7 +1118,7 @@ scan_partial_symbols (info_ptr, objfile, lowpc, highpc) if ((pdi.is_external || nesting_level == 1) && !pdi.is_declaration) { - add_partial_symbol (&pdi, objfile); + add_partial_symbol (&pdi, objfile, cu_header); } } break; @@ -1089,20 +1131,20 @@ scan_partial_symbols (info_ptr, objfile, lowpc, highpc) if ((pdi.is_external || nesting_level == 1) && !pdi.is_declaration) { - add_partial_symbol (&pdi, objfile); + add_partial_symbol (&pdi, objfile, cu_header); } break; case DW_TAG_enumerator: /* File scope enumerators are added to the partial symbol - table. */ + table. */ if (nesting_level == 2) - add_partial_symbol (&pdi, objfile); + add_partial_symbol (&pdi, objfile, cu_header); break; case DW_TAG_base_type: /* File scope base type definitions are added to the partial - symbol table. */ + symbol table. */ if (nesting_level == 1) - add_partial_symbol (&pdi, objfile); + add_partial_symbol (&pdi, objfile, cu_header); break; default: break; @@ -1110,8 +1152,8 @@ scan_partial_symbols (info_ptr, objfile, lowpc, highpc) } /* If the die has a sibling, skip to the sibling. - Do not skip enumeration types, we want to record their - enumerators. */ + Do not skip enumeration types, we want to record their + enumerators. */ if (pdi.sibling && pdi.tag != DW_TAG_enumeration_type) { info_ptr = pdi.sibling; @@ -1137,9 +1179,8 @@ scan_partial_symbols (info_ptr, objfile, lowpc, highpc) } static void -add_partial_symbol (pdi, objfile) - struct partial_die_info *pdi; - struct objfile *objfile; +add_partial_symbol (struct partial_die_info *pdi, struct objfile *objfile, + const struct comp_unit_head *cu_header) { CORE_ADDR addr = 0; @@ -1148,21 +1189,21 @@ add_partial_symbol (pdi, objfile) case DW_TAG_subprogram: if (pdi->is_external) { - prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr, - mst_text, objfile); + /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr, + mst_text, objfile); */ add_psymbol_to_list (pdi->name, strlen (pdi->name), VAR_NAMESPACE, LOC_BLOCK, &objfile->global_psymbols, - 0, pdi->lowpc + baseaddr, cu_language, objfile); + 0, pdi->lowpc + baseaddr, cu_language, objfile); } else { - prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr, - mst_file_text, objfile); + /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr, + mst_file_text, objfile); */ add_psymbol_to_list (pdi->name, strlen (pdi->name), VAR_NAMESPACE, LOC_BLOCK, &objfile->static_psymbols, - 0, pdi->lowpc + baseaddr, cu_language, objfile); + 0, pdi->lowpc + baseaddr, cu_language, objfile); } break; case DW_TAG_variable: @@ -1182,7 +1223,7 @@ add_partial_symbol (pdi, objfile) table building. */ if (pdi->locdesc) - addr = decode_locdesc (pdi->locdesc, objfile); + addr = decode_locdesc (pdi->locdesc, objfile, cu_header); if (pdi->locdesc || pdi->has_type) add_psymbol_to_list (pdi->name, strlen (pdi->name), VAR_NAMESPACE, LOC_STATIC, @@ -1194,9 +1235,9 @@ add_partial_symbol (pdi, objfile) /* Static Variable. Skip symbols without location descriptors. */ if (pdi->locdesc == NULL) return; - addr = decode_locdesc (pdi->locdesc, objfile); - prim_record_minimal_symbol (pdi->name, addr + baseaddr, - mst_file_data, objfile); + addr = decode_locdesc (pdi->locdesc, objfile, cu_header); + /*prim_record_minimal_symbol (pdi->name, addr + baseaddr, + mst_file_data, objfile); */ add_psymbol_to_list (pdi->name, strlen (pdi->name), VAR_NAMESPACE, LOC_STATIC, &objfile->static_psymbols, @@ -1215,7 +1256,7 @@ add_partial_symbol (pdi, objfile) case DW_TAG_union_type: case DW_TAG_enumeration_type: /* Skip aggregate types without children, these are external - references. */ + references. */ if (pdi->has_children == 0) return; add_psymbol_to_list (pdi->name, strlen (pdi->name), @@ -1246,8 +1287,7 @@ add_partial_symbol (pdi, objfile) /* Expand this partial symbol table into a full symbol table. */ static void -dwarf2_psymtab_to_symtab (pst) - struct partial_symtab *pst; +dwarf2_psymtab_to_symtab (struct partial_symtab *pst) { /* FIXME: This is barely more than a stub. */ if (pst != NULL) @@ -1274,8 +1314,7 @@ dwarf2_psymtab_to_symtab (pst) } static void -psymtab_to_symtab_1 (pst) - struct partial_symtab *pst; +psymtab_to_symtab_1 (struct partial_symtab *pst) { struct objfile *objfile = pst->objfile; bfd *abfd = objfile->obfd; @@ -1289,12 +1328,12 @@ psymtab_to_symtab_1 (pst) struct cleanup *back_to; /* Set local variables from the partial symbol table info. */ - offset = DWARF_INFO_OFFSET(pst); - dwarf_info_buffer = DWARF_INFO_BUFFER(pst); - dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER(pst); - dwarf_abbrev_size = DWARF_ABBREV_SIZE(pst); - dwarf_line_buffer = DWARF_LINE_BUFFER(pst); - baseaddr = ANOFFSET (pst->section_offsets, 0); + offset = DWARF_INFO_OFFSET (pst); + dwarf_info_buffer = DWARF_INFO_BUFFER (pst); + dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst); + dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst); + dwarf_line_buffer = DWARF_LINE_BUFFER (pst); + baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile)); cu_header_offset = offset; info_ptr = dwarf_info_buffer + offset; @@ -1305,31 +1344,24 @@ psymtab_to_symtab_1 (pst) make_cleanup (really_free_pendings, NULL); /* read in the comp_unit header */ - cu_header.length = read_4_bytes (abfd, info_ptr); - info_ptr += 4; - cu_header.version = read_2_bytes (abfd, info_ptr); - info_ptr += 2; - cu_header.abbrev_offset = read_4_bytes (abfd, info_ptr); - info_ptr += 4; - cu_header.addr_size = read_1_byte (abfd, info_ptr); - info_ptr += 1; + info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd); /* Read the abbrevs for this compilation unit */ dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset); make_cleanup (dwarf2_empty_abbrev_table, NULL); - dies = read_comp_unit (info_ptr, abfd); + dies = read_comp_unit (info_ptr, abfd, &cu_header); - make_cleanup (free_die_list, dies); + make_cleanup_free_die_list (dies); /* Do line number decoding in read_file_scope () */ - process_die (dies, objfile); + process_die (dies, objfile, &cu_header); if (!dwarf2_get_pc_bounds (dies, &lowpc, &highpc, objfile)) { /* 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. */ + 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) { @@ -1349,7 +1381,7 @@ psymtab_to_symtab_1 (pst) } } } - symtab = end_symtab (highpc + baseaddr, objfile, 0); + 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, @@ -1369,51 +1401,50 @@ psymtab_to_symtab_1 (pst) /* Process a die and its children. */ static void -process_die (die, objfile) - struct die_info *die; - struct objfile *objfile; +process_die (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { switch (die->tag) { case DW_TAG_padding: break; case DW_TAG_compile_unit: - read_file_scope (die, objfile); + read_file_scope (die, objfile, cu_header); break; case DW_TAG_subprogram: - read_subroutine_type (die, objfile); - read_func_scope (die, objfile); + read_subroutine_type (die, objfile, cu_header); + read_func_scope (die, objfile, cu_header); break; case DW_TAG_inlined_subroutine: /* FIXME: These are ignored for now. - They could be used to set breakpoints on all inlined instances - of a function and make GDB `next' properly over inlined functions. */ + They could be used to set breakpoints on all inlined instances + of a function and make GDB `next' properly over inlined functions. */ break; case DW_TAG_lexical_block: - read_lexical_block_scope (die, objfile); + read_lexical_block_scope (die, objfile, cu_header); break; case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: - read_structure_scope (die, objfile); + read_structure_scope (die, objfile, cu_header); break; case DW_TAG_enumeration_type: - read_enumeration (die, objfile); + read_enumeration (die, objfile, cu_header); break; case DW_TAG_subroutine_type: - read_subroutine_type (die, objfile); + read_subroutine_type (die, objfile, cu_header); break; case DW_TAG_array_type: - read_array_type (die, objfile); + read_array_type (die, objfile, cu_header); break; case DW_TAG_pointer_type: - read_tag_pointer_type (die, objfile); + read_tag_pointer_type (die, objfile, cu_header); break; case DW_TAG_ptr_to_member_type: - read_tag_ptr_to_member_type (die, objfile); + read_tag_ptr_to_member_type (die, objfile, cu_header); break; case DW_TAG_reference_type: - read_tag_reference_type (die, objfile); + read_tag_reference_type (die, objfile, cu_header); break; case DW_TAG_string_type: read_tag_string_type (die, objfile); @@ -1423,27 +1454,26 @@ process_die (die, objfile) if (dwarf_attr (die, DW_AT_name)) { /* Add a typedef symbol for the base type definition. */ - new_symbol (die, die->type, objfile); + new_symbol (die, die->type, objfile, cu_header); } break; case DW_TAG_common_block: - read_common_block (die, objfile); + read_common_block (die, objfile, cu_header); break; case DW_TAG_common_inclusion: break; default: - new_symbol (die, NULL, objfile); + new_symbol (die, NULL, objfile, cu_header); break; } } static void -read_file_scope (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_file_scope (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { unsigned int line_offset = 0; - CORE_ADDR lowpc = ((CORE_ADDR) -1); + CORE_ADDR lowpc = ((CORE_ADDR) -1); CORE_ADDR highpc = ((CORE_ADDR) 0); struct attribute *attr; char *name = ""; @@ -1516,8 +1546,8 @@ read_file_scope (die, objfile) /* We assume that we're processing GCC output. */ processing_gcc_compilation = 2; #if 0 - /* FIXME:Do something here. */ - if (dip->at_producer != NULL) + /* FIXME:Do something here. */ + if (dip->at_producer != NULL) { handle_producer (dip->at_producer); } @@ -1535,7 +1565,7 @@ read_file_scope (die, objfile) if (attr) { line_offset = DW_UNSND (attr); - dwarf_decode_lines (line_offset, comp_dir, abfd); + dwarf_decode_lines (line_offset, comp_dir, abfd, cu_header); } /* Process all dies in compilation unit. */ @@ -1544,16 +1574,15 @@ read_file_scope (die, objfile) child_die = die->next; while (child_die && child_die->tag) { - process_die (child_die, objfile); + process_die (child_die, objfile, cu_header); child_die = sibling_die (child_die); } } } static void -read_func_scope (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_func_scope (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { register struct context_stack *new; CORE_ADDR lowpc; @@ -1579,12 +1608,6 @@ read_func_scope (die, objfile) objfile->ei.entry_func_highpc = highpc; } - if (STREQ (name, "main")) /* FIXME: hardwired name */ - { - objfile->ei.main_func_lowpc = lowpc; - objfile->ei.main_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; @@ -1592,8 +1615,10 @@ read_func_scope (die, objfile) attr = dwarf_attr (die, DW_AT_frame_base); if (attr) { - CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile); - if (isreg) + CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); + if (isderef) + complain (&dwarf2_unsupported_at_frame_base, name); + else if (isreg) frame_base_reg = addr; else if (offreg) { @@ -1605,7 +1630,7 @@ read_func_scope (die, objfile) } new = push_context (0, lowpc); - new->name = new_symbol (die, die->type, objfile); + new->name = new_symbol (die, die->type, objfile, cu_header); list_in_scope = &local_symbols; if (die->has_children) @@ -1613,7 +1638,7 @@ read_func_scope (die, objfile) child_die = die->next; while (child_die && child_die->tag) { - process_die (child_die, objfile); + process_die (child_die, objfile, cu_header); child_die = sibling_die (child_die); } } @@ -1629,9 +1654,8 @@ read_func_scope (die, objfile) a new scope, process the dies, and then close the scope. */ static void -read_lexical_block_scope (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_lexical_block_scope (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { register struct context_stack *new; CORE_ADDR lowpc, highpc; @@ -1649,7 +1673,7 @@ read_lexical_block_scope (die, objfile) child_die = die->next; while (child_die && child_die->tag) { - process_die (child_die, objfile); + process_die (child_die, objfile, cu_header); child_die = sibling_die (child_die); } } @@ -1667,11 +1691,8 @@ read_lexical_block_scope (die, objfile) Return 1 if the attributes are present and valid, otherwise, return 0. */ static int -dwarf2_get_pc_bounds (die, lowpc, highpc, objfile) - struct die_info *die; - CORE_ADDR *lowpc; - CORE_ADDR *highpc; - struct objfile *objfile; +dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct objfile *objfile) { struct attribute *attr; CORE_ADDR low; @@ -1710,10 +1731,9 @@ dwarf2_get_pc_bounds (die, lowpc, highpc, objfile) /* Add an aggregate field to the field list. */ static void -dwarf2_add_field (fip, die, objfile) - struct field_info *fip; - struct die_info *die; - struct objfile *objfile; +dwarf2_add_field (struct field_info *fip, struct die_info *die, + struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct nextfield *new_field; struct attribute *attr; @@ -1722,7 +1742,7 @@ dwarf2_add_field (fip, die, objfile) /* Allocate a new field list entry and link it in. */ new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield)); - make_cleanup (free, new_field); + make_cleanup (xfree, new_field); memset (new_field, 0, sizeof (struct nextfield)); new_field->next = fip->fields; fip->fields = new_field; @@ -1750,7 +1770,7 @@ dwarf2_add_field (fip, die, objfile) if (die->tag == DW_TAG_member) { /* Get type of field. */ - fp->type = die_type (die, objfile); + fp->type = die_type (die, objfile, cu_header); /* Get bit size of field (zero if none). */ attr = dwarf_attr (die, DW_AT_bit_size); @@ -1768,7 +1788,7 @@ dwarf2_add_field (fip, die, objfile) if (attr) { FIELD_BITPOS (*fp) = - decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte; + decode_locdesc (DW_BLOCK (attr), objfile, cu_header) * bits_per_byte; } else FIELD_BITPOS (*fp) = 0; @@ -1778,20 +1798,20 @@ dwarf2_add_field (fip, die, objfile) if (BITS_BIG_ENDIAN) { /* For big endian bits, the DW_AT_bit_offset gives the - additional bit offset from the MSB of the containing - anonymous object to the MSB of the field. We don't - have to do anything special since we don't need to - know the size of the anonymous object. */ + additional bit offset from the MSB of the containing + anonymous object to the MSB of the field. We don't + have to do anything special since we don't need to + know the size of the anonymous object. */ FIELD_BITPOS (*fp) += DW_UNSND (attr); } else { /* For little endian bits, compute the bit offset to the - MSB of the anonymous object, subtract off the number of - bits from the MSB of the field to the MSB of the - object, and then subtract off the number of bits of - the field itself. The result is the bit offset of - the LSB of the field. */ + MSB of the anonymous object, subtract off the number of + bits from the MSB of the field to the MSB of the + object, and then subtract off the number of bits of + the field itself. The result is the bit offset of + the LSB of the field. */ int anonymous_size; int bit_offset = DW_UNSND (attr); @@ -1824,7 +1844,7 @@ dwarf2_add_field (fip, die, objfile) &objfile->type_obstack); /* Change accessibility for artificial fields (e.g. virtual table - pointer or virtual base class pointer) to private. */ + pointer or virtual base class pointer) to private. */ if (dwarf_attr (die, DW_AT_artificial)) { new_field->accessibility = DW_ACCESS_private; @@ -1834,38 +1854,33 @@ dwarf2_add_field (fip, die, objfile) else if (die->tag == DW_TAG_variable) { char *physname; - char *cp; /* C++ static member. - Get physical name, extract field name from physical name. */ - physname = dwarf2_linkage_name (die); - if (physname == NULL) + Get name of field. */ + attr = dwarf_attr (die, DW_AT_name); + if (attr && DW_STRING (attr)) + fieldname = DW_STRING (attr); + else return; - cp = physname; - while (*cp && !is_cplus_marker (*cp)) - cp++; - if (*cp) - fieldname = cp + 1; - if (*fieldname == '\0') - { - complain (&dwarf2_bad_static_member_name, physname); - } + /* Get physical name. */ + physname = dwarf2_linkage_name (die); SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname), - &objfile->type_obstack)); - FIELD_TYPE (*fp) = die_type (die, objfile); + &objfile->type_obstack)); + FIELD_TYPE (*fp) = die_type (die, objfile, cu_header); FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname), - &objfile->type_obstack); + &objfile->type_obstack); } else if (die->tag == DW_TAG_inheritance) { /* C++ base class field. */ attr = dwarf_attr (die, DW_AT_data_member_location); if (attr) - FIELD_BITPOS (*fp) = decode_locdesc (DW_BLOCK (attr), objfile) * bits_per_byte; + FIELD_BITPOS (*fp) = (decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + * bits_per_byte); FIELD_BITSIZE (*fp) = 0; - FIELD_TYPE (*fp) = die_type (die, objfile); + FIELD_TYPE (*fp) = die_type (die, objfile, cu_header); FIELD_NAME (*fp) = type_name_no_tag (fp->type); fip->nbaseclasses++; } @@ -1874,10 +1889,8 @@ dwarf2_add_field (fip, die, objfile) /* Create the vector of fields, and attach it to the type. */ static void -dwarf2_attach_fields_to_type (fip, type, objfile) - struct field_info *fip; - struct type *type; - struct objfile *objfile; +dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, + struct objfile *objfile) { int nfields = fip->nfields; @@ -1927,78 +1940,45 @@ dwarf2_attach_fields_to_type (fip, type, objfile) TYPE_FIELD (type, nfields) = fip->fields->field; switch (fip->fields->accessibility) { - case DW_ACCESS_private: - SET_TYPE_FIELD_PRIVATE (type, nfields); - break; + case DW_ACCESS_private: + SET_TYPE_FIELD_PRIVATE (type, nfields); + break; - case DW_ACCESS_protected: - SET_TYPE_FIELD_PROTECTED (type, nfields); - break; + case DW_ACCESS_protected: + SET_TYPE_FIELD_PROTECTED (type, nfields); + break; - case DW_ACCESS_public: - break; + case DW_ACCESS_public: + break; - default: - /* Unknown accessibility. Complain and treat it as public. */ - { - complain (&dwarf2_unsupported_accessibility, - fip->fields->accessibility); - } - break; + default: + /* Unknown accessibility. Complain and treat it as public. */ + { + complain (&dwarf2_unsupported_accessibility, + fip->fields->accessibility); + } + break; } if (nfields < fip->nbaseclasses) { switch (fip->fields->virtuality) { - case DW_VIRTUALITY_virtual: - case DW_VIRTUALITY_pure_virtual: - SET_TYPE_FIELD_VIRTUAL (type, nfields); - break; + case DW_VIRTUALITY_virtual: + case DW_VIRTUALITY_pure_virtual: + SET_TYPE_FIELD_VIRTUAL (type, nfields); + break; } } fip->fields = fip->fields->next; } } -/* Skip to the end of a member function name in a mangled name. */ - -static char * -skip_member_fn_name (physname) - char *physname; -{ - char *endname = physname; - - /* Skip over leading underscores. */ - while (*endname == '_') - endname++; - - /* Find two succesive underscores. */ - do - endname = strchr (endname, '_'); - while (endname != NULL && *++endname != '_'); - - if (endname == NULL) - { - complain (&dwarf2_bad_member_name_complaint, physname); - endname = physname; - } - else - { - /* Take care of trailing underscores. */ - if (endname[1] != '_') - endname--; - } - return endname; -} - /* Add a member function to the proper fieldlist. */ static void -dwarf2_add_member_fn (fip, die, type, objfile) - struct field_info *fip; - struct die_info *die; - struct type *type; - struct objfile *objfile; +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 attribute *attr; struct fnfieldlist *flp; @@ -2008,46 +1988,15 @@ dwarf2_add_member_fn (fip, die, type, objfile) char *physname; struct nextfnfield *new_fnfield; - /* Extract member function name from mangled name. */ - physname = dwarf2_linkage_name (die); - if (physname == NULL) - return; - if ((physname[0] == '_' && physname[1] == '_' - && strchr ("0123456789Qt", physname[2])) - || DESTRUCTOR_PREFIX_P (physname)) - { - /* Constructor and destructor field names are set to the name - of the class, but without template parameter lists. - The name might be missing for anonymous aggregates. */ - if (TYPE_TAG_NAME (type)) - { - char *p = strchr (TYPE_TAG_NAME (type), '<'); - - if (p == NULL) - fieldname = TYPE_TAG_NAME (type); - else - fieldname = obsavestring (TYPE_TAG_NAME (type), - p - TYPE_TAG_NAME (type), - &objfile->type_obstack); - } - else - { - char *anon_name = ""; - fieldname = obsavestring (anon_name, strlen (anon_name), - &objfile->type_obstack); - } - } + /* Get name of member function. */ + attr = dwarf_attr (die, DW_AT_name); + if (attr && DW_STRING (attr)) + fieldname = DW_STRING (attr); else - { - char *endname = skip_member_fn_name (physname); + return; - /* Ignore member function if we were unable not extract the member - function name. */ - if (endname == physname) - return; - fieldname = obsavestring (physname, endname - physname, - &objfile->type_obstack); - } + /* Get the mangled name. */ + physname = dwarf2_linkage_name (die); /* Look up member function name in fieldlist. */ for (i = 0; i < fip->nfnfields; i++) @@ -2066,7 +2015,7 @@ dwarf2_add_member_fn (fip, die, type, objfile) fip->fnfieldlists = (struct fnfieldlist *) xrealloc (fip->fnfieldlists, (fip->nfnfields + DW_FIELD_ALLOC_CHUNK) - * sizeof (struct fnfieldlist)); + * sizeof (struct fnfieldlist)); if (fip->nfnfields == 0) make_cleanup (free_current_contents, &fip->fnfieldlists); } @@ -2080,7 +2029,7 @@ dwarf2_add_member_fn (fip, die, type, objfile) /* Create a new member function field and chain it to the field list entry. */ new_fnfield = (struct nextfnfield *) xmalloc (sizeof (struct nextfnfield)); - make_cleanup (free, new_fnfield); + make_cleanup (xfree, new_fnfield); memset (new_fnfield, 0, sizeof (struct nextfnfield)); new_fnfield->next = flp->head; flp->head = new_fnfield; @@ -2113,11 +2062,11 @@ dwarf2_add_member_fn (fip, die, type, objfile) smash_to_method_type (fnp->type, type, return_type, arg_types); /* Handle static member functions. - Dwarf2 has no clean way to discern C++ static and non-static - member functions. G++ helps GDB by marking the first - parameter for non-static member functions (which is the - this pointer) as artificial. We obtain this information - from read_subroutine_type via TYPE_FIELD_ARTIFICIAL. */ + Dwarf2 has no clean way to discern C++ static and non-static + member functions. G++ helps GDB by marking the first + parameter for non-static member functions (which is the + this pointer) as artificial. We obtain this information + from read_subroutine_type via TYPE_FIELD_ARTIFICIAL. */ if (nparams == 0 || TYPE_FIELD_ARTIFICIAL (die->type, 0) == 0) fnp->voffset = VOFFSET_STATIC; } @@ -2126,7 +2075,7 @@ dwarf2_add_member_fn (fip, die, type, objfile) /* 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); + fnp->fcontext = die_containing_type (die, objfile, cu_header); /* 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. */ @@ -2137,28 +2086,26 @@ dwarf2_add_member_fn (fip, die, type, objfile) { switch (DW_UNSND (attr)) { - case DW_ACCESS_private: - fnp->is_private = 1; - break; - case DW_ACCESS_protected: - fnp->is_protected = 1; - break; + case DW_ACCESS_private: + fnp->is_private = 1; + break; + case DW_ACCESS_protected: + fnp->is_protected = 1; + break; } } /* Get index in virtual function table if it is a virtual member function. */ attr = dwarf_attr (die, DW_AT_vtable_elem_location); if (attr) - fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile) + 2; + fnp->voffset = decode_locdesc (DW_BLOCK (attr), objfile, cu_header) + 2; } /* Create the vector of member function fields, and attach it to the type. */ static void -dwarf2_attach_fn_fields_to_type (fip, type, objfile) - struct field_info *fip; - struct type *type; - struct objfile *objfile; +dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type, + struct objfile *objfile) { struct fnfieldlist *flp; int total_length = 0; @@ -2179,7 +2126,7 @@ dwarf2_attach_fn_fields_to_type (fip, type, objfile) fn_flp->fn_fields = (struct fn_field *) TYPE_ALLOC (type, sizeof (struct fn_field) * flp->length); for (k = flp->length; (k--, nfp); nfp = nfp->next) - fn_flp->fn_fields[k] = nfp->fnfield; + fn_flp->fn_fields[k] = nfp->fnfield; total_length += flp->length; } @@ -2205,9 +2152,8 @@ dwarf2_attach_fn_fields_to_type (fip, type, objfile) suppresses creating a symbol table entry itself). */ static void -read_structure_scope (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_structure_scope (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct type *type; struct attribute *attr; @@ -2234,7 +2180,7 @@ read_structure_scope (die, objfile) else { /* FIXME: TYPE_CODE_CLASS is currently defined to TYPE_CODE_STRUCT - in gdbtypes.h. */ + in gdbtypes.h. */ TYPE_CODE (type) = TYPE_CODE_CLASS; } @@ -2253,7 +2199,7 @@ read_structure_scope (die, objfile) type within the structure itself. */ die->type = type; - if (die->has_children) + if (die->has_children && ! die_is_declaration (die)) { struct field_info fi; struct die_info *child_die; @@ -2267,27 +2213,27 @@ read_structure_scope (die, objfile) { if (child_die->tag == DW_TAG_member) { - dwarf2_add_field (&fi, child_die, objfile); + dwarf2_add_field (&fi, child_die, objfile, cu_header); } else if (child_die->tag == DW_TAG_variable) { /* C++ static member. */ - dwarf2_add_field (&fi, child_die, objfile); + dwarf2_add_field (&fi, child_die, objfile, cu_header); } else if (child_die->tag == DW_TAG_subprogram) { /* C++ member function. */ - process_die (child_die, objfile); - dwarf2_add_member_fn (&fi, child_die, type, objfile); + process_die (child_die, objfile, cu_header); + dwarf2_add_member_fn (&fi, child_die, type, objfile, cu_header); } else if (child_die->tag == DW_TAG_inheritance) { /* C++ base class field. */ - dwarf2_add_field (&fi, child_die, objfile); + dwarf2_add_field (&fi, child_die, objfile, cu_header); } else { - process_die (child_die, objfile); + process_die (child_die, objfile, cu_header); } child_die = sibling_die (child_die); } @@ -2299,18 +2245,19 @@ read_structure_scope (die, objfile) { dwarf2_attach_fn_fields_to_type (&fi, type, objfile); - /* Get the type which refers to the base class (possibly this + /* 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) { - struct type *t = die_containing_type (die, objfile); + struct type *t = die_containing_type (die, objfile, cu_header); TYPE_VPTR_BASETYPE (type) = t; if (type == t) { - static const char vptr_name[] = { '_','v','p','t','r','\0' }; + static const char vptr_name[] = + {'_', 'v', 'p', 't', 'r', '\0'}; int i; /* Our own class provides vtbl ptr. */ @@ -2331,7 +2278,7 @@ read_structure_scope (die, objfile) /* Complain if virtual function table field not found. */ if (i < TYPE_N_BASECLASSES (t)) complain (&dwarf2_vtbl_not_found_complaint, - TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : ""); + TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) : ""); } else { @@ -2340,7 +2287,7 @@ read_structure_scope (die, objfile) } } - new_symbol (die, type, objfile); + new_symbol (die, type, objfile, cu_header); do_cleanups (back_to); } @@ -2363,9 +2310,8 @@ read_structure_scope (die, objfile) NOTE: We reverse the order of the element list. */ static void -read_enumeration (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_enumeration (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct die_info *child_die; struct type *type; @@ -2405,14 +2351,14 @@ read_enumeration (die, objfile) { if (child_die->tag != DW_TAG_enumerator) { - process_die (child_die, objfile); + process_die (child_die, objfile, cu_header); } else { attr = dwarf_attr (child_die, DW_AT_name); if (attr) { - sym = new_symbol (child_die, type, objfile); + sym = new_symbol (child_die, type, objfile, cu_header); if (SYMBOL_VALUE (sym) < 0) unsigned_enum = 0; @@ -2421,7 +2367,7 @@ read_enumeration (die, objfile) fields = (struct field *) xrealloc (fields, (num_fields + DW_FIELD_ALLOC_CHUNK) - * sizeof (struct field)); + * sizeof (struct field)); } FIELD_NAME (fields[num_fields]) = SYMBOL_NAME (sym); @@ -2443,13 +2389,13 @@ read_enumeration (die, objfile) TYPE_ALLOC (type, sizeof (struct field) * num_fields); memcpy (TYPE_FIELDS (type), fields, sizeof (struct field) * num_fields); - free (fields); + xfree (fields); } if (unsigned_enum) TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED; } die->type = type; - new_symbol (die, type, objfile); + new_symbol (die, type, objfile, cu_header); } /* Extract all information from a DW_TAG_array_type DIE and put it in @@ -2457,9 +2403,8 @@ read_enumeration (die, objfile) arrays. */ static void -read_array_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_array_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct die_info *child_die; struct type *type = NULL; @@ -2475,7 +2420,7 @@ read_array_type (die, objfile) return; } - element_type = die_type (die, objfile); + element_type = die_type (die, objfile, cu_header); /* Irix 6.2 native cc creates array types without children for arrays with unspecified length. */ @@ -2504,7 +2449,7 @@ read_array_type (die, objfile) low = 1; } - index_type = die_type (child_die, objfile); + index_type = die_type (child_die, objfile, cu_header); attr = dwarf_attr (child_die, DW_AT_lower_bound); if (attr) { @@ -2513,9 +2458,9 @@ read_array_type (die, objfile) 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_data1 + || attr->form == DW_FORM_data2 + || attr->form == DW_FORM_data4) { low = DW_UNSND (attr); } @@ -2539,9 +2484,9 @@ read_array_type (die, objfile) 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_data1 + || attr->form == DW_FORM_data2 + || attr->form == DW_FORM_data4) { high = DW_UNSND (attr); } @@ -2572,7 +2517,7 @@ read_array_type (die, objfile) { range_types = (struct type **) xrealloc (range_types, (ndim + DW_FIELD_ALLOC_CHUNK) - * sizeof (struct type *)); + * sizeof (struct type *)); if (ndim == 0) make_cleanup (free_current_contents, &range_types); } @@ -2596,9 +2541,8 @@ read_array_type (die, objfile) /* First cut: install each common block member as a global variable. */ static void -read_common_block (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_common_block (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct die_info *child_die; struct attribute *attr; @@ -2608,19 +2552,19 @@ read_common_block (die, objfile) attr = dwarf_attr (die, DW_AT_location); if (attr) { - base = decode_locdesc (DW_BLOCK (attr), objfile); + base = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); } if (die->has_children) { child_die = die->next; while (child_die && child_die->tag) { - sym = new_symbol (child_die, NULL, objfile); + sym = new_symbol (child_die, NULL, objfile, cu_header); attr = dwarf_attr (child_die, DW_AT_data_member_location); if (attr) { SYMBOL_VALUE_ADDRESS (sym) = - base + decode_locdesc (DW_BLOCK (attr), objfile); + base + decode_locdesc (DW_BLOCK (attr), objfile, cu_header); add_symbol_to_list (sym, &global_symbols); } child_die = sibling_die (child_die); @@ -2632,9 +2576,8 @@ read_common_block (die, objfile) the user defined type vector. */ static void -read_tag_pointer_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_tag_pointer_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct type *type; struct attribute *attr; @@ -2644,7 +2587,7 @@ read_tag_pointer_type (die, objfile) return; } - type = lookup_pointer_type (die_type (die, objfile)); + type = lookup_pointer_type (die_type (die, objfile, cu_header)); attr = dwarf_attr (die, DW_AT_byte_size); if (attr) { @@ -2652,7 +2595,7 @@ read_tag_pointer_type (die, objfile) } else { - TYPE_LENGTH (type) = address_size; + TYPE_LENGTH (type) = cu_header->addr_size; } die->type = type; } @@ -2661,9 +2604,8 @@ read_tag_pointer_type (die, objfile) the user defined type vector. */ static void -read_tag_ptr_to_member_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_tag_ptr_to_member_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct type *type; struct type *to_type; @@ -2675,8 +2617,8 @@ read_tag_ptr_to_member_type (die, objfile) } type = alloc_type (objfile); - to_type = die_type (die, objfile); - domain = die_containing_type (die, objfile); + to_type = die_type (die, objfile, cu_header); + domain = die_containing_type (die, objfile, cu_header); smash_to_member_type (type, domain, to_type); die->type = type; @@ -2686,9 +2628,8 @@ read_tag_ptr_to_member_type (die, objfile) the user defined type vector. */ static void -read_tag_reference_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_tag_reference_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct type *type; struct attribute *attr; @@ -2698,7 +2639,7 @@ read_tag_reference_type (die, objfile) return; } - type = lookup_reference_type (die_type (die, objfile)); + type = lookup_reference_type (die_type (die, objfile, cu_header)); attr = dwarf_attr (die, DW_AT_byte_size); if (attr) { @@ -2706,37 +2647,39 @@ read_tag_reference_type (die, objfile) } else { - TYPE_LENGTH (type) = address_size; + TYPE_LENGTH (type) = cu_header->addr_size; } die->type = type; } static void -read_tag_const_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_tag_const_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { + struct type *base_type; + if (die->type) { return; } - complain (&dwarf2_const_ignored); - die->type = die_type (die, objfile); + base_type = die_type (die, objfile, cu_header); + die->type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0); } static void -read_tag_volatile_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_tag_volatile_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { + struct type *base_type; + if (die->type) { return; } - complain (&dwarf2_volatile_ignored); - die->type = die_type (die, objfile); + base_type = die_type (die, objfile, cu_header); + die->type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0); } /* Extract all information from a DW_TAG_string_type DIE and add to @@ -2745,9 +2688,7 @@ read_tag_volatile_type (die, objfile) attribute to reference it. */ static void -read_tag_string_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_tag_string_type (struct die_info *die, struct objfile *objfile) { struct type *type, *range_type, *index_type, *char_type; struct attribute *attr; @@ -2777,18 +2718,17 @@ read_tag_string_type (die, objfile) /* Handle DIES due to C code like: struct foo - { - int (*funcp)(int a, long l); - int b; - }; + { + int (*funcp)(int a, long l); + int b; + }; ('funcp' generates a DW_TAG_subroutine_type DIE) -*/ + */ static void -read_subroutine_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_subroutine_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct type *type; /* Type that this function returns */ struct type *ftype; /* Function that returns above type */ @@ -2799,10 +2739,13 @@ read_subroutine_type (die, objfile) { return; } - type = die_type (die, objfile); + type = die_type (die, objfile, cu_header); ftype = lookup_function_type (type); + + /* All functions in C++ have prototypes. */ attr = dwarf_attr (die, DW_AT_prototyped); - if (attr && (DW_UNSND (attr) != 0)) + if ((attr && (DW_UNSND (attr) != 0)) + || cu_language == language_cplus) TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED; if (die->has_children) @@ -2835,16 +2778,17 @@ read_subroutine_type (die, objfile) if (child_die->tag == DW_TAG_formal_parameter) { /* Dwarf2 has no clean way to discern C++ static and non-static - member functions. G++ helps GDB by marking the first - 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. */ + member functions. G++ helps GDB by marking the first + 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); 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); + TYPE_FIELD_TYPE (ftype, iparams) = die_type (child_die, objfile, + cu_header); iparams++; } child_die = sibling_die (child_die); @@ -2855,9 +2799,8 @@ read_subroutine_type (die, objfile) } static void -read_typedef (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_typedef (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct type *type; @@ -2866,7 +2809,7 @@ read_typedef (die, objfile) struct attribute *attr; struct type *xtype; - xtype = die_type (die, objfile); + xtype = die_type (die, objfile, cu_header); type = alloc_type (objfile); TYPE_CODE (type) = TYPE_CODE_TYPEDEF; @@ -2886,9 +2829,7 @@ read_typedef (die, objfile) it in the TYPE field of the die. */ static void -read_base_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_base_type (struct die_info *die, struct objfile *objfile) { struct type *type; struct attribute *attr; @@ -2959,23 +2900,23 @@ read_base_type (die, objfile) /* Read a whole compilation unit into a linked list of dies. */ struct die_info * -read_comp_unit (info_ptr, abfd) - char *info_ptr; - bfd *abfd; +read_comp_unit (char *info_ptr, bfd *abfd, + const struct comp_unit_head *cu_header) { struct die_info *first_die, *last_die, *die; char *cur_ptr; int nesting_level; - /* Reset die reference table, we are building a new one now. */ - dwarf2_empty_die_ref_table (); + /* Reset die reference table; we are + building new ones now. */ + dwarf2_empty_hash_tables (); cur_ptr = info_ptr; nesting_level = 0; first_die = last_die = NULL; do { - cur_ptr = read_full_die (&die, abfd, cur_ptr); + cur_ptr = read_full_die (&die, abfd, cur_ptr, cu_header); if (die->has_children) { nesting_level++; @@ -3007,8 +2948,7 @@ read_comp_unit (info_ptr, abfd) /* Free a linked list of dies. */ static void -free_die_list (dies) - struct die_info *dies; +free_die_list (struct die_info *dies) { struct die_info *die, *next; @@ -3016,20 +2956,31 @@ free_die_list (dies) while (die) { next = die->next; - free (die->attrs); - free (die); + xfree (die->attrs); + xfree (die); die = next; } } +static void +do_free_die_list_cleanup (void *dies) +{ + free_die_list (dies); +} + +static struct cleanup * +make_cleanup_free_die_list (struct die_info *dies) +{ + return make_cleanup (do_free_die_list_cleanup, 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. */ static char * -dwarf2_read_section (objfile, offset, size) - struct objfile *objfile; - file_ptr offset; - unsigned int size; +dwarf2_read_section (struct objfile *objfile, file_ptr offset, + unsigned int size) { bfd *abfd = objfile->obfd; char *buf; @@ -3043,7 +2994,7 @@ dwarf2_read_section (objfile, offset, size) { buf = NULL; error ("Dwarf Error: Can't read DWARF data from '%s'", - bfd_get_filename (abfd)); + bfd_get_filename (abfd)); } return buf; } @@ -3054,9 +3005,7 @@ dwarf2_read_section (objfile, offset, size) in a hash table. */ static void -dwarf2_read_abbrevs (abfd, offset) - bfd * abfd; - unsigned int offset; +dwarf2_read_abbrevs (bfd *abfd, unsigned int offset) { char *abbrev_ptr; struct abbrev_info *cur_abbrev; @@ -3094,7 +3043,7 @@ dwarf2_read_abbrevs (abfd, offset) cur_abbrev->attrs = (struct attr_abbrev *) xrealloc (cur_abbrev->attrs, (cur_abbrev->num_attrs + ATTR_ALLOC_CHUNK) - * sizeof (struct attr_abbrev)); + * sizeof (struct attr_abbrev)); } cur_abbrev->attrs[cur_abbrev->num_attrs].name = abbrev_name; cur_abbrev->attrs[cur_abbrev->num_attrs++].form = abbrev_form; @@ -3110,13 +3059,13 @@ dwarf2_read_abbrevs (abfd, offset) /* Get next abbreviation. Under Irix6 the abbreviations for a compilation unit are not - always properly terminated with an abbrev number of 0. - Exit loop if we encounter an abbreviation which we have - already read (which means we are about to read the abbreviations - for the next compile unit) or if the end of the abbreviation - table is reached. */ + always properly terminated with an abbrev number of 0. + Exit loop if we encounter an abbreviation which we have + already read (which means we are about to read the abbreviations + for the next compile unit) or if the end of the abbreviation + table is reached. */ if ((unsigned int) (abbrev_ptr - dwarf_abbrev_buffer) - >= dwarf_abbrev_size) + >= dwarf_abbrev_size) break; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; @@ -3129,8 +3078,7 @@ dwarf2_read_abbrevs (abfd, offset) /* ARGSUSED */ static void -dwarf2_empty_abbrev_table (ignore) - PTR ignore; +dwarf2_empty_abbrev_table (PTR ignore) { int i; struct abbrev_info *abbrev, *next; @@ -3142,8 +3090,8 @@ dwarf2_empty_abbrev_table (ignore) while (abbrev) { next = abbrev->next; - free (abbrev->attrs); - free (abbrev); + xfree (abbrev->attrs); + xfree (abbrev); abbrev = next; } dwarf2_abbrevs[i] = NULL; @@ -3153,8 +3101,7 @@ dwarf2_empty_abbrev_table (ignore) /* Lookup an abbrev_info structure in the abbrev hash table. */ static struct abbrev_info * -dwarf2_lookup_abbrev (number) - unsigned int number; +dwarf2_lookup_abbrev (unsigned int number) { unsigned int hash_number; struct abbrev_info *abbrev; @@ -3175,18 +3122,16 @@ dwarf2_lookup_abbrev (number) /* Read a minimal amount of information into the minimal die structure. */ static char * -read_partial_die (part_die, abfd, info_ptr, has_pc_info) - struct partial_die_info *part_die; - bfd * abfd; - char *info_ptr; - int *has_pc_info; +read_partial_die (struct partial_die_info *part_die, bfd *abfd, + char *info_ptr, int *has_pc_info, + const struct comp_unit_head *cu_header) { unsigned int abbrev_number, bytes_read, i; struct abbrev_info *abbrev; struct attribute attr; struct attribute spec_attr; int found_spec_attr = 0; - int has_low_pc_attr = 0; + int has_low_pc_attr = 0; int has_high_pc_attr = 0; *part_die = zeroed_partial_die; @@ -3208,10 +3153,11 @@ read_partial_die (part_die, abfd, info_ptr, has_pc_info) for (i = 0; i < abbrev->num_attrs; ++i) { - info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, info_ptr); + info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, + info_ptr, cu_header); /* Store the data if it is of an attribute we want to keep in a - partial symbol table. */ + partial symbol table. */ switch (attr.name) { case DW_AT_name: @@ -3255,7 +3201,7 @@ read_partial_die (part_die, abfd, info_ptr, has_pc_info) /* Ignore absolute siblings, they might point outside of the current compile unit. */ if (attr.form == DW_FORM_ref_addr) - complain(&dwarf2_absolute_sibling_complaint); + complain (&dwarf2_absolute_sibling_complaint); else part_die->sibling = dwarf_info_buffer + dwarf2_get_ref_die_offset (&attr); @@ -3275,7 +3221,7 @@ read_partial_die (part_die, abfd, info_ptr, has_pc_info) int dummy; spec_ptr = dwarf_info_buffer + dwarf2_get_ref_die_offset (&spec_attr); - read_partial_die (&spec_die, abfd, spec_ptr, &dummy); + read_partial_die (&spec_die, abfd, spec_ptr, &dummy, cu_header); if (spec_die.name) { part_die->name = spec_die.name; @@ -3306,10 +3252,8 @@ read_partial_die (part_die, abfd, info_ptr, has_pc_info) point to a newly allocated die with its information. */ static char * -read_full_die (diep, abfd, info_ptr) - struct die_info **diep; - bfd *abfd; - char *info_ptr; +read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr, + const struct comp_unit_head *cu_header) { unsigned int abbrev_number, bytes_read, i, offset; struct abbrev_info *abbrev; @@ -3347,7 +3291,7 @@ read_full_die (diep, abfd, info_ptr) for (i = 0; i < abbrev->num_attrs; ++i) { info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i], - abfd, info_ptr); + abfd, info_ptr, cu_header); } *diep = die; @@ -3357,11 +3301,9 @@ read_full_die (diep, abfd, info_ptr) /* Read an attribute described by an abbreviated attribute. */ static char * -read_attribute (attr, abbrev, abfd, info_ptr) - struct attribute *attr; - struct attr_abbrev *abbrev; - bfd *abfd; - char *info_ptr; +read_attribute (struct attribute *attr, struct attr_abbrev *abbrev, + bfd *abfd, char *info_ptr, + const struct comp_unit_head *cu_header) { unsigned int bytes_read; struct dwarf_block *blk; @@ -3372,8 +3314,8 @@ read_attribute (attr, abbrev, abfd, info_ptr) { case DW_FORM_addr: case DW_FORM_ref_addr: - DW_ADDR (attr) = read_address (abfd, info_ptr); - info_ptr += address_size; + DW_ADDR (attr) = read_address (abfd, info_ptr, cu_header, &bytes_read); + info_ptr += bytes_read; break; case DW_FORM_block2: blk = dwarf_alloc_block (); @@ -3451,6 +3393,10 @@ read_attribute (attr, abbrev, abfd, info_ptr) DW_UNSND (attr) = read_4_bytes (abfd, info_ptr); info_ptr += 4; break; + case DW_FORM_ref8: + DW_UNSND (attr) = read_8_bytes (abfd, info_ptr); + info_ptr += 8; + break; case DW_FORM_ref_udata: DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; @@ -3467,98 +3413,180 @@ read_attribute (attr, abbrev, abfd, info_ptr) /* read dwarf information from a buffer */ static unsigned int -read_1_byte (abfd, buf) - bfd *abfd; - char *buf; +read_1_byte (bfd *abfd, char *buf) { return bfd_get_8 (abfd, (bfd_byte *) buf); } static int -read_1_signed_byte (abfd, buf) - bfd *abfd; - char *buf; +read_1_signed_byte (bfd *abfd, char *buf) { return bfd_get_signed_8 (abfd, (bfd_byte *) buf); } static unsigned int -read_2_bytes (abfd, buf) - bfd *abfd; - char *buf; +read_2_bytes (bfd *abfd, char *buf) { return bfd_get_16 (abfd, (bfd_byte *) buf); } static int -read_2_signed_bytes (abfd, buf) - bfd *abfd; - char *buf; +read_2_signed_bytes (bfd *abfd, char *buf) { return bfd_get_signed_16 (abfd, (bfd_byte *) buf); } static unsigned int -read_4_bytes (abfd, buf) - bfd *abfd; - char *buf; +read_4_bytes (bfd *abfd, char *buf) { return bfd_get_32 (abfd, (bfd_byte *) buf); } static int -read_4_signed_bytes (abfd, buf) - bfd *abfd; - char *buf; +read_4_signed_bytes (bfd *abfd, char *buf) { return bfd_get_signed_32 (abfd, (bfd_byte *) buf); } -static unsigned int -read_8_bytes (abfd, buf) - bfd *abfd; - char *buf; +static unsigned long +read_8_bytes (bfd *abfd, char *buf) { return bfd_get_64 (abfd, (bfd_byte *) buf); } static CORE_ADDR -read_address (abfd, buf) - bfd *abfd; - char *buf; +read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, + int *bytes_read) { CORE_ADDR retval = 0; - switch (address_size) + if (cu_header->signed_addr_p) + { + switch (cu_header->addr_size) + { + case 2: + retval = bfd_get_signed_16 (abfd, (bfd_byte *) buf); + break; + case 4: + retval = bfd_get_signed_32 (abfd, (bfd_byte *) buf); + break; + case 8: + retval = bfd_get_signed_64 (abfd, (bfd_byte *) buf); + break; + default: + internal_error (__FILE__, __LINE__, + "read_address: bad switch, signed"); + } + } + else + { + switch (cu_header->addr_size) + { + case 2: + retval = bfd_get_16 (abfd, (bfd_byte *) buf); + break; + case 4: + retval = bfd_get_32 (abfd, (bfd_byte *) buf); + break; + case 8: + retval = bfd_get_64 (abfd, (bfd_byte *) buf); + break; + default: + internal_error (__FILE__, __LINE__, + "read_address: bad switch, unsigned"); + } + } + + *bytes_read = cu_header->addr_size; + return retval; +} + +/* Reads the initial length from a section. The (draft) DWARF 2.1 + specification allows the initial length to take up either 4 bytes + or 12 bytes. If the first 4 bytes are 0xffffffff, then the next 8 + bytes describe the length and all offsets will be 8 bytes in length + instead of 4. + + The value returned via bytes_read should be used to increment + the relevant pointer after calling read_initial_length(). + + As a side effect, this function sets the fields initial_length_size + and offset_size in cu_header to the values appropriate for the + length field. (The format of the initial length field determines + the width of file offsets to be fetched later with fetch_offset().) + + [ Note: read_initial_length() and read_offset() are based on the + document entitled "DWARF Debugging Information Format", revision + 2.1, draft 4, dated July 20, 2000. This document was obtained + from: + + http://reality.sgi.com/dehnert_engr/dwarf/dwarf2p1-draft4-000720.pdf + + This document is only a draft and is subject to change. (So beware.) + + - Kevin, Aug 4, 2000 + ] */ + +static LONGEST +read_initial_length (bfd *abfd, char *buf, struct comp_unit_head *cu_header, + int *bytes_read) +{ + LONGEST retval = 0; + + retval = bfd_get_32 (abfd, (bfd_byte *) buf); + + if (retval == 0xffffffff) + { + retval = bfd_get_64 (abfd, (bfd_byte *) buf + 4); + *bytes_read = 12; + if (cu_header != NULL) + { + cu_header->initial_length_size = 12; + cu_header->offset_size = 8; + } + } + else + { + *bytes_read = 4; + if (cu_header != NULL) + { + cu_header->initial_length_size = 4; + cu_header->offset_size = 4; + } + } + + return retval; +} + +/* Read an offset from the data stream. The size of the offset is + given by cu_header->offset_size. */ + +static LONGEST +read_offset (bfd *abfd, char *buf, const struct comp_unit_head *cu_header, + int *bytes_read) +{ + LONGEST retval = 0; + + switch (cu_header->offset_size) { case 4: retval = bfd_get_32 (abfd, (bfd_byte *) buf); + *bytes_read = 4; break; case 8: retval = bfd_get_64 (abfd, (bfd_byte *) buf); + *bytes_read = 8; break; default: - /* *THE* alternative is 8, right? */ - abort (); - } - /* If the address being read is larger than the address that is - applicable for the object file format then mask it down to the - correct size. Take care to avoid unnecessary shift or shift - overflow */ - if (address_size > address_significant_size - && address_significant_size < sizeof (CORE_ADDR)) - { - CORE_ADDR mask = ((CORE_ADDR) 0) - 1; - retval &= ~(mask << (address_significant_size * 8)); + internal_error (__FILE__, __LINE__, + "read_offset: bad switch"); } - return retval; + + return retval; } static char * -read_n_bytes (abfd, buf, size) - bfd * abfd; - char *buf; - unsigned int size; +read_n_bytes (bfd *abfd, char *buf, unsigned int size) { /* If the size of a host char is 8 bits, we can return a pointer to the buffer, otherwise we have to copy the data to a buffer @@ -3580,10 +3608,7 @@ read_n_bytes (abfd, buf, size) } static char * -read_string (abfd, buf, bytes_read_ptr) - bfd *abfd; - char *buf; - unsigned int *bytes_read_ptr; +read_string (bfd *abfd, char *buf, unsigned int *bytes_read_ptr) { /* If the size of a host char is 8 bits, we can return a pointer to the string, otherwise we have to copy the string to a buffer @@ -3617,13 +3642,11 @@ read_string (abfd, buf, bytes_read_ptr) #endif } -static unsigned int -read_unsigned_leb128 (abfd, buf, bytes_read_ptr) - bfd *abfd; - char *buf; - unsigned int *bytes_read_ptr; +static unsigned long +read_unsigned_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr) { - unsigned int result, num_read; + unsigned long result; + unsigned int num_read; int i, shift; unsigned char byte; @@ -3636,7 +3659,7 @@ read_unsigned_leb128 (abfd, buf, bytes_read_ptr) byte = bfd_get_8 (abfd, (bfd_byte *) buf); buf++; num_read++; - result |= ((byte & 127) << shift); + result |= ((unsigned long)(byte & 127) << shift); if ((byte & 128) == 0) { break; @@ -3647,13 +3670,10 @@ read_unsigned_leb128 (abfd, buf, bytes_read_ptr) return result; } -static int -read_signed_leb128 (abfd, buf, bytes_read_ptr) - bfd *abfd; - char *buf; - unsigned int *bytes_read_ptr; +static long +read_signed_leb128 (bfd *abfd, char *buf, unsigned int *bytes_read_ptr) { - int result; + long result; int i, shift, size, num_read; unsigned char byte; @@ -3667,7 +3687,7 @@ read_signed_leb128 (abfd, buf, bytes_read_ptr) byte = bfd_get_8 (abfd, (bfd_byte *) buf); buf++; num_read++; - result |= ((byte & 127) << shift); + result |= ((long)(byte & 127) << shift); shift += 7; if ((byte & 128) == 0) { @@ -3683,8 +3703,7 @@ read_signed_leb128 (abfd, buf, bytes_read_ptr) } static void -set_cu_language (lang) - unsigned int lang; +set_cu_language (unsigned int lang) { switch (lang) { @@ -3702,6 +3721,9 @@ set_cu_language (lang) case DW_LANG_Mips_Assembler: cu_language = language_asm; break; + case DW_LANG_Java: + cu_language = language_java; + break; case DW_LANG_Ada83: case DW_LANG_Cobol74: case DW_LANG_Cobol85: @@ -3717,9 +3739,7 @@ set_cu_language (lang) /* Return the named attribute or NULL if not there. */ static struct attribute * -dwarf_attr (die, name) - struct die_info *die; - unsigned int name; +dwarf_attr (struct die_info *die, unsigned int name) { unsigned int i; struct attribute *spec = NULL; @@ -3737,15 +3757,22 @@ dwarf_attr (die, 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)); if (ref_die) return dwarf_attr (ref_die, name); } - + return NULL; } +static int +die_is_declaration (struct die_info *die) +{ + return (dwarf_attr (die, DW_AT_declaration) + && ! dwarf_attr (die, DW_AT_specification)); +} + /* Decode the line number information for the compilation unit whose line number info is at OFFSET in the .debug_line section. The compilation directory of the file is passed in COMP_DIR. */ @@ -3754,26 +3781,24 @@ struct filenames { unsigned int num_files; struct fileinfo - { - char *name; - unsigned int dir; - unsigned int time; - unsigned int size; - } - *files; + { + char *name; + unsigned int dir; + unsigned int time; + unsigned int size; + } + *files; }; struct directories -{ - unsigned int num_dirs; - char **dirs; -}; + { + unsigned int num_dirs; + char **dirs; + }; static void -dwarf_decode_lines (offset, comp_dir, abfd) - unsigned int offset; - char *comp_dir; - bfd *abfd; +dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd, + const struct comp_unit_head *cu_header) { char *line_ptr; char *line_end; @@ -3804,13 +3829,13 @@ dwarf_decode_lines (offset, comp_dir, abfd) line_ptr = dwarf_line_buffer + offset; /* read in the prologue */ - lh.total_length = read_4_bytes (abfd, line_ptr); - line_ptr += 4; + lh.total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read); + line_ptr += bytes_read; line_end = line_ptr + lh.total_length; lh.version = read_2_bytes (abfd, line_ptr); line_ptr += 2; - lh.prologue_length = read_4_bytes (abfd, line_ptr); - line_ptr += 4; + lh.prologue_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; lh.default_is_stmt = read_1_byte (abfd, line_ptr); @@ -3857,7 +3882,7 @@ dwarf_decode_lines (offset, comp_dir, abfd) files.files = (struct fileinfo *) xrealloc (files.files, (files.num_files + FILE_ALLOC_CHUNK) - * sizeof (struct fileinfo)); + * sizeof (struct fileinfo)); if (files.num_files == 0) make_cleanup (free_current_contents, &files.files); } @@ -3899,7 +3924,7 @@ dwarf_decode_lines (offset, comp_dir, abfd) } /* Decode the table. */ - while (! end_sequence) + while (!end_sequence) { op_code = read_1_byte (abfd, line_ptr); line_ptr += 1; @@ -3913,11 +3938,17 @@ dwarf_decode_lines (offset, comp_dir, abfd) { case DW_LNE_end_sequence: end_sequence = 1; - record_line (current_subfile, line, address); + /* Don't call record_line here. The end_sequence + instruction provides the address of the first byte + *after* the last line in the sequence; it's not the + address of any real source line. However, the GDB + linetable structure only records the starts of lines, + not the ends. This is a weakness of GDB. */ break; case DW_LNE_set_address: - address = read_address (abfd, line_ptr) + baseaddr; - line_ptr += address_size; + address = read_address (abfd, line_ptr, cu_header, &bytes_read); + line_ptr += bytes_read; + address += baseaddr; break; case DW_LNE_define_file: cur_file = read_string (abfd, line_ptr, &bytes_read); @@ -3927,7 +3958,7 @@ dwarf_decode_lines (offset, comp_dir, abfd) files.files = (struct fileinfo *) xrealloc (files.files, (files.num_files + FILE_ALLOC_CHUNK) - * sizeof (struct fileinfo)); + * sizeof (struct fileinfo)); if (files.num_files == 0) make_cleanup (free_current_contents, &files.files); } @@ -3963,7 +3994,7 @@ dwarf_decode_lines (offset, comp_dir, abfd) break; case DW_LNS_set_file: /* The file and directory tables are 0 based, the references - are 1 based. */ + are 1 based. */ file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); line_ptr += bytes_read; dwarf2_start_subfile @@ -3982,8 +4013,14 @@ dwarf_decode_lines (offset, comp_dir, abfd) case DW_LNS_set_basic_block: basic_block = 1; break; + /* Add to the address register of the state machine the + address increment value corresponding to special opcode + 255. Ie, this value is scaled by the minimum instruction + length since special opcode 255 would have scaled the + the increment. */ case DW_LNS_const_add_pc: - address += (255 - lh.opcode_base) / lh.line_range; + address += (lh.minimum_instruction_length + * ((255 - lh.opcode_base) / lh.line_range)); break; case DW_LNS_fixed_advance_pc: address += read_2_bytes (abfd, line_ptr); @@ -4014,39 +4051,37 @@ done: /srcdir and compiling it with Irix6.2 cc in /compdir using a filename of /srcdir/list0.c yields the following debugging information for list0.c: - DW_AT_name: /srcdir/list0.c - DW_AT_comp_dir: /compdir - files.files[0].name: list0.h - files.files[0].dir: /srcdir - files.files[1].name: list0.c - files.files[1].dir: /srcdir + DW_AT_name: /srcdir/list0.c + DW_AT_comp_dir: /compdir + files.files[0].name: list0.h + files.files[0].dir: /srcdir + files.files[1].name: list0.c + files.files[1].dir: /srcdir The line number information for list0.c has to end up in a single subfile, so that `break /srcdir/list0.c:1' works as expected. */ static void -dwarf2_start_subfile (filename, dirname) - char *filename; - char *dirname; +dwarf2_start_subfile (char *filename, char *dirname) { /* If the filename isn't absolute, try to match an existing subfile with the full pathname. */ - if (*filename != '/' && dirname != NULL) + if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL) { struct subfile *subfile; char *fullname = concat (dirname, "/", filename, NULL); for (subfile = subfiles; subfile; subfile = subfile->next) { - if (STREQ (subfile->name, fullname)) + if (FILENAME_CMP (subfile->name, fullname) == 0) { current_subfile = subfile; - free (fullname); + xfree (fullname); return; } } - free (fullname); + xfree (fullname); } start_subfile (filename, dirname); } @@ -4055,14 +4090,11 @@ dwarf2_start_subfile (filename, dirname) to make a symbol table entry for it, and if so, create a new entry and return a pointer to it. If TYPE is NULL, determine symbol type from the die, otherwise - used the passed type. - */ + used the passed type. */ static struct symbol * -new_symbol (die, type, objfile) - struct die_info *die; - struct type *type; - struct objfile *objfile; +new_symbol (struct die_info *die, struct type *type, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct symbol *sym = NULL; char *name; @@ -4081,13 +4113,13 @@ new_symbol (die, type, objfile) &objfile->symbol_obstack); /* Default assumptions. - Use the passed type or decode it from the die. */ + Use the passed type or decode it from the die. */ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; SYMBOL_CLASS (sym) = LOC_STATIC; if (type != NULL) SYMBOL_TYPE (sym) = type; else - SYMBOL_TYPE (sym) = die_type (die, objfile); + SYMBOL_TYPE (sym) = die_type (die, objfile, cu_header); attr = dwarf_attr (die, DW_AT_decl_line); if (attr) { @@ -4138,7 +4170,7 @@ new_symbol (die, type, objfile) attr = dwarf_attr (die, DW_AT_const_value); if (attr) { - dwarf2_const_value (attr, sym, objfile); + dwarf2_const_value (attr, sym, objfile, cu_header); attr2 = dwarf_attr (die, DW_AT_external); if (attr2 && (DW_UNSND (attr2) != 0)) add_symbol_to_list (sym, &global_symbols); @@ -4153,10 +4185,10 @@ new_symbol (die, type, objfile) if (attr2 && (DW_UNSND (attr2) != 0)) { SYMBOL_VALUE_ADDRESS (sym) = - decode_locdesc (DW_BLOCK (attr), objfile); + decode_locdesc (DW_BLOCK (attr), objfile, cu_header); add_symbol_to_list (sym, &global_symbols); - /* In shared libraries the address of the variable + /* In shared libraries the address of the variable in the location descriptor might still be relocatable, so its value could be zero. Enter the symbol as a LOC_UNRESOLVED symbol, if its @@ -4165,7 +4197,10 @@ new_symbol (die, type, objfile) the variable is referenced. */ if (SYMBOL_VALUE_ADDRESS (sym)) { - SYMBOL_VALUE_ADDRESS (sym) += baseaddr; + fixup_symbol_section (sym, objfile); + SYMBOL_VALUE_ADDRESS (sym) += + ANOFFSET (objfile->section_offsets, + SYMBOL_SECTION (sym)); SYMBOL_CLASS (sym) = LOC_STATIC; } else @@ -4174,7 +4209,7 @@ new_symbol (die, type, objfile) else { SYMBOL_VALUE (sym) = addr = - decode_locdesc (DW_BLOCK (attr), objfile); + decode_locdesc (DW_BLOCK (attr), objfile, cu_header); add_symbol_to_list (sym, list_in_scope); if (optimized_out) { @@ -4183,11 +4218,13 @@ new_symbol (die, type, objfile) else if (isreg) { SYMBOL_CLASS (sym) = LOC_REGISTER; + SYMBOL_VALUE (sym) = + DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym)); } else if (offreg) { SYMBOL_CLASS (sym) = LOC_BASEREG; - SYMBOL_BASEREG (sym) = basereg; + SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); } else if (islocal) { @@ -4195,19 +4232,22 @@ new_symbol (die, type, objfile) } else { + fixup_symbol_section (sym, objfile); + SYMBOL_VALUE_ADDRESS (sym) = + addr + ANOFFSET (objfile->section_offsets, + SYMBOL_SECTION (sym)); SYMBOL_CLASS (sym) = LOC_STATIC; - SYMBOL_VALUE_ADDRESS (sym) = addr + baseaddr; } } } else { /* We do not know the address of this symbol. - If it is an external symbol and we have type information - for it, enter the symbol as a LOC_UNRESOLVED symbol. - The address of the variable will then be determined from - the minimal symbol table whenever the variable is - referenced. */ + If it is an external symbol and we have type information + for it, enter the symbol as a LOC_UNRESOLVED symbol. + 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); if (attr2 && (DW_UNSND (attr2) != 0) && dwarf_attr (die, DW_AT_type) != NULL) @@ -4221,15 +4261,27 @@ new_symbol (die, type, objfile) attr = dwarf_attr (die, DW_AT_location); if (attr) { - SYMBOL_VALUE (sym) = decode_locdesc (DW_BLOCK (attr), objfile); + SYMBOL_VALUE (sym) = + decode_locdesc (DW_BLOCK (attr), objfile, cu_header); if (isreg) { SYMBOL_CLASS (sym) = LOC_REGPARM; + SYMBOL_VALUE (sym) = + DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym)); } else if (offreg) { - SYMBOL_CLASS (sym) = LOC_BASEREG_ARG; - SYMBOL_BASEREG (sym) = basereg; + if (isderef) + { + if (basereg != frame_base_reg) + complain (&dwarf2_complex_location_expr); + SYMBOL_CLASS (sym) = LOC_REF_ARG; + } + else + { + SYMBOL_CLASS (sym) = LOC_BASEREG_ARG; + SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); + } } else { @@ -4239,7 +4291,7 @@ new_symbol (die, type, objfile) attr = dwarf_attr (die, DW_AT_const_value); if (attr) { - dwarf2_const_value (attr, sym, objfile); + dwarf2_const_value (attr, sym, objfile, cu_header); } add_symbol_to_list (sym, list_in_scope); break; @@ -4262,8 +4314,8 @@ new_symbol (die, type, objfile) if (cu_language == language_cplus) { struct symbol *typedef_sym = (struct symbol *) - obstack_alloc (&objfile->symbol_obstack, - sizeof (struct symbol)); + obstack_alloc (&objfile->symbol_obstack, + sizeof (struct symbol)); *typedef_sym = *sym; SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE; if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0) @@ -4284,7 +4336,7 @@ new_symbol (die, type, objfile) attr = dwarf_attr (die, DW_AT_const_value); if (attr) { - dwarf2_const_value (attr, sym, objfile); + dwarf2_const_value (attr, sym, objfile, cu_header); } add_symbol_to_list (sym, list_in_scope); break; @@ -4303,22 +4355,22 @@ new_symbol (die, type, objfile) /* Copy constant value from an attribute to a symbol. */ static void -dwarf2_const_value (attr, sym, objfile) - struct attribute *attr; - struct symbol *sym; - struct objfile *objfile; +dwarf2_const_value (struct attribute *attr, struct symbol *sym, + struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct dwarf_block *blk; switch (attr->form) { case DW_FORM_addr: - if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != (unsigned int) address_size) + if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != cu_header->addr_size) complain (&dwarf2_const_value_length_mismatch, SYMBOL_NAME (sym), - address_size, TYPE_LENGTH (SYMBOL_TYPE (sym))); + cu_header->addr_size, TYPE_LENGTH (SYMBOL_TYPE (sym))); SYMBOL_VALUE_BYTES (sym) = (char *) - obstack_alloc (&objfile->symbol_obstack, address_size); - store_address (SYMBOL_VALUE_BYTES (sym), address_size, DW_ADDR (attr)); + obstack_alloc (&objfile->symbol_obstack, cu_header->addr_size); + store_address (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size, + DW_ADDR (attr)); SYMBOL_CLASS (sym) = LOC_CONST_BYTES; break; case DW_FORM_block1: @@ -4334,15 +4386,35 @@ dwarf2_const_value (attr, sym, objfile) memcpy (SYMBOL_VALUE_BYTES (sym), blk->data, blk->size); SYMBOL_CLASS (sym) = LOC_CONST_BYTES; break; + + /* The DW_AT_const_value attributes are supposed to carry the + symbol's value "represented as it would be on the target + architecture." By the time we get here, it's already been + converted to host endianness, so we just need to sign- or + zero-extend it as appropriate. */ + case DW_FORM_data1: + dwarf2_const_value_data (attr, sym, 8); + break; case DW_FORM_data2: + dwarf2_const_value_data (attr, sym, 16); + break; case DW_FORM_data4: + dwarf2_const_value_data (attr, sym, 32); + break; case DW_FORM_data8: - case DW_FORM_data1: + dwarf2_const_value_data (attr, sym, 64); + break; + case DW_FORM_sdata: + SYMBOL_VALUE (sym) = DW_SND (attr); + SYMBOL_CLASS (sym) = LOC_CONST; + break; + case DW_FORM_udata: SYMBOL_VALUE (sym) = DW_UNSND (attr); SYMBOL_CLASS (sym) = LOC_CONST; break; + default: complain (&dwarf2_unsupported_const_value_attr, dwarf_form_name (attr->form)); @@ -4352,12 +4424,34 @@ dwarf2_const_value (attr, sym, objfile) } } + +/* Given an attr with a DW_FORM_dataN value in host byte order, sign- + or zero-extend it as appropriate for the symbol's type. */ +static void +dwarf2_const_value_data (struct attribute *attr, + struct symbol *sym, + int bits) +{ + LONGEST l = DW_UNSND (attr); + + if (bits < sizeof (l) * 8) + { + if (TYPE_UNSIGNED (SYMBOL_TYPE (sym))) + l &= ((LONGEST) 1 << bits) - 1; + else + l = (l << (sizeof (l) * 8 - bits)) >> (sizeof (l) * 8 - bits); + } + + SYMBOL_VALUE (sym) = l; + SYMBOL_CLASS (sym) = LOC_CONST; +} + + /* Return the type of the die in question using its DW_AT_type attribute. */ static struct type * -die_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +die_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct type *type; struct attribute *type_attr; @@ -4380,7 +4474,7 @@ die_type (die, objfile) return NULL; } } - type = tag_type_to_type (type_die, objfile); + type = tag_type_to_type (type_die, objfile, cu_header); if (!type) { dump_die (type_die); @@ -4393,9 +4487,8 @@ die_type (die, objfile) DW_AT_containing_type attribute. */ static struct type * -die_containing_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +die_containing_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { struct type *type = NULL; struct attribute *type_attr; @@ -4412,7 +4505,7 @@ die_containing_type (die, objfile) error ("Dwarf Error: Cannot find referent at offset %d.", ref); return NULL; } - type = tag_type_to_type (type_die, objfile); + type = tag_type_to_type (type_die, objfile, cu_header); } if (!type) { @@ -4425,9 +4518,7 @@ die_containing_type (die, objfile) #if 0 static struct type * -type_at_offset (offset, objfile) - unsigned int offset; - struct objfile *objfile; +type_at_offset (unsigned int offset, struct objfile *objfile) { struct die_info *die; struct type *type; @@ -4444,9 +4535,8 @@ type_at_offset (offset, objfile) #endif static struct type * -tag_type_to_type (die, objfile) - struct die_info *die; - struct objfile *objfile; +tag_type_to_type (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { if (die->type) { @@ -4454,7 +4544,7 @@ tag_type_to_type (die, objfile) } else { - read_type_die (die, objfile); + read_type_die (die, objfile, cu_header); if (!die->type) { dump_die (die); @@ -4465,47 +4555,46 @@ tag_type_to_type (die, objfile) } static void -read_type_die (die, objfile) - struct die_info *die; - struct objfile *objfile; +read_type_die (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { switch (die->tag) { case DW_TAG_class_type: case DW_TAG_structure_type: case DW_TAG_union_type: - read_structure_scope (die, objfile); + read_structure_scope (die, objfile, cu_header); break; case DW_TAG_enumeration_type: - read_enumeration (die, objfile); + read_enumeration (die, objfile, cu_header); break; case DW_TAG_subprogram: case DW_TAG_subroutine_type: - read_subroutine_type (die, objfile); + read_subroutine_type (die, objfile, cu_header); break; case DW_TAG_array_type: - read_array_type (die, objfile); + read_array_type (die, objfile, cu_header); break; case DW_TAG_pointer_type: - read_tag_pointer_type (die, objfile); + read_tag_pointer_type (die, objfile, cu_header); break; case DW_TAG_ptr_to_member_type: - read_tag_ptr_to_member_type (die, objfile); + read_tag_ptr_to_member_type (die, objfile, cu_header); break; case DW_TAG_reference_type: - read_tag_reference_type (die, objfile); + read_tag_reference_type (die, objfile, cu_header); break; case DW_TAG_const_type: - read_tag_const_type (die, objfile); + read_tag_const_type (die, objfile, cu_header); break; case DW_TAG_volatile_type: - read_tag_volatile_type (die, objfile); + read_tag_volatile_type (die, objfile, cu_header); break; case DW_TAG_string_type: read_tag_string_type (die, objfile); break; case DW_TAG_typedef: - read_typedef (die, objfile); + read_typedef (die, objfile, cu_header); break; case DW_TAG_base_type: read_base_type (die, objfile); @@ -4517,10 +4606,7 @@ read_type_die (die, objfile) } static struct type * -dwarf_base_type (encoding, size, objfile) - int encoding; - int size; - struct objfile *objfile; +dwarf_base_type (int encoding, int size, struct objfile *objfile) { /* FIXME - this should not produce a new (struct type *) every time. It should cache base types. */ @@ -4597,8 +4683,7 @@ dwarf_base_type (encoding, size, objfile) #if 0 struct die_info * -copy_die (old_die) - struct die_info *old_die; +copy_die (struct die_info *old_die) { struct die_info *new_die; int i, num_attrs; @@ -4632,8 +4717,7 @@ copy_die (old_die) /* Return sibling of die, NULL if no sibling. */ struct die_info * -sibling_die (die) - struct die_info *die; +sibling_die (struct die_info *die) { int nesting_level = 0; @@ -4677,8 +4761,7 @@ sibling_die (die) /* Get linkage name of a die, return NULL if not found. */ static char * -dwarf2_linkage_name (die) - struct die_info *die; +dwarf2_linkage_name (struct die_info *die) { struct attribute *attr; @@ -4694,8 +4777,7 @@ dwarf2_linkage_name (die) /* Convert a DIE tag into its string name. */ static char * -dwarf_tag_name (tag) - register unsigned tag; +dwarf_tag_name (register unsigned tag) { switch (tag) { @@ -4811,8 +4893,7 @@ dwarf_tag_name (tag) /* Convert a DWARF attribute code into its string name. */ static char * -dwarf_attr_name (attr) - register unsigned attr; +dwarf_attr_name (register unsigned attr) { switch (attr) { @@ -4978,8 +5059,7 @@ dwarf_attr_name (attr) /* Convert a DWARF value form code into its string name. */ static char * -dwarf_form_name (form) - register unsigned form; +dwarf_form_name (register unsigned form) { switch (form) { @@ -5033,8 +5113,7 @@ dwarf_form_name (form) /* Convert a DWARF stack opcode into its string name. */ static char * -dwarf_stack_op_name (op) - register unsigned op; +dwarf_stack_op_name (register unsigned op) { switch (op) { @@ -5334,10 +5413,9 @@ dwarf_stack_op_name (op) } static char * -dwarf_bool_name (bool) - unsigned bool; +dwarf_bool_name (unsigned mybool) { - if (bool) + if (mybool) return "TRUE"; else return "FALSE"; @@ -5346,8 +5424,7 @@ dwarf_bool_name (bool) /* Convert a DWARF type code into its string name. */ static char * -dwarf_type_encoding_name (enc) - register unsigned enc; +dwarf_type_encoding_name (register unsigned enc) { switch (enc) { @@ -5376,8 +5453,7 @@ dwarf_type_encoding_name (enc) #if 0 static char * -dwarf_cfi_name (cfi_opc) - register unsigned cfi_opc; +dwarf_cfi_name (register unsigned cfi_opc) { switch (cfi_opc) { @@ -5427,8 +5503,7 @@ dwarf_cfi_name (cfi_opc) #endif void -dump_die (die) - struct die_info *die; +dump_die (struct die_info *die) { unsigned int i; @@ -5448,7 +5523,7 @@ dump_die (die) case DW_FORM_ref_addr: case DW_FORM_addr: fprintf (stderr, "address: "); - print_address_numeric (DW_ADDR (&die->attrs[i]), 1, stderr); + print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr); break; case DW_FORM_block2: case DW_FORM_block4: @@ -5459,17 +5534,18 @@ dump_die (die) case DW_FORM_data1: case DW_FORM_data2: case DW_FORM_data4: + case DW_FORM_data8: case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_udata: case DW_FORM_sdata: - fprintf (stderr, "constant: %d", DW_UNSND (&die->attrs[i])); + fprintf (stderr, "constant: %ld", DW_UNSND (&die->attrs[i])); break; case DW_FORM_string: fprintf (stderr, "string: \"%s\"", DW_STRING (&die->attrs[i]) - ? DW_STRING (&die->attrs[i]) : ""); + ? DW_STRING (&die->attrs[i]) : ""); break; case DW_FORM_flag: if (DW_UNSND (&die->attrs[i])) @@ -5480,18 +5556,16 @@ dump_die (die) case DW_FORM_strp: /* we do not support separate string section yet */ case DW_FORM_indirect: /* we do not handle indirect yet */ - case DW_FORM_data8: /* we do not have 64 bit quantities */ default: fprintf (stderr, "unsupported attribute form: %d.", - die->attrs[i].form); + die->attrs[i].form); } fprintf (stderr, "\n"); } } void -dump_die_list (die) - struct die_info *die; +dump_die_list (struct die_info *die) { while (die) { @@ -5501,9 +5575,7 @@ dump_die_list (die) } void -store_in_ref_table (offset, die) - unsigned int offset; - struct die_info *die; +store_in_ref_table (unsigned int offset, struct die_info *die) { int h; struct die_info *old; @@ -5516,14 +5588,13 @@ store_in_ref_table (offset, die) static void -dwarf2_empty_die_ref_table () +dwarf2_empty_hash_tables (void) { memset (die_ref_table, 0, sizeof (die_ref_table)); } static unsigned int -dwarf2_get_ref_die_offset (attr) - struct attribute *attr; +dwarf2_get_ref_die_offset (struct attribute *attr) { unsigned int result = 0; @@ -5535,6 +5606,7 @@ dwarf2_get_ref_die_offset (attr) case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: + case DW_FORM_ref8: case DW_FORM_ref_udata: result = cu_header_offset + DW_UNSND (attr); break; @@ -5545,8 +5617,7 @@ dwarf2_get_ref_die_offset (attr) } struct die_info * -follow_die_ref (offset) - unsigned int offset; +follow_die_ref (unsigned int offset) { struct die_info *die; int h; @@ -5565,9 +5636,7 @@ follow_die_ref (offset) } static struct type * -dwarf2_fundamental_type (objfile, typeid) - struct objfile *objfile; - int typeid; +dwarf2_fundamental_type (struct objfile *objfile, int typeid) { if (typeid < 0 || typeid >= FT_NUM_MEMBERS) { @@ -5611,14 +5680,13 @@ dwarf2_fundamental_type (objfile, typeid) 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 (blk, objfile) - struct dwarf_block *blk; - struct objfile *objfile; +decode_locdesc (struct dwarf_block *blk, struct objfile *objfile, + const struct comp_unit_head *cu_header) { int i; int size = blk->size; @@ -5633,6 +5701,7 @@ decode_locdesc (blk, objfile) stack[stacki] = 0; isreg = 0; offreg = 0; + isderef = 0; islocal = 0; optimized_out = 1; @@ -5729,6 +5798,14 @@ decode_locdesc (blk, objfile) 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; @@ -5746,8 +5823,9 @@ decode_locdesc (blk, objfile) break; case DW_OP_addr: - stack[++stacki] = read_address (objfile->obfd, &data[i]); - i += address_size; + stack[++stacki] = read_address (objfile->obfd, &data[i], + cu_header, &bytes_read); + i += bytes_read; break; case DW_OP_const1u: @@ -5782,7 +5860,7 @@ decode_locdesc (blk, objfile) case DW_OP_constu: stack[++stacki] = read_unsigned_leb128 (NULL, (data + i), - &bytes_read); + &bytes_read); i += bytes_read; break; @@ -5806,8 +5884,16 @@ decode_locdesc (blk, objfile) stacki--; 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. */ + if (i < size) + complain (&dwarf2_complex_location_expr); + break; + default: - complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name(op)); + complain (&dwarf2_unsupported_stack_op, dwarf_stack_op_name (op)); return (stack[stacki]); } } @@ -5818,14 +5904,13 @@ decode_locdesc (blk, objfile) /* ARGSUSED */ static void -dwarf2_free_tmp_obstack (ignore) - PTR ignore; +dwarf2_free_tmp_obstack (PTR ignore) { obstack_free (&dwarf2_tmp_obstack, NULL); } static struct dwarf_block * -dwarf_alloc_block () +dwarf_alloc_block (void) { struct dwarf_block *blk; @@ -5835,7 +5920,7 @@ dwarf_alloc_block () } static struct abbrev_info * -dwarf_alloc_abbrev () +dwarf_alloc_abbrev (void) { struct abbrev_info *abbrev; @@ -5845,7 +5930,7 @@ dwarf_alloc_abbrev () } static struct die_info * -dwarf_alloc_die () +dwarf_alloc_die (void) { struct die_info *die;