X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=1514e1393c00f4c941a05c971ce54ddb1139e8a8;hb=9703b51377ca945155cb74f09761fe6fb0431613;hp=c79f2bedd6d781405e99d7f01b0e4a75ddbd0862;hpb=08711b9a36344df9e29be436d9f959324fff4f42;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index c79f2bedd6..1514e1393c 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1,8 +1,6 @@ /* 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, 2010, 2011 - Free Software Foundation, Inc. + Copyright (C) 1994-2012 Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, Inc. with support from Florida State University (under contract @@ -26,6 +24,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +/* FIXME: Various die-reading functions need to be more careful with + reading off the end of the section. + E.g., load_partial_dies, read_partial_die. */ + #include "defs.h" #include "bfd.h" #include "symtab.h" @@ -34,6 +36,7 @@ #include "dwarf2.h" #include "buildsym.h" #include "demangle.h" +#include "gdb-demangle.h" #include "expression.h" #include "filenames.h" /* for DOSish file names */ #include "macrotab.h" @@ -56,7 +59,9 @@ #include "completer.h" #include "vec.h" #include "c-lang.h" +#include "go-lang.h" #include "valprint.h" +#include "gdbcore.h" /* for gnutarget */ #include #include @@ -76,52 +81,15 @@ typedef struct symbol *symbolp; DEF_VEC_P (symbolp); -#if 0 -/* .debug_info header for a compilation unit - Because of alignment constraints, this structure has padding and cannot - be mapped directly onto the beginning of the .debug_info section. */ -typedef struct comp_unit_header - { - unsigned int length; /* length of the .debug_info - contribution */ - unsigned short version; /* version number -- 2 for DWARF - version 2 */ - unsigned int abbrev_offset; /* offset into .debug_abbrev section */ - unsigned char addr_size; /* byte size of an address -- 4 */ - } -_COMP_UNIT_HEADER; -#define _ACTUAL_COMP_UNIT_HEADER_SIZE 11 -#endif - -/* .debug_line statement program prologue - Because of alignment constraints, this structure has padding and cannot - be mapped directly onto the beginning of the .debug_info section. */ -typedef struct statement_prologue - { - unsigned int total_length; /* byte length of the statement - information */ - unsigned short version; /* version number -- 2 for DWARF - version 2 */ - unsigned int prologue_length; /* # bytes between prologue & - stmt program */ - unsigned char minimum_instruction_length; /* byte size of - smallest instr */ - unsigned char default_is_stmt; /* initial value of is_stmt - register */ - char line_base; - unsigned char line_range; - unsigned char opcode_base; /* number assigned to first special - opcode */ - unsigned char *standard_opcode_lengths; - } -_STATEMENT_PROLOGUE; - /* When non-zero, dump DIEs after they are read in. */ static int dwarf2_die_debug = 0; /* When non-zero, cross-check physname against demangler. */ static int check_physname = 0; +/* When non-zero, do not reject deprecated .gdb_index sections. */ +int use_deprecated_index_sections = 0; + static int pagesize; /* When set, the file that we're processing is known to have debugging @@ -180,6 +148,12 @@ struct mapped_index const char *constant_pool; }; +typedef struct dwarf2_per_cu_data *dwarf2_per_cu_ptr; +DEF_VEC_P (dwarf2_per_cu_ptr); + +/* Collection of data recorded per objfile. + This hangs off of dwarf2_objfile_data_key. */ + struct dwarf2_per_objfile { struct dwarf2_section_info info; @@ -190,6 +164,7 @@ struct dwarf2_per_objfile struct dwarf2_section_info macro; struct dwarf2_section_info str; struct dwarf2_section_info ranges; + struct dwarf2_section_info addr; struct dwarf2_section_info frame; struct dwarf2_section_info eh_frame; struct dwarf2_section_info gdb_index; @@ -199,7 +174,7 @@ struct dwarf2_per_objfile /* Back link. */ struct objfile *objfile; - /* A list of all the compilation units. This is used to locate + /* Table of all the compilation units. This is used to locate the target compilation unit of a particular reference. */ struct dwarf2_per_cu_data **all_comp_units; @@ -207,10 +182,10 @@ struct dwarf2_per_objfile int n_comp_units; /* The number of .debug_types-related CUs. */ - int n_type_comp_units; + int n_type_units; - /* The .debug_types-related CUs. */ - struct dwarf2_per_cu_data **type_comp_units; + /* The .debug_types-related CUs (TUs). */ + struct dwarf2_per_cu_data **all_type_units; /* A chain of compilation units that are currently read in, so that they can be freed later. */ @@ -220,6 +195,10 @@ struct dwarf2_per_objfile This is NULL if the .debug_types section hasn't been read in yet. */ htab_t signatured_types; + /* A table mapping DW_AT_dwo_name values to struct dwo_file objects. + This is NULL if the table hasn't been allocated yet. */ + htab_t dwo_files; + /* A flag indicating wether this objfile has a section loaded at a VMA of 0. */ int has_section_at_zero; @@ -241,15 +220,13 @@ struct dwarf2_per_objfile symbols. */ int reading_partial_symbols; - /* Table mapping type .debug_info DIE offsets to types. + /* Table mapping type DIEs to their struct type *. This is NULL if not allocated yet. - It (currently) makes sense to allocate debug_types_type_hash lazily. - To keep things simple we allocate both lazily. */ - htab_t debug_info_type_hash; + The mapping is done via (CU/TU signature + DIE offset) -> type. */ + htab_t die_type_hash; - /* Table mapping type .debug_types DIE offsets to types. - This is NULL if not allocated yet. */ - htab_t debug_types_type_hash; + /* The CUs we recently read. */ + VEC (dwarf2_per_cu_ptr) *just_read_cus; }; static struct dwarf2_per_objfile *dwarf2_per_objfile; @@ -259,7 +236,8 @@ static struct dwarf2_per_objfile *dwarf2_per_objfile; /* Note that if the debugging section has been compressed, it might have a name like .zdebug_info. */ -static const struct dwarf2_debug_sections dwarf2_elf_names = { +static const struct dwarf2_debug_sections dwarf2_elf_names = +{ { ".debug_info", ".zdebug_info" }, { ".debug_abbrev", ".zdebug_abbrev" }, { ".debug_line", ".zdebug_line" }, @@ -269,12 +247,36 @@ static const struct dwarf2_debug_sections dwarf2_elf_names = { { ".debug_str", ".zdebug_str" }, { ".debug_ranges", ".zdebug_ranges" }, { ".debug_types", ".zdebug_types" }, + { ".debug_addr", ".zdebug_addr" }, { ".debug_frame", ".zdebug_frame" }, { ".eh_frame", NULL }, { ".gdb_index", ".zgdb_index" }, 23 }; +/* List of DWO sections. */ + +static const struct dwo_section_names +{ + struct dwarf2_section_names abbrev_dwo; + struct dwarf2_section_names info_dwo; + struct dwarf2_section_names line_dwo; + struct dwarf2_section_names loc_dwo; + struct dwarf2_section_names str_dwo; + struct dwarf2_section_names str_offsets_dwo; + struct dwarf2_section_names types_dwo; +} +dwo_section_names = +{ + { ".debug_abbrev.dwo", ".zdebug_abbrev.dwo" }, + { ".debug_info.dwo", ".zdebug_info.dwo" }, + { ".debug_line.dwo", ".zdebug_line.dwo" }, + { ".debug_loc.dwo", ".zdebug_loc.dwo" }, + { ".debug_str.dwo", ".zdebug_str.dwo" }, + { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo" }, + { ".debug_types.dwo", ".zdebug_types.dwo" }, +}; + /* local data types */ /* We hold several abbreviation tables in memory at the same time. */ @@ -290,7 +292,7 @@ struct comp_unit_head short version; unsigned char addr_size; unsigned char signed_addr_p; - unsigned int abbrev_offset; + sect_offset abbrev_offset; /* Size of file offsets; either 4 or 8. */ unsigned int offset_size; @@ -300,11 +302,11 @@ struct comp_unit_head /* Offset to the first byte of this compilation unit header in the .debug_info section, for resolving relative reference dies. */ - unsigned int offset; + sect_offset offset; /* Offset to first die in this cu from the start of the cu. This will be the first byte following the compilation unit header. */ - unsigned int first_die_offset; + cu_offset first_die_offset; }; /* Type used for delaying computation of method physnames. @@ -345,8 +347,6 @@ struct dwarf2_cu /* Non-zero if base_address has been set. */ int base_known; - struct function_range *first_fn, *last_fn, *cached_fn; - /* The language we are debugging. */ enum language language; const struct language_defn *language_defn; @@ -370,7 +370,8 @@ struct dwarf2_cu /* Storage for the abbrev table. */ struct obstack abbrev_obstack; - /* Hash table holding all the loaded partial DIEs. */ + /* Hash table holding all the loaded partial DIEs + with partial_die->offset.SECT_OFF as hash. */ htab_t partial_dies; /* Storage for things with the same lifetime as this read-in compilation @@ -389,7 +390,8 @@ struct dwarf2_cu /* How many compilation units ago was this CU last referenced? */ int last_used; - /* A hash table of die offsets for following references. */ + /* A hash table of DIE cu_offset for following references with + die_info->offset.sect_off as hash. */ htab_t die_hash; /* Full DIEs if read in. */ @@ -407,32 +409,41 @@ struct dwarf2_cu after all type information has been read. */ VEC (delayed_method_info) *method_list; - /* Mark used when releasing cached dies. */ - unsigned int mark : 1; + /* To be copied to symtab->call_site_htab. */ + htab_t call_site_htab; - /* This flag will be set if this compilation unit might include - inter-compilation-unit references. */ - unsigned int has_form_ref_addr : 1; + /* Non-NULL if this CU came from a DWO file. */ + struct dwo_unit *dwo_unit; - /* This flag will be set if this compilation unit includes any - DW_TAG_namespace DIEs. If we know that there are explicit - DIEs for namespaces, we don't need to try to infer them - from mangled names. */ - unsigned int has_namespace_info : 1; + /* The DW_AT_addr_base attribute if present, zero otherwise + (zero is a valid value though). + Note this value comes from the stub CU/TU's DIE. */ + ULONGEST addr_base; + + /* Mark used when releasing cached dies. */ + unsigned int mark : 1; /* This CU references .debug_loc. See the symtab->locations_valid field. This test is imperfect as there may exist optimized debug code not using any location list and still facing inlining issues if handled as unoptimized code. For a future better test see GCC PR other/32998. */ - unsigned int has_loclist : 1; + + /* These cache the results of producer_is_gxx_lt_4_6. + CHECKED_PRODUCER is set if PRODUCER_IS_GXX_LT_4_6 is valid. This + information is cached because profiling CU expansion showed + excessive time spent in producer_is_gxx_lt_4_6. */ + unsigned int checked_producer : 1; + unsigned int producer_is_gxx_lt_4_6 : 1; + + /* Non-zero if DW_AT_addr_base was found. + Used when processing DWO files. */ + unsigned int have_addr_base : 1; }; /* Persistent data held for a compilation unit, even when not processing it. We put a pointer to this structure in the - read_symtab_private field of the psymtab. If we encounter - inter-compilation-unit references, we also maintain a sorted - list of all compilation units. */ + read_symtab_private field of the psymtab. */ struct dwarf2_per_cu_data { @@ -440,29 +451,37 @@ struct dwarf2_per_cu_data 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; + initial_length_size. + If the DIE refers to a DWO file, this is always of the original die, + not the DWO file. */ + sect_offset offset; unsigned int length : 29; /* Flag indicating this compilation unit will be read in before any of the current compilation units are processed. */ unsigned int queued : 1; - /* This flag will be set if we need to load absolutely all DIEs - for this compilation unit, instead of just the ones we think - are interesting. It gets set if we look for a DIE in the + /* This flag will be set when reading partial DIEs if we need to load + absolutely all DIEs for this compilation unit, instead of just the ones + we think are interesting. It gets set if we look for a DIE in the hash table and don't find it. */ unsigned int load_all_dies : 1; - /* Non-null if this CU is from .debug_types; in which case it points - to the section. Otherwise it's from .debug_info. */ - struct dwarf2_section_info *debug_type_section; + /* Non-zero if this CU is from .debug_types. */ + unsigned int is_debug_types : 1; + + /* The section this CU/TU lives in. + If the DIE refers to a DWO file, this is always the original die, + not the DWO file. */ + struct dwarf2_section_info *info_or_types_section; /* Set to non-NULL iff this CU is currently loaded. When it gets freed out of the CU cache it gets reset to NULL again. */ struct dwarf2_cu *cu; - /* The corresponding objfile. */ + /* The corresponding objfile. + Normally we can get the objfile from dwarf2_per_objfile. + However we can enter this file with just a "per_cu" handle. */ struct objfile *objfile; /* When using partial symbol tables, the 'psymtab' field is active. @@ -470,47 +489,132 @@ struct dwarf2_per_cu_data union { /* The partial symbol table associated with this compilation unit, - or NULL for partial units (which do not have an associated - symtab). */ + or NULL for unread partial units. */ struct partial_symtab *psymtab; /* Data needed by the "quick" functions. */ struct dwarf2_per_cu_quick_data *quick; } v; + + /* The CUs we import using DW_TAG_imported_unit. This is filled in + while reading psymtabs, used to compute the psymtab dependencies, + and then cleared. Then it is filled in again while reading full + symbols, and only deleted when the objfile is destroyed. */ + VEC (dwarf2_per_cu_ptr) *imported_symtabs; }; /* Entry in the signatured_types hash table. */ struct signatured_type { + /* The type's signature. */ ULONGEST signature; - /* Offset in .debug_types of the type defined by this TU. */ - unsigned int type_offset; + /* Offset in the TU of the type's DIE, as read from the TU header. + If the definition lives in a DWO file, this value is unusable. */ + cu_offset type_offset_in_tu; + + /* Offset in the section of the type's DIE. + If the definition lives in a DWO file, this is the offset in the + .debug_types.dwo section. + The value is zero until the actual value is known. + Zero is otherwise not a valid section offset. */ + sect_offset type_offset_in_section; /* The CU(/TU) of this type. */ struct dwarf2_per_cu_data per_cu; }; +/* These sections are what may appear in a "dwo" file. */ + +struct dwo_sections +{ + struct dwarf2_section_info abbrev; + struct dwarf2_section_info info; + struct dwarf2_section_info line; + struct dwarf2_section_info loc; + struct dwarf2_section_info str; + struct dwarf2_section_info str_offsets; + VEC (dwarf2_section_info_def) *types; +}; + +/* Common bits of DWO CUs/TUs. */ + +struct dwo_unit +{ + /* Backlink to the containing struct dwo_file. */ + struct dwo_file *dwo_file; + + /* The "id" that distinguishes this CU/TU. + .debug_info calls this "dwo_id", .debug_types calls this "signature". + Since signatures came first, we stick with it for consistency. */ + ULONGEST signature; + + /* The section this CU/TU lives in, in the DWO file. */ + struct dwarf2_section_info *info_or_types_section; + + /* Same as dwarf2_per_cu_data:{offset,length} but for the DWO section. */ + sect_offset offset; + unsigned int length; + + /* For types, offset in the type's DIE of the type defined by this TU. */ + cu_offset type_offset_in_tu; +}; + +/* Data for one DWO file. */ + +struct dwo_file +{ + /* The DW_AT_GNU_dwo_name attribute. + We don't manage space for this, it's an attribute. */ + const char *dwo_name; + + /* The bfd, when the file is open. Otherwise this is NULL. */ + bfd *dwo_bfd; + + /* Section info for this file. */ + struct dwo_sections sections; + + /* Table of CUs in the file. + Each element is a struct dwo_unit. */ + htab_t cus; + + /* Table of TUs in the file. + Each element is a struct dwo_unit. */ + htab_t tus; +}; + /* 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 exists to abstract away the constant parameters of die reading. */ struct die_reader_specs { - /* The bfd of this objfile. */ + /* die_section->asection->owner. */ 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; + /* Non-NULL if reading a DWO file. */ + struct dwo_file *dwo_file; + + /* The section the die comes from. + This is either .debug_info or .debug_types, or the .dwo variants. */ + struct dwarf2_section_info *die_section; + + /* die_section->buffer. */ + gdb_byte *buffer; }; +/* Type of function passed to init_cutu_and_read_dies, et.al. */ +typedef void (die_reader_func_ftype) (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct die_info *comp_unit_die, + int has_children, + void *data); + /* 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. */ @@ -563,7 +667,7 @@ struct line_header struct partial_die_info { /* Offset of this DIE. */ - unsigned int offset; + sect_offset offset; /* DWARF-2 tag for this DIE. */ ENUM_BITFIELD(dwarf_tag) tag : 16; @@ -575,6 +679,7 @@ struct partial_die_info unsigned int has_type : 1; unsigned int has_specification : 1; unsigned int has_pc_info : 1; + unsigned int may_be_inlined : 1; /* Flag set if the SCOPE field of this structure has been computed. */ @@ -601,8 +706,15 @@ struct partial_die_info when this compilation unit leaves the cache. */ char *scope; - /* The location description associated with this DIE, if any. */ - struct dwarf_block *locdesc; + /* Some data associated with the partial DIE. The tag determines + which field is live. */ + union + { + /* The location description associated with this DIE, if any. */ + struct dwarf_block *locdesc; + /* The offset of an import, for DW_TAG_imported_unit. */ + sect_offset offset; + } d; /* If HAS_PC_INFO, the PC range associated with this DIE. */ CORE_ADDR lowpc; @@ -617,7 +729,7 @@ struct partial_die_info /* If HAS_SPECIFICATION, the offset of the DIE referred to by DW_AT_specification (or DW_AT_abstract_origin or DW_AT_extension). */ - unsigned int spec_offset; + sect_offset spec_offset; /* Pointers to this DIE's parent, first child, and next sibling, if any. */ @@ -681,7 +793,7 @@ struct die_info unsigned int abbrev; /* Offset in .debug_info or .debug_types section. */ - unsigned int offset; + sect_offset offset; /* The dies in a compilation unit form an n-ary tree. PARENT points to this die's parent; CHILD points to the first child of @@ -697,14 +809,6 @@ struct die_info struct attribute attrs[1]; }; -struct function_range -{ - const char *name; - CORE_ADDR lowpc, highpc; - int seen_line; - struct function_range *next; -}; - /* Get at parts of an attribute structure. */ #define DW_STRING(attr) ((attr)->u.str) @@ -719,6 +823,8 @@ struct function_range struct dwarf_block { unsigned int size; + + /* Valid only if SIZE is not zero. */ gdb_byte *data; }; @@ -799,6 +905,7 @@ struct field_info struct dwarf2_queue_item { struct dwarf2_per_cu_data *per_cu; + enum language pretend_language; struct dwarf2_queue_item *next; }; @@ -919,45 +1026,41 @@ static void add_partial_subprogram (struct partial_die_info *pdi, CORE_ADDR *lowpc, CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu); -static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi, - gdb_byte *buffer, gdb_byte *info_ptr, - bfd *abfd, struct dwarf2_cu *cu); - static void dwarf2_psymtab_to_symtab (struct partial_symtab *); static void psymtab_to_symtab_1 (struct partial_symtab *); -static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu); +static void dwarf2_read_abbrevs (struct dwarf2_cu *, + struct dwarf2_section_info *); static void dwarf2_free_abbrev_table (void *); +static unsigned int peek_abbrev_code (bfd *, gdb_byte *); + static struct abbrev_info *peek_die_abbrev (gdb_byte *, unsigned int *, struct dwarf2_cu *); static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int, struct dwarf2_cu *); -static struct partial_die_info *load_partial_dies (bfd *, - gdb_byte *, gdb_byte *, - int, struct dwarf2_cu *); +static struct partial_die_info *load_partial_dies + (const struct die_reader_specs *, gdb_byte *, int); -static gdb_byte *read_partial_die (struct partial_die_info *, - struct abbrev_info *abbrev, - unsigned int, bfd *, - gdb_byte *, gdb_byte *, - struct dwarf2_cu *); +static gdb_byte *read_partial_die (const struct die_reader_specs *, + struct partial_die_info *, + struct abbrev_info *, + unsigned int, + gdb_byte *); -static struct partial_die_info *find_partial_die (unsigned int, +static struct partial_die_info *find_partial_die (sect_offset, struct dwarf2_cu *); static void fixup_partial_die (struct partial_die_info *, struct dwarf2_cu *); -static gdb_byte *read_attribute (struct attribute *, struct attr_abbrev *, - bfd *, gdb_byte *, struct dwarf2_cu *); - -static gdb_byte *read_attribute_value (struct attribute *, unsigned, - bfd *, gdb_byte *, struct dwarf2_cu *); +static gdb_byte *read_attribute (const struct die_reader_specs *, + struct attribute *, struct attr_abbrev *, + gdb_byte *); static unsigned int read_1_byte (bfd *, gdb_byte *); @@ -991,9 +1094,15 @@ static char *read_indirect_string (bfd *, gdb_byte *, const struct comp_unit_head *, unsigned int *); -static unsigned long read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *); +static ULONGEST read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *); + +static LONGEST read_signed_leb128 (bfd *, gdb_byte *, unsigned int *); -static long read_signed_leb128 (bfd *, gdb_byte *, unsigned int *); +static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *, gdb_byte *, + unsigned int *); + +static char *read_str_index (const struct die_reader_specs *reader, + struct dwarf2_cu *cu, ULONGEST str_index); static gdb_byte *skip_leb128 (bfd *, gdb_byte *); @@ -1019,12 +1128,12 @@ static void free_line_header (struct line_header *lh); static void add_file_name (struct line_header *, char *, unsigned int, unsigned int, unsigned int); -static struct line_header *(dwarf_decode_line_header - (unsigned int offset, - bfd *abfd, struct dwarf2_cu *cu)); +static struct line_header *dwarf_decode_line_header (unsigned int offset, + struct dwarf2_cu *cu); -static void dwarf_decode_lines (struct line_header *, const char *, bfd *, - struct dwarf2_cu *, struct partial_symtab *); +static void dwarf_decode_lines (struct line_header *, const char *, + struct dwarf2_cu *, struct partial_symtab *, + int); static void dwarf2_start_subfile (char *, const char *, const char *); @@ -1041,7 +1150,7 @@ static void dwarf2_const_value_attr (struct attribute *attr, struct type *type, const char *name, struct obstack *obstack, - struct dwarf2_cu *cu, long *value, + struct dwarf2_cu *cu, LONGEST *value, gdb_byte **bytes, struct dwarf2_locexpr_baton **baton); @@ -1065,7 +1174,7 @@ static struct type *read_type_die (struct die_info *, struct dwarf2_cu *); static struct type *read_type_die_1 (struct die_info *, struct dwarf2_cu *); -static char *determine_prefix (struct die_info *die, struct dwarf2_cu *); +static const char *determine_prefix (struct die_info *die, struct dwarf2_cu *); static char *typename_concat (struct obstack *obs, const char *prefix, const char *suffix, int physname, @@ -1079,6 +1188,8 @@ static void read_func_scope (struct die_info *, struct dwarf2_cu *); static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *); +static void read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu); + static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *, struct partial_symtab *); @@ -1130,26 +1241,21 @@ 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 *, 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 (const struct die_reader_specs *reader, +static struct die_info *read_die_and_children (const struct die_reader_specs *, gdb_byte *info_ptr, gdb_byte **new_info_ptr, struct die_info *parent); -static struct die_info *read_die_and_siblings (const struct die_reader_specs *reader, +static struct die_info *read_die_and_siblings (const struct die_reader_specs *, 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 gdb_byte *read_full_die_1 (const struct die_reader_specs *, + struct die_info **, gdb_byte *, int *, int); + +static gdb_byte *read_full_die (const struct die_reader_specs *, + struct die_info **, gdb_byte *, int *); static void process_die (struct die_info *, struct dwarf2_cu *); @@ -1165,19 +1271,15 @@ static const char *dwarf2_full_name (char *name, static struct die_info *dwarf2_extension (struct die_info *die, struct dwarf2_cu **); -static char *dwarf_tag_name (unsigned int); +static const char *dwarf_tag_name (unsigned int); -static char *dwarf_attr_name (unsigned int); +static const char *dwarf_attr_name (unsigned int); -static char *dwarf_form_name (unsigned int); +static const char *dwarf_form_name (unsigned int); static char *dwarf_bool_name (unsigned int); -static char *dwarf_type_encoding_name (unsigned int); - -#if 0 -static char *dwarf_cfi_name (unsigned int); -#endif +static const char *dwarf_type_encoding_name (unsigned int); static struct die_info *sibling_die (struct die_info *); @@ -1195,7 +1297,7 @@ static void store_in_ref_table (struct die_info *, static int is_ref_attr (struct attribute *); -static unsigned int dwarf2_get_ref_die_offset (struct attribute *); +static sect_offset dwarf2_get_ref_die_offset (struct attribute *); static LONGEST dwarf2_get_attr_constant_value (struct attribute *, int); @@ -1213,15 +1315,11 @@ static struct die_info *follow_die_sig (struct die_info *, static struct signatured_type *lookup_signatured_type_at_offset (struct objfile *objfile, - struct dwarf2_section_info *section, - unsigned int offset); + struct dwarf2_section_info *section, sect_offset offset); -static void read_signatured_type_at_offset (struct objfile *objfile, - struct dwarf2_section_info *sect, - unsigned int offset); +static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu); -static void read_signatured_type (struct objfile *, - struct signatured_type *type_sig); +static void read_signatured_type (struct signatured_type *); /* memory allocation interface */ @@ -1231,15 +1329,10 @@ static struct abbrev_info *dwarf_alloc_abbrev (struct dwarf2_cu *); static struct die_info *dwarf_alloc_die (struct dwarf2_cu *, int); -static void initialize_cu_func_list (struct dwarf2_cu *); - -static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR, - struct dwarf2_cu *); - static void dwarf_decode_macros (struct line_header *, unsigned int, char *, bfd *, struct dwarf2_cu *, struct dwarf2_section_info *, - int); + int, const char *); static int attr_form_is_block (struct attribute *); @@ -1255,9 +1348,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 *buffer, gdb_byte *info_ptr, - struct abbrev_info *abbrev, - struct dwarf2_cu *cu); +static gdb_byte *skip_one_die (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct abbrev_info *abbrev); static void free_stack_comp_unit (void *); @@ -1266,36 +1359,35 @@ static hashval_t partial_die_hash (const void *item); static int partial_die_eq (const void *item_lhs, const void *item_rhs); static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit - (unsigned int offset, struct objfile *objfile); - -static struct dwarf2_per_cu_data *dwarf2_find_comp_unit - (unsigned int offset, struct objfile *objfile); + (sect_offset offset, struct objfile *objfile); static void init_one_comp_unit (struct dwarf2_cu *cu, - struct objfile *objfile); + struct dwarf2_per_cu_data *per_cu); static void prepare_one_comp_unit (struct dwarf2_cu *cu, - struct die_info *comp_unit_die); + struct die_info *comp_unit_die, + enum language pretend_language); -static void free_one_comp_unit (void *); +static void free_heap_comp_unit (void *); static void free_cached_comp_units (void *); static void age_cached_comp_units (void); -static void free_one_cached_comp_unit (void *); +static void free_one_cached_comp_unit (struct dwarf2_per_cu_data *); static struct type *set_die_type (struct die_info *, struct type *, struct dwarf2_cu *); static void create_all_comp_units (struct objfile *); -static int create_debug_types_hash_table (struct objfile *objfile); +static int create_all_type_units (struct objfile *); static void load_full_comp_unit (struct dwarf2_per_cu_data *, - struct objfile *); + enum language); -static void process_full_comp_unit (struct dwarf2_per_cu_data *); +static void process_full_comp_unit (struct dwarf2_per_cu_data *, + enum language); static void dwarf2_add_dependence (struct dwarf2_cu *, struct dwarf2_per_cu_data *); @@ -1304,7 +1396,7 @@ static void dwarf2_mark (struct dwarf2_cu *); static void dwarf2_clear_marks (struct dwarf2_per_cu_data *); -static struct type *get_die_type_at_offset (unsigned int, +static struct type *get_die_type_at_offset (sect_offset, struct dwarf2_per_cu_data *per_cu); static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu); @@ -1312,9 +1404,13 @@ static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu); static void dwarf2_release_queue (void *dummy); static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu, - struct objfile *objfile); + enum language pretend_language); -static void process_queue (struct objfile *objfile); +static int maybe_queue_comp_unit (struct dwarf2_cu *this_cu, + struct dwarf2_per_cu_data *per_cu, + enum language pretend_language); + +static void process_queue (void); static void find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu, @@ -1323,17 +1419,37 @@ static void find_file_and_directory (struct die_info *die, static char *file_full_name (int file, struct line_header *lh, const char *comp_dir); -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); +static gdb_byte *read_and_check_comp_unit_head + (struct comp_unit_head *header, + struct dwarf2_section_info *section, gdb_byte *info_ptr, + int is_debug_types_section); -static void init_cu_die_reader (struct die_reader_specs *reader, - struct dwarf2_cu *cu); +static void init_cutu_and_read_dies + (struct dwarf2_per_cu_data *this_cu, int use_existing_cu, int keep, + die_reader_func_ftype *die_reader_func, void *data); + +static void init_cutu_and_read_dies_simple + (struct dwarf2_per_cu_data *this_cu, + die_reader_func_ftype *die_reader_func, void *data); static htab_t allocate_signatured_type_table (struct objfile *objfile); +static void process_psymtab_comp_unit (struct dwarf2_per_cu_data *, int); + +static htab_t allocate_dwo_unit_table (struct objfile *objfile); + +static struct dwo_unit *lookup_dwo_comp_unit + (struct dwarf2_per_cu_data *, char *, const char *, ULONGEST); + +static struct dwo_unit *lookup_dwo_type_unit + (struct signatured_type *, char *, const char *); + +static void free_dwo_file_cleanup (void *); + +static void munmap_section_buffer (struct dwarf2_section_info *); + +static void process_cu_includes (void); + #if WORDS_BIGENDIAN /* Convert VALUE between big- and little-endian. */ @@ -1454,6 +1570,11 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames) dwarf2_per_objfile->str.asection = sectp; dwarf2_per_objfile->str.size = bfd_get_section_size (sectp); } + else if (section_is_p (sectp->name, &names->addr)) + { + dwarf2_per_objfile->addr.asection = sectp; + dwarf2_per_objfile->addr.size = bfd_get_section_size (sectp); + } else if (section_is_p (sectp->name, &names->frame)) { dwarf2_per_objfile->frame.asection = sectp; @@ -1461,7 +1582,7 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames) } else if (section_is_p (sectp->name, &names->eh_frame)) { - flagword aflag = bfd_get_section_flags (ignore_abfd, sectp); + flagword aflag = bfd_get_section_flags (abfd, sectp); if (aflag & SEC_HAS_CONTENTS) { @@ -1503,7 +1624,7 @@ static void zlib_decompress_section (struct objfile *objfile, asection *sectp, gdb_byte **outbuf, bfd_size_type *outsize) { - bfd *abfd = objfile->obfd; + bfd *abfd = sectp->owner; #ifndef HAVE_ZLIB_H error (_("Support for zlib-compressed DWARF data (from '%s') " "is disabled in this copy of GDB"), @@ -1575,7 +1696,8 @@ zlib_decompress_section (struct objfile *objfile, asection *sectp, #endif } -/* A helper function that decides whether a section is empty. */ +/* A helper function that decides whether a section is empty, + or not present. */ static int dwarf2_section_empty_p (struct dwarf2_section_info *info) @@ -1583,15 +1705,17 @@ dwarf2_section_empty_p (struct dwarf2_section_info *info) return info->asection == NULL || info->size == 0; } -/* Read the contents of the section SECTP from object file specified by - OBJFILE, store info about the section into INFO. +/* Read the contents of the section INFO. + OBJFILE is the main object file, but not necessarily the file where + the section comes from. E.g., for DWO files INFO->asection->owner + is the bfd of the DWO file. If the section is compressed, uncompress it before returning. */ static void dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) { - bfd *abfd = objfile->obfd; asection *sectp = info->asection; + bfd *abfd; gdb_byte *buf, *retbuf; unsigned char header[4]; @@ -1604,6 +1728,9 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info) if (dwarf2_section_empty_p (info)) return; + /* Note that ABFD may not be from OBJFILE, e.g. a DWO section. */ + abfd = sectp->owner; + /* Check if the file has a 4-byte header indicating compression. */ if (info->size > sizeof (header) && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0 @@ -1825,34 +1952,34 @@ create_quick_file_names_table (unsigned int nr_initial_entries) static void load_cu (struct dwarf2_per_cu_data *per_cu) { - if (per_cu->debug_type_section) - read_signatured_type_at_offset (per_cu->objfile, - per_cu->debug_type_section, - per_cu->offset); + if (per_cu->is_debug_types) + load_full_type_unit (per_cu); else - load_full_comp_unit (per_cu, per_cu->objfile); - - dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu); + load_full_comp_unit (per_cu, language_minimal); gdb_assert (per_cu->cu != NULL); + + dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu); } -/* Read in the symbols for PER_CU. OBJFILE is the objfile from which - this CU came. */ +/* Read in the symbols for PER_CU. */ static void -dw2_do_instantiate_symtab (struct objfile *objfile, - struct dwarf2_per_cu_data *per_cu) +dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu) { struct cleanup *back_to; back_to = make_cleanup (dwarf2_release_queue, NULL); - queue_comp_unit (per_cu, objfile); - - load_cu (per_cu); + if (dwarf2_per_objfile->using_index + ? per_cu->v.quick->symtab == NULL + : (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin)) + { + queue_comp_unit (per_cu, language_minimal); + load_cu (per_cu); + } - process_queue (objfile); + process_queue (); /* Age the cache, releasing compilation units that have not been used recently. */ @@ -1866,14 +1993,15 @@ dw2_do_instantiate_symtab (struct objfile *objfile, table. */ static struct symtab * -dw2_instantiate_symtab (struct objfile *objfile, - struct dwarf2_per_cu_data *per_cu) +dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu) { + gdb_assert (dwarf2_per_objfile->using_index); if (!per_cu->v.quick->symtab) { struct cleanup *back_to = make_cleanup (free_cached_comp_units, NULL); increment_reading_symtab (); - dw2_do_instantiate_symtab (objfile, per_cu); + dw2_do_instantiate_symtab (per_cu); + process_cu_includes (); do_cleanups (back_to); } return per_cu->v.quick->symtab; @@ -1887,7 +2015,7 @@ dw2_get_cu (int index) if (index >= dwarf2_per_objfile->n_comp_units) { index -= dwarf2_per_objfile->n_comp_units; - return dwarf2_per_objfile->type_comp_units[index]; + return dwarf2_per_objfile->all_type_units[index]; } return dwarf2_per_objfile->all_comp_units[index]; } @@ -1943,9 +2071,10 @@ create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list, the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwarf2_per_cu_data); - the_cu->offset = offset; + the_cu->offset.sect_off = offset; the_cu->length = length; the_cu->objfile = objfile; + the_cu->info_or_types_section = &dwarf2_per_objfile->info; the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwarf2_per_cu_quick_data); dwarf2_per_objfile->all_comp_units[i / 2] = the_cu; @@ -1965,41 +2094,42 @@ create_signatured_type_table_from_index (struct objfile *objfile, offset_type i; htab_t sig_types_hash; - dwarf2_per_objfile->n_type_comp_units = elements / 3; - dwarf2_per_objfile->type_comp_units + dwarf2_per_objfile->n_type_units = elements / 3; + dwarf2_per_objfile->all_type_units = obstack_alloc (&objfile->objfile_obstack, - dwarf2_per_objfile->n_type_comp_units + dwarf2_per_objfile->n_type_units * sizeof (struct dwarf2_per_cu_data *)); sig_types_hash = allocate_signatured_type_table (objfile); for (i = 0; i < elements; i += 3) { - struct signatured_type *type_sig; - ULONGEST offset, type_offset, signature; + struct signatured_type *sig_type; + ULONGEST offset, type_offset_in_tu, signature; void **slot; if (!extract_cu_value (bytes, &offset) - || !extract_cu_value (bytes + 8, &type_offset)) + || !extract_cu_value (bytes + 8, &type_offset_in_tu)) return 0; signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE); bytes += 3 * 8; - type_sig = OBSTACK_ZALLOC (&objfile->objfile_obstack, + sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct signatured_type); - type_sig->signature = signature; - type_sig->type_offset = type_offset; - type_sig->per_cu.debug_type_section = section; - type_sig->per_cu.offset = offset; - type_sig->per_cu.objfile = objfile; - type_sig->per_cu.v.quick + sig_type->signature = signature; + sig_type->type_offset_in_tu.cu_off = type_offset_in_tu; + sig_type->per_cu.is_debug_types = 1; + sig_type->per_cu.info_or_types_section = section; + sig_type->per_cu.offset.sect_off = offset; + sig_type->per_cu.objfile = objfile; + sig_type->per_cu.v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwarf2_per_cu_quick_data); - slot = htab_find_slot (sig_types_hash, type_sig, INSERT); - *slot = type_sig; + slot = htab_find_slot (sig_types_hash, sig_type, INSERT); + *slot = sig_type; - dwarf2_per_objfile->type_comp_units[i / 3] = &type_sig->per_cu; + dwarf2_per_objfile->all_type_units[i / 3] = &sig_type->per_cu; } dwarf2_per_objfile->signatured_types = sig_types_hash; @@ -2107,7 +2237,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name, } /* Index version 4 did not support case insensitive searches. But the - indexes for case insensitive languages are built in lowercase, therefore + indices for case insensitive languages are built in lowercase, therefore simulate our NAME being searched is also lowercased. */ hash = mapped_index_string_hash ((index->version == 4 && case_sensitivity == case_sensitive_off @@ -2174,13 +2304,41 @@ dwarf2_read_index (struct objfile *objfile) /* Versions earlier than 3 emitted every copy of a psymbol. This causes the index to behave very poorly for certain requests. Version 3 contained incomplete addrmap. So, it seems better to just ignore such - indices. Index version 4 uses a different hash function than index - version 5 and later. */ + indices. */ if (version < 4) - return 0; + { + static int warning_printed = 0; + if (!warning_printed) + { + warning (_("Skipping obsolete .gdb_index section in %s."), + objfile->name); + warning_printed = 1; + } + return 0; + } + /* Index version 4 uses a different hash function than index version + 5 and later. + + Versions earlier than 6 did not emit psymbols for inlined + functions. Using these files will cause GDB not to be able to + set breakpoints on inlined functions by name, so we ignore these + indices unless the --use-deprecated-index-sections command line + option was supplied. */ + if (version < 6 && !use_deprecated_index_sections) + { + static int warning_printed = 0; + if (!warning_printed) + { + warning (_("Skipping deprecated .gdb_index section in %s, pass " + "--use-deprecated-index-sections to use them anyway"), + objfile->name); + warning_printed = 1; + } + return 0; + } /* Indexes with higher version than the one supported by GDB may be no longer backward compatible. */ - if (version > 5) + if (version > 6) return 0; map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index); @@ -2214,6 +2372,10 @@ dwarf2_read_index (struct objfile *objfile) map->constant_pool = addr + MAYBE_SWAP (metadata[i]); + /* Don't use the index if it's empty. */ + if (map->symbol_table_slots == 0) + return 0; + if (!create_cus_from_index (objfile, cu_list, cu_list_elements)) return 0; @@ -2255,72 +2417,32 @@ dw2_setup (struct objfile *objfile) gdb_assert (dwarf2_per_objfile); } -/* A helper for the "quick" functions which attempts to read the line - table for THIS_CU. */ +/* die_reader_func for dw2_get_file_names. */ -static struct quick_file_names * -dw2_get_file_names (struct objfile *objfile, - struct dwarf2_per_cu_data *this_cu) +static void +dw2_get_file_names_reader (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct die_info *comp_unit_die, + int has_children, + void *data) { - bfd *abfd = objfile->obfd; + struct dwarf2_cu *cu = reader->cu; + struct dwarf2_per_cu_data *this_cu = cu->per_cu; + struct objfile *objfile = dwarf2_per_objfile->objfile; struct line_header *lh; struct attribute *attr; - struct cleanup *cleanups; - struct die_info *comp_unit_die; - struct dwarf2_section_info* sec; - gdb_byte *beg_of_comp_unit, *info_ptr, *buffer; - int has_children, i; - struct dwarf2_cu cu; - unsigned int bytes_read, buffer_size; - struct die_reader_specs reader_specs; + int i; + unsigned int bytes_read; char *name, *comp_dir; void **slot; struct quick_file_names *qfn; unsigned int line_offset; - if (this_cu->v.quick->file_names != NULL) - return this_cu->v.quick->file_names; - /* If we know there is no line data, no point in looking again. */ - if (this_cu->v.quick->no_file_data) - return NULL; - - init_one_comp_unit (&cu, objfile); - cleanups = make_cleanup (free_stack_comp_unit, &cu); - - if (this_cu->debug_type_section) - sec = this_cu->debug_type_section; - else - sec = &dwarf2_per_objfile->info; - dwarf2_read_section (objfile, sec); - buffer_size = sec->size; - buffer = sec->buffer; - info_ptr = buffer + this_cu->offset; - beg_of_comp_unit = info_ptr; - - info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr, - buffer, buffer_size, - abfd); - - /* Complete the cu_header. */ - cu.header.offset = beg_of_comp_unit - buffer; - cu.header.first_die_offset = info_ptr - beg_of_comp_unit; - - this_cu->cu = &cu; - cu.per_cu = this_cu; - - dwarf2_read_abbrevs (abfd, &cu); - make_cleanup (dwarf2_free_abbrev_table, &cu); - - if (this_cu->debug_type_section) - info_ptr += 8 /*signature*/ + cu.header.offset_size; - init_cu_die_reader (&reader_specs, &cu); - read_full_die (&reader_specs, &comp_unit_die, info_ptr, - &has_children); - lh = NULL; slot = NULL; line_offset = 0; - attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, &cu); + + attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu); if (attr) { struct quick_file_names find_entry; @@ -2334,18 +2456,16 @@ dw2_get_file_names (struct objfile *objfile, &find_entry, INSERT); if (*slot != NULL) { - do_cleanups (cleanups); this_cu->v.quick->file_names = *slot; - return *slot; + return; } - lh = dwarf_decode_line_header (line_offset, abfd, &cu); + lh = dwarf_decode_line_header (line_offset, cu); } if (lh == NULL) { - do_cleanups (cleanups); this_cu->v.quick->no_file_data = 1; - return NULL; + return; } qfn = obstack_alloc (&objfile->objfile_obstack, sizeof (*qfn)); @@ -2353,7 +2473,7 @@ dw2_get_file_names (struct objfile *objfile, gdb_assert (slot != NULL); *slot = qfn; - find_file_and_directory (comp_unit_die, &cu, &name, &comp_dir); + find_file_and_directory (comp_unit_die, cu, &name, &comp_dir); qfn->num_file_names = lh->num_file_names; qfn->file_names = obstack_alloc (&objfile->objfile_obstack, @@ -2363,10 +2483,35 @@ dw2_get_file_names (struct objfile *objfile, qfn->real_names = NULL; free_line_header (lh); - do_cleanups (cleanups); this_cu->v.quick->file_names = qfn; - return qfn; +} + +/* A helper for the "quick" functions which attempts to read the line + table for THIS_CU. */ + +static struct quick_file_names * +dw2_get_file_names (struct objfile *objfile, + struct dwarf2_per_cu_data *this_cu) +{ + if (this_cu->v.quick->file_names != NULL) + return this_cu->v.quick->file_names; + /* If we know there is no line data, no point in looking again. */ + if (this_cu->v.quick->no_file_data) + return NULL; + + /* If DWO files are in use, we can still find the DW_AT_stmt_list attribute + in the stub for CUs, there's is no need to lookup the DWO file. + However, that's not the case for TUs where DW_AT_stmt_list lives in the + DWO file. */ + if (this_cu->is_debug_types) + init_cutu_and_read_dies (this_cu, 0, 0, dw2_get_file_names_reader, NULL); + else + init_cutu_and_read_dies_simple (this_cu, dw2_get_file_names_reader, NULL); + + if (this_cu->v.quick->no_file_data) + return NULL; + return this_cu->v.quick->file_names; } /* A helper for the "quick" functions which computes and caches the @@ -2393,7 +2538,7 @@ dw2_find_last_source_symtab (struct objfile *objfile) dw2_setup (objfile); index = dwarf2_per_objfile->n_comp_units - 1; - return dw2_instantiate_symtab (objfile, dw2_get_cu (index)); + return dw2_instantiate_symtab (dw2_get_cu (index)); } /* Traversal function for dw2_forget_cached_source_info. */ @@ -2426,24 +2571,54 @@ dw2_forget_cached_source_info (struct objfile *objfile) dw2_free_cached_file_names, NULL); } +/* Helper function for dw2_map_symtabs_matching_filename that expands + the symtabs and calls the iterator. */ + +static int +dw2_map_expand_apply (struct objfile *objfile, + struct dwarf2_per_cu_data *per_cu, + const char *name, + const char *full_path, const char *real_path, + int (*callback) (struct symtab *, void *), + void *data) +{ + struct symtab *last_made = objfile->symtabs; + + /* Don't visit already-expanded CUs. */ + if (per_cu->v.quick->symtab) + return 0; + + /* This may expand more than one symtab, and we want to iterate over + all of them. */ + dw2_instantiate_symtab (per_cu); + + return iterate_over_some_symtabs (name, full_path, real_path, callback, data, + objfile->symtabs, last_made); +} + +/* Implementation of the map_symtabs_matching_filename method. */ + static int -dw2_lookup_symtab (struct objfile *objfile, const char *name, - const char *full_path, const char *real_path, - struct symtab **result) +dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name, + const char *full_path, const char *real_path, + int (*callback) (struct symtab *, void *), + void *data) { int i; - int check_basename = lbasename (name) == name; - struct dwarf2_per_cu_data *base_cu = NULL; + const char *name_basename = lbasename (name); + int name_len = strlen (name); + int is_abs = IS_ABSOLUTE_PATH (name); dw2_setup (objfile); for (i = 0; i < (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_comp_units); ++i) + + dwarf2_per_objfile->n_type_units); ++i) { int j; struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); struct quick_file_names *file_data; + /* We only need to look at symtabs not already expanded. */ if (per_cu->v.quick->symtab) continue; @@ -2455,15 +2630,21 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name, { const char *this_name = file_data->file_names[j]; - if (FILENAME_CMP (name, this_name) == 0) + if (FILENAME_CMP (name, this_name) == 0 + || (!is_abs && compare_filenames_for_search (this_name, + name, name_len))) { - *result = dw2_instantiate_symtab (objfile, per_cu); - return 1; + if (dw2_map_expand_apply (objfile, per_cu, + name, full_path, real_path, + callback, data)) + return 1; } - if (check_basename && ! base_cu - && FILENAME_CMP (lbasename (this_name), name) == 0) - base_cu = per_cu; + /* Before we invoke realpath, which can get expensive when many + files are involved, do a quick comparison of the basenames. */ + if (! basenames_may_differ + && FILENAME_CMP (lbasename (this_name), name_basename) != 0) + continue; if (full_path != NULL) { @@ -2471,10 +2652,15 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name, file_data, j); if (this_real_name != NULL - && FILENAME_CMP (full_path, this_real_name) == 0) + && (FILENAME_CMP (full_path, this_real_name) == 0 + || (!is_abs + && compare_filenames_for_search (this_real_name, + name, name_len)))) { - *result = dw2_instantiate_symtab (objfile, per_cu); - return 1; + if (dw2_map_expand_apply (objfile, per_cu, + name, full_path, real_path, + callback, data)) + return 1; } } @@ -2484,21 +2670,20 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name, file_data, j); if (this_real_name != NULL - && FILENAME_CMP (real_path, this_real_name) == 0) + && (FILENAME_CMP (real_path, this_real_name) == 0 + || (!is_abs + && compare_filenames_for_search (this_real_name, + name, name_len)))) { - *result = dw2_instantiate_symtab (objfile, per_cu); - return 1; + if (dw2_map_expand_apply (objfile, per_cu, + name, full_path, real_path, + callback, data)) + return 1; } } } } - if (base_cu) - { - *result = dw2_instantiate_symtab (objfile, base_cu); - return 1; - } - return 0; } @@ -2533,7 +2718,7 @@ dw2_do_expand_symtabs_matching (struct objfile *objfile, const char *name) offset_type cu_index = MAYBE_SWAP (vec[i + 1]); struct dwarf2_per_cu_data *per_cu = dw2_get_cu (cu_index); - dw2_instantiate_symtab (objfile, per_cu); + dw2_instantiate_symtab (per_cu); } } } @@ -2555,7 +2740,7 @@ dw2_print_stats (struct objfile *objfile) dw2_setup (objfile); count = 0; for (i = 0; i < (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_comp_units); ++i) + + dwarf2_per_objfile->n_type_units); ++i) { struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); @@ -2593,11 +2778,11 @@ dw2_expand_all_symtabs (struct objfile *objfile) dw2_setup (objfile); for (i = 0; i < (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_comp_units); ++i) + + dwarf2_per_objfile->n_type_units); ++i) { struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); - dw2_instantiate_symtab (objfile, per_cu); + dw2_instantiate_symtab (per_cu); } } @@ -2620,6 +2805,7 @@ dw2_expand_symtabs_with_filename (struct objfile *objfile, struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); struct quick_file_names *file_data; + /* We only need to look at symtabs not already expanded. */ if (per_cu->v.quick->symtab) continue; @@ -2632,7 +2818,7 @@ dw2_expand_symtabs_with_filename (struct objfile *objfile, const char *this_name = file_data->file_names[j]; if (FILENAME_CMP (this_name, filename) == 0) { - dw2_instantiate_symtab (objfile, per_cu); + dw2_instantiate_symtab (per_cu); break; } } @@ -2650,7 +2836,21 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name) /* index_table is NULL if OBJF_READNOW. */ if (!dwarf2_per_objfile->index_table) - return NULL; + { + struct symtab *s; + + ALL_OBJFILE_SYMTABS (objfile, s) + if (s->primary) + { + struct blockvector *bv = BLOCKVECTOR (s); + const struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); + struct symbol *sym = lookup_block_symbol (block, name, VAR_DOMAIN); + + if (sym) + return sym->symtab->filename; + } + return NULL; + } if (!find_slot_in_mapped_hash (dwarf2_per_objfile->index_table, name, &vec)) @@ -2664,7 +2864,8 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name) per_cu = dw2_get_cu (MAYBE_SWAP (vec[1])); file_data = dw2_get_file_names (objfile, per_cu); - if (file_data == NULL) + if (file_data == NULL + || file_data->num_file_names == 0) return NULL; return file_data->file_names[file_data->num_file_names - 1]; @@ -2684,11 +2885,12 @@ dw2_map_matching_symbols (const char * name, domain_enum namespace, } static void -dw2_expand_symtabs_matching (struct objfile *objfile, - int (*file_matcher) (const char *, void *), - int (*name_matcher) (const char *, void *), - enum search_domain kind, - void *data) +dw2_expand_symtabs_matching + (struct objfile *objfile, + int (*file_matcher) (const char *, void *), + int (*name_matcher) (const char *, void *), + enum search_domain kind, + void *data) { int i; offset_type iter; @@ -2702,30 +2904,63 @@ dw2_expand_symtabs_matching (struct objfile *objfile, index = dwarf2_per_objfile->index_table; if (file_matcher != NULL) - for (i = 0; i < (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_comp_units); ++i) - { - int j; - struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); - struct quick_file_names *file_data; + { + struct cleanup *cleanup; + htab_t visited_found, visited_not_found; - per_cu->v.quick->mark = 0; - if (per_cu->v.quick->symtab) - continue; + visited_found = htab_create_alloc (10, + htab_hash_pointer, htab_eq_pointer, + NULL, xcalloc, xfree); + cleanup = make_cleanup_htab_delete (visited_found); + visited_not_found = htab_create_alloc (10, + htab_hash_pointer, htab_eq_pointer, + NULL, xcalloc, xfree); + make_cleanup_htab_delete (visited_not_found); - file_data = dw2_get_file_names (objfile, per_cu); - if (file_data == NULL) - continue; + for (i = 0; i < (dwarf2_per_objfile->n_comp_units + + dwarf2_per_objfile->n_type_units); ++i) + { + int j; + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); + struct quick_file_names *file_data; + void **slot; - for (j = 0; j < file_data->num_file_names; ++j) - { - if (file_matcher (file_data->file_names[j], data)) - { - per_cu->v.quick->mark = 1; - break; - } - } - } + per_cu->v.quick->mark = 0; + + /* We only need to look at symtabs not already expanded. */ + if (per_cu->v.quick->symtab) + continue; + + file_data = dw2_get_file_names (objfile, per_cu); + if (file_data == NULL) + continue; + + if (htab_find (visited_not_found, file_data) != NULL) + continue; + else if (htab_find (visited_found, file_data) != NULL) + { + per_cu->v.quick->mark = 1; + continue; + } + + for (j = 0; j < file_data->num_file_names; ++j) + { + if (file_matcher (file_data->file_names[j], data)) + { + per_cu->v.quick->mark = 1; + break; + } + } + + slot = htab_find_slot (per_cu->v.quick->mark + ? visited_found + : visited_not_found, + file_data, INSERT); + *slot = file_data; + } + + do_cleanups (cleanup); + } for (iter = 0; iter < index->symbol_table_slots; ++iter) { @@ -2752,11 +2987,35 @@ dw2_expand_symtabs_matching (struct objfile *objfile, per_cu = dw2_get_cu (MAYBE_SWAP (vec[vec_idx + 1])); if (file_matcher == NULL || per_cu->v.quick->mark) - dw2_instantiate_symtab (objfile, per_cu); + dw2_instantiate_symtab (per_cu); } } } +/* A helper for dw2_find_pc_sect_symtab which finds the most specific + symtab. */ + +static struct symtab * +recursively_find_pc_sect_symtab (struct symtab *symtab, CORE_ADDR pc) +{ + int i; + + if (BLOCKVECTOR (symtab) != NULL + && blockvector_contains_pc (BLOCKVECTOR (symtab), pc)) + return symtab; + + for (i = 0; symtab->includes[i]; ++i) + { + struct symtab *s; + + s = recursively_find_pc_sect_symtab (s, pc); + if (s != NULL) + return s; + } + + return NULL; +} + static struct symtab * dw2_find_pc_sect_symtab (struct objfile *objfile, struct minimal_symbol *msymbol, @@ -2765,6 +3024,7 @@ dw2_find_pc_sect_symtab (struct objfile *objfile, int warn_if_readin) { struct dwarf2_per_cu_data *data; + struct symtab *result; dw2_setup (objfile); @@ -2779,24 +3039,47 @@ dw2_find_pc_sect_symtab (struct objfile *objfile, warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"), paddress (get_objfile_arch (objfile), pc)); - return dw2_instantiate_symtab (objfile, data); + result = recursively_find_pc_sect_symtab (dw2_instantiate_symtab (data), pc); + gdb_assert (result != NULL); + return result; } static void dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun, - void *data) + void *data, int need_fullname) { int i; + struct cleanup *cleanup; + htab_t visited = htab_create_alloc (10, htab_hash_pointer, htab_eq_pointer, + NULL, xcalloc, xfree); + cleanup = make_cleanup_htab_delete (visited); dw2_setup (objfile); + /* We can ignore file names coming from already-expanded CUs. */ for (i = 0; i < (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_comp_units); ++i) + + dwarf2_per_objfile->n_type_units); ++i) { - int j; struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); - struct quick_file_names *file_data; + if (per_cu->v.quick->symtab) + { + void **slot = htab_find_slot (visited, per_cu->v.quick->file_names, + INSERT); + + *slot = per_cu->v.quick->file_names; + } + } + + for (i = 0; i < (dwarf2_per_objfile->n_comp_units + + dwarf2_per_objfile->n_type_units); ++i) + { + int j; + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); + struct quick_file_names *file_data; + void **slot; + + /* We only need to look at symtabs not already expanded. */ if (per_cu->v.quick->symtab) continue; @@ -2804,13 +3087,27 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun, if (file_data == NULL) continue; + slot = htab_find_slot (visited, file_data, INSERT); + if (*slot) + { + /* Already visited. */ + continue; + } + *slot = file_data; + for (j = 0; j < file_data->num_file_names; ++j) { - const char *this_real_name = dw2_get_real_path (objfile, file_data, - j); + const char *this_real_name; + + if (need_fullname) + this_real_name = dw2_get_real_path (objfile, file_data, j); + else + this_real_name = NULL; (*fun) (file_data->file_names[j], this_real_name, data); } } + + do_cleanups (cleanup); } static int @@ -2824,7 +3121,7 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions = dw2_has_symbols, dw2_find_last_source_symtab, dw2_forget_cached_source_info, - dw2_lookup_symtab, + dw2_map_symtabs_matching_filename, dw2_lookup_symbol, dw2_pre_expand_symtabs_matching, dw2_print_stats, @@ -2856,12 +3153,12 @@ dwarf2_initialize_objfile (struct objfile *objfile) dwarf2_per_objfile->using_index = 1; create_all_comp_units (objfile); - create_debug_types_hash_table (objfile); + create_all_type_units (objfile); dwarf2_per_objfile->quick_file_names_table = create_quick_file_names_table (dwarf2_per_objfile->n_comp_units); for (i = 0; i < (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_comp_units); ++i) + + dwarf2_per_objfile->n_type_units); ++i) { struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); @@ -2899,14 +3196,13 @@ dwarf2_build_psymtabs (struct objfile *objfile) /* Return TRUE if OFFSET is within CU_HEADER. */ static inline int -offset_in_cu_p (const struct comp_unit_head *cu_header, unsigned int offset) +offset_in_cu_p (const struct comp_unit_head *cu_header, sect_offset offset) { - unsigned int bottom = cu_header->offset; - unsigned int top = (cu_header->offset - + cu_header->length - + cu_header->initial_length_size); + sect_offset bottom = { cu_header->offset.sect_off }; + sect_offset top = { (cu_header->offset.sect_off + cu_header->length + + cu_header->initial_length_size) }; - return (offset >= bottom && offset < top); + return (offset.sect_off >= bottom.sect_off && offset.sect_off < top.sect_off); } /* Read in the comp unit header information from the debug_info at info_ptr. @@ -2926,8 +3222,8 @@ read_comp_unit_head (struct comp_unit_head *cu_header, info_ptr += bytes_read; cu_header->version = read_2_bytes (abfd, info_ptr); info_ptr += 2; - cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header, - &bytes_read); + cu_header->abbrev_offset.sect_off = read_offset (abfd, info_ptr, cu_header, + &bytes_read); info_ptr += bytes_read; cu_header->addr_size = read_1_byte (abfd, info_ptr); info_ptr += 1; @@ -2940,36 +3236,66 @@ read_comp_unit_head (struct comp_unit_head *cu_header, return info_ptr; } -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; +/* Subroutine of read_and_check_comp_unit_head and + read_and_check_type_unit_head to simplify them. + Perform various error checking on the header. */ - info_ptr = read_comp_unit_head (header, info_ptr, abfd); +static void +error_check_comp_unit_head (struct comp_unit_head *header, + struct dwarf2_section_info *section) +{ + bfd *abfd = section->asection->owner; + const char *filename = bfd_get_filename (abfd); if (header->version != 2 && header->version != 3 && header->version != 4) error (_("Dwarf Error: wrong version in compilation unit header " "(is %d, should be 2, 3, or 4) [in module %s]"), header->version, - bfd_get_filename (abfd)); + filename); - if (header->abbrev_offset + if (header->abbrev_offset.sect_off >= dwarf2_section_size (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->abbrev)) 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 - buffer), - bfd_get_filename (abfd)); - - if (beg_of_comp_unit + header->length + header->initial_length_size - > buffer + buffer_size) + (long) header->abbrev_offset.sect_off, (long) header->offset.sect_off, + filename); + + /* Cast to unsigned long to use 64-bit arithmetic when possible to + avoid potential 32-bit overflow. */ + if (((unsigned long) header->offset.sect_off + + header->length + header->initial_length_size) + > section->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 - buffer), - bfd_get_filename (abfd)); + (long) header->length, (long) header->offset.sect_off, + filename); +} + +/* Read in a CU/TU header and perform some basic error checking. + The contents of the header are stored in HEADER. + The result is a pointer to the start of the first DIE. */ + +static gdb_byte * +read_and_check_comp_unit_head (struct comp_unit_head *header, + struct dwarf2_section_info *section, + gdb_byte *info_ptr, + int is_debug_types_section) +{ + gdb_byte *beg_of_comp_unit = info_ptr; + bfd *abfd = section->asection->owner; + + header->offset.sect_off = beg_of_comp_unit - section->buffer; + + info_ptr = read_comp_unit_head (header, info_ptr, abfd); + + /* If we're reading a type unit, skip over the signature and + type_offset fields. */ + if (is_debug_types_section) + info_ptr += 8 /*signature*/ + header->offset_size; + + header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit; + + error_check_comp_unit_head (header, section); return info_ptr; } @@ -2978,24 +3304,34 @@ partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr, 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, - struct dwarf2_section_info *section, - ULONGEST *signature, - gdb_byte *types_ptr, bfd *abfd) +read_and_check_type_unit_head (struct comp_unit_head *header, + struct dwarf2_section_info *section, + gdb_byte *info_ptr, + ULONGEST *signature, + cu_offset *type_offset_in_tu) { - gdb_byte *initial_types_ptr = types_ptr; + gdb_byte *beg_of_comp_unit = info_ptr; + bfd *abfd = section->asection->owner; - dwarf2_read_section (dwarf2_per_objfile->objfile, section); - cu_header->offset = types_ptr - section->buffer; + header->offset.sect_off = beg_of_comp_unit - section->buffer; + + info_ptr = read_comp_unit_head (header, info_ptr, abfd); - types_ptr = read_comp_unit_head (cu_header, types_ptr, abfd); + /* If we're reading a type unit, skip over the signature and + type_offset fields. */ + if (signature != NULL) + *signature = read_8_bytes (abfd, info_ptr); + info_ptr += 8; + if (type_offset_in_tu != NULL) + type_offset_in_tu->cu_off = read_offset_1 (abfd, info_ptr, + header->offset_size); + info_ptr += header->offset_size; - *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; + header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit; - return types_ptr; + error_check_comp_unit_head (header, section); + + return info_ptr; } /* Allocate a new partial symtab for file named NAME and mark this new @@ -3037,41 +3373,35 @@ dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst, static void dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, - struct die_info *die, - struct partial_symtab *pst) + struct die_info *die, + struct partial_symtab *pst) { - struct objfile *objfile = cu->objfile; - bfd *abfd = objfile->obfd; struct line_header *lh = NULL; struct attribute *attr; 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); - } + lh = dwarf_decode_line_header (DW_UNSND (attr), cu); if (lh == NULL) return; /* No linetable, so no includes. */ /* NOTE: pst->dirname is DW_AT_comp_dir (if present). */ - dwarf_decode_lines (lh, pst->dirname, abfd, cu, pst); + dwarf_decode_lines (lh, pst->dirname, cu, pst, 1); free_line_header (lh); } static hashval_t -hash_type_signature (const void *item) +hash_signatured_type (const void *item) { - const struct signatured_type *type_sig = item; + const struct signatured_type *sig_type = item; /* This drops the top 32 bits of the signature, but is ok for a hash. */ - return type_sig->signature; + return sig_type->signature; } static int -eq_type_signature (const void *item_lhs, const void *item_rhs) +eq_signatured_type (const void *item_lhs, const void *item_rhs) { const struct signatured_type *lhs = item_lhs; const struct signatured_type *rhs = item_rhs; @@ -3085,18 +3415,18 @@ static htab_t allocate_signatured_type_table (struct objfile *objfile) { return htab_create_alloc_ex (41, - hash_type_signature, - eq_type_signature, + hash_signatured_type, + eq_signatured_type, NULL, &objfile->objfile_obstack, hashtab_obstack_allocate, dummy_obstack_deallocate); } -/* A helper function to add a signatured type CU to a list. */ +/* A helper function to add a signatured type CU to a table. */ static int -add_signatured_type_cu_to_list (void **slot, void *datum) +add_signatured_type_cu_to_table (void **slot, void *datum) { struct signatured_type *sigt = *slot; struct dwarf2_per_cu_data ***datap = datum; @@ -3108,28 +3438,27 @@ add_signatured_type_cu_to_list (void **slot, void *datum) } /* 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. */ + DWO_FILE is a pointer to the DWO file for .debug_types.dwo, NULL otherwise. + The result is a pointer to the hash table or NULL if there are + no types. */ -static int -create_debug_types_hash_table (struct objfile *objfile) +static htab_t +create_debug_types_hash_table (struct dwo_file *dwo_file, + VEC (dwarf2_section_info_def) *types) { + struct objfile *objfile = dwarf2_per_objfile->objfile; htab_t types_htab = NULL; - struct dwarf2_per_cu_data **iter; int ix; struct dwarf2_section_info *section; - if (VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)) - { - dwarf2_per_objfile->signatured_types = NULL; - return 0; - } + if (VEC_empty (dwarf2_section_info_def, types)) + return NULL; for (ix = 0; - VEC_iterate (dwarf2_section_info_def, dwarf2_per_objfile->types, - ix, section); + VEC_iterate (dwarf2_section_info_def, types, ix, section); ++ix) { + bfd *abfd; gdb_byte *info_ptr, *end_ptr; dwarf2_read_section (objfile, section); @@ -3138,102 +3467,164 @@ create_debug_types_hash_table (struct objfile *objfile) if (info_ptr == NULL) continue; + /* We can't set abfd until now because the section may be empty or + not present, in which case section->asection will be NULL. */ + abfd = section->asection->owner; + if (types_htab == NULL) - types_htab = allocate_signatured_type_table (objfile); + { + if (dwo_file) + types_htab = allocate_dwo_unit_table (objfile); + else + types_htab = allocate_signatured_type_table (objfile); + } if (dwarf2_die_debug) - fprintf_unfiltered (gdb_stdlog, "Signatured types:\n"); + fprintf_unfiltered (gdb_stdlog, "Reading signatured types for %s:\n", + bfd_get_filename (abfd)); + + /* We don't use init_cutu_and_read_dies_simple, or some such, here + because we don't need to read any dies: the signature is in the + header. */ end_ptr = info_ptr + section->size; while (info_ptr < end_ptr) { - unsigned int offset; - unsigned int offset_size; - unsigned int type_offset; - unsigned int length, initial_length_size; - unsigned short version; + sect_offset offset; + cu_offset type_offset_in_tu; ULONGEST signature; - struct signatured_type *type_sig; + struct signatured_type *sig_type; + struct dwo_unit *dwo_tu; void **slot; gdb_byte *ptr = info_ptr; + struct comp_unit_head header; + unsigned int length; - offset = ptr - section->buffer; + offset.sect_off = ptr - section->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. */ + table, but we don't need 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 > end_ptr) + ptr = read_and_check_type_unit_head (&header, section, ptr, + &signature, &type_offset_in_tu); + + length = header.initial_length_size + header.length; + + /* Skip dummy type units. */ + if (ptr >= info_ptr + length + || peek_abbrev_code (abfd, ptr) == 0) { - complaint (&symfile_complaints, - _("debug type entry runs off end " - "of `.debug_types' section, ignored")); - break; + info_ptr += header.initial_length_size + header.length; + continue; + } + + if (dwo_file) + { + sig_type = NULL; + dwo_tu = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct dwo_unit); + dwo_tu->dwo_file = dwo_file; + dwo_tu->signature = signature; + dwo_tu->type_offset_in_tu = type_offset_in_tu; + dwo_tu->info_or_types_section = section; + dwo_tu->offset = offset; + dwo_tu->length = length; + } + else + { + /* N.B.: type_offset is not usable if this type uses a DWO file. + The real type_offset is in the DWO file. */ + dwo_tu = NULL; + sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct signatured_type); + sig_type->signature = signature; + sig_type->type_offset_in_tu = type_offset_in_tu; + sig_type->per_cu.objfile = objfile; + sig_type->per_cu.is_debug_types = 1; + sig_type->per_cu.info_or_types_section = section; + sig_type->per_cu.offset = offset; + sig_type->per_cu.length = length; } - 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->type_offset = type_offset; - type_sig->per_cu.objfile = objfile; - type_sig->per_cu.debug_type_section = section; - type_sig->per_cu.offset = offset; - - slot = htab_find_slot (types_htab, type_sig, INSERT); + slot = htab_find_slot (types_htab, + dwo_file ? (void*) dwo_tu : (void *) sig_type, + INSERT); gdb_assert (slot != NULL); if (*slot != NULL) { - const struct signatured_type *dup_sig = *slot; + sect_offset dup_offset; + + if (dwo_file) + { + const struct dwo_unit *dup_tu = *slot; + + dup_offset = dup_tu->offset; + } + else + { + const struct signatured_type *dup_tu = *slot; + + dup_offset = dup_tu->per_cu.offset; + } complaint (&symfile_complaints, _("debug type entry at offset 0x%x is duplicate to the " "entry at offset 0x%x, signature 0x%s"), - offset, dup_sig->per_cu.offset, + offset.sect_off, dup_offset.sect_off, phex (signature, sizeof (signature))); - gdb_assert (signature == dup_sig->signature); } - *slot = type_sig; + *slot = dwo_file ? (void *) dwo_tu : (void *) sig_type; if (dwarf2_die_debug) fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n", - offset, phex (signature, sizeof (signature))); + offset.sect_off, + phex (signature, sizeof (signature))); - info_ptr = info_ptr + initial_length_size + length; + info_ptr += length; } } + return types_htab; +} + +/* Create the hash table of all entries in the .debug_types section, + and initialize all_type_units. + The result is zero if there is an error (e.g. missing .debug_types section), + otherwise non-zero. */ + +static int +create_all_type_units (struct objfile *objfile) +{ + htab_t types_htab; + struct dwarf2_per_cu_data **iter; + + types_htab = create_debug_types_hash_table (NULL, dwarf2_per_objfile->types); + if (types_htab == NULL) + { + dwarf2_per_objfile->signatured_types = NULL; + return 0; + } + dwarf2_per_objfile->signatured_types = types_htab; - dwarf2_per_objfile->n_type_comp_units = htab_elements (types_htab); - dwarf2_per_objfile->type_comp_units + dwarf2_per_objfile->n_type_units = htab_elements (types_htab); + dwarf2_per_objfile->all_type_units = obstack_alloc (&objfile->objfile_obstack, - dwarf2_per_objfile->n_type_comp_units + dwarf2_per_objfile->n_type_units * sizeof (struct dwarf2_per_cu_data *)); - iter = &dwarf2_per_objfile->type_comp_units[0]; - htab_traverse_noresize (types_htab, add_signatured_type_cu_to_list, &iter); - gdb_assert (iter - &dwarf2_per_objfile->type_comp_units[0] - == dwarf2_per_objfile->n_type_comp_units); + iter = &dwarf2_per_objfile->all_type_units[0]; + htab_traverse_noresize (types_htab, add_signatured_type_cu_to_table, &iter); + gdb_assert (iter - &dwarf2_per_objfile->all_type_units[0] + == dwarf2_per_objfile->n_type_units); return 1; } -/* Lookup a signature based type. - Returns NULL if SIG is not present in the table. */ +/* Lookup a signature based type for DW_FORM_ref_sig8. + Returns NULL if signature SIG is not present in the table. */ static struct signatured_type * -lookup_signatured_type (struct objfile *objfile, ULONGEST sig) +lookup_signatured_type (ULONGEST sig) { struct signatured_type find_entry, *entry; @@ -3241,7 +3632,7 @@ lookup_signatured_type (struct objfile *objfile, ULONGEST sig) { complaint (&symfile_complaints, _("missing `.debug_types' section for DW_FORM_ref_sig8 die")); - return 0; + return NULL; } find_entry.signature = sig; @@ -3253,20 +3644,16 @@ lookup_signatured_type (struct objfile *objfile, ULONGEST sig) static void init_cu_die_reader (struct die_reader_specs *reader, - struct dwarf2_cu *cu) + struct dwarf2_cu *cu, + struct dwarf2_section_info *section, + struct dwo_file *dwo_file) { - reader->abfd = cu->objfile->obfd; + gdb_assert (section->readin && section->buffer != NULL); + reader->abfd = section->asection->owner; reader->cu = cu; - if (cu->per_cu->debug_type_section) - { - gdb_assert (cu->per_cu->debug_type_section->readin); - reader->buffer = cu->per_cu->debug_type_section->buffer; - } - else - { - gdb_assert (dwarf2_per_objfile->info.readin); - reader->buffer = dwarf2_per_objfile->info.buffer; - } + reader->dwo_file = dwo_file; + reader->die_section = section; + reader->buffer = section->buffer; } /* Find the base address of the compilation unit for range lists and @@ -3300,91 +3687,408 @@ dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu) } } -/* 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. */ +/* Initialize a CU (or TU) and read its DIEs. + If the CU defers to a DWO file, read the DWO file as well. -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) -{ - bfd *abfd = objfile->obfd; - gdb_byte *beg_of_comp_unit = info_ptr; + If USE_EXISTING_CU is non-zero, and THIS_CU->cu is non-NULL, then use it. + Otherwise, a new CU is allocated with xmalloc. + + If KEEP is non-zero, then if we allocated a dwarf2_cu we add it to + read_in_chain. Otherwise the dwarf2_cu data is freed at the end. + + WARNING: If THIS_CU is a "dummy CU" (used as filler by the incremental + linker) then DIE_READER_FUNC will not get called. */ + +static void +init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, + int use_existing_cu, int keep, + die_reader_func_ftype *die_reader_func, + void *data) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwarf2_section_info *section = this_cu->info_or_types_section; + bfd *abfd = section->asection->owner; + struct dwarf2_cu *cu; + gdb_byte *begin_info_ptr, *info_ptr; + struct die_reader_specs reader; struct die_info *comp_unit_die; - struct partial_symtab *pst; - CORE_ADDR baseaddr; - struct cleanup *back_to_inner; - struct dwarf2_cu cu; - int has_children, has_pc_info; + int has_children; struct attribute *attr; - CORE_ADDR best_lowpc = 0, best_highpc = 0; - struct die_reader_specs reader_specs; - const char *filename; + struct cleanup *cleanups, *free_cu_cleanup = NULL; + struct signatured_type *sig_type = NULL; - init_one_comp_unit (&cu, objfile); - back_to_inner = make_cleanup (free_stack_comp_unit, &cu); + if (use_existing_cu) + gdb_assert (keep); - info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr, - buffer, buffer_size, - abfd); + cleanups = make_cleanup (null_cleanup, NULL); - /* Complete the cu_header. */ - cu.header.offset = beg_of_comp_unit - buffer; - cu.header.first_die_offset = info_ptr - beg_of_comp_unit; + /* This is cheap if the section is already read in. */ + dwarf2_read_section (objfile, section); - cu.list_in_scope = &file_symbols; + begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off; - /* 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); + if (use_existing_cu && this_cu->cu != NULL) + { + cu = this_cu->cu; + info_ptr += cu->header.first_die_offset.cu_off; + } + else + { + /* If !use_existing_cu, this_cu->cu must be NULL. */ + gdb_assert (this_cu->cu == NULL); + + cu = xmalloc (sizeof (*cu)); + init_one_comp_unit (cu, this_cu); + + /* If an error occurs while loading, release our storage. */ + free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu); + + if (this_cu->is_debug_types) + { + ULONGEST signature; + + info_ptr = read_and_check_type_unit_head (&cu->header, + section, info_ptr, + &signature, NULL); + + /* There's no way to get from PER_CU to its containing + struct signatured_type. + But we have the signature so we can use that. */ + sig_type = lookup_signatured_type (signature); + /* We've already scanned all the signatured types, + this must succeed. */ + gdb_assert (sig_type != NULL); + gdb_assert (&sig_type->per_cu == this_cu); + gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off); + + /* LENGTH has not been set yet for type units. */ + this_cu->length = cu->header.length + cu->header.initial_length_size; + + /* Establish the type offset that can be used to lookup the type. */ + sig_type->type_offset_in_section.sect_off = + this_cu->offset.sect_off + sig_type->type_offset_in_tu.cu_off; + } + else + { + info_ptr = read_and_check_comp_unit_head (&cu->header, + section, info_ptr, 0); + + gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off); + gdb_assert (this_cu->length + == cu->header.length + cu->header.initial_length_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; - cu.per_cu = this_cu; + /* Skip dummy compilation units. */ + if (info_ptr >= begin_info_ptr + this_cu->length + || peek_abbrev_code (abfd, info_ptr) == 0) + { + do_cleanups (cleanups); + return; + } /* Read the abbrevs for this compilation unit into a table. */ - dwarf2_read_abbrevs (abfd, &cu); - make_cleanup (dwarf2_free_abbrev_table, &cu); + if (cu->dwarf2_abbrevs == NULL) + { + dwarf2_read_abbrevs (cu, &dwarf2_per_objfile->abbrev); + make_cleanup (dwarf2_free_abbrev_table, cu); + } + + /* Read the top level CU/TU die. */ + init_cu_die_reader (&reader, cu, section, NULL); + info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children); + + /* If we have a DWO stub, process it and then read in the DWO file. + Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains + a DWO CU, that this test will fail. */ + attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu); + if (attr) + { + char *dwo_name = DW_STRING (attr); + const char *comp_dir; + struct dwo_unit *dwo_unit; + ULONGEST signature; /* Or dwo_id. */ + struct attribute *stmt_list, *low_pc, *high_pc, *ranges; + int i,num_extra_attrs; + + if (has_children) + error (_("Dwarf Error: compilation unit with DW_AT_GNU_dwo_name" + " has children (offset 0x%x) [in module %s]"), + this_cu->offset.sect_off, bfd_get_filename (abfd)); + + /* These attributes aren't processed until later: + DW_AT_stmt_list, DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges. + However, the attribute is found in the stub which we won't have later. + In order to not impose this complication on the rest of the code, + we read them here and copy them to the DWO CU/TU die. */ + stmt_list = low_pc = high_pc = ranges = NULL; + + /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the + DWO file. */ + if (! this_cu->is_debug_types) + stmt_list = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu); + low_pc = dwarf2_attr (comp_unit_die, DW_AT_low_pc, cu); + high_pc = dwarf2_attr (comp_unit_die, DW_AT_high_pc, cu); + ranges = dwarf2_attr (comp_unit_die, DW_AT_ranges, cu); + + /* There should be a DW_AT_addr_base attribute here (if needed). + We need the value before we can process DW_FORM_GNU_addr_index. */ + cu->addr_base = 0; + cu->have_addr_base = 0; + attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_addr_base, cu); + if (attr) + { + cu->addr_base = DW_UNSND (attr); + cu->have_addr_base = 1; + } + + if (this_cu->is_debug_types) + { + gdb_assert (sig_type != NULL); + signature = sig_type->signature; + } + else + { + attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu); + if (! attr) + error (_("Dwarf Error: missing dwo_id [in module %s]"), + dwo_name); + signature = DW_UNSND (attr); + } + + /* We may need the comp_dir in order to find the DWO file. */ + comp_dir = NULL; + attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu); + if (attr) + comp_dir = DW_STRING (attr); + + if (this_cu->is_debug_types) + dwo_unit = lookup_dwo_type_unit (sig_type, dwo_name, comp_dir); + else + dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir, + signature); + + if (dwo_unit == NULL) + { + error (_("Dwarf Error: CU at offset 0x%x references unknown DWO" + " with ID %s [in module %s]"), + this_cu->offset.sect_off, + phex (signature, sizeof (signature)), + objfile->name); + } + + /* Set up for reading the DWO CU/TU. */ + cu->dwo_unit = dwo_unit; + section = dwo_unit->info_or_types_section; + begin_info_ptr = info_ptr = section->buffer + dwo_unit->offset.sect_off; + init_cu_die_reader (&reader, cu, section, dwo_unit->dwo_file); + + if (this_cu->is_debug_types) + { + ULONGEST signature; + + info_ptr = read_and_check_type_unit_head (&cu->header, + section, info_ptr, + &signature, NULL); + gdb_assert (sig_type->signature == signature); + gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off); + gdb_assert (dwo_unit->length + == cu->header.length + cu->header.initial_length_size); + + /* Establish the type offset that can be used to lookup the type. + For DWO files, we don't know it until now. */ + sig_type->type_offset_in_section.sect_off = + dwo_unit->offset.sect_off + dwo_unit->type_offset_in_tu.cu_off; + } + else + { + info_ptr = read_and_check_comp_unit_head (&cu->header, + section, info_ptr, 0); + gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off); + gdb_assert (dwo_unit->length + == cu->header.length + cu->header.initial_length_size); + } + + /* Discard the original CU's abbrev table, and read the DWO's. */ + dwarf2_free_abbrev_table (cu); + dwarf2_read_abbrevs (cu, &dwo_unit->dwo_file->sections.abbrev); + + /* Read in the die, but leave space to copy over the attributes + from the stub. This has the benefit of simplifying the rest of + the code - all the real work is done here. */ + num_extra_attrs = ((stmt_list != NULL) + + (low_pc != NULL) + + (high_pc != NULL) + + (ranges != NULL)); + info_ptr = read_full_die_1 (&reader, &comp_unit_die, info_ptr, + &has_children, num_extra_attrs); + + /* Copy over the attributes from the stub to the DWO die. */ + i = comp_unit_die->num_attrs; + if (stmt_list != NULL) + comp_unit_die->attrs[i++] = *stmt_list; + if (low_pc != NULL) + comp_unit_die->attrs[i++] = *low_pc; + if (high_pc != NULL) + comp_unit_die->attrs[i++] = *high_pc; + if (ranges != NULL) + comp_unit_die->attrs[i++] = *ranges; + comp_unit_die->num_attrs += num_extra_attrs; + + /* Skip dummy compilation units. */ + if (info_ptr >= begin_info_ptr + dwo_unit->length + || peek_abbrev_code (abfd, info_ptr) == 0) + { + do_cleanups (cleanups); + return; + } + } - /* Read the compilation unit die. */ - if (this_cu->debug_type_section) - 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); + die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data); - if (this_cu->debug_type_section) + if (free_cu_cleanup != NULL) { - /* LENGTH has not been set yet for type units. */ - gdb_assert (this_cu->offset == cu.header.offset); - this_cu->length = cu.header.length + cu.header.initial_length_size; + if (keep) + { + /* We've successfully allocated this compilation unit. Let our + caller clean it up when finished with it. */ + discard_cleanups (free_cu_cleanup); + + /* We can only discard free_cu_cleanup and all subsequent cleanups. + So we have to manually free the abbrev table. */ + dwarf2_free_abbrev_table (cu); + + /* Link this CU into read_in_chain. */ + this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; + dwarf2_per_objfile->read_in_chain = this_cu; + } + else + do_cleanups (free_cu_cleanup); } - else if (comp_unit_die->tag == DW_TAG_partial_unit) + + do_cleanups (cleanups); +} + +/* Read CU/TU THIS_CU in section SECTION, + but do not follow DW_AT_GNU_dwo_name if present. + DWO_FILE, if non-NULL, is the DWO file to read (the caller is assumed to + have already done the lookup to find the DWO file). + + The caller is required to fill in THIS_CU->section, THIS_CU->offset, and + THIS_CU->is_debug_types, but nothing else. + + We fill in THIS_CU->length. + + WARNING: If THIS_CU is a "dummy CU" (used as filler by the incremental + linker) then DIE_READER_FUNC will not get called. + + THIS_CU->cu is always freed when done. + This is done in order to not leave THIS_CU->cu in a state where we have + to care whether it refers to the "main" CU or the DWO CU. */ + +static void +init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu, + struct dwarf2_section_info *abbrev_section, + struct dwo_file *dwo_file, + die_reader_func_ftype *die_reader_func, + void *data) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwarf2_section_info *section = this_cu->info_or_types_section; + bfd *abfd = section->asection->owner; + struct dwarf2_cu cu; + gdb_byte *begin_info_ptr, *info_ptr; + struct die_reader_specs reader; + struct cleanup *cleanups; + struct die_info *comp_unit_die; + int has_children; + + gdb_assert (this_cu->cu == NULL); + + /* This is cheap if the section is already read in. */ + dwarf2_read_section (objfile, section); + + init_one_comp_unit (&cu, this_cu); + + cleanups = make_cleanup (free_stack_comp_unit, &cu); + + begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off; + info_ptr = read_and_check_comp_unit_head (&cu.header, section, info_ptr, + this_cu->is_debug_types); + + this_cu->length = cu.header.length + cu.header.initial_length_size; + + /* Skip dummy compilation units. */ + if (info_ptr >= begin_info_ptr + this_cu->length + || peek_abbrev_code (abfd, info_ptr) == 0) { - info_ptr = (beg_of_comp_unit + cu.header.length - + cu.header.initial_length_size); - do_cleanups (back_to_inner); - return info_ptr; + do_cleanups (cleanups); + return; } - prepare_one_comp_unit (&cu, comp_unit_die); + dwarf2_read_abbrevs (&cu, abbrev_section); + make_cleanup (dwarf2_free_abbrev_table, &cu); + + init_cu_die_reader (&reader, &cu, section, dwo_file); + info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children); + + die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data); + + do_cleanups (cleanups); +} + +/* Read a CU/TU, except that this does not look for DW_AT_GNU_dwo_name and + does not lookup the specified DWO file. + This cannot be used to read DWO files. + + THIS_CU->cu is always freed when done. + This is done in order to not leave THIS_CU->cu in a state where we have + to care whether it refers to the "main" CU or the DWO CU. + We can revisit this if the data shows there's a performance issue. */ + +static void +init_cutu_and_read_dies_simple (struct dwarf2_per_cu_data *this_cu, + die_reader_func_ftype *die_reader_func, + void *data) +{ + init_cutu_and_read_dies_no_follow (this_cu, + &dwarf2_per_objfile->abbrev, + NULL, + die_reader_func, data); +} + +/* die_reader_func for process_psymtab_comp_unit. */ + +static void +process_psymtab_comp_unit_reader (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct die_info *comp_unit_die, + int has_children, + void *data) +{ + struct dwarf2_cu *cu = reader->cu; + struct objfile *objfile = cu->objfile; + struct dwarf2_per_cu_data *per_cu = cu->per_cu; + bfd *abfd = objfile->obfd; + struct attribute *attr; + CORE_ADDR baseaddr; + CORE_ADDR best_lowpc = 0, best_highpc = 0; + struct partial_symtab *pst; + int has_pc_info; + const char *filename; + int *want_partial_unit_ptr = data; + + if (comp_unit_die->tag == DW_TAG_partial_unit + && (want_partial_unit_ptr == NULL + || !*want_partial_unit_ptr)) + return; + + prepare_one_comp_unit (cu, comp_unit_die, language_minimal); + + cu->list_in_scope = &file_symbols; /* Allocate a new partial symbol table structure. */ - attr = dwarf2_attr (comp_unit_die, DW_AT_name, &cu); + attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu); if (attr == NULL || !DW_STRING (attr)) filename = ""; else @@ -3395,26 +4099,27 @@ process_psymtab_comp_unit (struct objfile *objfile, 0, objfile->global_psymbols.next, objfile->static_psymbols.next); + pst->psymtabs_addrmap_supported = 1; - attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, &cu); + attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu); if (attr != NULL) pst->dirname = DW_STRING (attr); - pst->read_symtab_private = this_cu; + pst->read_symtab_private = per_cu; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); /* Store the function that reads in the rest of the symbol table. */ pst->read_symtab = dwarf2_psymtab_to_symtab; - this_cu->v.psymtab = pst; + per_cu->v.psymtab = pst; - dwarf2_find_base_address (comp_unit_die, &cu); + dwarf2_find_base_address (comp_unit_die, cu); /* 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); + &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. */ @@ -3433,10 +4138,10 @@ process_psymtab_comp_unit (struct objfile *objfile, lowpc = ((CORE_ADDR) -1); highpc = ((CORE_ADDR) 0); - first_die = load_partial_dies (abfd, buffer, info_ptr, 1, &cu); + first_die = load_partial_dies (reader, info_ptr, 1); scan_partial_symbols (first_die, &lowpc, &highpc, - ! has_pc_info, &cu); + ! has_pc_info, cu); /* If we didn't find a lowpc, set it to highpc to avoid complaints from `maint check'. */ @@ -3460,10 +4165,27 @@ process_psymtab_comp_unit (struct objfile *objfile, (objfile->static_psymbols.list + pst->statics_offset); sort_pst_symbols (pst); - info_ptr = (beg_of_comp_unit + cu.header.length - + cu.header.initial_length_size); + if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs)) + { + int i; + int len = VEC_length (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs); + struct dwarf2_per_cu_data *iter; + + /* Fill in 'dependencies' here; we fill in 'users' in a + post-pass. */ + pst->number_of_dependencies = len; + pst->dependencies = obstack_alloc (&objfile->objfile_obstack, + len * sizeof (struct symtab *)); + for (i = 0; + VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs, + i, iter); + ++i) + pst->dependencies[i] = iter->v.psymtab; - if (this_cu->debug_type_section) + VEC_free (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs); + } + + if (per_cu->is_debug_types) { /* It's not clear we want to do anything with stmt lists here. Waiting to see what gcc ultimately does. */ @@ -3472,32 +4194,58 @@ process_psymtab_comp_unit (struct objfile *objfile, { /* 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); + dwarf2_build_include_psymtabs (cu, comp_unit_die, pst); } +} - do_cleanups (back_to_inner); +/* Subroutine of dwarf2_build_psymtabs_hard to simplify it. + Process compilation unit THIS_CU for a psymtab. */ - return info_ptr; +static void +process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu, + int want_partial_unit) +{ + /* 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); + + gdb_assert (! this_cu->is_debug_types); + init_cutu_and_read_dies (this_cu, 0, 0, process_psymtab_comp_unit_reader, + &want_partial_unit); + + /* Age out any secondary CUs. */ + age_cached_comp_units (); } /* Traversal function for htab_traverse_noresize. Process one .debug_types comp-unit. */ static int -process_type_comp_unit (void **slot, void *info) +process_psymtab_type_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; + struct signatured_type *sig_type = (struct signatured_type *) *slot; + struct dwarf2_per_cu_data *per_cu = &sig_type->per_cu; + + gdb_assert (per_cu->is_debug_types); + gdb_assert (info == NULL); + + /* 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 (per_cu->cu != NULL) + free_one_cached_comp_unit (per_cu); - this_cu = &entry->per_cu; + init_cutu_and_read_dies (per_cu, 0, 0, process_psymtab_comp_unit_reader, + NULL); - gdb_assert (this_cu->debug_type_section->readin); - process_psymtab_comp_unit (objfile, this_cu, - this_cu->debug_type_section->buffer, - (this_cu->debug_type_section->buffer - + this_cu->offset), - this_cu->debug_type_section->size); + /* Age out any secondary CUs. */ + age_cached_comp_units (); return 1; } @@ -3508,11 +4256,11 @@ process_type_comp_unit (void **slot, void *info) static void build_type_psymtabs (struct objfile *objfile) { - if (! create_debug_types_hash_table (objfile)) + if (! create_all_type_units (objfile)) return; htab_traverse_noresize (dwarf2_per_objfile->signatured_types, - process_type_comp_unit, objfile); + process_psymtab_type_unit, NULL); } /* A cleanup function that clears objfile's psymtabs_addrmap field. */ @@ -3525,20 +4273,41 @@ psymtabs_addrmap_cleanup (void *o) objfile->psymtabs_addrmap = NULL; } +/* Compute the 'user' field for each psymtab in OBJFILE. */ + +static void +set_partial_user (struct objfile *objfile) +{ + int i; + + for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) + { + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); + struct partial_symtab *pst = per_cu->v.psymtab; + int j; + + for (j = 0; j < pst->number_of_dependencies; ++j) + { + /* Set the 'user' field only if it is not already set. */ + if (pst->dependencies[j]->user == NULL) + pst->dependencies[j]->user = pst; + } + } +} + /* Build the partial symbol table by doing a quick pass through the .debug_info and .debug_abbrev sections. */ static void dwarf2_build_psymtabs_hard (struct objfile *objfile) { - gdb_byte *info_ptr; struct cleanup *back_to, *addrmap_cleanup; struct obstack temp_obstack; + int i; dwarf2_per_objfile->reading_partial_symbols = 1; dwarf2_read_section (objfile, &dwarf2_per_objfile->info); - info_ptr = dwarf2_per_objfile->info.buffer; /* Any cached compilation units will be linked by the per-objfile read_in_chain. Make sure to free them when we're done. */ @@ -3555,35 +4324,15 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile) objfile->psymtabs_addrmap = addrmap_create_mutable (&temp_obstack); addrmap_cleanup = make_cleanup (psymtabs_addrmap_cleanup, objfile); - /* 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. - - 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. - - 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)) + for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) { - struct dwarf2_per_cu_data *this_cu; - - this_cu = dwarf2_find_comp_unit (info_ptr - - dwarf2_per_objfile->info.buffer, - objfile); + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); - info_ptr = process_psymtab_comp_unit (objfile, this_cu, - dwarf2_per_objfile->info.buffer, - info_ptr, - dwarf2_per_objfile->info.size); + process_psymtab_comp_unit (per_cu, 0); } + set_partial_user (objfile); + objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap, &objfile->objfile_obstack); discard_cleanups (addrmap_cleanup); @@ -3591,92 +4340,37 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile) do_cleanups (back_to); } -/* Load the partial DIEs for a secondary CU into memory. */ +/* die_reader_func for load_partial_comp_unit. */ static void -load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu, - struct objfile *objfile) +load_partial_comp_unit_reader (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct die_info *comp_unit_die, + int has_children, + void *data) { - bfd *abfd = objfile->obfd; - gdb_byte *info_ptr, *beg_of_comp_unit; - struct die_info *comp_unit_die; - struct dwarf2_cu *cu; - struct cleanup *free_abbrevs_cleanup, *free_cu_cleanup = NULL; - int has_children; - struct die_reader_specs reader_specs; - int read_cu = 0; - - gdb_assert (! this_cu->debug_type_section); - - gdb_assert (dwarf2_per_objfile->info.readin); - info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset; - beg_of_comp_unit = info_ptr; - - if (this_cu->cu == NULL) - { - cu = xmalloc (sizeof (*cu)); - init_one_comp_unit (cu, objfile); - - read_cu = 1; - - /* If an error occurs while loading, release our storage. */ - free_cu_cleanup = make_cleanup (free_one_comp_unit, cu); - - 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 = this_cu->offset; - cu->header.first_die_offset = info_ptr - beg_of_comp_unit; - - /* Link this compilation unit into the compilation unit tree. */ - this_cu->cu = cu; - cu->per_cu = this_cu; - - /* Link this CU into read_in_chain. */ - this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; - dwarf2_per_objfile->read_in_chain = this_cu; - } - else - { - cu = this_cu->cu; - info_ptr += cu->header.first_die_offset; - } - - /* Read the abbrevs for this compilation unit into a table. */ - gdb_assert (cu->dwarf2_abbrevs == NULL); - dwarf2_read_abbrevs (abfd, cu); - free_abbrevs_cleanup = make_cleanup (dwarf2_free_abbrev_table, cu); - - /* Read the compilation unit die. */ - init_cu_die_reader (&reader_specs, cu); - info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr, - &has_children); + struct dwarf2_cu *cu = reader->cu; - prepare_one_comp_unit (cu, comp_unit_die); + prepare_one_comp_unit (cu, comp_unit_die, language_minimal); /* 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) - load_partial_dies (abfd, dwarf2_per_objfile->info.buffer, info_ptr, 0, cu); + load_partial_dies (reader, info_ptr, 0); +} - do_cleanups (free_abbrevs_cleanup); +/* Load the partial DIEs for a secondary CU into memory. + This is also used when rereading a primary CU with load_all_dies. */ - if (read_cu) - { - /* We've successfully allocated this compilation unit. Let our - caller clean it up when finished with it. */ - discard_cleanups (free_cu_cleanup); - } +static void +load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu) +{ + init_cutu_and_read_dies (this_cu, 1, 1, load_partial_comp_unit_reader, NULL); } -/* Create a list of all compilation units in OBJFILE. We do this only - if an inter-comp-unit reference is found; presumably if there is one, - there will be many, and one will occur early in the .debug_info section. - So there's no point in building this list incrementally. */ +/* Create a list of all compilation units in OBJFILE. + This is only done for -readnow and building partial symtabs. */ static void create_all_comp_units (struct objfile *objfile) @@ -3699,9 +4393,9 @@ create_all_comp_units (struct objfile *objfile) { unsigned int length, initial_length_size; struct dwarf2_per_cu_data *this_cu; - unsigned int offset; + sect_offset offset; - offset = info_ptr - dwarf2_per_objfile->info.buffer; + offset.sect_off = info_ptr - dwarf2_per_objfile->info.buffer; /* Read just enough information to find out where the next compilation unit is. */ @@ -3715,6 +4409,7 @@ create_all_comp_units (struct objfile *objfile) this_cu->offset = offset; this_cu->length = length + initial_length_size; this_cu->objfile = objfile; + this_cu->info_or_types_section = &dwarf2_per_objfile->info; if (n_comp_units == n_allocated) { @@ -3765,7 +4460,8 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, enums. */ if (pdi->name != NULL || pdi->tag == DW_TAG_namespace - || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type) + || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type + || pdi->tag == DW_TAG_imported_unit) { switch (pdi->tag) { @@ -3805,6 +4501,21 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, case DW_TAG_module: add_partial_module (pdi, lowpc, highpc, need_pc, cu); break; + case DW_TAG_imported_unit: + { + struct dwarf2_per_cu_data *per_cu; + + per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset, + cu->objfile); + + /* Go read the partial unit, if needed. */ + if (per_cu->v.psymtab == NULL) + process_psymtab_comp_unit (per_cu, 1); + + VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs, + per_cu); + } + break; default: break; } @@ -3878,7 +4589,10 @@ partial_die_parent_scope (struct partial_die_info *pdi, return NULL; } - if (parent->tag == DW_TAG_namespace + if (pdi->tag == DW_TAG_enumerator) + /* Enumerators should not get the name of the enumeration as a prefix. */ + parent->scope = grandparent_scope; + else if (parent->tag == DW_TAG_namespace || parent->tag == DW_TAG_module || parent->tag == DW_TAG_structure_type || parent->tag == DW_TAG_class_type @@ -3893,9 +4607,6 @@ partial_die_parent_scope (struct partial_die_info *pdi, grandparent_scope, parent->name, 0, cu); } - else if (parent->tag == DW_TAG_enumerator) - /* Enumerators should not get the name of the enumeration as a prefix. */ - parent->scope = grandparent_scope; else { /* FIXME drow/2004-04-01: What should we be doing with @@ -3903,7 +4614,7 @@ partial_die_parent_scope (struct partial_die_info *pdi, ignoring them. */ complaint (&symfile_complaints, _("unhandled containing DIE tag %d for DIE at %d"), - parent->tag, pdi->offset); + parent->tag, pdi->offset.sect_off); parent->scope = grandparent_scope; } @@ -3913,6 +4624,7 @@ partial_die_parent_scope (struct partial_die_info *pdi, /* Return the fully scoped name associated with PDI, from compilation unit CU. The result will be allocated with malloc. */ + static char * partial_die_full_name (struct partial_die_info *pdi, struct dwarf2_cu *cu) @@ -3933,9 +4645,10 @@ partial_die_full_name (struct partial_die_info *pdi, struct attribute attr; struct dwarf2_cu *ref_cu = cu; + /* DW_FORM_ref_addr is using section offset. */ attr.name = 0; attr.form = DW_FORM_ref_addr; - attr.u.addr = pdi->offset; + attr.u.unsnd = pdi->offset.sect_off; die = follow_die_ref (NULL, &attr, &ref_cu); return xstrdup (dwarf2_full_name (NULL, die, ref_cu)); @@ -3955,7 +4668,6 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) struct objfile *objfile = cu->objfile; CORE_ADDR addr = 0; char *actual_name = NULL; - const struct partial_symbol *psym = NULL; CORE_ADDR baseaddr; int built_actual_name = 0; @@ -4012,10 +4724,10 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) } break; case DW_TAG_variable: - if (pdi->locdesc) - addr = decode_locdesc (pdi->locdesc, cu); + if (pdi->d.locdesc) + addr = decode_locdesc (pdi->d.locdesc, cu); - if (pdi->locdesc + if (pdi->d.locdesc && addr == 0 && !dwarf2_per_objfile->has_section_at_zero) { @@ -4039,7 +4751,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) used by GDB, but it comes in handy for debugging partial symbol table building. */ - if (pdi->locdesc || pdi->has_type) + if (pdi->d.locdesc || pdi->has_type) add_psymbol_to_list (actual_name, strlen (actual_name), built_actual_name, VAR_DOMAIN, LOC_STATIC, @@ -4050,7 +4762,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) else { /* Static Variable. Skip symbols without location descriptors. */ - if (pdi->locdesc == NULL) + if (pdi->d.locdesc == NULL) { if (built_actual_name) xfree (actual_name); @@ -4195,6 +4907,10 @@ add_partial_subprogram (struct partial_die_info *pdi, pdi->highpc - 1 + baseaddr, cu->per_cu->v.psymtab); } + } + + if (pdi->has_pc_info || (!pdi->is_external && pdi->may_be_inlined)) + { if (!pdi->is_declaration) /* Ignore subprogram DIEs that do not have a name, they are illegal. Do not emit a complaint at this point, we will @@ -4243,6 +4959,16 @@ add_partial_enumeration (struct partial_die_info *enum_pdi, } } +/* Return the initial uleb128 in the die at INFO_PTR. */ + +static unsigned int +peek_abbrev_code (bfd *abfd, gdb_byte *info_ptr) +{ + unsigned int bytes_read; + + return read_unsigned_leb128 (abfd, info_ptr, &bytes_read); +} + /* Read the initial uleb128 in the die at INFO_PTR in compilation unit CU. Return the corresponding abbrev, or NULL if the number is zero (indicating an empty DIE). In either case *BYTES_READ will be set to the length of @@ -4276,8 +5002,9 @@ peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read, DIE. Any children of the skipped DIEs will also be skipped. */ static gdb_byte * -skip_children (gdb_byte *buffer, gdb_byte *info_ptr, struct dwarf2_cu *cu) +skip_children (const struct die_reader_specs *reader, gdb_byte *info_ptr) { + struct dwarf2_cu *cu = reader->cu; struct abbrev_info *abbrev; unsigned int bytes_read; @@ -4287,7 +5014,7 @@ skip_children (gdb_byte *buffer, gdb_byte *info_ptr, struct dwarf2_cu *cu) if (abbrev == NULL) return info_ptr + bytes_read; else - info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu); + info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev); } } @@ -4298,12 +5025,14 @@ skip_children (gdb_byte *buffer, gdb_byte *info_ptr, struct dwarf2_cu *cu) children. */ static gdb_byte * -skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr, - struct abbrev_info *abbrev, struct dwarf2_cu *cu) +skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr, + struct abbrev_info *abbrev) { unsigned int bytes_read; struct attribute attr; - bfd *abfd = cu->objfile->obfd; + bfd *abfd = reader->abfd; + struct dwarf2_cu *cu = reader->cu; + gdb_byte *buffer = reader->buffer; unsigned int form, i; for (i = 0; i < abbrev->num_attrs; i++) @@ -4311,13 +5040,12 @@ skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr, /* The only abbrev we care about is DW_AT_sibling. */ if (abbrev->attrs[i].name == DW_AT_sibling) { - read_attribute (&attr, &abbrev->attrs[i], - abfd, info_ptr, cu); + read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr); if (attr.form == DW_FORM_ref_addr) complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling")); else - return buffer + dwarf2_get_ref_die_offset (&attr); + return buffer + dwarf2_get_ref_die_offset (&attr).sect_off; } /* If it isn't DW_AT_sibling, skip this attribute. */ @@ -4381,6 +5109,8 @@ skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr, case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_ref_udata: + case DW_FORM_GNU_addr_index: + case DW_FORM_GNU_str_index: info_ptr = skip_leb128 (abfd, info_ptr); break; case DW_FORM_indirect: @@ -4399,19 +5129,18 @@ skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr, } if (abbrev->has_children) - return skip_children (buffer, info_ptr, cu); + return skip_children (reader, info_ptr); else return info_ptr; } /* Locate ORIG_PDI's sibling. - INFO_PTR should point to the start of the next DIE after ORIG_PDI - in BUFFER. */ + INFO_PTR should point to the start of the next DIE after ORIG_PDI. */ static gdb_byte * -locate_pdi_sibling (struct partial_die_info *orig_pdi, - gdb_byte *buffer, gdb_byte *info_ptr, - bfd *abfd, struct dwarf2_cu *cu) +locate_pdi_sibling (const struct die_reader_specs *reader, + struct partial_die_info *orig_pdi, + gdb_byte *info_ptr) { /* Do we know the sibling already? */ @@ -4425,7 +5154,7 @@ locate_pdi_sibling (struct partial_die_info *orig_pdi, /* Skip the children the long way. */ - return skip_children (buffer, info_ptr, cu); + return skip_children (reader, info_ptr); } /* Expand this partial symbol table into a full symbol table. */ @@ -4476,18 +5205,24 @@ dwarf2_psymtab_to_symtab (struct partial_symtab *pst) printf_filtered (_("done.\n")); } } + + process_cu_includes (); } + +/* Reading in full CUs. */ /* Add PER_CU to the queue. */ static void -queue_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile) +queue_comp_unit (struct dwarf2_per_cu_data *per_cu, + enum language pretend_language) { struct dwarf2_queue_item *item; per_cu->queued = 1; item = xmalloc (sizeof (*item)); item->per_cu = per_cu; + item->pretend_language = pretend_language; item->next = NULL; if (dwarf2_queue == NULL) @@ -4501,7 +5236,7 @@ queue_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile) /* Process the queue. */ static void -process_queue (struct objfile *objfile) +process_queue (void) { struct dwarf2_queue_item *item, *next_item; @@ -4512,7 +5247,7 @@ process_queue (struct objfile *objfile) if (dwarf2_per_objfile->using_index ? !item->per_cu->v.quick->symtab : (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin)) - process_full_comp_unit (item->per_cu); + process_full_comp_unit (item->per_cu, item->pretend_language); item->per_cu->queued = 0; next_item = item->next; @@ -4539,7 +5274,7 @@ dwarf2_release_queue (void *dummy) if (item->per_cu->queued) { if (item->per_cu->cu != NULL) - free_one_cached_comp_unit (item->per_cu->cu); + free_one_cached_comp_unit (item->per_cu); item->per_cu->queued = 0; } @@ -4560,8 +5295,12 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) struct cleanup *back_to; int i; + if (pst->readin) + return; + for (i = 0; i < pst->number_of_dependencies; i++) - if (!pst->dependencies[i]->readin) + if (!pst->dependencies[i]->readin + && pst->dependencies[i]->user == NULL) { /* Inform about additional files that need to be read in. */ if (info_verbose) @@ -4588,89 +5327,82 @@ psymtab_to_symtab_1 (struct partial_symtab *pst) return; } - dw2_do_instantiate_symtab (pst->objfile, per_cu); + dw2_do_instantiate_symtab (per_cu); } -/* Load the DIEs associated with PER_CU into memory. */ +/* Trivial hash function for die_info: the hash value of a DIE + is its offset in .debug_info for this objfile. */ -static void -load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, - struct objfile *objfile) +static hashval_t +die_hash (const void *item) { - bfd *abfd = objfile->obfd; - struct dwarf2_cu *cu; - unsigned int offset; - gdb_byte *info_ptr, *beg_of_comp_unit; - struct cleanup *free_abbrevs_cleanup = NULL, *free_cu_cleanup = NULL; - struct attribute *attr; - int read_cu = 0; - - gdb_assert (! per_cu->debug_type_section); - - /* Set local variables from the partial symbol table info. */ - offset = per_cu->offset; - - dwarf2_read_section (objfile, &dwarf2_per_objfile->info); - info_ptr = dwarf2_per_objfile->info.buffer + offset; - beg_of_comp_unit = info_ptr; - - if (per_cu->cu == NULL) - { - cu = xmalloc (sizeof (*cu)); - init_one_comp_unit (cu, objfile); + const struct die_info *die = item; - read_cu = 1; + return die->offset.sect_off; +} - /* If an error occurs while loading, release our storage. */ - free_cu_cleanup = make_cleanup (free_one_comp_unit, cu); +/* Trivial comparison function for die_info structures: two DIEs + are equal if they have the same offset. */ - /* Read in the comp_unit header. */ - info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd); +static int +die_eq (const void *item_lhs, const void *item_rhs) +{ + const struct die_info *die_lhs = item_lhs; + const struct die_info *die_rhs = item_rhs; - /* Complete the cu_header. */ - cu->header.offset = offset; - cu->header.first_die_offset = info_ptr - beg_of_comp_unit; + return die_lhs->offset.sect_off == die_rhs->offset.sect_off; +} - /* Read the abbrevs for this compilation unit. */ - dwarf2_read_abbrevs (abfd, cu); - free_abbrevs_cleanup = make_cleanup (dwarf2_free_abbrev_table, cu); +/* die_reader_func for load_full_comp_unit. + This is identical to read_signatured_type_reader, + but is kept separate for now. */ - /* Link this compilation unit into the compilation unit tree. */ - per_cu->cu = cu; - cu->per_cu = per_cu; +static void +load_full_comp_unit_reader (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct die_info *comp_unit_die, + int has_children, + void *data) +{ + struct dwarf2_cu *cu = reader->cu; + struct attribute *attr; + enum language *language_ptr = data; - /* 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; - } - else - { - cu = per_cu->cu; - info_ptr += cu->header.first_die_offset; - } + gdb_assert (cu->die_hash == NULL); + 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); - cu->dies = read_comp_unit (info_ptr, cu); + if (has_children) + comp_unit_die->child = read_die_and_siblings (reader, info_ptr, + &info_ptr, comp_unit_die); + cu->dies = comp_unit_die; + /* comp_unit_die is not stored in die_hash, no need. */ /* We try not to read any attributes in this function, because not - all objfiles needed for references have been loaded yet, and symbol + all CUs 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. */ - prepare_one_comp_unit (cu, cu->dies); - - /* Similarly, if we do not read the producer, we can not apply + or we won't be able to build types correctly. + Similarly, if we do not read the producer, we can not apply producer-specific interpretation. */ - attr = dwarf2_attr (cu->dies, DW_AT_producer, cu); - if (attr) - cu->producer = DW_STRING (attr); + prepare_one_comp_unit (cu, cu->dies, *language_ptr); +} - if (read_cu) - { - do_cleanups (free_abbrevs_cleanup); +/* Load the DIEs associated with PER_CU into memory. */ - /* We've successfully allocated this compilation unit. Let our - caller clean it up when finished with it. */ - discard_cleanups (free_cu_cleanup); - } +static void +load_full_comp_unit (struct dwarf2_per_cu_data *this_cu, + enum language pretend_language) +{ + gdb_assert (! this_cu->is_debug_types); + + init_cutu_and_read_dies (this_cu, 1, 1, load_full_comp_unit_reader, + &pretend_language); } /* Add a DIE to the delayed physname list. */ @@ -4723,55 +5455,189 @@ compute_delayed_physnames (struct dwarf2_cu *cu) } } -/* Check for GCC >= 4.x. Return minor version (x) of 4.x in such case. If it - is not GCC or it is GCC older than 4.x return -1. If it is GCC 5.x or - higher return INT_MAX. */ +/* Go objects should be embedded in a DW_TAG_module DIE, + and it's not clear if/how imported objects will appear. + To keep Go support simple until that's worked out, + go back through what we've read and create something usable. + We could do this while processing each DIE, and feels kinda cleaner, + but that way is more invasive. + This is to, for example, allow the user to type "p var" or "b main" + without having to specify the package name, and allow lookups + of module.object to work in contexts that use the expression + parser. */ -static int -producer_is_gcc_ge_4 (struct dwarf2_cu *cu) +static void +fixup_go_packaging (struct dwarf2_cu *cu) { - const char *cs; - int major, minor; + char *package_name = NULL; + struct pending *list; + int i; - if (cu->producer == NULL) + for (list = global_symbols; list != NULL; list = list->next) { - /* For unknown compilers expect their behavior is not compliant. For GCC - this case can also happen for -gdwarf-4 type units supported since - gcc-4.5. */ + for (i = 0; i < list->nsyms; ++i) + { + struct symbol *sym = list->symbol[i]; - return -1; - } + if (SYMBOL_LANGUAGE (sym) == language_go + && SYMBOL_CLASS (sym) == LOC_BLOCK) + { + char *this_package_name = go_symbol_package_name (sym); - /* Skip any identifier after "GNU " - such as "C++" or "Java". */ + if (this_package_name == NULL) + continue; + if (package_name == NULL) + package_name = this_package_name; + else + { + if (strcmp (package_name, this_package_name) != 0) + complaint (&symfile_complaints, + _("Symtab %s has objects from two different Go packages: %s and %s"), + (sym->symtab && sym->symtab->filename + ? sym->symtab->filename + : cu->objfile->name), + this_package_name, package_name); + xfree (this_package_name); + } + } + } + } - if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0) + if (package_name != NULL) { - /* For non-GCC compilers expect their behavior is not compliant. */ + struct objfile *objfile = cu->objfile; + struct type *type = init_type (TYPE_CODE_MODULE, 0, 0, + package_name, objfile); + struct symbol *sym; + + TYPE_TAG_NAME (type) = TYPE_NAME (type); + + sym = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol); + SYMBOL_SET_LANGUAGE (sym, language_go); + SYMBOL_SET_NAMES (sym, package_name, strlen (package_name), 1, objfile); + /* This is not VAR_DOMAIN because we want a way to ensure a lookup of, + e.g., "main" finds the "main" module and not C's main(). */ + SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN; + SYMBOL_CLASS (sym) = LOC_TYPEDEF; + SYMBOL_TYPE (sym) = type; + + add_symbol_to_list (sym, &global_symbols); + + xfree (package_name); + } +} + +static void compute_symtab_includes (struct dwarf2_per_cu_data *per_cu); - return -1; +/* Return the symtab for PER_CU. This works properly regardless of + whether we're using the index or psymtabs. */ + +static struct symtab * +get_symtab (struct dwarf2_per_cu_data *per_cu) +{ + return (dwarf2_per_objfile->using_index + ? per_cu->v.quick->symtab + : per_cu->v.psymtab->symtab); +} + +/* A helper function for computing the list of all symbol tables + included by PER_CU. */ + +static void +recursively_compute_inclusions (VEC (dwarf2_per_cu_ptr) **result, + htab_t all_children, + struct dwarf2_per_cu_data *per_cu) +{ + void **slot; + int ix; + struct dwarf2_per_cu_data *iter; + + slot = htab_find_slot (all_children, per_cu, INSERT); + if (*slot != NULL) + { + /* This inclusion and its children have been processed. */ + return; } - cs = &cu->producer[strlen ("GNU ")]; - while (*cs && !isdigit (*cs)) - cs++; - if (sscanf (cs, "%d.%d", &major, &minor) != 2) + + *slot = per_cu; + /* Only add a CU if it has a symbol table. */ + if (get_symtab (per_cu) != NULL) + VEC_safe_push (dwarf2_per_cu_ptr, *result, per_cu); + + for (ix = 0; + VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs, ix, iter); + ++ix) + recursively_compute_inclusions (result, all_children, iter); +} + +/* Compute the symtab 'includes' fields for the symtab related to + PER_CU. */ + +static void +compute_symtab_includes (struct dwarf2_per_cu_data *per_cu) +{ + if (!VEC_empty (dwarf2_per_cu_ptr, per_cu->imported_symtabs)) { - /* Not recognized as GCC. */ + int ix, len; + struct dwarf2_per_cu_data *iter; + VEC (dwarf2_per_cu_ptr) *result_children = NULL; + htab_t all_children; + struct symtab *symtab = get_symtab (per_cu); + + /* If we don't have a symtab, we can just skip this case. */ + if (symtab == NULL) + return; + + all_children = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer, + NULL, xcalloc, xfree); + + for (ix = 0; + VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs, + ix, iter); + ++ix) + recursively_compute_inclusions (&result_children, all_children, iter); + + /* Now we have a transitive closure of all the included CUs, so + we can convert it to a list of symtabs. */ + len = VEC_length (dwarf2_per_cu_ptr, result_children); + symtab->includes + = obstack_alloc (&dwarf2_per_objfile->objfile->objfile_obstack, + (len + 1) * sizeof (struct symtab *)); + for (ix = 0; + VEC_iterate (dwarf2_per_cu_ptr, result_children, ix, iter); + ++ix) + symtab->includes[ix] = get_symtab (iter); + symtab->includes[len] = NULL; - return -1; + VEC_free (dwarf2_per_cu_ptr, result_children); + htab_delete (all_children); } +} + +/* Compute the 'includes' field for the symtabs of all the CUs we just + read. */ + +static void +process_cu_includes (void) +{ + int ix; + struct dwarf2_per_cu_data *iter; + + for (ix = 0; + VEC_iterate (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus, + ix, iter); + ++ix) + compute_symtab_includes (iter); - if (major < 4) - return -1; - if (major > 4) - return INT_MAX; - return minor; + VEC_free (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus); } -/* Generate full symbol information for PST and CU, whose DIEs have +/* Generate full symbol information for PER_CU, whose DIEs have already been loaded into memory. */ static void -process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) +process_full_comp_unit (struct dwarf2_per_cu_data *per_cu, + enum language pretend_language) { struct dwarf2_cu *cu = per_cu->cu; struct objfile *objfile = per_cu->objfile; @@ -4788,9 +5654,16 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) cu->list_in_scope = &file_symbols; + cu->language = pretend_language; + cu->language_defn = language_def (cu->language); + /* Do line number decoding in read_file_scope () */ process_die (cu->dies, cu); + /* For now fudge the Go package. */ + if (cu->language == language_go) + fixup_go_packaging (cu); + /* Now that we have processed all the DIEs in the CU, all the types should be complete, and it should now be safe to compute all of the physnames. */ @@ -4806,7 +5679,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) if (symtab != NULL) { - int gcc_4_minor = producer_is_gcc_ge_4 (cu); + int gcc_4_minor = producer_is_gcc_ge_4 (cu->producer); /* Set symtab language to language from DW_AT_language. If the compilation is from a C file generated by language preprocessors, do @@ -4816,7 +5689,9 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) /* GCC-4.0 has started to support -fvar-tracking. GCC-3.x still can produce DW_AT_location with location lists but it can be possibly - invalid without -fvar-tracking. + invalid without -fvar-tracking. Still up to GCC-4.4.x incl. 4.4.0 + there were bugs in prologue debug info, fixed later in GCC-4.5 + by "unwind info for epilogues" patch (which is not directly related). For -gdwarf-4 type units LOCATIONS_VALID indication is fortunately not needed, it would be wrong due to missing DW_AT_producer there. @@ -4824,14 +5699,13 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) Still one can confuse GDB by using non-standard GCC compilation options - this waits on GCC PR other/32998 (-frecord-gcc-switches). */ - if (cu->has_loclist && gcc_4_minor >= 0) + if (cu->has_loclist && gcc_4_minor >= 5) symtab->locations_valid = 1; if (gcc_4_minor >= 5) symtab->epilogue_unwind_valid = 1; - if (gcc_4_minor >= 6) - symtab->amd64_prologue_line_bug = 1; + symtab->call_site_htab = cu->call_site_htab; } if (dwarf2_per_objfile->using_index) @@ -4843,9 +5717,38 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) pst->readin = 1; } + /* Push it for inclusion processing later. */ + VEC_safe_push (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus, per_cu); + do_cleanups (back_to); } +/* Process an imported unit DIE. */ + +static void +process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu) +{ + struct attribute *attr; + + attr = dwarf2_attr (die, DW_AT_import, cu); + if (attr != NULL) + { + struct dwarf2_per_cu_data *per_cu; + struct symtab *imported_symtab; + sect_offset offset; + + offset = dwarf2_get_ref_die_offset (attr); + per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile); + + /* Queue the unit, if needed. */ + if (maybe_queue_comp_unit (cu, per_cu, cu->language)) + load_full_comp_unit (per_cu, cu->language); + + VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs, + per_cu); + } +} + /* Process a die and its children. */ static void @@ -4856,6 +5759,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_padding: break; case DW_TAG_compile_unit: + case DW_TAG_partial_unit: read_file_scope (die, cu); break; case DW_TAG_type_unit: @@ -4870,6 +5774,9 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_catch_block: read_lexical_block_scope (die, cu); break; + case DW_TAG_GNU_call_site: + read_call_site_scope (die, cu); + break; case DW_TAG_class_type: case DW_TAG_interface_type: case DW_TAG_structure_type: @@ -4921,6 +5828,11 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) dwarf_tag_name (die->tag)); read_import_statement (die, cu); break; + + case DW_TAG_imported_unit: + process_imported_unit_die (die, cu); + break; + default: new_symbol (die, NULL, cu); break; @@ -4996,8 +5908,14 @@ do_ui_file_peek_last (void *object, const char *buffer, long length) } /* Compute the fully qualified name of DIE in CU. If PHYSNAME is nonzero, - compute the physname for the object, which include a method's - formal parameters (C++/Java) and return type (Java). + compute the physname for the object, which include a method's: + - formal parameters (C++/Java), + - receiver type (Go), + - return type (Java). + + The term "physname" is a bit confusing. + For C++, for example, it is the demangled name. + For Go, for example, it's the mangled name. For Ada, return the DIE's linkage name rather than the fully qualified name. PHYSNAME is ignored.. @@ -5008,7 +5926,9 @@ static const char * dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, int physname) { - if (name == NULL) + struct objfile *objfile = cu->objfile; + + if (name == NULL) name = dwarf2_name (die, cu); /* For Fortran GDB prefers DW_AT_*linkage_name if present but otherwise @@ -5038,7 +5958,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, if (die_needs_namespace (die, cu)) { long length; - char *prefix; + const char *prefix; struct ui_file *buf; prefix = determine_prefix (die, cu); @@ -5086,7 +6006,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, for (child = die->child; child != NULL; child = child->sibling) { struct type *type; - long value; + LONGEST value; gdb_byte *bytes; struct dwarf2_locexpr_baton *baton; struct value *v; @@ -5215,7 +6135,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, } } - name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, + name = ui_file_obsavestring (buf, &objfile->objfile_obstack, &length); ui_file_delete (buf); @@ -5223,7 +6143,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, { char *cname = dwarf2_canonicalize_name (name, cu, - &cu->objfile->objfile_obstack); + &objfile->objfile_obstack); if (cname != NULL) name = cname; @@ -5258,6 +6178,7 @@ dwarf2_full_name (char *name, struct die_info *die, struct dwarf2_cu *cu) static const char * dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct attribute *attr; const char *retval, *mangled = NULL, *canon = NULL; struct cleanup *back_to; @@ -5291,10 +6212,21 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu) variant `long name(params)' does not have the proper inferior type. */ - demangled = cplus_demangle (mangled, (DMGL_PARAMS | DMGL_ANSI - | (cu->language == language_java - ? DMGL_JAVA | DMGL_RET_POSTFIX - : DMGL_RET_DROP))); + if (cu->language == language_go) + { + /* This is a lie, but we already lie to the caller new_symbol_full. + new_symbol_full assumes we return the mangled name. + This just undoes that lie until things are cleaned up. */ + demangled = NULL; + } + else + { + demangled = cplus_demangle (mangled, + (DMGL_PARAMS | DMGL_ANSI + | (cu->language == language_java + ? DMGL_JAVA | DMGL_RET_POSTFIX + : DMGL_RET_DROP))); + } if (demangled) { make_cleanup (xfree, demangled); @@ -5320,7 +6252,7 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("Computed physname <%s> does not match demangled <%s> " "(from linkage <%s>) - DIE at 0x%x [in module %s]"), - physname, canon, mangled, die->offset, cu->objfile->name); + physname, canon, mangled, die->offset.sect_off, objfile->name); /* Prefer DW_AT_linkage_name (in the CANON form) - when it is available here - over computed PHYSNAME. It is safer @@ -5339,7 +6271,7 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu) if (need_copy) retval = obsavestring (retval, strlen (retval), - &cu->objfile->objfile_obstack); + &objfile->objfile_obstack); do_cleanups (back_to); return retval; @@ -5350,6 +6282,7 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu) static void read_import_statement (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct attribute *import_attr; struct die_info *imported_die, *child_die; struct dwarf2_cu *imported_cu; @@ -5456,7 +6389,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("child DW_TAG_imported_declaration expected " "- DIE at 0x%x [in module %s]"), - child_die->offset, cu->objfile->name); + child_die->offset.sect_off, objfile->name); continue; } @@ -5477,7 +6410,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("child DW_TAG_imported_declaration has unknown " "imported name - DIE at 0x%x [in module %s]"), - child_die->offset, cu->objfile->name); + child_die->offset.sect_off, objfile->name); continue; } @@ -5491,17 +6424,11 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu) import_alias, imported_declaration, excludes, - &cu->objfile->objfile_obstack); + &objfile->objfile_obstack); do_cleanups (cleanups); } -static void -initialize_cu_func_list (struct dwarf2_cu *cu) -{ - cu->first_fn = cu->last_fn = cu->cached_fn = NULL; -} - /* Cleanup function for read_file_scope. */ static void @@ -5553,41 +6480,39 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu, *name = ""; } -/* Handle DW_AT_stmt_list for a compilation unit. */ +/* Handle DW_AT_stmt_list for a compilation unit or type unit. + DIE is the DW_TAG_compile_unit or DW_TAG_type_unit die for CU. + COMP_DIR is the compilation directory. + WANT_LINE_INFO is non-zero if the pc/line-number mapping is needed. */ static void handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, - const char *comp_dir) + const char *comp_dir, int want_line_info) { struct attribute *attr; - struct objfile *objfile = cu->objfile; - bfd *abfd = objfile->obfd; - /* Decode line number information if present. We do this before - processing child DIEs, so that the line header table is available - for DW_AT_decl_file. */ attr = dwarf2_attr (die, DW_AT_stmt_list, cu); if (attr) { unsigned int line_offset = DW_UNSND (attr); struct line_header *line_header - = dwarf_decode_line_header (line_offset, abfd, cu); + = dwarf_decode_line_header (line_offset, cu); if (line_header) - { - cu->line_header = line_header; - make_cleanup (free_cu_line_header, cu); - dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL); - } + { + cu->line_header = line_header; + make_cleanup (free_cu_line_header, cu); + dwarf_decode_lines (line_header, comp_dir, cu, NULL, want_line_info); + } } } -/* Process DW_TAG_compile_unit. */ +/* Process DW_TAG_compile_unit or DW_TAG_partial_unit. */ static void read_file_scope (struct die_info *die, struct dwarf2_cu *cu) { - struct objfile *objfile = cu->objfile; + struct objfile *objfile = dwarf2_per_objfile->objfile; struct cleanup *back_to = make_cleanup (null_cleanup, 0); CORE_ADDR lowpc = ((CORE_ADDR) -1); CORE_ADDR highpc = ((CORE_ADDR) 0); @@ -5611,15 +6536,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) find_file_and_directory (die, cu, &name, &comp_dir); - attr = dwarf2_attr (die, DW_AT_language, cu); - if (attr) - { - set_cu_language (DW_UNSND (attr), cu); - } - - attr = dwarf2_attr (die, DW_AT_producer, cu); - if (attr) - cu->producer = DW_STRING (attr); + prepare_one_comp_unit (cu, die, cu->language); /* The XLCL doesn't generate DW_LANG_OpenCL because this attribute is not standardised yet. As a workaround for the language detection we fall @@ -5627,6 +6544,10 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) if (cu->producer && strstr (cu->producer, "IBM XL C for OpenCL") != NULL) cu->language = language_opencl; + /* Similar hack for Go. */ + if (cu->producer && strstr (cu->producer, "GNU Go ") != NULL) + set_cu_language (DW_LANG_Go, cu); + /* We assume that we're processing GCC output. */ processing_gcc_compilation = 2; @@ -5636,9 +6557,10 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) record_debugformat ("DWARF 2"); record_producer (cu->producer); - initialize_cu_func_list (cu); - - handle_DW_AT_stmt_list (die, cu, comp_dir); + /* Decode line number information if present. We do this before + processing child DIEs, so that the line header table is available + for DW_AT_decl_file. */ + handle_DW_AT_stmt_list (die, cu, comp_dir, 1); /* Process all dies in compilation unit. */ if (die->child != NULL) @@ -5664,7 +6586,8 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) dwarf_decode_macros (cu->line_header, DW_UNSND (attr), comp_dir, abfd, cu, - &dwarf2_per_objfile->macro, 1); + &dwarf2_per_objfile->macro, 1, + ".debug_macro"); } else { @@ -5675,9 +6598,11 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) dwarf_decode_macros (cu->line_header, macro_offset, comp_dir, abfd, cu, - &dwarf2_per_objfile->macinfo, 0); + &dwarf2_per_objfile->macinfo, 0, + ".debug_macinfo"); } } + do_cleanups (back_to); } @@ -5721,15 +6646,7 @@ read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu) 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); + prepare_one_comp_unit (cu, die, language_minimal); /* We assume that we're processing GCC output. */ processing_gcc_compilation = 2; @@ -5740,7 +6657,11 @@ read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu) record_debugformat ("DWARF 2"); record_producer (cu->producer); - handle_DW_AT_stmt_list (die, cu, comp_dir); + /* Decode line number information if present. We do this before + processing child DIEs, so that the line header table is available + for DW_AT_decl_file. + We don't need the pc/line-number mapping for type units. */ + handle_DW_AT_stmt_list (die, cu, comp_dir, 0); /* Process the dies in the type unit. */ if (die->child == NULL) @@ -5761,29 +6682,537 @@ read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu) do_cleanups (back_to); } + +/* DWO files. */ + +static hashval_t +hash_dwo_file (const void *item) +{ + const struct dwo_file *dwo_file = item; + + return htab_hash_string (dwo_file->dwo_name); +} + +static int +eq_dwo_file (const void *item_lhs, const void *item_rhs) +{ + const struct dwo_file *lhs = item_lhs; + const struct dwo_file *rhs = item_rhs; + + return strcmp (lhs->dwo_name, rhs->dwo_name) == 0; +} + +/* Allocate a hash table for DWO files. */ + +static htab_t +allocate_dwo_file_hash_table (void) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + + return htab_create_alloc_ex (41, + hash_dwo_file, + eq_dwo_file, + NULL, + &objfile->objfile_obstack, + hashtab_obstack_allocate, + dummy_obstack_deallocate); +} + +static hashval_t +hash_dwo_unit (const void *item) +{ + const struct dwo_unit *dwo_unit = item; + + /* This drops the top 32 bits of the id, but is ok for a hash. */ + return dwo_unit->signature; +} + +static int +eq_dwo_unit (const void *item_lhs, const void *item_rhs) +{ + const struct dwo_unit *lhs = item_lhs; + const struct dwo_unit *rhs = item_rhs; + + /* The signature is assumed to be unique within the DWO file. + So while object file CU dwo_id's always have the value zero, + that's OK, assuming each object file DWO file has only one CU, + and that's the rule for now. */ + return lhs->signature == rhs->signature; +} + +/* Allocate a hash table for DWO CUs,TUs. + There is one of these tables for each of CUs,TUs for each DWO file. */ + +static htab_t +allocate_dwo_unit_table (struct objfile *objfile) +{ + /* Start out with a pretty small number. + Generally DWO files contain only one CU and maybe some TUs. */ + return htab_create_alloc_ex (3, + hash_dwo_unit, + eq_dwo_unit, + NULL, + &objfile->objfile_obstack, + hashtab_obstack_allocate, + dummy_obstack_deallocate); +} + +/* This function is mapped across the sections and remembers the offset and + size of each of the DWO debugging sections we are interested in. */ static void -add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc, - struct dwarf2_cu *cu) +dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp, void *dwo_file_ptr) +{ + struct dwo_file *dwo_file = dwo_file_ptr; + const struct dwo_section_names *names = &dwo_section_names; + + if (section_is_p (sectp->name, &names->abbrev_dwo)) + { + dwo_file->sections.abbrev.asection = sectp; + dwo_file->sections.abbrev.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->info_dwo)) + { + dwo_file->sections.info.asection = sectp; + dwo_file->sections.info.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->line_dwo)) + { + dwo_file->sections.line.asection = sectp; + dwo_file->sections.line.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->loc_dwo)) + { + dwo_file->sections.loc.asection = sectp; + dwo_file->sections.loc.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->str_dwo)) + { + dwo_file->sections.str.asection = sectp; + dwo_file->sections.str.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->str_offsets_dwo)) + { + dwo_file->sections.str_offsets.asection = sectp; + dwo_file->sections.str_offsets.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->types_dwo)) + { + struct dwarf2_section_info type_section; + + memset (&type_section, 0, sizeof (type_section)); + type_section.asection = sectp; + type_section.size = bfd_get_section_size (sectp); + VEC_safe_push (dwarf2_section_info_def, dwo_file->sections.types, + &type_section); + } +} + +/* Structure used to pass data to create_debug_info_hash_table_reader. */ + +struct create_dwo_info_table_data +{ + struct dwo_file *dwo_file; + htab_t cu_htab; +}; + +/* die_reader_func for create_debug_info_hash_table. */ + +static void +create_debug_info_hash_table_reader (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct die_info *comp_unit_die, + int has_children, + void *datap) { - struct function_range *thisfn; + struct dwarf2_cu *cu = reader->cu; + struct objfile *objfile = dwarf2_per_objfile->objfile; + sect_offset offset = cu->per_cu->offset; + struct dwarf2_section_info *section = cu->per_cu->info_or_types_section; + struct create_dwo_info_table_data *data = datap; + struct dwo_file *dwo_file = data->dwo_file; + htab_t cu_htab = data->cu_htab; + void **slot; + struct attribute *attr; + struct dwo_unit *dwo_unit; - thisfn = (struct function_range *) - obstack_alloc (&cu->comp_unit_obstack, sizeof (struct function_range)); - thisfn->name = name; - thisfn->lowpc = lowpc; - thisfn->highpc = highpc; - thisfn->seen_line = 0; - thisfn->next = NULL; + attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu); + if (attr == NULL) + { + error (_("Dwarf Error: debug entry at offset 0x%x is missing" + " its dwo_id [in module %s]"), + offset.sect_off, dwo_file->dwo_name); + return; + } + + dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit); + dwo_unit->dwo_file = dwo_file; + dwo_unit->signature = DW_UNSND (attr); + dwo_unit->info_or_types_section = section; + dwo_unit->offset = offset; + dwo_unit->length = cu->per_cu->length; + + slot = htab_find_slot (cu_htab, dwo_unit, INSERT); + gdb_assert (slot != NULL); + if (*slot != NULL) + { + const struct dwo_unit *dup_dwo_unit = *slot; - if (cu->last_fn == NULL) - cu->first_fn = thisfn; + complaint (&symfile_complaints, + _("debug entry at offset 0x%x is duplicate to the entry at" + " offset 0x%x, dwo_id 0x%s [in module %s]"), + offset.sect_off, dup_dwo_unit->offset.sect_off, + phex (dwo_unit->signature, sizeof (dwo_unit->signature)), + dwo_file->dwo_name); + } else - cu->last_fn->next = thisfn; + *slot = dwo_unit; + + if (dwarf2_die_debug) + fprintf_unfiltered (gdb_stdlog, " offset 0x%x, dwo_id 0x%s\n", + offset.sect_off, + phex (dwo_unit->signature, + sizeof (dwo_unit->signature))); +} + +/* Create a hash table to map DWO IDs to their CU entry in .debug_info.dwo. */ + +static htab_t +create_debug_info_hash_table (struct dwo_file *dwo_file) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwarf2_section_info *section = &dwo_file->sections.info; + bfd *abfd; + htab_t cu_htab; + gdb_byte *info_ptr, *end_ptr; + struct create_dwo_info_table_data create_dwo_info_table_data; + + dwarf2_read_section (objfile, section); + info_ptr = section->buffer; + + if (info_ptr == NULL) + return NULL; + + /* We can't set abfd until now because the section may be empty or + not present, in which case section->asection will be NULL. */ + abfd = section->asection->owner; + + if (dwarf2_die_debug) + fprintf_unfiltered (gdb_stdlog, "Reading .debug_info.dwo for %s:\n", + bfd_get_filename (abfd)); - cu->last_fn = thisfn; + cu_htab = allocate_dwo_unit_table (objfile); + + create_dwo_info_table_data.dwo_file = dwo_file; + create_dwo_info_table_data.cu_htab = cu_htab; + + end_ptr = info_ptr + section->size; + while (info_ptr < end_ptr) + { + struct dwarf2_per_cu_data per_cu; + + memset (&per_cu, 0, sizeof (per_cu)); + per_cu.objfile = objfile; + per_cu.is_debug_types = 0; + per_cu.offset.sect_off = info_ptr - section->buffer; + per_cu.info_or_types_section = section; + + init_cutu_and_read_dies_no_follow (&per_cu, + &dwo_file->sections.abbrev, + dwo_file, + create_debug_info_hash_table_reader, + &create_dwo_info_table_data); + + info_ptr += per_cu.length; + } + + return cu_htab; +} + +/* Subroutine of open_dwo_file to simplify it. + Open the file specified by FILE_NAME and hand it off to BFD for + preliminary analysis. Return a newly initialized bfd *, which + includes a canonicalized copy of FILE_NAME. + In case of trouble, return NULL. + NOTE: This function is derived from symfile_bfd_open. */ + +static bfd * +try_open_dwo_file (const char *file_name) +{ + bfd *sym_bfd; + int desc; + char *absolute_name; + char *name; + + desc = openp (debug_file_directory, OPF_TRY_CWD_FIRST, file_name, + O_RDONLY | O_BINARY, &absolute_name); + if (desc < 0) + return NULL; + + sym_bfd = bfd_fopen (absolute_name, gnutarget, FOPEN_RB, desc); + if (!sym_bfd) + { + close (desc); + xfree (absolute_name); + return NULL; + } + bfd_set_cacheable (sym_bfd, 1); + + if (!bfd_check_format (sym_bfd, bfd_object)) + { + bfd_close (sym_bfd); /* This also closes desc. */ + xfree (absolute_name); + return NULL; + } + + /* bfd_usrdata exists for applications and libbfd must not touch it. */ + gdb_assert (bfd_usrdata (sym_bfd) == NULL); + + return sym_bfd; +} + +/* Try to open DWO file DWO_NAME. + COMP_DIR is the DW_AT_comp_dir attribute. + The result is the bfd handle of the file. + If there is a problem finding or opening the file, return NULL. + Upon success, the canonicalized path of the file is stored in the bfd, + same as symfile_bfd_open. */ + +static bfd * +open_dwo_file (const char *dwo_name, const char *comp_dir) +{ + bfd *abfd; + char *path_to_try, *debug_dir; + + if (IS_ABSOLUTE_PATH (dwo_name)) + return try_open_dwo_file (dwo_name); + + /* Before trying the search path, try DWO_NAME in COMP_DIR. */ + + if (comp_dir != NULL) + { + char *path_to_try = concat (comp_dir, SLASH_STRING, dwo_name, NULL); + + /* NOTE: If comp_dir is a relative path, this will also try the + search path, which seems useful. */ + abfd = try_open_dwo_file (path_to_try); + xfree (path_to_try); + if (abfd != NULL) + return abfd; + } + + /* That didn't work, try debug-file-directory, which, despite its name, + is a list of paths. */ + + if (*debug_file_directory == '\0') + return NULL; + + return try_open_dwo_file (dwo_name); } +/* Initialize the use of the DWO file specified by DWO_NAME. */ + +static struct dwo_file * +init_dwo_file (const char *dwo_name, const char *comp_dir) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwo_file *dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct dwo_file); + bfd *abfd; + struct cleanup *cleanups; + + if (dwarf2_die_debug) + fprintf_unfiltered (gdb_stdlog, "Reading DWO file %s:\n", dwo_name); + + abfd = open_dwo_file (dwo_name, comp_dir); + if (abfd == NULL) + return NULL; + dwo_file->dwo_name = dwo_name; + dwo_file->dwo_bfd = abfd; + + cleanups = make_cleanup (free_dwo_file_cleanup, dwo_file); + + bfd_map_over_sections (abfd, dwarf2_locate_dwo_sections, dwo_file); + + dwo_file->cus = create_debug_info_hash_table (dwo_file); + + dwo_file->tus = create_debug_types_hash_table (dwo_file, + dwo_file->sections.types); + + discard_cleanups (cleanups); + + return dwo_file; +} + +/* Lookup DWO file DWO_NAME. */ + +static struct dwo_file * +lookup_dwo_file (char *dwo_name, const char *comp_dir) +{ + struct dwo_file *dwo_file; + struct dwo_file find_entry; + void **slot; + + if (dwarf2_per_objfile->dwo_files == NULL) + dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table (); + + /* Have we already seen this DWO file? */ + find_entry.dwo_name = dwo_name; + slot = htab_find_slot (dwarf2_per_objfile->dwo_files, &find_entry, INSERT); + + /* If not, read it in and build a table of the DWOs it contains. */ + if (*slot == NULL) + *slot = init_dwo_file (dwo_name, comp_dir); + + /* NOTE: This will be NULL if unable to open the file. */ + dwo_file = *slot; + + return dwo_file; +} + +/* Lookup the DWO CU referenced from THIS_CU in DWO file DWO_NAME. + If non-NULL, comp_dir is the DW_AT_comp_dir attribute. + SIGNATURE is the "dwo_id" of the CU (for consistency we use the same + nomenclature as TUs). + The result is the DWO CU or NULL if we didn't find it + (dwo_id mismatch or couldn't find the DWO file). */ + +static struct dwo_unit * +lookup_dwo_comp_unit (struct dwarf2_per_cu_data *this_cu, + char *dwo_name, const char *comp_dir, + ULONGEST signature) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwo_file *dwo_file; + + dwo_file = lookup_dwo_file (dwo_name, comp_dir); + if (dwo_file == NULL) + return NULL; + + /* Look up the DWO using its signature(dwo_id). */ + + if (dwo_file->cus != NULL) + { + struct dwo_unit find_dwo_cu, *dwo_cu; + + find_dwo_cu.signature = signature; + dwo_cu = htab_find (dwo_file->cus, &find_dwo_cu); + + if (dwo_cu != NULL) + return dwo_cu; + } + + /* We didn't find it. This must mean a dwo_id mismatch. */ + + complaint (&symfile_complaints, + _("Could not find DWO CU referenced by CU at offset 0x%x" + " [in module %s]"), + this_cu->offset.sect_off, objfile->name); + return NULL; +} + +/* Lookup the DWO TU referenced from THIS_TU in DWO file DWO_NAME. + If non-NULL, comp_dir is the DW_AT_comp_dir attribute. + The result is the DWO CU or NULL if we didn't find it + (dwo_id mismatch or couldn't find the DWO file). */ + +static struct dwo_unit * +lookup_dwo_type_unit (struct signatured_type *this_tu, + char *dwo_name, const char *comp_dir) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwo_file *dwo_file; + struct dwo_unit find_dwo_tu, *dwo_tu; + + dwo_file = lookup_dwo_file (dwo_name, comp_dir); + if (dwo_file == NULL) + return NULL; + + /* Look up the DWO using its signature(dwo_id). */ + + if (dwo_file->tus != NULL) + { + struct dwo_unit find_dwo_tu, *dwo_tu; + + find_dwo_tu.signature = this_tu->signature; + dwo_tu = htab_find (dwo_file->tus, &find_dwo_tu); + + if (dwo_tu != NULL) + return dwo_tu; + } + + /* We didn't find it. This must mean a dwo_id mismatch. */ + + complaint (&symfile_complaints, + _("Could not find DWO TU referenced by TU at offset 0x%x" + " [in module %s]"), + this_tu->per_cu.offset.sect_off, objfile->name); + return NULL; +} + +/* Free all resources associated with DWO_FILE. + Close the DWO file and munmap the sections. + All memory should be on the objfile obstack. */ + +static void +free_dwo_file (struct dwo_file *dwo_file, struct objfile *objfile) +{ + int ix; + struct dwarf2_section_info *section; + + gdb_assert (dwo_file->dwo_bfd != objfile->obfd); + bfd_close (dwo_file->dwo_bfd); + + munmap_section_buffer (&dwo_file->sections.abbrev); + munmap_section_buffer (&dwo_file->sections.info); + munmap_section_buffer (&dwo_file->sections.line); + munmap_section_buffer (&dwo_file->sections.loc); + munmap_section_buffer (&dwo_file->sections.str); + munmap_section_buffer (&dwo_file->sections.str_offsets); + + for (ix = 0; + VEC_iterate (dwarf2_section_info_def, dwo_file->sections.types, + ix, section); + ++ix) + munmap_section_buffer (section); + + VEC_free (dwarf2_section_info_def, dwo_file->sections.types); +} + +/* Wrapper for free_dwo_file for use in cleanups. */ + +static void +free_dwo_file_cleanup (void *arg) +{ + struct dwo_file *dwo_file = (struct dwo_file *) arg; + struct objfile *objfile = dwarf2_per_objfile->objfile; + + free_dwo_file (dwo_file, objfile); +} + +/* Traversal function for free_dwo_files. */ + +static int +free_dwo_file_from_slot (void **slot, void *info) +{ + struct dwo_file *dwo_file = (struct dwo_file *) *slot; + struct objfile *objfile = (struct objfile *) info; + + free_dwo_file (dwo_file, objfile); + + return 1; +} + +/* Free all resources associated with DWO_FILES. */ + +static void +free_dwo_files (htab_t dwo_files, struct objfile *objfile) +{ + htab_traverse_noresize (dwo_files, free_dwo_file_from_slot, objfile); +} + +/* Read in various DIEs. */ + /* qsort helper for inherit_abstract_dies. */ static int @@ -5806,8 +7235,8 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) struct die_info *child_die; unsigned die_children_count; /* CU offsets which were referenced by children of the current DIE. */ - unsigned *offsets; - unsigned *offsets_end, *offsetp; + sect_offset *offsets; + sect_offset *offsets_end, *offsetp; /* Parent of DIE - referenced by DW_AT_abstract_origin. */ struct die_info *origin_die; /* Iterator of the ORIGIN_DIE children. */ @@ -5837,7 +7266,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) && 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); + die->offset.sect_off, origin_die->offset.sect_off); child_die = die->child; die_children_count = 0; @@ -5880,13 +7309,13 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) && 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); + "different tags"), child_die->offset.sect_off, + child_origin_die->offset.sect_off); 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); + "different parents"), child_die->offset.sect_off, + child_origin_die->offset.sect_off); else *offsets_end++ = child_origin_die->offset; } @@ -5895,20 +7324,22 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu) qsort (offsets, offsets_end - offsets, sizeof (*offsets), unsigned_int_compar); for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++) - if (offsetp[-1] == *offsetp) + if (offsetp[-1].sect_off == offsetp->sect_off) complaint (&symfile_complaints, _("Multiple children of DIE 0x%x refer " "to DIE 0x%x as their abstract origin"), - die->offset, *offsetp); + die->offset.sect_off, offsetp->sect_off); offsetp = offsets; origin_child_die = origin_die->child; while (origin_child_die && origin_child_die->tag) { /* Is ORIGIN_CHILD_DIE referenced by any of the DIE children? */ - while (offsetp < offsets_end && *offsetp < origin_child_die->offset) + while (offsetp < offsets_end + && offsetp->sect_off < origin_child_die->offset.sect_off) offsetp++; - if (offsetp >= offsets_end || *offsetp > origin_child_die->offset) + if (offsetp >= offsets_end + || offsetp->sect_off > origin_child_die->offset.sect_off) { /* Found that ORIGIN_CHILD_DIE is really not referenced. */ process_die (origin_child_die, origin_cu); @@ -5959,7 +7390,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) if (name == NULL) { complaint (&symfile_complaints, - _("missing name for subprogram DIE at %d"), die->offset); + _("missing name for subprogram DIE at %d"), + die->offset.sect_off); return; } @@ -5971,16 +7403,13 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("cannot get low and high bounds " "for subprogram DIE at %d"), - die->offset); + die->offset.sect_off); return; } lowpc += baseaddr; highpc += baseaddr; - /* Record the function range for dwarf_decode_lines. */ - add_to_cu_func_list (name, lowpc, highpc, cu); - /* If we have any template arguments, then we must allocate a different sort of symbol. */ for (child_die = die->child; child_die; child_die = sibling_die (child_die)) @@ -6164,6 +7593,257 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu) using_directives = new->using_directives; } +/* Read in DW_TAG_GNU_call_site and insert it to CU->call_site_htab. */ + +static void +read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + struct gdbarch *gdbarch = get_objfile_arch (objfile); + CORE_ADDR pc, baseaddr; + struct attribute *attr; + struct call_site *call_site, call_site_local; + void **slot; + int nparams; + struct die_info *child_die; + + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + attr = dwarf2_attr (die, DW_AT_low_pc, cu); + if (!attr) + { + complaint (&symfile_complaints, + _("missing DW_AT_low_pc for DW_TAG_GNU_call_site " + "DIE 0x%x [in module %s]"), + die->offset.sect_off, objfile->name); + return; + } + pc = DW_ADDR (attr) + baseaddr; + + if (cu->call_site_htab == NULL) + cu->call_site_htab = htab_create_alloc_ex (16, core_addr_hash, core_addr_eq, + NULL, &objfile->objfile_obstack, + hashtab_obstack_allocate, NULL); + call_site_local.pc = pc; + slot = htab_find_slot (cu->call_site_htab, &call_site_local, INSERT); + if (*slot != NULL) + { + complaint (&symfile_complaints, + _("Duplicate PC %s for DW_TAG_GNU_call_site " + "DIE 0x%x [in module %s]"), + paddress (gdbarch, pc), die->offset.sect_off, objfile->name); + return; + } + + /* Count parameters at the caller. */ + + nparams = 0; + for (child_die = die->child; child_die && child_die->tag; + child_die = sibling_die (child_die)) + { + if (child_die->tag != DW_TAG_GNU_call_site_parameter) + { + complaint (&symfile_complaints, + _("Tag %d is not DW_TAG_GNU_call_site_parameter in " + "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"), + child_die->tag, child_die->offset.sect_off, objfile->name); + continue; + } + + nparams++; + } + + call_site = obstack_alloc (&objfile->objfile_obstack, + (sizeof (*call_site) + + (sizeof (*call_site->parameter) + * (nparams - 1)))); + *slot = call_site; + memset (call_site, 0, sizeof (*call_site) - sizeof (*call_site->parameter)); + call_site->pc = pc; + + if (dwarf2_flag_true_p (die, DW_AT_GNU_tail_call, cu)) + { + struct die_info *func_die; + + /* Skip also over DW_TAG_inlined_subroutine. */ + for (func_die = die->parent; + func_die && func_die->tag != DW_TAG_subprogram + && func_die->tag != DW_TAG_subroutine_type; + func_die = func_die->parent); + + /* DW_AT_GNU_all_call_sites is a superset + of DW_AT_GNU_all_tail_call_sites. */ + if (func_die + && !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_call_sites, cu) + && !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_tail_call_sites, cu)) + { + /* TYPE_TAIL_CALL_LIST is not interesting in functions where it is + not complete. But keep CALL_SITE for look ups via call_site_htab, + both the initial caller containing the real return address PC and + the final callee containing the current PC of a chain of tail + calls do not need to have the tail call list complete. But any + function candidate for a virtual tail call frame searched via + TYPE_TAIL_CALL_LIST must have the tail call list complete to be + determined unambiguously. */ + } + else + { + struct type *func_type = NULL; + + if (func_die) + func_type = get_die_type (func_die, cu); + if (func_type != NULL) + { + gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC); + + /* Enlist this call site to the function. */ + call_site->tail_call_next = TYPE_TAIL_CALL_LIST (func_type); + TYPE_TAIL_CALL_LIST (func_type) = call_site; + } + else + complaint (&symfile_complaints, + _("Cannot find function owning DW_TAG_GNU_call_site " + "DIE 0x%x [in module %s]"), + die->offset.sect_off, objfile->name); + } + } + + attr = dwarf2_attr (die, DW_AT_GNU_call_site_target, cu); + if (attr == NULL) + attr = dwarf2_attr (die, DW_AT_abstract_origin, cu); + SET_FIELD_DWARF_BLOCK (call_site->target, NULL); + if (!attr || (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0)) + /* Keep NULL DWARF_BLOCK. */; + else if (attr_form_is_block (attr)) + { + struct dwarf2_locexpr_baton *dlbaton; + + dlbaton = obstack_alloc (&objfile->objfile_obstack, sizeof (*dlbaton)); + dlbaton->data = DW_BLOCK (attr)->data; + dlbaton->size = DW_BLOCK (attr)->size; + dlbaton->per_cu = cu->per_cu; + + SET_FIELD_DWARF_BLOCK (call_site->target, dlbaton); + } + else if (is_ref_attr (attr)) + { + struct dwarf2_cu *target_cu = cu; + struct die_info *target_die; + + target_die = follow_die_ref_or_sig (die, attr, &target_cu); + gdb_assert (target_cu->objfile == objfile); + if (die_is_declaration (target_die, target_cu)) + { + const char *target_physname; + + target_physname = dwarf2_physname (NULL, target_die, target_cu); + if (target_physname == NULL) + complaint (&symfile_complaints, + _("DW_AT_GNU_call_site_target target DIE has invalid " + "physname, for referencing DIE 0x%x [in module %s]"), + die->offset.sect_off, objfile->name); + else + SET_FIELD_PHYSNAME (call_site->target, (char *) target_physname); + } + else + { + CORE_ADDR lowpc; + + /* DW_AT_entry_pc should be preferred. */ + if (!dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu, NULL)) + complaint (&symfile_complaints, + _("DW_AT_GNU_call_site_target target DIE has invalid " + "low pc, for referencing DIE 0x%x [in module %s]"), + die->offset.sect_off, objfile->name); + else + SET_FIELD_PHYSADDR (call_site->target, lowpc + baseaddr); + } + } + else + complaint (&symfile_complaints, + _("DW_TAG_GNU_call_site DW_AT_GNU_call_site_target is neither " + "block nor reference, for DIE 0x%x [in module %s]"), + die->offset.sect_off, objfile->name); + + call_site->per_cu = cu->per_cu; + + for (child_die = die->child; + child_die && child_die->tag; + child_die = sibling_die (child_die)) + { + struct dwarf2_locexpr_baton *dlbaton; + struct call_site_parameter *parameter; + + if (child_die->tag != DW_TAG_GNU_call_site_parameter) + { + /* Already printed the complaint above. */ + continue; + } + + gdb_assert (call_site->parameter_count < nparams); + parameter = &call_site->parameter[call_site->parameter_count]; + + /* DW_AT_location specifies the register number. Value of the data + assumed for the register is contained in DW_AT_GNU_call_site_value. */ + + attr = dwarf2_attr (child_die, DW_AT_location, cu); + if (!attr || !attr_form_is_block (attr)) + { + complaint (&symfile_complaints, + _("No DW_FORM_block* DW_AT_location for " + "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"), + child_die->offset.sect_off, objfile->name); + continue; + } + parameter->dwarf_reg = dwarf_block_to_dwarf_reg (DW_BLOCK (attr)->data, + &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size]); + if (parameter->dwarf_reg == -1 + && !dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (attr)->data, + &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size], + ¶meter->fb_offset)) + { + complaint (&symfile_complaints, + _("Only single DW_OP_reg or DW_OP_fbreg is supported " + "for DW_FORM_block* DW_AT_location for " + "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"), + child_die->offset.sect_off, objfile->name); + continue; + } + + attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu); + if (!attr_form_is_block (attr)) + { + complaint (&symfile_complaints, + _("No DW_FORM_block* DW_AT_GNU_call_site_value for " + "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"), + child_die->offset.sect_off, objfile->name); + continue; + } + parameter->value = DW_BLOCK (attr)->data; + parameter->value_size = DW_BLOCK (attr)->size; + + /* Parameters are not pre-cleared by memset above. */ + parameter->data_value = NULL; + parameter->data_value_size = 0; + call_site->parameter_count++; + + attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_data_value, cu); + if (attr) + { + if (!attr_form_is_block (attr)) + complaint (&symfile_complaints, + _("No DW_FORM_block* DW_AT_GNU_call_site_data_value for " + "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"), + child_die->offset.sect_off, objfile->name); + else + { + parameter->data_value = DW_BLOCK (attr)->data; + parameter->data_value_size = DW_BLOCK (attr)->size; + } + } + } +} + /* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET. Return 1 if the attributes are present and valid, otherwise, return 0. If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'. */ @@ -6309,23 +7989,31 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return, /* Get low and high pc attributes from a die. Return 1 if the attributes are present and valid, otherwise, return 0. Return -1 if the range is 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, struct partial_symtab *pst) { struct attribute *attr; + struct attribute *attr_high; CORE_ADDR low = 0; CORE_ADDR high = 0; int ret = 0; - attr = dwarf2_attr (die, DW_AT_high_pc, cu); - if (attr) + attr_high = dwarf2_attr (die, DW_AT_high_pc, cu); + if (attr_high) { - high = DW_ADDR (attr); attr = dwarf2_attr (die, DW_AT_low_pc, cu); if (attr) - low = DW_ADDR (attr); + { + low = DW_ADDR (attr); + if (attr_high->form == DW_FORM_addr + || attr_high->form == DW_FORM_GNU_addr_index) + high = DW_ADDR (attr_high); + else + high = low + DW_UNSND (attr_high); + } else /* Found high w/o low attribute. */ return 0; @@ -6363,7 +8051,8 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, return 0; *lowpc = low; - *highpc = high; + if (highpc) + *highpc = high; return ret; } @@ -6465,21 +8154,28 @@ get_scope_pc_bounds (struct die_info *die, /* Record the address ranges for BLOCK, offset by BASEADDR, as given in DIE. */ + static void dwarf2_record_block_ranges (struct die_info *die, struct block *block, CORE_ADDR baseaddr, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct attribute *attr; + struct attribute *attr_high; - attr = dwarf2_attr (die, DW_AT_high_pc, cu); - if (attr) + attr_high = dwarf2_attr (die, DW_AT_high_pc, cu); + if (attr_high) { - CORE_ADDR high = DW_ADDR (attr); - attr = dwarf2_attr (die, DW_AT_low_pc, cu); if (attr) { CORE_ADDR low = DW_ADDR (attr); + CORE_ADDR high; + if (attr_high->form == DW_FORM_addr + || attr_high->form == DW_FORM_GNU_addr_index) + high = DW_ADDR (attr_high); + else + high = low + DW_UNSND (attr_high); record_block_range (block, baseaddr + low, baseaddr + high - 1); } @@ -6488,7 +8184,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block, attr = dwarf2_attr (die, DW_AT_ranges, cu); if (attr) { - bfd *obfd = cu->objfile->obfd; + bfd *obfd = objfile->obfd; /* The value of the DW_AT_ranges attribute is the offset of the address range list in the .debug_ranges section. */ @@ -6583,6 +8279,7 @@ producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu) { const char *cs; int major, minor, release; + int result = 0; if (cu->producer == NULL) { @@ -6598,26 +8295,33 @@ producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu) return 0; } + if (cu->checked_producer) + return cu->producer_is_gxx_lt_4_6; + /* Skip any identifier after "GNU " - such as "C++" or "Java". */ if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0) { /* For non-GCC compilers expect their behavior is DWARF version compliant. */ - - return 0; } - cs = &cu->producer[strlen ("GNU ")]; - while (*cs && !isdigit (*cs)) - cs++; - if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3) + else { - /* Not recognized as GCC. */ - - return 0; + cs = &cu->producer[strlen ("GNU ")]; + while (*cs && !isdigit (*cs)) + cs++; + if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3) + { + /* Not recognized as GCC. */ + } + else + result = major < 4 || (major == 4 && minor < 6); } - return major < 4 || (major == 4 && minor < 6); + cu->checked_producer = 1; + cu->producer_is_gxx_lt_4_6 = result; + + return result; } /* Return the default accessibility type if it is not overriden by @@ -6765,7 +8469,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, anonymous object to the MSB of the field. We don't have to do anything special since we don't need to know the size of the anonymous object. */ - FIELD_BITPOS (*fp) += DW_UNSND (attr); + SET_FIELD_BITPOS (*fp, FIELD_BITPOS (*fp) + DW_UNSND (attr)); } else { @@ -6794,8 +8498,10 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, bit field. */ anonymous_size = TYPE_LENGTH (fp->type); } - FIELD_BITPOS (*fp) += anonymous_size * bits_per_byte - - bit_offset - FIELD_BITSIZE (*fp); + SET_FIELD_BITPOS (*fp, + (FIELD_BITPOS (*fp) + + anonymous_size * bits_per_byte + - bit_offset - FIELD_BITSIZE (*fp))); } } @@ -7195,7 +8901,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, complaint (&symfile_complaints, _("Member function \"%s\" (offset %d) is virtual " "but the vtable offset is not specified"), - fieldname, die->offset); + fieldname, die->offset.sect_off); ALLOCATE_CPLUS_STRUCT_TYPE (type); TYPE_CPLUS_DYNAMIC (type) = 1; } @@ -7209,7 +8915,6 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type, struct dwarf2_cu *cu) { struct fnfieldlist *flp; - int total_length = 0; int i; if (cu->language == language_ada) @@ -7231,12 +8936,9 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type, TYPE_ALLOC (type, sizeof (struct fn_field) * flp->length); for (k = flp->length; (k--, nfp); nfp = nfp->next) fn_flp->fn_fields[k] = nfp->fnfield; - - total_length += flp->length; } TYPE_NFN_FIELDS (type) = fip->nfnfields; - TYPE_NFN_FIELDS_TOTAL (type) = total_length; } /* Returns non-zero if NAME is the name of a vtable member in CU's @@ -7528,7 +9230,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) i >= TYPE_N_BASECLASSES (t); --i) { - char *fieldname = TYPE_FIELD_NAME (t, i); + const char *fieldname = TYPE_FIELD_NAME (t, i); if (is_vtable_name (fieldname, cu)) { @@ -7603,7 +9305,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) TYPE_CPLUS_REALLY_JAVA (type) = cu->language == language_java; } - quirk_gcc_member_function_pointer (type, cu->objfile); + quirk_gcc_member_function_pointer (type, objfile); /* NOTE: carlton/2004-03-16: GCC 3.4 (or at least one of its snapshots) has been known to create a die giving a declaration @@ -7714,6 +9416,8 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) int num_fields = 0; int unsigned_enum = 1; char *name; + int flag_enum = 1; + ULONGEST mask = 0; child_die = die->child; while (child_die && child_die->tag) @@ -7729,7 +9433,14 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) { sym = new_symbol (child_die, this_type, cu); if (SYMBOL_VALUE (sym) < 0) - unsigned_enum = 0; + { + unsigned_enum = 0; + flag_enum = 0; + } + else if ((mask & SYMBOL_VALUE (sym)) != 0) + flag_enum = 0; + else + mask |= SYMBOL_VALUE (sym); if ((num_fields % DW_FIELD_ALLOC_CHUNK) == 0) { @@ -7741,7 +9452,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) FIELD_NAME (fields[num_fields]) = SYMBOL_LINKAGE_NAME (sym); FIELD_TYPE (fields[num_fields]) = NULL; - SET_FIELD_BITPOS (fields[num_fields], SYMBOL_VALUE (sym)); + SET_FIELD_ENUMVAL (fields[num_fields], SYMBOL_VALUE (sym)); FIELD_BITSIZE (fields[num_fields]) = 0; num_fields++; @@ -7762,6 +9473,8 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) } if (unsigned_enum) TYPE_UNSIGNED (this_type) = 1; + if (flag_enum) + TYPE_FLAG_ENUM (this_type) = 1; } /* If we are reading an enum from a .debug_types unit, and the enum @@ -7772,16 +9485,17 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) actually available. Note that we do not want to do this for all enums which are just declarations, because C++0x allows forward enum declarations. */ - if (cu->per_cu->debug_type_section + if (cu->per_cu->is_debug_types && die_is_declaration (die, cu)) { - struct signatured_type *type_sig; + struct signatured_type *sig_type; - type_sig + sig_type = lookup_signatured_type_at_offset (dwarf2_per_objfile->objfile, - cu->per_cu->debug_type_section, + cu->per_cu->info_or_types_section, cu->per_cu->offset); - if (type_sig->type_offset != die->offset) + gdb_assert (sig_type->type_offset_in_section.sect_off != 0); + if (sig_type->type_offset_in_section.sect_off != die->offset.sect_off) return; } @@ -8107,7 +9821,7 @@ read_module_type (struct die_info *die, struct dwarf2_cu *cu) if (!module_name) complaint (&symfile_complaints, _("DW_TAG_module has no name, offset 0x%x"), - die->offset); + die->offset.sect_off); type = init_type (TYPE_CODE_MODULE, 0, 0, module_name, objfile); /* determine_prefix uses TYPE_TAG_NAME. */ @@ -8390,6 +10104,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu) static struct type * read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct type *type; /* Type that this function returns. */ struct type *ftype; /* Function that returns above type. */ struct attribute *attr; @@ -8435,7 +10150,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) if (die->child != NULL) { - struct type *void_type = objfile_type (cu->objfile)->builtin_void; + struct type *void_type = objfile_type (objfile)->builtin_void; struct die_info *child_die; int nparams, iparams; @@ -8545,14 +10260,26 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; const char *name = NULL; - struct type *this_type; + struct type *this_type, *target_type; name = dwarf2_full_name (NULL, die, cu); this_type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, NULL, objfile); TYPE_NAME (this_type) = (char *) name; set_die_type (die, this_type, cu); - TYPE_TARGET_TYPE (this_type) = die_type (die, cu); + target_type = die_type (die, cu); + if (target_type != this_type) + TYPE_TARGET_TYPE (this_type) = target_type; + else + { + /* Self-referential typedefs are, it seems, not allowed by the DWARF + spec and cause infinite loops in GDB. */ + complaint (&symfile_complaints, + _("Self-referential DW_TAG_typedef " + "- DIE at 0x%x [in module %s]"), + die->offset.sect_off, objfile->name); + TYPE_TARGET_TYPE (this_type) = NULL; + } return this_type; } @@ -8661,8 +10388,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) struct type *base_type; struct type *range_type; struct attribute *attr; - LONGEST low = 0; - LONGEST high = -1; + LONGEST low, high; + int low_default_is_valid; char *name; LONGEST negative_mask; @@ -8675,10 +10402,35 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) if (range_type) return range_type; - if (cu->language == language_fortran) + /* Set LOW_DEFAULT_IS_VALID if current language and DWARF version allow + omitting DW_AT_lower_bound. */ + switch (cu->language) { - /* FORTRAN implies a lower bound of 1, if not given. */ + case language_c: + case language_cplus: + low = 0; + low_default_is_valid = 1; + break; + case language_fortran: + low = 1; + low_default_is_valid = 1; + break; + case language_d: + case language_java: + case language_objc: + low = 0; + low_default_is_valid = (cu->header.version >= 4); + break; + case language_ada: + case language_m2: + case language_pascal: low = 1; + low_default_is_valid = (cu->header.version >= 4); + break; + default: + low = 0; + low_default_is_valid = 0; + break; } /* FIXME: For variable sized arrays either of these could be @@ -8686,7 +10438,11 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) but we don't know how to handle it. */ attr = dwarf2_attr (die, DW_AT_lower_bound, cu); if (attr) - low = dwarf2_get_attr_constant_value (attr, 0); + low = dwarf2_get_attr_constant_value (attr, low); + else if (!low_default_is_valid) + complaint (&symfile_complaints, _("Missing DW_AT_lower_bound " + "- DIE at 0x%x [in module %s]"), + die->offset.sect_off, cu->objfile->name); attr = dwarf2_attr (die, DW_AT_upper_bound, cu); if (attr) @@ -8810,92 +10566,6 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu) return set_die_type (die, type, cu); } -/* Trivial hash function for die_info: the hash value of a DIE - is its offset in .debug_info for this objfile. */ - -static hashval_t -die_hash (const void *item) -{ - const struct die_info *die = item; - - return die->offset; -} - -/* Trivial comparison function for die_info structures: two DIEs - are equal if they have the same offset. */ - -static int -die_eq (const void *item_lhs, const void *item_rhs) -{ - const struct die_info *die_lhs = item_lhs; - const struct die_info *die_rhs = item_rhs; - - return die_lhs->offset == die_rhs->offset; -} - -/* Read a whole compilation unit into a linked list of dies. */ - -static struct die_info * -read_comp_unit (gdb_byte *info_ptr, struct dwarf2_cu *cu) -{ - struct die_reader_specs reader_specs; - int read_abbrevs = 0; - struct cleanup *back_to = NULL; - struct die_info *die; - - if (cu->dwarf2_abbrevs == NULL) - { - dwarf2_read_abbrevs (cu->objfile->obfd, cu); - back_to = make_cleanup (dwarf2_free_abbrev_table, cu); - read_abbrevs = 1; - } - - gdb_assert (cu->die_hash == NULL); - 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); - - init_cu_die_reader (&reader_specs, cu); - - die = read_die_and_children (&reader_specs, info_ptr, &info_ptr, NULL); - - if (read_abbrevs) - do_cleanups (back_to); - - return die; -} - -/* 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 (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 (reader, info_ptr, - new_info_ptr, parent); - - if (dwarf2_die_debug) - { - fprintf_unfiltered (gdb_stdlog, - "\nRead die from %s of %s:\n", - (reader->cu->per_cu->debug_type_section - ? ".debug_types" - : ".debug_info"), - reader->abfd->filename); - dump_die (result, dwarf2_die_debug); - } - - return result; -} - /* Read a single die and all its descendents. Set the die's sibling field to NULL; set other fields in the die correctly, and set all of the descendents' fields correctly. Set *NEW_INFO_PTR to the @@ -8903,10 +10573,10 @@ read_die_and_children (const struct die_reader_specs *reader, is the parent of the die in question. */ 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) +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 *die; gdb_byte *cur_ptr; @@ -8952,7 +10622,7 @@ read_die_and_siblings (const struct die_reader_specs *reader, while (1) { struct die_info *die - = read_die_and_children_1 (reader, cur_ptr, &cur_ptr, parent); + = read_die_and_children (reader, cur_ptr, &cur_ptr, parent); if (die == NULL) { @@ -8969,23 +10639,27 @@ read_die_and_siblings (const struct die_reader_specs *reader, } } -/* 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. */ +/* Read a die and all its attributes, leave space for NUM_EXTRA_ATTRS + attributes. + The caller is responsible for filling in the extra attributes + and updating (*DIEP)->num_attrs. + 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) +read_full_die_1 (const struct die_reader_specs *reader, + struct die_info **diep, gdb_byte *info_ptr, + int *has_children, int num_extra_attrs) { - unsigned int abbrev_number, bytes_read, i, offset; + unsigned int abbrev_number, bytes_read, i; + sect_offset offset; struct abbrev_info *abbrev; struct die_info *die; struct dwarf2_cu *cu = reader->cu; bfd *abfd = reader->abfd; - offset = info_ptr - reader->buffer; + offset.sect_off = info_ptr - reader->buffer; abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; if (!abbrev_number) @@ -9001,22 +10675,38 @@ read_full_die (const struct die_reader_specs *reader, abbrev_number, bfd_get_filename (abfd)); - die = dwarf_alloc_die (cu, abbrev->num_attrs); + die = dwarf_alloc_die (cu, abbrev->num_attrs + num_extra_attrs); die->offset = offset; die->tag = abbrev->tag; die->abbrev = abbrev_number; + /* Make the result usable. + The caller needs to update num_attrs after adding the extra + attributes. */ 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); + info_ptr = read_attribute (reader, &die->attrs[i], &abbrev->attrs[i], + info_ptr); *diep = die; *has_children = abbrev->has_children; return info_ptr; } +/* Read a die and all its attributes. + 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) +{ + return read_full_die_1 (reader, diep, info_ptr, has_children, 0); +} + /* 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 @@ -9024,8 +10714,11 @@ read_full_die (const struct die_reader_specs *reader, the data found in the abbrev table. */ static void -dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) +dwarf2_read_abbrevs (struct dwarf2_cu *cu, + struct dwarf2_section_info *abbrev_section) + { + bfd *abfd = abbrev_section->asection->owner; struct comp_unit_head *cu_header = &cu->header; gdb_byte *abbrev_ptr; struct abbrev_info *cur_abbrev; @@ -9042,9 +10735,8 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) memset (cu->dwarf2_abbrevs, 0, ABBREV_HASH_SIZE * sizeof (struct abbrev_info *)); - dwarf2_read_section (dwarf2_per_objfile->objfile, - &dwarf2_per_objfile->abbrev); - abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset; + dwarf2_read_section (cu->objfile, abbrev_section); + abbrev_ptr = abbrev_section->buffer + cu_header->abbrev_offset.sect_off; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; @@ -9063,9 +10755,6 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr); abbrev_ptr += 1; - if (cur_abbrev->tag == DW_TAG_namespace) - cu->has_namespace_info = 1; - /* now read in declarations */ abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; @@ -9081,16 +10770,6 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) * sizeof (struct attr_abbrev))); } - /* Record whether this compilation unit might have - inter-compilation-unit references. If we don't know what form - this attribute will have, then it might potentially be a - DW_FORM_ref_addr, so we conservatively expect inter-CU - references. */ - - if (abbrev_form == DW_FORM_ref_addr - || abbrev_form == DW_FORM_indirect) - cu->has_form_ref_addr = 1; - cur_attrs[cur_abbrev->num_attrs].name = abbrev_name; cur_attrs[cur_abbrev->num_attrs++].form = abbrev_form; abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); @@ -9116,8 +10795,8 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) already read (which means we are about to read the abbreviations for the next compile unit) or if the end of the abbreviation table is reached. */ - if ((unsigned int) (abbrev_ptr - dwarf2_per_objfile->abbrev.buffer) - >= dwarf2_per_objfile->abbrev.size) + if ((unsigned int) (abbrev_ptr - abbrev_section->buffer) + >= abbrev_section->size) break; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; @@ -9195,21 +10874,23 @@ 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 *buffer, gdb_byte *info_ptr, - int building_psymtab, struct dwarf2_cu *cu) +load_partial_dies (const struct die_reader_specs *reader, + gdb_byte *info_ptr, int building_psymtab) { + struct dwarf2_cu *cu = reader->cu; + struct objfile *objfile = cu->objfile; struct partial_die_info *part_die; struct partial_die_info *parent_die, *last_die, *first_die = NULL; struct abbrev_info *abbrev; unsigned int bytes_read; unsigned int load_all = 0; - int nesting_level = 1; parent_die = NULL; last_die = NULL; - if (cu->per_cu && cu->per_cu->load_all_dies) + gdb_assert (cu->per_cu != NULL); + if (cu->per_cu->load_all_dies) load_all = 1; cu->partial_dies @@ -9259,20 +10940,19 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, if (!load_all) { /* We don't need a partial DIE for the template argument. */ - info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, - cu); + info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev); continue; } } - /* We only recurse into subprograms looking for template arguments. + /* We only recurse into c++ subprograms looking for template arguments. Skip their other children. */ if (!load_all && cu->language == language_cplus && parent_die != NULL && parent_die->tag == DW_TAG_subprogram) { - info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu); + info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev); continue; } @@ -9289,15 +10969,16 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, && abbrev->tag != DW_TAG_variable && abbrev->tag != DW_TAG_namespace && abbrev->tag != DW_TAG_module - && abbrev->tag != DW_TAG_member) + && abbrev->tag != DW_TAG_member + && abbrev->tag != DW_TAG_imported_unit) { /* Otherwise we skip to the next sibling, if any. */ - info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu); + info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev); continue; } - info_ptr = read_partial_die (part_die, abbrev, bytes_read, abfd, - buffer, info_ptr, cu); + info_ptr = read_partial_die (reader, part_die, abbrev, bytes_read, + info_ptr); /* This two-pass algorithm for processing partial symbols has a high cost in cache pressure. Thus, handle some simple cases @@ -9325,9 +11006,9 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, if (building_psymtab && part_die->name != NULL) 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, buffer, info_ptr, abfd, cu); + &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); + info_ptr = locate_pdi_sibling (reader, part_die, info_ptr); continue; } @@ -9343,7 +11024,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, complaint (&symfile_complaints, _("DW_TAG_typedef has childen - GCC PR debug/47510 bug " "- DIE at 0x%x [in module %s]"), - part_die->offset, cu->objfile->name); + part_die->offset.sect_off, objfile->name); /* If we're at the second level, and we're an enumerator, and our parent has no specification (meaning possibly lives in a @@ -9363,11 +11044,11 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, VAR_DOMAIN, LOC_CONST, (cu->language == language_cplus || cu->language == language_java) - ? &cu->objfile->global_psymbols - : &cu->objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu->language, cu->objfile); + ? &objfile->global_psymbols + : &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); - info_ptr = locate_pdi_sibling (part_die, buffer, info_ptr, abfd, cu); + info_ptr = locate_pdi_sibling (reader, part_die, info_ptr); continue; } @@ -9417,7 +11098,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, void **slot; slot = htab_find_slot_with_hash (cu->partial_dies, part_die, - part_die->offset, INSERT); + part_die->offset.sect_off, INSERT); *slot = part_die; } @@ -9460,7 +11141,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, } /* Otherwise we skip to the next sibling, if any. */ - info_ptr = locate_pdi_sibling (last_die, buffer, info_ptr, abfd, cu); + info_ptr = locate_pdi_sibling (reader, last_die, info_ptr); /* Back to the top, do it again. */ } @@ -9469,20 +11150,23 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, /* Read a minimal amount of information into the minimal die structure. */ static gdb_byte * -read_partial_die (struct partial_die_info *part_die, - struct abbrev_info *abbrev, - unsigned int abbrev_len, bfd *abfd, - gdb_byte *buffer, gdb_byte *info_ptr, - struct dwarf2_cu *cu) +read_partial_die (const struct die_reader_specs *reader, + struct partial_die_info *part_die, + struct abbrev_info *abbrev, unsigned int abbrev_len, + gdb_byte *info_ptr) { + struct dwarf2_cu *cu = reader->cu; + struct objfile *objfile = cu->objfile; + gdb_byte *buffer = reader->buffer; unsigned int i; struct attribute attr; int has_low_pc_attr = 0; int has_high_pc_attr = 0; + int high_pc_relative = 0; memset (part_die, 0, sizeof (struct partial_die_info)); - part_die->offset = info_ptr - buffer; + part_die->offset.sect_off = info_ptr - buffer; info_ptr += abbrev_len; @@ -9494,7 +11178,7 @@ read_partial_die (struct partial_die_info *part_die, for (i = 0; i < abbrev->num_attrs; ++i) { - info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, info_ptr, cu); + info_ptr = read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr); /* Store the data if it is of an attribute we want to keep in a partial symbol table. */ @@ -9504,6 +11188,7 @@ read_partial_die (struct partial_die_info *part_die, switch (part_die->tag) { case DW_TAG_compile_unit: + case DW_TAG_partial_unit: case DW_TAG_type_unit: /* Compilation units have a DW_AT_name that is a filename, not a source language identifier. */ @@ -9516,7 +11201,7 @@ read_partial_die (struct partial_die_info *part_die, default: part_die->name = dwarf2_canonicalize_name (DW_STRING (&attr), cu, - &cu->objfile->objfile_obstack); + &objfile->objfile_obstack); break; } break; @@ -9535,13 +11220,20 @@ read_partial_die (struct partial_die_info *part_die, break; case DW_AT_high_pc: has_high_pc_attr = 1; - part_die->highpc = DW_ADDR (&attr); + if (attr.form == DW_FORM_addr + || attr.form == DW_FORM_GNU_addr_index) + part_die->highpc = DW_ADDR (&attr); + else + { + high_pc_relative = 1; + part_die->highpc = DW_UNSND (&attr); + } break; case DW_AT_location: /* Support the .debug_loc offsets. */ if (attr_form_is_block (&attr)) { - part_die->locdesc = DW_BLOCK (&attr); + part_die->d.locdesc = DW_BLOCK (&attr); } else if (attr_form_is_section_offset (&attr)) { @@ -9575,7 +11267,7 @@ read_partial_die (struct partial_die_info *part_die, complaint (&symfile_complaints, _("ignoring absolute DW_AT_sibling")); else - part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr); + part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr).sect_off; break; case DW_AT_byte_size: part_die->has_byte_size = 1; @@ -9605,11 +11297,25 @@ read_partial_die (struct partial_die_info *part_die, language_of_main = language_fortran; } break; + case DW_AT_inline: + if (DW_UNSND (&attr) == DW_INL_inlined + || DW_UNSND (&attr) == DW_INL_declared_inlined) + part_die->may_be_inlined = 1; + break; + + case DW_AT_import: + if (part_die->tag == DW_TAG_imported_unit) + part_die->d.offset = dwarf2_get_ref_die_offset (&attr); + break; + default: break; } } + if (high_pc_relative) + part_die->highpc += part_die->lowpc; + if (has_low_pc_attr && has_high_pc_attr) { /* When using the GNU linker, .gnu.linkonce. sections are used to @@ -9622,25 +11328,25 @@ read_partial_die (struct partial_die_info *part_die, so that GDB will ignore it. */ if (part_die->lowpc == 0 && !dwarf2_per_objfile->has_section_at_zero) { - struct gdbarch *gdbarch = get_objfile_arch (cu->objfile); + struct gdbarch *gdbarch = get_objfile_arch (objfile); complaint (&symfile_complaints, _("DW_AT_low_pc %s is zero " "for DIE at 0x%x [in module %s]"), paddress (gdbarch, part_die->lowpc), - part_die->offset, cu->objfile->name); + part_die->offset.sect_off, objfile->name); } /* dwarf2_get_pc_bounds has also the strict low < high requirement. */ else if (part_die->lowpc >= part_die->highpc) { - struct gdbarch *gdbarch = get_objfile_arch (cu->objfile); + struct gdbarch *gdbarch = get_objfile_arch (objfile); complaint (&symfile_complaints, _("DW_AT_low_pc %s is not < DW_AT_high_pc %s " "for DIE at 0x%x [in module %s]"), paddress (gdbarch, part_die->lowpc), paddress (gdbarch, part_die->highpc), - part_die->offset, cu->objfile->name); + part_die->offset.sect_off, objfile->name); } else part_die->has_pc_info = 1; @@ -9652,13 +11358,14 @@ read_partial_die (struct partial_die_info *part_die, /* Find a cached partial DIE at OFFSET in CU. */ static struct partial_die_info * -find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu) +find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu) { struct partial_die_info *lookup_die = NULL; struct partial_die_info part_die; part_die.offset = offset; - lookup_die = htab_find_with_hash (cu->partial_dies, &part_die, offset); + lookup_die = htab_find_with_hash (cu->partial_dies, &part_die, + offset.sect_off); return lookup_die; } @@ -9669,75 +11376,63 @@ find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu) DW_FORM_ref_sig8). */ static struct partial_die_info * -find_partial_die (unsigned int offset, struct dwarf2_cu *cu) +find_partial_die (sect_offset offset, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct dwarf2_per_cu_data *per_cu = NULL; struct partial_die_info *pd = NULL; - if (cu->per_cu->debug_type_section) - { - 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); if (pd != NULL) return pd; + /* We missed recording what we needed. + Load all dies and try again. */ + per_cu = cu->per_cu; } + else + { + /* TUs don't reference other CUs/TUs (except via type signatures). */ + if (cu->per_cu->is_debug_types) + { + error (_("Dwarf Error: Type Unit at offset 0x%lx contains" + " external reference to offset 0x%lx [in module %s].\n"), + (long) cu->header.offset.sect_off, (long) offset.sect_off, + bfd_get_filename (objfile->obfd)); + } + per_cu = dwarf2_find_containing_comp_unit (offset, objfile); - per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile); + if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL) + load_partial_comp_unit (per_cu); - if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL) - load_partial_comp_unit (per_cu, cu->objfile); + per_cu->cu->last_used = 0; + pd = find_partial_die_in_comp_unit (offset, per_cu->cu); + } - per_cu->cu->last_used = 0; - pd = find_partial_die_in_comp_unit (offset, per_cu->cu); + /* If we didn't find it, and not all dies have been loaded, + load them all and try again. */ if (pd == NULL && per_cu->load_all_dies == 0) { - struct cleanup *back_to; - struct partial_die_info comp_unit_die; - struct abbrev_info *abbrev; - unsigned int bytes_read; - char *info_ptr; - per_cu->load_all_dies = 1; - /* Re-read the DIEs. */ - back_to = make_cleanup (null_cleanup, 0); - if (per_cu->cu->dwarf2_abbrevs == NULL) - { - dwarf2_read_abbrevs (per_cu->cu->objfile->obfd, 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, - dwarf2_per_objfile->info.buffer, info_ptr, - per_cu->cu); - if (comp_unit_die.has_children) - load_partial_dies (per_cu->cu->objfile->obfd, - dwarf2_per_objfile->info.buffer, info_ptr, - 0, per_cu->cu); - do_cleanups (back_to); + /* This is nasty. When we reread the DIEs, somewhere up the call chain + THIS_CU->cu may already be in use. So we can't just free it and + replace its DIEs with the ones we read in. Instead, we leave those + DIEs alone (which can still be in use, e.g. in scan_partial_symbols), + and clobber THIS_CU->cu->partial_dies with the hash table for the new + set. */ + load_partial_comp_unit (per_cu); 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"), - offset, bfd_get_filename (cu->objfile->obfd)); + offset.sect_off, bfd_get_filename (objfile->obfd)); return pd; } @@ -9833,9 +11528,7 @@ fixup_partial_die (struct partial_die_info *part_die, /* If there is no parent die to provide a namespace, and there are children, see if we can determine the namespace from their linkage - name. - NOTE: We need to do this even if cu->has_namespace_info != 0. - gcc-4.5 -gdwarf-4 can drop the enclosing namespace. */ + name. */ if (cu->language == language_cplus && !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types) && part_die->die_parent == NULL @@ -9848,9 +11541,10 @@ fixup_partial_die (struct partial_die_info *part_die, /* GCC might emit a nameless struct or union that has a linkage name. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */ if (part_die->name == NULL - && (part_die->tag == DW_TAG_structure_type - || part_die->tag == DW_TAG_union_type - || part_die->tag == DW_TAG_class_type) + && (part_die->tag == DW_TAG_class_type + || part_die->tag == DW_TAG_interface_type + || part_die->tag == DW_TAG_structure_type + || part_die->tag == DW_TAG_union_type) && part_die->linkage_name != NULL) { char *demangled; @@ -9858,7 +11552,17 @@ fixup_partial_die (struct partial_die_info *part_die, demangled = cplus_demangle (part_die->linkage_name, DMGL_TYPES); if (demangled) { - part_die->name = obsavestring (demangled, strlen (demangled), + const char *base; + + /* Strip any leading namespaces/classes, keep only the base name. + DW_AT_name for named DIEs does not contain the prefixes. */ + base = strrchr (demangled, ':'); + if (base && base > demangled && base[-1] == ':') + base++; + else + base = demangled; + + part_die->name = obsavestring (base, strlen (base), &cu->objfile->objfile_obstack); xfree (demangled); } @@ -9870,10 +11574,12 @@ fixup_partial_die (struct partial_die_info *part_die, /* Read an attribute value described by an attribute form. */ static gdb_byte * -read_attribute_value (struct attribute *attr, unsigned form, - bfd *abfd, gdb_byte *info_ptr, - struct dwarf2_cu *cu) +read_attribute_value (const struct die_reader_specs *reader, + struct attribute *attr, unsigned form, + gdb_byte *info_ptr) { + struct dwarf2_cu *cu = reader->cu; + bfd *abfd = reader->abfd; struct comp_unit_head *cu_header = &cu->header; unsigned int bytes_read; struct dwarf_block *blk; @@ -9883,10 +11589,10 @@ read_attribute_value (struct attribute *attr, unsigned form, { case DW_FORM_ref_addr: if (cu->header.version == 2) - DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read); + DW_UNSND (attr) = read_address (abfd, info_ptr, cu, &bytes_read); else - DW_ADDR (attr) = read_offset (abfd, info_ptr, - &cu->header, &bytes_read); + DW_UNSND (attr) = read_offset (abfd, info_ptr, + &cu->header, &bytes_read); info_ptr += bytes_read; break; case DW_FORM_addr: @@ -9973,19 +11679,23 @@ read_attribute_value (struct attribute *attr, unsigned form, info_ptr += bytes_read; break; case DW_FORM_ref1: - DW_ADDR (attr) = cu->header.offset + read_1_byte (abfd, info_ptr); + DW_UNSND (attr) = (cu->header.offset.sect_off + + read_1_byte (abfd, info_ptr)); info_ptr += 1; break; case DW_FORM_ref2: - DW_ADDR (attr) = cu->header.offset + read_2_bytes (abfd, info_ptr); + DW_UNSND (attr) = (cu->header.offset.sect_off + + read_2_bytes (abfd, info_ptr)); info_ptr += 2; break; case DW_FORM_ref4: - DW_ADDR (attr) = cu->header.offset + read_4_bytes (abfd, info_ptr); + DW_UNSND (attr) = (cu->header.offset.sect_off + + read_4_bytes (abfd, info_ptr)); info_ptr += 4; break; case DW_FORM_ref8: - DW_ADDR (attr) = cu->header.offset + read_8_bytes (abfd, info_ptr); + DW_UNSND (attr) = (cu->header.offset.sect_off + + read_8_bytes (abfd, info_ptr)); info_ptr += 8; break; case DW_FORM_ref_sig8: @@ -9993,18 +11703,48 @@ read_attribute_value (struct attribute *attr, unsigned form, 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)); + lookup_signatured_type (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)); + DW_UNSND (attr) = (cu->header.offset.sect_off + + read_unsigned_leb128 (abfd, info_ptr, &bytes_read)); info_ptr += bytes_read; break; case DW_FORM_indirect: form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; - info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu); + info_ptr = read_attribute_value (reader, attr, form, info_ptr); + break; + case DW_FORM_GNU_addr_index: + if (reader->dwo_file == NULL) + { + /* For now flag a hard error. + Later we can turn this into a complaint. */ + error (_("Dwarf Error: %s found in non-DWO CU [in module %s]"), + dwarf_form_name (form), + bfd_get_filename (abfd)); + } + DW_ADDR (attr) = read_addr_index_from_leb128 (cu, info_ptr, &bytes_read); + info_ptr += bytes_read; + break; + case DW_FORM_GNU_str_index: + if (reader->dwo_file == NULL) + { + /* For now flag a hard error. + Later we can turn this into a complaint if warranted. */ + error (_("Dwarf Error: %s found in non-DWO CU [in module %s]"), + dwarf_form_name (form), + bfd_get_filename (abfd)); + } + { + ULONGEST str_index = + read_unsigned_leb128 (abfd, info_ptr, &bytes_read); + + DW_STRING (attr) = read_str_index (reader, cu, str_index); + DW_STRING_IS_CANONICAL (attr) = 0; + info_ptr += bytes_read; + } break; default: error (_("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]"), @@ -10035,11 +11775,12 @@ read_attribute_value (struct attribute *attr, unsigned form, /* Read an attribute described by an abbreviated attribute. */ static gdb_byte * -read_attribute (struct attribute *attr, struct attr_abbrev *abbrev, - bfd *abfd, gdb_byte *info_ptr, struct dwarf2_cu *cu) +read_attribute (const struct die_reader_specs *reader, + struct attribute *attr, struct attr_abbrev *abbrev, + gdb_byte *info_ptr) { attr->name = abbrev->name; - return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu); + return read_attribute_value (reader, attr, abbrev->form, info_ptr); } /* Read dwarf information from a buffer. */ @@ -10062,12 +11803,24 @@ read_2_bytes (bfd *abfd, gdb_byte *buf) return bfd_get_16 (abfd, buf); } +static int +read_2_signed_bytes (bfd *abfd, gdb_byte *buf) +{ + return bfd_get_signed_16 (abfd, buf); +} + static unsigned int read_4_bytes (bfd *abfd, gdb_byte *buf) { return bfd_get_32 (abfd, buf); } +static int +read_4_signed_bytes (bfd *abfd, gdb_byte *buf) +{ + return bfd_get_signed_32 (abfd, buf); +} + static ULONGEST read_8_bytes (bfd *abfd, gdb_byte *buf) { @@ -10305,10 +12058,10 @@ read_indirect_string (bfd *abfd, gdb_byte *buf, return read_indirect_string_at_offset (abfd, str_offset); } -static unsigned long +static ULONGEST read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr) { - unsigned long result; + ULONGEST result; unsigned int num_read; int i, shift; unsigned char byte; @@ -10322,44 +12075,207 @@ read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr) byte = bfd_get_8 (abfd, buf); buf++; num_read++; - result |= ((unsigned long)(byte & 127) << shift); + result |= ((ULONGEST) (byte & 127) << shift); if ((byte & 128) == 0) { break; } shift += 7; } - *bytes_read_ptr = num_read; - return result; + *bytes_read_ptr = num_read; + return result; +} + +static LONGEST +read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr) +{ + LONGEST result; + int i, shift, num_read; + unsigned char byte; + + result = 0; + shift = 0; + num_read = 0; + i = 0; + while (1) + { + byte = bfd_get_8 (abfd, buf); + buf++; + num_read++; + result |= ((LONGEST) (byte & 127) << shift); + shift += 7; + if ((byte & 128) == 0) + { + break; + } + } + if ((shift < 8 * sizeof (result)) && (byte & 0x40)) + result |= -(((LONGEST) 1) << shift); + *bytes_read_ptr = num_read; + return result; +} + +/* Given index ADDR_INDEX in .debug_addr, fetch the value. + ADDR_BASE is the DW_AT_GNU_addr_base attribute or zero. + ADDR_SIZE is the size of addresses from the CU header. */ + +static CORE_ADDR +read_addr_index_1 (unsigned int addr_index, ULONGEST addr_base, int addr_size) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + bfd *abfd = objfile->obfd; + const gdb_byte *info_ptr; + + dwarf2_read_section (objfile, &dwarf2_per_objfile->addr); + if (dwarf2_per_objfile->addr.buffer == NULL) + error (_("DW_FORM_addr_index used without .debug_addr section [in module %s]"), + objfile->name); + if (addr_base + addr_index * addr_size >= dwarf2_per_objfile->addr.size) + error (_("DW_FORM_addr_index pointing outside of " + ".debug_addr section [in module %s]"), + objfile->name); + info_ptr = (dwarf2_per_objfile->addr.buffer + + addr_base + addr_index * addr_size); + if (addr_size == 4) + return bfd_get_32 (abfd, info_ptr); + else + return bfd_get_64 (abfd, info_ptr); +} + +/* Given index ADDR_INDEX in .debug_addr, fetch the value. */ + +static CORE_ADDR +read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index) +{ + return read_addr_index_1 (addr_index, cu->addr_base, cu->header.addr_size); +} + +/* Given a pointer to an leb128 value, fetch the value from .debug_addr. */ + +static CORE_ADDR +read_addr_index_from_leb128 (struct dwarf2_cu *cu, gdb_byte *info_ptr, + unsigned int *bytes_read) +{ + bfd *abfd = cu->objfile->obfd; + unsigned int addr_index = read_unsigned_leb128 (abfd, info_ptr, bytes_read); + + return read_addr_index (cu, addr_index); +} + +/* Data structure to pass results from dwarf2_read_addr_index_reader + back to dwarf2_read_addr_index. */ + +struct dwarf2_read_addr_index_data +{ + ULONGEST addr_base; + int addr_size; +}; + +/* die_reader_func for dwarf2_read_addr_index. */ + +static void +dwarf2_read_addr_index_reader (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct die_info *comp_unit_die, + int has_children, + void *data) +{ + struct dwarf2_cu *cu = reader->cu; + struct dwarf2_read_addr_index_data *aidata = + (struct dwarf2_read_addr_index_data *) data; + + aidata->addr_base = cu->addr_base; + aidata->addr_size = cu->header.addr_size; +} + +/* Given an index in .debug_addr, fetch the value. + NOTE: This can be called during dwarf expression evaluation, + long after the debug information has been read, and thus per_cu->cu + may no longer exist. */ + +CORE_ADDR +dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu, + unsigned int addr_index) +{ + struct objfile *objfile = per_cu->objfile; + struct dwarf2_cu *cu = per_cu->cu; + ULONGEST addr_base; + int addr_size; + + /* This is intended to be called from outside this file. */ + dw2_setup (objfile); + + /* We need addr_base and addr_size. + If we don't have PER_CU->cu, we have to get it. + Nasty, but the alternative is storing the needed info in PER_CU, + which at this point doesn't seem justified: it's not clear how frequently + it would get used and it would increase the size of every PER_CU. + Entry points like dwarf2_per_cu_addr_size do a similar thing + so we're not in uncharted territory here. + Alas we need to be a bit more complicated as addr_base is contained + in the DIE. + + We don't need to read the entire CU(/TU). + We just need the header and top level die. + IWBN to use the aging mechanism to let us lazily later discard the CU. + See however init_cutu_and_read_dies_simple. */ + + if (cu != NULL) + { + addr_base = cu->addr_base; + addr_size = cu->header.addr_size; + } + else + { + struct dwarf2_read_addr_index_data aidata; + + init_cutu_and_read_dies_simple (per_cu, dwarf2_read_addr_index_reader, + &aidata); + addr_base = aidata.addr_base; + addr_size = aidata.addr_size; + } + + return read_addr_index_1 (addr_index, addr_base, addr_size); } -static long -read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr) -{ - long result; - int i, shift, num_read; - unsigned char byte; +/* Given a DW_AT_str_index, fetch the string. */ - result = 0; - shift = 0; - num_read = 0; - i = 0; - while (1) - { - byte = bfd_get_8 (abfd, buf); - buf++; - num_read++; - result |= ((long)(byte & 127) << shift); - shift += 7; - if ((byte & 128) == 0) - { - break; - } - } - if ((shift < 8 * sizeof (result)) && (byte & 0x40)) - result |= -(((long)1) << shift); - *bytes_read_ptr = num_read; - return result; +static char * +read_str_index (const struct die_reader_specs *reader, + struct dwarf2_cu *cu, ULONGEST str_index) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + const char *dwo_name = objfile->name; + bfd *abfd = objfile->obfd; + struct dwo_sections *sections = &reader->dwo_file->sections; + gdb_byte *info_ptr; + ULONGEST str_offset; + + dwarf2_read_section (objfile, §ions->str); + dwarf2_read_section (objfile, §ions->str_offsets); + if (sections->str.buffer == NULL) + error (_("DW_FORM_str_index used without .debug_str.dwo section" + " in CU at offset 0x%lx [in module %s]"), + (long) cu->header.offset.sect_off, dwo_name); + if (sections->str_offsets.buffer == NULL) + error (_("DW_FORM_str_index used without .debug_str_offsets.dwo section" + " in CU at offset 0x%lx [in module %s]"), + (long) cu->header.offset.sect_off, dwo_name); + if (str_index * cu->header.offset_size >= sections->str_offsets.size) + error (_("DW_FORM_str_index pointing outside of .debug_str_offsets.dwo" + " section in CU at offset 0x%lx [in module %s]"), + (long) cu->header.offset.sect_off, dwo_name); + info_ptr = (sections->str_offsets.buffer + + str_index * cu->header.offset_size); + if (cu->header.offset_size == 4) + str_offset = bfd_get_32 (abfd, info_ptr); + else + str_offset = bfd_get_64 (abfd, info_ptr); + if (str_offset >= sections->str.size) + error (_("Offset from DW_FORM_str_index pointing outside of" + " .debug_str.dwo section in CU at offset 0x%lx [in module %s]"), + (long) cu->header.offset.sect_off, dwo_name); + return (char *) (sections->str.buffer + str_offset); } /* Return a pointer to just past the end of an LEB128 number in BUF. */ @@ -10378,6 +12294,22 @@ skip_leb128 (bfd *abfd, gdb_byte *buf) } } +/* Return the length of an LEB128 number in BUF. */ + +static int +leb128_size (const gdb_byte *buf) +{ + const gdb_byte *begin = buf; + gdb_byte byte; + + while (1) + { + byte = *buf++; + if ((byte & 128) == 0) + return buf - begin; + } +} + static void set_cu_language (unsigned int lang, struct dwarf2_cu *cu) { @@ -10399,6 +12331,9 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu) case DW_LANG_Fortran95: cu->language = language_fortran; break; + case DW_LANG_Go: + cu->language = language_go; + break; case DW_LANG_Mips_Assembler: cu->language = language_asm; break; @@ -10432,22 +12367,24 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu) static struct attribute * dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu) { - unsigned int i; - struct attribute *spec = NULL; - - for (i = 0; i < die->num_attrs; ++i) + for (;;) { - if (die->attrs[i].name == name) - return &die->attrs[i]; - if (die->attrs[i].name == DW_AT_specification - || die->attrs[i].name == DW_AT_abstract_origin) - spec = &die->attrs[i]; - } + unsigned int i; + struct attribute *spec = NULL; + + for (i = 0; i < die->num_attrs; ++i) + { + if (die->attrs[i].name == name) + return &die->attrs[i]; + if (die->attrs[i].name == DW_AT_specification + || die->attrs[i].name == DW_AT_abstract_origin) + spec = &die->attrs[i]; + } + + if (!spec) + break; - if (spec) - { die = follow_die_ref (die, spec, &cu); - return dwarf2_attr (die, name, cu); } return NULL; @@ -10600,16 +12537,15 @@ add_file_name (struct line_header *lh, } /* Read the statement program header starting at OFFSET in - .debug_line, according to the endianness of ABFD. Return a pointer + .debug_line, or .debug_line.dwo. Return a pointer to a struct line_header, allocated using xmalloc. NOTE: the strings in the include directory and file name tables of - the returned object point into debug_line_buffer, and must not be - freed. */ + the returned object point into the dwarf line section buffer, + and must not be freed. */ static struct line_header * -dwarf_decode_line_header (unsigned int offset, bfd *abfd, - struct dwarf2_cu *cu) +dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu) { struct cleanup *back_to; struct line_header *lh; @@ -10617,17 +12553,33 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, unsigned int bytes_read, offset_size; int i; char *cur_dir, *cur_file; + struct dwarf2_section_info *section; + bfd *abfd; + + /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the + DWO file. */ + if (cu->dwo_unit && cu->per_cu->is_debug_types) + section = &cu->dwo_unit->dwo_file->sections.line; + else + section = &dwarf2_per_objfile->line; - dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->line); - if (dwarf2_per_objfile->line.buffer == NULL) + dwarf2_read_section (dwarf2_per_objfile->objfile, section); + if (section->buffer == NULL) { - complaint (&symfile_complaints, _("missing .debug_line section")); + if (cu->dwo_unit && cu->per_cu->is_debug_types) + complaint (&symfile_complaints, _("missing .debug_line.dwo section")); + else + complaint (&symfile_complaints, _("missing .debug_line section")); return 0; } + /* We can't do this until we know the section is non-empty. + Only then do we know we have such a section. */ + abfd = section->asection->owner; + /* Make sure that at least there's room for the total_length field. That could be 12 bytes long, but we're just going to fudge that. */ - if (offset + 4 >= dwarf2_per_objfile->line.size) + if (offset + 4 >= section->size) { dwarf2_statement_list_fits_in_line_number_section_complaint (); return 0; @@ -10638,15 +12590,14 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, back_to = make_cleanup ((make_cleanup_ftype *) free_line_header, (void *) lh); - line_ptr = dwarf2_per_objfile->line.buffer + offset; + line_ptr = section->buffer + offset; /* Read in the header. */ lh->total_length = read_checked_initial_length_and_offset (abfd, line_ptr, &cu->header, &bytes_read, &offset_size); line_ptr += bytes_read; - if (line_ptr + lh->total_length > (dwarf2_per_objfile->line.buffer - + dwarf2_per_objfile->line.size)) + if (line_ptr + lh->total_length > (section->buffer + section->size)) { dwarf2_statement_list_fits_in_line_number_section_complaint (); return 0; @@ -10718,8 +12669,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, line_ptr += bytes_read; lh->statement_program_start = line_ptr; - if (line_ptr > (dwarf2_per_objfile->line.buffer - + dwarf2_per_objfile->line.size)) + if (line_ptr > (section->buffer + section->size)) complaint (&symfile_complaints, _("line number info header doesn't " "fit in `.debug_line' section")); @@ -10728,52 +12678,6 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd, return lh; } -/* This function exists to work around a bug in certain compilers - (particularly GCC 2.95), in which the first line number marker of a - function does not show up until after the prologue, right before - the second line number marker. This function shifts ADDRESS down - to the beginning of the function if necessary, and is called on - addresses passed to record_line. */ - -static CORE_ADDR -check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu) -{ - struct function_range *fn; - - /* Find the function_range containing address. */ - if (!cu->first_fn) - return address; - - if (!cu->cached_fn) - cu->cached_fn = cu->first_fn; - - fn = cu->cached_fn; - while (fn) - if (fn->lowpc <= address && fn->highpc > address) - goto found; - else - fn = fn->next; - - fn = cu->first_fn; - while (fn && fn != cu->cached_fn) - if (fn->lowpc <= address && fn->highpc > address) - goto found; - else - fn = fn->next; - - return address; - - found: - if (fn->seen_line) - return address; - if (address != fn->lowpc) - complaint (&symfile_complaints, - _("misplaced first line number at 0x%lx for '%s'"), - (unsigned long) address, fn->name); - fn->seen_line = 1; - return fn->lowpc; -} - /* Subroutine of dwarf_decode_lines to simplify it. Return the file name of the psymtab for included file FILE_INDEX in line header LH of PST. @@ -10861,31 +12765,12 @@ noop_record_line (struct subfile *subfile, int line, CORE_ADDR pc) return; } -/* Decode the Line Number Program (LNP) for the given line_header - structure and CU. The actual information extracted and the type - of structures created from the LNP depends on the value of PST. - - 1. If PST is NULL, then this procedure uses the data from the program - to create all necessary symbol tables, and their linetables. - - 2. If PST is not NULL, this procedure reads the program to determine - the list of files included by the unit represented by PST, and - builds all the associated partial symbol tables. - - COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown. - It is used for relative paths in the line table. - NOTE: When processing partial symtabs (pst != NULL), - comp_dir == pst->dirname. - - NOTE: It is important that psymtabs have the same file name (via strcmp) - as the corresponding symtab. Since COMP_DIR is not used in the name of the - symtab we don't use it in the name of the psymtabs we create. - E.g. expand_line_sal requires this when finding psymtabs to expand. - A good testcase for this is mb-inline.exp. */ +/* Subroutine of dwarf_decode_lines to simplify it. + Process the line number information in LH. */ static void -dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd, - struct dwarf2_cu *cu, struct partial_symtab *pst) +dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir, + struct dwarf2_cu *cu, struct partial_symtab *pst) { gdb_byte *line_ptr, *extended_end; gdb_byte *line_end; @@ -10893,9 +12778,10 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd, unsigned char op_code, extended_op, adj_opcode; CORE_ADDR baseaddr; struct objfile *objfile = cu->objfile; + bfd *abfd = objfile->obfd; struct gdbarch *gdbarch = get_objfile_arch (objfile); const int decode_for_pst_p = (pst != NULL); - struct subfile *last_subfile = NULL, *first_subfile = current_subfile; + struct subfile *last_subfile = NULL; void (*p_record_line) (struct subfile *subfile, int line, CORE_ADDR pc) = record_line; @@ -10971,8 +12857,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd, last_subfile = current_subfile; } /* Append row to matrix using current values. */ - addr = check_cu_functions (address, cu); - addr = gdbarch_addr_bits_remove (gdbarch, addr); + addr = gdbarch_addr_bits_remove (gdbarch, address); (*p_record_line) (current_subfile, line, addr); } } @@ -11007,7 +12892,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd, complaint (&symfile_complaints, _(".debug_line address at offset 0x%lx is 0 " "[in module %s]"), - line_offset, cu->objfile->name); + line_offset, objfile->name); p_record_line = noop_record_line; } @@ -11070,8 +12955,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd, (*p_record_line) (last_subfile, 0, addr); last_subfile = current_subfile; } - addr = check_cu_functions (address, cu); - addr = gdbarch_addr_bits_remove (gdbarch, addr); + addr = gdbarch_addr_bits_remove (gdbarch, address); (*p_record_line) (current_subfile, line, addr); } } @@ -11175,6 +13059,41 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd, } } } +} + +/* Decode the Line Number Program (LNP) for the given line_header + structure and CU. The actual information extracted and the type + of structures created from the LNP depends on the value of PST. + + 1. If PST is NULL, then this procedure uses the data from the program + to create all necessary symbol tables, and their linetables. + + 2. If PST is not NULL, this procedure reads the program to determine + the list of files included by the unit represented by PST, and + builds all the associated partial symbol tables. + + COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown. + It is used for relative paths in the line table. + NOTE: When processing partial symtabs (pst != NULL), + comp_dir == pst->dirname. + + NOTE: It is important that psymtabs have the same file name (via strcmp) + as the corresponding symtab. Since COMP_DIR is not used in the name of the + symtab we don't use it in the name of the psymtabs we create. + E.g. expand_line_sal requires this when finding psymtabs to expand. + A good testcase for this is mb-inline.exp. */ + +static void +dwarf_decode_lines (struct line_header *lh, const char *comp_dir, + struct dwarf2_cu *cu, struct partial_symtab *pst, + int want_line_info) +{ + struct objfile *objfile = cu->objfile; + const int decode_for_pst_p = (pst != NULL); + struct subfile *first_subfile = current_subfile; + + if (want_line_info) + dwarf_decode_lines_1 (lh, comp_dir, cu, pst); if (decode_for_pst_p) { @@ -11196,13 +13115,12 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd, /* Make sure a symtab is created for every file, even files which contain only variables (i.e. no code with associated line numbers). */ - int i; - struct file_entry *fe; for (i = 0; i < lh->num_file_names; i++) { char *dir = NULL; + struct file_entry *fe; fe = &lh->file_names[i]; if (fe->dir_index) @@ -11217,7 +13135,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd, if (current_subfile->symtab == NULL) current_subfile->symtab = allocate_symtab (current_subfile->name, - cu->objfile); + objfile); fe->symtab = current_subfile->symtab; } } @@ -11301,17 +13219,24 @@ var_decode_location (struct attribute *attr, struct symbol *sym, /* Handle one degenerate form of location expression specially, to preserve GDB's previous behavior when section offsets are - specified. If this is just a DW_OP_addr then mark this symbol - as LOC_STATIC. */ + specified. If this is just a DW_OP_addr or DW_OP_GNU_addr_index + then mark this symbol as LOC_STATIC. */ if (attr_form_is_block (attr) - && DW_BLOCK (attr)->size == 1 + cu_header->addr_size - && DW_BLOCK (attr)->data[0] == DW_OP_addr) + && ((DW_BLOCK (attr)->data[0] == DW_OP_addr + && DW_BLOCK (attr)->size == 1 + cu_header->addr_size) + || (DW_BLOCK (attr)->data[0] == DW_OP_GNU_addr_index + && (DW_BLOCK (attr)->size + == 1 + leb128_size (&DW_BLOCK (attr)->data[1]))))) { unsigned int dummy; - SYMBOL_VALUE_ADDRESS (sym) = - read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy); + if (DW_BLOCK (attr)->data[0] == DW_OP_addr) + SYMBOL_VALUE_ADDRESS (sym) = + read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy); + else + SYMBOL_VALUE_ADDRESS (sym) = + read_addr_index_from_leb128 (cu, DW_BLOCK (attr)->data + 1, &dummy); SYMBOL_CLASS (sym) = LOC_STATIC; fixup_symbol_section (sym, objfile); SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets, @@ -11457,8 +13382,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, 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. */ + list_to_add = cu->list_in_scope; break; case DW_TAG_template_value_param: suppress_add = 1; @@ -11689,7 +13613,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, namespaces based on the demangled name. */ if (!processing_has_namespace_info && cu->language == language_cplus) - cp_scan_for_anonymous_namespaces (sym); + cp_scan_for_anonymous_namespaces (sym, objfile); } return (sym); } @@ -11713,7 +13637,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu) static gdb_byte * dwarf2_const_value_data (struct attribute *attr, struct type *type, const char *name, struct obstack *obstack, - struct dwarf2_cu *cu, long *value, int bits) + struct dwarf2_cu *cu, LONGEST *value, int bits) { struct objfile *objfile = cu->objfile; enum bfd_endian byte_order = bfd_big_endian (objfile->obfd) ? @@ -11747,7 +13671,7 @@ static void dwarf2_const_value_attr (struct attribute *attr, struct type *type, const char *name, struct obstack *obstack, struct dwarf2_cu *cu, - long *value, gdb_byte **bytes, + LONGEST *value, gdb_byte **bytes, struct dwarf2_locexpr_baton **baton) { struct objfile *objfile = cu->objfile; @@ -11763,6 +13687,7 @@ dwarf2_const_value_attr (struct attribute *attr, struct type *type, switch (attr->form) { case DW_FORM_addr: + case DW_FORM_GNU_addr_index: { gdb_byte *data; @@ -11790,6 +13715,7 @@ dwarf2_const_value_attr (struct attribute *attr, struct type *type, break; case DW_FORM_string: case DW_FORM_strp: + case DW_FORM_GNU_str_index: /* DW_STRING is already allocated on the objfile obstack, point directly to it. */ *bytes = (gdb_byte *) DW_STRING (attr); @@ -11854,7 +13780,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym, { struct objfile *objfile = cu->objfile; struct comp_unit_head *cu_header = &cu->header; - long value; + LONGEST value; gdb_byte *bytes; struct dwarf2_locexpr_baton *baton; @@ -11971,38 +13897,44 @@ static struct type * lookup_die_type (struct die_info *die, struct attribute *attr, struct dwarf2_cu *cu) { + struct objfile *objfile = cu->objfile; struct type *this_type; /* First see if we have it cached. */ if (is_ref_attr (attr)) { - unsigned int offset = dwarf2_get_ref_die_offset (attr); + sect_offset offset = dwarf2_get_ref_die_offset (attr); this_type = get_die_type_at_offset (offset, cu->per_cu); } else if (attr->form == DW_FORM_ref_sig8) { struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr); - struct dwarf2_cu *sig_cu; - unsigned int offset; /* 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]"), - die->offset, cu->objfile->name); + die->offset.sect_off, objfile->name); - gdb_assert (sig_type->per_cu.debug_type_section); - offset = sig_type->per_cu.offset + sig_type->type_offset; - this_type = get_die_type_at_offset (offset, &sig_type->per_cu); + gdb_assert (sig_type->per_cu.is_debug_types); + /* If we haven't filled in type_offset_in_section yet, then we + haven't read the type in yet. */ + this_type = NULL; + if (sig_type->type_offset_in_section.sect_off != 0) + { + this_type = + get_die_type_at_offset (sig_type->type_offset_in_section, + &sig_type->per_cu); + } } else { dump_die_for_error (die); error (_("Dwarf Error: Bad type attribute %s [in module %s]"), - dwarf_attr_name (attr->name), cu->objfile->name); + dwarf_attr_name (attr->name), objfile->name); } /* If not cached we need to read it in. */ @@ -12013,9 +13945,12 @@ lookup_die_type (struct die_info *die, struct attribute *attr, struct dwarf2_cu *type_cu = cu; type_die = follow_die_ref_or_sig (die, attr, &type_cu); - /* If the type is cached, we should have found it above. */ - gdb_assert (get_die_type (type_die, type_cu) == NULL); - this_type = read_type_die_1 (type_die, type_cu); + /* If we found the type now, it's probably because the type came + from an inter-CU reference and the type's CU got expanded before + ours. */ + this_type = get_die_type (type_die, type_cu); + if (this_type == NULL) + this_type = read_type_die_1 (type_die, type_cu); } /* If we still don't have a type use an error marker. */ @@ -12026,14 +13961,14 @@ lookup_die_type (struct die_info *die, struct attribute *attr, /* read_type_die already issued a complaint. */ message = xstrprintf (_(""), - cu->objfile->name, - cu->header.offset, - die->offset); - saved = obstack_copy0 (&cu->objfile->objfile_obstack, + objfile->name, + cu->header.offset.sect_off, + die->offset.sect_off); + saved = obstack_copy0 (&objfile->objfile_obstack, message, strlen (message)); xfree (message); - this_type = init_type (TYPE_CODE_ERROR, 0, 0, saved, cu->objfile); + this_type = init_type (TYPE_CODE_ERROR, 0, 0, saved, objfile); } return this_type; @@ -12207,6 +14142,42 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu) return NULL; } +/* GCC might emit a nameless typedef that has a linkage name. Determine the + prefix part in such case. See + http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */ + +static char * +anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu) +{ + struct attribute *attr; + char *base; + + if (die->tag != DW_TAG_class_type && die->tag != DW_TAG_interface_type + && die->tag != DW_TAG_structure_type && die->tag != DW_TAG_union_type) + return NULL; + + attr = dwarf2_attr (die, DW_AT_name, cu); + if (attr != NULL && DW_STRING (attr) != NULL) + return NULL; + + attr = dwarf2_attr (die, DW_AT_linkage_name, cu); + if (attr == NULL) + attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); + if (attr == NULL || DW_STRING (attr) == NULL) + return NULL; + + /* dwarf2_name had to be already called. */ + gdb_assert (DW_STRING_IS_CANONICAL (attr)); + + /* Strip the base name, keep any leading namespaces/classes. */ + base = strrchr (DW_STRING (attr), ':'); + if (base == NULL || base == DW_STRING (attr) || base[-1] != ':') + return ""; + + return obsavestring (DW_STRING (attr), &base[-1] - DW_STRING (attr), + &cu->objfile->objfile_obstack); +} + /* Return the name of the namespace/class that DIE is defined within, or "" if we can't tell. The caller should not xfree the result. @@ -12222,17 +14193,22 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu) then determine_prefix on foo's die will return "N::C". */ -static char * +static const char * determine_prefix (struct die_info *die, struct dwarf2_cu *cu) { struct die_info *parent, *spec_die; struct dwarf2_cu *spec_cu; struct type *parent_type; + char *retval; if (cu->language != language_cplus && cu->language != language_java && cu->language != language_fortran) return ""; + retval = anonymous_struct_prefix (die, cu); + if (retval) + return retval; + /* We have to be careful in the presence of DW_AT_specification. For example, with GCC 3.4, given the code @@ -12334,6 +14310,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu) So it does not need a prefix. */ return ""; case DW_TAG_compile_unit: + case DW_TAG_partial_unit: /* gcc-4.5 -gdwarf-4 can drop the enclosing namespace. Cope. */ if (cu->language == language_cplus && !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types) @@ -12454,6 +14431,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) switch (die->tag) { case DW_TAG_compile_unit: + case DW_TAG_partial_unit: /* Compilation units have a DW_AT_name that is a filename, not a source language identifier. */ case DW_TAG_enumeration_type: @@ -12487,7 +14465,8 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) if (die->tag == DW_TAG_class_type) return dwarf2_name (die, cu); } - while (die->tag != DW_TAG_compile_unit); + while (die->tag != DW_TAG_compile_unit + && die->tag != DW_TAG_partial_unit); } break; @@ -12524,12 +14503,21 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) if (demangled) { + char *base; + /* FIXME: we already did this for the partial symbol... */ - DW_STRING (attr) - = obsavestring (demangled, strlen (demangled), - &cu->objfile->objfile_obstack); + DW_STRING (attr) = obsavestring (demangled, strlen (demangled), + &cu->objfile->objfile_obstack); DW_STRING_IS_CANONICAL (attr) = 1; xfree (demangled); + + /* Strip any leading namespaces/classes, keep only the base name. + DW_AT_name for named DIEs does not contain the prefixes. */ + base = strrchr (DW_STRING (attr), ':'); + if (base && base > DW_STRING (attr) && base[-1] == ':') + return &base[1]; + else + return DW_STRING (attr); } } break; @@ -12566,841 +14554,51 @@ dwarf2_extension (struct die_info *die, struct dwarf2_cu **ext_cu) /* Convert a DIE tag into its string name. */ -static char * -dwarf_tag_name (unsigned tag) -{ - switch (tag) - { - case DW_TAG_padding: - return "DW_TAG_padding"; - case DW_TAG_array_type: - return "DW_TAG_array_type"; - case DW_TAG_class_type: - return "DW_TAG_class_type"; - case DW_TAG_entry_point: - return "DW_TAG_entry_point"; - case DW_TAG_enumeration_type: - return "DW_TAG_enumeration_type"; - case DW_TAG_formal_parameter: - return "DW_TAG_formal_parameter"; - case DW_TAG_imported_declaration: - return "DW_TAG_imported_declaration"; - case DW_TAG_label: - return "DW_TAG_label"; - case DW_TAG_lexical_block: - return "DW_TAG_lexical_block"; - case DW_TAG_member: - return "DW_TAG_member"; - case DW_TAG_pointer_type: - return "DW_TAG_pointer_type"; - case DW_TAG_reference_type: - return "DW_TAG_reference_type"; - case DW_TAG_compile_unit: - return "DW_TAG_compile_unit"; - case DW_TAG_string_type: - return "DW_TAG_string_type"; - case DW_TAG_structure_type: - return "DW_TAG_structure_type"; - case DW_TAG_subroutine_type: - return "DW_TAG_subroutine_type"; - case DW_TAG_typedef: - return "DW_TAG_typedef"; - case DW_TAG_union_type: - return "DW_TAG_union_type"; - case DW_TAG_unspecified_parameters: - return "DW_TAG_unspecified_parameters"; - case DW_TAG_variant: - return "DW_TAG_variant"; - case DW_TAG_common_block: - return "DW_TAG_common_block"; - case DW_TAG_common_inclusion: - return "DW_TAG_common_inclusion"; - case DW_TAG_inheritance: - return "DW_TAG_inheritance"; - case DW_TAG_inlined_subroutine: - return "DW_TAG_inlined_subroutine"; - case DW_TAG_module: - return "DW_TAG_module"; - case DW_TAG_ptr_to_member_type: - return "DW_TAG_ptr_to_member_type"; - case DW_TAG_set_type: - return "DW_TAG_set_type"; - case DW_TAG_subrange_type: - return "DW_TAG_subrange_type"; - case DW_TAG_with_stmt: - return "DW_TAG_with_stmt"; - case DW_TAG_access_declaration: - return "DW_TAG_access_declaration"; - case DW_TAG_base_type: - return "DW_TAG_base_type"; - case DW_TAG_catch_block: - return "DW_TAG_catch_block"; - case DW_TAG_const_type: - return "DW_TAG_const_type"; - case DW_TAG_constant: - return "DW_TAG_constant"; - case DW_TAG_enumerator: - return "DW_TAG_enumerator"; - case DW_TAG_file_type: - return "DW_TAG_file_type"; - case DW_TAG_friend: - return "DW_TAG_friend"; - case DW_TAG_namelist: - return "DW_TAG_namelist"; - case DW_TAG_namelist_item: - return "DW_TAG_namelist_item"; - case DW_TAG_packed_type: - return "DW_TAG_packed_type"; - case DW_TAG_subprogram: - return "DW_TAG_subprogram"; - case DW_TAG_template_type_param: - return "DW_TAG_template_type_param"; - case DW_TAG_template_value_param: - return "DW_TAG_template_value_param"; - case DW_TAG_thrown_type: - return "DW_TAG_thrown_type"; - case DW_TAG_try_block: - return "DW_TAG_try_block"; - case DW_TAG_variant_part: - return "DW_TAG_variant_part"; - case DW_TAG_variable: - return "DW_TAG_variable"; - case DW_TAG_volatile_type: - return "DW_TAG_volatile_type"; - case DW_TAG_dwarf_procedure: - return "DW_TAG_dwarf_procedure"; - case DW_TAG_restrict_type: - return "DW_TAG_restrict_type"; - case DW_TAG_interface_type: - return "DW_TAG_interface_type"; - case DW_TAG_namespace: - return "DW_TAG_namespace"; - case DW_TAG_imported_module: - return "DW_TAG_imported_module"; - case DW_TAG_unspecified_type: - return "DW_TAG_unspecified_type"; - case DW_TAG_partial_unit: - return "DW_TAG_partial_unit"; - case DW_TAG_imported_unit: - return "DW_TAG_imported_unit"; - case DW_TAG_condition: - 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: - return "DW_TAG_HP_array_descriptor"; - case DW_TAG_format_label: - return "DW_TAG_format_label"; - case DW_TAG_function_template: - return "DW_TAG_function_template"; - case DW_TAG_class_template: - return "DW_TAG_class_template"; - case DW_TAG_GNU_BINCL: - return "DW_TAG_GNU_BINCL"; - case DW_TAG_GNU_EINCL: - return "DW_TAG_GNU_EINCL"; - case DW_TAG_upc_shared_type: - return "DW_TAG_upc_shared_type"; - case DW_TAG_upc_strict_type: - return "DW_TAG_upc_strict_type"; - case DW_TAG_upc_relaxed_type: - return "DW_TAG_upc_relaxed_type"; - case DW_TAG_PGI_kanji_type: - return "DW_TAG_PGI_kanji_type"; - case DW_TAG_PGI_interface_block: - return "DW_TAG_PGI_interface_block"; - default: - return "DW_TAG_"; - } -} - -/* Convert a DWARF attribute code into its string name. */ - -static char * -dwarf_attr_name (unsigned attr) -{ - switch (attr) - { - case DW_AT_sibling: - return "DW_AT_sibling"; - case DW_AT_location: - return "DW_AT_location"; - case DW_AT_name: - return "DW_AT_name"; - case DW_AT_ordering: - return "DW_AT_ordering"; - case DW_AT_subscr_data: - return "DW_AT_subscr_data"; - case DW_AT_byte_size: - return "DW_AT_byte_size"; - case DW_AT_bit_offset: - return "DW_AT_bit_offset"; - case DW_AT_bit_size: - return "DW_AT_bit_size"; - case DW_AT_element_list: - return "DW_AT_element_list"; - case DW_AT_stmt_list: - return "DW_AT_stmt_list"; - case DW_AT_low_pc: - return "DW_AT_low_pc"; - case DW_AT_high_pc: - return "DW_AT_high_pc"; - case DW_AT_language: - return "DW_AT_language"; - case DW_AT_member: - return "DW_AT_member"; - case DW_AT_discr: - return "DW_AT_discr"; - case DW_AT_discr_value: - return "DW_AT_discr_value"; - case DW_AT_visibility: - return "DW_AT_visibility"; - case DW_AT_import: - return "DW_AT_import"; - case DW_AT_string_length: - return "DW_AT_string_length"; - case DW_AT_common_reference: - return "DW_AT_common_reference"; - case DW_AT_comp_dir: - return "DW_AT_comp_dir"; - case DW_AT_const_value: - return "DW_AT_const_value"; - case DW_AT_containing_type: - return "DW_AT_containing_type"; - case DW_AT_default_value: - return "DW_AT_default_value"; - case DW_AT_inline: - return "DW_AT_inline"; - case DW_AT_is_optional: - return "DW_AT_is_optional"; - case DW_AT_lower_bound: - return "DW_AT_lower_bound"; - case DW_AT_producer: - return "DW_AT_producer"; - case DW_AT_prototyped: - return "DW_AT_prototyped"; - case DW_AT_return_addr: - return "DW_AT_return_addr"; - case DW_AT_start_scope: - return "DW_AT_start_scope"; - case DW_AT_bit_stride: - return "DW_AT_bit_stride"; - case DW_AT_upper_bound: - return "DW_AT_upper_bound"; - case DW_AT_abstract_origin: - return "DW_AT_abstract_origin"; - case DW_AT_accessibility: - return "DW_AT_accessibility"; - case DW_AT_address_class: - return "DW_AT_address_class"; - case DW_AT_artificial: - return "DW_AT_artificial"; - case DW_AT_base_types: - return "DW_AT_base_types"; - case DW_AT_calling_convention: - return "DW_AT_calling_convention"; - case DW_AT_count: - return "DW_AT_count"; - case DW_AT_data_member_location: - return "DW_AT_data_member_location"; - case DW_AT_decl_column: - return "DW_AT_decl_column"; - case DW_AT_decl_file: - return "DW_AT_decl_file"; - case DW_AT_decl_line: - return "DW_AT_decl_line"; - case DW_AT_declaration: - return "DW_AT_declaration"; - case DW_AT_discr_list: - return "DW_AT_discr_list"; - case DW_AT_encoding: - return "DW_AT_encoding"; - case DW_AT_external: - return "DW_AT_external"; - case DW_AT_frame_base: - return "DW_AT_frame_base"; - case DW_AT_friend: - return "DW_AT_friend"; - case DW_AT_identifier_case: - return "DW_AT_identifier_case"; - case DW_AT_macro_info: - return "DW_AT_macro_info"; - case DW_AT_namelist_items: - return "DW_AT_namelist_items"; - case DW_AT_priority: - return "DW_AT_priority"; - case DW_AT_segment: - return "DW_AT_segment"; - case DW_AT_specification: - return "DW_AT_specification"; - case DW_AT_static_link: - return "DW_AT_static_link"; - case DW_AT_type: - return "DW_AT_type"; - case DW_AT_use_location: - return "DW_AT_use_location"; - case DW_AT_variable_parameter: - return "DW_AT_variable_parameter"; - case DW_AT_virtuality: - return "DW_AT_virtuality"; - case DW_AT_vtable_elem_location: - return "DW_AT_vtable_elem_location"; - /* DWARF 3 values. */ - case DW_AT_allocated: - return "DW_AT_allocated"; - case DW_AT_associated: - return "DW_AT_associated"; - case DW_AT_data_location: - return "DW_AT_data_location"; - case DW_AT_byte_stride: - return "DW_AT_byte_stride"; - case DW_AT_entry_pc: - return "DW_AT_entry_pc"; - case DW_AT_use_UTF8: - return "DW_AT_use_UTF8"; - case DW_AT_extension: - return "DW_AT_extension"; - case DW_AT_ranges: - return "DW_AT_ranges"; - case DW_AT_trampoline: - return "DW_AT_trampoline"; - case DW_AT_call_column: - return "DW_AT_call_column"; - case DW_AT_call_file: - return "DW_AT_call_file"; - case DW_AT_call_line: - return "DW_AT_call_line"; - case DW_AT_description: - return "DW_AT_description"; - case DW_AT_binary_scale: - return "DW_AT_binary_scale"; - case DW_AT_decimal_scale: - return "DW_AT_decimal_scale"; - case DW_AT_small: - return "DW_AT_small"; - case DW_AT_decimal_sign: - return "DW_AT_decimal_sign"; - case DW_AT_digit_count: - return "DW_AT_digit_count"; - case DW_AT_picture_string: - return "DW_AT_picture_string"; - case DW_AT_mutable: - return "DW_AT_mutable"; - case DW_AT_threads_scaled: - return "DW_AT_threads_scaled"; - case DW_AT_explicit: - return "DW_AT_explicit"; - case DW_AT_object_pointer: - return "DW_AT_object_pointer"; - case DW_AT_endianity: - return "DW_AT_endianity"; - case DW_AT_elemental: - return "DW_AT_elemental"; - case DW_AT_pure: - return "DW_AT_pure"; - case DW_AT_recursive: - return "DW_AT_recursive"; - /* DWARF 4 values. */ - case DW_AT_signature: - return "DW_AT_signature"; - case DW_AT_linkage_name: - return "DW_AT_linkage_name"; - /* SGI/MIPS extensions. */ -#ifdef MIPS /* collides with DW_AT_HP_block_index */ - case DW_AT_MIPS_fde: - return "DW_AT_MIPS_fde"; -#endif - case DW_AT_MIPS_loop_begin: - return "DW_AT_MIPS_loop_begin"; - case DW_AT_MIPS_tail_loop_begin: - return "DW_AT_MIPS_tail_loop_begin"; - case DW_AT_MIPS_epilog_begin: - return "DW_AT_MIPS_epilog_begin"; - case DW_AT_MIPS_loop_unroll_factor: - return "DW_AT_MIPS_loop_unroll_factor"; - case DW_AT_MIPS_software_pipeline_depth: - return "DW_AT_MIPS_software_pipeline_depth"; - case DW_AT_MIPS_linkage_name: - return "DW_AT_MIPS_linkage_name"; - case DW_AT_MIPS_stride: - return "DW_AT_MIPS_stride"; - case DW_AT_MIPS_abstract_name: - return "DW_AT_MIPS_abstract_name"; - case DW_AT_MIPS_clone_origin: - return "DW_AT_MIPS_clone_origin"; - case DW_AT_MIPS_has_inlines: - return "DW_AT_MIPS_has_inlines"; - /* HP extensions. */ -#ifndef MIPS /* collides with DW_AT_MIPS_fde */ - case DW_AT_HP_block_index: - return "DW_AT_HP_block_index"; -#endif - case DW_AT_HP_unmodifiable: - return "DW_AT_HP_unmodifiable"; - case DW_AT_HP_actuals_stmt_list: - return "DW_AT_HP_actuals_stmt_list"; - case DW_AT_HP_proc_per_section: - return "DW_AT_HP_proc_per_section"; - case DW_AT_HP_raw_data_ptr: - return "DW_AT_HP_raw_data_ptr"; - case DW_AT_HP_pass_by_reference: - return "DW_AT_HP_pass_by_reference"; - case DW_AT_HP_opt_level: - return "DW_AT_HP_opt_level"; - case DW_AT_HP_prof_version_id: - return "DW_AT_HP_prof_version_id"; - case DW_AT_HP_opt_flags: - return "DW_AT_HP_opt_flags"; - case DW_AT_HP_cold_region_low_pc: - return "DW_AT_HP_cold_region_low_pc"; - case DW_AT_HP_cold_region_high_pc: - return "DW_AT_HP_cold_region_high_pc"; - case DW_AT_HP_all_variables_modifiable: - return "DW_AT_HP_all_variables_modifiable"; - case DW_AT_HP_linkage_name: - return "DW_AT_HP_linkage_name"; - case DW_AT_HP_prof_flags: - return "DW_AT_HP_prof_flags"; - /* GNU extensions. */ - case DW_AT_sf_names: - return "DW_AT_sf_names"; - case DW_AT_src_info: - return "DW_AT_src_info"; - case DW_AT_mac_info: - return "DW_AT_mac_info"; - case DW_AT_src_coords: - return "DW_AT_src_coords"; - case DW_AT_body_begin: - return "DW_AT_body_begin"; - case DW_AT_body_end: - return "DW_AT_body_end"; - case DW_AT_GNU_vector: - return "DW_AT_GNU_vector"; - case DW_AT_GNU_odr_signature: - return "DW_AT_GNU_odr_signature"; - /* VMS extensions. */ - case DW_AT_VMS_rtnbeg_pd_address: - return "DW_AT_VMS_rtnbeg_pd_address"; - /* UPC extension. */ - case DW_AT_upc_threads_scaled: - return "DW_AT_upc_threads_scaled"; - /* PGI (STMicroelectronics) extensions. */ - case DW_AT_PGI_lbase: - return "DW_AT_PGI_lbase"; - case DW_AT_PGI_soffset: - return "DW_AT_PGI_soffset"; - case DW_AT_PGI_lstride: - return "DW_AT_PGI_lstride"; - default: - return "DW_AT_"; - } -} - -/* Convert a DWARF value form code into its string name. */ - -static char * -dwarf_form_name (unsigned form) -{ - switch (form) - { - case DW_FORM_addr: - return "DW_FORM_addr"; - case DW_FORM_block2: - return "DW_FORM_block2"; - case DW_FORM_block4: - return "DW_FORM_block4"; - case DW_FORM_data2: - return "DW_FORM_data2"; - case DW_FORM_data4: - return "DW_FORM_data4"; - case DW_FORM_data8: - return "DW_FORM_data8"; - case DW_FORM_string: - return "DW_FORM_string"; - case DW_FORM_block: - return "DW_FORM_block"; - case DW_FORM_block1: - return "DW_FORM_block1"; - case DW_FORM_data1: - return "DW_FORM_data1"; - case DW_FORM_flag: - return "DW_FORM_flag"; - case DW_FORM_sdata: - return "DW_FORM_sdata"; - case DW_FORM_strp: - return "DW_FORM_strp"; - case DW_FORM_udata: - return "DW_FORM_udata"; - case DW_FORM_ref_addr: - return "DW_FORM_ref_addr"; - case DW_FORM_ref1: - return "DW_FORM_ref1"; - case DW_FORM_ref2: - return "DW_FORM_ref2"; - case DW_FORM_ref4: - return "DW_FORM_ref4"; - case DW_FORM_ref8: - return "DW_FORM_ref8"; - case DW_FORM_ref_udata: - return "DW_FORM_ref_udata"; - case DW_FORM_indirect: - return "DW_FORM_indirect"; - 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_ref_sig8: - return "DW_FORM_ref_sig8"; - default: - return "DW_FORM_"; - } -} - -/* Convert a DWARF stack opcode into its string name. */ - -const char * -dwarf_stack_op_name (unsigned op) -{ - switch (op) - { - case DW_OP_addr: - return "DW_OP_addr"; - case DW_OP_deref: - return "DW_OP_deref"; - case DW_OP_const1u: - return "DW_OP_const1u"; - case DW_OP_const1s: - return "DW_OP_const1s"; - case DW_OP_const2u: - return "DW_OP_const2u"; - case DW_OP_const2s: - return "DW_OP_const2s"; - case DW_OP_const4u: - return "DW_OP_const4u"; - case DW_OP_const4s: - return "DW_OP_const4s"; - case DW_OP_const8u: - return "DW_OP_const8u"; - case DW_OP_const8s: - return "DW_OP_const8s"; - case DW_OP_constu: - return "DW_OP_constu"; - case DW_OP_consts: - return "DW_OP_consts"; - case DW_OP_dup: - return "DW_OP_dup"; - case DW_OP_drop: - return "DW_OP_drop"; - case DW_OP_over: - return "DW_OP_over"; - case DW_OP_pick: - return "DW_OP_pick"; - case DW_OP_swap: - return "DW_OP_swap"; - case DW_OP_rot: - return "DW_OP_rot"; - case DW_OP_xderef: - return "DW_OP_xderef"; - case DW_OP_abs: - return "DW_OP_abs"; - case DW_OP_and: - return "DW_OP_and"; - case DW_OP_div: - return "DW_OP_div"; - case DW_OP_minus: - return "DW_OP_minus"; - case DW_OP_mod: - return "DW_OP_mod"; - case DW_OP_mul: - return "DW_OP_mul"; - case DW_OP_neg: - return "DW_OP_neg"; - case DW_OP_not: - return "DW_OP_not"; - case DW_OP_or: - return "DW_OP_or"; - case DW_OP_plus: - return "DW_OP_plus"; - case DW_OP_plus_uconst: - return "DW_OP_plus_uconst"; - case DW_OP_shl: - return "DW_OP_shl"; - case DW_OP_shr: - return "DW_OP_shr"; - case DW_OP_shra: - return "DW_OP_shra"; - case DW_OP_xor: - return "DW_OP_xor"; - case DW_OP_bra: - return "DW_OP_bra"; - case DW_OP_eq: - return "DW_OP_eq"; - case DW_OP_ge: - return "DW_OP_ge"; - case DW_OP_gt: - return "DW_OP_gt"; - case DW_OP_le: - return "DW_OP_le"; - case DW_OP_lt: - return "DW_OP_lt"; - case DW_OP_ne: - return "DW_OP_ne"; - case DW_OP_skip: - return "DW_OP_skip"; - case DW_OP_lit0: - return "DW_OP_lit0"; - case DW_OP_lit1: - return "DW_OP_lit1"; - case DW_OP_lit2: - return "DW_OP_lit2"; - case DW_OP_lit3: - return "DW_OP_lit3"; - case DW_OP_lit4: - return "DW_OP_lit4"; - case DW_OP_lit5: - return "DW_OP_lit5"; - case DW_OP_lit6: - return "DW_OP_lit6"; - case DW_OP_lit7: - return "DW_OP_lit7"; - case DW_OP_lit8: - return "DW_OP_lit8"; - case DW_OP_lit9: - return "DW_OP_lit9"; - case DW_OP_lit10: - return "DW_OP_lit10"; - case DW_OP_lit11: - return "DW_OP_lit11"; - case DW_OP_lit12: - return "DW_OP_lit12"; - case DW_OP_lit13: - return "DW_OP_lit13"; - case DW_OP_lit14: - return "DW_OP_lit14"; - case DW_OP_lit15: - return "DW_OP_lit15"; - case DW_OP_lit16: - return "DW_OP_lit16"; - case DW_OP_lit17: - return "DW_OP_lit17"; - case DW_OP_lit18: - return "DW_OP_lit18"; - case DW_OP_lit19: - return "DW_OP_lit19"; - case DW_OP_lit20: - return "DW_OP_lit20"; - case DW_OP_lit21: - return "DW_OP_lit21"; - case DW_OP_lit22: - return "DW_OP_lit22"; - case DW_OP_lit23: - return "DW_OP_lit23"; - case DW_OP_lit24: - return "DW_OP_lit24"; - case DW_OP_lit25: - return "DW_OP_lit25"; - case DW_OP_lit26: - return "DW_OP_lit26"; - case DW_OP_lit27: - return "DW_OP_lit27"; - case DW_OP_lit28: - return "DW_OP_lit28"; - case DW_OP_lit29: - return "DW_OP_lit29"; - case DW_OP_lit30: - return "DW_OP_lit30"; - case DW_OP_lit31: - return "DW_OP_lit31"; - case DW_OP_reg0: - return "DW_OP_reg0"; - case DW_OP_reg1: - return "DW_OP_reg1"; - case DW_OP_reg2: - return "DW_OP_reg2"; - case DW_OP_reg3: - return "DW_OP_reg3"; - case DW_OP_reg4: - return "DW_OP_reg4"; - case DW_OP_reg5: - return "DW_OP_reg5"; - case DW_OP_reg6: - return "DW_OP_reg6"; - case DW_OP_reg7: - return "DW_OP_reg7"; - case DW_OP_reg8: - return "DW_OP_reg8"; - case DW_OP_reg9: - return "DW_OP_reg9"; - case DW_OP_reg10: - return "DW_OP_reg10"; - case DW_OP_reg11: - return "DW_OP_reg11"; - case DW_OP_reg12: - return "DW_OP_reg12"; - case DW_OP_reg13: - return "DW_OP_reg13"; - case DW_OP_reg14: - return "DW_OP_reg14"; - case DW_OP_reg15: - return "DW_OP_reg15"; - case DW_OP_reg16: - return "DW_OP_reg16"; - case DW_OP_reg17: - return "DW_OP_reg17"; - case DW_OP_reg18: - return "DW_OP_reg18"; - case DW_OP_reg19: - return "DW_OP_reg19"; - case DW_OP_reg20: - return "DW_OP_reg20"; - case DW_OP_reg21: - return "DW_OP_reg21"; - case DW_OP_reg22: - return "DW_OP_reg22"; - case DW_OP_reg23: - return "DW_OP_reg23"; - case DW_OP_reg24: - return "DW_OP_reg24"; - case DW_OP_reg25: - return "DW_OP_reg25"; - case DW_OP_reg26: - return "DW_OP_reg26"; - case DW_OP_reg27: - return "DW_OP_reg27"; - case DW_OP_reg28: - return "DW_OP_reg28"; - case DW_OP_reg29: - return "DW_OP_reg29"; - case DW_OP_reg30: - return "DW_OP_reg30"; - case DW_OP_reg31: - return "DW_OP_reg31"; - case DW_OP_breg0: - return "DW_OP_breg0"; - case DW_OP_breg1: - return "DW_OP_breg1"; - case DW_OP_breg2: - return "DW_OP_breg2"; - case DW_OP_breg3: - return "DW_OP_breg3"; - case DW_OP_breg4: - return "DW_OP_breg4"; - case DW_OP_breg5: - return "DW_OP_breg5"; - case DW_OP_breg6: - return "DW_OP_breg6"; - case DW_OP_breg7: - return "DW_OP_breg7"; - case DW_OP_breg8: - return "DW_OP_breg8"; - case DW_OP_breg9: - return "DW_OP_breg9"; - case DW_OP_breg10: - return "DW_OP_breg10"; - case DW_OP_breg11: - return "DW_OP_breg11"; - case DW_OP_breg12: - return "DW_OP_breg12"; - case DW_OP_breg13: - return "DW_OP_breg13"; - case DW_OP_breg14: - return "DW_OP_breg14"; - case DW_OP_breg15: - return "DW_OP_breg15"; - case DW_OP_breg16: - return "DW_OP_breg16"; - case DW_OP_breg17: - return "DW_OP_breg17"; - case DW_OP_breg18: - return "DW_OP_breg18"; - case DW_OP_breg19: - return "DW_OP_breg19"; - case DW_OP_breg20: - return "DW_OP_breg20"; - case DW_OP_breg21: - return "DW_OP_breg21"; - case DW_OP_breg22: - return "DW_OP_breg22"; - case DW_OP_breg23: - return "DW_OP_breg23"; - case DW_OP_breg24: - return "DW_OP_breg24"; - case DW_OP_breg25: - return "DW_OP_breg25"; - case DW_OP_breg26: - return "DW_OP_breg26"; - case DW_OP_breg27: - return "DW_OP_breg27"; - case DW_OP_breg28: - return "DW_OP_breg28"; - case DW_OP_breg29: - return "DW_OP_breg29"; - case DW_OP_breg30: - return "DW_OP_breg30"; - case DW_OP_breg31: - return "DW_OP_breg31"; - case DW_OP_regx: - return "DW_OP_regx"; - case DW_OP_fbreg: - return "DW_OP_fbreg"; - case DW_OP_bregx: - return "DW_OP_bregx"; - case DW_OP_piece: - return "DW_OP_piece"; - case DW_OP_deref_size: - return "DW_OP_deref_size"; - case DW_OP_xderef_size: - return "DW_OP_xderef_size"; - case DW_OP_nop: - return "DW_OP_nop"; - /* DWARF 3 extensions. */ - case DW_OP_push_object_address: - return "DW_OP_push_object_address"; - case DW_OP_call2: - return "DW_OP_call2"; - case DW_OP_call4: - return "DW_OP_call4"; - case DW_OP_call_ref: - return "DW_OP_call_ref"; - case DW_OP_form_tls_address: - return "DW_OP_form_tls_address"; - case DW_OP_call_frame_cfa: - return "DW_OP_call_frame_cfa"; - case DW_OP_bit_piece: - return "DW_OP_bit_piece"; - /* DWARF 4 extensions. */ - case DW_OP_implicit_value: - return "DW_OP_implicit_value"; - case DW_OP_stack_value: - return "DW_OP_stack_value"; - /* GNU extensions. */ - case DW_OP_GNU_push_tls_address: - return "DW_OP_GNU_push_tls_address"; - case DW_OP_GNU_uninit: - return "DW_OP_GNU_uninit"; - case DW_OP_GNU_implicit_pointer: - return "DW_OP_GNU_implicit_pointer"; - case DW_OP_GNU_entry_value: - return "DW_OP_GNU_entry_value"; - case DW_OP_GNU_const_type: - return "DW_OP_GNU_const_type"; - case DW_OP_GNU_regval_type: - return "DW_OP_GNU_regval_type"; - case DW_OP_GNU_deref_type: - return "DW_OP_GNU_deref_type"; - case DW_OP_GNU_convert: - return "DW_OP_GNU_convert"; - case DW_OP_GNU_reinterpret: - return "DW_OP_GNU_reinterpret"; - default: - return NULL; - } +static const char * +dwarf_tag_name (unsigned tag) +{ + const char *name = get_DW_TAG_name (tag); + + if (name == NULL) + return "DW_TAG_"; + + return name; +} + +/* Convert a DWARF attribute code into its string name. */ + +static const char * +dwarf_attr_name (unsigned attr) +{ + const char *name; + +#ifdef MIPS /* collides with DW_AT_HP_block_index */ + if (attr == DW_AT_MIPS_fde) + return "DW_AT_MIPS_fde"; +#else + if (attr == DW_AT_HP_block_index) + return "DW_AT_HP_block_index"; +#endif + + name = get_DW_AT_name (attr); + + if (name == NULL) + return "DW_AT_"; + + return name; +} + +/* Convert a DWARF value form code into its string name. */ + +static const char * +dwarf_form_name (unsigned form) +{ + const char *name = get_DW_FORM_name (form); + + if (name == NULL) + return "DW_FORM_"; + + return name; } static char * @@ -13414,143 +14612,16 @@ dwarf_bool_name (unsigned mybool) /* Convert a DWARF type code into its string name. */ -static char * +static const char * dwarf_type_encoding_name (unsigned enc) { - switch (enc) - { - case DW_ATE_void: - return "DW_ATE_void"; - case DW_ATE_address: - return "DW_ATE_address"; - case DW_ATE_boolean: - return "DW_ATE_boolean"; - case DW_ATE_complex_float: - return "DW_ATE_complex_float"; - case DW_ATE_float: - return "DW_ATE_float"; - case DW_ATE_signed: - return "DW_ATE_signed"; - case DW_ATE_signed_char: - return "DW_ATE_signed_char"; - case DW_ATE_unsigned: - return "DW_ATE_unsigned"; - case DW_ATE_unsigned_char: - return "DW_ATE_unsigned_char"; - /* DWARF 3. */ - case DW_ATE_imaginary_float: - return "DW_ATE_imaginary_float"; - case DW_ATE_packed_decimal: - return "DW_ATE_packed_decimal"; - case DW_ATE_numeric_string: - return "DW_ATE_numeric_string"; - case DW_ATE_edited: - return "DW_ATE_edited"; - case DW_ATE_signed_fixed: - return "DW_ATE_signed_fixed"; - case DW_ATE_unsigned_fixed: - return "DW_ATE_unsigned_fixed"; - case DW_ATE_decimal_float: - return "DW_ATE_decimal_float"; - /* DWARF 4. */ - case DW_ATE_UTF: - return "DW_ATE_UTF"; - /* HP extensions. */ - case DW_ATE_HP_float80: - return "DW_ATE_HP_float80"; - case DW_ATE_HP_complex_float80: - return "DW_ATE_HP_complex_float80"; - case DW_ATE_HP_float128: - return "DW_ATE_HP_float128"; - case DW_ATE_HP_complex_float128: - return "DW_ATE_HP_complex_float128"; - case DW_ATE_HP_floathpintel: - return "DW_ATE_HP_floathpintel"; - case DW_ATE_HP_imaginary_float80: - return "DW_ATE_HP_imaginary_float80"; - case DW_ATE_HP_imaginary_float128: - return "DW_ATE_HP_imaginary_float128"; - default: - return "DW_ATE_"; - } -} + const char *name = get_DW_ATE_name (enc); -/* Convert a DWARF call frame info operation to its string name. */ + if (name == NULL) + return "DW_ATE_"; -#if 0 -static char * -dwarf_cfi_name (unsigned cfi_opc) -{ - switch (cfi_opc) - { - case DW_CFA_advance_loc: - return "DW_CFA_advance_loc"; - case DW_CFA_offset: - return "DW_CFA_offset"; - case DW_CFA_restore: - return "DW_CFA_restore"; - case DW_CFA_nop: - return "DW_CFA_nop"; - case DW_CFA_set_loc: - return "DW_CFA_set_loc"; - case DW_CFA_advance_loc1: - return "DW_CFA_advance_loc1"; - case DW_CFA_advance_loc2: - return "DW_CFA_advance_loc2"; - case DW_CFA_advance_loc4: - return "DW_CFA_advance_loc4"; - case DW_CFA_offset_extended: - return "DW_CFA_offset_extended"; - case DW_CFA_restore_extended: - return "DW_CFA_restore_extended"; - case DW_CFA_undefined: - return "DW_CFA_undefined"; - case DW_CFA_same_value: - return "DW_CFA_same_value"; - case DW_CFA_register: - return "DW_CFA_register"; - case DW_CFA_remember_state: - return "DW_CFA_remember_state"; - case DW_CFA_restore_state: - return "DW_CFA_restore_state"; - case DW_CFA_def_cfa: - return "DW_CFA_def_cfa"; - case DW_CFA_def_cfa_register: - return "DW_CFA_def_cfa_register"; - case DW_CFA_def_cfa_offset: - return "DW_CFA_def_cfa_offset"; - /* DWARF 3. */ - case DW_CFA_def_cfa_expression: - return "DW_CFA_def_cfa_expression"; - case DW_CFA_expression: - return "DW_CFA_expression"; - case DW_CFA_offset_extended_sf: - return "DW_CFA_offset_extended_sf"; - case DW_CFA_def_cfa_sf: - return "DW_CFA_def_cfa_sf"; - case DW_CFA_def_cfa_offset_sf: - return "DW_CFA_def_cfa_offset_sf"; - case DW_CFA_val_offset: - return "DW_CFA_val_offset"; - case DW_CFA_val_offset_sf: - return "DW_CFA_val_offset_sf"; - case DW_CFA_val_expression: - return "DW_CFA_val_expression"; - /* SGI/MIPS specific. */ - case DW_CFA_MIPS_advance_loc8: - return "DW_CFA_MIPS_advance_loc8"; - /* GNU extensions. */ - case DW_CFA_GNU_window_save: - return "DW_CFA_GNU_window_save"; - case DW_CFA_GNU_args_size: - return "DW_CFA_GNU_args_size"; - case DW_CFA_GNU_negative_offset_extended: - return "DW_CFA_GNU_negative_offset_extended"; - default: - return "DW_CFA_"; - } + return name; } -#endif static void dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) @@ -13559,13 +14630,13 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) print_spaces (indent, f); fprintf_unfiltered (f, "Die: %s (abbrev %d, offset 0x%x)\n", - dwarf_tag_name (die->tag), die->abbrev, die->offset); + dwarf_tag_name (die->tag), die->abbrev, die->offset.sect_off); if (die->parent != NULL) { print_spaces (indent, f); fprintf_unfiltered (f, " parent at offset: 0x%x\n", - die->parent->offset); + die->parent->offset.sect_off); } print_spaces (indent, f); @@ -13584,8 +14655,8 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) switch (die->attrs[i].form) { - case DW_FORM_ref_addr: case DW_FORM_addr: + case DW_FORM_GNU_addr_index: fprintf_unfiltered (f, "address: "); fputs_filtered (hex_string (DW_ADDR (&die->attrs[i])), f); break; @@ -13600,11 +14671,17 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) fprintf_unfiltered (f, "expression: size %u", DW_BLOCK (&die->attrs[i])->size); break; + case DW_FORM_ref_addr: + fprintf_unfiltered (f, "ref address: "); + fputs_filtered (hex_string (DW_UNSND (&die->attrs[i])), f); + break; case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: fprintf_unfiltered (f, "constant ref: 0x%lx (adjusted)", - (long) (DW_ADDR (&die->attrs[i]))); + (long) (DW_UNSND (&die->attrs[i]))); break; case DW_FORM_data1: case DW_FORM_data2: @@ -13622,12 +14699,13 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) case DW_FORM_ref_sig8: if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL) fprintf_unfiltered (f, "signatured type, offset: 0x%x", - DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset); + DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset.sect_off); else fprintf_unfiltered (f, "signatured type, offset: unknown"); break; case DW_FORM_string: case DW_FORM_strp: + case DW_FORM_GNU_str_index: fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)", DW_STRING (&die->attrs[i]) ? DW_STRING (&die->attrs[i]) : "", @@ -13711,11 +14789,15 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu) { void **slot; - slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset, INSERT); + slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset.sect_off, + INSERT); *slot = die; } +/* DW_ADDR is always stored already as sect_offset; despite for the forms + besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file. */ + static int is_ref_attr (struct attribute *attr) { @@ -13733,16 +14815,22 @@ is_ref_attr (struct attribute *attr) } } -static unsigned int +/* Return DIE offset of ATTR. Return 0 with complaint if ATTR is not of the + required kind. */ + +static sect_offset dwarf2_get_ref_die_offset (struct attribute *attr) { + sect_offset retval = { DW_UNSND (attr) }; + if (is_ref_attr (attr)) - return DW_ADDR (attr); + return retval; + retval.sect_off = 0; complaint (&symfile_complaints, _("unsupported die ref attribute form: '%s'"), dwarf_form_name (attr->form)); - return 0; + return retval; } /* Return the constant value held by ATTR. Return DEFAULT_VALUE if @@ -13775,7 +14863,8 @@ dwarf2_get_attr_constant_value (struct attribute *attr, int default_value) static int maybe_queue_comp_unit (struct dwarf2_cu *this_cu, - struct dwarf2_per_cu_data *per_cu) + struct dwarf2_per_cu_data *per_cu, + enum language pretend_language) { /* We may arrive here during partial symbol reading, if we need full DIEs to process an unusual case (e.g. template arguments). Do @@ -13804,7 +14893,7 @@ maybe_queue_comp_unit (struct dwarf2_cu *this_cu, } /* Add it to the queue. */ - queue_comp_unit (per_cu, this_cu->objfile); + queue_comp_unit (per_cu, pretend_language); return 1; } @@ -13839,7 +14928,7 @@ follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr, Returns NULL if OFFSET is invalid. */ static struct die_info * -follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu) +follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu) { struct die_info temp_die; struct dwarf2_cu *target_cu, *cu = *ref_cu; @@ -13848,7 +14937,7 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu) target_cu = cu; - if (cu->per_cu->debug_type_section) + if (cu->per_cu->is_debug_types) { /* .debug_types CUs cannot reference anything outside their CU. If they need to, they have to reference a signatured type via @@ -13863,8 +14952,8 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu) per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile); /* If necessary, add it to the queue and load its DIEs. */ - if (maybe_queue_comp_unit (cu, per_cu)) - load_full_comp_unit (per_cu, cu->objfile); + if (maybe_queue_comp_unit (cu, per_cu, cu->language)) + load_full_comp_unit (per_cu, cu->language); target_cu = per_cu->cu; } @@ -13872,12 +14961,12 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu) { /* We're loading full DIEs during partial symbol reading. */ gdb_assert (dwarf2_per_objfile->reading_partial_symbols); - load_full_comp_unit (cu->per_cu, cu->objfile); + load_full_comp_unit (cu->per_cu, language_minimal); } *ref_cu = target_cu; temp_die.offset = offset; - return htab_find_with_hash (target_cu->die_hash, &temp_die, offset); + return htab_find_with_hash (target_cu->die_hash, &temp_die, offset.sect_off); } /* Follow reference attribute ATTR of SRC_DIE. @@ -13888,7 +14977,7 @@ static struct die_info * follow_die_ref (struct die_info *src_die, struct attribute *attr, struct dwarf2_cu **ref_cu) { - unsigned int offset = dwarf2_get_ref_die_offset (attr); + sect_offset offset = dwarf2_get_ref_die_offset (attr); struct dwarf2_cu *cu = *ref_cu; struct die_info *die; @@ -13896,21 +14985,22 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr, if (!die) 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); + offset.sect_off, src_die->offset.sect_off, cu->objfile->name); return die; } -/* Return DWARF block and its CU referenced by OFFSET at PER_CU. Returned - value is intended for DW_OP_call*. You must call xfree on returned - dwarf2_locexpr_baton->data. */ +/* Return DWARF block referenced by DW_AT_location of DIE at OFFSET at PER_CU. + Returned value is intended for DW_OP_call*. Returned + dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE. */ struct dwarf2_locexpr_baton -dwarf2_fetch_die_location_block (unsigned int offset, +dwarf2_fetch_die_location_block (cu_offset offset_in_cu, struct dwarf2_per_cu_data *per_cu, CORE_ADDR (*get_frame_pc) (void *baton), void *baton) { + sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off }; struct dwarf2_cu *cu; struct die_info *die; struct attribute *attr; @@ -13925,12 +15015,13 @@ dwarf2_fetch_die_location_block (unsigned int offset, die = follow_die_offset (offset, &cu); if (!die) error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"), - offset, per_cu->cu->objfile->name); + offset.sect_off, per_cu->objfile->name); attr = dwarf2_attr (die, DW_AT_location, cu); if (!attr) { - /* DWARF: "If there is no such attribute, then there is no effect.". */ + /* DWARF: "If there is no such attribute, then there is no effect.". + DATA is ignored if SIZE is 0. */ retval.data = NULL; retval.size = 0; @@ -13952,16 +15043,13 @@ dwarf2_fetch_die_location_block (unsigned int offset, if (!attr_form_is_block (attr)) error (_("Dwarf Error: DIE at 0x%x referenced in module %s " "is neither DW_FORM_block* nor DW_FORM_exprloc"), - offset, per_cu->cu->objfile->name); + offset.sect_off, per_cu->objfile->name); retval.data = DW_BLOCK (attr)->data; retval.size = DW_BLOCK (attr)->size; } retval.per_cu = cu->per_cu; - if (retval.data) - retval.data = xmemdup (retval.data, retval.size, retval.size); - age_cached_comp_units (); return retval; @@ -13971,11 +15059,15 @@ dwarf2_fetch_die_location_block (unsigned int offset, PER_CU. */ struct type * -dwarf2_get_die_type (unsigned int die_offset, +dwarf2_get_die_type (cu_offset die_offset, struct dwarf2_per_cu_data *per_cu) { + sect_offset die_offset_sect; + dw2_setup (per_cu->objfile); - return get_die_type_at_offset (die_offset, per_cu); + + die_offset_sect.sect_off = per_cu->offset.sect_off + die_offset.cu_off; + return get_die_type_at_offset (die_offset_sect, per_cu); } /* Follow the signature attribute ATTR in SRC_DIE. @@ -13997,18 +15089,20 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr, 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); + src_die->offset.sect_off, 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); + if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, language_minimal)) + read_signatured_type (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); + gdb_assert (sig_type->type_offset_in_section.sect_off != 0); + temp_die.offset = sig_type->type_offset_in_section; + die = htab_find_with_hash (sig_cu->die_hash, &temp_die, + temp_die.offset.sect_off); if (die) { *ref_cu = sig_cu; @@ -14017,7 +15111,7 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr, 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); + temp_die.offset.sect_off, src_die->offset.sect_off, objfile->name); } /* Given an offset of a signatured type, return its signatured_type. */ @@ -14025,12 +15119,12 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr, static struct signatured_type * lookup_signatured_type_at_offset (struct objfile *objfile, struct dwarf2_section_info *section, - unsigned int offset) + sect_offset offset) { - gdb_byte *info_ptr = section->buffer + offset; + gdb_byte *info_ptr = section->buffer + offset.sect_off; unsigned int length, initial_length_size; unsigned int sig_offset; - struct signatured_type find_entry, *type_sig; + struct signatured_type find_entry, *sig_type; length = read_initial_length (objfile->obfd, info_ptr, &initial_length_size); sig_offset = (initial_length_size @@ -14038,133 +15132,98 @@ lookup_signatured_type_at_offset (struct objfile *objfile, + (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); + sig_type = 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->per_cu.offset); + gdb_assert (sig_type != NULL); + gdb_assert (offset.sect_off == sig_type->per_cu.offset.sect_off); - return type_sig; + return sig_type; } -/* Read in signatured type at OFFSET and build its CU and die(s). */ +/* Load the DIEs associated with type unit PER_CU into memory. */ static void -read_signatured_type_at_offset (struct objfile *objfile, - struct dwarf2_section_info *sect, - unsigned int offset) +load_full_type_unit (struct dwarf2_per_cu_data *per_cu) { - struct signatured_type *type_sig; + struct objfile *objfile = per_cu->objfile; + struct dwarf2_section_info *sect = per_cu->info_or_types_section; + sect_offset offset = per_cu->offset; + struct signatured_type *sig_type; dwarf2_read_section (objfile, sect); /* We have the section offset, but we need the signature to do the - hash table lookup. */ - type_sig = lookup_signatured_type_at_offset (objfile, sect, offset); + hash table lookup. */ + /* FIXME: This is sorta unnecessary, read_signatured_type only uses + the signature to assert we found the right one. + Ok, but it's a lot of work. We should simplify things so any needed + assert doesn't require all this clumsiness. */ + sig_type = lookup_signatured_type_at_offset (objfile, sect, offset); - gdb_assert (type_sig->per_cu.cu == NULL); + gdb_assert (&sig_type->per_cu == per_cu); + gdb_assert (sig_type->per_cu.cu == NULL); - read_signatured_type (objfile, type_sig); + read_signatured_type (sig_type); - gdb_assert (type_sig->per_cu.cu != NULL); + gdb_assert (sig_type->per_cu.cu != NULL); } -/* Read in a signatured type and build its CU and DIEs. */ +/* die_reader_func for read_signatured_type. + This is identical to load_full_comp_unit_reader, + but is kept separate for now. */ static void -read_signatured_type (struct objfile *objfile, - struct signatured_type *type_sig) +read_signatured_type_reader (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct die_info *comp_unit_die, + int has_children, + void *data) { - gdb_byte *types_ptr; - struct die_reader_specs reader_specs; - struct dwarf2_cu *cu; - ULONGEST signature; - struct cleanup *back_to, *free_cu_cleanup; - struct dwarf2_section_info *section = type_sig->per_cu.debug_type_section; - - dwarf2_read_section (objfile, section); - types_ptr = section->buffer + type_sig->per_cu.offset; - - gdb_assert (type_sig->per_cu.cu == NULL); - - cu = xmalloc (sizeof (*cu)); - init_one_comp_unit (cu, 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, section, &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); + struct dwarf2_cu *cu = reader->cu; + struct attribute *attr; - init_cu_die_reader (&reader_specs, cu); + gdb_assert (cu->die_hash == NULL); + 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); - cu->dies = read_die_and_children (&reader_specs, types_ptr, &types_ptr, - NULL /*parent*/); + if (has_children) + comp_unit_die->child = read_die_and_siblings (reader, info_ptr, + &info_ptr, comp_unit_die); + cu->dies = comp_unit_die; + /* comp_unit_die is not stored in die_hash, no need. */ /* We try not to read any attributes in this function, because not - all objfiles needed for references have been loaded yet, and symbol + all CUs 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. */ - prepare_one_comp_unit (cu, cu->dies); - - 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; + or we won't be able to build types correctly. + Similarly, if we do not read the producer, we can not apply + producer-specific interpretation. */ + prepare_one_comp_unit (cu, cu->dies, language_minimal); } -/* Workaround as dwarf_expr_context_funcs.read_mem implementation before - a proper runtime DWARF expressions evaluator gets implemented. - Otherwise gnuv3_baseclass_offset would error by: - Expected a negative vbase offset (old compiler?) */ +/* Read in a signatured type and build its CU and DIEs. + If the type is a stub for the real type in a DWO file, + read in the real type from the DWO file as well. */ static void -decode_locdesc_read_mem (void *baton, gdb_byte *buf, CORE_ADDR addr, - size_t length) +read_signatured_type (struct signatured_type *sig_type) { - struct dwarf_expr_context *ctx = baton; - struct gdbarch *gdbarch = ctx->gdbarch; - struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr; + struct dwarf2_per_cu_data *per_cu = &sig_type->per_cu; - memset (buf, 0, length); + gdb_assert (per_cu->is_debug_types); + gdb_assert (per_cu->cu == NULL); - if (TYPE_LENGTH (ptr_type) == length) - store_typed_address (buf, ptr_type, addr); + init_cutu_and_read_dies (per_cu, 0, 1, read_signatured_type_reader, NULL); } -static const struct dwarf_expr_context_funcs decode_locdesc_ctx_funcs = -{ - ctx_no_read_reg, - decode_locdesc_read_mem, - ctx_no_get_frame_base, - ctx_no_get_frame_cfa, - ctx_no_get_frame_pc, - ctx_no_get_tls_address, - ctx_no_dwarf_call, - ctx_no_get_base_type -}; - /* Decode simple location descriptions. Given a pointer to a dwarf block that defines a location, compute the location and return the value. @@ -14182,59 +15241,249 @@ static const struct dwarf_expr_context_funcs decode_locdesc_ctx_funcs = object is optimized out. The return value is 0 for that case. FIXME drow/2003-11-16: No callers check for this case any more; soon all callers will only want a very basic result and this can become a - complaint. */ + complaint. + + Note that stack[0] is unused except as a default error return. */ static CORE_ADDR decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; - struct dwarf_expr_context *ctx; - struct cleanup *old_chain; - volatile struct gdb_exception ex; + int i; + int size = blk->size; + gdb_byte *data = blk->data; + CORE_ADDR stack[64]; + int stacki; + unsigned int bytes_read, unsnd; + gdb_byte op; + + i = 0; + stacki = 0; + stack[stacki] = 0; + stack[++stacki] = 0; - ctx = new_dwarf_expr_context (); - old_chain = make_cleanup_free_dwarf_expr_context (ctx); - make_cleanup_value_free_to_mark (value_mark ()); + while (i < size) + { + op = data[i++]; + switch (op) + { + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + stack[++stacki] = op - DW_OP_lit0; + break; - ctx->gdbarch = get_objfile_arch (objfile); - ctx->addr_size = cu->header.addr_size; - ctx->offset = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - ctx->baton = ctx; - ctx->funcs = &decode_locdesc_ctx_funcs; + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + stack[++stacki] = op - DW_OP_reg0; + if (i < size) + dwarf2_complex_location_expr_complaint (); + break; - /* DW_AT_data_member_location expects the structure address to be pushed on - the stack. Simulate the offset by address 0. */ - dwarf_expr_push_address (ctx, 0, 0); + case DW_OP_regx: + unsnd = read_unsigned_leb128 (NULL, (data + i), &bytes_read); + i += bytes_read; + stack[++stacki] = unsnd; + if (i < size) + dwarf2_complex_location_expr_complaint (); + break; - TRY_CATCH (ex, RETURN_MASK_ERROR) - { - dwarf_expr_eval (ctx, blk->data, blk->size); - } - if (ex.reason < 0) - { - if (ex.message) - complaint (&symfile_complaints, "%s", ex.message); - } - else if (ctx->num_pieces == 0) - switch (ctx->location) - { - /* The returned number will be bogus, just do not complain for locations - in global registers - it is here only a partial symbol address. */ - case DWARF_VALUE_REGISTER: + case DW_OP_addr: + stack[++stacki] = read_address (objfile->obfd, &data[i], + cu, &bytes_read); + i += bytes_read; + break; - case DWARF_VALUE_MEMORY: - case DWARF_VALUE_STACK: - { - CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0); + case DW_OP_const1u: + stack[++stacki] = read_1_byte (objfile->obfd, &data[i]); + i += 1; + break; + + case DW_OP_const1s: + stack[++stacki] = read_1_signed_byte (objfile->obfd, &data[i]); + i += 1; + break; + + case DW_OP_const2u: + stack[++stacki] = read_2_bytes (objfile->obfd, &data[i]); + i += 2; + break; + + case DW_OP_const2s: + stack[++stacki] = read_2_signed_bytes (objfile->obfd, &data[i]); + i += 2; + break; + + case DW_OP_const4u: + stack[++stacki] = read_4_bytes (objfile->obfd, &data[i]); + i += 4; + break; + + case DW_OP_const4s: + stack[++stacki] = read_4_signed_bytes (objfile->obfd, &data[i]); + i += 4; + break; + + case DW_OP_const8u: + stack[++stacki] = read_8_bytes (objfile->obfd, &data[i]); + i += 8; + break; + + case DW_OP_constu: + stack[++stacki] = read_unsigned_leb128 (NULL, (data + i), + &bytes_read); + i += bytes_read; + break; + + case DW_OP_consts: + stack[++stacki] = read_signed_leb128 (NULL, (data + i), &bytes_read); + i += bytes_read; + break; + + case DW_OP_dup: + stack[stacki + 1] = stack[stacki]; + stacki++; + break; + + case DW_OP_plus: + stack[stacki - 1] += stack[stacki]; + stacki--; + break; + + case DW_OP_plus_uconst: + stack[stacki] += read_unsigned_leb128 (NULL, (data + i), + &bytes_read); + i += bytes_read; + break; + + case DW_OP_minus: + stack[stacki - 1] -= stack[stacki]; + stacki--; + break; + + case DW_OP_deref: + /* If we're not the last op, then we definitely can't encode + this using GDB's address_class enum. This is valid for partial + global symbols, although the variable's address will be bogus + in the psymtab. */ + if (i < size) + dwarf2_complex_location_expr_complaint (); + break; + + case DW_OP_GNU_push_tls_address: + /* The top of the stack has the offset from the beginning + of the thread control block at which the variable is located. */ + /* Nothing should follow this operator, so the top of stack would + be returned. */ + /* This is valid for partial global symbols, but the variable's + address will be bogus in the psymtab. Make it always at least + non-zero to not look as a variable garbage collected by linker + which have DW_OP_addr 0. */ + if (i < size) + dwarf2_complex_location_expr_complaint (); + stack[stacki]++; + break; + + case DW_OP_GNU_uninit: + break; + + case DW_OP_GNU_addr_index: + stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i], + &bytes_read); + i += bytes_read; + break; + + default: + { + const char *name = get_DW_OP_name (op); - do_cleanups (old_chain); - return address; + if (name) + complaint (&symfile_complaints, _("unsupported stack op: '%s'"), + name); + else + complaint (&symfile_complaints, _("unsupported stack op: '%02x'"), + op); + } + + return (stack[stacki]); } - } - do_cleanups (old_chain); - dwarf2_complex_location_expr_complaint (); - return 0; + /* Enforce maximum stack depth of SIZE-1 to avoid writing + outside of the allocated space. Also enforce minimum>0. */ + if (stacki >= ARRAY_SIZE (stack) - 1) + { + complaint (&symfile_complaints, + _("location description stack overflow")); + return 0; + } + + if (stacki <= 0) + { + complaint (&symfile_complaints, + _("location description stack underflow")); + return 0; + } + } + return (stack[stacki]); } /* memory allocation interface */ @@ -14350,9 +15599,12 @@ macro_start_file (int file, int line, objfile->macro_cache); if (! current_file) - /* If we have no current file, then this must be the start_file - directive for the compilation unit's main source file. */ - current_file = macro_set_main (pending_macros, full_name); + { + /* If we have no current file, then this must be the start_file + directive for the compilation unit's main source file. */ + current_file = macro_set_main (pending_macros, full_name); + macro_define_special (pending_macros); + } else current_file = macro_include (current_file, line, full_name); @@ -14590,6 +15842,8 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, case DW_FORM_sdata: case DW_FORM_udata: + case DW_FORM_GNU_addr_index: + case DW_FORM_GNU_str_index: bytes = skip_leb128 (abfd, bytes); break; @@ -14710,7 +15964,7 @@ dwarf_parse_macro_header (gdb_byte **opcode_definitions, } /* A helper for dwarf_decode_macros that handles the GNU extensions, - including DW_GNU_MACINFO_transparent_include. */ + including DW_MACRO_GNU_transparent_include. */ static void dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, @@ -14719,7 +15973,8 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, struct dwarf2_section_info *section, int section_is_gnu, unsigned int offset_size, - struct objfile *objfile) + struct objfile *objfile, + htab_t include_hash) { enum dwarf_macro_record_type macinfo_type; int at_commandline; @@ -14894,16 +16149,33 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, case DW_MACRO_GNU_transparent_include: { LONGEST offset; + void **slot; offset = read_offset_1 (abfd, mac_ptr, offset_size); mac_ptr += offset_size; - dwarf_decode_macro_bytes (abfd, - section->buffer + offset, - mac_end, current_file, - lh, comp_dir, - section, section_is_gnu, - offset_size, objfile); + slot = htab_find_slot (include_hash, mac_ptr, INSERT); + if (*slot != NULL) + { + /* This has actually happened; see + http://sourceware.org/bugzilla/show_bug.cgi?id=13568. */ + complaint (&symfile_complaints, + _("recursive DW_MACRO_GNU_transparent_include in " + ".debug_macro section")); + } + else + { + *slot = mac_ptr; + + dwarf_decode_macro_bytes (abfd, + section->buffer + offset, + mac_end, current_file, + lh, comp_dir, + section, section_is_gnu, + offset_size, objfile, include_hash); + + htab_remove_elt (include_hash, mac_ptr); + } } break; @@ -14939,19 +16211,22 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, char *comp_dir, bfd *abfd, struct dwarf2_cu *cu, struct dwarf2_section_info *section, - int section_is_gnu) + int section_is_gnu, const char *section_name) { + struct objfile *objfile = dwarf2_per_objfile->objfile; gdb_byte *mac_ptr, *mac_end; struct macro_source_file *current_file = 0; enum dwarf_macro_record_type macinfo_type; unsigned int offset_size = cu->header.offset_size; gdb_byte *opcode_definitions[256]; + struct cleanup *cleanup; + htab_t include_hash; + void **slot; - dwarf2_read_section (dwarf2_per_objfile->objfile, section); + dwarf2_read_section (objfile, section); if (section->buffer == NULL) { - complaint (&symfile_complaints, _("missing %s section"), - section->asection->name); + complaint (&symfile_complaints, _("missing %s section"), section_name); return; } @@ -15024,7 +16299,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, mac_ptr += bytes_read; current_file = macro_start_file (file, line, current_file, - comp_dir, lh, cu->objfile); + comp_dir, lh, objfile); } break; @@ -15079,13 +16354,21 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, command-line macro definitions/undefinitions. This flag is unset when we reach the first DW_MACINFO_start_file entry. */ - dwarf_decode_macro_bytes (abfd, section->buffer + offset, mac_end, + include_hash = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer, + NULL, xcalloc, xfree); + cleanup = make_cleanup_htab_delete (include_hash); + mac_ptr = section->buffer + offset; + slot = htab_find_slot (include_hash, mac_ptr, INSERT); + *slot = mac_ptr; + dwarf_decode_macro_bytes (abfd, mac_ptr, mac_end, current_file, lh, comp_dir, section, section_is_gnu, - offset_size, cu->objfile); + offset_size, objfile, include_hash); + do_cleanups (cleanup); } /* Check if the attribute's form is a DW_FORM_block* if so return true else false. */ + static int attr_form_is_block (struct attribute *attr) { @@ -15105,6 +16388,7 @@ attr_form_is_block (struct attribute *attr) may have a value that belongs to more than one of these classes; it would be ambiguous if we did, because we use the same forms for all of them. */ + static int attr_form_is_section_offset (struct attribute *attr) { @@ -15113,7 +16397,6 @@ attr_form_is_section_offset (struct attribute *attr) || attr->form == DW_FORM_sec_offset); } - /* Return non-zero if ATTR's value falls in the 'constant' class, or zero otherwise. When this function returns true, you can apply dwarf2_get_attr_constant_value to it. @@ -15126,6 +16409,7 @@ attr_form_is_section_offset (struct attribute *attr) that, if an attribute's can be either a constant or one of the section offset classes, DW_FORM_data4 and DW_FORM_data8 should be taken as section offsets, not constants. */ + static int attr_form_is_constant (struct attribute *attr) { @@ -15143,6 +16427,17 @@ attr_form_is_constant (struct attribute *attr) } } +/* Return the .debug_loc section to use for CU. + For DWO files use .debug_loc.dwo. */ + +static struct dwarf2_section_info * +cu_debug_loc_section (struct dwarf2_cu *cu) +{ + if (cu->dwo_unit) + return &cu->dwo_unit->dwo_file->sections.loc; + return &dwarf2_per_objfile->loc; +} + /* A helper function that fills in a dwarf2_loclist_baton. */ static void @@ -15150,15 +16445,16 @@ fill_in_loclist_baton (struct dwarf2_cu *cu, struct dwarf2_loclist_baton *baton, struct attribute *attr) { - dwarf2_read_section (dwarf2_per_objfile->objfile, - &dwarf2_per_objfile->loc); + struct dwarf2_section_info *section = cu_debug_loc_section (cu); + + dwarf2_read_section (dwarf2_per_objfile->objfile, section); baton->per_cu = cu->per_cu; gdb_assert (baton->per_cu); /* We don't know how long the location list is, but make sure we don't run off the edge of the section. */ - baton->size = dwarf2_per_objfile->loc.size - DW_UNSND (attr); - baton->data = dwarf2_per_objfile->loc.buffer + DW_UNSND (attr); + baton->size = section->size - DW_UNSND (attr); + baton->data = section->buffer + DW_UNSND (attr); baton->base_address = cu->base_address; } @@ -15166,16 +16462,18 @@ static void dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, struct dwarf2_cu *cu) { + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwarf2_section_info *section = cu_debug_loc_section (cu); + if (attr_form_is_section_offset (attr) - /* ".debug_loc" may not exist at all, or the offset may be outside + /* .debug_loc{,.dwo} may not exist at all, or the offset may be outside the section. If so, fall through to the complaint in the other branch. */ - && DW_UNSND (attr) < dwarf2_section_size (dwarf2_per_objfile->objfile, - &dwarf2_per_objfile->loc)) + && DW_UNSND (attr) < dwarf2_section_size (objfile, section)) { struct dwarf2_loclist_baton *baton; - baton = obstack_alloc (&cu->objfile->objfile_obstack, + baton = obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_loclist_baton)); fill_in_loclist_baton (cu, baton, attr); @@ -15192,7 +16490,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, { struct dwarf2_locexpr_baton *baton; - baton = obstack_alloc (&cu->objfile->objfile_obstack, + baton = obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_locexpr_baton)); baton->per_cu = cu->per_cu; gdb_assert (baton->per_cu); @@ -15212,7 +16510,6 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym, dwarf2_invalid_attrib_class_complaint ("location description", SYMBOL_NATURAL_NAME (sym)); baton->size = 0; - baton->data = NULL; } SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs; @@ -15237,26 +16534,42 @@ dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *per_cu) return objfile; } +/* Return comp_unit_head for PER_CU, either already available in PER_CU->CU + (CU_HEADERP is unused in such case) or prepare a temporary copy at + CU_HEADERP first. */ + +static const struct comp_unit_head * +per_cu_header_read_in (struct comp_unit_head *cu_headerp, + struct dwarf2_per_cu_data *per_cu) +{ + struct objfile *objfile; + struct dwarf2_per_objfile *per_objfile; + gdb_byte *info_ptr; + + if (per_cu->cu) + return &per_cu->cu->header; + + objfile = per_cu->objfile; + per_objfile = objfile_data (objfile, dwarf2_objfile_data_key); + info_ptr = per_objfile->info.buffer + per_cu->offset.sect_off; + + memset (cu_headerp, 0, sizeof (*cu_headerp)); + read_comp_unit_head (cu_headerp, info_ptr, objfile->obfd); + + return cu_headerp; +} + /* Return the address size given in the compilation unit header for CU. */ -CORE_ADDR +int dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu) { - if (per_cu->cu) - return per_cu->cu->header.addr_size; - else - { - /* If the CU is not currently read in, we re-read its header. */ - struct objfile *objfile = per_cu->objfile; - struct dwarf2_per_objfile *per_objfile - = objfile_data (objfile, dwarf2_objfile_data_key); - gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset; - struct comp_unit_head cu_header; + struct comp_unit_head cu_header_local; + const struct comp_unit_head *cu_headerp; - memset (&cu_header, 0, sizeof cu_header); - read_comp_unit_head (&cu_header, info_ptr, objfile->obfd); - return cu_header.addr_size; - } + cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu); + + return cu_headerp->addr_size; } /* Return the offset size given in the compilation unit header for CU. */ @@ -15264,21 +16577,28 @@ dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu) int dwarf2_per_cu_offset_size (struct dwarf2_per_cu_data *per_cu) { - if (per_cu->cu) - return per_cu->cu->header.offset_size; - else - { - /* If the CU is not currently read in, we re-read its header. */ - struct objfile *objfile = per_cu->objfile; - struct dwarf2_per_objfile *per_objfile - = objfile_data (objfile, dwarf2_objfile_data_key); - gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset; - struct comp_unit_head cu_header; + struct comp_unit_head cu_header_local; + const struct comp_unit_head *cu_headerp; - memset (&cu_header, 0, sizeof cu_header); - read_comp_unit_head (&cu_header, info_ptr, objfile->obfd); - return cu_header.offset_size; - } + cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu); + + return cu_headerp->offset_size; +} + +/* See its dwarf2loc.h declaration. */ + +int +dwarf2_per_cu_ref_addr_size (struct dwarf2_per_cu_data *per_cu) +{ + struct comp_unit_head cu_header_local; + const struct comp_unit_head *cu_headerp; + + cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu); + + if (cu_headerp->version == 2) + return cu_headerp->addr_size; + else + return cu_headerp->offset_size; } /* Return the text offset of the CU. The returned offset comes from @@ -15298,7 +16618,7 @@ dwarf2_per_cu_text_offset (struct dwarf2_per_cu_data *per_cu) the DIE at OFFSET. Raises an error on failure. */ static struct dwarf2_per_cu_data * -dwarf2_find_containing_comp_unit (unsigned int offset, +dwarf2_find_containing_comp_unit (sect_offset offset, struct objfile *objfile) { struct dwarf2_per_cu_data *this_cu; @@ -15310,61 +16630,53 @@ dwarf2_find_containing_comp_unit (unsigned int offset, { int mid = low + (high - low) / 2; - if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset) + if (dwarf2_per_objfile->all_comp_units[mid]->offset.sect_off + >= offset.sect_off) high = mid; else low = mid + 1; } gdb_assert (low == high); - if (dwarf2_per_objfile->all_comp_units[low]->offset > offset) + if (dwarf2_per_objfile->all_comp_units[low]->offset.sect_off + > offset.sect_off) { if (low == 0) error (_("Dwarf Error: could not find partial DIE containing " "offset 0x%lx [in module %s]"), - (long) offset, bfd_get_filename (objfile->obfd)); + (long) offset.sect_off, bfd_get_filename (objfile->obfd)); - gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset <= offset); + gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset.sect_off + <= offset.sect_off); return dwarf2_per_objfile->all_comp_units[low-1]; } else { this_cu = dwarf2_per_objfile->all_comp_units[low]; if (low == dwarf2_per_objfile->n_comp_units - 1 - && offset >= this_cu->offset + this_cu->length) - error (_("invalid dwarf2 offset %u"), offset); - gdb_assert (offset < this_cu->offset + this_cu->length); + && offset.sect_off >= this_cu->offset.sect_off + this_cu->length) + error (_("invalid dwarf2 offset %u"), offset.sect_off); + gdb_assert (offset.sect_off < this_cu->offset.sect_off + this_cu->length); return this_cu; } } -/* Locate the compilation unit from OBJFILE which is located at exactly - OFFSET. Raises an error on failure. */ - -static struct dwarf2_per_cu_data * -dwarf2_find_comp_unit (unsigned int offset, struct objfile *objfile) -{ - struct dwarf2_per_cu_data *this_cu; - - this_cu = dwarf2_find_containing_comp_unit (offset, objfile); - if (this_cu->offset != offset) - error (_("no compilation unit with offset %u."), offset); - return this_cu; -} - -/* Initialize dwarf2_cu CU for OBJFILE in a pre-allocated space. */ +/* Initialize dwarf2_cu CU, owned by PER_CU. */ static void -init_one_comp_unit (struct dwarf2_cu *cu, struct objfile *objfile) +init_one_comp_unit (struct dwarf2_cu *cu, struct dwarf2_per_cu_data *per_cu) { memset (cu, 0, sizeof (*cu)); - cu->objfile = objfile; + per_cu->cu = cu; + cu->per_cu = per_cu; + cu->objfile = per_cu->objfile; obstack_init (&cu->comp_unit_obstack); } /* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE. */ static void -prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die) +prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die, + enum language pretend_language) { struct attribute *attr; @@ -15374,9 +16686,13 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die) set_cu_language (DW_UNSND (attr), cu); else { - cu->language = language_minimal; + cu->language = pretend_language; cu->language_defn = language_def (cu->language); } + + attr = dwarf2_attr (comp_unit_die, DW_AT_producer, cu); + if (attr) + cu->producer = DW_STRING (attr); } /* Release one cached compilation unit, CU. We unlink it from the tree @@ -15386,12 +16702,12 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die) cleanup routine. */ static void -free_one_comp_unit (void *data) +free_heap_comp_unit (void *data) { struct dwarf2_cu *cu = data; - if (cu->per_cu != NULL) - cu->per_cu->cu = NULL; + gdb_assert (cu->per_cu != NULL); + cu->per_cu->cu = NULL; cu->per_cu = NULL; obstack_free (&cu->comp_unit_obstack, NULL); @@ -15401,30 +16717,19 @@ free_one_comp_unit (void *data) /* This cleanup function is passed the address of a dwarf2_cu on the stack when we're finished with it. We can't free the pointer itself, but be - sure to unlink it from the cache. Also release any associated storage - and perform cache maintenance. - - Only used during partial symbol parsing. */ + sure to unlink it from the cache. Also release any associated storage. */ static void free_stack_comp_unit (void *data) { struct dwarf2_cu *cu = data; + gdb_assert (cu->per_cu != NULL); + cu->per_cu->cu = NULL; + cu->per_cu = NULL; + obstack_free (&cu->comp_unit_obstack, NULL); cu->partial_dies = NULL; - - if (cu->per_cu != NULL) - { - /* This compilation unit is on the stack in our caller, so we - should not xfree it. Just unlink it. */ - cu->per_cu->cu = NULL; - cu->per_cu = NULL; - - /* If we had a per-cu pointer, then we may have other compilation - units loaded, so age them now. */ - age_cached_comp_units (); - } } /* Free all cached compilation units. */ @@ -15442,7 +16747,7 @@ free_cached_comp_units (void *data) next_cu = per_cu->cu->read_in_chain; - free_one_comp_unit (per_cu->cu); + free_heap_comp_unit (per_cu->cu); *last_chain = next_cu; per_cu = next_cu; @@ -15477,7 +16782,7 @@ age_cached_comp_units (void) if (!per_cu->cu->mark) { - free_one_comp_unit (per_cu->cu); + free_heap_comp_unit (per_cu->cu); *last_chain = next_cu; } else @@ -15490,7 +16795,7 @@ age_cached_comp_units (void) /* Remove a single compilation unit from the cache. */ static void -free_one_cached_comp_unit (void *target_cu) +free_one_cached_comp_unit (struct dwarf2_per_cu_data *target_per_cu) { struct dwarf2_per_cu_data *per_cu, **last_chain; @@ -15502,9 +16807,10 @@ free_one_cached_comp_unit (void *target_cu) next_cu = per_cu->cu->read_in_chain; - if (per_cu->cu == target_cu) + if (per_cu == target_per_cu) { - free_one_comp_unit (per_cu->cu); + free_heap_comp_unit (per_cu->cu); + per_cu->cu = NULL; *last_chain = next_cu; break; } @@ -15534,35 +16840,45 @@ dwarf2_free_objfile (struct objfile *objfile) /* Everything else should be on the objfile obstack. */ } -/* A pair of DIE offset and GDB type pointer. We store these - in a hash table separate from the DIEs, and preserve them - when the DIEs are flushed out of cache. */ +/* A set of CU "per_cu" pointer, DIE offset, and GDB type pointer. + We store these in a hash table separate from the DIEs, and preserve them + when the DIEs are flushed out of cache. -struct dwarf2_offset_and_type + The CU "per_cu" pointer is needed because offset alone is not enough to + uniquely identify the type. A file may have multiple .debug_types sections, + or the type may come from a DWO file. We have to use something in + dwarf2_per_cu_data (or the pointer to it) because we can enter the lookup + routine, get_die_type_at_offset, from outside this file, and thus won't + necessarily have PER_CU->cu. Fortunately, PER_CU is stable for the life + of the objfile. */ + +struct dwarf2_per_cu_offset_and_type { - unsigned int offset; + const struct dwarf2_per_cu_data *per_cu; + sect_offset offset; struct type *type; }; -/* Hash function for a dwarf2_offset_and_type. */ +/* Hash function for a dwarf2_per_cu_offset_and_type. */ static hashval_t -offset_and_type_hash (const void *item) +per_cu_offset_and_type_hash (const void *item) { - const struct dwarf2_offset_and_type *ofs = item; + const struct dwarf2_per_cu_offset_and_type *ofs = item; - return ofs->offset; + return (uintptr_t) ofs->per_cu + ofs->offset.sect_off; } -/* Equality function for a dwarf2_offset_and_type. */ +/* Equality function for a dwarf2_per_cu_offset_and_type. */ static int -offset_and_type_eq (const void *item_lhs, const void *item_rhs) +per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs) { - const struct dwarf2_offset_and_type *ofs_lhs = item_lhs; - const struct dwarf2_offset_and_type *ofs_rhs = item_rhs; + const struct dwarf2_per_cu_offset_and_type *ofs_lhs = item_lhs; + const struct dwarf2_per_cu_offset_and_type *ofs_rhs = item_rhs; - return ofs_lhs->offset == ofs_rhs->offset; + return (ofs_lhs->per_cu == ofs_rhs->per_cu + && ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off); } /* Set the type associated with DIE to TYPE. Save it in CU's hash @@ -15586,9 +16902,8 @@ offset_and_type_eq (const void *item_lhs, const void *item_rhs) static struct type * set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) { - struct dwarf2_offset_and_type **slot, ofs; + struct dwarf2_per_cu_offset_and_type **slot, ofs; struct objfile *objfile = cu->objfile; - htab_t *type_hash_ptr; /* For Ada types, make sure that the gnat-specific data is always initialized (if not already set). There are a few types where @@ -15603,55 +16918,47 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) && !HAVE_GNAT_AUX_INFO (type)) INIT_GNAT_SPECIFIC (type); - if (cu->per_cu->debug_type_section) - type_hash_ptr = &dwarf2_per_objfile->debug_types_type_hash; - else - type_hash_ptr = &dwarf2_per_objfile->debug_info_type_hash; - - if (*type_hash_ptr == NULL) + if (dwarf2_per_objfile->die_type_hash == NULL) { - *type_hash_ptr - = htab_create_alloc_ex (127, - offset_and_type_hash, - offset_and_type_eq, - NULL, - &objfile->objfile_obstack, - hashtab_obstack_allocate, - dummy_obstack_deallocate); + dwarf2_per_objfile->die_type_hash = + htab_create_alloc_ex (127, + per_cu_offset_and_type_hash, + per_cu_offset_and_type_eq, + NULL, + &objfile->objfile_obstack, + hashtab_obstack_allocate, + dummy_obstack_deallocate); } + ofs.per_cu = cu->per_cu; ofs.offset = die->offset; ofs.type = type; - slot = (struct dwarf2_offset_and_type **) - htab_find_slot_with_hash (*type_hash_ptr, &ofs, ofs.offset, INSERT); + slot = (struct dwarf2_per_cu_offset_and_type **) + htab_find_slot (dwarf2_per_objfile->die_type_hash, &ofs, INSERT); if (*slot) complaint (&symfile_complaints, _("A problem internal to GDB: DIE 0x%x has type already set"), - die->offset); + die->offset.sect_off); *slot = obstack_alloc (&objfile->objfile_obstack, sizeof (**slot)); **slot = ofs; return type; } -/* Look up the type for the die at DIE_OFFSET in the appropriate type_hash +/* Look up the type for the die at OFFSET in the appropriate type_hash table, or return NULL if the die does not have a saved type. */ static struct type * -get_die_type_at_offset (unsigned int offset, +get_die_type_at_offset (sect_offset offset, struct dwarf2_per_cu_data *per_cu) { - struct dwarf2_offset_and_type *slot, ofs; - htab_t type_hash; + struct dwarf2_per_cu_offset_and_type *slot, ofs; - if (per_cu->debug_type_section) - type_hash = dwarf2_per_objfile->debug_types_type_hash; - else - type_hash = dwarf2_per_objfile->debug_info_type_hash; - if (type_hash == NULL) + if (dwarf2_per_objfile->die_type_hash == NULL) return NULL; + ofs.per_cu = per_cu; ofs.offset = offset; - slot = htab_find_with_hash (type_hash, &ofs, ofs.offset); + slot = htab_find (dwarf2_per_objfile->die_type_hash, &ofs); if (slot) return slot->type; else @@ -15745,7 +17052,7 @@ partial_die_hash (const void *item) { const struct partial_die_info *part_die = item; - return part_die->offset; + return part_die->offset.sect_off; } /* Trivial comparison function for partial_die_info structures: two DIEs @@ -15757,7 +17064,7 @@ partial_die_eq (const void *item_lhs, const void *item_rhs) const struct partial_die_info *part_die_lhs = item_lhs; const struct partial_die_info *part_die_rhs = item_rhs; - return part_die_lhs->offset == part_die_rhs->offset; + return part_die_lhs->offset.sect_off == part_die_rhs->offset.sect_off; } static struct cmd_list_element *set_dwarf2_cmdlist; @@ -15813,6 +17120,7 @@ dwarf2_per_objfile_free (struct objfile *objfile, void *d) munmap_section_buffer (&data->macro); munmap_section_buffer (&data->str); munmap_section_buffer (&data->ranges); + munmap_section_buffer (&data->addr); munmap_section_buffer (&data->frame); munmap_section_buffer (&data->eh_frame); munmap_section_buffer (&data->gdb_index); @@ -15822,7 +17130,14 @@ dwarf2_per_objfile_free (struct objfile *objfile, void *d) ++ix) munmap_section_buffer (section); + for (ix = 0; ix < dwarf2_per_objfile->n_comp_units; ++ix) + VEC_free (dwarf2_per_cu_ptr, + dwarf2_per_objfile->all_comp_units[ix]->imported_symtabs); + VEC_free (dwarf2_section_info_def, data->types); + + if (data->dwo_files) + free_dwo_files (data->dwo_files, objfile); } @@ -16303,7 +17618,7 @@ write_psymbols (struct mapped_symtab *symtab, if (!*slot) { *slot = lookup; - add_index_entry (symtab, SYMBOL_NATURAL_NAME (*psymp), cu_index); + add_index_entry (symtab, SYMBOL_SEARCH_NAME (*psymp), cu_index); } } } @@ -16365,9 +17680,11 @@ write_one_signatured_type (void **slot, void *d) psymtab->n_static_syms, info->cu_index, 1); - store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->per_cu.offset); + store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, + entry->per_cu.offset.sect_off); obstack_grow (info->types_list, val, 8); - store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset); + store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, + entry->type_offset_in_tu.cu_off); obstack_grow (info->types_list, val, 8); store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->signature); obstack_grow (info->types_list, val, 8); @@ -16377,12 +17694,33 @@ write_one_signatured_type (void **slot, void *d) return 1; } -/* A cleanup function for an htab_t. */ +/* Recurse into all "included" dependencies and write their symbols as + if they appeared in this psymtab. */ static void -cleanup_htab (void *arg) +recursively_write_psymbols (struct objfile *objfile, + struct partial_symtab *psymtab, + struct mapped_symtab *symtab, + htab_t psyms_seen, + offset_type cu_index) { - htab_delete (arg); + int i; + + for (i = 0; i < psymtab->number_of_dependencies; ++i) + if (psymtab->dependencies[i]->user != NULL) + recursively_write_psymbols (objfile, psymtab->dependencies[i], + symtab, psyms_seen, cu_index); + + write_psymbols (symtab, + psyms_seen, + objfile->global_psymbols.list + psymtab->globals_offset, + psymtab->n_global_syms, cu_index, + 0); + write_psymbols (symtab, + psyms_seen, + objfile->static_psymbols.list + psymtab->statics_offset, + psymtab->n_static_syms, cu_index, + 1); } /* Create an index file for OBJFILE in the directory DIR. */ @@ -16441,7 +17779,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) psyms_seen = htab_create_alloc (100, htab_hash_pointer, htab_eq_pointer, NULL, xcalloc, xfree); - make_cleanup (cleanup_htab, psyms_seen); + make_cleanup_htab_delete (psyms_seen); /* While we're scanning CU's create a table that maps a psymtab pointer (which is what addrmap records) to its index (which is what is recorded @@ -16451,7 +17789,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) hash_psymtab_cu_index, eq_psymtab_cu_index, NULL, xcalloc, xfree); - make_cleanup (cleanup_htab, cu_index_htab); + make_cleanup_htab_delete (cu_index_htab); psymtab_cu_index_map = (struct psymtab_cu_index_map *) xmalloc (sizeof (struct psymtab_cu_index_map) * dwarf2_per_objfile->n_comp_units); @@ -16469,16 +17807,8 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) struct psymtab_cu_index_map *map; void **slot; - write_psymbols (symtab, - psyms_seen, - objfile->global_psymbols.list + psymtab->globals_offset, - psymtab->n_global_syms, i, - 0); - write_psymbols (symtab, - psyms_seen, - objfile->static_psymbols.list + psymtab->statics_offset, - psymtab->n_static_syms, i, - 1); + if (psymtab->user == NULL) + recursively_write_psymbols (objfile, psymtab, symtab, psyms_seen, i); map = &psymtab_cu_index_map[i]; map->psymtab = psymtab; @@ -16488,7 +17818,8 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) gdb_assert (*slot == NULL); *slot = map; - store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->offset); + store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, + per_cu->offset.sect_off); obstack_grow (&cu_list, val, 8); store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->length); obstack_grow (&cu_list, val, 8); @@ -16523,7 +17854,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) total_len = size_of_contents; /* The version number. */ - val = MAYBE_SWAP (5); + val = MAYBE_SWAP (6); obstack_grow (&contents, &val, sizeof (val)); /* The offset of the CU list from the start of the file. */