X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=8088830fca53d0fc895540f80161039ca1805367;hb=0b92b5bb46877299511949f5a437883ddb7dd60e;hp=9c24f8ebdd02c67608f1b30d7fb9b79731d6f6c2;hpb=27aa8d6aa032b25160328cd92c78c4f8158fa0b7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 9c24f8ebdd..8088830fca 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1,7 +1,7 @@ /* DWARF 2 debugging format support for GDB. Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006, 2007, 2008, 2009 + 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, @@ -31,7 +31,7 @@ #include "symtab.h" #include "gdbtypes.h" #include "objfiles.h" -#include "elf/dwarf2.h" +#include "dwarf2.h" #include "buildsym.h" #include "demangle.h" #include "expression.h" @@ -46,6 +46,7 @@ #include "hashtab.h" #include "command.h" #include "gdbcmd.h" +#include "block.h" #include "addrmap.h" #include @@ -57,6 +58,9 @@ #endif #ifdef HAVE_MMAP #include +#ifndef MAP_FAILED +#define MAP_FAILED ((void *) -1) +#endif #endif #if 0 @@ -163,6 +167,7 @@ struct dwarf2_per_objfile struct dwarf2_section_info macinfo; struct dwarf2_section_info str; struct dwarf2_section_info ranges; + struct dwarf2_section_info types; struct dwarf2_section_info frame; struct dwarf2_section_info eh_frame; @@ -177,6 +182,10 @@ struct dwarf2_per_objfile they can be freed later. */ struct dwarf2_per_cu_data *read_in_chain; + /* A table mapping .debug_types signatures to its signatured_type entry. + This is NULL if the .debug_types section hasn't been read in yet. */ + htab_t signatured_types; + /* A flag indicating wether this objfile has a section loaded at a VMA of 0. */ int has_section_at_zero; @@ -198,6 +207,7 @@ static struct dwarf2_per_objfile *dwarf2_per_objfile; #define MACINFO_SECTION "debug_macinfo" #define STR_SECTION "debug_str" #define RANGES_SECTION "debug_ranges" +#define TYPES_SECTION "debug_types" #define FRAME_SECTION "debug_frame" #define EH_FRAME_SECTION "eh_frame" @@ -276,9 +286,6 @@ struct dwarf2_cu /* Hash table holding all the loaded partial DIEs. */ htab_t partial_dies; - /* `.debug_ranges' offset for this `DW_TAG_compile_unit' DIE. */ - unsigned int ranges_offset; - /* Storage for things with the same lifetime as this read-in compilation unit, including partial DIEs. */ struct obstack comp_unit_obstack; @@ -326,9 +333,6 @@ struct dwarf2_cu DIEs for namespaces, we don't need to try to infer them from mangled names. */ unsigned int has_namespace_info : 1; - - /* Field `ranges_offset' is filled in; flag as the value may be zero. */ - unsigned int has_ranges_offset : 1; }; /* Persistent data held for a compilation unit, even when not @@ -339,13 +343,13 @@ struct dwarf2_cu struct dwarf2_per_cu_data { - /* The start offset and length of this compilation unit. 2**30-1 + /* The start offset and length of this compilation unit. 2**29-1 bytes should suffice to store the length of any compilation unit - if it doesn't, GDB will fall over anyway. NOTE: Unlike comp_unit_head.length, this length includes initial_length_size. */ unsigned int offset; - unsigned int length : 30; + unsigned int length : 29; /* Flag indicating this compilation unit will be read in before any of the current compilation units are processed. */ @@ -357,6 +361,10 @@ struct dwarf2_per_cu_data hash table and don't find it. */ unsigned int load_all_dies : 1; + /* Non-zero if this CU is from .debug_types. + Otherwise it's from .debug_info. */ + unsigned int from_debug_types : 1; + /* Set iff currently read in. */ struct dwarf2_cu *cu; @@ -372,6 +380,41 @@ struct dwarf2_per_cu_data struct partial_symtab *psymtab; }; +/* Entry in the signatured_types hash table. */ + +struct signatured_type +{ + ULONGEST signature; + + /* Offset in .debug_types of the TU (type_unit) for this type. */ + unsigned int offset; + + /* Offset in .debug_types of the type defined by this TU. */ + unsigned int type_offset; + + /* The CU(/TU) of this type. */ + struct dwarf2_per_cu_data per_cu; +}; + +/* Struct used to pass misc. parameters to read_die_and_children, et. al. + which are used for both .debug_info and .debug_types dies. + All parameters here are unchanging for the life of the call. + This struct exists to abstract away the constant parameters of + die reading. */ + +struct die_reader_specs +{ + /* The bfd of this objfile. */ + bfd* abfd; + + /* The CU of the DIE we are parsing. */ + struct dwarf2_cu *cu; + + /* Pointer to start of section buffer. + This is either the start of .debug_info or .debug_types. */ + const gdb_byte *buffer; +}; + /* The line number information for a compilation unit (found in the .debug_line section) begins with a "statement program header", which contains the following information. */ @@ -428,17 +471,12 @@ struct partial_die_info /* DWARF-2 tag for this DIE. */ ENUM_BITFIELD(dwarf_tag) tag : 16; - /* Language code associated with this DIE. This is only used - for the compilation unit DIE. */ - unsigned int language : 8; - /* Assorted flags describing the data found in this DIE. */ unsigned int has_children : 1; unsigned int is_external : 1; unsigned int is_declaration : 1; unsigned int has_type : 1; unsigned int has_specification : 1; - unsigned int has_stmt_list : 1; unsigned int has_pc_info : 1; /* Flag set if the SCOPE field of this structure has been @@ -452,7 +490,6 @@ struct partial_die_info sometimes DW_TAG_MIPS_linkage_name or a string computed in some other fashion. */ char *name; - char *dirname; /* The scope to prepend to our children. This is generally allocated on the comp_unit_obstack, so will disappear @@ -466,7 +503,7 @@ struct partial_die_info CORE_ADDR lowpc; CORE_ADDR highpc; - /* Pointer into the info_buffer pointing at the target of + /* Pointer into the info_buffer (or types_buffer) pointing at the target of DW_AT_sibling, if any. */ gdb_byte *sibling; @@ -475,9 +512,6 @@ struct partial_die_info DW_AT_extension). */ unsigned int spec_offset; - /* If HAS_STMT_LIST, the offset of the Line Number Information data. */ - unsigned int line_offset; - /* Pointers to this DIE's parent, first child, and next sibling, if any. */ struct partial_die_info *die_parent, *die_child, *die_sibling; @@ -500,27 +534,25 @@ struct attr_abbrev ENUM_BITFIELD(dwarf_form) form : 16; }; -/* Additional GDB-specific attribute forms. */ -enum - { - /* A string which has been updated to GDB's internal - representation (e.g. converted to canonical form) and does not - need to be updated again. */ - GDB_FORM_cached_string = 0xff - }; - /* Attributes have a name and a value */ struct attribute { ENUM_BITFIELD(dwarf_attribute) name : 16; - ENUM_BITFIELD(dwarf_form) form : 16; + ENUM_BITFIELD(dwarf_form) form : 15; + + /* Has DW_STRING already been updated by dwarf2_canonicalize_name? This + field should be in u.str (existing only for DW_STRING) but it is kept + here for better struct attribute alignment. */ + unsigned int string_is_canonical : 1; + union { char *str; struct dwarf_block *blk; - unsigned long unsnd; - long int snd; + ULONGEST unsnd; + LONGEST snd; CORE_ADDR addr; + struct signatured_type *signatured_type; } u; }; @@ -537,7 +569,7 @@ struct die_info /* Abbrev number */ unsigned int abbrev; - /* Offset in .debug_info section */ + /* Offset in .debug_info or .debug_types section. */ unsigned int offset; /* The dies in a compilation unit form an n-ary tree. PARENT @@ -566,10 +598,12 @@ struct function_range /* Get at parts of an attribute structure */ #define DW_STRING(attr) ((attr)->u.str) +#define DW_STRING_IS_CANONICAL(attr) ((attr)->string_is_canonical) #define DW_UNSND(attr) ((attr)->u.unsnd) #define DW_BLOCK(attr) ((attr)->u.blk) #define DW_SND(attr) ((attr)->u.snd) #define DW_ADDR(attr) ((attr)->u.addr) +#define DW_SIGNATURED_TYPE(attr) ((attr)->u.signatured_type) /* Blocks are a bunch of untyped bytes. */ struct dwarf_block @@ -608,9 +642,9 @@ struct field_info int virtuality; struct field field; } - *fields; + *fields, *baseclasses; - /* Number of fields. */ + /* Number of fields (including baseclasses). */ int nfields; /* Number of baseclasses. */ @@ -735,17 +769,17 @@ dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2) static void dwarf2_locate_sections (bfd *, asection *, void *); #if 0 -static void dwarf2_build_psymtabs_easy (struct objfile *, int); +static void dwarf2_build_psymtabs_easy (struct objfile *); #endif static void dwarf2_create_include_psymtab (char *, struct partial_symtab *, struct objfile *); static void dwarf2_build_include_psymtabs (struct dwarf2_cu *, - struct partial_die_info *, + struct die_info *, struct partial_symtab *); -static void dwarf2_build_psymtabs_hard (struct objfile *, int); +static void dwarf2_build_psymtabs_hard (struct objfile *); static void scan_partial_symbols (struct partial_die_info *, CORE_ADDR *, CORE_ADDR *, @@ -772,9 +806,8 @@ static void add_partial_subprogram (struct partial_die_info *pdi, int need_pc, struct dwarf2_cu *cu); static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi, - gdb_byte *info_ptr, - bfd *abfd, - struct dwarf2_cu *cu); + gdb_byte *buffer, gdb_byte *info_ptr, + bfd *abfd, struct dwarf2_cu *cu); static void dwarf2_psymtab_to_symtab (struct partial_symtab *); @@ -790,12 +823,15 @@ static struct abbrev_info *peek_die_abbrev (gdb_byte *, unsigned int *, static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int, struct dwarf2_cu *); -static struct partial_die_info *load_partial_dies (bfd *, gdb_byte *, int, - struct dwarf2_cu *); +static struct partial_die_info *load_partial_dies (bfd *, + gdb_byte *, gdb_byte *, + int, struct dwarf2_cu *); static gdb_byte *read_partial_die (struct partial_die_info *, - struct abbrev_info *abbrev, unsigned int, - bfd *, gdb_byte *, struct dwarf2_cu *); + struct abbrev_info *abbrev, + unsigned int, bfd *, + gdb_byte *, gdb_byte *, + struct dwarf2_cu *); static struct partial_die_info *find_partial_die (unsigned int, struct dwarf2_cu *); @@ -803,9 +839,6 @@ static struct partial_die_info *find_partial_die (unsigned int, static void fixup_partial_die (struct partial_die_info *, struct dwarf2_cu *); -static gdb_byte *read_full_die (struct die_info **, bfd *, gdb_byte *, - struct dwarf2_cu *, int *); - static gdb_byte *read_attribute (struct attribute *, struct attr_abbrev *, bfd *, gdb_byte *, struct dwarf2_cu *); @@ -820,7 +853,7 @@ static unsigned int read_2_bytes (bfd *, gdb_byte *); static unsigned int read_4_bytes (bfd *, gdb_byte *); -static unsigned long read_8_bytes (bfd *, gdb_byte *); +static ULONGEST read_8_bytes (bfd *, gdb_byte *); static CORE_ADDR read_address (bfd *, gdb_byte *ptr, struct dwarf2_cu *, unsigned int *); @@ -855,6 +888,10 @@ static void set_cu_language (unsigned int, struct dwarf2_cu *); static struct attribute *dwarf2_attr (struct die_info *, unsigned int, struct dwarf2_cu *); +static struct attribute *dwarf2_attr_no_follow (struct die_info *, + unsigned int, + struct dwarf2_cu *); + static int dwarf2_flag_true_p (struct die_info *die, unsigned name, struct dwarf2_cu *cu); @@ -889,6 +926,13 @@ static void dwarf2_const_value_data (struct attribute *attr, static struct type *die_type (struct die_info *, struct dwarf2_cu *); +static int need_gnat_info (struct dwarf2_cu *); + +static struct type *die_descriptive_type (struct die_info *, struct dwarf2_cu *); + +static void set_descriptive_type (struct type *, struct die_info *, + struct dwarf2_cu *); + static struct type *die_containing_type (struct die_info *, struct dwarf2_cu *); @@ -905,6 +949,8 @@ static char *typename_concat (struct obstack *, static void read_file_scope (struct die_info *, struct dwarf2_cu *); +static void read_type_unit_scope (struct die_info *, struct dwarf2_cu *); + static void read_func_scope (struct die_info *, struct dwarf2_cu *); static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *); @@ -913,7 +959,8 @@ static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *, struct partial_symtab *); static int dwarf2_get_pc_bounds (struct die_info *, - CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *); + CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *, + struct partial_symtab *); static void get_scope_pc_bounds (struct die_info *, CORE_ADDR *, CORE_ADDR *, @@ -958,23 +1005,27 @@ static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *); static enum dwarf_array_dim_ordering read_array_order (struct die_info *, struct dwarf2_cu *); -static struct die_info *read_comp_unit (gdb_byte *, bfd *, struct dwarf2_cu *); +static struct die_info *read_comp_unit (gdb_byte *, struct dwarf2_cu *); -static struct die_info *read_die_and_children_1 (gdb_byte *info_ptr, bfd *abfd, - struct dwarf2_cu *, +static struct die_info *read_die_and_children_1 (const struct die_reader_specs *reader, + gdb_byte *info_ptr, gdb_byte **new_info_ptr, struct die_info *parent); -static struct die_info *read_die_and_children (gdb_byte *info_ptr, bfd *abfd, - struct dwarf2_cu *, +static struct die_info *read_die_and_children (const struct die_reader_specs *reader, + gdb_byte *info_ptr, gdb_byte **new_info_ptr, struct die_info *parent); -static struct die_info *read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd, - struct dwarf2_cu *, +static struct die_info *read_die_and_siblings (const struct die_reader_specs *reader, + gdb_byte *info_ptr, gdb_byte **new_info_ptr, struct die_info *parent); +static gdb_byte *read_full_die (const struct die_reader_specs *reader, + struct die_info **, gdb_byte *, + int *); + static void process_die (struct die_info *, struct dwarf2_cu *); static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *); @@ -1017,14 +1068,30 @@ static void dump_die_1 (struct ui_file *, int level, int max_level, static void store_in_ref_table (struct die_info *, struct dwarf2_cu *); +static int is_ref_attr (struct attribute *); + static unsigned int dwarf2_get_ref_die_offset (struct attribute *); -static int dwarf2_get_attr_constant_value (struct attribute *, int); +static LONGEST dwarf2_get_attr_constant_value (struct attribute *, int); + +static struct die_info *follow_die_ref_or_sig (struct die_info *, + struct attribute *, + struct dwarf2_cu **); static struct die_info *follow_die_ref (struct die_info *, struct attribute *, struct dwarf2_cu **); +static struct die_info *follow_die_sig (struct die_info *, + struct attribute *, + struct dwarf2_cu **); + +static void read_signatured_type_at_offset (struct objfile *objfile, + unsigned int offset); + +static void read_signatured_type (struct objfile *, + struct signatured_type *type_sig); + /* memory allocation interface */ static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *); @@ -1051,8 +1118,9 @@ static void dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, struct dwarf2_cu *cu); -static gdb_byte *skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev, - struct dwarf2_cu *cu); +static gdb_byte *skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr, + struct abbrev_info *abbrev, + struct dwarf2_cu *cu); static void free_stack_comp_unit (void *); @@ -1066,6 +1134,8 @@ static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit static struct dwarf2_per_cu_data *dwarf2_find_comp_unit (unsigned int offset, struct objfile *objfile); +static struct dwarf2_cu *alloc_one_comp_unit (struct objfile *objfile); + static void free_one_comp_unit (void *); static void free_cached_comp_units (void *); @@ -1079,8 +1149,8 @@ static struct type *set_die_type (struct die_info *, struct type *, static void create_all_comp_units (struct objfile *); -static struct dwarf2_cu *load_full_comp_unit (struct dwarf2_per_cu_data *, - struct objfile *); +static void load_full_comp_unit (struct dwarf2_per_cu_data *, + struct objfile *); static void process_full_comp_unit (struct dwarf2_per_cu_data *); @@ -1189,6 +1259,11 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr) dwarf2_per_objfile->ranges.asection = sectp; dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp); } + else if (section_is_p (sectp->name, TYPES_SECTION)) + { + dwarf2_per_objfile->types.asection = sectp; + dwarf2_per_objfile->types.size = bfd_get_section_size (sectp); + } if ((bfd_get_section_flags (abfd, sectp) & SEC_LOAD) && bfd_section_vma (abfd, sectp) == 0) @@ -1380,7 +1455,7 @@ dwarf2_get_section_info (struct objfile *objfile, const char *section_name, /* Build a partial symbol table. */ void -dwarf2_build_psymtabs (struct objfile *objfile, int mainline) +dwarf2_build_psymtabs (struct objfile *objfile) { dwarf2_read_section (objfile, &dwarf2_per_objfile->info); dwarf2_read_section (objfile, &dwarf2_per_objfile->abbrev); @@ -1388,13 +1463,12 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline) dwarf2_read_section (objfile, &dwarf2_per_objfile->str); dwarf2_read_section (objfile, &dwarf2_per_objfile->macinfo); dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges); + dwarf2_read_section (objfile, &dwarf2_per_objfile->types); dwarf2_read_section (objfile, &dwarf2_per_objfile->loc); dwarf2_read_section (objfile, &dwarf2_per_objfile->eh_frame); dwarf2_read_section (objfile, &dwarf2_per_objfile->frame); - if (mainline - || (objfile->global_psymbols.size == 0 - && objfile->static_psymbols.size == 0)) + if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0) { init_psymbol_list (objfile, 1024); } @@ -1405,14 +1479,14 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline) /* Things are significantly easier if we have .debug_aranges and .debug_pubnames sections */ - dwarf2_build_psymtabs_easy (objfile, mainline); + dwarf2_build_psymtabs_easy (objfile); } else #endif /* only test this case for now */ { /* In this case we have to work a bit harder */ - dwarf2_build_psymtabs_hard (objfile, mainline); + dwarf2_build_psymtabs_hard (objfile); } } @@ -1421,7 +1495,7 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline) .debug_pubnames and .debug_aranges sections. */ static void -dwarf2_build_psymtabs_easy (struct objfile *objfile, int mainline) +dwarf2_build_psymtabs_easy (struct objfile *objfile) { bfd *abfd = objfile->obfd; char *aranges_buffer, *pubnames_buffer; @@ -1463,8 +1537,9 @@ offset_in_cu_p (const struct comp_unit_head *cu_header, unsigned int offset) return (offset >= bottom && offset < top); } -/* Read in the comp unit header information from the debug_info at - info_ptr. */ +/* Read in the comp unit header information from the debug_info at info_ptr. + NOTE: This leaves members offset, first_die_offset to be filled in + by the caller. */ static gdb_byte * read_comp_unit_head (struct comp_unit_head *cu_header, @@ -1495,6 +1570,7 @@ read_comp_unit_head (struct comp_unit_head *cu_header, static gdb_byte * partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr, + gdb_byte *buffer, unsigned int buffer_size, bfd *abfd) { gdb_byte *beg_of_comp_unit = info_ptr; @@ -1510,20 +1586,43 @@ partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr, error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header " "(offset 0x%lx + 6) [in module %s]"), (long) header->abbrev_offset, - (long) (beg_of_comp_unit - dwarf2_per_objfile->info.buffer), + (long) (beg_of_comp_unit - buffer), bfd_get_filename (abfd)); if (beg_of_comp_unit + header->length + header->initial_length_size - > dwarf2_per_objfile->info.buffer + dwarf2_per_objfile->info.size) + > buffer + buffer_size) error (_("Dwarf Error: bad length (0x%lx) in compilation unit header " "(offset 0x%lx + 0) [in module %s]"), (long) header->length, - (long) (beg_of_comp_unit - dwarf2_per_objfile->info.buffer), + (long) (beg_of_comp_unit - buffer), bfd_get_filename (abfd)); return info_ptr; } +/* Read in the types comp unit header information from .debug_types entry at + types_ptr. The result is a pointer to one past the end of the header. */ + +static gdb_byte * +read_type_comp_unit_head (struct comp_unit_head *cu_header, + ULONGEST *signature, + gdb_byte *types_ptr, bfd *abfd) +{ + unsigned int bytes_read; + gdb_byte *initial_types_ptr = types_ptr; + + cu_header->offset = types_ptr - dwarf2_per_objfile->types.buffer; + + types_ptr = read_comp_unit_head (cu_header, types_ptr, abfd); + + *signature = read_8_bytes (abfd, types_ptr); + types_ptr += 8; + types_ptr += cu_header->offset_size; + cu_header->first_die_offset = types_ptr - initial_types_ptr; + + return types_ptr; +} + /* Allocate a new partial symtab for file named NAME and mark this new partial symtab as being an include of PST. */ @@ -1559,22 +1658,24 @@ dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst, /* Read the Line Number Program data and extract the list of files included by the source file represented by PST. Build an include - partial symtab for each of these included files. - - This procedure assumes that there *is* a Line Number Program in - the given CU. Callers should check that PDI->HAS_STMT_LIST is set - before calling this procedure. */ + partial symtab for each of these included files. */ static void dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, - struct partial_die_info *pdi, + struct die_info *die, struct partial_symtab *pst) { struct objfile *objfile = cu->objfile; bfd *abfd = objfile->obfd; - struct line_header *lh; + struct line_header *lh = NULL; + struct attribute *attr; - lh = dwarf_decode_line_header (pdi->line_offset, abfd, cu); + attr = dwarf2_attr (die, DW_AT_stmt_list, cu); + if (attr) + { + unsigned int line_offset = DW_UNSND (attr); + lh = dwarf_decode_line_header (line_offset, abfd, cu); + } if (lh == NULL) return; /* No linetable, so no includes. */ @@ -1583,204 +1684,443 @@ dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, free_line_header (lh); } +static hashval_t +hash_type_signature (const void *item) +{ + const struct signatured_type *type_sig = item; + /* This drops the top 32 bits of the signature, but is ok for a hash. */ + return type_sig->signature; +} -/* Build the partial symbol table by doing a quick pass through the - .debug_info and .debug_abbrev sections. */ +static int +eq_type_signature (const void *item_lhs, const void *item_rhs) +{ + const struct signatured_type *lhs = item_lhs; + const struct signatured_type *rhs = item_rhs; + return lhs->signature == rhs->signature; +} + +/* Create the hash table of all entries in the .debug_types section. + The result is zero if there is an error (e.g. missing .debug_types section), + otherwise non-zero. */ + +static int +create_debug_types_hash_table (struct objfile *objfile) +{ + gdb_byte *info_ptr = dwarf2_per_objfile->types.buffer; + htab_t types_htab; + + if (info_ptr == NULL) + { + dwarf2_per_objfile->signatured_types = NULL; + return 0; + } + + types_htab = htab_create_alloc_ex (41, + hash_type_signature, + eq_type_signature, + NULL, + &objfile->objfile_obstack, + hashtab_obstack_allocate, + dummy_obstack_deallocate); + + if (dwarf2_die_debug) + fprintf_unfiltered (gdb_stdlog, "Signatured types:\n"); + + while (info_ptr < dwarf2_per_objfile->types.buffer + dwarf2_per_objfile->types.size) + { + unsigned int offset; + unsigned int offset_size; + unsigned int type_offset; + unsigned int length, initial_length_size; + unsigned short version; + ULONGEST signature; + struct signatured_type *type_sig; + void **slot; + gdb_byte *ptr = info_ptr; + + offset = ptr - dwarf2_per_objfile->types.buffer; + + /* We need to read the type's signature in order to build the hash + table, but we don't need to read anything else just yet. */ + + /* Sanity check to ensure entire cu is present. */ + length = read_initial_length (objfile->obfd, ptr, &initial_length_size); + if (ptr + length + initial_length_size + > dwarf2_per_objfile->types.buffer + dwarf2_per_objfile->types.size) + { + complaint (&symfile_complaints, + _("debug type entry runs off end of `.debug_types' section, ignored")); + break; + } + + offset_size = initial_length_size == 4 ? 4 : 8; + ptr += initial_length_size; + version = bfd_get_16 (objfile->obfd, ptr); + ptr += 2; + ptr += offset_size; /* abbrev offset */ + ptr += 1; /* address size */ + signature = bfd_get_64 (objfile->obfd, ptr); + ptr += 8; + type_offset = read_offset_1 (objfile->obfd, ptr, offset_size); + + type_sig = obstack_alloc (&objfile->objfile_obstack, sizeof (*type_sig)); + memset (type_sig, 0, sizeof (*type_sig)); + type_sig->signature = signature; + type_sig->offset = offset; + type_sig->type_offset = type_offset; + + slot = htab_find_slot (types_htab, type_sig, INSERT); + gdb_assert (slot != NULL); + *slot = type_sig; + + if (dwarf2_die_debug) + fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n", + offset, phex (signature, sizeof (signature))); + + info_ptr = info_ptr + initial_length_size + length; + } + + dwarf2_per_objfile->signatured_types = types_htab; + + return 1; +} + +/* Lookup a signature based type. + Returns NULL if SIG is not present in the table. */ + +static struct signatured_type * +lookup_signatured_type (struct objfile *objfile, ULONGEST sig) +{ + struct signatured_type find_entry, *entry; + + if (dwarf2_per_objfile->signatured_types == NULL) + { + complaint (&symfile_complaints, + _("missing `.debug_types' section for DW_FORM_sig8 die")); + return 0; + } + + find_entry.signature = sig; + entry = htab_find (dwarf2_per_objfile->signatured_types, &find_entry); + return entry; +} + +/* Initialize a die_reader_specs struct from a dwarf2_cu struct. */ static void -dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) +init_cu_die_reader (struct die_reader_specs *reader, + struct dwarf2_cu *cu) +{ + reader->abfd = cu->objfile->obfd; + reader->cu = cu; + if (cu->per_cu->from_debug_types) + reader->buffer = dwarf2_per_objfile->types.buffer; + else + reader->buffer = dwarf2_per_objfile->info.buffer; +} + +/* Find the base address of the compilation unit for range lists and + location lists. It will normally be specified by DW_AT_low_pc. + In DWARF-3 draft 4, the base address could be overridden by + DW_AT_entry_pc. It's been removed, but GCC still uses this for + compilation units with discontinuous ranges. */ + +static void +dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu) +{ + struct attribute *attr; + + cu->base_known = 0; + cu->base_address = 0; + + attr = dwarf2_attr (die, DW_AT_entry_pc, cu); + if (attr) + { + cu->base_address = DW_ADDR (attr); + cu->base_known = 1; + } + else + { + attr = dwarf2_attr (die, DW_AT_low_pc, cu); + if (attr) + { + cu->base_address = DW_ADDR (attr); + cu->base_known = 1; + } + } +} + +/* Subroutine of process_type_comp_unit and dwarf2_build_psymtabs_hard + to combine the common parts. + Process a compilation unit for a psymtab. + BUFFER is a pointer to the beginning of the dwarf section buffer, + either .debug_info or debug_types. + INFO_PTR is a pointer to the start of the CU. + Returns a pointer to the next CU. */ + +static gdb_byte * +process_psymtab_comp_unit (struct objfile *objfile, + struct dwarf2_per_cu_data *this_cu, + gdb_byte *buffer, gdb_byte *info_ptr, + unsigned int buffer_size) { - /* Instead of reading this into a big buffer, we should probably use - mmap() on architectures that support it. (FIXME) */ bfd *abfd = objfile->obfd; - gdb_byte *info_ptr; - gdb_byte *beg_of_comp_unit; - struct partial_die_info comp_unit_die; + gdb_byte *beg_of_comp_unit = info_ptr; + struct die_info *comp_unit_die; struct partial_symtab *pst; - struct cleanup *back_to; CORE_ADDR baseaddr; + struct cleanup *back_to_inner; + struct dwarf2_cu cu; + unsigned int bytes_read; + int has_children, has_pc_info; + struct attribute *attr; + const char *name; + CORE_ADDR best_lowpc = 0, best_highpc = 0; + struct die_reader_specs reader_specs; - info_ptr = dwarf2_per_objfile->info.buffer; + memset (&cu, 0, sizeof (cu)); + cu.objfile = objfile; + obstack_init (&cu.comp_unit_obstack); - /* Any cached compilation units will be linked by the per-objfile - read_in_chain. Make sure to free them when we're done. */ - back_to = make_cleanup (free_cached_comp_units, NULL); + back_to_inner = make_cleanup (free_stack_comp_unit, &cu); - create_all_comp_units (objfile); + info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr, + buffer, buffer_size, + abfd); - objfile->psymtabs_addrmap = addrmap_create_mutable - (&objfile->objfile_obstack); + /* Complete the cu_header. */ + cu.header.offset = beg_of_comp_unit - buffer; + cu.header.first_die_offset = info_ptr - beg_of_comp_unit; + + cu.list_in_scope = &file_symbols; + + /* If this compilation unit was already read in, free the + cached copy in order to read it in again. This is + necessary because we skipped some symbols when we first + read in the compilation unit (see load_partial_dies). + This problem could be avoided, but the benefit is + unclear. */ + if (this_cu->cu != NULL) + free_one_cached_comp_unit (this_cu->cu); + + /* Note that this is a pointer to our stack frame, being + added to a global data structure. It will be cleaned up + in free_stack_comp_unit when we finish with this + compilation unit. */ + this_cu->cu = &cu; + cu.per_cu = this_cu; - /* Since the objects we're extracting from .debug_info vary in - length, only the individual functions to extract them (like - read_comp_unit_head and load_partial_die) can really know whether - the buffer is large enough to hold another complete object. + /* Read the abbrevs for this compilation unit into a table. */ + dwarf2_read_abbrevs (abfd, &cu); + make_cleanup (dwarf2_free_abbrev_table, &cu); - At the moment, they don't actually check that. If .debug_info - 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. + /* Read the compilation unit die. */ + if (this_cu->from_debug_types) + info_ptr += 8 /*signature*/ + cu.header.offset_size; + init_cu_die_reader (&reader_specs, &cu); + info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr, + &has_children); - For this loop condition, simply checking whether there's any data - left at all should be sufficient. */ - while (info_ptr < (dwarf2_per_objfile->info.buffer - + dwarf2_per_objfile->info.size)) + if (this_cu->from_debug_types) { - struct cleanup *back_to_inner; - struct dwarf2_cu cu; - struct abbrev_info *abbrev; - unsigned int bytes_read; - struct dwarf2_per_cu_data *this_cu; + /* offset,length haven't been set yet for type units. */ + this_cu->offset = cu.header.offset; + this_cu->length = cu.header.length + cu.header.initial_length_size; + } + else if (comp_unit_die->tag == DW_TAG_partial_unit) + { + info_ptr = (beg_of_comp_unit + cu.header.length + + cu.header.initial_length_size); + do_cleanups (back_to_inner); + return info_ptr; + } - beg_of_comp_unit = info_ptr; + /* Set the language we're debugging. */ + attr = dwarf2_attr (comp_unit_die, DW_AT_language, &cu); + if (attr) + set_cu_language (DW_UNSND (attr), &cu); + else + set_cu_language (language_minimal, &cu); - memset (&cu, 0, sizeof (cu)); + /* Allocate a new partial symbol table structure. */ + attr = dwarf2_attr (comp_unit_die, DW_AT_name, &cu); + pst = start_psymtab_common (objfile, objfile->section_offsets, + (attr != NULL) ? DW_STRING (attr) : "", + /* TEXTLOW and TEXTHIGH are set below. */ + 0, + objfile->global_psymbols.next, + objfile->static_psymbols.next); - obstack_init (&cu.comp_unit_obstack); + attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, &cu); + if (attr != NULL) + pst->dirname = DW_STRING (attr); - back_to_inner = make_cleanup (free_stack_comp_unit, &cu); + pst->read_symtab_private = (char *) this_cu; - cu.objfile = objfile; - info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr, abfd); + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - /* Complete the cu_header */ - cu.header.offset = beg_of_comp_unit - dwarf2_per_objfile->info.buffer; - cu.header.first_die_offset = info_ptr - beg_of_comp_unit; + /* Store the function that reads in the rest of the symbol table */ + pst->read_symtab = dwarf2_psymtab_to_symtab; - cu.list_in_scope = &file_symbols; + this_cu->psymtab = pst; - /* Read the abbrevs for this compilation unit into a table */ - dwarf2_read_abbrevs (abfd, &cu); - make_cleanup (dwarf2_free_abbrev_table, &cu); + dwarf2_find_base_address (comp_unit_die, &cu); - this_cu = dwarf2_find_comp_unit (cu.header.offset, objfile); + /* Possibly set the default values of LOWPC and HIGHPC from + `DW_AT_ranges'. */ + has_pc_info = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc, + &best_highpc, &cu, pst); + if (has_pc_info == 1 && best_lowpc < best_highpc) + /* Store the contiguous range if it is not empty; it can be empty for + CUs with no code. */ + addrmap_set_empty (objfile->psymtabs_addrmap, + best_lowpc + baseaddr, + best_highpc + baseaddr - 1, pst); - /* Read the compilation unit die */ - abbrev = peek_die_abbrev (info_ptr, &bytes_read, &cu); - info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, - abfd, info_ptr, &cu); + /* Check if comp unit has_children. + If so, read the rest of the partial symbols from this comp unit. + If not, there's no more debug_info for this comp unit. */ + if (has_children) + { + struct partial_die_info *first_die; + CORE_ADDR lowpc, highpc; + + lowpc = ((CORE_ADDR) -1); + highpc = ((CORE_ADDR) 0); - if (comp_unit_die.tag == DW_TAG_partial_unit) + first_die = load_partial_dies (abfd, buffer, info_ptr, 1, &cu); + + scan_partial_symbols (first_die, &lowpc, &highpc, + ! has_pc_info, &cu); + + /* If we didn't find a lowpc, set it to highpc to avoid + complaints from `maint check'. */ + if (lowpc == ((CORE_ADDR) -1)) + lowpc = highpc; + + /* If the compilation unit didn't have an explicit address range, + then use the information extracted from its child dies. */ + if (! has_pc_info) { - info_ptr = (beg_of_comp_unit + cu.header.length - + cu.header.initial_length_size); - do_cleanups (back_to_inner); - continue; + best_lowpc = lowpc; + best_highpc = highpc; } + } + pst->textlow = best_lowpc + baseaddr; + pst->texthigh = best_highpc + baseaddr; - /* Set the language we're debugging */ - set_cu_language (comp_unit_die.language, &cu); + pst->n_global_syms = objfile->global_psymbols.next - + (objfile->global_psymbols.list + pst->globals_offset); + pst->n_static_syms = objfile->static_psymbols.next - + (objfile->static_psymbols.list + pst->statics_offset); + sort_pst_symbols (pst); - /* Allocate a new partial symbol table structure */ - pst = start_psymtab_common (objfile, objfile->section_offsets, - comp_unit_die.name ? comp_unit_die.name : "", - /* TEXTLOW and TEXTHIGH are set below. */ - 0, - objfile->global_psymbols.next, - objfile->static_psymbols.next); + info_ptr = (beg_of_comp_unit + cu.header.length + + cu.header.initial_length_size); - if (comp_unit_die.dirname) - pst->dirname = obsavestring (comp_unit_die.dirname, - strlen (comp_unit_die.dirname), - &objfile->objfile_obstack); + if (this_cu->from_debug_types) + { + /* It's not clear we want to do anything with stmt lists here. + Waiting to see what gcc ultimately does. */ + } + else + { + /* Get the list of files included in the current compilation unit, + and build a psymtab for each of them. */ + dwarf2_build_include_psymtabs (&cu, comp_unit_die, pst); + } - pst->read_symtab_private = (char *) this_cu; + do_cleanups (back_to_inner); - baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + return info_ptr; +} + +/* Traversal function for htab_traverse_noresize. + Process one .debug_types comp-unit. */ - /* Store the function that reads in the rest of the symbol table */ - pst->read_symtab = dwarf2_psymtab_to_symtab; +static int +process_type_comp_unit (void **slot, void *info) +{ + struct signatured_type *entry = (struct signatured_type *) *slot; + struct objfile *objfile = (struct objfile *) info; + struct dwarf2_per_cu_data *this_cu; - /* If this compilation unit was already read in, free the - cached copy in order to read it in again. This is - necessary because we skipped some symbols when we first - read in the compilation unit (see load_partial_dies). - This problem could be avoided, but the benefit is - unclear. */ - if (this_cu->cu != NULL) - free_one_cached_comp_unit (this_cu->cu); + this_cu = &entry->per_cu; + this_cu->from_debug_types = 1; - cu.per_cu = this_cu; + process_psymtab_comp_unit (objfile, this_cu, + dwarf2_per_objfile->types.buffer, + dwarf2_per_objfile->types.buffer + entry->offset, + dwarf2_per_objfile->types.size); - /* Note that this is a pointer to our stack frame, being - added to a global data structure. It will be cleaned up - in free_stack_comp_unit when we finish with this - compilation unit. */ - this_cu->cu = &cu; + return 1; +} - this_cu->psymtab = pst; +/* Subroutine of dwarf2_build_psymtabs_hard to simplify it. + Build partial symbol tables for the .debug_types comp-units. */ - /* Possibly set the default values of LOWPC and HIGHPC from - `DW_AT_ranges'. */ - if (cu.has_ranges_offset) - { - if (dwarf2_ranges_read (cu.ranges_offset, &comp_unit_die.lowpc, - &comp_unit_die.highpc, &cu, pst)) - comp_unit_die.has_pc_info = 1; - } - else if (comp_unit_die.has_pc_info - && comp_unit_die.lowpc < comp_unit_die.highpc) - /* Store the contiguous range if it is not empty; it can be empty for - CUs with no code. */ - addrmap_set_empty (objfile->psymtabs_addrmap, - comp_unit_die.lowpc + baseaddr, - comp_unit_die.highpc + baseaddr - 1, pst); +static void +build_type_psymtabs (struct objfile *objfile) +{ + if (! create_debug_types_hash_table (objfile)) + return; - /* Check if comp unit has_children. - If so, read the rest of the partial symbols from this comp unit. - If not, there's no more debug_info for this comp unit. */ - if (comp_unit_die.has_children) - { - struct partial_die_info *first_die; - CORE_ADDR lowpc, highpc; + htab_traverse_noresize (dwarf2_per_objfile->signatured_types, + process_type_comp_unit, objfile); +} - lowpc = ((CORE_ADDR) -1); - highpc = ((CORE_ADDR) 0); +/* Build the partial symbol table by doing a quick pass through the + .debug_info and .debug_abbrev sections. */ - first_die = load_partial_dies (abfd, info_ptr, 1, &cu); +static void +dwarf2_build_psymtabs_hard (struct objfile *objfile) +{ + /* Instead of reading this into a big buffer, we should probably use + mmap() on architectures that support it. (FIXME) */ + bfd *abfd = objfile->obfd; + gdb_byte *info_ptr; + struct cleanup *back_to; - scan_partial_symbols (first_die, &lowpc, &highpc, - ! comp_unit_die.has_pc_info, &cu); + info_ptr = dwarf2_per_objfile->info.buffer; - /* If we didn't find a lowpc, set it to highpc to avoid - complaints from `maint check'. */ - if (lowpc == ((CORE_ADDR) -1)) - lowpc = highpc; + /* Any cached compilation units will be linked by the per-objfile + read_in_chain. Make sure to free them when we're done. */ + back_to = make_cleanup (free_cached_comp_units, NULL); - /* If the compilation unit didn't have an explicit address range, - then use the information extracted from its child dies. */ - if (! comp_unit_die.has_pc_info) - { - comp_unit_die.lowpc = lowpc; - comp_unit_die.highpc = highpc; - } - } - pst->textlow = comp_unit_die.lowpc + baseaddr; - pst->texthigh = comp_unit_die.highpc + baseaddr; + build_type_psymtabs (objfile); - pst->n_global_syms = objfile->global_psymbols.next - - (objfile->global_psymbols.list + pst->globals_offset); - pst->n_static_syms = objfile->static_psymbols.next - - (objfile->static_psymbols.list + pst->statics_offset); - sort_pst_symbols (pst); + create_all_comp_units (objfile); - /* If there is already a psymtab or symtab for a file of this - name, remove it. (If there is a symtab, more drastic things - also happen.) This happens in VxWorks. */ - free_named_symtabs (pst->filename); + objfile->psymtabs_addrmap = + addrmap_create_mutable (&objfile->objfile_obstack); - info_ptr = beg_of_comp_unit + cu.header.length - + cu.header.initial_length_size; + /* Since the objects we're extracting from .debug_info vary in + length, only the individual functions to extract them (like + read_comp_unit_head and load_partial_die) can really know whether + the buffer is large enough to hold another complete object. - if (comp_unit_die.has_stmt_list) - { - /* Get the list of files included in the current compilation unit, - and build a psymtab for each of them. */ - dwarf2_build_include_psymtabs (&cu, &comp_unit_die, pst); - } + At the moment, they don't actually check that. If .debug_info + 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. - do_cleanups (back_to_inner); + For this loop condition, simply checking whether there's any data + left at all should be sufficient. */ + + while (info_ptr < (dwarf2_per_objfile->info.buffer + + dwarf2_per_objfile->info.size)) + { + struct dwarf2_per_cu_data *this_cu; + + this_cu = dwarf2_find_comp_unit (info_ptr - dwarf2_per_objfile->info.buffer, + objfile); + + info_ptr = process_psymtab_comp_unit (objfile, this_cu, + dwarf2_per_objfile->info.buffer, + info_ptr, + dwarf2_per_objfile->info.size); } objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap, @@ -1789,32 +2129,43 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) do_cleanups (back_to); } -/* Load the DIEs for a secondary CU into memory. */ +/* Load the partial DIEs for a secondary CU into memory. */ static void -load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile) +load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu, + struct objfile *objfile) { bfd *abfd = objfile->obfd; gdb_byte *info_ptr, *beg_of_comp_unit; - struct partial_die_info comp_unit_die; + struct die_info *comp_unit_die; struct dwarf2_cu *cu; - struct abbrev_info *abbrev; unsigned int bytes_read; struct cleanup *back_to; + struct attribute *attr; + int has_children; + struct die_reader_specs reader_specs; + + gdb_assert (! this_cu->from_debug_types); info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset; beg_of_comp_unit = info_ptr; - cu = xmalloc (sizeof (struct dwarf2_cu)); - memset (cu, 0, sizeof (struct dwarf2_cu)); + cu = alloc_one_comp_unit (objfile); - obstack_init (&cu->comp_unit_obstack); + /* ??? Missing cleanup for CU? */ - cu->objfile = objfile; - info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr, abfd); + /* Link this compilation unit into the compilation unit tree. */ + this_cu->cu = cu; + cu->per_cu = this_cu; + cu->type_hash = this_cu->type_hash; + + info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr, + dwarf2_per_objfile->info.buffer, + dwarf2_per_objfile->info.size, + abfd); /* Complete the cu_header. */ - cu->header.offset = beg_of_comp_unit - dwarf2_per_objfile->info.buffer; + cu->header.offset = this_cu->offset; cu->header.first_die_offset = info_ptr - beg_of_comp_unit; /* Read the abbrevs for this compilation unit into a table. */ @@ -1822,23 +2173,22 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile) back_to = make_cleanup (dwarf2_free_abbrev_table, cu); /* Read the compilation unit die. */ - abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu); - info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, - abfd, info_ptr, cu); + init_cu_die_reader (&reader_specs, cu); + info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr, + &has_children); /* Set the language we're debugging. */ - set_cu_language (comp_unit_die.language, cu); - - /* Link this compilation unit into the compilation unit tree. */ - this_cu->cu = cu; - cu->per_cu = this_cu; - cu->type_hash = cu->per_cu->type_hash; + attr = dwarf2_attr (comp_unit_die, DW_AT_language, cu); + if (attr) + set_cu_language (DW_UNSND (attr), cu); + else + set_cu_language (language_minimal, cu); /* Check if comp unit has_children. If so, read the rest of the partial symbols from this comp unit. If not, there's no more debug_info for this comp unit. */ - if (comp_unit_die.has_children) - load_partial_dies (abfd, info_ptr, 0, cu); + if (has_children) + load_partial_dies (abfd, dwarf2_per_objfile->info.buffer, info_ptr, 0, cu); do_cleanups (back_to); } @@ -2036,7 +2386,8 @@ partial_die_parent_scope (struct partial_die_info *pdi, || parent->tag == DW_TAG_structure_type || parent->tag == DW_TAG_class_type || parent->tag == DW_TAG_interface_type - || parent->tag == DW_TAG_union_type) + || parent->tag == DW_TAG_union_type + || parent->tag == DW_TAG_enumeration_type) { if (grandparent_scope == NULL) parent->scope = parent->name; @@ -2044,7 +2395,7 @@ partial_die_parent_scope (struct partial_die_info *pdi, parent->scope = typename_concat (&cu->comp_unit_obstack, grandparent_scope, parent->name, cu); } - else if (parent->tag == DW_TAG_enumeration_type) + else if (parent->tag == DW_TAG_enumerator) /* Enumerators should not get the name of the enumeration as a prefix. */ parent->scope = grandparent_scope; else @@ -2112,6 +2463,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr, mst_text, objfile); */ psym = add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name, VAR_DOMAIN, LOC_BLOCK, &objfile->global_psymbols, 0, pdi->lowpc + baseaddr, @@ -2122,6 +2474,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) /*prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr, mst_file_text, objfile); */ psym = add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name, VAR_DOMAIN, LOC_BLOCK, &objfile->static_psymbols, 0, pdi->lowpc + baseaddr, @@ -2148,6 +2501,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) addr = decode_locdesc (pdi->locdesc, cu); if (pdi->locdesc || pdi->has_type) psym = add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name, VAR_DOMAIN, LOC_STATIC, &objfile->global_psymbols, 0, addr + baseaddr, @@ -2166,6 +2520,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) /*prim_record_minimal_symbol (actual_name, addr + baseaddr, mst_file_data, objfile); */ psym = add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name, VAR_DOMAIN, LOC_STATIC, &objfile->static_psymbols, 0, addr + baseaddr, @@ -2176,12 +2531,14 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) case DW_TAG_base_type: case DW_TAG_subrange_type: add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name, VAR_DOMAIN, LOC_TYPEDEF, &objfile->static_psymbols, 0, (CORE_ADDR) 0, cu->language, objfile); break; case DW_TAG_namespace: add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name, VAR_DOMAIN, LOC_TYPEDEF, &objfile->global_psymbols, 0, (CORE_ADDR) 0, cu->language, objfile); @@ -2206,6 +2563,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) /* NOTE: carlton/2003-10-07: See comment in new_symbol about static vs. global. */ add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name, STRUCT_DOMAIN, LOC_TYPEDEF, (cu->language == language_cplus || cu->language == language_java) @@ -2216,6 +2574,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) break; case DW_TAG_enumerator: add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name, VAR_DOMAIN, LOC_CONST, (cu->language == language_cplus || cu->language == language_java) @@ -2469,12 +2828,12 @@ peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read, return abbrev; } -/* Scan the debug information for CU starting at INFO_PTR. Returns a - pointer to the end of a series of DIEs, terminated by an empty +/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER. + Returns a pointer to the end of a series of DIEs, terminated by an empty DIE. Any children of the skipped DIEs will also be skipped. */ static gdb_byte * -skip_children (gdb_byte *info_ptr, struct dwarf2_cu *cu) +skip_children (gdb_byte *buffer, gdb_byte *info_ptr, struct dwarf2_cu *cu) { struct abbrev_info *abbrev; unsigned int bytes_read; @@ -2485,19 +2844,19 @@ skip_children (gdb_byte *info_ptr, struct dwarf2_cu *cu) if (abbrev == NULL) return info_ptr + bytes_read; else - info_ptr = skip_one_die (info_ptr + bytes_read, abbrev, cu); + info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu); } } -/* Scan the debug information for CU starting at INFO_PTR. INFO_PTR - should point just after the initial uleb128 of a DIE, and the +/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER. + INFO_PTR should point just after the initial uleb128 of a DIE, and the abbrev corresponding to that skipped uleb128 should be passed in ABBREV. Returns a pointer to this DIE's sibling, skipping any children. */ static gdb_byte * -skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev, - struct dwarf2_cu *cu) +skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr, + struct abbrev_info *abbrev, struct dwarf2_cu *cu) { unsigned int bytes_read; struct attribute attr; @@ -2514,8 +2873,7 @@ skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev, if (attr.form == DW_FORM_ref_addr) complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling")); else - return dwarf2_per_objfile->info.buffer - + dwarf2_get_ref_die_offset (&attr); + return buffer + dwarf2_get_ref_die_offset (&attr); } /* If it isn't DW_AT_sibling, skip this attribute. */ @@ -2542,6 +2900,7 @@ skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev, break; case DW_FORM_data8: case DW_FORM_ref8: + case DW_FORM_sig8: info_ptr += 8; break; case DW_FORM_string: @@ -2584,16 +2943,18 @@ skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev, } if (abbrev->has_children) - return skip_children (info_ptr, cu); + return skip_children (buffer, info_ptr, cu); else return info_ptr; } -/* Locate ORIG_PDI's sibling; INFO_PTR should point to the start of - the next DIE after ORIG_PDI. */ +/* Locate ORIG_PDI's sibling. + INFO_PTR should point to the start of the next DIE after ORIG_PDI + in BUFFER. */ static gdb_byte * -locate_pdi_sibling (struct partial_die_info *orig_pdi, gdb_byte *info_ptr, +locate_pdi_sibling (struct partial_die_info *orig_pdi, + gdb_byte *buffer, gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *cu) { /* Do we know the sibling already? */ @@ -2608,7 +2969,7 @@ locate_pdi_sibling (struct partial_die_info *orig_pdi, gdb_byte *info_ptr, /* Skip the children the long way. */ - return skip_children (info_ptr, cu); + return skip_children (buffer, info_ptr, cu); } /* Expand this partial symbol table into a full symbol table. */ @@ -2675,12 +3036,6 @@ queue_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile) dwarf2_queue_tail->next = item; dwarf2_queue_tail = item; - - /* Either PER_CU is the CU we want to process, or we're following a reference - pointing into PER_CU. Either way, we need its DIEs now. */ - load_full_comp_unit (item->per_cu, objfile); - item->per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; - dwarf2_per_objfile->read_in_chain = item->per_cu; } /* Process the queue. */ @@ -2775,6 +3130,11 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) queue_comp_unit (per_cu, pst->objfile); + if (per_cu->from_debug_types) + read_signatured_type_at_offset (pst->objfile, per_cu->offset); + else + load_full_comp_unit (per_cu, pst->objfile); + process_queue (pst->objfile); /* Age the cache, releasing compilation units that have not @@ -2784,49 +3144,49 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) do_cleanups (back_to); } -/* Load the DIEs associated with PST and PER_CU into memory. */ +/* Load the DIEs associated with PER_CU into memory. */ -static struct dwarf2_cu * +static void load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile) { bfd *abfd = objfile->obfd; struct dwarf2_cu *cu; unsigned int offset; - gdb_byte *info_ptr; + gdb_byte *info_ptr, *beg_of_comp_unit; struct cleanup *back_to, *free_cu_cleanup; struct attribute *attr; CORE_ADDR baseaddr; + gdb_assert (! per_cu->from_debug_types); + /* Set local variables from the partial symbol table info. */ offset = per_cu->offset; info_ptr = dwarf2_per_objfile->info.buffer + offset; + beg_of_comp_unit = info_ptr; - cu = xmalloc (sizeof (struct dwarf2_cu)); - memset (cu, 0, sizeof (struct dwarf2_cu)); + cu = alloc_one_comp_unit (objfile); /* If an error occurs while loading, release our storage. */ free_cu_cleanup = make_cleanup (free_one_comp_unit, cu); - cu->objfile = objfile; - - /* read in the comp_unit header */ + /* Read in the comp_unit header. */ info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd); - /* Read the abbrevs for this compilation unit */ + /* Complete the cu_header. */ + cu->header.offset = offset; + cu->header.first_die_offset = info_ptr - beg_of_comp_unit; + + /* Read the abbrevs for this compilation unit. */ dwarf2_read_abbrevs (abfd, cu); back_to = make_cleanup (dwarf2_free_abbrev_table, cu); - cu->header.offset = offset; - - cu->per_cu = per_cu; + /* Link this compilation unit into the compilation unit tree. */ per_cu->cu = cu; + cu->per_cu = per_cu; cu->type_hash = per_cu->type_hash; - /* We use this obstack for block values in dwarf_alloc_block. */ - obstack_init (&cu->comp_unit_obstack); - - cu->dies = read_comp_unit (info_ptr, abfd, cu); + cu->dies = read_comp_unit (info_ptr, cu); /* We try not to read any attributes in this function, because not all objfiles needed for references have been loaded yet, and symbol @@ -2838,13 +3198,15 @@ load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile) else set_cu_language (language_minimal, cu); + /* Link this CU into read_in_chain. */ + per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; + dwarf2_per_objfile->read_in_chain = per_cu; + do_cleanups (back_to); /* We've successfully allocated this compilation unit. Let our caller clean it up when finished with it. */ discard_cleanups (free_cu_cleanup); - - return cu; } /* Generate full symbol information for PST and CU, whose DIEs have @@ -2860,41 +3222,17 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) CORE_ADDR lowpc, highpc; struct symtab *symtab; struct cleanup *back_to; - struct attribute *attr; CORE_ADDR baseaddr; - baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - - buildsym_init (); - back_to = make_cleanup (really_free_pendings, NULL); - - cu->list_in_scope = &file_symbols; - - /* Find the base address of the compilation unit for range lists and - location lists. It will normally be specified by DW_AT_low_pc. - In DWARF-3 draft 4, the base address could be overridden by - DW_AT_entry_pc. It's been removed, but GCC still uses this for - compilation units with discontinuous ranges. */ - - cu->base_known = 0; - cu->base_address = 0; - - attr = dwarf2_attr (cu->dies, DW_AT_entry_pc, cu); - if (attr) - { - cu->base_address = DW_ADDR (attr); - cu->base_known = 1; - } - else - { - attr = dwarf2_attr (cu->dies, DW_AT_low_pc, cu); - if (attr) - { - cu->base_address = DW_ADDR (attr); - cu->base_known = 1; - } - } - + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + buildsym_init (); + back_to = make_cleanup (really_free_pendings, NULL); + + cu->list_in_scope = &file_symbols; + + dwarf2_find_base_address (cu->dies, cu); + /* Do line number decoding in read_file_scope () */ process_die (cu->dies, cu); @@ -2931,13 +3269,12 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_compile_unit: read_file_scope (die, cu); break; - case DW_TAG_subprogram: - read_func_scope (die, cu); + case DW_TAG_type_unit: + read_type_unit_scope (die, cu); break; + case DW_TAG_subprogram: case DW_TAG_inlined_subroutine: - /* FIXME: These are ignored for now. - They could be used to set breakpoints on all inlined instances - of a function and make GDB `next' properly over inlined functions. */ + read_func_scope (die, cu); break; case DW_TAG_lexical_block: case DW_TAG_try_block: @@ -3045,7 +3382,11 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) { struct attribute *import_attr; struct die_info *imported_die; + struct dwarf2_cu *imported_cu; const char *imported_name; + const char *imported_name_prefix; + const char *import_prefix; + char *canonical_name; import_attr = dwarf2_attr (die, DW_AT_import, cu); if (import_attr == NULL) @@ -3055,8 +3396,9 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) return; } - imported_die = follow_die_ref (die, import_attr, &cu); - imported_name = dwarf2_name (imported_die, cu); + imported_cu = cu; + imported_die = follow_die_ref_or_sig (die, import_attr, &imported_cu); + imported_name = dwarf2_name (imported_die, imported_cu); if (imported_name == NULL) { /* GCC bug: https://bugzilla.redhat.com/show_bug.cgi?id=506524 @@ -3096,8 +3438,27 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) /* FIXME: dwarf2_name (die); for the local name after import. */ - using_directives = cp_add_using (imported_name, strlen (imported_name), 0, - using_directives); + /* Figure out where the statement is being imported to. */ + import_prefix = determine_prefix (die, cu); + + /* Figure out what the scope of the imported die is and prepend it + to the name of the imported die. */ + imported_name_prefix = determine_prefix (imported_die, imported_cu); + + if (strlen (imported_name_prefix) > 0) + { + canonical_name = alloca (strlen (imported_name_prefix) + 2 + strlen (imported_name) + 1); + strcpy (canonical_name, imported_name_prefix); + strcat (canonical_name, "::"); + strcat (canonical_name, imported_name); + } + else + { + canonical_name = alloca (strlen (imported_name) + 1); + strcpy (canonical_name, imported_name); + } + + using_directives = cp_add_using (import_prefix,canonical_name, using_directives); } static void @@ -3234,6 +3595,85 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) do_cleanups (back_to); } +/* For TUs we want to skip the first top level sibling if it's not the + actual type being defined by this TU. In this case the first top + level sibling is there to provide context only. */ + +static void +read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + struct cleanup *back_to = make_cleanup (null_cleanup, 0); + CORE_ADDR lowpc; + struct attribute *attr; + char *name = NULL; + char *comp_dir = NULL; + struct die_info *child_die; + bfd *abfd = objfile->obfd; + struct line_header *line_header = 0; + + /* start_symtab needs a low pc, but we don't really have one. + Do what read_file_scope would do in the absence of such info. */ + lowpc = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + /* Find the filename. Do not use dwarf2_name here, since the filename + is not a source language identifier. */ + attr = dwarf2_attr (die, DW_AT_name, cu); + if (attr) + name = DW_STRING (attr); + + attr = dwarf2_attr (die, DW_AT_comp_dir, cu); + if (attr) + comp_dir = DW_STRING (attr); + else if (name != NULL && IS_ABSOLUTE_PATH (name)) + { + comp_dir = ldirname (name); + if (comp_dir != NULL) + make_cleanup (xfree, comp_dir); + } + + if (name == NULL) + name = ""; + + attr = dwarf2_attr (die, DW_AT_language, cu); + if (attr) + set_cu_language (DW_UNSND (attr), cu); + + /* This isn't technically needed today. It is done for symmetry + with read_file_scope. */ + attr = dwarf2_attr (die, DW_AT_producer, cu); + if (attr) + cu->producer = DW_STRING (attr); + + /* We assume that we're processing GCC output. */ + processing_gcc_compilation = 2; + + processing_has_namespace_info = 0; + + start_symtab (name, comp_dir, lowpc); + record_debugformat ("DWARF 2"); + record_producer (cu->producer); + + /* Process the dies in the type unit. */ + if (die->child == NULL) + { + dump_die_for_error (die); + error (_("Dwarf Error: Missing children for type unit [in module %s]"), + bfd_get_filename (abfd)); + } + + child_die = die->child; + + while (child_die && child_die->tag) + { + process_die (child_die, cu); + + child_die = sibling_die (child_die); + } + + do_cleanups (back_to); +} + static void add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc, struct dwarf2_cu *cu) @@ -3291,7 +3731,9 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) return; origin_die = follow_die_ref (die, attr, &cu); - if (die->tag != origin_die->tag) + if (die->tag != origin_die->tag + && !(die->tag == DW_TAG_inlined_subroutine + && origin_die->tag == DW_TAG_subprogram)) complaint (&symfile_complaints, _("DIE 0x%x and its abstract origin 0x%x have different tags"), die->offset, origin_die->offset); @@ -3310,20 +3752,38 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) child_die = die->child; while (child_die && child_die->tag) { - attr = dwarf2_attr (child_die, DW_AT_abstract_origin, cu); + /* For each CHILD_DIE, find the corresponding child of + ORIGIN_DIE. If there is more than one layer of + DW_AT_abstract_origin, follow them all; there shouldn't be, + but GCC versions at least through 4.4 generate this (GCC PR + 40573). */ + struct die_info *child_origin_die = child_die; + while (1) + { + attr = dwarf2_attr (child_origin_die, DW_AT_abstract_origin, cu); + if (attr == NULL) + break; + child_origin_die = follow_die_ref (child_origin_die, attr, &cu); + } + /* According to DWARF3 3.3.8.2 #3 new entries without their abstract counterpart may exist. */ - if (attr) + if (child_origin_die != child_die) { - struct die_info *child_origin_die; - - child_origin_die = follow_die_ref (child_die, attr, &cu); - if (child_die->tag != child_origin_die->tag) + if (child_die->tag != child_origin_die->tag + && !(child_die->tag == DW_TAG_inlined_subroutine + && child_origin_die->tag == DW_TAG_subprogram)) complaint (&symfile_complaints, _("Child DIE 0x%x and its abstract origin 0x%x have " "different tags"), child_die->offset, child_origin_die->offset); - *offsets_end++ = child_origin_die->offset; + if (child_origin_die->parent != origin_die) + complaint (&symfile_complaints, + _("Child DIE 0x%x and its abstract origin 0x%x have " + "different parents"), child_die->offset, + child_origin_die->offset); + else + *offsets_end++ = child_origin_die->offset; } child_die = sibling_die (child_die); } @@ -3361,10 +3821,25 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) CORE_ADDR lowpc; CORE_ADDR highpc; struct die_info *child_die; - struct attribute *attr; + struct attribute *attr, *call_line, *call_file; char *name; CORE_ADDR baseaddr; struct block *block; + int inlined_func = (die->tag == DW_TAG_inlined_subroutine); + + if (inlined_func) + { + /* If we do not have call site information, we can't show the + caller of this inlined function. That's too confusing, so + only use the scope for local variables. */ + call_line = dwarf2_attr (die, DW_AT_call_line, cu); + call_file = dwarf2_attr (die, DW_AT_call_file, cu); + if (call_line == NULL || call_file == NULL) + { + read_lexical_block_scope (die, cu); + return; + } + } baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -3372,7 +3847,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) /* Ignore functions with missing or empty names and functions with missing or invalid low and high pc attributes. */ - if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu)) + if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)) return; lowpc += baseaddr; @@ -3460,7 +3935,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) as multiple lexical blocks? Handling children in a sane way would be nasty. Might be easier to properly extend generic blocks to describe ranges. */ - if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu)) + if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu, NULL)) return; lowpc += baseaddr; highpc += baseaddr; @@ -3632,7 +4107,8 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return, discontinuous, i.e. derived from DW_AT_ranges information. */ static int dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, - CORE_ADDR *highpc, struct dwarf2_cu *cu) + CORE_ADDR *highpc, struct dwarf2_cu *cu, + struct partial_symtab *pst) { struct attribute *attr; CORE_ADDR low = 0; @@ -3660,7 +4136,7 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, { /* Value of the DW_AT_ranges attribute is the offset in the .debug_ranges section. */ - if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, NULL)) + if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, pst)) return 0; /* Found discontinuous range of addresses. */ ret = -1; @@ -3699,7 +4175,7 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die, CORE_ADDR low, high; struct die_info *child = die->child; - if (dwarf2_get_pc_bounds (die, &low, &high, cu)) + if (dwarf2_get_pc_bounds (die, &low, &high, cu, NULL)) { *lowpc = min (*lowpc, low); *highpc = max (*highpc, high); @@ -3736,7 +4212,7 @@ get_scope_pc_bounds (struct die_info *die, CORE_ADDR best_high = (CORE_ADDR) 0; CORE_ADDR current_low, current_high; - if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu)) + if (dwarf2_get_pc_bounds (die, ¤t_low, ¤t_high, cu, NULL)) { best_low = current_low; best_high = current_high; @@ -3892,8 +4368,17 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield)); make_cleanup (xfree, new_field); memset (new_field, 0, sizeof (struct nextfield)); - new_field->next = fip->fields; - fip->fields = new_field; + + if (die->tag == DW_TAG_inheritance) + { + new_field->next = fip->baseclasses; + fip->baseclasses = new_field; + } + else + { + new_field->next = fip->fields; + fip->fields = new_field; + } fip->nfields++; /* Handle accessibility and virtuality of field. @@ -3940,17 +4425,16 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, attr = dwarf2_attr (die, DW_AT_data_member_location, cu); if (attr) { - int byte_offset; + int byte_offset = 0; if (attr_form_is_section_offset (attr)) - { - dwarf2_complex_location_expr_complaint (); - byte_offset = 0; - } + dwarf2_complex_location_expr_complaint (); else if (attr_form_is_constant (attr)) byte_offset = dwarf2_get_attr_constant_value (attr, 0); - else + else if (attr_form_is_block (attr)) byte_offset = decode_locdesc (DW_BLOCK (attr), cu); + else + dwarf2_complex_location_expr_complaint (); SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte); } @@ -4011,6 +4495,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, pointer or virtual base class pointer) to private. */ if (dwarf2_attr (die, DW_AT_artificial, cu)) { + FIELD_ARTIFICIAL (*fp) = 1; new_field->accessibility = DW_ACCESS_private; fip->non_public_fields = 1; } @@ -4045,8 +4530,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, /* C++ base class field. */ attr = dwarf2_attr (die, DW_AT_data_member_location, cu); if (attr) - SET_FIELD_BITPOS (*fp, decode_locdesc (DW_BLOCK (attr), cu) - * bits_per_byte); + { + int byte_offset = 0; + + if (attr_form_is_section_offset (attr)) + dwarf2_complex_location_expr_complaint (); + else if (attr_form_is_constant (attr)) + byte_offset = dwarf2_get_attr_constant_value (attr, 0); + else if (attr_form_is_block (attr)) + byte_offset = decode_locdesc (DW_BLOCK (attr), cu); + else + dwarf2_complex_location_expr_complaint (); + + SET_FIELD_BITPOS (*fp, byte_offset * bits_per_byte); + } FIELD_BITSIZE (*fp) = 0; FIELD_TYPE (*fp) = die_type (die, cu); FIELD_NAME (*fp) = type_name_no_tag (fp->type); @@ -4069,7 +4566,7 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, TYPE_ALLOC (type, sizeof (struct field) * nfields); memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields); - if (fip->non_public_fields) + if (fip->non_public_fields && cu->language != language_ada) { ALLOCATE_CPLUS_STRUCT_TYPE (type); @@ -4088,7 +4585,7 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, /* If the type has baseclasses, allocate and clear a bit vector for TYPE_FIELD_VIRTUAL_BITS. */ - if (fip->nbaseclasses) + if (fip->nbaseclasses && cu->language != language_ada) { int num_bytes = B_BYTES (fip->nbaseclasses); unsigned char *pointer; @@ -4105,15 +4602,30 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, up in the same order in the array in which they were added to the list. */ while (nfields-- > 0) { - TYPE_FIELD (type, nfields) = fip->fields->field; - switch (fip->fields->accessibility) + struct nextfield *fieldp; + + if (fip->fields) + { + fieldp = fip->fields; + fip->fields = fieldp->next; + } + else + { + fieldp = fip->baseclasses; + fip->baseclasses = fieldp->next; + } + + TYPE_FIELD (type, nfields) = fieldp->field; + switch (fieldp->accessibility) { case DW_ACCESS_private: - SET_TYPE_FIELD_PRIVATE (type, nfields); + if (cu->language != language_ada) + SET_TYPE_FIELD_PRIVATE (type, nfields); break; case DW_ACCESS_protected: - SET_TYPE_FIELD_PROTECTED (type, nfields); + if (cu->language != language_ada) + SET_TYPE_FIELD_PROTECTED (type, nfields); break; case DW_ACCESS_public: @@ -4123,21 +4635,22 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, /* Unknown accessibility. Complain and treat it as public. */ { complaint (&symfile_complaints, _("unsupported accessibility %d"), - fip->fields->accessibility); + fieldp->accessibility); } break; } if (nfields < fip->nbaseclasses) { - switch (fip->fields->virtuality) + switch (fieldp->virtuality) { case DW_VIRTUALITY_virtual: case DW_VIRTUALITY_pure_virtual: + if (cu->language == language_ada) + error ("unexpected virtuality in component of Ada type"); SET_TYPE_FIELD_VIRTUAL (type, nfields); break; } } - fip->fields = fip->fields->next; } } @@ -4157,6 +4670,9 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, struct nextfnfield *new_fnfield; struct type *this_type; + if (cu->language == language_ada) + error ("unexpected member function in Ada type"); + /* Get name of member function. */ fieldname = dwarf2_name (die, cu); if (fieldname == NULL) @@ -4261,9 +4777,14 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, if (attr && DW_UNSND (attr) != 0) fnp->is_artificial = 1; - /* Get index in virtual function table if it is a virtual member function. */ + /* Get index in virtual function table if it is a virtual member + function. For GCC, this is an offset in the appropriate + virtual table, as specified by DW_AT_containing_type. For + everyone else, it is an expression to be evaluated relative + to the object address. */ + attr = dwarf2_attr (die, DW_AT_vtable_elem_location, cu); - if (attr) + if (attr && fnp->fcontext) { /* Support the .debug_loc offsets */ if (attr_form_is_block (attr)) @@ -4279,7 +4800,40 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, dwarf2_invalid_attrib_class_complaint ("DW_AT_vtable_elem_location", fieldname); } - } + } + else if (attr) + { + /* We only support trivial expressions here. This hack will work + for v3 classes, which always start with the vtable pointer. */ + if (attr_form_is_block (attr) && DW_BLOCK (attr)->size > 0 + && DW_BLOCK (attr)->data[0] == DW_OP_deref) + { + struct dwarf_block blk; + blk.size = DW_BLOCK (attr)->size - 1; + blk.data = DW_BLOCK (attr)->data + 1; + fnp->voffset = decode_locdesc (&blk, cu); + if ((fnp->voffset % cu->header.addr_size) != 0) + dwarf2_complex_location_expr_complaint (); + else + fnp->voffset /= cu->header.addr_size; + fnp->voffset += 2; + fnp->fcontext = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (this_type, 0)); + } + else + dwarf2_complex_location_expr_complaint (); + } + else + { + attr = dwarf2_attr (die, DW_AT_virtuality, cu); + if (attr && DW_UNSND (attr)) + { + /* GCC does this, as of 2008-08-25; PR debug/37237. */ + complaint (&symfile_complaints, + _("Member function \"%s\" (offset %d) is virtual but the vtable offset is not specified"), + fieldname, die->offset); + TYPE_CPLUS_DYNAMIC (type) = 1; + } + } } /* Create the vector of member function fields, and attach it to the type. */ @@ -4292,6 +4846,9 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type, int total_length = 0; int i; + if (cu->language == language_ada) + error ("unexpected member functions in Ada type"); + ALLOCATE_CPLUS_STRUCT_TYPE (type); TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) TYPE_ALLOC (type, sizeof (struct fn_fieldlist) * fip->nfnfields); @@ -4335,68 +4892,48 @@ is_vtable_name (const char *name, struct dwarf2_cu *cu) } /* GCC outputs unnamed structures that are really pointers to member - functions, with the ABI-specified layout. If DIE (from CU) describes - such a structure, set its type, and return nonzero. Otherwise return - zero. + functions, with the ABI-specified layout. If TYPE describes + such a structure, smash it into a member function type. GCC shouldn't do this; it should just output pointer to member DIEs. This is GCC PR debug/28767. */ -static struct type * -quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu) +static void +quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile) { - struct objfile *objfile = cu->objfile; - struct type *type; - struct die_info *pfn_die, *delta_die; - struct attribute *pfn_name, *delta_name; - struct type *pfn_type, *domain_type; + struct type *pfn_type, *domain_type, *new_type; /* Check for a structure with no name and two children. */ - if (die->tag != DW_TAG_structure_type - || dwarf2_attr (die, DW_AT_name, cu) != NULL - || die->child == NULL - || die->child->sibling == NULL - || (die->child->sibling->sibling != NULL - && die->child->sibling->sibling->tag != DW_TAG_padding)) - return NULL; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2) + return; /* Check for __pfn and __delta members. */ - pfn_die = die->child; - pfn_name = dwarf2_attr (pfn_die, DW_AT_name, cu); - if (pfn_die->tag != DW_TAG_member - || pfn_name == NULL - || DW_STRING (pfn_name) == NULL - || strcmp ("__pfn", DW_STRING (pfn_name)) != 0) - return NULL; - - delta_die = pfn_die->sibling; - delta_name = dwarf2_attr (delta_die, DW_AT_name, cu); - if (delta_die->tag != DW_TAG_member - || delta_name == NULL - || DW_STRING (delta_name) == NULL - || strcmp ("__delta", DW_STRING (delta_name)) != 0) - return NULL; + if (TYPE_FIELD_NAME (type, 0) == NULL + || strcmp (TYPE_FIELD_NAME (type, 0), "__pfn") != 0 + || TYPE_FIELD_NAME (type, 1) == NULL + || strcmp (TYPE_FIELD_NAME (type, 1), "__delta") != 0) + return; /* Find the type of the method. */ - pfn_type = die_type (pfn_die, cu); + pfn_type = TYPE_FIELD_TYPE (type, 0); if (pfn_type == NULL || TYPE_CODE (pfn_type) != TYPE_CODE_PTR || TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC) - return NULL; + return; /* Look for the "this" argument. */ pfn_type = TYPE_TARGET_TYPE (pfn_type); if (TYPE_NFIELDS (pfn_type) == 0 + /* || TYPE_FIELD_TYPE (pfn_type, 0) == NULL */ || TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR) - return NULL; + return; domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0)); - type = alloc_type (objfile); - smash_to_method_type (type, domain_type, TYPE_TARGET_TYPE (pfn_type), + new_type = alloc_type (objfile); + smash_to_method_type (new_type, domain_type, TYPE_TARGET_TYPE (pfn_type), TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type), TYPE_VARARGS (pfn_type)); - type = lookup_methodptr_type (type); - return set_die_type (die, type, cu); + smash_to_methodptr_type (type, new_type); } /* Called when we find the DIE that starts a structure or union scope @@ -4424,12 +4961,25 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) char *name; struct cleanup *back_to = make_cleanup (null_cleanup, 0); - type = quirk_gcc_member_function_pointer (die, cu); - if (type) - return type; + /* If the definition of this type lives in .debug_types, read that type. + Don't follow DW_AT_specification though, that will take us back up + the chain and we want to go down. */ + attr = dwarf2_attr_no_follow (die, DW_AT_signature, cu); + if (attr) + { + struct dwarf2_cu *type_cu = cu; + struct die_info *type_die = follow_die_ref_or_sig (die, attr, &type_cu); + /* We could just recurse on read_structure_type, but we need to call + get_die_type to ensure only one type for this DIE is created. + This is important, for example, because for c++ classes we need + TYPE_NAME set which is only done by new_symbol. Blech. */ + type = read_type_die (type_die, type_cu); + return set_die_type (die, type, cu); + } type = alloc_type (objfile); INIT_CPLUS_SPECIFIC (type); + name = dwarf2_name (die, cu); if (name != NULL) { @@ -4476,6 +5026,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) if (die_is_declaration (die, cu)) TYPE_STUB (type) = 1; + set_descriptive_type (type, die, cu); + /* We need to add the type field to the die immediately so we don't infinitely recurse when dealing with pointers to the structure type within the structure itself. */ @@ -4524,7 +5076,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) /* Get the type which refers to the base class (possibly this class itself) which contains the vtable pointer for the current - class from the DW_AT_containing_type attribute. */ + class from the DW_AT_containing_type attribute. This use of + DW_AT_containing_type is a GNU extension. */ if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL) { @@ -4586,6 +5139,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) } } + quirk_gcc_member_function_pointer (type, cu->objfile); + do_cleanups (back_to); return type; } @@ -4641,6 +5196,18 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) struct attribute *attr; const char *name; + /* If the definition of this type lives in .debug_types, read that type. + Don't follow DW_AT_specification though, that will take us back up + the chain and we want to go down. */ + attr = dwarf2_attr_no_follow (die, DW_AT_signature, cu); + if (attr) + { + struct dwarf2_cu *type_cu = cu; + struct die_info *type_die = follow_die_ref_or_sig (die, attr, &type_cu); + type = read_type_die (type_die, type_cu); + return set_die_type (die, type, cu); + } + type = alloc_type (objfile); TYPE_CODE (type) = TYPE_CODE_ENUM; @@ -4814,7 +5381,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) arrays with unspecified length. */ if (die->child == NULL) { - index_type = builtin_type_int32; + index_type = objfile_type (objfile)->builtin_int; range_type = create_range_type (NULL, index_type, 0, -1); type = create_array_type (NULL, element_type, range_type); return set_die_type (die, type, cu); @@ -4876,6 +5443,8 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) if (name) TYPE_NAME (type) = name; + set_descriptive_type (type, die, cu); + do_cleanups (back_to); /* Install the type in the die. */ @@ -4900,8 +5469,8 @@ read_array_order (struct die_info *die, struct dwarf2_cu *cu) version checking. */ - if (cu->language == language_fortran && - cu->producer && strstr (cu->producer, "GNU F77")) + if (cu->language == language_fortran + && cu->producer && strstr (cu->producer, "GNU F77")) { return DW_ORD_row_major; } @@ -4964,8 +5533,18 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) attr = dwarf2_attr (child_die, DW_AT_data_member_location, cu); if (attr) { - SYMBOL_VALUE_ADDRESS (sym) = - base + decode_locdesc (DW_BLOCK (attr), cu); + CORE_ADDR byte_offset = 0; + + if (attr_form_is_section_offset (attr)) + dwarf2_complex_location_expr_complaint (); + else if (attr_form_is_constant (attr)) + byte_offset = dwarf2_get_attr_constant_value (attr, 0); + else if (attr_form_is_block (attr)) + byte_offset = decode_locdesc (DW_BLOCK (attr), cu); + else + dwarf2_complex_location_expr_complaint (); + + SYMBOL_VALUE_ADDRESS (sym) = base + byte_offset; add_symbol_to_list (sym, &global_symbols); } child_die = sibling_die (child_die); @@ -5037,9 +5616,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu) if (is_anonymous) { const char *previous_prefix = determine_prefix (die, cu); - cp_add_using_directive (TYPE_NAME (type), - strlen (previous_prefix), - strlen (TYPE_NAME (type))); + cp_add_using_directive (previous_prefix, TYPE_NAME (type)); } } @@ -5254,7 +5831,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu) } } - index_type = builtin_type_int32; + index_type = objfile_type (objfile)->builtin_int; range_type = create_range_type (NULL, index_type, 1, length); char_type = language_string_char_type (cu->language_defn, gdbarch); type = create_string_type (NULL, char_type, range_type); @@ -5281,7 +5858,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) struct attribute *attr; type = die_type (die, cu); - ftype = make_function_type (type, (struct type **) 0, cu->objfile); + ftype = lookup_function_type (type); /* All functions in C++, Pascal and Java have prototypes. */ attr = dwarf2_attr (die, DW_AT_prototyped, cu); @@ -5296,6 +5873,11 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) the default value DW_CC_normal. */ attr = dwarf2_attr (die, DW_AT_calling_convention, cu); TYPE_CALLING_CONVENTION (ftype) = attr ? DW_UNSND (attr) : DW_CC_normal; + + /* We need to add the subroutine type to the die immediately so + we don't infinitely recurse when dealing with parameters + declared as the same subroutine type. */ + set_die_type (die, ftype, cu); if (die->child != NULL) { @@ -5343,7 +5925,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) } } - return set_die_type (die, ftype, cu); + return ftype; } static struct type * @@ -5458,9 +6040,10 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) struct type *base_type; struct type *range_type; struct attribute *attr; - int low = 0; - int high = -1; + LONGEST low = 0; + LONGEST high = -1; char *name; + LONGEST negative_mask; base_type = die_type (die, cu); if (TYPE_CODE (base_type) == TYPE_CODE_VOID) @@ -5507,6 +6090,13 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) high = dwarf2_get_attr_constant_value (attr, 1); } + negative_mask = + (LONGEST) -1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1); + if (!TYPE_UNSIGNED (base_type) && (low & negative_mask)) + low |= negative_mask; + if (!TYPE_UNSIGNED (base_type) && (high & negative_mask)) + high |= negative_mask; + range_type = create_range_type (NULL, base_type, low, high); name = dwarf2_name (die, cu); @@ -5517,6 +6107,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) if (attr) TYPE_LENGTH (range_type) = DW_UNSND (attr); + set_descriptive_type (range_type, die, cu); + return set_die_type (die, range_type, cu); } @@ -5557,8 +6149,11 @@ die_eq (const void *item_lhs, const void *item_rhs) /* Read a whole compilation unit into a linked list of dies. */ static struct die_info * -read_comp_unit (gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *cu) +read_comp_unit (gdb_byte *info_ptr, struct dwarf2_cu *cu) { + struct die_reader_specs reader_specs; + + gdb_assert (cu->die_hash == NULL); cu->die_hash = htab_create_alloc_ex (cu->header.length / 12, die_hash, @@ -5568,24 +6163,33 @@ read_comp_unit (gdb_byte *info_ptr, bfd *abfd, struct dwarf2_cu *cu) hashtab_obstack_allocate, dummy_obstack_deallocate); - return read_die_and_children (info_ptr, abfd, cu, &info_ptr, NULL); + init_cu_die_reader (&reader_specs, cu); + + return read_die_and_children (&reader_specs, info_ptr, &info_ptr, NULL); } /* Main entry point for reading a DIE and all children. Read the DIE and dump it if requested. */ static struct die_info * -read_die_and_children (gdb_byte *info_ptr, bfd *abfd, - struct dwarf2_cu *cu, +read_die_and_children (const struct die_reader_specs *reader, + gdb_byte *info_ptr, gdb_byte **new_info_ptr, struct die_info *parent) { - struct die_info *result = read_die_and_children_1 (info_ptr, abfd, cu, + struct die_info *result = read_die_and_children_1 (reader, info_ptr, new_info_ptr, parent); if (dwarf2_die_debug) { - fprintf_unfiltered (gdb_stdlog, "Read die from .debug_info:\n"); + fprintf_unfiltered (gdb_stdlog, + "\nRead die from %s of %s:\n", + reader->buffer == dwarf2_per_objfile->info.buffer + ? ".debug_info" + : reader->buffer == dwarf2_per_objfile->types.buffer + ? ".debug_types" + : "unknown section", + reader->abfd->filename); dump_die (result, dwarf2_die_debug); } @@ -5599,8 +6203,8 @@ read_die_and_children (gdb_byte *info_ptr, bfd *abfd, is the parent of the die in question. */ static struct die_info * -read_die_and_children_1 (gdb_byte *info_ptr, bfd *abfd, - struct dwarf2_cu *cu, +read_die_and_children_1 (const struct die_reader_specs *reader, + gdb_byte *info_ptr, gdb_byte **new_info_ptr, struct die_info *parent) { @@ -5608,19 +6212,16 @@ read_die_and_children_1 (gdb_byte *info_ptr, bfd *abfd, gdb_byte *cur_ptr; int has_children; - cur_ptr = read_full_die (&die, abfd, info_ptr, cu, &has_children); + cur_ptr = read_full_die (reader, &die, info_ptr, &has_children); if (die == NULL) { *new_info_ptr = cur_ptr; return NULL; } - store_in_ref_table (die, cu); + store_in_ref_table (die, reader->cu); if (has_children) - { - die->child = read_die_and_siblings (cur_ptr, abfd, cu, - new_info_ptr, die); - } + die->child = read_die_and_siblings (reader, cur_ptr, new_info_ptr, die); else { die->child = NULL; @@ -5637,8 +6238,8 @@ read_die_and_children_1 (gdb_byte *info_ptr, bfd *abfd, in read_die_and_children. */ static struct die_info * -read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd, - struct dwarf2_cu *cu, +read_die_and_siblings (const struct die_reader_specs *reader, + gdb_byte *info_ptr, gdb_byte **new_info_ptr, struct die_info *parent) { @@ -5651,7 +6252,7 @@ read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd, while (1) { struct die_info *die - = read_die_and_children_1 (cur_ptr, abfd, cu, &cur_ptr, parent); + = read_die_and_children_1 (reader, cur_ptr, &cur_ptr, parent); if (die == NULL) { @@ -5668,6 +6269,54 @@ read_die_and_siblings (gdb_byte *info_ptr, bfd *abfd, } } +/* Read the die from the .debug_info section buffer. Set DIEP to + point to a newly allocated die with its information, except for its + child, sibling, and parent fields. Set HAS_CHILDREN to tell + whether the die has children or not. */ + +static gdb_byte * +read_full_die (const struct die_reader_specs *reader, + struct die_info **diep, gdb_byte *info_ptr, + int *has_children) +{ + unsigned int abbrev_number, bytes_read, i, offset; + struct abbrev_info *abbrev; + struct die_info *die; + struct dwarf2_cu *cu = reader->cu; + bfd *abfd = reader->abfd; + + offset = info_ptr - reader->buffer; + abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); + info_ptr += bytes_read; + if (!abbrev_number) + { + *diep = NULL; + *has_children = 0; + return info_ptr; + } + + abbrev = dwarf2_lookup_abbrev (abbrev_number, cu); + if (!abbrev) + error (_("Dwarf Error: could not find abbrev number %d [in module %s]"), + abbrev_number, + bfd_get_filename (abfd)); + + die = dwarf_alloc_die (cu, abbrev->num_attrs); + die->offset = offset; + die->tag = abbrev->tag; + die->abbrev = abbrev_number; + + die->num_attrs = abbrev->num_attrs; + + for (i = 0; i < abbrev->num_attrs; ++i) + info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i], + abfd, info_ptr, cu); + + *diep = die; + *has_children = abbrev->has_children; + return info_ptr; +} + /* In DWARF version 2, the description of the debugging information is stored in a separate .debug_abbrev section. Before we read any dies from a section we read in all abbreviations and install them @@ -5844,8 +6493,8 @@ is_type_tag_for_partial (int tag) /* Load all DIEs that are interesting for partial symbols into memory. */ static struct partial_die_info * -load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab, - struct dwarf2_cu *cu) +load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, + int building_psymtab, struct dwarf2_cu *cu) { struct partial_die_info *part_die; struct partial_die_info *parent_die, *last_die, *first_die = NULL; @@ -5910,12 +6559,12 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab, && abbrev->tag != DW_TAG_member) { /* Otherwise we skip to the next sibling, if any. */ - info_ptr = skip_one_die (info_ptr + bytes_read, abbrev, cu); + info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu); continue; } - info_ptr = read_partial_die (part_die, abbrev, bytes_read, - abfd, info_ptr, cu); + info_ptr = read_partial_die (part_die, abbrev, bytes_read, abfd, + buffer, info_ptr, cu); /* This two-pass algorithm for processing partial symbols has a high cost in cache pressure. Thus, handle some simple cases @@ -5941,11 +6590,11 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab, || part_die->tag == DW_TAG_subrange_type)) { if (building_psymtab && part_die->name != NULL) - add_psymbol_to_list (part_die->name, strlen (part_die->name), + add_psymbol_to_list (part_die->name, strlen (part_die->name), 0, VAR_DOMAIN, LOC_TYPEDEF, &cu->objfile->static_psymbols, 0, (CORE_ADDR) 0, cu->language, cu->objfile); - info_ptr = locate_pdi_sibling (part_die, info_ptr, abfd, cu); + info_ptr = locate_pdi_sibling (part_die, buffer, info_ptr, abfd, cu); continue; } @@ -5962,7 +6611,7 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab, if (part_die->name == NULL) complaint (&symfile_complaints, _("malformed enumerator DIE ignored")); else if (building_psymtab) - add_psymbol_to_list (part_die->name, strlen (part_die->name), + add_psymbol_to_list (part_die->name, strlen (part_die->name), 0, VAR_DOMAIN, LOC_CONST, (cu->language == language_cplus || cu->language == language_java) @@ -5970,7 +6619,7 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab, : &cu->objfile->static_psymbols, 0, (CORE_ADDR) 0, cu->language, cu->objfile); - info_ptr = locate_pdi_sibling (part_die, info_ptr, abfd, cu); + info_ptr = locate_pdi_sibling (part_die, buffer, info_ptr, abfd, cu); continue; } @@ -6054,7 +6703,7 @@ load_partial_dies (bfd *abfd, gdb_byte *info_ptr, int building_psymtab, } /* Otherwise we skip to the next sibling, if any. */ - info_ptr = locate_pdi_sibling (last_die, info_ptr, abfd, cu); + info_ptr = locate_pdi_sibling (last_die, buffer, info_ptr, abfd, cu); /* Back to the top, do it again. */ } @@ -6066,25 +6715,17 @@ static gdb_byte * read_partial_die (struct partial_die_info *part_die, struct abbrev_info *abbrev, unsigned int abbrev_len, bfd *abfd, - gdb_byte *info_ptr, struct dwarf2_cu *cu) + gdb_byte *buffer, gdb_byte *info_ptr, + struct dwarf2_cu *cu) { unsigned int bytes_read, i; struct attribute attr; int has_low_pc_attr = 0; int has_high_pc_attr = 0; - CORE_ADDR base_address = 0; - enum - { - base_address_none, - base_address_low_pc, - /* Overrides BASE_ADDRESS_LOW_PC. */ - base_address_entry_pc - } - base_address_type = base_address_none; memset (part_die, 0, sizeof (struct partial_die_info)); - part_die->offset = info_ptr - dwarf2_per_objfile->info.buffer; + part_die->offset = info_ptr - buffer; info_ptr += abbrev_len; @@ -6106,6 +6747,7 @@ read_partial_die (struct partial_die_info *part_die, switch (part_die->tag) { case DW_TAG_compile_unit: + case DW_TAG_type_unit: /* Compilation units have a DW_AT_name that is a filename, not a source language identifier. */ case DW_TAG_enumeration_type: @@ -6117,46 +6759,21 @@ read_partial_die (struct partial_die_info *part_die, default: part_die->name = dwarf2_canonicalize_name (DW_STRING (&attr), cu, - &cu->comp_unit_obstack); + &cu->objfile->objfile_obstack); break; } break; - case DW_AT_comp_dir: - if (part_die->dirname == NULL) - part_die->dirname = DW_STRING (&attr); - break; case DW_AT_MIPS_linkage_name: part_die->name = DW_STRING (&attr); break; case DW_AT_low_pc: has_low_pc_attr = 1; part_die->lowpc = DW_ADDR (&attr); - if (part_die->tag == DW_TAG_compile_unit - && base_address_type < base_address_low_pc) - { - base_address = DW_ADDR (&attr); - base_address_type = base_address_low_pc; - } break; case DW_AT_high_pc: has_high_pc_attr = 1; part_die->highpc = DW_ADDR (&attr); break; - case DW_AT_entry_pc: - if (part_die->tag == DW_TAG_compile_unit - && base_address_type < base_address_entry_pc) - { - base_address = DW_ADDR (&attr); - base_address_type = base_address_entry_pc; - } - break; - case DW_AT_ranges: - if (part_die->tag == DW_TAG_compile_unit) - { - cu->ranges_offset = DW_UNSND (&attr); - cu->has_ranges_offset = 1; - } - break; case DW_AT_location: /* Support the .debug_loc offsets */ if (attr_form_is_block (&attr)) @@ -6173,9 +6790,6 @@ read_partial_die (struct partial_die_info *part_die, "partial symbol information"); } break; - case DW_AT_language: - part_die->language = DW_UNSND (&attr); - break; case DW_AT_external: part_die->is_external = DW_UNSND (&attr); break; @@ -6197,13 +6811,8 @@ read_partial_die (struct partial_die_info *part_die, if (attr.form == DW_FORM_ref_addr) complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling")); else - part_die->sibling = dwarf2_per_objfile->info.buffer - + dwarf2_get_ref_die_offset (&attr); + part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr); break; - case DW_AT_stmt_list: - part_die->has_stmt_list = 1; - part_die->line_offset = DW_UNSND (&attr); - break; case DW_AT_byte_size: part_die->has_byte_size = 1; break; @@ -6241,16 +6850,9 @@ read_partial_die (struct partial_die_info *part_die, so that GDB will ignore it. */ if (has_low_pc_attr && has_high_pc_attr && part_die->lowpc < part_die->highpc - && (part_die->lowpc != 0 - || dwarf2_per_objfile->has_section_at_zero)) - part_die->has_pc_info = 1; - - if (base_address_type != base_address_none && !cu->base_known) - { - gdb_assert (part_die->tag == DW_TAG_compile_unit); - cu->base_known = 1; - cu->base_address = base_address; - } + && (part_die->lowpc != 0 + || dwarf2_per_objfile->has_section_at_zero)) + part_die->has_pc_info = 1; return info_ptr; } @@ -6269,7 +6871,10 @@ find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu) return lookup_die; } -/* Find a partial DIE at OFFSET, which may or may not be in CU. */ +/* Find a partial DIE at OFFSET, which may or may not be in CU, + except in the case of .debug_types DIEs which do not reference + outside their CU (they do however referencing other types via + DW_FORM_sig8). */ static struct partial_die_info * find_partial_die (unsigned int offset, struct dwarf2_cu *cu) @@ -6277,6 +6882,14 @@ find_partial_die (unsigned int offset, struct dwarf2_cu *cu) struct dwarf2_per_cu_data *per_cu = NULL; struct partial_die_info *pd = NULL; + if (cu->per_cu->from_debug_types) + { + pd = find_partial_die_in_comp_unit (offset, cu); + if (pd != NULL) + return pd; + goto not_found; + } + if (offset_in_cu_p (&cu->header, offset)) { pd = find_partial_die_in_comp_unit (offset, cu); @@ -6288,7 +6901,7 @@ find_partial_die (unsigned int offset, struct dwarf2_cu *cu) if (per_cu->cu == NULL) { - load_comp_unit (per_cu, cu->objfile); + load_partial_comp_unit (per_cu, cu->objfile); per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; dwarf2_per_objfile->read_in_chain = per_cu; } @@ -6311,22 +6924,27 @@ find_partial_die (unsigned int offset, struct dwarf2_cu *cu) if (per_cu->cu->dwarf2_abbrevs == NULL) { dwarf2_read_abbrevs (per_cu->cu->objfile->obfd, per_cu->cu); - back_to = make_cleanup (dwarf2_free_abbrev_table, per_cu->cu); + make_cleanup (dwarf2_free_abbrev_table, per_cu->cu); } info_ptr = (dwarf2_per_objfile->info.buffer + per_cu->cu->header.offset + per_cu->cu->header.first_die_offset); abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu); info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, - per_cu->cu->objfile->obfd, info_ptr, + per_cu->cu->objfile->obfd, + dwarf2_per_objfile->info.buffer, info_ptr, per_cu->cu); if (comp_unit_die.has_children) - load_partial_dies (per_cu->cu->objfile->obfd, info_ptr, 0, per_cu->cu); + load_partial_dies (per_cu->cu->objfile->obfd, + dwarf2_per_objfile->info.buffer, info_ptr, + 0, per_cu->cu); do_cleanups (back_to); pd = find_partial_die_in_comp_unit (offset, per_cu->cu); } + not_found: + if (pd == NULL) internal_error (__FILE__, __LINE__, _("could not find partial DIE 0x%x in cache [from module %s]\n"), @@ -6376,52 +6994,6 @@ fixup_partial_die (struct partial_die_info *part_die, guess_structure_name (part_die, cu); } -/* Read the die from the .debug_info section buffer. Set DIEP to - point to a newly allocated die with its information, except for its - child, sibling, and parent fields. Set HAS_CHILDREN to tell - whether the die has children or not. */ - -static gdb_byte * -read_full_die (struct die_info **diep, bfd *abfd, gdb_byte *info_ptr, - struct dwarf2_cu *cu, int *has_children) -{ - unsigned int abbrev_number, bytes_read, i, offset; - struct abbrev_info *abbrev; - struct die_info *die; - - offset = info_ptr - dwarf2_per_objfile->info.buffer; - abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - if (!abbrev_number) - { - *diep = NULL; - *has_children = 0; - return info_ptr; - } - - abbrev = dwarf2_lookup_abbrev (abbrev_number, cu); - if (!abbrev) - { - error (_("Dwarf Error: could not find abbrev number %d [in module %s]"), - abbrev_number, - bfd_get_filename (abfd)); - } - die = dwarf_alloc_die (cu, abbrev->num_attrs); - die->offset = offset; - die->tag = abbrev->tag; - die->abbrev = abbrev_number; - - die->num_attrs = abbrev->num_attrs; - - for (i = 0; i < abbrev->num_attrs; ++i) - info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i], - abfd, info_ptr, cu); - - *diep = die; - *has_children = abbrev->has_children; - return info_ptr; -} - /* Read an attribute value described by an attribute form. */ static gdb_byte * @@ -6471,11 +7043,13 @@ read_attribute_value (struct attribute *attr, unsigned form, break; case DW_FORM_string: DW_STRING (attr) = read_string (abfd, info_ptr, &bytes_read); + DW_STRING_IS_CANONICAL (attr) = 0; info_ptr += bytes_read; break; case DW_FORM_strp: DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header, &bytes_read); + DW_STRING_IS_CANONICAL (attr) = 0; info_ptr += bytes_read; break; case DW_FORM_block: @@ -6526,6 +7100,14 @@ read_attribute_value (struct attribute *attr, unsigned form, DW_ADDR (attr) = cu->header.offset + read_8_bytes (abfd, info_ptr); info_ptr += 8; break; + case DW_FORM_sig8: + /* Convert the signature to something we can record in DW_UNSND + for later lookup. + NOTE: This is NULL if the type wasn't found. */ + DW_SIGNATURED_TYPE (attr) = + lookup_signatured_type (cu->objfile, read_8_bytes (abfd, info_ptr)); + info_ptr += 8; + break; case DW_FORM_ref_udata: DW_ADDR (attr) = (cu->header.offset + read_unsigned_leb128 (abfd, info_ptr, &bytes_read)); @@ -6554,8 +7136,8 @@ read_attribute_value (struct attribute *attr, unsigned form, { complaint (&symfile_complaints, - _("Suspicious DW_AT_byte_size value treated as zero instead of 0x%lx"), - DW_UNSND (attr)); + _("Suspicious DW_AT_byte_size value treated as zero instead of %s"), + hex_string (DW_UNSND (attr))); DW_UNSND (attr) = 0; } @@ -6610,7 +7192,7 @@ read_4_signed_bytes (bfd *abfd, gdb_byte *buf) return bfd_get_signed_32 (abfd, buf); } -static unsigned long +static ULONGEST read_8_bytes (bfd *abfd, gdb_byte *buf) { return bfd_get_64 (abfd, buf); @@ -6988,6 +7570,25 @@ dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu) return NULL; } +/* Return the named attribute or NULL if not there, + but do not follow DW_AT_specification, etc. + This is for use in contexts where we're reading .debug_types dies. + Following DW_AT_specification, DW_AT_abstract_origin will take us + back up the chain, and we want to go down. */ + +static struct attribute * +dwarf2_attr_no_follow (struct die_info *die, unsigned int name, + struct dwarf2_cu *cu) +{ + unsigned int i; + + for (i = 0; i < die->num_attrs; ++i) + if (die->attrs[i].name == name) + return &die->attrs[i]; + + return NULL; +} + /* Return non-zero iff the attribute NAME is defined for the given DIE, and holds a non-zero value. This function should only be used for DW_FORM_flag attributes. */ @@ -7016,7 +7617,9 @@ die_is_declaration (struct die_info *die, struct dwarf2_cu *cu) /* Return the die giving the specification for DIE, if there is one. *SPEC_CU is the CU containing DIE on input, and the CU - containing the return value on output. */ + containing the return value on output. If there is no + specification, but there is an abstract origin, that is + returned. */ static struct die_info * die_specification (struct die_info *die, struct dwarf2_cu **spec_cu) @@ -7024,6 +7627,9 @@ die_specification (struct die_info *die, struct dwarf2_cu **spec_cu) struct attribute *spec_attr = dwarf2_attr (die, DW_AT_specification, *spec_cu); + if (spec_attr == NULL) + spec_attr = dwarf2_attr (die, DW_AT_abstract_origin, *spec_cu); + if (spec_attr == NULL) return NULL; else @@ -7353,7 +7959,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, else { lh->file_names[file - 1].included_p = 1; - if (!decode_for_pst_p) + if (!decode_for_pst_p && is_stmt) { if (last_subfile != current_subfile) { @@ -7368,7 +7974,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, record_line (current_subfile, line, addr); } } - basic_block = 1; + basic_block = 0; } else switch (op_code) { @@ -7433,7 +8039,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd, else { lh->file_names[file - 1].included_p = 1; - if (!decode_for_pst_p) + if (!decode_for_pst_p && is_stmt) { if (last_subfile != current_subfile) { @@ -7714,12 +8320,12 @@ static struct symbol * new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; - struct gdbarch *gdbarch = get_objfile_arch (objfile); struct symbol *sym = NULL; char *name; struct attribute *attr = NULL; struct attribute *attr2 = NULL; CORE_ADDR baseaddr; + int inlined_func = (die->tag == DW_TAG_inlined_subroutine); baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -7737,7 +8343,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) /* Cache this symbol's name and the name's demangled form (if any). */ SYMBOL_LANGUAGE (sym) = cu->language; - SYMBOL_SET_NAMES (sym, name, strlen (name), objfile); + SYMBOL_SET_NAMES (sym, name, strlen (name), 0, objfile); /* Default assumptions. Use the passed type or decode it from the die. */ @@ -7747,13 +8353,17 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) SYMBOL_TYPE (sym) = type; else SYMBOL_TYPE (sym) = die_type (die, cu); - attr = dwarf2_attr (die, DW_AT_decl_line, cu); + attr = dwarf2_attr (die, + inlined_func ? DW_AT_call_line : DW_AT_decl_line, + cu); if (attr) { SYMBOL_LINE (sym) = DW_UNSND (attr); } - attr = dwarf2_attr (die, DW_AT_decl_file, cu); + attr = dwarf2_attr (die, + inlined_func ? DW_AT_call_file : DW_AT_decl_file, + cu); if (attr) { int file_index = DW_UNSND (attr); @@ -7800,13 +8410,21 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) add_symbol_to_list (sym, cu->list_in_scope); } break; + case DW_TAG_inlined_subroutine: + /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by + finish_block. */ + SYMBOL_CLASS (sym) = LOC_BLOCK; + SYMBOL_INLINED (sym) = 1; + /* Do not add the symbol to any lists. It will be found via + BLOCK_FUNCTION from the blockvector. */ + break; case DW_TAG_variable: /* Compilation with minimal debug info may result in variables with missing type entries. Change the misleading `void' type to something sensible. */ if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID) SYMBOL_TYPE (sym) - = builtin_type (gdbarch)->nodebug_data_symbol; + = objfile_type (objfile)->nodebug_data_symbol; attr = dwarf2_attr (die, DW_AT_const_value, cu); if (attr) @@ -7841,8 +8459,15 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) if (attr2 && (DW_UNSND (attr2) != 0) && dwarf2_attr (die, DW_AT_type, cu) != NULL) { + struct pending **list_to_add; + + /* A variable with DW_AT_external is never static, but it + may be block-scoped. */ + list_to_add = (cu->list_in_scope == &file_symbols + ? &global_symbols : cu->list_in_scope); + SYMBOL_CLASS (sym) = LOC_UNRESOLVED; - add_symbol_to_list (sym, cu->list_in_scope); + add_symbol_to_list (sym, list_to_add); } else if (!die_is_declaration (die, cu)) { @@ -7853,7 +8478,14 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) } break; case DW_TAG_formal_parameter: - SYMBOL_IS_ARGUMENT (sym) = 1; + /* If we are inside a function, mark this as an argument. If + not, we might be looking at an argument to an inlined function + when we do not have enough information to show inlined frames; + pretend it's a local variable in that case so that the user can + still see it. */ + if (context_stack_depth > 0 + && context_stack[context_stack_depth - 1].name != NULL) + SYMBOL_IS_ARGUMENT (sym) = 1; attr = dwarf2_attr (die, DW_AT_location, cu); if (attr) { @@ -8000,6 +8632,8 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym, { struct objfile *objfile = cu->objfile; struct comp_unit_head *cu_header = &cu->header; + enum bfd_endian byte_order = bfd_big_endian (objfile->obfd) ? + BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE; struct dwarf_block *blk; switch (attr->form) @@ -8015,7 +8649,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym, /* NOTE: cagney/2003-05-09: In-lined store_address call with it's body - store_unsigned_integer. */ store_unsigned_integer (SYMBOL_VALUE_BYTES (sym), cu_header->addr_size, - DW_ADDR (attr)); + byte_order, DW_ADDR (attr)); SYMBOL_CLASS (sym) = LOC_CONST_BYTES; break; case DW_FORM_string: @@ -8107,7 +8741,6 @@ dwarf2_const_value_data (struct attribute *attr, static struct type * die_type (struct die_info *die, struct dwarf2_cu *cu) { - struct gdbarch *gdbarch = get_objfile_arch (cu->objfile); struct type *type; struct attribute *type_attr; struct die_info *type_die; @@ -8116,11 +8749,56 @@ die_type (struct die_info *die, struct dwarf2_cu *cu) if (!type_attr) { /* A missing DW_AT_type represents a void type. */ - return builtin_type (gdbarch)->builtin_void; + return objfile_type (cu->objfile)->builtin_void; } - else - type_die = follow_die_ref (die, type_attr, &cu); + type_die = follow_die_ref_or_sig (die, type_attr, &cu); + + type = tag_type_to_type (type_die, cu); + if (!type) + { + dump_die_for_error (type_die); + error (_("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]"), + cu->objfile->name); + } + return type; +} + +/* True iff CU's producer generates GNAT Ada auxiliary information + that allows to find parallel types through that information instead + of having to do expensive parallel lookups by type name. */ + +static int +need_gnat_info (struct dwarf2_cu *cu) +{ + /* FIXME: brobecker/2010-10-12: As of now, only the AdaCore version + of GNAT produces this auxiliary information, without any indication + that it is produced. Part of enhancing the FSF version of GNAT + to produce that information will be to put in place an indicator + that we can use in order to determine whether the descriptive type + info is available or not. One suggestion that has been made is + to use a new attribute, attached to the CU die. For now, assume + that the descriptive type info is not available. */ + return 0; +} + + +/* Return the auxiliary type of the die in question using its + DW_AT_GNAT_descriptive_type attribute. Returns NULL if the + attribute is not present. */ + +static struct type * +die_descriptive_type (struct die_info *die, struct dwarf2_cu *cu) +{ + struct type *type; + struct attribute *type_attr; + struct die_info *type_die; + + type_attr = dwarf2_attr (die, DW_AT_GNAT_descriptive_type, cu); + if (!type_attr) + return NULL; + + type_die = follow_die_ref (die, type_attr, &cu); type = tag_type_to_type (type_die, cu); if (!type) { @@ -8131,6 +8809,22 @@ die_type (struct die_info *die, struct dwarf2_cu *cu) return type; } +/* If DIE has a descriptive_type attribute, then set the TYPE's + descriptive type accordingly. */ + +static void +set_descriptive_type (struct type *type, struct die_info *die, + struct dwarf2_cu *cu) +{ + struct type *descriptive_type = die_descriptive_type (die, cu); + + if (descriptive_type) + { + ALLOCATE_GNAT_AUX_TYPE (type); + TYPE_DESCRIPTIVE_TYPE (type) = descriptive_type; + } +} + /* Return the containing type of the die in question using its DW_AT_containing_type attribute. */ @@ -8144,7 +8838,7 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu) type_attr = dwarf2_attr (die, DW_AT_containing_type, cu); if (type_attr) { - type_die = follow_die_ref (die, type_attr, &cu); + type_die = follow_die_ref_or_sig (die, type_attr, &cu); type = tag_type_to_type (type_die, cu); } if (!type) @@ -8194,6 +8888,7 @@ read_type_die (struct die_info *die, struct dwarf2_cu *cu) break; case DW_TAG_subprogram: case DW_TAG_subroutine_type: + case DW_TAG_inlined_subroutine: this_type = read_subroutine_type (die, cu); break; case DW_TAG_array_type: @@ -8432,12 +9127,12 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) to canonicalize them. */ return DW_STRING (attr); default: - if (attr->form != GDB_FORM_cached_string) + if (!DW_STRING_IS_CANONICAL (attr)) { DW_STRING (attr) = dwarf2_canonicalize_name (DW_STRING (attr), cu, &cu->objfile->objfile_obstack); - attr->form = GDB_FORM_cached_string; + DW_STRING_IS_CANONICAL (attr) = 1; } return DW_STRING (attr); } @@ -8582,6 +9277,8 @@ dwarf_tag_name (unsigned tag) return "DW_TAG_condition"; case DW_TAG_shared_type: return "DW_TAG_shared_type"; + case DW_TAG_type_unit: + return "DW_TAG_type_unit"; case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop"; case DW_TAG_HP_array_descriptor: @@ -8797,6 +9494,9 @@ dwarf_attr_name (unsigned attr) return "DW_AT_pure"; case DW_AT_recursive: return "DW_AT_recursive"; + /* DWARF 4 values. */ + case DW_AT_signature: + return "DW_AT_signature"; /* SGI/MIPS extensions. */ #ifdef MIPS /* collides with DW_AT_HP_block_index */ case DW_AT_MIPS_fde: @@ -8935,8 +9635,14 @@ dwarf_form_name (unsigned form) return "DW_FORM_ref_udata"; case DW_FORM_indirect: return "DW_FORM_indirect"; - case GDB_FORM_cached_string: - return "GDB_FORM_cached_string"; + case DW_FORM_sec_offset: + return "DW_FORM_sec_offset"; + case DW_FORM_exprloc: + return "DW_FORM_exprloc"; + case DW_FORM_flag_present: + return "DW_FORM_flag_present"; + case DW_FORM_sig8: + return "DW_FORM_sig8"; default: return "DW_FORM_"; } @@ -9458,7 +10164,7 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) case DW_FORM_ref_addr: case DW_FORM_addr: fprintf_unfiltered (f, "address: "); - fputs_filtered (paddress (DW_ADDR (&die->attrs[i])), f); + fputs_filtered (hex_string (DW_ADDR (&die->attrs[i])), f); break; case DW_FORM_block2: case DW_FORM_block4: @@ -9478,14 +10184,22 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) case DW_FORM_data8: case DW_FORM_udata: case DW_FORM_sdata: - fprintf_unfiltered (f, "constant: %ld", DW_UNSND (&die->attrs[i])); + fprintf_unfiltered (f, "constant: %s", + pulongest (DW_UNSND (&die->attrs[i]))); + break; + case DW_FORM_sig8: + if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL) + fprintf_unfiltered (f, "signatured type, offset: 0x%x", + DW_SIGNATURED_TYPE (&die->attrs[i])->offset); + else + fprintf_unfiltered (f, "signatured type, offset: unknown"); break; case DW_FORM_string: case DW_FORM_strp: - case GDB_FORM_cached_string: - fprintf_unfiltered (f, "string: \"%s\"", + fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)", DW_STRING (&die->attrs[i]) - ? DW_STRING (&die->attrs[i]) : ""); + ? DW_STRING (&die->attrs[i]) : "", + DW_STRING_IS_CANONICAL (&die->attrs[i]) ? "is" : "not"); break; case DW_FORM_flag: if (DW_UNSND (&die->attrs[i])) @@ -9565,11 +10279,9 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu) *slot = die; } -static unsigned int -dwarf2_get_ref_die_offset (struct attribute *attr) +static int +is_ref_attr (struct attribute *attr) { - unsigned int result = 0; - switch (attr->form) { case DW_FORM_ref_addr: @@ -9578,20 +10290,28 @@ dwarf2_get_ref_die_offset (struct attribute *attr) case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: - result = DW_ADDR (attr); - break; + return 1; default: - complaint (&symfile_complaints, - _("unsupported die ref attribute form: '%s'"), - dwarf_form_name (attr->form)); + return 0; } - return result; } -/* Return the constant value held by the given attribute. Return -1 - if the value held by the attribute is not constant. */ +static unsigned int +dwarf2_get_ref_die_offset (struct attribute *attr) +{ + if (is_ref_attr (attr)) + return DW_ADDR (attr); -static int + complaint (&symfile_complaints, + _("unsupported die ref attribute form: '%s'"), + dwarf_form_name (attr->form)); + return 0; +} + +/* Return the constant value held by ATTR. Return DEFAULT_VALUE if + * the value held by the attribute is not constant. */ + +static LONGEST dwarf2_get_attr_constant_value (struct attribute *attr, int default_value) { if (attr->form == DW_FORM_sdata) @@ -9611,9 +10331,11 @@ dwarf2_get_attr_constant_value (struct attribute *attr, int default_value) } /* THIS_CU has a reference to PER_CU. If necessary, load the new compilation - unit and add it to our queue. */ + unit and add it to our queue. + The result is non-zero if PER_CU was queued, otherwise the result is zero + meaning either PER_CU is already queued or it is already loaded. */ -static void +static int maybe_queue_comp_unit (struct dwarf2_cu *this_cu, struct dwarf2_per_cu_data *per_cu) { @@ -9623,18 +10345,44 @@ maybe_queue_comp_unit (struct dwarf2_cu *this_cu, /* If it's already on the queue, we have nothing to do. */ if (per_cu->queued) - return; + return 0; /* If the compilation unit is already loaded, just mark it as used. */ if (per_cu->cu != NULL) { per_cu->cu->last_used = 0; - return; + return 0; } /* Add it to the queue. */ queue_comp_unit (per_cu, this_cu->objfile); + + return 1; +} + +/* Follow reference or signature attribute ATTR of SRC_DIE. + On entry *REF_CU is the CU of SRC_DIE. + On exit *REF_CU is the CU of the result. */ + +static struct die_info * +follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr, + struct dwarf2_cu **ref_cu) +{ + struct die_info *die; + + if (is_ref_attr (attr)) + die = follow_die_ref (src_die, attr, ref_cu); + else if (attr->form == DW_FORM_sig8) + die = follow_die_sig (src_die, attr, ref_cu); + else + { + dump_die_for_error (src_die); + error (_("Dwarf Error: Expected reference attribute [in module %s]"), + (*ref_cu)->objfile->name); + } + + return die; } /* Follow reference attribute ATTR of SRC_DIE. @@ -9650,15 +10398,27 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr, struct die_info temp_die; struct dwarf2_cu *target_cu, *cu = *ref_cu; + gdb_assert (cu->per_cu != NULL); + offset = dwarf2_get_ref_die_offset (attr); - if (! offset_in_cu_p (&cu->header, offset)) + if (cu->per_cu->from_debug_types) + { + /* .debug_types CUs cannot reference anything outside their CU. + If they need to, they have to reference a signatured type via + DW_FORM_sig8. */ + if (! offset_in_cu_p (&cu->header, offset)) + goto not_found; + target_cu = cu; + } + else if (! offset_in_cu_p (&cu->header, offset)) { struct dwarf2_per_cu_data *per_cu; per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile); /* If necessary, add it to the queue and load its DIEs. */ - maybe_queue_comp_unit (cu, per_cu); + if (maybe_queue_comp_unit (cu, per_cu)) + load_full_comp_unit (per_cu, cu->objfile); target_cu = per_cu->cu; } @@ -9671,9 +10431,164 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr, if (die) return die; - error (_("Dwarf Error: Cannot find DIE at 0x%lx referenced from DIE " - "at 0x%lx [in module %s]"), - (long) offset, (long) src_die->offset, cu->objfile->name); + not_found: + + error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE " + "at 0x%x [in module %s]"), + offset, src_die->offset, cu->objfile->name); +} + +/* Follow the signature attribute ATTR in SRC_DIE. + On entry *REF_CU is the CU of SRC_DIE. + On exit *REF_CU is the CU of the result. */ + +static struct die_info * +follow_die_sig (struct die_info *src_die, struct attribute *attr, + struct dwarf2_cu **ref_cu) +{ + struct objfile *objfile = (*ref_cu)->objfile; + struct die_info temp_die; + struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr); + struct dwarf2_cu *sig_cu; + struct die_info *die; + + /* sig_type will be NULL if the signatured type is missing from + the debug info. */ + if (sig_type == NULL) + error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE " + "at 0x%x [in module %s]"), + src_die->offset, objfile->name); + + /* If necessary, add it to the queue and load its DIEs. */ + + if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu)) + read_signatured_type (objfile, sig_type); + + gdb_assert (sig_type->per_cu.cu != NULL); + + sig_cu = sig_type->per_cu.cu; + temp_die.offset = sig_cu->header.offset + sig_type->type_offset; + die = htab_find_with_hash (sig_cu->die_hash, &temp_die, temp_die.offset); + if (die) + { + *ref_cu = sig_cu; + return die; + } + + error (_("Dwarf Error: Cannot find signatured DIE at 0x%x referenced from DIE " + "at 0x%x [in module %s]"), + sig_type->type_offset, src_die->offset, objfile->name); +} + +/* Given an offset of a signatured type, return its signatured_type. */ + +static struct signatured_type * +lookup_signatured_type_at_offset (struct objfile *objfile, unsigned int offset) +{ + gdb_byte *info_ptr = dwarf2_per_objfile->types.buffer + offset; + unsigned int length, initial_length_size; + unsigned int sig_offset; + struct signatured_type find_entry, *type_sig; + + length = read_initial_length (objfile->obfd, info_ptr, &initial_length_size); + sig_offset = (initial_length_size + + 2 /*version*/ + + (initial_length_size == 4 ? 4 : 8) /*debug_abbrev_offset*/ + + 1 /*address_size*/); + find_entry.signature = bfd_get_64 (objfile->obfd, info_ptr + sig_offset); + type_sig = htab_find (dwarf2_per_objfile->signatured_types, &find_entry); + + /* This is only used to lookup previously recorded types. + If we didn't find it, it's our bug. */ + gdb_assert (type_sig != NULL); + gdb_assert (offset == type_sig->offset); + + return type_sig; +} + +/* Read in signatured type at OFFSET and build its CU and die(s). */ + +static void +read_signatured_type_at_offset (struct objfile *objfile, + unsigned int offset) +{ + struct signatured_type *type_sig; + + /* We have the section offset, but we need the signature to do the + hash table lookup. */ + type_sig = lookup_signatured_type_at_offset (objfile, offset); + + gdb_assert (type_sig->per_cu.cu == NULL); + + read_signatured_type (objfile, type_sig); + + gdb_assert (type_sig->per_cu.cu != NULL); +} + +/* Read in a signatured type and build its CU and DIEs. */ + +static void +read_signatured_type (struct objfile *objfile, + struct signatured_type *type_sig) +{ + gdb_byte *types_ptr = dwarf2_per_objfile->types.buffer + type_sig->offset; + struct die_reader_specs reader_specs; + struct dwarf2_cu *cu; + ULONGEST signature; + struct cleanup *back_to, *free_cu_cleanup; + struct attribute *attr; + + gdb_assert (type_sig->per_cu.cu == NULL); + + cu = xmalloc (sizeof (struct dwarf2_cu)); + memset (cu, 0, sizeof (struct dwarf2_cu)); + obstack_init (&cu->comp_unit_obstack); + cu->objfile = objfile; + type_sig->per_cu.cu = cu; + cu->per_cu = &type_sig->per_cu; + + /* If an error occurs while loading, release our storage. */ + free_cu_cleanup = make_cleanup (free_one_comp_unit, cu); + + types_ptr = read_type_comp_unit_head (&cu->header, &signature, + types_ptr, objfile->obfd); + gdb_assert (signature == type_sig->signature); + + cu->die_hash + = htab_create_alloc_ex (cu->header.length / 12, + die_hash, + die_eq, + NULL, + &cu->comp_unit_obstack, + hashtab_obstack_allocate, + dummy_obstack_deallocate); + + dwarf2_read_abbrevs (cu->objfile->obfd, cu); + back_to = make_cleanup (dwarf2_free_abbrev_table, cu); + + init_cu_die_reader (&reader_specs, cu); + + cu->dies = read_die_and_children (&reader_specs, types_ptr, &types_ptr, + NULL /*parent*/); + + /* We try not to read any attributes in this function, because not + all objfiles needed for references have been loaded yet, and symbol + table processing isn't initialized. But we have to set the CU language, + or we won't be able to build types correctly. */ + attr = dwarf2_attr (cu->dies, DW_AT_language, cu); + if (attr) + set_cu_language (DW_UNSND (attr), cu); + else + set_cu_language (language_minimal, cu); + + do_cleanups (back_to); + + /* We've successfully allocated this compilation unit. Let our caller + clean it up when finished with it. */ + discard_cleanups (free_cu_cleanup); + + type_sig->per_cu.cu->read_in_chain = dwarf2_per_objfile->read_in_chain; + dwarf2_per_objfile->read_in_chain = &type_sig->per_cu; } /* Decode simple location descriptions. @@ -10349,20 +11264,22 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, complaint (&symfile_complaints, _("debug info with no main source gives macro %s " "on line %d: %s"), - macinfo_type == - DW_MACINFO_define ? _("definition") : macinfo_type == - DW_MACINFO_undef ? _("undefinition") : - "something-or-other", line, body); + macinfo_type == DW_MACINFO_define ? + _("definition") : + macinfo_type == DW_MACINFO_undef ? + _("undefinition") : + _("something-or-other"), line, body); break; } if ((line == 0 && !at_commandline) || (line != 0 && at_commandline)) complaint (&symfile_complaints, _("debug info gives %s macro %s with %s line %d: %s"), at_commandline ? _("command-line") : _("in-file"), - macinfo_type == - DW_MACINFO_define ? _("definition") : macinfo_type == - DW_MACINFO_undef ? _("undefinition") : - "something-or-other", + macinfo_type == DW_MACINFO_define ? + _("definition") : + macinfo_type == DW_MACINFO_undef ? + _("undefinition") : + _("something-or-other"), line == 0 ? _("zero") : _("non-zero"), line, body); if (macinfo_type == DW_MACINFO_define) @@ -10609,8 +11526,8 @@ dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu) } } -/* Locate the compilation unit from CU's objfile which contains the - DIE at OFFSET. Raises an error on failure. */ +/* Locate the .debug_info compilation unit from CU's objfile which contains + the DIE at OFFSET. Raises an error on failure. */ static struct dwarf2_per_cu_data * dwarf2_find_containing_comp_unit (unsigned int offset, @@ -10664,9 +11581,22 @@ dwarf2_find_comp_unit (unsigned int offset, struct objfile *objfile) return this_cu; } +/* Malloc space for a dwarf2_cu for OBJFILE and initialize it. */ + +static struct dwarf2_cu * +alloc_one_comp_unit (struct objfile *objfile) +{ + struct dwarf2_cu *cu = xcalloc (1, sizeof (struct dwarf2_cu)); + cu->objfile = objfile; + obstack_init (&cu->comp_unit_obstack); + return cu; +} + /* Release one cached compilation unit, CU. We unlink it from the tree of compilation units, but we don't remove it from the read_in_chain; - the caller is responsible for that. */ + the caller is responsible for that. + NOTE: DATA is a void * because this function is also used as a + cleanup routine. */ static void free_one_comp_unit (void *data) @@ -10851,6 +11781,19 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) { struct dwarf2_offset_and_type **slot, ofs; + /* For Ada types, make sure that the gnat-specific data is always + initialized (if not already set). There are a few types where + we should not be doing so, because the type-specific area is + already used to hold some other piece of info (eg: TYPE_CODE_FLT + where the type-specific area is used to store the floatformat). + But this is not a problem, because the gnat-specific information + is actually not needed for these types. */ + if (need_gnat_info (cu) + && TYPE_CODE (type) != TYPE_CODE_FUNC + && TYPE_CODE (type) != TYPE_CODE_FLT + && !HAVE_GNAT_AUX_INFO (type)) + INIT_GNAT_SPECIFIC (type); + if (cu->type_hash == NULL) { gdb_assert (cu->per_cu != NULL); @@ -11015,7 +11958,7 @@ munmap_section_buffer (struct dwarf2_section_info *info) /* munmap debug sections for OBJFILE, if necessary. */ static void -dwarf2_per_objfile_cleanup (struct objfile *objfile, void *d) +dwarf2_per_objfile_free (struct objfile *objfile, void *d) { struct dwarf2_per_objfile *data = d; munmap_section_buffer (&data->info); @@ -11035,7 +11978,7 @@ void _initialize_dwarf2_read (void) { dwarf2_objfile_data_key - = register_objfile_data_with_cleanup (dwarf2_per_objfile_cleanup); + = register_objfile_data_with_cleanup (NULL, dwarf2_per_objfile_free); add_prefix_cmd ("dwarf2", class_maintenance, set_dwarf2_cmd, _("\ Set DWARF 2 specific variables.\n\