diff options
Diffstat (limited to 'contrib/gdb/gdb/dwarf2read.c')
-rw-r--r-- | contrib/gdb/gdb/dwarf2read.c | 2292 |
1 files changed, 1271 insertions, 1021 deletions
diff --git a/contrib/gdb/gdb/dwarf2read.c b/contrib/gdb/gdb/dwarf2read.c index cf52066..9dbcbde 100644 --- a/contrib/gdb/gdb/dwarf2read.c +++ b/contrib/gdb/gdb/dwarf2read.c @@ -1,5 +1,6 @@ /* DWARF 2 debugging format support for GDB. - Copyright 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 + 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,22 @@ 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 <fcntl.h> #include "gdb_string.h" +#include "gdb_assert.h" #include <sys/types.h> -/* .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 +65,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 @@ -122,6 +132,8 @@ static file_ptr dwarf_aranges_offset; static file_ptr dwarf_loc_offset; static file_ptr dwarf_macinfo_offset; static file_ptr dwarf_str_offset; +file_ptr dwarf_frame_offset; +file_ptr dwarf_eh_frame_offset; static unsigned int dwarf_info_size; static unsigned int dwarf_abbrev_size; @@ -131,6 +143,8 @@ static unsigned int dwarf_aranges_size; static unsigned int dwarf_loc_size; static unsigned int dwarf_macinfo_size; static unsigned int dwarf_str_size; +unsigned int dwarf_frame_size; +unsigned int dwarf_eh_frame_size; /* names of the debugging sections */ @@ -142,16 +156,23 @@ static unsigned int dwarf_str_size; #define LOC_SECTION ".debug_loc" #define MACINFO_SECTION ".debug_macinfo" #define STR_SECTION ".debug_str" +#define FRAME_SECTION ".debug_frame" +#define EH_FRAME_SECTION ".eh_frame" /* 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. */ @@ -180,6 +201,7 @@ struct partial_die_info unsigned int offset; unsigned int abbrev; char *name; + int has_pc_info; CORE_ADDR lowpc; CORE_ADDR highpc; struct dwarf_block *locdesc; @@ -207,15 +229,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 +249,8 @@ struct attribute { char *str; struct dwarf_block *blk; - unsigned int unsnd; - int snd; + unsigned long unsnd; + long int snd; CORE_ADDR addr; } u; @@ -287,6 +309,7 @@ static const struct language_defn *cu_language_defn; static char *dwarf_info_buffer; static char *dwarf_abbrev_buffer; static char *dwarf_line_buffer; +static char *dwarf_str_buffer; /* A zeroed version of a partial die for initialization purposes. */ static struct partial_die_info zeroed_partial_die; @@ -302,13 +325,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 +356,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 +371,35 @@ 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; + + /* Pointer to start of dwarf string buffer for the objfile. */ + + char *dwarf_str_buffer; + + /* Size of dwarf string section for the objfile. */ + + unsigned int dwarf_str_size; + }; #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private) #define DWARF_INFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_info_buffer) @@ -361,6 +407,8 @@ struct dwarf2_pinfo #define DWARF_ABBREV_BUFFER(p) (PST_PRIVATE(p)->dwarf_abbrev_buffer) #define DWARF_ABBREV_SIZE(p) (PST_PRIVATE(p)->dwarf_abbrev_size) #define DWARF_LINE_BUFFER(p) (PST_PRIVATE(p)->dwarf_line_buffer) +#define DWARF_STR_BUFFER(p) (PST_PRIVATE(p)->dwarf_str_buffer) +#define DWARF_STR_SIZE(p) (PST_PRIVATE(p)->dwarf_str_size) /* Maintain an array of referenced fundamental types for the current compilation unit being read. For DWARF version 1, we have to construct @@ -382,57 +430,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; - - /* Number of fields. */ - int nfields; - - /* Number of baseclasses. */ - int nbaseclasses; + { + /* List of data member and baseclasses fields. */ + struct nextfield + { + struct nextfield *next; + int accessibility; + int virtuality; + struct field field; + } + *fields; - /* Set if the accesibility of one of the fields is not public. */ - int non_public_fields; + /* Number of fields. */ + int nfields; - /* 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; + /* Number of baseclasses. */ + int nbaseclasses; - /* 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; + /* Set if the accesibility of one of the fields is not public. */ + int non_public_fields; - /* Number of entries in the fnfieldlists array. */ - int nfnfields; -}; + /* 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; -/* FIXME: Kludge to mark a varargs function type for C++ member function - argument processing. */ -#define TYPE_FLAG_VARARGS (1 << 10) + /* 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; -/* 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 between dwarf2_add_member_fn and - read_subroutine_type via TYPE_FIELD_ARTIFICIAL. */ -#define TYPE_FIELD_ARTIFICIAL TYPE_FIELD_BITPOS + /* Number of entries in the fnfieldlists array. */ + int nfnfields; + }; /* Various complaints about symbol reading that don't abort the process */ @@ -464,6 +504,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,240 +561,248 @@ 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 *)); +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 *, + 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 char *read_attribute_value (struct attribute *, unsigned, + bfd *, char *, const struct comp_unit_head *); -static char *read_partial_die PARAMS ((struct partial_die_info *, - bfd *, char *, int *)); +static unsigned int read_1_byte (bfd *, char *); -static char *read_full_die PARAMS ((struct die_info **, bfd *, char *)); +static int read_1_signed_byte (bfd *, char *); -static char *read_attribute PARAMS ((struct attribute *, struct attr_abbrev *, - bfd *, char *)); +static unsigned int read_2_bytes (bfd *, char *); -static unsigned int read_1_byte PARAMS ((bfd *, char *)); +static unsigned int read_4_bytes (bfd *, char *); -static int read_1_signed_byte PARAMS ((bfd *, char *)); +static unsigned long read_8_bytes (bfd *, char *); -static unsigned int read_2_bytes PARAMS ((bfd *, char *)); +static CORE_ADDR read_address (bfd *, char *ptr, const struct comp_unit_head *, + int *bytes_read); -static unsigned int read_4_bytes PARAMS ((bfd *, char *)); +static LONGEST read_initial_length (bfd *, char *, + struct comp_unit_head *, int *bytes_read); -static unsigned int read_8_bytes PARAMS ((bfd *, char *)); +static LONGEST read_offset (bfd *, char *, const struct comp_unit_head *, + int *bytes_read); -static CORE_ADDR read_address PARAMS ((bfd *, char *)); +static char *read_n_bytes (bfd *, char *, unsigned int); -static char *read_n_bytes PARAMS ((bfd *, char *, unsigned int)); +static char *read_string (bfd *, char *, unsigned int *); -static char *read_string PARAMS ((bfd *, char *, unsigned int *)); +static char *read_indirect_string (bfd *, char *, const struct comp_unit_head *, + unsigned int *); -static unsigned int read_unsigned_leb128 PARAMS ((bfd *, char *, - unsigned int *)); +static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *); -static int read_signed_leb128 PARAMS ((bfd *, char *, unsigned int *)); +static long read_signed_leb128 (bfd *, char *, unsigned int *); -static void set_cu_language PARAMS ((unsigned int)); +static void set_cu_language (unsigned int); -static struct attribute *dwarf_attr PARAMS ((struct die_info *, - unsigned int)); +static struct attribute *dwarf_attr (struct die_info *, unsigned int); -static void dwarf_decode_lines PARAMS ((unsigned int, char *, bfd *)); +static int die_is_declaration (struct die_info *); -static void dwarf2_start_subfile PARAMS ((char *, char *)); +static void dwarf_decode_lines (unsigned int, char *, bfd *, + const struct comp_unit_head *); -static struct symbol *new_symbol PARAMS ((struct die_info *, struct type *, - struct objfile *)); +static void dwarf2_start_subfile (char *, char *); -static void dwarf2_const_value PARAMS ((struct attribute *, struct symbol *, - struct objfile *)); +static struct symbol *new_symbol (struct die_info *, struct type *, + struct objfile *, const struct comp_unit_head *); -static struct type *die_type PARAMS ((struct die_info *, struct objfile *)); +static void dwarf2_const_value (struct attribute *, struct symbol *, + struct objfile *, const struct comp_unit_head *); -static struct type *die_containing_type PARAMS ((struct die_info *, - struct objfile *)); +static void dwarf2_const_value_data (struct attribute *attr, + struct symbol *sym, + int bits); + +static struct type *die_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); + +static struct type *die_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 *)); +static 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 *)); +static struct die_info *sibling_die (struct die_info *); -void dump_die PARAMS ((struct die_info *)); +static void dump_die (struct die_info *); -void dump_die_list PARAMS ((struct die_info *)); +static void dump_die_list (struct die_info *); -void store_in_ref_table PARAMS ((unsigned int, struct die_info *)); +static 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)); +static 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; + dwarf_str_offset = 0; + dwarf_frame_offset = dwarf_eh_frame_offset = 0; bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL); if (dwarf_info_offset && dwarf_abbrev_offset) { @@ -767,10 +819,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)) { @@ -812,15 +861,22 @@ dwarf2_locate_sections (ignore_abfd, sectp, ignore_ptr) dwarf_str_offset = sectp->filepos; dwarf_str_size = bfd_get_section_size_before_reloc (sectp); } + else if (STREQ (sectp->name, FRAME_SECTION)) + { + dwarf_frame_offset = sectp->filepos; + dwarf_frame_size = bfd_get_section_size_before_reloc (sectp); + } + else if (STREQ (sectp->name, EH_FRAME_SECTION)) + { + dwarf_eh_frame_offset = sectp->filepos; + dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp); + } } /* 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 */ @@ -835,8 +891,16 @@ dwarf2_build_psymtabs (objfile, section_offsets, mainline) dwarf_line_offset, dwarf_line_size); - if (mainline || objfile->global_psymbols.size == 0 || - objfile->static_psymbols.size == 0) + if (dwarf_str_offset) + dwarf_str_buffer = dwarf2_read_section (objfile, + dwarf_str_offset, + dwarf_str_size); + else + dwarf_str_buffer = NULL; + + if (mainline + || (objfile->global_psymbols.size == 0 + && objfile->static_psymbols.size == 0)) { init_psymbol_list (objfile, 1024); } @@ -844,17 +908,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 +927,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 +940,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,49 +961,101 @@ 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; + /* We use dwarf2_tmp_obstack for objects that don't need to survive + the partial symbol scan, like attribute values. + + We could reduce our peak memory consumption during partial symbol + table construction by freeing stuff from this obstack more often + --- say, after processing each compilation unit, or each die --- + but it turns out that this saves almost nothing. For an + executable with 11Mb of Dwarf 2 data, I found about 64k allocated + on dwarf2_tmp_obstack. Some investigation showed: + + 1) 69% of the attributes used forms DW_FORM_addr, DW_FORM_data*, + DW_FORM_flag, DW_FORM_[su]data, and DW_FORM_ref*. These are + all fixed-length values not requiring dynamic allocation. + + 2) 30% of the attributes used the form DW_FORM_string. For + DW_FORM_string, read_attribute simply hands back a pointer to + the null-terminated string in dwarf_info_buffer, so no dynamic + allocation is needed there either. + + 3) The remaining 1% of the attributes all used DW_FORM_block1. + 75% of those were DW_AT_frame_base location lists for + functions; the rest were DW_AT_location attributes, probably + for the global variables. + + Anyway, what this all means is that the memory the dwarf2 + reader uses as temporary space reading partial symbols is about + 0.5% as much as we use for dwarf_*_buffer. That's noise. */ + obstack_init (&dwarf2_tmp_obstack); 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) + /* Since the objects we're extracting from dwarf_info_buffer vary in + length, only the individual functions to extract them (like + read_comp_unit_head and read_partial_die) can really know whether + the buffer is large enough to hold another complete object. + + At the moment, they don't actually check that. If + dwarf_info_buffer holds just one extra byte after the last + compilation unit's dies, then read_comp_unit_head will happily + read off the end of the buffer. read_partial_die is similarly + casual. Those functions should be fixed. + + For this loop condition, simply checking whether there's any data + left at all should be sufficient. */ + while (info_ptr < dwarf_info_buffer + 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 +1069,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 +1077,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, + &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 +1098,14 @@ 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; + DWARF_STR_BUFFER (pst) = dwarf_str_buffer; + DWARF_STR_SIZE (pst) = dwarf_str_size; + 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; @@ -1003,17 +1115,18 @@ dwarf2_build_psymtabs_hard (objfile, section_offsets, mainline) If not, there's no more debug_info for this comp unit. */ if (comp_unit_die.has_children) { - info_ptr = scan_partial_symbols (info_ptr, objfile, &lowpc, &highpc); + 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) + if (! comp_unit_die.has_pc_info) { - comp_unit_die.lowpc = lowpc; + comp_unit_die.lowpc = lowpc; comp_unit_die.highpc = highpc; } } - pst->textlow = comp_unit_die.lowpc + baseaddr; + pst->textlow = comp_unit_die.lowpc + baseaddr; pst->texthigh = comp_unit_die.highpc + baseaddr; pst->n_global_syms = objfile->global_psymbols.next - @@ -1027,7 +1140,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); } @@ -1035,11 +1149,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; @@ -1051,21 +1163,20 @@ scan_partial_symbols (info_ptr, objfile, lowpc, highpc) back to that level. */ 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, cu_header); if (pdi.name) { switch (pdi.tag) { case DW_TAG_subprogram: - if (has_pc_info) + if (pdi.has_pc_info) { if (pdi.lowpc < *lowpc) { @@ -1078,7 +1189,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; @@ -1091,20 +1202,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; @@ -1112,8 +1223,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; @@ -1139,9 +1250,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; @@ -1151,20 +1261,20 @@ add_partial_symbol (pdi, objfile) if (pdi->is_external) { /*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr, - mst_text, objfile);*/ + 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);*/ + 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: @@ -1184,7 +1294,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, @@ -1196,9 +1306,9 @@ add_partial_symbol (pdi, objfile) /* Static Variable. Skip symbols without location descriptors. */ if (pdi->locdesc == NULL) return; - addr = decode_locdesc (pdi->locdesc, objfile); + addr = decode_locdesc (pdi->locdesc, objfile, cu_header); /*prim_record_minimal_symbol (pdi->name, addr + baseaddr, - mst_file_data, objfile);*/ + mst_file_data, objfile); */ add_psymbol_to_list (pdi->name, strlen (pdi->name), VAR_NAMESPACE, LOC_STATIC, &objfile->static_psymbols, @@ -1217,7 +1327,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), @@ -1248,8 +1358,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) @@ -1276,8 +1385,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; @@ -1291,12 +1399,14 @@ 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); + dwarf_str_buffer = DWARF_STR_BUFFER (pst); + dwarf_str_size = DWARF_STR_SIZE (pst); + baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile)); cu_header_offset = offset; info_ptr = dwarf_info_buffer + offset; @@ -1304,34 +1414,27 @@ psymtab_to_symtab_1 (pst) back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL); buildsym_init (); - make_cleanup ((make_cleanup_func) really_free_pendings, NULL); + 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 ((make_cleanup_func) 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) { @@ -1351,7 +1454,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, @@ -1371,51 +1474,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); @@ -1425,27 +1527,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 = "<unknown>"; @@ -1518,8 +1619,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); } @@ -1537,7 +1638,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. */ @@ -1546,16 +1647,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; @@ -1581,12 +1681,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; @@ -1594,8 +1688,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) { @@ -1607,7 +1703,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) @@ -1615,7 +1711,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); } } @@ -1631,9 +1727,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; @@ -1651,7 +1746,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); } } @@ -1669,11 +1764,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; @@ -1712,10 +1804,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; @@ -1724,7 +1815,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; @@ -1752,7 +1843,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); @@ -1770,7 +1861,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; @@ -1780,20 +1871,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); @@ -1826,7 +1917,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; @@ -1836,38 +1927,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++; } @@ -1876,10 +1962,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; @@ -1929,78 +2013,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; @@ -2010,46 +2061,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++) @@ -2068,10 +2088,9 @@ 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 ((make_cleanup_func) free_current_contents, - &fip->fnfieldlists); + make_cleanup (free_current_contents, &fip->fnfieldlists); } flp = &fip->fnfieldlists[fip->nfnfields]; flp->name = fieldname; @@ -2083,7 +2102,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; @@ -2108,7 +2127,7 @@ dwarf2_add_member_fn (fip, die, type, objfile) arg_types[iparams] = TYPE_FIELD_TYPE (die->type, iparams); /* Set last entry in argument type vector. */ - if (TYPE_FLAGS (die->type) & TYPE_FLAG_VARARGS) + if (TYPE_VARARGS (die->type)) arg_types[nparams] = NULL; else arg_types[nparams] = dwarf2_fundamental_type (objfile, FT_VOID); @@ -2116,11 +2135,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; } @@ -2129,7 +2148,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. */ @@ -2140,28 +2159,31 @@ 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; } } + /* Check for artificial methods. */ + attr = dwarf_attr (die, DW_AT_artificial); + if (attr && DW_UNSND (attr) != 0) + fnp->is_artificial = 1; + /* Get index in virtual function table if it is a virtual member function. */ attr = dwarf_attr (die, DW_AT_vtable_elem_location); 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; @@ -2182,7 +2204,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; } @@ -2208,9 +2230,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; @@ -2237,7 +2258,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; } @@ -2256,7 +2277,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; @@ -2270,27 +2291,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); } @@ -2302,18 +2323,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. */ @@ -2334,7 +2356,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 { @@ -2343,7 +2365,7 @@ read_structure_scope (die, objfile) } } - new_symbol (die, type, objfile); + new_symbol (die, type, objfile, cu_header); do_cleanups (back_to); } @@ -2353,7 +2375,7 @@ read_structure_scope (die, objfile) TYPE_FLAGS (type) |= TYPE_FLAG_STUB; } - die->type = type; + finish_cv_type (die->type); } /* Given a pointer to a die which begins an enumeration, process all @@ -2366,9 +2388,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; @@ -2408,14 +2429,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; @@ -2424,7 +2445,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); @@ -2446,13 +2467,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 @@ -2460,9 +2481,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; @@ -2478,7 +2498,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. */ @@ -2507,7 +2527,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) { @@ -2516,9 +2536,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); } @@ -2542,9 +2562,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); } @@ -2575,10 +2595,9 @@ 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 ((make_cleanup_func) free_current_contents, - &range_types); + make_cleanup (free_current_contents, &range_types); } range_types[ndim++] = create_range_type (NULL, index_type, low, high); } @@ -2600,9 +2619,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; @@ -2612,19 +2630,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); @@ -2636,9 +2654,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; @@ -2648,7 +2665,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) { @@ -2656,7 +2673,7 @@ read_tag_pointer_type (die, objfile) } else { - TYPE_LENGTH (type) = address_size; + TYPE_LENGTH (type) = cu_header->addr_size; } die->type = type; } @@ -2665,9 +2682,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; @@ -2679,8 +2695,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; @@ -2690,9 +2706,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; @@ -2702,7 +2717,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) { @@ -2710,37 +2725,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 @@ -2749,9 +2766,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; @@ -2769,30 +2784,47 @@ read_tag_string_type (die, objfile) } else { - length = 1; + /* check for the DW_AT_byte_size attribute */ + attr = dwarf_attr (die, DW_AT_byte_size); + if (attr) + { + length = DW_UNSND (attr); + } + else + { + length = 1; + } } index_type = dwarf2_fundamental_type (objfile, FT_INTEGER); range_type = create_range_type (NULL, index_type, 1, length); - char_type = dwarf2_fundamental_type (objfile, FT_CHAR); - type = create_string_type (char_type, range_type); + if (cu_language == language_fortran) + { + /* Need to create a unique string type for bounds + information */ + type = create_string_type (0, range_type); + } + else + { + char_type = dwarf2_fundamental_type (objfile, FT_CHAR); + type = create_string_type (char_type, range_type); + } die->type = type; } /* 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 */ @@ -2803,7 +2835,7 @@ 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. */ @@ -2842,16 +2874,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); @@ -2862,30 +2895,21 @@ 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; + struct attribute *attr; + char *name = NULL; if (!die->type) { - struct attribute *attr; - struct type *xtype; - - xtype = die_type (die, objfile); - - type = alloc_type (objfile); - TYPE_CODE (type) = TYPE_CODE_TYPEDEF; - TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB; - TYPE_TARGET_TYPE (type) = xtype; attr = dwarf_attr (die, DW_AT_name); if (attr && DW_STRING (attr)) - TYPE_NAME (type) = obsavestring (DW_STRING (attr), - strlen (DW_STRING (attr)), - &objfile->type_obstack); - - die->type = type; + { + name = DW_STRING (attr); + } + die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile); + TYPE_TARGET_TYPE (die->type) = die_type (die, objfile, cu_header); } } @@ -2893,9 +2917,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; @@ -2921,18 +2943,18 @@ read_base_type (die, objfile) if (attr && DW_STRING (attr)) { enum type_code code = TYPE_CODE_INT; - int is_unsigned = 0; + int type_flags = 0; switch (encoding) { case DW_ATE_address: /* Turn DW_ATE_address into a void * pointer. */ code = TYPE_CODE_PTR; - is_unsigned = 1; + type_flags |= TYPE_FLAG_UNSIGNED; break; case DW_ATE_boolean: code = TYPE_CODE_BOOL; - is_unsigned = 1; + type_flags |= TYPE_FLAG_UNSIGNED; break; case DW_ATE_complex_float: code = TYPE_CODE_COMPLEX; @@ -2945,14 +2967,14 @@ read_base_type (die, objfile) break; case DW_ATE_unsigned: case DW_ATE_unsigned_char: - is_unsigned = 1; + type_flags |= TYPE_FLAG_UNSIGNED; break; default: complain (&dwarf2_unsupported_at_encoding, dwarf_type_encoding_name (encoding)); break; } - type = init_type (code, size, is_unsigned, DW_STRING (attr), objfile); + type = init_type (code, size, type_flags, DW_STRING (attr), objfile); if (encoding == DW_ATE_address) TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID); } @@ -2965,24 +2987,24 @@ 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; +static struct die_info * +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++; @@ -3014,8 +3036,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; @@ -3023,20 +3044,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; +char * +dwarf2_read_section (struct objfile *objfile, file_ptr offset, + unsigned int size) { bfd *abfd = objfile->obfd; char *buf; @@ -3046,11 +3078,11 @@ dwarf2_read_section (objfile, offset, size) buf = (char *) obstack_alloc (&objfile->psymbol_obstack, size); if ((bfd_seek (abfd, offset, SEEK_SET) != 0) || - (bfd_read (buf, size, 1, abfd) != size)) + (bfd_bread (buf, size, abfd) != size)) { buf = NULL; error ("Dwarf Error: Can't read DWARF data from '%s'", - bfd_get_filename (abfd)); + bfd_get_filename (abfd)); } return buf; } @@ -3061,9 +3093,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; @@ -3101,7 +3131,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; @@ -3117,13 +3147,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; @@ -3136,8 +3166,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; @@ -3149,8 +3178,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; @@ -3160,8 +3189,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; @@ -3182,22 +3210,18 @@ 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, 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; - *has_pc_info = 0; abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; if (!abbrev_number) @@ -3215,10 +3239,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: @@ -3262,7 +3287,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); @@ -3282,7 +3307,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, cu_header); if (spec_die.name) { part_die->name = spec_die.name; @@ -3305,7 +3330,7 @@ read_partial_die (part_die, abfd, info_ptr, has_pc_info) && part_die->lowpc < part_die->highpc && (part_die->lowpc != 0 || (bfd_get_file_flags (abfd) & HAS_RELOC))) - *has_pc_info = 1; + part_die->has_pc_info = 1; return info_ptr; } @@ -3313,10 +3338,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; @@ -3354,33 +3377,30 @@ 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; return info_ptr; } -/* Read an attribute described by an abbreviated attribute. */ +/* Read an attribute value described by an attribute form. */ static char * -read_attribute (attr, abbrev, abfd, info_ptr) - struct attribute *attr; - struct attr_abbrev *abbrev; - bfd *abfd; - char *info_ptr; +read_attribute_value (struct attribute *attr, unsigned form, + bfd *abfd, char *info_ptr, + const struct comp_unit_head *cu_header) { unsigned int bytes_read; struct dwarf_block *blk; - attr->name = abbrev->name; - attr->form = abbrev->form; - switch (abbrev->form) + attr->form = form; + switch (form) { 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 (); @@ -3414,6 +3434,11 @@ read_attribute (attr, abbrev, abfd, info_ptr) DW_STRING (attr) = read_string (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; break; + case DW_FORM_strp: + DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header, + &bytes_read); + info_ptr += bytes_read; + break; case DW_FORM_block: blk = dwarf_alloc_block (); blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); @@ -3458,144 +3483,229 @@ 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; break; - case DW_FORM_strp: case DW_FORM_indirect: + form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); + info_ptr += bytes_read; + info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu_header); + break; default: error ("Dwarf Error: Cannot handle %s in DWARF reader.", - dwarf_form_name (abbrev->form)); + dwarf_form_name (form)); } return info_ptr; } +/* Read an attribute described by an abbreviated attribute. */ + +static char * +read_attribute (struct attribute *attr, struct attr_abbrev *abbrev, + bfd *abfd, char *info_ptr, + const struct comp_unit_head *cu_header) +{ + attr->name = abbrev->name; + return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu_header); +} + /* 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 allocated on the temporary obstack. */ -#if HOST_CHAR_BIT == 8 + gdb_assert (HOST_CHAR_BIT == 8); return buf; -#else - char *ret; - unsigned int i; - - ret = obstack_alloc (&dwarf2_tmp_obstack, size); - for (i = 0; i < size; ++i) - { - ret[i] = bfd_get_8 (abfd, (bfd_byte *) buf); - buf++; - } - return ret; -#endif } 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 allocated on the temporary obstack. */ -#if HOST_CHAR_BIT == 8 + gdb_assert (HOST_CHAR_BIT == 8); if (*buf == '\0') { *bytes_read_ptr = 1; @@ -3603,34 +3713,37 @@ read_string (abfd, buf, bytes_read_ptr) } *bytes_read_ptr = strlen (buf) + 1; return buf; -#else - int byte; - unsigned int i = 0; +} + +static char * +read_indirect_string (bfd *abfd, char *buf, + const struct comp_unit_head *cu_header, + unsigned int *bytes_read_ptr) +{ + LONGEST str_offset = read_offset (abfd, buf, cu_header, + (int *) bytes_read_ptr); - while ((byte = bfd_get_8 (abfd, (bfd_byte *) buf)) != 0) + if (dwarf_str_buffer == NULL) { - obstack_1grow (&dwarf2_tmp_obstack, byte); - i++; - buf++; + error ("DW_FORM_strp used without .debug_str section"); + return NULL; } - if (i == 0) + if (str_offset >= dwarf_str_size) { - *bytes_read_ptr = 1; + error ("DW_FORM_strp pointing outside of .debug_str section"); return NULL; } - obstack_1grow (&dwarf2_tmp_obstack, '\0'); - *bytes_read_ptr = i + 1; - return obstack_finish (&dwarf2_tmp_obstack); -#endif + gdb_assert (HOST_CHAR_BIT == 8); + if (dwarf_str_buffer[str_offset] == '\0') + return NULL; + return dwarf_str_buffer + str_offset; } -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; @@ -3643,7 +3756,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; @@ -3654,13 +3767,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; @@ -3674,7 +3784,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) { @@ -3690,8 +3800,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) { @@ -3704,11 +3813,15 @@ set_cu_language (lang) break; case DW_LANG_Fortran77: case DW_LANG_Fortran90: + case DW_LANG_Fortran95: cu_language = language_fortran; break; 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: @@ -3724,9 +3837,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; @@ -3744,15 +3855,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. */ @@ -3761,26 +3879,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; @@ -3811,13 +3927,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); @@ -3830,8 +3946,7 @@ dwarf_decode_lines (offset, comp_dir, abfd) line_ptr += 1; lh.standard_opcode_lengths = (unsigned char *) xmalloc (lh.opcode_base * sizeof (unsigned char)); - back_to = make_cleanup ((make_cleanup_func) free_current_contents, - &lh.standard_opcode_lengths); + back_to = make_cleanup (free_current_contents, &lh.standard_opcode_lengths); lh.standard_opcode_lengths[0] = 1; for (i = 1; i < lh.opcode_base; ++i) @@ -3850,7 +3965,7 @@ dwarf_decode_lines (offset, comp_dir, abfd) xrealloc (dirs.dirs, (dirs.num_dirs + DIR_ALLOC_CHUNK) * sizeof (char *)); if (dirs.num_dirs == 0) - make_cleanup ((make_cleanup_func) free_current_contents, &dirs.dirs); + make_cleanup (free_current_contents, &dirs.dirs); } dirs.dirs[dirs.num_dirs++] = cur_dir; } @@ -3865,10 +3980,9 @@ 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 ((make_cleanup_func) free_current_contents, - &files.files); + make_cleanup (free_current_contents, &files.files); } files.files[files.num_files].name = cur_file; files.files[files.num_files].dir = @@ -3908,11 +4022,22 @@ 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; - switch (op_code) + + if (op_code >= lh.opcode_base) + { /* Special operand. */ + adj_opcode = op_code - lh.opcode_base; + address += (adj_opcode / lh.line_range) + * lh.minimum_instruction_length; + line += lh.line_base + (adj_opcode % lh.line_range); + /* append row to matrix using current values */ + record_line (current_subfile, line, address); + basic_block = 1; + } + else switch (op_code) { case DW_LNS_extended_op: line_ptr += 1; /* ignore length */ @@ -3922,11 +4047,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); @@ -3936,10 +4067,9 @@ 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 ((make_cleanup_func) free_current_contents, - &files.files); + make_cleanup (free_current_contents, &files.files); } files.files[files.num_files].name = cur_file; files.files[files.num_files].dir = @@ -3973,7 +4103,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 @@ -3992,21 +4122,28 @@ 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); line_ptr += 2; break; - default: /* special operand */ - adj_opcode = op_code - lh.opcode_base; - address += (adj_opcode / lh.line_range) - * lh.minimum_instruction_length; - line += lh.line_base + (adj_opcode % lh.line_range); - /* append row to matrix using current values */ - record_line (current_subfile, line, address); - basic_block = 1; + default: + { /* Unknown standard opcode, ignore it. */ + int i; + for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++) + { + (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + line_ptr += bytes_read; + } + } } } } @@ -4024,39 +4161,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); } @@ -4065,14 +4200,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; @@ -4091,13 +4223,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) { @@ -4148,7 +4280,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); @@ -4163,10 +4295,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 @@ -4175,7 +4307,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 @@ -4184,7 +4319,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) { @@ -4193,11 +4328,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) { @@ -4205,19 +4342,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) @@ -4231,15 +4371,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 { @@ -4249,7 +4401,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; @@ -4272,8 +4424,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) @@ -4294,7 +4446,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; @@ -4313,22 +4465,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: @@ -4344,15 +4496,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)); @@ -4362,12 +4534,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; @@ -4390,7 +4584,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); @@ -4403,9 +4597,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; @@ -4422,7 +4615,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) { @@ -4435,9 +4628,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; @@ -4454,9 +4645,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) { @@ -4464,7 +4654,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); @@ -4475,47 +4665,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); @@ -4527,10 +4716,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. */ @@ -4607,8 +4793,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; @@ -4641,9 +4826,8 @@ copy_die (old_die) /* Return sibling of die, NULL if no sibling. */ -struct die_info * -sibling_die (die) - struct die_info *die; +static struct die_info * +sibling_die (struct die_info *die) { int nesting_level = 0; @@ -4687,8 +4871,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; @@ -4704,8 +4887,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) { @@ -4821,8 +5003,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) { @@ -4988,8 +5169,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) { @@ -5043,8 +5223,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) { @@ -5344,8 +5523,7 @@ dwarf_stack_op_name (op) } static char * -dwarf_bool_name (mybool) - unsigned mybool; +dwarf_bool_name (unsigned mybool) { if (mybool) return "TRUE"; @@ -5356,8 +5534,7 @@ dwarf_bool_name (mybool) /* 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) { @@ -5386,8 +5563,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,81 +5603,104 @@ dwarf_cfi_name (cfi_opc) return "DW_CFA_def_cfa_register"; case DW_CFA_def_cfa_offset: return "DW_CFA_def_cfa_offset"; + + /* DWARF 3 */ + case DW_CFA_def_cfa_expression: + return "DW_CFA_def_cfa_expression"; + case DW_CFA_expression: + return "DW_CFA_expression"; + case DW_CFA_offset_extended_sf: + return "DW_CFA_offset_extended_sf"; + case DW_CFA_def_cfa_sf: + return "DW_CFA_def_cfa_sf"; + case DW_CFA_def_cfa_offset_sf: + return "DW_CFA_def_cfa_offset_sf"; + /* SGI/MIPS specific */ case DW_CFA_MIPS_advance_loc8: return "DW_CFA_MIPS_advance_loc8"; + + /* GNU extensions */ + case DW_CFA_GNU_window_save: + return "DW_CFA_GNU_window_save"; + case DW_CFA_GNU_args_size: + return "DW_CFA_GNU_args_size"; + case DW_CFA_GNU_negative_offset_extended: + return "DW_CFA_GNU_negative_offset_extended"; + default: return "DW_CFA_<unknown>"; } } #endif -void -dump_die (die) - struct die_info *die; +static void +dump_die (struct die_info *die) { unsigned int i; - fprintf (stderr, "Die: %s (abbrev = %d, offset = %d)\n", + fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n", dwarf_tag_name (die->tag), die->abbrev, die->offset); - fprintf (stderr, "\thas children: %s\n", + fprintf_unfiltered (gdb_stderr, "\thas children: %s\n", dwarf_bool_name (die->has_children)); - fprintf (stderr, "\tattributes:\n"); + fprintf_unfiltered (gdb_stderr, "\tattributes:\n"); for (i = 0; i < die->num_attrs; ++i) { - fprintf (stderr, "\t\t%s (%s) ", + fprintf_unfiltered (gdb_stderr, "\t\t%s (%s) ", dwarf_attr_name (die->attrs[i].name), dwarf_form_name (die->attrs[i].form)); switch (die->attrs[i].form) { case DW_FORM_ref_addr: case DW_FORM_addr: - fprintf (stderr, "address: "); + fprintf_unfiltered (gdb_stderr, "address: "); print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr); break; case DW_FORM_block2: case DW_FORM_block4: case DW_FORM_block: case DW_FORM_block1: - fprintf (stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size); + fprintf_unfiltered (gdb_stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size); break; 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_unfiltered (gdb_stderr, "constant: %ld", DW_UNSND (&die->attrs[i])); break; case DW_FORM_string: - fprintf (stderr, "string: \"%s\"", + case DW_FORM_strp: + fprintf_unfiltered (gdb_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])) - fprintf (stderr, "flag: TRUE"); + fprintf_unfiltered (gdb_stderr, "flag: TRUE"); else - fprintf (stderr, "flag: FALSE"); + fprintf_unfiltered (gdb_stderr, "flag: FALSE"); + break; + case DW_FORM_indirect: + /* the reader will have reduced the indirect form to + the "base form" so this form should not occur */ + fprintf_unfiltered (gdb_stderr, "unexpected attribute form: DW_FORM_indirect"); break; - 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); + fprintf_unfiltered (gdb_stderr, "unsupported attribute form: %d.", + die->attrs[i].form); } - fprintf (stderr, "\n"); + fprintf_unfiltered (gdb_stderr, "\n"); } } -void -dump_die_list (die) - struct die_info *die; +static void +dump_die_list (struct die_info *die) { while (die) { @@ -5510,10 +5709,8 @@ dump_die_list (die) } } -void -store_in_ref_table (offset, die) - unsigned int offset; - struct die_info *die; +static void +store_in_ref_table (unsigned int offset, struct die_info *die) { int h; struct die_info *old; @@ -5526,14 +5723,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; @@ -5545,6 +5741,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; @@ -5554,9 +5751,8 @@ dwarf2_get_ref_die_offset (attr) return result; } -struct die_info * -follow_die_ref (offset) - unsigned int offset; +static struct die_info * +follow_die_ref (unsigned int offset) { struct die_info *die; int h; @@ -5575,9 +5771,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) { @@ -5621,14 +5815,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; @@ -5643,6 +5836,7 @@ decode_locdesc (blk, objfile) stack[stacki] = 0; isreg = 0; offreg = 0; + isderef = 0; islocal = 0; optimized_out = 1; @@ -5652,6 +5846,41 @@ decode_locdesc (blk, objfile) op = data[i++]; switch (op) { + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + stack[++stacki] = op - DW_OP_lit0; + break; + case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: @@ -5739,6 +5968,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; @@ -5756,8 +5993,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: @@ -5792,7 +6030,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; @@ -5801,6 +6039,11 @@ decode_locdesc (blk, objfile) i += bytes_read; break; + case DW_OP_dup: + stack[stacki + 1] = stack[stacki]; + stacki++; + break; + case DW_OP_plus: stack[stacki - 1] += stack[stacki]; stacki--; @@ -5812,12 +6055,20 @@ decode_locdesc (blk, objfile) break; case DW_OP_minus: - stack[stacki - 1] = stack[stacki] - stack[stacki - 1]; + stack[stacki - 1] -= stack[stacki]; 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]); } } @@ -5828,14 +6079,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; @@ -5845,7 +6095,7 @@ dwarf_alloc_block () } static struct abbrev_info * -dwarf_alloc_abbrev () +dwarf_alloc_abbrev (void) { struct abbrev_info *abbrev; @@ -5855,7 +6105,7 @@ dwarf_alloc_abbrev () } static struct die_info * -dwarf_alloc_die () +dwarf_alloc_die (void) { struct die_info *die; |