X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=0f05c0922fcc1c077a223e294deb589fa5a683a2;hb=0f7d239c5ad7daea45f8b300b5308f90b76647a7;hp=73ccd0644b66719632c03c3438c7647ff2726532;hpb=a14ed312fd86dd2c862847230931451da2e49942;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 73ccd0644b..0f05c0922f 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1,5 +1,6 @@ /* DWARF 2 debugging format support for GDB. - Copyright 1994, 1995, 1996, 1997, 1998 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 @@ -35,14 +36,22 @@ #include "buildsym.h" #include "demangle.h" #include "expression.h" +#include "filenames.h" /* for DOSish file names */ + #include "language.h" #include "complaints.h" - +#include "bcache.h" #include #include "gdb_string.h" +#include "gdb_assert.h" #include -/* .debug_info header for a compilation unit +#ifndef DWARF2_REG_TO_REGNUM +#define DWARF2_REG_TO_REGNUM(REG) (REG) +#endif + +#if 0 +/* .debug_info header for a compilation unit Because of alignment constraints, this structure has padding and cannot be mapped directly onto the beginning of the .debug_info section. */ typedef struct comp_unit_header @@ -56,6 +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; @@ -227,13 +249,23 @@ struct attribute { char *str; struct dwarf_block *blk; - unsigned int unsnd; - int snd; + unsigned long unsnd; + long int snd; CORE_ADDR addr; } u; }; +struct function_range +{ + const char *name; + CORE_ADDR lowpc, highpc; + int seen_line; + struct function_range *next; +}; + +static struct function_range *cu_first_fn, *cu_last_fn, *cu_cached_fn; + /* Get at parts of an attribute structure */ #define DW_STRING(attr) ((attr)->u.str) @@ -287,6 +319,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; @@ -333,7 +366,7 @@ static int islocal; /* Variable is at the returned offset 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 */ @@ -368,6 +401,14 @@ struct dwarf2_pinfo /* Pointer to start of dwarf line buffer for the objfile. */ 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) @@ -376,6 +417,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 @@ -441,17 +484,6 @@ struct field_info int nfnfields; }; -/* FIXME: Kludge to mark a varargs function type for C++ member function - argument processing. */ -#define TYPE_FLAG_VARARGS (1 << 10) - -/* 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 - /* Various complaints about symbol reading that don't abort the process */ static struct complaint dwarf2_const_ignored = @@ -538,15 +570,10 @@ 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; - -/* Externals references. */ -extern int info_verbose; /* From main.c; nonzero => verbose */ +static struct complaint dwarf2_misplaced_line_number = +{ + "misplaced first line number at 0x%lx for '%s'", 0, 0 +}; /* local function prototypes */ @@ -559,15 +586,17 @@ static void dwarf2_build_psymtabs_easy (struct objfile *, int); static void dwarf2_build_psymtabs_hard (struct objfile *, int); static char *scan_partial_symbols (char *, struct objfile *, - CORE_ADDR *, CORE_ADDR *); + CORE_ADDR *, CORE_ADDR *, + const struct comp_unit_head *); -static void add_partial_symbol (struct partial_die_info *, struct objfile *); +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 *dwarf2_read_section (struct objfile *, file_ptr, unsigned int); +char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int); static void dwarf2_read_abbrevs (bfd *, unsigned int); @@ -576,12 +605,17 @@ static void dwarf2_empty_abbrev_table (PTR); static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int); static char *read_partial_die (struct partial_die_info *, - bfd *, char *, int *); + bfd *, char *, + const struct comp_unit_head *); -static char *read_full_die (struct die_info **, bfd *, char *); +static char *read_full_die (struct die_info **, bfd *, char *, + const struct comp_unit_head *); static char *read_attribute (struct attribute *, struct attr_abbrev *, - bfd *, char *); + bfd *, char *, const struct comp_unit_head *); + +static char *read_attribute_value (struct attribute *, unsigned, + bfd *, char *, const struct comp_unit_head *); static unsigned int read_1_byte (bfd *, char *); @@ -591,17 +625,27 @@ static unsigned int read_2_bytes (bfd *, char *); static unsigned int read_4_bytes (bfd *, char *); -static unsigned int read_8_bytes (bfd *, char *); +static unsigned long read_8_bytes (bfd *, char *); + +static CORE_ADDR read_address (bfd *, char *ptr, const struct comp_unit_head *, + int *bytes_read); + +static LONGEST read_initial_length (bfd *, char *, + struct comp_unit_head *, int *bytes_read); -static CORE_ADDR read_address (bfd *, char *); +static LONGEST read_offset (bfd *, char *, const struct comp_unit_head *, + int *bytes_read); static char *read_n_bytes (bfd *, char *, unsigned int); static char *read_string (bfd *, char *, unsigned int *); -static unsigned int read_unsigned_leb128 (bfd *, char *, unsigned int *); +static char *read_indirect_string (bfd *, char *, const struct comp_unit_head *, + unsigned int *); -static int read_signed_leb128 (bfd *, char *, unsigned int *); +static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *); + +static long read_signed_leb128 (bfd *, char *, unsigned int *); static void set_cu_language (unsigned int); @@ -609,91 +653,114 @@ static struct attribute *dwarf_attr (struct die_info *, unsigned int); static int die_is_declaration (struct die_info *); -static void dwarf_decode_lines (unsigned int, char *, bfd *); +static void dwarf_decode_lines (unsigned int, char *, bfd *, + const struct comp_unit_head *); static void dwarf2_start_subfile (char *, char *); static struct symbol *new_symbol (struct die_info *, struct type *, - struct objfile *); + struct objfile *, const struct comp_unit_head *); static void dwarf2_const_value (struct attribute *, struct symbol *, - struct objfile *); + struct objfile *, const struct comp_unit_head *); static void dwarf2_const_value_data (struct attribute *attr, struct symbol *sym, int bits); -static struct type *die_type (struct die_info *, struct objfile *); +static struct type *die_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static struct type *die_containing_type (struct die_info *, struct objfile *); +static struct type *die_containing_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); #if 0 static struct type *type_at_offset (unsigned int, struct objfile *); #endif -static struct type *tag_type_to_type (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 (struct die_info *, struct objfile *); +static void read_type_die (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_typedef (struct die_info *, struct objfile *); +static void read_typedef (struct die_info *, struct objfile *, + const struct comp_unit_head *); static void read_base_type (struct die_info *, struct objfile *); -static void read_file_scope (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 (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 (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 (struct die_info *, CORE_ADDR *, CORE_ADDR *, struct objfile *); static void dwarf2_add_field (struct field_info *, struct die_info *, - struct objfile *); + struct objfile *, const struct comp_unit_head *); static void dwarf2_attach_fields_to_type (struct field_info *, struct type *, struct objfile *); static void dwarf2_add_member_fn (struct field_info *, struct die_info *, struct type *, - struct objfile *objfile); + struct objfile *objfile, + const struct comp_unit_head *); static void dwarf2_attach_fn_fields_to_type (struct field_info *, struct type *, struct objfile *); -static void read_structure_scope (struct die_info *, struct objfile *); +static void read_structure_scope (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_common_block (struct die_info *, struct objfile *); +static void read_common_block (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_enumeration (struct die_info *, struct objfile *); +static void read_enumeration (struct die_info *, struct objfile *, + const struct comp_unit_head *); static struct type *dwarf_base_type (int, int, struct objfile *); -static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *); +static CORE_ADDR decode_locdesc (struct dwarf_block *, struct objfile *, + const struct comp_unit_head *); -static void read_array_type (struct die_info *, struct objfile *); +static void read_array_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_tag_pointer_type (struct die_info *, struct objfile *); +static void read_tag_pointer_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_tag_ptr_to_member_type (struct die_info *, struct objfile *); +static void read_tag_ptr_to_member_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_tag_reference_type (struct die_info *, struct objfile *); +static void read_tag_reference_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_tag_const_type (struct die_info *, struct objfile *); +static void read_tag_const_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -static void read_tag_volatile_type (struct die_info *, struct objfile *); +static void read_tag_volatile_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); static void read_tag_string_type (struct die_info *, struct objfile *); -static void read_subroutine_type (struct die_info *, struct objfile *); +static void read_subroutine_type (struct die_info *, struct objfile *, + const struct comp_unit_head *); -struct die_info *read_comp_unit (char *, bfd *); +static struct die_info *read_comp_unit (char *, bfd *, + const struct comp_unit_head *); static void free_die_list (struct die_info *); static struct cleanup *make_cleanup_free_die_list (struct die_info *); -static void process_die (struct die_info *, struct objfile *); +static void process_die (struct die_info *, struct objfile *, + const struct comp_unit_head *); static char *dwarf2_linkage_name (struct die_info *); @@ -715,19 +782,19 @@ static char *dwarf_cfi_name (unsigned int); struct die_info *copy_die (struct die_info *); #endif -struct die_info *sibling_die (struct die_info *); +static struct die_info *sibling_die (struct die_info *); -void dump_die (struct die_info *); +static void dump_die (struct die_info *); -void dump_die_list (struct die_info *); +static void dump_die_list (struct die_info *); -void store_in_ref_table (unsigned int, struct die_info *); +static void store_in_ref_table (unsigned int, struct die_info *); -static void dwarf2_empty_die_ref_table (void); +static void dwarf2_empty_hash_tables (void); static unsigned int dwarf2_get_ref_die_offset (struct attribute *); -struct die_info *follow_die_ref (unsigned int); +static struct die_info *follow_die_ref (unsigned int); static struct type *dwarf2_fundamental_type (struct objfile *, int); @@ -741,14 +808,19 @@ static struct abbrev_info *dwarf_alloc_abbrev (void); static struct die_info *dwarf_alloc_die (void); +static void initialize_cu_func_list (void); + +static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR); + /* 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) { @@ -765,10 +837,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)) { @@ -810,14 +879,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, mainline) - struct objfile *objfile; - int mainline; +dwarf2_build_psymtabs (struct objfile *objfile, int mainline) { /* We definitely need the .debug_info and .debug_abbrev sections */ @@ -832,8 +909,16 @@ dwarf2_build_psymtabs (objfile, 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); } @@ -860,9 +945,7 @@ dwarf2_build_psymtabs (objfile, mainline) .debug_pubnames and .debug_aranges sections. */ static void -dwarf2_build_psymtabs_easy (objfile, mainline) - struct objfile *objfile; - int mainline; +dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) { bfd *abfd = objfile->obfd; char *aranges_buffer, *pubnames_buffer; @@ -875,8 +958,12 @@ dwarf2_build_psymtabs_easy (objfile, 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); @@ -892,45 +979,101 @@ dwarf2_build_psymtabs_easy (objfile, 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, mainline) - struct objfile *objfile; - 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; 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) { @@ -944,7 +1087,7 @@ dwarf2_build_psymtabs_hard (objfile, 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).", @@ -957,8 +1100,8 @@ dwarf2_build_psymtabs_hard (objfile, mainline) 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); @@ -978,7 +1121,9 @@ dwarf2_build_psymtabs_hard (objfile, mainline) DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer; DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size; DWARF_LINE_BUFFER (pst) = dwarf_line_buffer; - baseaddr = ANOFFSET (objfile->section_offsets, 0); + 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; @@ -988,11 +1133,12 @@ dwarf2_build_psymtabs_hard (objfile, 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.highpc = highpc; @@ -1012,7 +1158,8 @@ dwarf2_build_psymtabs_hard (objfile, 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); } @@ -1020,11 +1167,9 @@ dwarf2_build_psymtabs_hard (objfile, 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; @@ -1036,21 +1181,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); *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) { @@ -1063,7 +1207,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; @@ -1076,20 +1220,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. */ 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. */ if (nesting_level == 1) - add_partial_symbol (&pdi, objfile); + add_partial_symbol (&pdi, objfile, cu_header); break; default: break; @@ -1124,9 +1268,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; @@ -1169,7 +1312,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, @@ -1181,7 +1324,7 @@ 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); */ add_psymbol_to_list (pdi->name, strlen (pdi->name), @@ -1233,8 +1376,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) @@ -1261,8 +1403,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; @@ -1281,7 +1422,9 @@ psymtab_to_symtab_1 (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); + 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; @@ -1292,25 +1435,18 @@ psymtab_to_symtab_1 (pst) make_cleanup (really_free_pendings, NULL); /* read in the comp_unit header */ - cu_header.length = read_4_bytes (abfd, info_ptr); - info_ptr += 4; - cu_header.version = read_2_bytes (abfd, info_ptr); - info_ptr += 2; - cu_header.abbrev_offset = read_4_bytes (abfd, info_ptr); - info_ptr += 4; - cu_header.addr_size = read_1_byte (abfd, info_ptr); - info_ptr += 1; + info_ptr = read_comp_unit_head (&cu_header, info_ptr, abfd); /* Read the abbrevs for this compilation unit */ dwarf2_read_abbrevs (abfd, cu_header.abbrev_offset); make_cleanup (dwarf2_empty_abbrev_table, NULL); - dies = read_comp_unit (info_ptr, abfd); + dies = read_comp_unit (info_ptr, abfd, &cu_header); make_cleanup_free_die_list (dies); /* 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)) { @@ -1336,7 +1472,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, @@ -1356,20 +1492,19 @@ 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. @@ -1377,30 +1512,30 @@ process_die (die, objfile) 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); @@ -1410,24 +1545,29 @@ 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; +initialize_cu_func_list (void) +{ + cu_first_fn = cu_last_fn = cu_cached_fn = NULL; +} + +static void +read_file_scope (struct die_info *die, struct objfile *objfile, + const struct comp_unit_head *cu_header) { unsigned int line_offset = 0; CORE_ADDR lowpc = ((CORE_ADDR) -1); @@ -1517,13 +1657,7 @@ read_file_scope (die, objfile) start_symtab (name, comp_dir, lowpc); record_debugformat ("DWARF 2"); - /* Decode line number information if present. */ - attr = dwarf_attr (die, DW_AT_stmt_list); - if (attr) - { - line_offset = DW_UNSND (attr); - dwarf_decode_lines (line_offset, comp_dir, abfd); - } + initialize_cu_func_list (); /* Process all dies in compilation unit. */ if (die->has_children) @@ -1531,16 +1665,44 @@ 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); } } + + /* Decode line number information if present. */ + attr = dwarf_attr (die, DW_AT_stmt_list); + if (attr) + { + line_offset = DW_UNSND (attr); + dwarf_decode_lines (line_offset, comp_dir, abfd, cu_header); + } +} + +static void +add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc) +{ + struct function_range *thisfn; + + thisfn = (struct function_range *) + obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct function_range)); + thisfn->name = name; + thisfn->lowpc = lowpc; + thisfn->highpc = highpc; + thisfn->seen_line = 0; + thisfn->next = NULL; + + if (cu_last_fn == NULL) + cu_first_fn = thisfn; + else + cu_last_fn->next = thisfn; + + cu_last_fn = thisfn; } 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; @@ -1559,6 +1721,9 @@ read_func_scope (die, objfile) lowpc += baseaddr; highpc += baseaddr; + /* Record the function range for dwarf_decode_lines. */ + add_to_cu_func_list (name, lowpc, highpc); + if (objfile->ei.entry_point >= lowpc && objfile->ei.entry_point < highpc) { @@ -1573,7 +1738,7 @@ read_func_scope (die, objfile) attr = dwarf_attr (die, DW_AT_frame_base); if (attr) { - CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile); + CORE_ADDR addr = decode_locdesc (DW_BLOCK (attr), objfile, cu_header); if (isderef) complain (&dwarf2_unsupported_at_frame_base, name); else if (isreg) @@ -1588,7 +1753,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) @@ -1596,7 +1761,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); } } @@ -1612,9 +1777,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; @@ -1632,7 +1796,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); } } @@ -1650,11 +1814,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; @@ -1693,10 +1854,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; @@ -1705,7 +1865,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; @@ -1733,7 +1893,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); @@ -1751,7 +1911,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; @@ -1831,7 +1991,7 @@ dwarf2_add_field (fip, die, objfile) SET_FIELD_PHYSNAME (*fp, obsavestring (physname, strlen (physname), &objfile->type_obstack)); - FIELD_TYPE (*fp) = die_type (die, objfile); + FIELD_TYPE (*fp) = die_type (die, objfile, cu_header); FIELD_NAME (*fp) = obsavestring (fieldname, strlen (fieldname), &objfile->type_obstack); } @@ -1840,9 +2000,10 @@ dwarf2_add_field (fip, die, objfile) /* 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++; } @@ -1851,10 +2012,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; @@ -1940,11 +2099,9 @@ dwarf2_attach_fields_to_type (fip, type, objfile) /* 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; @@ -1995,7 +2152,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; @@ -2020,7 +2177,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); @@ -2041,7 +2198,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. */ @@ -2061,19 +2218,22 @@ dwarf2_add_member_fn (fip, die, type, objfile) } } + /* 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; @@ -2120,9 +2280,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; @@ -2182,27 +2341,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); } @@ -2220,7 +2379,7 @@ read_structure_scope (die, objfile) 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) @@ -2256,7 +2415,7 @@ read_structure_scope (die, objfile) } } - new_symbol (die, type, objfile); + new_symbol (die, type, objfile, cu_header); do_cleanups (back_to); } @@ -2266,7 +2425,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 @@ -2279,9 +2438,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; @@ -2321,14 +2479,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; @@ -2359,13 +2517,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 @@ -2373,9 +2531,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; @@ -2391,7 +2548,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. */ @@ -2420,7 +2577,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) { @@ -2431,7 +2588,8 @@ read_array_type (die, objfile) 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_data4 + || attr->form == DW_FORM_data8) { low = DW_UNSND (attr); } @@ -2457,7 +2615,8 @@ read_array_type (die, objfile) 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_data4 + || attr->form == DW_FORM_data8) { high = DW_UNSND (attr); } @@ -2503,6 +2662,16 @@ read_array_type (die, objfile) while (ndim-- > 0) type = create_array_type (NULL, type, range_types[ndim]); + /* Understand Dwarf2 support for vector types (like they occur on + the PowerPC w/ AltiVec). Gcc just adds another attribute to the + array type. This is not part of the Dwarf2/3 standard yet, but a + custom vendor extension. The main difference between a regular + array and the vector variant is that vectors are passed by value + to functions. */ + attr = dwarf_attr (die, DW_AT_GNU_vector); + if (attr) + TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR; + do_cleanups (back_to); /* Install the type in the die. */ @@ -2512,9 +2681,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; @@ -2524,19 +2692,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); @@ -2548,9 +2716,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; @@ -2560,7 +2727,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) { @@ -2568,7 +2735,7 @@ read_tag_pointer_type (die, objfile) } else { - TYPE_LENGTH (type) = address_size; + TYPE_LENGTH (type) = cu_header->addr_size; } die->type = type; } @@ -2577,9 +2744,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; @@ -2591,8 +2757,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; @@ -2602,9 +2768,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; @@ -2614,7 +2779,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) { @@ -2622,37 +2787,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 @@ -2661,9 +2828,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; @@ -2681,12 +2846,30 @@ 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; } @@ -2702,9 +2885,8 @@ read_tag_string_type (die, objfile) */ 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 */ @@ -2715,7 +2897,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. */ @@ -2763,7 +2945,8 @@ read_subroutine_type (die, objfile) 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); @@ -2774,30 +2957,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); } } @@ -2805,9 +2979,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; @@ -2833,18 +3005,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; @@ -2857,16 +3029,28 @@ 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); + else if (encoding == DW_ATE_complex_float) + { + if (size == 32) + TYPE_TARGET_TYPE (type) + = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT); + else if (size == 16) + TYPE_TARGET_TYPE (type) + = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT); + else if (size == 8) + TYPE_TARGET_TYPE (type) + = dwarf2_fundamental_type (objfile, FT_FLOAT); + } } else { @@ -2877,24 +3061,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++; @@ -2926,8 +3110,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; @@ -2935,8 +3118,8 @@ free_die_list (dies) while (die) { next = die->next; - free (die->attrs); - free (die); + xfree (die->attrs); + xfree (die); die = next; } } @@ -2957,11 +3140,9 @@ make_cleanup_free_die_list (struct die_info *dies) /* Read the contents of the section at OFFSET and of size SIZE from the object file specified by OBJFILE into the psymbol_obstack and return it. */ -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; @@ -2971,7 +3152,7 @@ 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'", @@ -2986,9 +3167,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; @@ -3061,8 +3240,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; @@ -3074,8 +3252,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; @@ -3085,8 +3263,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; @@ -3107,11 +3284,8 @@ 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; @@ -3122,7 +3296,6 @@ read_partial_die (part_die, abfd, info_ptr, has_pc_info) 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) @@ -3140,7 +3313,8 @@ 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. */ @@ -3207,7 +3381,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; @@ -3230,7 +3404,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; } @@ -3238,10 +3412,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; @@ -3279,33 +3451,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 (); @@ -3339,6 +3508,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); @@ -3383,138 +3557,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 2: - retval = bfd_get_16 (abfd, (bfd_byte *) buf); - break; 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 (); + internal_error (__FILE__, __LINE__, + "read_offset: bad switch"); } 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; @@ -3522,34 +3787,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; @@ -3562,7 +3830,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; @@ -3573,13 +3841,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; @@ -3593,7 +3858,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) { @@ -3609,8 +3874,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) { @@ -3623,11 +3887,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: @@ -3643,9 +3911,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; @@ -3702,11 +3968,54 @@ struct directories char **dirs; }; +/* This function exists to work around a bug in certain compilers + (particularly GCC 2.95), in which the first line number marker of a + function does not show up until after the prologue, right before + the second line number marker. This function shifts ADDRESS down + to the beginning of the function if necessary, and is called on + addresses passed to record_line. */ + +static CORE_ADDR +check_cu_functions (CORE_ADDR address) +{ + struct function_range *fn; + + /* Find the function_range containing address. */ + if (!cu_first_fn) + return address; + + if (!cu_cached_fn) + cu_cached_fn = cu_first_fn; + + fn = cu_cached_fn; + while (fn) + if (fn->lowpc <= address && fn->highpc > address) + goto found; + else + fn = fn->next; + + fn = cu_first_fn; + while (fn && fn != cu_cached_fn) + if (fn->lowpc <= address && fn->highpc > address) + goto found; + else + fn = fn->next; + + return address; + + found: + if (fn->seen_line) + return address; + if (address != fn->lowpc) + complain (&dwarf2_misplaced_line_number, + (unsigned long) address, fn->name); + fn->seen_line = 1; + return fn->lowpc; +} + 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; @@ -3737,13 +4046,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); @@ -3836,7 +4145,19 @@ dwarf_decode_lines (offset, comp_dir, abfd) { 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 */ + address = check_cu_functions (address); + record_line (current_subfile, line, address); + basic_block = 1; + } + else switch (op_code) { case DW_LNS_extended_op: line_ptr += 1; /* ignore length */ @@ -3846,16 +4167,12 @@ dwarf_decode_lines (offset, comp_dir, abfd) { case DW_LNE_end_sequence: end_sequence = 1; - /* 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. */ + record_line (current_subfile, 0, address); 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); @@ -3887,6 +4204,7 @@ dwarf_decode_lines (offset, comp_dir, abfd) } break; case DW_LNS_copy: + address = check_cu_functions (address); record_line (current_subfile, line, address); basic_block = 0; break; @@ -3933,14 +4251,15 @@ dwarf_decode_lines (offset, comp_dir, abfd) 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; + } + } } } } @@ -3960,37 +4279,35 @@ done: DW_AT_name: /srcdir/list0.c DW_AT_comp_dir: /compdir - files.files[0].name: list0.h + files.files[0].name: list0.h files.files[0].dir: /srcdir - files.files[1].name: list0.c + 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); } @@ -4002,10 +4319,8 @@ dwarf2_start_subfile (filename, dirname) 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; @@ -4030,7 +4345,7 @@ new_symbol (die, type, objfile) 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) { @@ -4081,7 +4396,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); @@ -4096,7 +4411,7 @@ 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 @@ -4108,7 +4423,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 @@ -4117,7 +4435,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) { @@ -4126,11 +4444,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) { @@ -4138,8 +4458,11 @@ 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; } } } @@ -4164,10 +4487,13 @@ 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) { @@ -4180,7 +4506,7 @@ new_symbol (die, type, objfile) else { SYMBOL_CLASS (sym) = LOC_BASEREG_ARG; - SYMBOL_BASEREG (sym) = basereg; + SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg); } } else @@ -4191,7 +4517,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; @@ -4236,7 +4562,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; @@ -4255,22 +4581,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: @@ -4350,9 +4676,8 @@ dwarf2_const_value_data (struct attribute *attr, /* Return the type of the die in question using its DW_AT_type attribute. */ static struct type * -die_type (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; @@ -4375,7 +4700,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); @@ -4388,9 +4713,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; @@ -4407,7 +4731,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) { @@ -4420,9 +4744,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; @@ -4439,9 +4761,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) { @@ -4449,7 +4770,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); @@ -4460,47 +4781,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); @@ -4512,10 +4832,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. */ @@ -4592,8 +4909,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; @@ -4626,9 +4942,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; @@ -4672,8 +4987,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; @@ -4689,8 +5003,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) { @@ -4806,8 +5119,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) { @@ -4965,6 +5277,8 @@ dwarf_attr_name (attr) return "DW_AT_body_begin"; case DW_AT_body_end: return "DW_AT_body_end"; + case DW_AT_GNU_vector: + return "DW_AT_GNU_vector"; default: return "DW_AT_"; } @@ -4973,8 +5287,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) { @@ -5028,8 +5341,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) { @@ -5329,8 +5641,7 @@ dwarf_stack_op_name (op) } static char * -dwarf_bool_name (mybool) - unsigned mybool; +dwarf_bool_name (unsigned mybool) { if (mybool) return "TRUE"; @@ -5341,8 +5652,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) { @@ -5371,8 +5681,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) { @@ -5412,81 +5721,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_"; } } #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]) : ""); 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.", + 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) { @@ -5495,10 +5827,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; @@ -5511,14 +5841,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; @@ -5530,6 +5859,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; @@ -5539,9 +5869,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; @@ -5560,9 +5889,7 @@ follow_die_ref (offset) } static struct type * -dwarf2_fundamental_type (objfile, typeid) - struct objfile *objfile; - int typeid; +dwarf2_fundamental_type (struct objfile *objfile, int typeid) { if (typeid < 0 || typeid >= FT_NUM_MEMBERS) { @@ -5611,9 +5938,8 @@ dwarf2_fundamental_type (objfile, typeid) 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; @@ -5638,6 +5964,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: @@ -5750,8 +6111,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: @@ -5795,6 +6157,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--; @@ -5806,7 +6173,7 @@ decode_locdesc (blk, objfile) break; case DW_OP_minus: - stack[stacki - 1] = stack[stacki] - stack[stacki - 1]; + stack[stacki - 1] -= stack[stacki]; stacki--; break; @@ -5830,14 +6197,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; @@ -5847,7 +6213,7 @@ dwarf_alloc_block () } static struct abbrev_info * -dwarf_alloc_abbrev () +dwarf_alloc_abbrev (void) { struct abbrev_info *abbrev; @@ -5857,7 +6223,7 @@ dwarf_alloc_abbrev () } static struct die_info * -dwarf_alloc_die () +dwarf_alloc_die (void) { struct die_info *die;