X-Git-Url: https://gitweb.dragonflybsd.org/~tuxillo/dragonfly.git/blobdiff_plain/6b445a628d016cb98daa614ade67aed0ed1d4ec0..ef5ccd6c41237a870dd7242b72b006d6bd42cd07:/contrib/gdb-7/gdb/dwarf2read.c diff --git a/contrib/gdb-7/gdb/dwarf2read.c b/contrib/gdb-7/gdb/dwarf2read.c index 8c81c8a78d..6151b3d515 100644 --- a/contrib/gdb-7/gdb/dwarf2read.c +++ b/contrib/gdb-7/gdb/dwarf2read.c @@ -1,6 +1,6 @@ /* DWARF 2 debugging format support for GDB. - Copyright (C) 1994-2012 Free Software Foundation, Inc. + Copyright (C) 1994-2013 Free Software Foundation, Inc. Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, Inc. with support from Florida State University (under contract @@ -24,8 +24,13 @@ 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 "elf-bfd.h" #include "symtab.h" #include "gdbtypes.h" #include "objfiles.h" @@ -55,79 +60,35 @@ #include "completer.h" #include "vec.h" #include "c-lang.h" +#include "go-lang.h" #include "valprint.h" +#include "gdbcore.h" /* for gnutarget */ +#include "gdb/gdb-index.h" #include +#include "gdb_bfd.h" +#include "f-lang.h" +#include "source.h" #include #include "gdb_string.h" #include "gdb_assert.h" #include -#ifdef HAVE_ZLIB_H -#include -#endif -#ifdef HAVE_MMAP -#include -#ifndef MAP_FAILED -#define MAP_FAILED ((void *) -1) -#endif -#endif 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, print basic high level tracing messages. + This is in contrast to the low level DIE reading of dwarf2_die_debug. */ +static int dwarf2_read_debug = 0; /* When non-zero, dump DIEs after they are read in. */ -static int dwarf2_die_debug = 0; +static unsigned int dwarf2_die_debug = 0; /* When non-zero, cross-check physname against demangler. */ static int check_physname = 0; -static int pagesize; - -/* When set, the file that we're processing is known to have debugging - info for C++ namespaces. GCC 3.3.x did not produce this information, - but later versions do. */ - -static int processing_has_namespace_info; +/* When non-zero, do not reject deprecated .gdb_index sections. */ +static int use_deprecated_index_sections = 0; static const struct objfile_data *dwarf2_objfile_data_key; @@ -136,10 +97,6 @@ struct dwarf2_section_info asection *asection; gdb_byte *buffer; bfd_size_type size; - /* Not NULL if the section was actually mmapped. */ - void *map_addr; - /* Page aligned size of mmapped area. */ - bfd_size_type map_len; /* True if we have tried to read this section. */ int readin; }; @@ -153,6 +110,28 @@ typedef uint32_t offset_type; DEF_VEC_I (offset_type); +/* Ensure only legit values are used. */ +#define DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE(cu_index, value) \ + do { \ + gdb_assert ((unsigned int) (value) <= 1); \ + GDB_INDEX_SYMBOL_STATIC_SET_VALUE((cu_index), (value)); \ + } while (0) + +/* Ensure only legit values are used. */ +#define DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE(cu_index, value) \ + do { \ + gdb_assert ((value) >= GDB_INDEX_SYMBOL_KIND_TYPE \ + && (value) <= GDB_INDEX_SYMBOL_KIND_OTHER); \ + GDB_INDEX_SYMBOL_KIND_SET_VALUE((cu_index), (value)); \ + } while (0) + +/* Ensure we don't use more than the alloted nuber of bits for the CU. */ +#define DW2_GDB_INDEX_CU_SET_VALUE(cu_index, value) \ + do { \ + gdb_assert (((value) & ~GDB_INDEX_CU_MASK) == 0); \ + GDB_INDEX_CU_SET_VALUE((cu_index), (value)); \ + } while (0) + /* A description of the mapped index. The file format is described in a comment by the code that writes the index. */ struct mapped_index @@ -179,6 +158,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; @@ -189,6 +174,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; @@ -198,7 +184,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; @@ -206,19 +192,54 @@ 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 signatured_type **all_type_units; - /* A chain of compilation units that are currently read in, so that - they can be freed later. */ - struct dwarf2_per_cu_data *read_in_chain; + /* The number of entries in all_type_unit_groups. */ + int n_type_unit_groups; + + /* Table of type unit groups. + This exists to make it easy to iterate over all CUs and TU groups. */ + struct type_unit_group **all_type_unit_groups; + + /* Table of struct type_unit_group objects. + The hash key is the DW_AT_stmt_list value. */ + htab_t type_unit_groups; /* A table mapping .debug_types signatures to its signatured_type entry. This is NULL if the .debug_types section hasn't been read in yet. */ htab_t signatured_types; + /* Type unit statistics, to see how well the scaling improvements + are doing. */ + struct tu_stats + { + int nr_uniq_abbrev_tables; + int nr_symtabs; + int nr_symtab_sharers; + int nr_stmt_less_type_units; + } tu_stats; + + /* A chain of compilation units that are currently read in, so that + they can be freed later. */ + struct dwarf2_per_cu_data *read_in_chain; + + /* 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; + + /* Non-zero if we've check for whether there is a DWP file. */ + int dwp_checked; + + /* The DWP file if there is one, or NULL. */ + struct dwp_file *dwp_file; + + /* The shared '.dwz' file, if one exists. This is used when the + original data was compressed using 'dwz -m'. */ + struct dwz_file *dwz_file; + /* A flag indicating wether this objfile has a section loaded at a VMA of 0. */ int has_section_at_zero; @@ -231,24 +252,25 @@ struct dwarf2_per_objfile struct mapped_index *index_table; /* When using index_table, this keeps track of all quick_file_names entries. - TUs can share line table entries with CUs or other TUs, and there can be - a lot more TUs than unique line tables, so we maintain a separate table - of all line table entries to support the sharing. */ + TUs typically share line table entries with a CU, so we maintain a + separate table of all line table entries to support the sharing. + Note that while there can be way more TUs than CUs, we've already + sorted all the TUs into "type unit groups", grouped by their + DW_AT_stmt_list value. Therefore the only sharing done here is with a + CU and its associated TU group if there is one. */ htab_t quick_file_names_table; /* Set during partial symbol reading, to prevent queueing of full 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; @@ -258,7 +280,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" }, @@ -268,18 +291,45 @@ 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 }; -/* local data types */ +/* List of DWO/DWP sections. */ + +static const struct dwop_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 macinfo_dwo; + struct dwarf2_section_names macro_dwo; + struct dwarf2_section_names str_dwo; + struct dwarf2_section_names str_offsets_dwo; + struct dwarf2_section_names types_dwo; + struct dwarf2_section_names cu_index; + struct dwarf2_section_names tu_index; +} +dwop_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_macinfo.dwo", ".zdebug_macinfo.dwo" }, + { ".debug_macro.dwo", ".zdebug_macro.dwo" }, + { ".debug_str.dwo", ".zdebug_str.dwo" }, + { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo" }, + { ".debug_types.dwo", ".zdebug_types.dwo" }, + { ".debug_cu_index", ".zdebug_cu_index" }, + { ".debug_tu_index", ".zdebug_tu_index" }, +}; -/* We hold several abbreviation tables in memory at the same time. */ -#ifndef ABBREV_HASH_SIZE -#define ABBREV_HASH_SIZE 121 -#endif +/* local data types */ /* The data in a compilation unit header, after target2host translation, looks like this. */ @@ -289,7 +339,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; @@ -299,11 +349,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. @@ -344,8 +394,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; @@ -363,13 +411,13 @@ struct dwarf2_cu distinguish these in buildsym.c. */ struct pending **list_in_scope; - /* DWARF abbreviation table associated with this compilation unit. */ - struct abbrev_info **dwarf2_abbrevs; - - /* Storage for the abbrev table. */ - struct obstack abbrev_obstack; + /* The abbrev table for this CU. + Normally this points to the abbrev table in the objfile. + But if DWO_UNIT is non-NULL this is the abbrev table in the DWO file. */ + struct abbrev_table *abbrev_table; - /* 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 @@ -388,7 +436,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. */ @@ -409,62 +458,101 @@ struct dwarf2_cu /* To be copied to symtab->call_site_htab. */ htab_t call_site_htab; + /* Non-NULL if this CU came from a DWO file. + There is an invariant here that is important to remember: + Except for attributes copied from the top level DIE in the "main" + (or "stub") file in preparation for reading the DWO file + (e.g., DW_AT_GNU_addr_base), we KISS: there is only *one* CU. + Either there isn't a DWO file (in which case this is NULL and the point + is moot), or there is and either we're not going to read it (in which + case this is NULL) or there is and we are reading it (in which case this + is non-NULL). */ + struct dwo_unit *dwo_unit; + + /* 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; + + /* The DW_AT_ranges_base attribute if present, zero otherwise + (zero is a valid value though). + Note this value comes from the stub CU/TU's DIE. + Also note that the value is zero in the non-DWO case so this value can + be used without needing to know whether DWO files are in use or not. + N.B. This does not apply to DW_AT_ranges appearing in + DW_TAG_compile_unit dies. This is a bit of a wart, consider if ever + DW_AT_ranges appeared in the DW_TAG_compile_unit of DWO DIEs: then + DW_AT_ranges_base *would* have to be applied, and we'd have to care + whether the DW_AT_ranges attribute came from the skeleton or DWO. */ + ULONGEST ranges_base; + /* Mark used when releasing cached dies. */ unsigned int mark : 1; - /* This flag will be set if this compilation unit might include - inter-compilation-unit references. */ - unsigned int has_form_ref_addr : 1; - - /* 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; - /* 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 for producer_is_* fields. CHECKED_PRODUCER is set + if all the producer_is_* fields are 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; + unsigned int producer_is_gcc_lt_4_3 : 1; + unsigned int producer_is_icc : 1; + + /* When set, the file that we're processing is known to have + debugging info for C++ namespaces. GCC 3.3.x did not produce + this information, but later versions do. */ + + unsigned int processing_has_namespace_info : 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 { - /* The start offset and length of this compilation unit. 2**29-1 - bytes should suffice to store the length of any compilation unit - - if it doesn't, GDB will fall over anyway. + /* The start offset and length of this compilation unit. NOTE: Unlike comp_unit_head.length, this length includes - initial_length_size. */ - unsigned int offset; - unsigned int length : 29; + 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; /* 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_types_section; + /* Non-zero if this CU is from .debug_types. */ + unsigned int is_debug_types : 1; + + /* Non-zero if this CU is from the .dwz file. */ + unsigned int is_dwz : 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. @@ -472,47 +560,301 @@ 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. + + This is also used to work around a difference between the way gold + generates .gdb_index version <=7 and the way gdb does. Arguably this + is a gold bug. For symbols coming from TUs, gold records in the index + the CU that includes the TU instead of the TU itself. This breaks + dw2_lookup_symbol: It assumes that if the index says symbol X lives + in CU/TU Y, then one need only expand Y and a subsequent lookup in Y + will find X. Alas TUs live in their own symtab, so after expanding CU Y + we need to look in TU Z to find X. Fortunately, this is akin to + DW_TAG_imported_unit, so we just use the same mechanism: For + .gdb_index version <=7 this also records the TUs that the CU referred + to. Concurrently with this change gdb was modified to emit version 8 + indices so we only pay a price for gold generated indices. */ + VEC (dwarf2_per_cu_ptr) *imported_symtabs; + + /* Type units are grouped by their DW_AT_stmt_list entry so that they + can share them. If this is a TU, this points to the containing + symtab. */ + struct type_unit_group *type_unit_group; }; /* Entry in the signatured_types hash table. */ struct signatured_type { + /* The "per_cu" object of this type. + N.B.: This is the first member so that it's easy to convert pointers + between them. */ + struct dwarf2_per_cu_data per_cu; + + /* 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; +}; + +/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list. + This includes type_unit_group and quick_file_names. */ + +struct stmt_list_hash +{ + /* The DWO unit this table is from or NULL if there is none. */ + struct dwo_unit *dwo_unit; + + /* Offset in .debug_line or .debug_line.dwo. */ + sect_offset line_offset; +}; + +/* Each element of dwarf2_per_objfile->type_unit_groups is a pointer to + an object of this type. */ - /* The CU(/TU) of this type. */ +struct type_unit_group +{ + /* dwarf2read.c's main "handle" on the symtab. + To simplify things we create an artificial CU that "includes" all the + type units using this stmt_list so that the rest of the code still has + a "per_cu" handle on the symtab. + This PER_CU is recognized by having no section. */ +#define IS_TYPE_UNIT_GROUP(per_cu) ((per_cu)->info_or_types_section == NULL) struct dwarf2_per_cu_data per_cu; + + union + { + /* The TUs that share this DW_AT_stmt_list entry. + This is added to while parsing type units to build partial symtabs, + and is deleted afterwards and not used again. */ + VEC (dwarf2_per_cu_ptr) *tus; + + /* When reading the line table in "quick" functions, we need a real TU. + Any will do, we know they all share the same DW_AT_stmt_list entry. + For simplicity's sake, we pick the first one. */ + struct dwarf2_per_cu_data *first_tu; + } t; + + /* The primary symtab. + Type units in a group needn't all be defined in the same source file, + so we create an essentially anonymous symtab as the primary symtab. */ + struct symtab *primary_symtab; + + /* The data used to construct the hash key. */ + struct stmt_list_hash hash; + + /* The number of symtabs from the line header. + The value here must match line_header.num_file_names. */ + unsigned int num_symtabs; + + /* The symbol tables for this TU (obtained from the files listed in + DW_AT_stmt_list). + WARNING: The order of entries here must match the order of entries + in the line header. After the first TU using this type_unit_group, the + line header for the subsequent TUs is recreated from this. This is done + because we need to use the same symtabs for each TU using the same + DW_AT_stmt_list value. Also note that symtabs may be repeated here, + there's no guarantee the line header doesn't have duplicate entries. */ + struct symtab **symtabs; +}; + +/* These sections are what may appear in a DWO file. */ + +struct dwo_sections +{ + struct dwarf2_section_info abbrev; + struct dwarf2_section_info line; + struct dwarf2_section_info loc; + struct dwarf2_section_info macinfo; + struct dwarf2_section_info macro; + struct dwarf2_section_info str; + struct dwarf2_section_info str_offsets; + /* In the case of a virtual DWO file, these two are unused. */ + struct dwarf2_section_info info; + 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. + This includes virtual DWO files that have been packaged into a + DWP file. */ + +struct dwo_file +{ + /* The DW_AT_GNU_dwo_name attribute. This is the hash key. + For virtual DWO files the name is constructed from the section offsets + of abbrev,line,loc,str_offsets so that we combine virtual DWO files + from related CU+TUs. */ + const char *name; + + /* The bfd, when the file is open. Otherwise this is NULL. + This is unused(NULL) for virtual DWO files where we use dwp_file.dbfd. */ + bfd *dbfd; + + /* 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; +}; + +/* These sections are what may appear in a DWP file. */ + +struct dwp_sections +{ + struct dwarf2_section_info str; + struct dwarf2_section_info cu_index; + struct dwarf2_section_info tu_index; + /* The .debug_info.dwo, .debug_types.dwo, and other sections are referenced + by section number. We don't need to record them here. */ +}; + +/* These sections are what may appear in a virtual DWO file. */ + +struct virtual_dwo_sections +{ + struct dwarf2_section_info abbrev; + struct dwarf2_section_info line; + struct dwarf2_section_info loc; + struct dwarf2_section_info macinfo; + struct dwarf2_section_info macro; + struct dwarf2_section_info str_offsets; + /* Each DWP hash table entry records one CU or one TU. + That is recorded here, and copied to dwo_unit.info_or_types_section. */ + struct dwarf2_section_info info_or_types; +}; + +/* Contents of DWP hash tables. */ + +struct dwp_hash_table +{ + uint32_t nr_units, nr_slots; + const gdb_byte *hash_table, *unit_table, *section_pool; +}; + +/* Data for one DWP file. */ + +struct dwp_file +{ + /* Name of the file. */ + const char *name; + + /* The bfd, when the file is open. Otherwise this is NULL. */ + bfd *dbfd; + + /* Section info for this file. */ + struct dwp_sections sections; + + /* Table of CUs in the file. */ + const struct dwp_hash_table *cus; + + /* Table of TUs in the file. */ + const struct dwp_hash_table *tus; + + /* Table of loaded CUs/TUs. Each entry is a struct dwo_unit *. */ + htab_t loaded_cutus; + + /* Table to map ELF section numbers to their sections. */ + unsigned int num_sections; + asection **elf_sections; +}; + +/* This represents a '.dwz' file. */ + +struct dwz_file +{ + /* A dwz file can only contain a few sections. */ + struct dwarf2_section_info abbrev; + struct dwarf2_section_info info; + struct dwarf2_section_info str; + struct dwarf2_section_info line; + struct dwarf2_section_info macro; + struct dwarf2_section_info gdb_index; + + /* The dwz's BFD. */ + bfd *dwz_bfd; }; /* 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 (including one packaged into a DWP). */ + 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; + + /* The end of the buffer. */ + const gdb_byte *buffer_end; }; +/* 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. */ @@ -565,7 +907,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; @@ -577,6 +919,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. */ @@ -591,9 +934,15 @@ struct partial_die_info /* Flag set if fixup_partial_die has been called on this die. */ unsigned int fixup_called : 1; + /* Flag set if DW_TAG_imported_unit uses DW_FORM_GNU_ref_alt. */ + unsigned int is_dwz : 1; + + /* Flag set if spec_offset uses DW_FORM_GNU_ref_alt. */ + unsigned int spec_is_dwz : 1; + /* The name of this DIE. Normally the value of DW_AT_name, but sometimes a default name for unnamed DIEs. */ - char *name; + const char *name; /* The linkage name, if present. */ const char *linkage_name; @@ -601,10 +950,17 @@ struct partial_die_info /* The scope to prepend to our children. This is generally allocated on the comp_unit_obstack, so will disappear when this compilation unit leaves the cache. */ - char *scope; + const 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; @@ -619,7 +975,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. */ @@ -643,6 +999,27 @@ struct attr_abbrev ENUM_BITFIELD(dwarf_form) form : 16; }; +/* Size of abbrev_table.abbrev_hash_table. */ +#define ABBREV_HASH_SIZE 121 + +/* Top level data structure to contain an abbreviation table. */ + +struct abbrev_table +{ + /* Where the abbrev table came from. + This is used as a sanity check when the table is used. */ + sect_offset offset; + + /* Storage for the abbrev table. */ + struct obstack abbrev_obstack; + + /* Hash table of abbrevs. + This is an array of size ABBREV_HASH_SIZE allocated in abbrev_obstack. + It could be statically allocated, but the previous code didn't so we + don't either. */ + struct abbrev_info **abbrevs; +}; + /* Attributes have a name and a value. */ struct attribute { @@ -656,7 +1033,7 @@ struct attribute union { - char *str; + const char *str; struct dwarf_block *blk; ULONGEST unsnd; LONGEST snd; @@ -683,7 +1060,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 @@ -699,14 +1076,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) @@ -720,7 +1089,7 @@ struct function_range /* Blocks are a bunch of untyped bytes. */ struct dwarf_block { - unsigned int size; + size_t size; /* Valid only if SIZE is not zero. */ gdb_byte *data; @@ -778,7 +1147,7 @@ struct field_info to the head of the member function field chain. */ struct fnfieldlist { - char *name; + const char *name; int length; struct nextfnfield *head; } @@ -803,6 +1172,7 @@ struct field_info struct dwarf2_queue_item { struct dwarf2_per_cu_data *per_cu; + enum language pretend_language; struct dwarf2_queue_item *next; }; @@ -865,11 +1235,13 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2, } static void -dwarf2_macros_too_long_complaint (struct dwarf2_section_info *section) +dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section) { complaint (&symfile_complaints, - _("macro info runs off end of `%s' section"), - section->asection->name); + _("debug info runs off end of %s section" + " [in module %s]"), + section->asection->name, + bfd_get_filename (section->asection->owner)); } static void @@ -923,57 +1295,56 @@ 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 dwarf2_read_symtab (struct partial_symtab *, + struct objfile *); static void psymtab_to_symtab_1 (struct partial_symtab *); -static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu); +static struct abbrev_info *abbrev_table_lookup_abbrev + (const struct abbrev_table *, unsigned int); -static void dwarf2_free_abbrev_table (void *); +static struct abbrev_table *abbrev_table_read_table + (struct dwarf2_section_info *, sect_offset); -static unsigned int peek_abbrev_code (bfd *, gdb_byte *); +static void abbrev_table_free (struct abbrev_table *); + +static void abbrev_table_free_cleanup (void *); -static struct abbrev_info *peek_die_abbrev (gdb_byte *, unsigned int *, - struct dwarf2_cu *); +static void dwarf2_read_abbrevs (struct dwarf2_cu *, + struct dwarf2_section_info *); + +static void dwarf2_free_abbrev_table (void *); -static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int, - struct dwarf2_cu *); +static unsigned int peek_abbrev_code (bfd *, gdb_byte *); -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, int, 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 *); +static unsigned int read_1_byte (bfd *, const gdb_byte *); -static int read_1_signed_byte (bfd *, gdb_byte *); +static int read_1_signed_byte (bfd *, const gdb_byte *); -static unsigned int read_2_bytes (bfd *, gdb_byte *); +static unsigned int read_2_bytes (bfd *, const gdb_byte *); -static unsigned int read_4_bytes (bfd *, gdb_byte *); +static unsigned int read_4_bytes (bfd *, const gdb_byte *); -static ULONGEST read_8_bytes (bfd *, gdb_byte *); +static ULONGEST read_8_bytes (bfd *, const gdb_byte *); static CORE_ADDR read_address (bfd *, gdb_byte *ptr, struct dwarf2_cu *, unsigned int *); @@ -989,6 +1360,9 @@ static LONGEST read_offset (bfd *, gdb_byte *, const struct comp_unit_head *, static LONGEST read_offset_1 (bfd *, gdb_byte *, unsigned int); +static sect_offset read_abbrev_offset (struct dwarf2_section_info *, + sect_offset); + static gdb_byte *read_n_bytes (bfd *, gdb_byte *, unsigned int); static char *read_direct_string (bfd *, gdb_byte *, unsigned int *); @@ -997,11 +1371,17 @@ 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 char *read_indirect_string_from_dwz (struct dwz_file *, LONGEST); + +static ULONGEST read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *); -static long read_signed_leb128 (bfd *, gdb_byte *, unsigned int *); +static LONGEST read_signed_leb128 (bfd *, gdb_byte *, unsigned int *); -static gdb_byte *skip_leb128 (bfd *, gdb_byte *); +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 void set_cu_language (unsigned int, struct dwarf2_cu *); @@ -1009,8 +1389,7 @@ static struct attribute *dwarf2_attr (struct die_info *, unsigned int, struct dwarf2_cu *); static struct attribute *dwarf2_attr_no_follow (struct die_info *, - unsigned int, - struct dwarf2_cu *); + unsigned int); static int dwarf2_flag_true_p (struct die_info *die, unsigned name, struct dwarf2_cu *cu); @@ -1025,9 +1404,8 @@ 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 *, struct dwarf2_cu *, struct partial_symtab *, @@ -1035,6 +1413,9 @@ static void dwarf_decode_lines (struct line_header *, const char *, static void dwarf2_start_subfile (char *, const char *, const char *); +static void dwarf2_start_symtab (struct dwarf2_cu *, + const char *, const char *, CORE_ADDR); + static struct symbol *new_symbol (struct die_info *, struct type *, struct dwarf2_cu *); @@ -1048,7 +1429,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); @@ -1072,7 +1453,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, @@ -1139,54 +1520,45 @@ 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 *); -static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *, - struct obstack *); +static const char *dwarf2_canonicalize_name (const char *, struct dwarf2_cu *, + struct obstack *); -static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *); +static const char *dwarf2_name (struct die_info *die, struct dwarf2_cu *); -static const char *dwarf2_full_name (char *name, +static const char *dwarf2_full_name (const char *name, struct die_info *die, struct dwarf2_cu *cu); 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 *); @@ -1204,7 +1576,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); @@ -1222,33 +1594,25 @@ 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 *); + +static struct type_unit_group *get_type_unit_group + (struct dwarf2_cu *, struct attribute *); + +static void build_type_unit_groups (die_reader_func_ftype *, void *); /* memory allocation interface */ static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *); -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); +static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int, + const char *, int); static int attr_form_is_block (struct attribute *); @@ -1264,9 +1628,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 *); @@ -1275,36 +1639,38 @@ 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, unsigned int offset_in_dwz, 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 *, + enum language); -static void process_full_comp_unit (struct dwarf2_per_cu_data *); +static void process_full_type_unit (struct dwarf2_per_cu_data *, + enum language); static void dwarf2_add_dependence (struct dwarf2_cu *, struct dwarf2_per_cu_data *); @@ -1313,7 +1679,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); @@ -1321,29 +1687,52 @@ 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, - char **name, char **comp_dir); + const char **name, const char **comp_dir); 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, - int is_debug_types_section); +static gdb_byte *read_and_check_comp_unit_head + (struct comp_unit_head *header, + struct dwarf2_section_info *section, + struct dwarf2_section_info *abbrev_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, struct abbrev_table *abbrev_table, + 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 htab_t allocate_dwo_unit_table (struct objfile *objfile); + +static struct dwo_unit *lookup_dwo_comp_unit + (struct dwarf2_per_cu_data *, const char *, const char *, ULONGEST); + +static struct dwo_unit *lookup_dwo_type_unit + (struct signatured_type *, const char *, const char *); + +static void free_dwo_file_cleanup (void *); + +static void process_cu_includes (void); + +static void check_producer (struct dwarf2_cu *cu); + #if WORDS_BIGENDIAN /* Convert VALUE between big- and little-endian. */ @@ -1368,7 +1757,7 @@ byte_swap (offset_type value) /* The suffix for an index file. */ #define INDEX_SUFFIX ".gdb-index" -static const char *dwarf2_physname (char *name, struct die_info *die, +static const char *dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu); /* Try to locate the sections we need for DWARF 2 debugging @@ -1423,13 +1812,17 @@ static void dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames) { const struct dwarf2_debug_sections *names; + flagword aflag = bfd_get_section_flags (abfd, sectp); if (vnames == NULL) names = &dwarf2_elf_names; else names = (const struct dwarf2_debug_sections *) vnames; - if (section_is_p (sectp->name, &names->info)) + if ((aflag & SEC_HAS_CONTENTS) == 0) + { + } + else if (section_is_p (sectp->name, &names->info)) { dwarf2_per_objfile->info.asection = sectp; dwarf2_per_objfile->info.size = bfd_get_section_size (sectp); @@ -1464,6 +1857,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; @@ -1471,13 +1869,8 @@ 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); - - if (aflag & SEC_HAS_CONTENTS) - { - dwarf2_per_objfile->eh_frame.asection = sectp; - dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp); - } + dwarf2_per_objfile->eh_frame.asection = sectp; + dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp); } else if (section_is_p (sectp->name, &names->ranges)) { @@ -1506,86 +1899,8 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames) dwarf2_per_objfile->has_section_at_zero = 1; } -/* Decompress a section that was compressed using zlib. Store the - decompressed buffer, and its size, in OUTBUF and OUTSIZE. */ - -static void -zlib_decompress_section (struct objfile *objfile, asection *sectp, - gdb_byte **outbuf, bfd_size_type *outsize) -{ - bfd *abfd = objfile->obfd; -#ifndef HAVE_ZLIB_H - error (_("Support for zlib-compressed DWARF data (from '%s') " - "is disabled in this copy of GDB"), - bfd_get_filename (abfd)); -#else - bfd_size_type compressed_size = bfd_get_section_size (sectp); - gdb_byte *compressed_buffer = xmalloc (compressed_size); - struct cleanup *cleanup = make_cleanup (xfree, compressed_buffer); - bfd_size_type uncompressed_size; - gdb_byte *uncompressed_buffer; - z_stream strm; - int rc; - int header_size = 12; - - if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 - || bfd_bread (compressed_buffer, - compressed_size, abfd) != compressed_size) - error (_("Dwarf Error: Can't read DWARF data from '%s'"), - bfd_get_filename (abfd)); - - /* Read the zlib header. In this case, it should be "ZLIB" followed - by the uncompressed section size, 8 bytes in big-endian order. */ - if (compressed_size < header_size - || strncmp (compressed_buffer, "ZLIB", 4) != 0) - error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"), - bfd_get_filename (abfd)); - uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[11]; - - /* It is possible the section consists of several compressed - buffers concatenated together, so we uncompress in a loop. */ - strm.zalloc = NULL; - strm.zfree = NULL; - strm.opaque = NULL; - strm.avail_in = compressed_size - header_size; - strm.next_in = (Bytef*) compressed_buffer + header_size; - strm.avail_out = uncompressed_size; - uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack, - uncompressed_size); - rc = inflateInit (&strm); - while (strm.avail_in > 0) - { - if (rc != Z_OK) - error (_("Dwarf Error: setting up DWARF uncompression in '%s': %d"), - bfd_get_filename (abfd), rc); - strm.next_out = ((Bytef*) uncompressed_buffer - + (uncompressed_size - strm.avail_out)); - rc = inflate (&strm, Z_FINISH); - if (rc != Z_STREAM_END) - error (_("Dwarf Error: zlib error uncompressing from '%s': %d"), - bfd_get_filename (abfd), rc); - rc = inflateReset (&strm); - } - rc = inflateEnd (&strm); - if (rc != Z_OK - || strm.avail_out != 0) - error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"), - bfd_get_filename (abfd), rc); - - do_cleanups (cleanup); - *outbuf = uncompressed_buffer; - *outsize = uncompressed_size; -#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) @@ -1593,68 +1908,44 @@ 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]; if (info->readin) return; info->buffer = NULL; - info->map_addr = NULL; info->readin = 1; if (dwarf2_section_empty_p (info)) return; - /* Check if the file has a 4-byte header indicating compression. */ - if (info->size > sizeof (header) - && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0 - && bfd_bread (header, sizeof (header), abfd) == sizeof (header)) - { - /* Upon decompression, update the buffer and its size. */ - if (strncmp (header, "ZLIB", sizeof (header)) == 0) - { - zlib_decompress_section (objfile, sectp, &info->buffer, - &info->size); - return; - } - } - -#ifdef HAVE_MMAP - if (pagesize == 0) - pagesize = getpagesize (); + abfd = sectp->owner; - /* Only try to mmap sections which are large enough: we don't want to - waste space due to fragmentation. Also, only try mmap for sections - without relocations. */ - - if (info->size > 4 * pagesize && (sectp->flags & SEC_RELOC) == 0) + /* If the section has relocations, we must read it ourselves. + Otherwise we attach it to the BFD. */ + if ((sectp->flags & SEC_RELOC) == 0) { - info->buffer = bfd_mmap (abfd, 0, info->size, PROT_READ, - MAP_PRIVATE, sectp->filepos, - &info->map_addr, &info->map_len); + const gdb_byte *bytes = gdb_bfd_map_section (sectp, &info->size); - if ((caddr_t)info->buffer != MAP_FAILED) - { -#if HAVE_POSIX_MADVISE - posix_madvise (info->map_addr, info->map_len, POSIX_MADV_WILLNEED); -#endif - return; - } + /* We have to cast away const here for historical reasons. + Fixing dwarf2read to be const-correct would be quite nice. */ + info->buffer = (gdb_byte *) bytes; + return; } -#endif - /* If we get here, we are a normal, not-compressed section. */ - info->buffer = buf - = obstack_alloc (&objfile->objfile_obstack, info->size); + buf = obstack_alloc (&objfile->objfile_obstack, info->size); + info->buffer = buf; /* When debugging .o files, we may need to apply relocations; see http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html . @@ -1730,23 +2021,129 @@ dwarf2_get_section_info (struct objfile *objfile, *sizep = info->size; } - -/* DWARF quick_symbols_functions support. */ +/* A helper function to find the sections for a .dwz file. */ -/* TUs can share .debug_line entries, and there can be a lot more TUs than - unique line tables, so we maintain a separate table of all .debug_line - derived entries to support the sharing. - All the quick functions need is the list of file names. We discard the - line_header when we're done and don't need to record it here. */ -struct quick_file_names +static void +locate_dwz_sections (bfd *abfd, asection *sectp, void *arg) { - /* The offset in .debug_line of the line table. We hash on this. */ - unsigned int offset; + struct dwz_file *dwz_file = arg; - /* The number of entries in file_names, real_names. */ - unsigned int num_file_names; + /* Note that we only support the standard ELF names, because .dwz + is ELF-only (at the time of writing). */ + if (section_is_p (sectp->name, &dwarf2_elf_names.abbrev)) + { + dwz_file->abbrev.asection = sectp; + dwz_file->abbrev.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &dwarf2_elf_names.info)) + { + dwz_file->info.asection = sectp; + dwz_file->info.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &dwarf2_elf_names.str)) + { + dwz_file->str.asection = sectp; + dwz_file->str.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &dwarf2_elf_names.line)) + { + dwz_file->line.asection = sectp; + dwz_file->line.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &dwarf2_elf_names.macro)) + { + dwz_file->macro.asection = sectp; + dwz_file->macro.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &dwarf2_elf_names.gdb_index)) + { + dwz_file->gdb_index.asection = sectp; + dwz_file->gdb_index.size = bfd_get_section_size (sectp); + } +} - /* The file names from the line table, after being run through +/* Open the separate '.dwz' debug file, if needed. Error if the file + cannot be found. */ + +static struct dwz_file * +dwarf2_get_dwz_file (void) +{ + bfd *abfd, *dwz_bfd; + asection *section; + gdb_byte *data; + struct cleanup *cleanup; + const char *filename; + struct dwz_file *result; + + if (dwarf2_per_objfile->dwz_file != NULL) + return dwarf2_per_objfile->dwz_file; + + abfd = dwarf2_per_objfile->objfile->obfd; + section = bfd_get_section_by_name (abfd, ".gnu_debugaltlink"); + if (section == NULL) + error (_("could not find '.gnu_debugaltlink' section")); + if (!bfd_malloc_and_get_section (abfd, section, &data)) + error (_("could not read '.gnu_debugaltlink' section: %s"), + bfd_errmsg (bfd_get_error ())); + cleanup = make_cleanup (xfree, data); + + filename = data; + if (!IS_ABSOLUTE_PATH (filename)) + { + char *abs = gdb_realpath (dwarf2_per_objfile->objfile->name); + char *rel; + + make_cleanup (xfree, abs); + abs = ldirname (abs); + make_cleanup (xfree, abs); + + rel = concat (abs, SLASH_STRING, filename, (char *) NULL); + make_cleanup (xfree, rel); + filename = rel; + } + + /* The format is just a NUL-terminated file name, followed by the + build-id. For now, though, we ignore the build-id. */ + dwz_bfd = gdb_bfd_open (filename, gnutarget, -1); + if (dwz_bfd == NULL) + error (_("could not read '%s': %s"), filename, + bfd_errmsg (bfd_get_error ())); + + if (!bfd_check_format (dwz_bfd, bfd_object)) + { + gdb_bfd_unref (dwz_bfd); + error (_("file '%s' was not usable: %s"), filename, + bfd_errmsg (bfd_get_error ())); + } + + result = OBSTACK_ZALLOC (&dwarf2_per_objfile->objfile->objfile_obstack, + struct dwz_file); + result->dwz_bfd = dwz_bfd; + + bfd_map_over_sections (dwz_bfd, locate_dwz_sections, result); + + do_cleanups (cleanup); + + dwarf2_per_objfile->dwz_file = result; + return result; +} + +/* DWARF quick_symbols_functions support. */ + +/* TUs can share .debug_line entries, and there can be a lot more TUs than + unique line tables, so we maintain a separate table of all .debug_line + derived entries to support the sharing. + All the quick functions need is the list of file names. We discard the + line_header when we're done and don't need to record it here. */ +struct quick_file_names +{ + /* The data used to construct the hash key. */ + struct stmt_list_hash hash; + + /* The number of entries in file_names, real_names. */ + unsigned int num_file_names; + + /* The file names from the line table, after being run through file_full_name. */ const char **file_names; @@ -1778,6 +2175,34 @@ struct dwarf2_per_cu_quick_data unsigned int no_file_data : 1; }; +/* Utility hash function for a stmt_list_hash. */ + +static hashval_t +hash_stmt_list_entry (const struct stmt_list_hash *stmt_list_hash) +{ + hashval_t v = 0; + + if (stmt_list_hash->dwo_unit != NULL) + v += (uintptr_t) stmt_list_hash->dwo_unit->dwo_file; + v += stmt_list_hash->line_offset.sect_off; + return v; +} + +/* Utility equality function for a stmt_list_hash. */ + +static int +eq_stmt_list_entry (const struct stmt_list_hash *lhs, + const struct stmt_list_hash *rhs) +{ + if ((lhs->dwo_unit != NULL) != (rhs->dwo_unit != NULL)) + return 0; + if (lhs->dwo_unit != NULL + && lhs->dwo_unit->dwo_file != rhs->dwo_unit->dwo_file) + return 0; + + return lhs->line_offset.sect_off == rhs->line_offset.sect_off; +} + /* Hash function for a quick_file_names. */ static hashval_t @@ -1785,7 +2210,7 @@ hash_file_name_entry (const void *e) { const struct quick_file_names *file_data = e; - return file_data->offset; + return hash_stmt_list_entry (&file_data->hash); } /* Equality function for a quick_file_names. */ @@ -1796,7 +2221,7 @@ eq_file_name_entry (const void *a, const void *b) const struct quick_file_names *ea = a; const struct quick_file_names *eb = b; - return ea->offset == eb->offset; + return eq_stmt_list_entry (&ea->hash, &eb->hash); } /* Delete function for a quick_file_names. */ @@ -1835,34 +2260,39 @@ 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_types_section) - read_signatured_type_at_offset (per_cu->objfile, - per_cu->debug_types_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); + /* Skip type_unit_groups, reading the type units they contain + is handled elsewhere. */ + if (IS_TYPE_UNIT_GROUP (per_cu)) + return; - queue_comp_unit (per_cu, objfile); + back_to = make_cleanup (dwarf2_release_queue, NULL); - 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. */ @@ -1876,20 +2306,32 @@ 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; } -/* Return the CU given its index. */ +/* Return the CU given its index. + + This is intended for loops like: + + for (i = 0; i < (dwarf2_per_objfile->n_comp_units + + dwarf2_per_objfile->n_type_units); ++i) + { + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); + + ...; + } +*/ static struct dwarf2_per_cu_data * dw2_get_cu (int index) @@ -1897,76 +2339,106 @@ 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]; + gdb_assert (index < dwarf2_per_objfile->n_type_units); + return &dwarf2_per_objfile->all_type_units[index]->per_cu; } + return dwarf2_per_objfile->all_comp_units[index]; } -/* A helper function that knows how to read a 64-bit value in a way - that doesn't make gdb die. Returns 1 if the conversion went ok, 0 - otherwise. */ +/* Return the primary CU given its index. + The difference between this function and dw2_get_cu is in the handling + of type units (TUs). Here we return the type_unit_group object. -static int -extract_cu_value (const char *bytes, ULONGEST *result) -{ - if (sizeof (ULONGEST) < 8) - { - int i; + This is intended for loops like: - /* Ignore the upper 4 bytes if they are all zero. */ - for (i = 0; i < 4; ++i) - if (bytes[i + 4] != 0) - return 0; + for (i = 0; i < (dwarf2_per_objfile->n_comp_units + + dwarf2_per_objfile->n_type_unit_groups); ++i) + { + struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i); + + ...; + } +*/ - *result = extract_unsigned_integer (bytes, 4, BFD_ENDIAN_LITTLE); +static struct dwarf2_per_cu_data * +dw2_get_primary_cu (int index) +{ + if (index >= dwarf2_per_objfile->n_comp_units) + { + index -= dwarf2_per_objfile->n_comp_units; + gdb_assert (index < dwarf2_per_objfile->n_type_unit_groups); + return &dwarf2_per_objfile->all_type_unit_groups[index]->per_cu; } - else - *result = extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE); - return 1; + + return dwarf2_per_objfile->all_comp_units[index]; } -/* Read the CU list from the mapped index, and use it to create all - the CU objects for this objfile. Return 0 if something went wrong, - 1 if everything went ok. */ +/* A helper for create_cus_from_index that handles a given list of + CUs. */ -static int -create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list, - offset_type cu_list_elements) +static void +create_cus_from_index_list (struct objfile *objfile, + const gdb_byte *cu_list, offset_type n_elements, + struct dwarf2_section_info *section, + int is_dwz, + int base_offset) { offset_type i; - dwarf2_per_objfile->n_comp_units = cu_list_elements / 2; - dwarf2_per_objfile->all_comp_units - = obstack_alloc (&objfile->objfile_obstack, - dwarf2_per_objfile->n_comp_units - * sizeof (struct dwarf2_per_cu_data *)); - - for (i = 0; i < cu_list_elements; i += 2) + for (i = 0; i < n_elements; i += 2) { struct dwarf2_per_cu_data *the_cu; ULONGEST offset, length; - if (!extract_cu_value (cu_list, &offset) - || !extract_cu_value (cu_list + 8, &length)) - return 0; + gdb_static_assert (sizeof (ULONGEST) >= 8); + offset = extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE); + length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE); cu_list += 2 * 8; 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 = section; 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; + the_cu->is_dwz = is_dwz; + dwarf2_per_objfile->all_comp_units[base_offset + i / 2] = the_cu; } +} - return 1; +/* Read the CU list from the mapped index, and use it to create all + the CU objects for this objfile. */ + +static void +create_cus_from_index (struct objfile *objfile, + const gdb_byte *cu_list, offset_type cu_list_elements, + const gdb_byte *dwz_list, offset_type dwz_elements) +{ + struct dwz_file *dwz; + + dwarf2_per_objfile->n_comp_units = (cu_list_elements + dwz_elements) / 2; + dwarf2_per_objfile->all_comp_units + = obstack_alloc (&objfile->objfile_obstack, + dwarf2_per_objfile->n_comp_units + * sizeof (struct dwarf2_per_cu_data *)); + + create_cus_from_index_list (objfile, cu_list, cu_list_elements, + &dwarf2_per_objfile->info, 0, 0); + + if (dwz_elements == 0) + return; + + dwz = dwarf2_get_dwz_file (); + create_cus_from_index_list (objfile, dwz_list, dwz_elements, &dwz->info, 1, + cu_list_elements / 2); } /* Create the signatured type hash table from the index. */ -static int +static void create_signatured_type_table_from_index (struct objfile *objfile, struct dwarf2_section_info *section, const gdb_byte *bytes, @@ -1975,46 +2447,46 @@ 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 - * sizeof (struct dwarf2_per_cu_data *)); + dwarf2_per_objfile->n_type_units + * sizeof (struct signatured_type *)); 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)) - return 0; + gdb_static_assert (sizeof (ULONGEST) >= 8); + offset = extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE); + type_offset_in_tu = extract_unsigned_integer (bytes + 8, 8, + BFD_ENDIAN_LITTLE); 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_types_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; } dwarf2_per_objfile->signatured_types = sig_types_hash; - - return 1; } /* Read the address map data from the mapped index, and use it to @@ -2117,7 +2589,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 @@ -2152,63 +2624,108 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name, } } -/* Read the index file. If everything went ok, initialize the "quick" - elements of all the CUs and return 1. Otherwise, return 0. */ +/* A helper function that reads the .gdb_index from SECTION and fills + in MAP. FILENAME is the name of the file containing the section; + it is used for error reporting. DEPRECATED_OK is nonzero if it is + ok to use deprecated sections. + + CU_LIST, CU_LIST_ELEMENTS, TYPES_LIST, and TYPES_LIST_ELEMENTS are + out parameters that are filled in with information about the CU and + TU lists in the section. + + Returns 1 if all went well, 0 otherwise. */ static int -dwarf2_read_index (struct objfile *objfile) +read_index_from_section (struct objfile *objfile, + const char *filename, + int deprecated_ok, + struct dwarf2_section_info *section, + struct mapped_index *map, + const gdb_byte **cu_list, + offset_type *cu_list_elements, + const gdb_byte **types_list, + offset_type *types_list_elements) { char *addr; - struct mapped_index *map; + offset_type version; offset_type *metadata; - const gdb_byte *cu_list; - const gdb_byte *types_list = NULL; - offset_type version, cu_list_elements; - offset_type types_list_elements = 0; int i; - if (dwarf2_section_empty_p (&dwarf2_per_objfile->gdb_index)) + if (dwarf2_section_empty_p (section)) return 0; /* Older elfutils strip versions could keep the section in the main executable while splitting it for the separate debug info file. */ - if ((bfd_get_file_flags (dwarf2_per_objfile->gdb_index.asection) - & SEC_HAS_CONTENTS) == 0) + if ((bfd_get_file_flags (section->asection) & SEC_HAS_CONTENTS) == 0) return 0; - dwarf2_read_section (objfile, &dwarf2_per_objfile->gdb_index); + dwarf2_read_section (objfile, section); - addr = dwarf2_per_objfile->gdb_index.buffer; + addr = section->buffer; /* Version check. */ version = MAYBE_SWAP (*(offset_type *) addr); /* 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."), + filename); + 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 user has done + "set use-deprecated-index-sections on". */ + if (version < 6 && !deprecated_ok) + { + static int warning_printed = 0; + if (!warning_printed) + { + warning (_("\ +Skipping deprecated .gdb_index section in %s.\n\ +Do \"set use-deprecated-index-sections on\" before the file is read\n\ +to use the section anyway."), + filename); + warning_printed = 1; + } + return 0; + } + /* Version 7 indices generated by gold refer to the CU for a symbol instead + of the TU (for symbols coming from TUs). It's just a performance bug, and + we can't distinguish gdb-generated indices from gold-generated ones, so + nothing to do here. */ + /* Indexes with higher version than the one supported by GDB may be no longer backward compatible. */ - if (version > 5) + if (version > 8) return 0; - map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index); map->version = version; - map->total_size = dwarf2_per_objfile->gdb_index.size; + map->total_size = section->size; metadata = (offset_type *) (addr + sizeof (offset_type)); i = 0; - cu_list = addr + MAYBE_SWAP (metadata[i]); - cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i])) - / 8); + *cu_list = addr + MAYBE_SWAP (metadata[i]); + *cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i])) + / 8); ++i; - types_list = addr + MAYBE_SWAP (metadata[i]); - types_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - - MAYBE_SWAP (metadata[i])) - / 8); + *types_list = addr + MAYBE_SWAP (metadata[i]); + *types_list_elements = ((MAYBE_SWAP (metadata[i + 1]) + - MAYBE_SWAP (metadata[i])) + / 8); ++i; map->address_table = addr + MAYBE_SWAP (metadata[i]); @@ -2224,9 +2741,56 @@ dwarf2_read_index (struct objfile *objfile) map->constant_pool = addr + MAYBE_SWAP (metadata[i]); - if (!create_cus_from_index (objfile, cu_list, cu_list_elements)) + return 1; +} + + +/* Read the index file. If everything went ok, initialize the "quick" + elements of all the CUs and return 1. Otherwise, return 0. */ + +static int +dwarf2_read_index (struct objfile *objfile) +{ + struct mapped_index local_map, *map; + const gdb_byte *cu_list, *types_list, *dwz_list = NULL; + offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0; + + if (!read_index_from_section (objfile, objfile->name, + use_deprecated_index_sections, + &dwarf2_per_objfile->gdb_index, &local_map, + &cu_list, &cu_list_elements, + &types_list, &types_list_elements)) + return 0; + + /* Don't use the index if it's empty. */ + if (local_map.symbol_table_slots == 0) return 0; + /* If there is a .dwz file, read it so we can get its CU list as + well. */ + if (bfd_get_section_by_name (objfile->obfd, ".gnu_debugaltlink") != NULL) + { + struct dwz_file *dwz = dwarf2_get_dwz_file (); + struct mapped_index dwz_map; + const gdb_byte *dwz_types_ignore; + offset_type dwz_types_elements_ignore; + + if (!read_index_from_section (objfile, bfd_get_filename (dwz->dwz_bfd), + 1, + &dwz->gdb_index, &dwz_map, + &dwz_list, &dwz_list_elements, + &dwz_types_ignore, + &dwz_types_elements_ignore)) + { + warning (_("could not read '.gdb_index' section from %s; skipping"), + bfd_get_filename (dwz->dwz_bfd)); + return 0; + } + } + + create_cus_from_index (objfile, cu_list, cu_list_elements, dwz_list, + dwz_list_elements); + if (types_list_elements) { struct dwarf2_section_info *section; @@ -2239,13 +2803,14 @@ dwarf2_read_index (struct objfile *objfile) section = VEC_index (dwarf2_section_info_def, dwarf2_per_objfile->types, 0); - if (!create_signatured_type_table_from_index (objfile, section, - types_list, - types_list_elements)) - return 0; + create_signatured_type_table_from_index (objfile, section, types_list, + types_list_elements); } - create_addrmap_from_index (objfile, map); + create_addrmap_from_index (objfile, &local_map); + + map = obstack_alloc (&objfile->objfile_obstack, sizeof (struct mapped_index)); + *map = local_map; dwarf2_per_objfile->index_table = map; dwarf2_per_objfile->using_index = 1; @@ -2265,74 +2830,52 @@ 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 dwarf2_per_cu_data *lh_cu; struct line_header *lh; struct attribute *attr; - struct cleanup *cleanups; - struct die_info *comp_unit_die; - struct dwarf2_section_info* sec; - gdb_byte *info_ptr, *buffer; - int has_children, i; - struct dwarf2_cu cu; - unsigned int bytes_read, buffer_size; - struct die_reader_specs reader_specs; - char *name, *comp_dir; + int i; + const 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_types_section) - sec = this_cu->debug_types_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; - - info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr, - buffer, buffer_size, - abfd, - this_cu->debug_types_section != NULL); - - /* Skip dummy compilation units. */ - if (info_ptr >= buffer + buffer_size - || peek_abbrev_code (abfd, info_ptr) == 0) + /* Our callers never want to match partial units -- instead they + will match the enclosing full CU. */ + if (comp_unit_die->tag == DW_TAG_partial_unit) { - do_cleanups (cleanups); - return NULL; + this_cu->v.quick->no_file_data = 1; + return; } - this_cu->cu = &cu; - cu.per_cu = this_cu; - - dwarf2_read_abbrevs (abfd, &cu); - make_cleanup (dwarf2_free_abbrev_table, &cu); + /* If we're reading the line header for TUs, store it in the "per_cu" + for tu_group. */ + if (this_cu->is_debug_types) + { + struct type_unit_group *tu_group = data; - init_cu_die_reader (&reader_specs, &cu); - read_full_die (&reader_specs, &comp_unit_die, info_ptr, - &has_children); + gdb_assert (tu_group != NULL); + lh_cu = &tu_group->per_cu; + } + else + lh_cu = this_cu; 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; @@ -2341,31 +2884,31 @@ dw2_get_file_names (struct objfile *objfile, /* We may have already read in this line header (TU line header sharing). If we have we're done. */ - find_entry.offset = line_offset; + find_entry.hash.dwo_unit = cu->dwo_unit; + find_entry.hash.line_offset.sect_off = line_offset; slot = htab_find_slot (dwarf2_per_objfile->quick_file_names_table, &find_entry, INSERT); if (*slot != NULL) { - do_cleanups (cleanups); - this_cu->v.quick->file_names = *slot; - return *slot; + lh_cu->v.quick->file_names = *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; + lh_cu->v.quick->no_file_data = 1; + return; } qfn = obstack_alloc (&objfile->objfile_obstack, sizeof (*qfn)); - qfn->offset = line_offset; + qfn->hash.dwo_unit = cu->dwo_unit; + qfn->hash.line_offset.sect_off = line_offset; 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, @@ -2375,10 +2918,44 @@ 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; + lh_cu->v.quick->file_names = 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) +{ + /* For TUs this should only be called on the parent group. */ + if (this_cu->is_debug_types) + gdb_assert (IS_TYPE_UNIT_GROUP (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) + { + struct type_unit_group *tu_group = this_cu->type_unit_group; + + init_cutu_and_read_dies (tu_group->t.first_tu, NULL, 0, 0, + dw2_get_file_names_reader, tu_group); + } + 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 @@ -2405,7 +2982,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. */ @@ -2444,8 +3021,7 @@ dw2_forget_cached_source_info (struct objfile *objfile) 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, + const char *name, const char *real_path, int (*callback) (struct symtab *, void *), void *data) { @@ -2457,9 +3033,9 @@ dw2_map_expand_apply (struct objfile *objfile, /* This may expand more than one symtab, and we want to iterate over all of them. */ - dw2_instantiate_symtab (objfile, per_cu); + dw2_instantiate_symtab (per_cu); - return iterate_over_some_symtabs (name, full_path, real_path, callback, data, + return iterate_over_some_symtabs (name, real_path, callback, data, objfile->symtabs, last_made); } @@ -2467,22 +3043,22 @@ dw2_map_expand_apply (struct objfile *objfile, static int dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name, - const char *full_path, const char *real_path, + const char *real_path, int (*callback) (struct symtab *, void *), void *data) { int i; const char *name_basename = lbasename (name); - int check_basename = name_basename == name; - struct dwarf2_per_cu_data *base_cu = NULL; dw2_setup (objfile); - for (i = 0; i < (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_comp_units); ++i) + /* The rule is CUs specify all the files, including those used by + any TU, so there's no need to scan TUs here. */ + + for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) { int j; - struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); + struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i); struct quick_file_names *file_data; /* We only need to look at symtabs not already expanded. */ @@ -2496,50 +3072,37 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name, for (j = 0; j < file_data->num_file_names; ++j) { const char *this_name = file_data->file_names[j]; + const char *this_real_name; - if (FILENAME_CMP (name, this_name) == 0) + if (compare_filenames_for_search (this_name, name)) { - if (dw2_map_expand_apply (objfile, per_cu, - name, full_path, real_path, + if (dw2_map_expand_apply (objfile, per_cu, name, 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) + this_real_name = dw2_get_real_path (objfile, file_data, j); + if (compare_filenames_for_search (this_real_name, name)) { - const char *this_real_name = dw2_get_real_path (objfile, - file_data, j); - - if (this_real_name != NULL - && FILENAME_CMP (full_path, this_real_name) == 0) - { - if (dw2_map_expand_apply (objfile, per_cu, - name, full_path, real_path, - callback, data)) - return 1; - } + if (dw2_map_expand_apply (objfile, per_cu, name, real_path, + callback, data)) + return 1; } if (real_path != NULL) { - const char *this_real_name = dw2_get_real_path (objfile, - file_data, j); - + gdb_assert (IS_ABSOLUTE_PATH (real_path)); + gdb_assert (IS_ABSOLUTE_PATH (name)); if (this_real_name != NULL && FILENAME_CMP (real_path, this_real_name) == 0) { - if (dw2_map_expand_apply (objfile, per_cu, - name, full_path, real_path, + if (dw2_map_expand_apply (objfile, per_cu, name, real_path, callback, data)) return 1; } @@ -2547,60 +3110,171 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name, } } - if (base_cu) - { - if (dw2_map_expand_apply (objfile, base_cu, - name, full_path, real_path, - callback, data)) - return 1; - } - return 0; } -static struct symtab * -dw2_lookup_symbol (struct objfile *objfile, int block_index, - const char *name, domain_enum domain) +/* Struct used to manage iterating over all CUs looking for a symbol. */ + +struct dw2_symtab_iterator { - /* We do all the work in the pre_expand_symtabs_matching hook - instead. */ - return NULL; -} + /* The internalized form of .gdb_index. */ + struct mapped_index *index; + /* If non-zero, only look for symbols that match BLOCK_INDEX. */ + int want_specific_block; + /* One of GLOBAL_BLOCK or STATIC_BLOCK. + Unused if !WANT_SPECIFIC_BLOCK. */ + int block_index; + /* The kind of symbol we're looking for. */ + domain_enum domain; + /* The list of CUs from the index entry of the symbol, + or NULL if not found. */ + offset_type *vec; + /* The next element in VEC to look at. */ + int next; + /* The number of elements in VEC, or zero if there is no match. */ + int length; +}; -/* A helper function that expands all symtabs that hold an object - named NAME. */ +/* Initialize the index symtab iterator ITER. + If WANT_SPECIFIC_BLOCK is non-zero, only look for symbols + in block BLOCK_INDEX. Otherwise BLOCK_INDEX is ignored. */ static void -dw2_do_expand_symtabs_matching (struct objfile *objfile, const char *name) -{ - dw2_setup (objfile); - - /* index_table is NULL if OBJF_READNOW. */ - if (dwarf2_per_objfile->index_table) +dw2_symtab_iter_init (struct dw2_symtab_iterator *iter, + struct mapped_index *index, + int want_specific_block, + int block_index, + domain_enum domain, + const char *name) +{ + iter->index = index; + iter->want_specific_block = want_specific_block; + iter->block_index = block_index; + iter->domain = domain; + iter->next = 0; + + if (find_slot_in_mapped_hash (index, name, &iter->vec)) + iter->length = MAYBE_SWAP (*iter->vec); + else { - offset_type *vec; + iter->vec = NULL; + iter->length = 0; + } +} - if (find_slot_in_mapped_hash (dwarf2_per_objfile->index_table, - name, &vec)) +/* Return the next matching CU or NULL if there are no more. */ + +static struct dwarf2_per_cu_data * +dw2_symtab_iter_next (struct dw2_symtab_iterator *iter) +{ + for ( ; iter->next < iter->length; ++iter->next) + { + offset_type cu_index_and_attrs = + MAYBE_SWAP (iter->vec[iter->next + 1]); + offset_type cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs); + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (cu_index); + int want_static = iter->block_index != GLOBAL_BLOCK; + /* This value is only valid for index versions >= 7. */ + int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs); + gdb_index_symbol_kind symbol_kind = + GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs); + /* Only check the symbol attributes if they're present. + Indices prior to version 7 don't record them, + and indices >= 7 may elide them for certain symbols + (gold does this). */ + int attrs_valid = + (iter->index->version >= 7 + && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE); + + /* Skip if already read in. */ + if (per_cu->v.quick->symtab) + continue; + + if (attrs_valid + && iter->want_specific_block + && want_static != is_static) + continue; + + /* Only check the symbol's kind if it has one. */ + if (attrs_valid) { - offset_type i, len = MAYBE_SWAP (*vec); - for (i = 0; i < len; ++i) + switch (iter->domain) { - 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); + case VAR_DOMAIN: + if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE + && symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION + /* Some types are also in VAR_DOMAIN. */ + && symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE) + continue; + break; + case STRUCT_DOMAIN: + if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE) + continue; + break; + case LABEL_DOMAIN: + if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER) + continue; + break; + default: + break; } } + + ++iter->next; + return per_cu; } + + return NULL; } -static void -dw2_pre_expand_symtabs_matching (struct objfile *objfile, - enum block_enum block_kind, const char *name, - domain_enum domain) +static struct symtab * +dw2_lookup_symbol (struct objfile *objfile, int block_index, + const char *name, domain_enum domain) { - dw2_do_expand_symtabs_matching (objfile, name); + struct symtab *stab_best = NULL; + struct mapped_index *index; + + dw2_setup (objfile); + + index = dwarf2_per_objfile->index_table; + + /* index is NULL if OBJF_READNOW. */ + if (index) + { + struct dw2_symtab_iterator iter; + struct dwarf2_per_cu_data *per_cu; + + dw2_symtab_iter_init (&iter, index, 1, block_index, domain, name); + + while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL) + { + struct symbol *sym = NULL; + struct symtab *stab = dw2_instantiate_symtab (per_cu); + + /* Some caution must be observed with overloaded functions + and methods, since the index will not contain any overload + information (but NAME might contain it). */ + if (stab->primary) + { + struct blockvector *bv = BLOCKVECTOR (stab); + struct block *block = BLOCKVECTOR_BLOCK (bv, block_index); + + sym = lookup_block_symbol (block, name, domain); + } + + if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0) + { + if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) + return stab; + + stab_best = stab; + } + + /* Keep looking through other CUs. */ + } + } + + return stab_best; } static void @@ -2611,7 +3285,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); @@ -2638,7 +3312,25 @@ static void dw2_expand_symtabs_for_function (struct objfile *objfile, const char *func_name) { - dw2_do_expand_symtabs_matching (objfile, func_name); + struct mapped_index *index; + + dw2_setup (objfile); + + index = dwarf2_per_objfile->index_table; + + /* index is NULL if OBJF_READNOW. */ + if (index) + { + struct dw2_symtab_iterator iter; + struct dwarf2_per_cu_data *per_cu; + + /* Note: It doesn't matter what we pass for block_index here. */ + dw2_symtab_iter_init (&iter, index, 0, GLOBAL_BLOCK, VAR_DOMAIN, + func_name); + + while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL) + dw2_instantiate_symtab (per_cu); + } } static void @@ -2649,17 +3341,17 @@ 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); } } static void -dw2_expand_symtabs_with_filename (struct objfile *objfile, - const char *filename) +dw2_expand_symtabs_with_fullname (struct objfile *objfile, + const char *fullname) { int i; @@ -2686,22 +3378,44 @@ dw2_expand_symtabs_with_filename (struct objfile *objfile, for (j = 0; j < file_data->num_file_names; ++j) { - const char *this_name = file_data->file_names[j]; - if (FILENAME_CMP (this_name, filename) == 0) + const char *this_fullname = file_data->file_names[j]; + + if (filename_cmp (this_fullname, fullname) == 0) { - dw2_instantiate_symtab (objfile, per_cu); + dw2_instantiate_symtab (per_cu); break; } } } } +/* A helper function for dw2_find_symbol_file that finds the primary + file name for a given CU. This is a die_reader_func. */ + +static void +dw2_get_primary_filename_reader (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct die_info *comp_unit_die, + int has_children, + void *data) +{ + const char **result_ptr = data; + struct dwarf2_cu *cu = reader->cu; + struct attribute *attr; + + attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu); + if (attr == NULL) + *result_ptr = NULL; + else + *result_ptr = DW_STRING (attr); +} + static const char * dw2_find_symbol_file (struct objfile *objfile, const char *name) { struct dwarf2_per_cu_data *per_cu; offset_type *vec; - struct quick_file_names *file_data; + const char *filename; dw2_setup (objfile); @@ -2710,16 +3424,18 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name) { 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); + ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s) + { + 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; - } + if (sym) + { + /* Only file extension of returned filename is recognized. */ + return SYMBOL_SYMTAB (sym)->filename; + } + } return NULL; } @@ -2732,13 +3448,19 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name) should be rewritten so that it doesn't require a custom hook. It could just use the ordinary symbol tables. */ /* vec[0] is the length, which must always be >0. */ - per_cu = dw2_get_cu (MAYBE_SWAP (vec[1])); + per_cu = dw2_get_cu (GDB_INDEX_CU_VALUE (MAYBE_SWAP (vec[1]))); - file_data = dw2_get_file_names (objfile, per_cu); - if (file_data == NULL) - return NULL; + if (per_cu->v.quick->symtab != NULL) + { + /* Only file extension of returned filename is recognized. */ + return per_cu->v.quick->symtab->filename; + } + + init_cutu_and_read_dies (per_cu, NULL, 0, 0, + dw2_get_primary_filename_reader, &filename); - return file_data->file_names[file_data->num_file_names - 1]; + /* Only file extension of returned filename is recognized. */ + return filename; } static void @@ -2757,8 +3479,8 @@ 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 struct language_defn *, const char *, void *), + int (*file_matcher) (const char *, void *, int basenames), + int (*name_matcher) (const char *, void *), enum search_domain kind, void *data) { @@ -2774,32 +3496,81 @@ dw2_expand_symtabs_matching 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; + 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); - /* We only need to look at symtabs not already expanded. */ - if (per_cu->v.quick->symtab) - continue; + /* The rule is CUs specify all the files, including those used by + any TU, so there's no need to scan TUs here. */ - file_data = dw2_get_file_names (objfile, per_cu); - if (file_data == NULL) - continue; + for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) + { + int j; + struct dwarf2_per_cu_data *per_cu = dw2_get_primary_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) + { + const char *this_real_name; + + if (file_matcher (file_data->file_names[j], data, 0)) + { + per_cu->v.quick->mark = 1; + break; + } + + /* Before we invoke realpath, which can get expensive when many + files are involved, do a quick comparison of the basenames. */ + if (!basenames_may_differ + && !file_matcher (lbasename (file_data->file_names[j]), + data, 1)) + continue; + + this_real_name = dw2_get_real_path (objfile, file_data, j); + if (file_matcher (this_real_name, data, 0)) + { + 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) { @@ -2812,7 +3583,7 @@ dw2_expand_symtabs_matching name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]); - if (! (*name_matcher) (current_language, name, data)) + if (! (*name_matcher) (name, data)) continue; /* The name was matched, now expand corresponding CUs that were @@ -2823,14 +3594,73 @@ dw2_expand_symtabs_matching for (vec_idx = 0; vec_idx < vec_len; ++vec_idx) { struct dwarf2_per_cu_data *per_cu; + offset_type cu_index_and_attrs = MAYBE_SWAP (vec[vec_idx + 1]); + gdb_index_symbol_kind symbol_kind = + GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs); + int cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs); + + /* Don't crash on bad data. */ + if (cu_index >= (dwarf2_per_objfile->n_comp_units + + dwarf2_per_objfile->n_type_units)) + continue; + + /* Only check the symbol's kind if it has one. + Indices prior to version 7 don't record it. */ + if (index->version >= 7) + { + switch (kind) + { + case VARIABLES_DOMAIN: + if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE) + continue; + break; + case FUNCTIONS_DOMAIN: + if (symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION) + continue; + break; + case TYPES_DOMAIN: + if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE) + continue; + break; + default: + break; + } + } - per_cu = dw2_get_cu (MAYBE_SWAP (vec[vec_idx + 1])); + per_cu = dw2_get_cu (cu_index); 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; + + if (symtab->includes == NULL) + return NULL; + + for (i = 0; symtab->includes[i]; ++i) + { + struct symtab *s = symtab->includes[i]; + + 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, @@ -2839,6 +3669,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); @@ -2853,7 +3684,9 @@ 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 @@ -2861,15 +3694,36 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun, 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); - for (i = 0; i < (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_comp_units); ++i) + /* The rule is CUs specify all the files, including those used by + any TU, so there's no need to scan TUs here. + We can ignore file names coming from already-expanded CUs. */ + + for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) { - int j; struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); + + 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; ++i) + { + int j; + struct dwarf2_per_cu_data *per_cu = dw2_get_primary_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) @@ -2879,6 +3733,14 @@ 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; @@ -2890,6 +3752,8 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun, (*fun) (file_data->file_names[j], this_real_name, data); } } + + do_cleanups (cleanup); } static int @@ -2905,13 +3769,12 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions = dw2_forget_cached_source_info, dw2_map_symtabs_matching_filename, dw2_lookup_symbol, - dw2_pre_expand_symtabs_matching, dw2_print_stats, dw2_dump, dw2_relocate, dw2_expand_symtabs_for_function, dw2_expand_all_symtabs, - dw2_expand_symtabs_with_filename, + dw2_expand_symtabs_with_fullname, dw2_find_symbol_file, dw2_map_matching_symbols, dw2_expand_symtabs_matching, @@ -2935,12 +3798,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); @@ -2967,25 +3830,75 @@ dwarf2_initialize_objfile (struct objfile *objfile) void dwarf2_build_psymtabs (struct objfile *objfile) { + volatile struct gdb_exception except; + if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0) { init_psymbol_list (objfile, 1024); } - dwarf2_build_psymtabs_hard (objfile); + TRY_CATCH (except, RETURN_MASK_ERROR) + { + /* This isn't really ideal: all the data we allocate on the + objfile's obstack is still uselessly kept around. However, + freeing it seems unsafe. */ + struct cleanup *cleanups = make_cleanup_discard_psymtabs (objfile); + + dwarf2_build_psymtabs_hard (objfile); + discard_cleanups (cleanups); + } + if (except.reason < 0) + exception_print (gdb_stderr, except); +} + +/* Return the total length of the CU described by HEADER. */ + +static unsigned int +get_cu_length (const struct comp_unit_head *header) +{ + return header->initial_length_size + header->length; } /* 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) +{ + sect_offset bottom = { cu_header->offset.sect_off }; + sect_offset top = { cu_header->offset.sect_off + get_cu_length (cu_header) }; + + return (offset.sect_off >= bottom.sect_off && offset.sect_off < top.sect_off); +} + +/* Find the base address of the compilation unit for range lists and + location lists. It will normally be specified by DW_AT_low_pc. + In DWARF-3 draft 4, the base address could be overridden by + DW_AT_entry_pc. It's been removed, but GCC still uses this for + compilation units with discontinuous ranges. */ + +static void +dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu) { - unsigned int bottom = cu_header->offset; - unsigned int top = (cu_header->offset - + cu_header->length - + cu_header->initial_length_size); + struct attribute *attr; - return (offset >= bottom && offset < top); + cu->base_known = 0; + cu->base_address = 0; + + attr = dwarf2_attr (die, DW_AT_entry_pc, cu); + if (attr) + { + cu->base_address = DW_ADDR (attr); + cu->base_known = 1; + } + else + { + attr = dwarf2_attr (die, DW_AT_low_pc, cu); + if (attr) + { + cu->base_address = DW_ADDR (attr); + cu->base_known = 1; + } + } } /* Read in the comp unit header information from the debug_info at info_ptr. @@ -3005,8 +3918,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; @@ -3019,47 +3932,82 @@ read_comp_unit_head (struct comp_unit_head *cu_header, return info_ptr; } -/* Read in a CU header and perform some basic error checking. */ +/* Helper function that returns the proper abbrev section for + THIS_CU. */ -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, int is_debug_types_section) +static struct dwarf2_section_info * +get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu) { - gdb_byte *beg_of_comp_unit = info_ptr; + struct dwarf2_section_info *abbrev; - header->offset = beg_of_comp_unit - buffer; + if (this_cu->is_dwz) + abbrev = &dwarf2_get_dwz_file ()->abbrev; + else + abbrev = &dwarf2_per_objfile->abbrev; - info_ptr = read_comp_unit_head (header, info_ptr, abfd); + return abbrev; +} - /* 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; +/* 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. */ - header->first_die_offset = info_ptr - beg_of_comp_unit; +static void +error_check_comp_unit_head (struct comp_unit_head *header, + struct dwarf2_section_info *section, + struct dwarf2_section_info *abbrev_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 - >= dwarf2_section_size (dwarf2_per_objfile->objfile, - &dwarf2_per_objfile->abbrev)) + if (header->abbrev_offset.sect_off + >= dwarf2_section_size (dwarf2_per_objfile->objfile, abbrev_section)) 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)); + (long) header->abbrev_offset.sect_off, (long) header->offset.sect_off, + filename); - if (beg_of_comp_unit + header->length + header->initial_length_size - > buffer + buffer_size) + /* Cast to unsigned long to use 64-bit arithmetic when possible to + avoid potential 32-bit overflow. */ + if (((unsigned long) header->offset.sect_off + get_cu_length (header)) + > 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, + struct dwarf2_section_info *abbrev_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, abbrev_section); return info_ptr; } @@ -3068,35 +4016,72 @@ 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, + struct dwarf2_section_info *abbrev_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); + + /* 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; - types_ptr = read_comp_unit_head (cu_header, types_ptr, abfd); + header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit; - *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; + error_check_comp_unit_head (header, section, abbrev_section); - return types_ptr; + return info_ptr; } -/* Allocate a new partial symtab for file named NAME and mark this new - partial symtab as being an include of PST. */ +/* Fetch the abbreviation table offset from a comp or type unit header. */ -static void -dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst, - struct objfile *objfile) +static sect_offset +read_abbrev_offset (struct dwarf2_section_info *section, + sect_offset offset) +{ + bfd *abfd = section->asection->owner; + gdb_byte *info_ptr; + unsigned int length, initial_length_size, offset_size; + sect_offset abbrev_offset; + + dwarf2_read_section (dwarf2_per_objfile->objfile, section); + info_ptr = section->buffer + offset.sect_off; + length = read_initial_length (abfd, info_ptr, &initial_length_size); + offset_size = initial_length_size == 4 ? 4 : 8; + info_ptr += initial_length_size + 2 /*version*/; + abbrev_offset.sect_off = read_offset_1 (abfd, info_ptr, offset_size); + return abbrev_offset; +} + +/* Allocate a new partial symtab for file named NAME and mark this new + partial symtab as being an include of PST. */ + +static void +dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst, + struct objfile *objfile) { struct partial_symtab *subpst = allocate_psymtab (name, objfile); + if (!IS_ABSOLUTE_PATH (subpst->filename)) + { + /* It shares objfile->objfile_obstack. */ + subpst->dirname = pst->dirname; + } + subpst->section_offsets = pst->section_offsets; subpst->textlow = 0; subpst->texthigh = 0; @@ -3127,21 +4112,15 @@ 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. */ @@ -3152,16 +4131,16 @@ dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, } 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; @@ -3175,52 +4154,64 @@ 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; + struct signatured_type ***datap = datum; - **datap = &sigt->per_cu; + **datap = sigt; ++*datap; return 1; } /* 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. + Note: This function processes DWO files only, not DWP files. + 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; + struct dwarf2_section_info *abbrev_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; + + abbrev_section = (dwo_file != NULL + ? &dwo_file->sections.abbrev + : &dwarf2_per_objfile->abbrev); + + if (dwarf2_read_debug) + fprintf_unfiltered (gdb_stdlog, "Reading .debug_types%s for %s:\n", + dwo_file ? ".dwo" : "", + bfd_get_filename (abbrev_section->asection->owner)); 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; + struct dwarf2_section_info *abbrev_section; dwarf2_read_section (objfile, section); info_ptr = section->buffer; @@ -3228,110 +4219,166 @@ 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 (dwo_file) + abbrev_section = &dwo_file->sections.abbrev; + else + abbrev_section = &dwarf2_per_objfile->abbrev; + 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"); + /* 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) - { - complaint (&symfile_complaints, - _("debug type entry runs off end " - "of `.debug_types' section, ignored")); - break; - } + ptr = read_and_check_type_unit_head (&header, section, + abbrev_section, ptr, + &signature, &type_offset_in_tu); - 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); - ptr += offset_size; + length = get_cu_length (&header); /* Skip dummy type units. */ - if (ptr >= end_ptr || peek_abbrev_code (objfile->obfd, ptr) == 0) + if (ptr >= info_ptr + length + || peek_abbrev_code (abfd, ptr) == 0) { - info_ptr = info_ptr + initial_length_size + length; + info_ptr += length; continue; } - 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_types_section = section; - type_sig->per_cu.offset = offset; + 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; + } - 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) + if (dwarf2_read_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 signatured_type **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 - * 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); + dwarf2_per_objfile->n_type_units + * sizeof (struct signatured_type *)); + 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; @@ -3339,1109 +4386,1919 @@ 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; entry = htab_find (dwarf2_per_objfile->signatured_types, &find_entry); return entry; } + +/* Low level DIE reading support. */ /* Initialize a die_reader_specs struct from a dwarf2_cu struct. */ 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_types_section) - { - gdb_assert (cu->per_cu->debug_types_section->readin); - reader->buffer = cu->per_cu->debug_types_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; + reader->buffer_end = section->buffer + section->size; } -/* Find the base address of the compilation unit for range lists and - location lists. It will normally be specified by DW_AT_low_pc. - In DWARF-3 draft 4, the base address could be overridden by - DW_AT_entry_pc. It's been removed, but GCC still uses this for - compilation units with discontinuous ranges. */ +/* Initialize a CU (or TU) and read its DIEs. + If the CU defers to a DWO file, read the DWO file as well. + + ABBREV_TABLE, if non-NULL, is the abbreviation table to use. + Otherwise the table specified in the comp unit header is read in and used. + This is an optimization for when we already have the abbrev table. + + 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 -dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu) -{ +init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, + struct abbrev_table *abbrev_table, + 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; + int has_children; struct attribute *attr; + struct cleanup *cleanups, *free_cu_cleanup = NULL; + struct signatured_type *sig_type = NULL; + struct dwarf2_section_info *abbrev_section; + /* Non-zero if CU currently points to a DWO file and we need to + reread it. When this happens we need to reread the skeleton die + before we can reread the DWO file. */ + int rereading_dwo_cu = 0; - cu->base_known = 0; - cu->base_address = 0; + if (dwarf2_die_debug) + fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset 0x%x\n", + this_cu->is_debug_types ? "type" : "comp", + this_cu->offset.sect_off); - attr = dwarf2_attr (die, DW_AT_entry_pc, cu); - if (attr) + if (use_existing_cu) + gdb_assert (keep); + + cleanups = make_cleanup (null_cleanup, NULL); + + /* This is cheap if the section is already read in. */ + dwarf2_read_section (objfile, section); + + begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off; + + abbrev_section = get_abbrev_section_for_cu (this_cu); + + if (use_existing_cu && this_cu->cu != NULL) { - cu->base_address = DW_ADDR (attr); - cu->base_known = 1; + cu = this_cu->cu; + + /* If this CU is from a DWO file we need to start over, we need to + refetch the attributes from the skeleton CU. + This could be optimized by retrieving those attributes from when we + were here the first time: the previous comp_unit_die was stored in + comp_unit_obstack. But there's no data yet that we need this + optimization. */ + if (cu->dwo_unit != NULL) + rereading_dwo_cu = 1; } else { - attr = dwarf2_attr (die, DW_AT_low_pc, cu); - if (attr) - { - cu->base_address = DW_ADDR (attr); - cu->base_known = 1; - } - } -} + /* If !use_existing_cu, this_cu->cu must be NULL. */ + gdb_assert (this_cu->cu == NULL); -/* 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. */ + cu = xmalloc (sizeof (*cu)); + init_one_comp_unit (cu, this_cu); -static gdb_byte * -process_psymtab_comp_unit (struct objfile *objfile, - struct dwarf2_per_cu_data *this_cu, - gdb_byte *buffer, gdb_byte *info_ptr, - unsigned int buffer_size) -{ - bfd *abfd = objfile->obfd; - gdb_byte *beg_of_comp_unit = info_ptr; - 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; - struct attribute *attr; - CORE_ADDR best_lowpc = 0, best_highpc = 0; - struct die_reader_specs reader_specs; - const char *filename; + /* If an error occurs while loading, release our storage. */ + free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu); + } - init_one_comp_unit (&cu, objfile); - back_to_inner = make_cleanup (free_stack_comp_unit, &cu); + if (cu->header.first_die_offset.cu_off != 0 && ! rereading_dwo_cu) + { + /* We already have the header, there's no need to read it in again. */ + info_ptr += cu->header.first_die_offset.cu_off; + } + else + { + if (this_cu->is_debug_types) + { + ULONGEST signature; + cu_offset type_offset_in_tu; + + info_ptr = read_and_check_type_unit_head (&cu->header, section, + abbrev_section, info_ptr, + &signature, + &type_offset_in_tu); + + /* Since per_cu is the first member of struct signatured_type, + we can go from a pointer to one to a pointer to the other. */ + sig_type = (struct signatured_type *) this_cu; + gdb_assert (sig_type->signature == signature); + gdb_assert (sig_type->type_offset_in_tu.cu_off + == type_offset_in_tu.cu_off); + gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off); + + /* LENGTH has not been set yet for type units if we're + using .gdb_index. */ + this_cu->length = get_cu_length (&cu->header); + + /* 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, + abbrev_section, + info_ptr, 0); - info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr, - buffer, buffer_size, - abfd, - this_cu->debug_types_section != NULL); + gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off); + gdb_assert (this_cu->length == get_cu_length (&cu->header)); + } + } /* Skip dummy compilation units. */ - if (info_ptr >= buffer + buffer_size + 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; } - cu.list_in_scope = &file_symbols; - - /* If this compilation unit was already read in, free the - cached copy in order to read it in again. This is - necessary because we skipped some symbols when we first - read in the compilation unit (see load_partial_dies). - This problem could be avoided, but the benefit is - unclear. */ - if (this_cu->cu != NULL) - free_one_cached_comp_unit (this_cu->cu); - - /* Note that this is a pointer to our stack frame, being - added to a global data structure. It will be cleaned up - in free_stack_comp_unit when we finish with this - compilation unit. */ - this_cu->cu = &cu; - cu.per_cu = this_cu; - - /* Read the abbrevs for this compilation unit into a table. */ - dwarf2_read_abbrevs (abfd, &cu); - 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); - - if (this_cu->debug_types_section) + /* If we don't have them yet, read the abbrevs for this compilation unit. + And if we need to read them now, make sure they're freed when we're + done. Note that it's important that if the CU had an abbrev table + on entry we don't free it when we're done: Somewhere up the call stack + it may be in use. */ + if (abbrev_table != 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; + gdb_assert (cu->abbrev_table == NULL); + gdb_assert (cu->header.abbrev_offset.sect_off + == abbrev_table->offset.sect_off); + cu->abbrev_table = abbrev_table; } - else if (comp_unit_die->tag == DW_TAG_partial_unit) + else if (cu->abbrev_table == NULL) { - info_ptr = (beg_of_comp_unit + cu.header.length - + cu.header.initial_length_size); - do_cleanups (back_to_inner); - return info_ptr; + dwarf2_read_abbrevs (cu, abbrev_section); + make_cleanup (dwarf2_free_abbrev_table, cu); + } + else if (rereading_dwo_cu) + { + dwarf2_free_abbrev_table (cu); + dwarf2_read_abbrevs (cu, abbrev_section); } - prepare_one_comp_unit (&cu, comp_unit_die); - - /* Allocate a new partial symbol table structure. */ - attr = dwarf2_attr (comp_unit_die, DW_AT_name, &cu); - if (attr == NULL || !DW_STRING (attr)) - filename = ""; - else - filename = DW_STRING (attr); - pst = start_psymtab_common (objfile, objfile->section_offsets, - filename, - /* TEXTLOW and TEXTHIGH are set below. */ - 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); - if (attr != NULL) - pst->dirname = DW_STRING (attr); - - pst->read_symtab_private = this_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); - baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + /* 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) + { + const char *dwo_name = DW_STRING (attr); + const char *comp_dir_string; + struct dwo_unit *dwo_unit; + ULONGEST signature; /* Or dwo_id. */ + struct attribute *comp_dir, *stmt_list, *low_pc, *high_pc, *ranges; + int i,num_extra_attrs; + struct dwarf2_section_info *dwo_abbrev_section; + + 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. */ + + /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the + DWO file. */ + stmt_list = NULL; + 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); + comp_dir = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, 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; + attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_addr_base, cu); + if (attr) + cu->addr_base = DW_UNSND (attr); - /* Store the function that reads in the rest of the symbol table. */ - pst->read_symtab = dwarf2_psymtab_to_symtab; + /* There should be a DW_AT_ranges_base attribute here (if needed). + We need the value before we can process DW_AT_ranges. */ + cu->ranges_base = 0; + attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_ranges_base, cu); + if (attr) + cu->ranges_base = DW_UNSND (attr); - this_cu->v.psymtab = pst; + 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); + } - dwarf2_find_base_address (comp_unit_die, &cu); + /* We may need the comp_dir in order to find the DWO file. */ + comp_dir_string = NULL; + if (comp_dir) + comp_dir_string = DW_STRING (comp_dir); - /* Possibly set the default values of LOWPC and HIGHPC from - `DW_AT_ranges'. */ - has_pc_info = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc, - &best_highpc, &cu, pst); - if (has_pc_info == 1 && best_lowpc < best_highpc) - /* Store the contiguous range if it is not empty; it can be empty for - CUs with no code. */ - addrmap_set_empty (objfile->psymtabs_addrmap, - best_lowpc + baseaddr, - best_highpc + baseaddr - 1, pst); + if (this_cu->is_debug_types) + dwo_unit = lookup_dwo_type_unit (sig_type, dwo_name, comp_dir_string); + else + dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir_string, + signature); - /* Check if comp unit has_children. - If so, read the rest of the partial symbols from this comp unit. - If not, there's no more debug_info for this comp unit. */ - if (has_children) - { - struct partial_die_info *first_die; - CORE_ADDR lowpc, highpc; + 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); + } - lowpc = ((CORE_ADDR) -1); - highpc = ((CORE_ADDR) 0); + /* Set up for reading the DWO CU/TU. */ + cu->dwo_unit = dwo_unit; + section = dwo_unit->info_or_types_section; + dwarf2_read_section (objfile, section); + begin_info_ptr = info_ptr = section->buffer + dwo_unit->offset.sect_off; + dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev; + init_cu_die_reader (&reader, cu, section, dwo_unit->dwo_file); - first_die = load_partial_dies (abfd, buffer, info_ptr, 1, &cu); + if (this_cu->is_debug_types) + { + ULONGEST signature; + cu_offset type_offset_in_tu; + + info_ptr = read_and_check_type_unit_head (&cu->header, section, + dwo_abbrev_section, + info_ptr, + &signature, + &type_offset_in_tu); + gdb_assert (sig_type->signature == signature); + gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off); + /* For DWOs coming from DWP files, we don't know the CU length + nor the type's offset in the TU until now. */ + dwo_unit->length = get_cu_length (&cu->header); + dwo_unit->type_offset_in_tu = type_offset_in_tu; + + /* 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, + dwo_abbrev_section, + info_ptr, 0); + gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off); + /* For DWOs coming from DWP files, we don't know the CU length + until now. */ + dwo_unit->length = get_cu_length (&cu->header); + } - scan_partial_symbols (first_die, &lowpc, &highpc, - ! has_pc_info, &cu); + /* Discard the original CU's abbrev table, and read the DWO's. */ + if (abbrev_table == NULL) + { + dwarf2_free_abbrev_table (cu); + dwarf2_read_abbrevs (cu, dwo_abbrev_section); + } + else + { + dwarf2_read_abbrevs (cu, dwo_abbrev_section); + make_cleanup (dwarf2_free_abbrev_table, cu); + } - /* If we didn't find a lowpc, set it to highpc to avoid - complaints from `maint check'. */ - if (lowpc == ((CORE_ADDR) -1)) - lowpc = highpc; + /* 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) + + (comp_dir != 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; + if (comp_dir != NULL) + comp_unit_die->attrs[i++] = *comp_dir; + comp_unit_die->num_attrs += num_extra_attrs; - /* If the compilation unit didn't have an explicit address range, - then use the information extracted from its child dies. */ - if (! has_pc_info) + /* Skip dummy compilation units. */ + if (info_ptr >= begin_info_ptr + dwo_unit->length + || peek_abbrev_code (abfd, info_ptr) == 0) { - best_lowpc = lowpc; - best_highpc = highpc; + do_cleanups (cleanups); + return; } } - pst->textlow = best_lowpc + baseaddr; - pst->texthigh = best_highpc + baseaddr; - - pst->n_global_syms = objfile->global_psymbols.next - - (objfile->global_psymbols.list + pst->globals_offset); - pst->n_static_syms = objfile->static_psymbols.next - - (objfile->static_psymbols.list + pst->statics_offset); - sort_pst_symbols (pst); - info_ptr = (beg_of_comp_unit + cu.header.length - + cu.header.initial_length_size); + die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data); - if (this_cu->debug_types_section) + if (free_cu_cleanup != NULL) { - /* It's not clear we want to do anything with stmt lists here. - Waiting to see what gcc ultimately does. */ - } - else - { - /* Get the list of files included in the current compilation unit, - and build a psymtab for each of them. */ - dwarf2_build_include_psymtabs (&cu, comp_unit_die, pst); - } + if (keep) + { + /* We've successfully allocated this compilation unit. Let our + caller clean it up when finished with it. */ + discard_cleanups (free_cu_cleanup); - do_cleanups (back_to_inner); + /* 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); - return info_ptr; + /* 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); + } + + do_cleanups (cleanups); } -/* Traversal function for htab_traverse_noresize. - Process one .debug_types comp-unit. */ +/* Read CU/TU THIS_CU in section SECTION, + but do not follow DW_AT_GNU_dwo_name if present. + DWOP_FILE, if non-NULL, is the DWO/DWP file to read (the caller is assumed + to have already done the lookup to find the DWO/DWP file). -static int -process_type_comp_unit (void **slot, void *info) -{ - struct signatured_type *entry = (struct signatured_type *) *slot; - struct objfile *objfile = (struct objfile *) info; - struct dwarf2_per_cu_data *this_cu; + The caller is required to fill in THIS_CU->section, THIS_CU->offset, and + THIS_CU->is_debug_types, but nothing else. - this_cu = &entry->per_cu; + We fill in THIS_CU->length. - gdb_assert (this_cu->debug_types_section->readin); - process_psymtab_comp_unit (objfile, this_cu, - this_cu->debug_types_section->buffer, - (this_cu->debug_types_section->buffer - + this_cu->offset), - this_cu->debug_types_section->size); + WARNING: If THIS_CU is a "dummy CU" (used as filler by the incremental + linker) then DIE_READER_FUNC will not get called. - return 1; -} - -/* Subroutine of dwarf2_build_psymtabs_hard to simplify it. - Build partial symbol tables for the .debug_types comp-units. */ + 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 -build_type_psymtabs (struct objfile *objfile) +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) { - if (! create_debug_types_hash_table (objfile)) - return; + 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; - htab_traverse_noresize (dwarf2_per_objfile->signatured_types, - process_type_comp_unit, objfile); -} + if (dwarf2_die_debug) + fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset 0x%x\n", + this_cu->is_debug_types ? "type" : "comp", + this_cu->offset.sect_off); -/* A cleanup function that clears objfile's psymtabs_addrmap field. */ + gdb_assert (this_cu->cu == NULL); -static void -psymtabs_addrmap_cleanup (void *o) -{ - struct objfile *objfile = o; + /* This is cheap if the section is already read in. */ + dwarf2_read_section (objfile, section); - objfile->psymtabs_addrmap = NULL; -} + init_one_comp_unit (&cu, this_cu); -/* Build the partial symbol table by doing a quick pass through the - .debug_info and .debug_abbrev sections. */ + cleanups = make_cleanup (free_stack_comp_unit, &cu); -static void -dwarf2_build_psymtabs_hard (struct objfile *objfile) -{ - gdb_byte *info_ptr; - struct cleanup *back_to, *addrmap_cleanup; - struct obstack temp_obstack; + begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off; + info_ptr = read_and_check_comp_unit_head (&cu.header, section, + abbrev_section, info_ptr, + this_cu->is_debug_types); - dwarf2_per_objfile->reading_partial_symbols = 1; + this_cu->length = get_cu_length (&cu.header); - dwarf2_read_section (objfile, &dwarf2_per_objfile->info); - info_ptr = dwarf2_per_objfile->info.buffer; + /* Skip dummy compilation units. */ + if (info_ptr >= begin_info_ptr + this_cu->length + || peek_abbrev_code (abfd, info_ptr) == 0) + { + do_cleanups (cleanups); + return; + } - /* Any cached compilation units will be linked by the per-objfile - read_in_chain. Make sure to free them when we're done. */ - back_to = make_cleanup (free_cached_comp_units, NULL); + dwarf2_read_abbrevs (&cu, abbrev_section); + make_cleanup (dwarf2_free_abbrev_table, &cu); - build_type_psymtabs (objfile); + init_cu_die_reader (&reader, &cu, section, dwo_file); + info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children); - create_all_comp_units (objfile); + die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data); - /* Create a temporary address map on a temporary obstack. We later - copy this to the final obstack. */ - obstack_init (&temp_obstack); - make_cleanup_obstack_free (&temp_obstack); - objfile->psymtabs_addrmap = addrmap_create_mutable (&temp_obstack); - addrmap_cleanup = make_cleanup (psymtabs_addrmap_cleanup, objfile); + do_cleanups (cleanups); +} - /* Since the objects we're extracting from .debug_info vary in - length, only the individual functions to extract them (like - read_comp_unit_head and load_partial_die) can really know whether - the buffer is large enough to hold another complete object. +/* Read 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. - 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. + 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. */ - For this loop condition, simply checking whether there's any data - left at all should be sufficient. */ +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, + get_abbrev_section_for_cu (this_cu), + NULL, + die_reader_func, data); +} - while (info_ptr < (dwarf2_per_objfile->info.buffer - + dwarf2_per_objfile->info.size)) - { - struct dwarf2_per_cu_data *this_cu; +/* Create a psymtab named NAME and assign it to PER_CU. - this_cu = dwarf2_find_comp_unit (info_ptr - - dwarf2_per_objfile->info.buffer, - objfile); + The caller must fill in the following details: + dirname, textlow, texthigh. */ - info_ptr = process_psymtab_comp_unit (objfile, this_cu, - dwarf2_per_objfile->info.buffer, - info_ptr, - dwarf2_per_objfile->info.size); - } +static struct partial_symtab * +create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name) +{ + struct objfile *objfile = per_cu->objfile; + struct partial_symtab *pst; - objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap, - &objfile->objfile_obstack); - discard_cleanups (addrmap_cleanup); + pst = start_psymtab_common (objfile, objfile->section_offsets, + name, 0, + objfile->global_psymbols.next, + objfile->static_psymbols.next); - do_cleanups (back_to); + pst->psymtabs_addrmap_supported = 1; + + /* This is the glue that links PST into GDB's symbol API. */ + pst->read_symtab_private = per_cu; + pst->read_symtab = dwarf2_read_symtab; + per_cu->v.psymtab = pst; + + return pst; } -/* Load the partial DIEs for a secondary CU into memory. */ +/* die_reader_func for process_psymtab_comp_unit. */ static void -load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu, - struct objfile *objfile) +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) { - bfd *abfd = objfile->obfd; - gdb_byte *info_ptr; - 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; + struct dwarf2_cu *cu = reader->cu; + struct objfile *objfile = cu->objfile; + struct dwarf2_per_cu_data *per_cu = cu->per_cu; + 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; + + gdb_assert (! per_cu->is_debug_types); + + 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); + if (attr == NULL || !DW_STRING (attr)) + filename = ""; + else + filename = DW_STRING (attr); + + pst = create_partial_symtab (per_cu, filename); + + /* This must be done before calling dwarf2_build_include_psymtabs. */ + attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu); + if (attr != NULL) + pst->dirname = DW_STRING (attr); - gdb_assert (! this_cu->debug_types_section); + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + dwarf2_find_base_address (comp_unit_die, cu); - gdb_assert (dwarf2_per_objfile->info.readin); - info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset; + /* Possibly set the default values of LOWPC and HIGHPC from + `DW_AT_ranges'. */ + has_pc_info = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc, + &best_highpc, cu, pst); + if (has_pc_info == 1 && best_lowpc < best_highpc) + /* Store the contiguous range if it is not empty; it can be empty for + CUs with no code. */ + addrmap_set_empty (objfile->psymtabs_addrmap, + best_lowpc + baseaddr, + best_highpc + baseaddr - 1, pst); - if (this_cu->cu == NULL) + /* 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) { - cu = xmalloc (sizeof (*cu)); - init_one_comp_unit (cu, objfile); + struct partial_die_info *first_die; + CORE_ADDR lowpc, highpc; - read_cu = 1; + lowpc = ((CORE_ADDR) -1); + highpc = ((CORE_ADDR) 0); - /* If an error occurs while loading, release our storage. */ - free_cu_cleanup = make_cleanup (free_one_comp_unit, cu); + first_die = load_partial_dies (reader, info_ptr, 1); - info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr, - dwarf2_per_objfile->info.buffer, - dwarf2_per_objfile->info.size, - abfd, 0); + scan_partial_symbols (first_die, &lowpc, &highpc, + ! has_pc_info, cu); - /* Skip dummy compilation units. */ - if (info_ptr >= (dwarf2_per_objfile->info.buffer - + dwarf2_per_objfile->info.size) - || peek_abbrev_code (abfd, info_ptr) == 0) + /* If we didn't find a lowpc, set it to highpc to avoid + complaints from `maint check'. */ + if (lowpc == ((CORE_ADDR) -1)) + lowpc = highpc; + + /* If the compilation unit didn't have an explicit address range, + then use the information extracted from its child dies. */ + if (! has_pc_info) { - do_cleanups (free_cu_cleanup); - return; + best_lowpc = lowpc; + best_highpc = highpc; } + } + pst->textlow = best_lowpc + baseaddr; + pst->texthigh = best_highpc + baseaddr; + + pst->n_global_syms = objfile->global_psymbols.next - + (objfile->global_psymbols.list + pst->globals_offset); + pst->n_static_syms = objfile->static_psymbols.next - + (objfile->static_psymbols.list + pst->statics_offset); + sort_pst_symbols (objfile, pst); - /* Link this compilation unit into the compilation unit tree. */ - this_cu->cu = cu; - cu->per_cu = this_cu; + 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; - /* 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; + VEC_free (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs); } - else + + /* Get the list of files included in the current compilation unit, + and build a psymtab for each of them. */ + dwarf2_build_include_psymtabs (cu, comp_unit_die, pst); + + if (dwarf2_read_debug) { - cu = this_cu->cu; - info_ptr += cu->header.first_die_offset; + struct gdbarch *gdbarch = get_objfile_arch (objfile); + + fprintf_unfiltered (gdb_stdlog, + "Psymtab for %s unit @0x%x: %s - %s" + ", %d global, %d static syms\n", + per_cu->is_debug_types ? "type" : "comp", + per_cu->offset.sect_off, + paddress (gdbarch, pst->textlow), + paddress (gdbarch, pst->texthigh), + pst->n_global_syms, pst->n_static_syms); } +} - /* 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); +/* Subroutine of dwarf2_build_psymtabs_hard to simplify it. + Process compilation unit THIS_CU for a psymtab. */ - /* 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); +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); - prepare_one_comp_unit (cu, comp_unit_die); + gdb_assert (! this_cu->is_debug_types); + init_cutu_and_read_dies (this_cu, NULL, 0, 0, + process_psymtab_comp_unit_reader, + &want_partial_unit); - /* 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); + /* Age out any secondary CUs. */ + age_cached_comp_units (); +} - do_cleanups (free_abbrevs_cleanup); +static hashval_t +hash_type_unit_group (const void *item) +{ + const struct type_unit_group *tu_group = item; - 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); - } + return hash_stmt_list_entry (&tu_group->hash); } -/* 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. */ +static int +eq_type_unit_group (const void *item_lhs, const void *item_rhs) +{ + const struct type_unit_group *lhs = item_lhs; + const struct type_unit_group *rhs = item_rhs; -static void -create_all_comp_units (struct objfile *objfile) + return eq_stmt_list_entry (&lhs->hash, &rhs->hash); +} + +/* Allocate a hash table for type unit groups. */ + +static htab_t +allocate_type_unit_groups_table (void) { - int n_allocated; - int n_comp_units; - struct dwarf2_per_cu_data **all_comp_units; - gdb_byte *info_ptr; + return htab_create_alloc_ex (3, + hash_type_unit_group, + eq_type_unit_group, + NULL, + &dwarf2_per_objfile->objfile->objfile_obstack, + hashtab_obstack_allocate, + dummy_obstack_deallocate); +} - dwarf2_read_section (objfile, &dwarf2_per_objfile->info); - info_ptr = dwarf2_per_objfile->info.buffer; +/* Type units that don't have DW_AT_stmt_list are grouped into their own + partial symtabs. We combine several TUs per psymtab to not let the size + of any one psymtab grow too big. */ +#define NO_STMT_LIST_TYPE_UNIT_PSYMTAB (1 << 31) +#define NO_STMT_LIST_TYPE_UNIT_PSYMTAB_SIZE 10 - n_comp_units = 0; - n_allocated = 10; - all_comp_units = xmalloc (n_allocated - * sizeof (struct dwarf2_per_cu_data *)); +/* Helper routine for get_type_unit_group. + Create the type_unit_group object used to hold one or more TUs. */ - while (info_ptr < dwarf2_per_objfile->info.buffer - + dwarf2_per_objfile->info.size) - { - unsigned int length, initial_length_size; - struct dwarf2_per_cu_data *this_cu; - unsigned int offset; +static struct type_unit_group * +create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwarf2_per_cu_data *per_cu; + struct type_unit_group *tu_group; - offset = info_ptr - dwarf2_per_objfile->info.buffer; + tu_group = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct type_unit_group); + per_cu = &tu_group->per_cu; + per_cu->objfile = objfile; + per_cu->is_debug_types = 1; + per_cu->type_unit_group = tu_group; - /* Read just enough information to find out where the next - compilation unit is. */ - length = read_initial_length (objfile->obfd, info_ptr, - &initial_length_size); + if (dwarf2_per_objfile->using_index) + { + per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct dwarf2_per_cu_quick_data); + tu_group->t.first_tu = cu->per_cu; + } + else + { + unsigned int line_offset = line_offset_struct.sect_off; + struct partial_symtab *pst; + char *name; - /* Save the compilation unit for later lookup. */ - this_cu = obstack_alloc (&objfile->objfile_obstack, - sizeof (struct dwarf2_per_cu_data)); - memset (this_cu, 0, sizeof (*this_cu)); - this_cu->offset = offset; - this_cu->length = length + initial_length_size; - this_cu->objfile = objfile; + /* Give the symtab a useful name for debug purposes. */ + if ((line_offset & NO_STMT_LIST_TYPE_UNIT_PSYMTAB) != 0) + name = xstrprintf ("", + (line_offset & ~NO_STMT_LIST_TYPE_UNIT_PSYMTAB)); + else + name = xstrprintf ("", line_offset); - if (n_comp_units == n_allocated) - { - n_allocated *= 2; - all_comp_units = xrealloc (all_comp_units, - n_allocated - * sizeof (struct dwarf2_per_cu_data *)); - } - all_comp_units[n_comp_units++] = this_cu; + pst = create_partial_symtab (per_cu, name); + pst->anonymous = 1; - info_ptr = info_ptr + this_cu->length; + xfree (name); } - dwarf2_per_objfile->all_comp_units - = obstack_alloc (&objfile->objfile_obstack, - n_comp_units * sizeof (struct dwarf2_per_cu_data *)); - memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units, - n_comp_units * sizeof (struct dwarf2_per_cu_data *)); - xfree (all_comp_units); - dwarf2_per_objfile->n_comp_units = n_comp_units; + tu_group->hash.dwo_unit = cu->dwo_unit; + tu_group->hash.line_offset = line_offset_struct; + + return tu_group; } -/* Process all loaded DIEs for compilation unit CU, starting at - FIRST_DIE. The caller should pass NEED_PC == 1 if the compilation - unit DIE did not have PC info (DW_AT_low_pc and DW_AT_high_pc, or - DW_AT_ranges). If NEED_PC is set, then this function will set - *LOWPC and *HIGHPC to the lowest and highest PC values found in CU - and record the covered ranges in the addrmap. */ +/* Look up the type_unit_group for type unit CU, and create it if necessary. + STMT_LIST is a DW_AT_stmt_list attribute. */ -static void -scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, - CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu) +static struct type_unit_group * +get_type_unit_group (struct dwarf2_cu *cu, struct attribute *stmt_list) { - struct partial_die_info *pdi; + struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats; + struct type_unit_group *tu_group; + void **slot; + unsigned int line_offset; + struct type_unit_group type_unit_group_for_lookup; - /* Now, march along the PDI's, descending into ones which have - interesting children but skipping the children of the other ones, - until we reach the end of the compilation unit. */ + if (dwarf2_per_objfile->type_unit_groups == NULL) + { + dwarf2_per_objfile->type_unit_groups = + allocate_type_unit_groups_table (); + } - pdi = first_die; + /* Do we need to create a new group, or can we use an existing one? */ - while (pdi != NULL) + if (stmt_list) { - fixup_partial_die (pdi, cu); + line_offset = DW_UNSND (stmt_list); + ++tu_stats->nr_symtab_sharers; + } + else + { + /* Ugh, no stmt_list. Rare, but we have to handle it. + We can do various things here like create one group per TU or + spread them over multiple groups to split up the expansion work. + To avoid worst case scenarios (too many groups or too large groups) + we, umm, group them in bunches. */ + line_offset = (NO_STMT_LIST_TYPE_UNIT_PSYMTAB + | (tu_stats->nr_stmt_less_type_units + / NO_STMT_LIST_TYPE_UNIT_PSYMTAB_SIZE)); + ++tu_stats->nr_stmt_less_type_units; + } + + type_unit_group_for_lookup.hash.dwo_unit = cu->dwo_unit; + type_unit_group_for_lookup.hash.line_offset.sect_off = line_offset; + slot = htab_find_slot (dwarf2_per_objfile->type_unit_groups, + &type_unit_group_for_lookup, INSERT); + if (*slot != NULL) + { + tu_group = *slot; + gdb_assert (tu_group != NULL); + } + else + { + sect_offset line_offset_struct; - /* Anonymous namespaces or modules have no name but have interesting - children, so we need to look at them. Ditto for anonymous - enums. */ + line_offset_struct.sect_off = line_offset; + tu_group = create_type_unit_group (cu, line_offset_struct); + *slot = tu_group; + ++tu_stats->nr_symtabs; + } - if (pdi->name != NULL || pdi->tag == DW_TAG_namespace - || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type) - { - switch (pdi->tag) - { - case DW_TAG_subprogram: - add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu); - break; - case DW_TAG_constant: - case DW_TAG_variable: - case DW_TAG_typedef: - case DW_TAG_union_type: - if (!pdi->is_declaration) - { - add_partial_symbol (pdi, cu); - } - break; - case DW_TAG_class_type: - case DW_TAG_interface_type: - case DW_TAG_structure_type: - if (!pdi->is_declaration) - { - add_partial_symbol (pdi, cu); - } - break; - case DW_TAG_enumeration_type: - if (!pdi->is_declaration) - add_partial_enumeration (pdi, cu); - break; - case DW_TAG_base_type: - case DW_TAG_subrange_type: - /* File scope base type definitions are added to the partial - symbol table. */ - add_partial_symbol (pdi, cu); - break; - case DW_TAG_namespace: - add_partial_namespace (pdi, lowpc, highpc, need_pc, cu); - break; - case DW_TAG_module: - add_partial_module (pdi, lowpc, highpc, need_pc, cu); - break; - default: - break; - } - } + return tu_group; +} - /* If the die has a sibling, skip to the sibling. */ +/* Struct used to sort TUs by their abbreviation table offset. */ - pdi = pdi->die_sibling; - } +struct tu_abbrev_offset +{ + struct signatured_type *sig_type; + sect_offset abbrev_offset; +}; + +/* Helper routine for build_type_unit_groups, passed to qsort. */ + +static int +sort_tu_by_abbrev_offset (const void *ap, const void *bp) +{ + const struct tu_abbrev_offset * const *a = ap; + const struct tu_abbrev_offset * const *b = bp; + unsigned int aoff = (*a)->abbrev_offset.sect_off; + unsigned int boff = (*b)->abbrev_offset.sect_off; + + return (aoff > boff) - (aoff < boff); } -/* Functions used to compute the fully scoped name of a partial DIE. +/* A helper function to add a type_unit_group to a table. */ - Normally, this is simple. For C++, the parent DIE's fully scoped - name is concatenated with "::" and the partial DIE's name. For - Java, the same thing occurs except that "." is used instead of "::". - Enumerators are an exception; they use the scope of their parent - enumeration type, i.e. the name of the enumeration type is not - prepended to the enumerator. +static int +add_type_unit_group_to_table (void **slot, void *datum) +{ + struct type_unit_group *tu_group = *slot; + struct type_unit_group ***datap = datum; - There are two complexities. One is DW_AT_specification; in this - case "parent" means the parent of the target of the specification, - instead of the direct parent of the DIE. The other is compilers - which do not emit DW_TAG_namespace; in this case we try to guess - the fully qualified name of structure types from their members' - linkage names. This must be done using the DIE's children rather - than the children of any DW_AT_specification target. We only need - to do this for structures at the top level, i.e. if the target of - any DW_AT_specification (if any; otherwise the DIE itself) does not - have a parent. */ + **datap = tu_group; + ++*datap; -/* Compute the scope prefix associated with PDI's parent, in - compilation unit CU. The result will be allocated on CU's - comp_unit_obstack, or a copy of the already allocated PDI->NAME - field. NULL is returned if no prefix is necessary. */ -static char * -partial_die_parent_scope (struct partial_die_info *pdi, - struct dwarf2_cu *cu) + return 1; +} + +/* Efficiently read all the type units, calling init_cutu_and_read_dies on + each one passing FUNC,DATA. + + The efficiency is because we sort TUs by the abbrev table they use and + only read each abbrev table once. In one program there are 200K TUs + sharing 8K abbrev tables. + + The main purpose of this function is to support building the + dwarf2_per_objfile->type_unit_groups table. + TUs typically share the DW_AT_stmt_list of the CU they came from, so we + can collapse the search space by grouping them by stmt_list. + The savings can be significant, in the same program from above the 200K TUs + share 8K stmt_list tables. + + FUNC is expected to call get_type_unit_group, which will create the + struct type_unit_group if necessary and add it to + dwarf2_per_objfile->type_unit_groups. */ + +static void +build_type_unit_groups (die_reader_func_ftype *func, void *data) { - char *grandparent_scope; - struct partial_die_info *parent, *real_pdi; + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats; + struct cleanup *cleanups; + struct abbrev_table *abbrev_table; + sect_offset abbrev_offset; + struct tu_abbrev_offset *sorted_by_abbrev; + struct type_unit_group **iter; + int i; - /* We need to look at our parent DIE; if we have a DW_AT_specification, - then this means the parent of the specification DIE. */ + /* It's up to the caller to not call us multiple times. */ + gdb_assert (dwarf2_per_objfile->type_unit_groups == NULL); - real_pdi = pdi; - while (real_pdi->has_specification) - real_pdi = find_partial_die (real_pdi->spec_offset, cu); + if (dwarf2_per_objfile->n_type_units == 0) + return; - parent = real_pdi->die_parent; - if (parent == NULL) - return NULL; + /* TUs typically share abbrev tables, and there can be way more TUs than + abbrev tables. Sort by abbrev table to reduce the number of times we + read each abbrev table in. + Alternatives are to punt or to maintain a cache of abbrev tables. + This is simpler and efficient enough for now. - if (parent->scope_set) - return parent->scope; + Later we group TUs by their DW_AT_stmt_list value (as this defines the + symtab to use). Typically TUs with the same abbrev offset have the same + stmt_list value too so in practice this should work well. - fixup_partial_die (parent, cu); + The basic algorithm here is: - grandparent_scope = partial_die_parent_scope (parent, cu); + sort TUs by abbrev table + for each TU with same abbrev table: + read abbrev table if first user + read TU top level DIE + [IWBN if DWO skeletons had DW_AT_stmt_list] + call FUNC */ - /* GCC 4.0 and 4.1 had a bug (PR c++/28460) where they generated bogus - DW_TAG_namespace DIEs with a name of "::" for the global namespace. - Work around this problem here. */ - if (cu->language == language_cplus - && parent->tag == DW_TAG_namespace - && strcmp (parent->name, "::") == 0 - && grandparent_scope == NULL) + if (dwarf2_read_debug) + fprintf_unfiltered (gdb_stdlog, "Building type unit groups ...\n"); + + /* Sort in a separate table to maintain the order of all_type_units + for .gdb_index: TU indices directly index all_type_units. */ + sorted_by_abbrev = XNEWVEC (struct tu_abbrev_offset, + dwarf2_per_objfile->n_type_units); + for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i) { - parent->scope = NULL; - parent->scope_set = 1; - return NULL; + struct signatured_type *sig_type = dwarf2_per_objfile->all_type_units[i]; + + sorted_by_abbrev[i].sig_type = sig_type; + sorted_by_abbrev[i].abbrev_offset = + read_abbrev_offset (sig_type->per_cu.info_or_types_section, + sig_type->per_cu.offset); } + cleanups = make_cleanup (xfree, sorted_by_abbrev); + qsort (sorted_by_abbrev, dwarf2_per_objfile->n_type_units, + sizeof (struct tu_abbrev_offset), sort_tu_by_abbrev_offset); - 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 - || parent->tag == DW_TAG_interface_type - || parent->tag == DW_TAG_union_type - || parent->tag == DW_TAG_enumeration_type) + /* Note: In the .gdb_index case, get_type_unit_group may have already been + called any number of times, so we don't reset tu_stats here. */ + + abbrev_offset.sect_off = ~(unsigned) 0; + abbrev_table = NULL; + make_cleanup (abbrev_table_free_cleanup, &abbrev_table); + + for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i) { - if (grandparent_scope == NULL) - parent->scope = parent->name; - else - parent->scope = typename_concat (&cu->comp_unit_obstack, - grandparent_scope, - parent->name, 0, cu); + const struct tu_abbrev_offset *tu = &sorted_by_abbrev[i]; + + /* Switch to the next abbrev table if necessary. */ + if (abbrev_table == NULL + || tu->abbrev_offset.sect_off != abbrev_offset.sect_off) + { + if (abbrev_table != NULL) + { + abbrev_table_free (abbrev_table); + /* Reset to NULL in case abbrev_table_read_table throws + an error: abbrev_table_free_cleanup will get called. */ + abbrev_table = NULL; + } + abbrev_offset = tu->abbrev_offset; + abbrev_table = + abbrev_table_read_table (&dwarf2_per_objfile->abbrev, + abbrev_offset); + ++tu_stats->nr_uniq_abbrev_tables; + } + + init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table, 0, 0, + func, data); } - else + + /* Create a vector of pointers to primary type units to make it easy to + iterate over them and CUs. See dw2_get_primary_cu. */ + dwarf2_per_objfile->n_type_unit_groups = + htab_elements (dwarf2_per_objfile->type_unit_groups); + dwarf2_per_objfile->all_type_unit_groups = + obstack_alloc (&objfile->objfile_obstack, + dwarf2_per_objfile->n_type_unit_groups + * sizeof (struct type_unit_group *)); + iter = &dwarf2_per_objfile->all_type_unit_groups[0]; + htab_traverse_noresize (dwarf2_per_objfile->type_unit_groups, + add_type_unit_group_to_table, &iter); + gdb_assert (iter - &dwarf2_per_objfile->all_type_unit_groups[0] + == dwarf2_per_objfile->n_type_unit_groups); + + do_cleanups (cleanups); + + if (dwarf2_read_debug) { - /* FIXME drow/2004-04-01: What should we be doing with - function-local names? For partial symbols, we should probably be - ignoring them. */ - complaint (&symfile_complaints, - _("unhandled containing DIE tag %d for DIE at %d"), - parent->tag, pdi->offset); - parent->scope = grandparent_scope; + fprintf_unfiltered (gdb_stdlog, "Done building type unit groups:\n"); + fprintf_unfiltered (gdb_stdlog, " %d TUs\n", + dwarf2_per_objfile->n_type_units); + fprintf_unfiltered (gdb_stdlog, " %d uniq abbrev tables\n", + tu_stats->nr_uniq_abbrev_tables); + fprintf_unfiltered (gdb_stdlog, " %d symtabs from stmt_list entries\n", + tu_stats->nr_symtabs); + fprintf_unfiltered (gdb_stdlog, " %d symtab sharers\n", + tu_stats->nr_symtab_sharers); + fprintf_unfiltered (gdb_stdlog, " %d type units without a stmt_list\n", + tu_stats->nr_stmt_less_type_units); } - - parent->scope_set = 1; - return parent->scope; } -/* 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) +/* Reader function for build_type_psymtabs. */ + +static void +build_type_psymtabs_reader (const struct die_reader_specs *reader, + gdb_byte *info_ptr, + struct die_info *type_unit_die, + int has_children, + void *data) { - char *parent_scope; + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwarf2_cu *cu = reader->cu; + struct dwarf2_per_cu_data *per_cu = cu->per_cu; + struct type_unit_group *tu_group; + struct attribute *attr; + struct partial_die_info *first_die; + CORE_ADDR lowpc, highpc; + struct partial_symtab *pst; - /* If this is a template instantiation, we can not work out the - template arguments from partial DIEs. So, unfortunately, we have - to go through the full DIEs. At least any work we do building - types here will be reused if full symbols are loaded later. */ - if (pdi->has_template_arguments) - { - fixup_partial_die (pdi, cu); + gdb_assert (data == NULL); - if (pdi->name != NULL && strchr (pdi->name, '<') == NULL) - { - struct die_info *die; - struct attribute attr; - struct dwarf2_cu *ref_cu = cu; + if (! has_children) + return; - attr.name = 0; - attr.form = DW_FORM_ref_addr; - attr.u.addr = pdi->offset; - die = follow_die_ref (NULL, &attr, &ref_cu); + attr = dwarf2_attr_no_follow (type_unit_die, DW_AT_stmt_list); + tu_group = get_type_unit_group (cu, attr); - return xstrdup (dwarf2_full_name (NULL, die, ref_cu)); - } + VEC_safe_push (dwarf2_per_cu_ptr, tu_group->t.tus, per_cu); + + prepare_one_comp_unit (cu, type_unit_die, language_minimal); + cu->list_in_scope = &file_symbols; + pst = create_partial_symtab (per_cu, ""); + pst->anonymous = 1; + + first_die = load_partial_dies (reader, info_ptr, 1); + + lowpc = (CORE_ADDR) -1; + highpc = (CORE_ADDR) 0; + scan_partial_symbols (first_die, &lowpc, &highpc, 0, cu); + + pst->n_global_syms = objfile->global_psymbols.next - + (objfile->global_psymbols.list + pst->globals_offset); + pst->n_static_syms = objfile->static_psymbols.next - + (objfile->static_psymbols.list + pst->statics_offset); + sort_pst_symbols (objfile, pst); +} + +/* Traversal function for build_type_psymtabs. */ + +static int +build_type_psymtab_dependencies (void **slot, void *info) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct type_unit_group *tu_group = (struct type_unit_group *) *slot; + struct dwarf2_per_cu_data *per_cu = &tu_group->per_cu; + struct partial_symtab *pst = per_cu->v.psymtab; + int len = VEC_length (dwarf2_per_cu_ptr, tu_group->t.tus); + struct dwarf2_per_cu_data *iter; + int i; + + gdb_assert (len > 0); + + pst->number_of_dependencies = len; + pst->dependencies = obstack_alloc (&objfile->objfile_obstack, + len * sizeof (struct psymtab *)); + for (i = 0; + VEC_iterate (dwarf2_per_cu_ptr, tu_group->t.tus, i, iter); + ++i) + { + pst->dependencies[i] = iter->v.psymtab; + iter->type_unit_group = tu_group; } - parent_scope = partial_die_parent_scope (pdi, cu); - if (parent_scope == NULL) - return NULL; - else - return typename_concat (NULL, parent_scope, pdi->name, 0, cu); + VEC_free (dwarf2_per_cu_ptr, tu_group->t.tus); + + return 1; } +/* Subroutine of dwarf2_build_psymtabs_hard to simplify it. + Build partial symbol tables for the .debug_types comp-units. */ + static void -add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) +build_type_psymtabs (struct objfile *objfile) { - 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; + if (! create_all_type_units (objfile)) + return; - baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + build_type_unit_groups (build_type_psymtabs_reader, NULL); - actual_name = partial_die_full_name (pdi, cu); - if (actual_name) - built_actual_name = 1; + /* Now that all TUs have been processed we can fill in the dependencies. */ + htab_traverse_noresize (dwarf2_per_objfile->type_unit_groups, + build_type_psymtab_dependencies, NULL); +} - if (actual_name == NULL) - actual_name = pdi->name; +/* A cleanup function that clears objfile's psymtabs_addrmap field. */ - switch (pdi->tag) +static void +psymtabs_addrmap_cleanup (void *o) +{ + struct objfile *objfile = 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) { - case DW_TAG_subprogram: - if (pdi->is_external || cu->language == language_ada) + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); + struct partial_symtab *pst = per_cu->v.psymtab; + int j; + + if (pst == NULL) + continue; + + for (j = 0; j < pst->number_of_dependencies; ++j) { - /* brobecker/2007-12-26: Normally, only "external" DIEs are part - of the global scope. But in Ada, we want to be able to access - nested procedures globally. So all Ada subprograms are stored - in the global scope. */ - /* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr, - mst_text, objfile); */ - add_psymbol_to_list (actual_name, strlen (actual_name), - built_actual_name, - VAR_DOMAIN, LOC_BLOCK, - &objfile->global_psymbols, - 0, pdi->lowpc + baseaddr, - cu->language, objfile); - } - else - { - /* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr, - mst_file_text, objfile); */ - add_psymbol_to_list (actual_name, strlen (actual_name), - built_actual_name, - VAR_DOMAIN, LOC_BLOCK, - &objfile->static_psymbols, - 0, pdi->lowpc + baseaddr, - cu->language, objfile); + /* Set the 'user' field only if it is not already set. */ + if (pst->dependencies[j]->user == NULL) + pst->dependencies[j]->user = pst; } - break; - case DW_TAG_constant: - { - struct psymbol_allocation_list *list; + } +} - if (pdi->is_external) - list = &objfile->global_psymbols; - else - list = &objfile->static_psymbols; - add_psymbol_to_list (actual_name, strlen (actual_name), - built_actual_name, VAR_DOMAIN, LOC_STATIC, - list, 0, 0, cu->language, objfile); - } - break; - case DW_TAG_variable: - if (pdi->locdesc) - addr = decode_locdesc (pdi->locdesc, cu); +/* Build the partial symbol table by doing a quick pass through the + .debug_info and .debug_abbrev sections. */ - if (pdi->locdesc - && addr == 0 - && !dwarf2_per_objfile->has_section_at_zero) - { - /* A global or static variable may also have been stripped - out by the linker if unused, in which case its address - will be nullified; do not add such variables into partial - symbol table then. */ - } - else if (pdi->is_external) - { - /* Global Variable. - Don't enter into the minimal symbol tables as there is - a minimal symbol table entry from the ELF symbols already. - Enter into partial symbol table if it has a location - descriptor or a type. - If the location descriptor is missing, new_symbol will create - a LOC_UNRESOLVED symbol, the address of the variable will then - be determined from the minimal symbol table whenever the variable - is referenced. - The address for the partial symbol table entry is not - used by GDB, but it comes in handy for debugging partial symbol - table building. */ +static void +dwarf2_build_psymtabs_hard (struct objfile *objfile) +{ + struct cleanup *back_to, *addrmap_cleanup; + struct obstack temp_obstack; + int i; - if (pdi->locdesc || pdi->has_type) - add_psymbol_to_list (actual_name, strlen (actual_name), - built_actual_name, - VAR_DOMAIN, LOC_STATIC, - &objfile->global_psymbols, - 0, addr + baseaddr, - cu->language, objfile); - } - else - { - /* Static Variable. Skip symbols without location descriptors. */ - if (pdi->locdesc == NULL) - { - if (built_actual_name) - xfree (actual_name); - return; - } - /* prim_record_minimal_symbol (actual_name, addr + baseaddr, - mst_file_data, objfile); */ - add_psymbol_to_list (actual_name, strlen (actual_name), - built_actual_name, - VAR_DOMAIN, LOC_STATIC, - &objfile->static_psymbols, - 0, addr + baseaddr, - cu->language, objfile); - } - break; - case DW_TAG_typedef: - case DW_TAG_base_type: - case DW_TAG_subrange_type: - add_psymbol_to_list (actual_name, strlen (actual_name), - built_actual_name, - VAR_DOMAIN, LOC_TYPEDEF, - &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu->language, objfile); - break; - case DW_TAG_namespace: - add_psymbol_to_list (actual_name, strlen (actual_name), - built_actual_name, - VAR_DOMAIN, LOC_TYPEDEF, - &objfile->global_psymbols, - 0, (CORE_ADDR) 0, cu->language, objfile); - break; - case DW_TAG_class_type: - case DW_TAG_interface_type: - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_enumeration_type: - /* Skip external references. The DWARF standard says in the section - about "Structure, Union, and Class Type Entries": "An incomplete - structure, union or class type is represented by a structure, - union or class entry that does not have a byte size attribute - and that has a DW_AT_declaration attribute." */ - if (!pdi->has_byte_size && pdi->is_declaration) - { - if (built_actual_name) - xfree (actual_name); - return; - } + if (dwarf2_read_debug) + { + fprintf_unfiltered (gdb_stdlog, "Building psymtabs of objfile %s ...\n", + objfile->name); + } - /* NOTE: carlton/2003-10-07: See comment in new_symbol about - static vs. global. */ - add_psymbol_to_list (actual_name, strlen (actual_name), - built_actual_name, - STRUCT_DOMAIN, LOC_TYPEDEF, - (cu->language == language_cplus - || cu->language == language_java) - ? &objfile->global_psymbols - : &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu->language, objfile); + dwarf2_per_objfile->reading_partial_symbols = 1; - break; - case DW_TAG_enumerator: - add_psymbol_to_list (actual_name, strlen (actual_name), - built_actual_name, - VAR_DOMAIN, LOC_CONST, - (cu->language == language_cplus - || cu->language == language_java) - ? &objfile->global_psymbols - : &objfile->static_psymbols, - 0, (CORE_ADDR) 0, cu->language, objfile); - break; - default: - break; - } + dwarf2_read_section (objfile, &dwarf2_per_objfile->info); - if (built_actual_name) - xfree (actual_name); -} + /* Any cached compilation units will be linked by the per-objfile + read_in_chain. Make sure to free them when we're done. */ + back_to = make_cleanup (free_cached_comp_units, NULL); -/* Read a partial die corresponding to a namespace; also, add a symbol - corresponding to that namespace to the symbol table. NAMESPACE is - the name of the enclosing namespace. */ + build_type_psymtabs (objfile); -static void -add_partial_namespace (struct partial_die_info *pdi, - CORE_ADDR *lowpc, CORE_ADDR *highpc, - int need_pc, struct dwarf2_cu *cu) -{ - /* Add a symbol for the namespace. */ + create_all_comp_units (objfile); - add_partial_symbol (pdi, cu); + /* Create a temporary address map on a temporary obstack. We later + copy this to the final obstack. */ + obstack_init (&temp_obstack); + make_cleanup_obstack_free (&temp_obstack); + objfile->psymtabs_addrmap = addrmap_create_mutable (&temp_obstack); + addrmap_cleanup = make_cleanup (psymtabs_addrmap_cleanup, objfile); - /* Now scan partial symbols in that namespace. */ + for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) + { + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); - if (pdi->has_children) - scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu); + 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); + + do_cleanups (back_to); + + if (dwarf2_read_debug) + fprintf_unfiltered (gdb_stdlog, "Done building psymtabs of %s\n", + objfile->name); } -/* Read a partial die corresponding to a Fortran module. */ +/* die_reader_func for load_partial_comp_unit. */ static void -add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc, - CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu) +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) { - /* Now scan partial symbols in that module. */ + struct dwarf2_cu *cu = reader->cu; - if (pdi->has_children) - scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu); + 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 (reader, info_ptr, 0); } -/* Read a partial die corresponding to a subprogram and create a partial - symbol for that subprogram. When the CU language allows it, this - routine also defines a partial symbol for each nested subprogram - that this subprogram contains. +/* Load the partial DIEs for a secondary CU into memory. + This is also used when rereading a primary CU with load_all_dies. */ - DIE my also be a lexical block, in which case we simply search - recursively for suprograms defined inside that lexical block. - Again, this is only performed when the CU language allows this - type of definitions. */ +static void +load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu) +{ + init_cutu_and_read_dies (this_cu, NULL, 1, 1, + load_partial_comp_unit_reader, NULL); +} static void -add_partial_subprogram (struct partial_die_info *pdi, - CORE_ADDR *lowpc, CORE_ADDR *highpc, - int need_pc, struct dwarf2_cu *cu) +read_comp_units_from_section (struct objfile *objfile, + struct dwarf2_section_info *section, + unsigned int is_dwz, + int *n_allocated, + int *n_comp_units, + struct dwarf2_per_cu_data ***all_comp_units) { - if (pdi->tag == DW_TAG_subprogram) - { - if (pdi->has_pc_info) - { - if (pdi->lowpc < *lowpc) - *lowpc = pdi->lowpc; - if (pdi->highpc > *highpc) - *highpc = pdi->highpc; - if (need_pc) - { - CORE_ADDR baseaddr; - struct objfile *objfile = cu->objfile; + gdb_byte *info_ptr; + bfd *abfd = section->asection->owner; - baseaddr = ANOFFSET (objfile->section_offsets, - SECT_OFF_TEXT (objfile)); - addrmap_set_empty (objfile->psymtabs_addrmap, - pdi->lowpc + baseaddr, - pdi->highpc - 1 + baseaddr, - cu->per_cu->v.psymtab); - } - 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 - do so when we convert this psymtab into a symtab. */ - if (pdi->name) - add_partial_symbol (pdi, cu); - } - } + dwarf2_read_section (objfile, section); - if (! pdi->has_children) - return; + info_ptr = section->buffer; - if (cu->language == language_ada) + while (info_ptr < section->buffer + section->size) { - pdi = pdi->die_child; - while (pdi != NULL) + unsigned int length, initial_length_size; + struct dwarf2_per_cu_data *this_cu; + sect_offset offset; + + offset.sect_off = info_ptr - section->buffer; + + /* Read just enough information to find out where the next + compilation unit is. */ + length = read_initial_length (abfd, info_ptr, &initial_length_size); + + /* Save the compilation unit for later lookup. */ + this_cu = obstack_alloc (&objfile->objfile_obstack, + sizeof (struct dwarf2_per_cu_data)); + memset (this_cu, 0, sizeof (*this_cu)); + this_cu->offset = offset; + this_cu->length = length + initial_length_size; + this_cu->is_dwz = is_dwz; + this_cu->objfile = objfile; + this_cu->info_or_types_section = section; + + if (*n_comp_units == *n_allocated) { - fixup_partial_die (pdi, cu); - if (pdi->tag == DW_TAG_subprogram - || pdi->tag == DW_TAG_lexical_block) - add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu); - pdi = pdi->die_sibling; + *n_allocated *= 2; + *all_comp_units = xrealloc (*all_comp_units, + *n_allocated + * sizeof (struct dwarf2_per_cu_data *)); } + (*all_comp_units)[*n_comp_units] = this_cu; + ++*n_comp_units; + + info_ptr = info_ptr + this_cu->length; } } -/* Read a partial die corresponding to an enumeration type. */ +/* Create a list of all compilation units in OBJFILE. + This is only done for -readnow and building partial symtabs. */ static void -add_partial_enumeration (struct partial_die_info *enum_pdi, - struct dwarf2_cu *cu) +create_all_comp_units (struct objfile *objfile) { - struct partial_die_info *pdi; - - if (enum_pdi->name != NULL) - add_partial_symbol (enum_pdi, cu); + int n_allocated; + int n_comp_units; + struct dwarf2_per_cu_data **all_comp_units; - pdi = enum_pdi->die_child; - while (pdi) + n_comp_units = 0; + n_allocated = 10; + all_comp_units = xmalloc (n_allocated + * sizeof (struct dwarf2_per_cu_data *)); + + read_comp_units_from_section (objfile, &dwarf2_per_objfile->info, 0, + &n_allocated, &n_comp_units, &all_comp_units); + + if (bfd_get_section_by_name (objfile->obfd, ".gnu_debugaltlink") != NULL) { - if (pdi->tag != DW_TAG_enumerator || pdi->name == NULL) - complaint (&symfile_complaints, _("malformed enumerator DIE ignored")); - else - add_partial_symbol (pdi, cu); - pdi = pdi->die_sibling; + struct dwz_file *dwz = dwarf2_get_dwz_file (); + + read_comp_units_from_section (objfile, &dwz->info, 1, + &n_allocated, &n_comp_units, + &all_comp_units); } + + dwarf2_per_objfile->all_comp_units + = obstack_alloc (&objfile->objfile_obstack, + n_comp_units * sizeof (struct dwarf2_per_cu_data *)); + memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units, + n_comp_units * sizeof (struct dwarf2_per_cu_data *)); + xfree (all_comp_units); + dwarf2_per_objfile->n_comp_units = n_comp_units; } -/* Return the initial uleb128 in the die at INFO_PTR. */ +/* Process all loaded DIEs for compilation unit CU, starting at + FIRST_DIE. The caller should pass NEED_PC == 1 if the compilation + unit DIE did not have PC info (DW_AT_low_pc and DW_AT_high_pc, or + DW_AT_ranges). If NEED_PC is set, then this function will set + *LOWPC and *HIGHPC to the lowest and highest PC values found in CU + and record the covered ranges in the addrmap. */ -static unsigned int -peek_abbrev_code (bfd *abfd, gdb_byte *info_ptr) +static void +scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, + CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu) { - unsigned int bytes_read; + struct partial_die_info *pdi; - return read_unsigned_leb128 (abfd, info_ptr, &bytes_read); + /* Now, march along the PDI's, descending into ones which have + interesting children but skipping the children of the other ones, + until we reach the end of the compilation unit. */ + + pdi = first_die; + + while (pdi != NULL) + { + fixup_partial_die (pdi, cu); + + /* Anonymous namespaces or modules have no name but have interesting + children, so we need to look at them. Ditto for anonymous + 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_imported_unit) + { + switch (pdi->tag) + { + case DW_TAG_subprogram: + add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu); + break; + case DW_TAG_constant: + case DW_TAG_variable: + case DW_TAG_typedef: + case DW_TAG_union_type: + if (!pdi->is_declaration) + { + add_partial_symbol (pdi, cu); + } + break; + case DW_TAG_class_type: + case DW_TAG_interface_type: + case DW_TAG_structure_type: + if (!pdi->is_declaration) + { + add_partial_symbol (pdi, cu); + } + break; + case DW_TAG_enumeration_type: + if (!pdi->is_declaration) + add_partial_enumeration (pdi, cu); + break; + case DW_TAG_base_type: + case DW_TAG_subrange_type: + /* File scope base type definitions are added to the partial + symbol table. */ + add_partial_symbol (pdi, cu); + break; + case DW_TAG_namespace: + add_partial_namespace (pdi, lowpc, highpc, need_pc, cu); + break; + 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; + + /* For now we don't handle imported units in type units. */ + if (cu->per_cu->is_debug_types) + { + error (_("Dwarf Error: DW_TAG_imported_unit is not" + " supported in type units [in module %s]"), + cu->objfile->name); + } + + per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset, + pdi->is_dwz, + 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; + } + } + + /* If the die has a sibling, skip to the sibling. */ + + pdi = pdi->die_sibling; + } } -/* 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 - the initial number. */ +/* Functions used to compute the fully scoped name of a partial DIE. -static struct abbrev_info * -peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read, - struct dwarf2_cu *cu) + Normally, this is simple. For C++, the parent DIE's fully scoped + name is concatenated with "::" and the partial DIE's name. For + Java, the same thing occurs except that "." is used instead of "::". + Enumerators are an exception; they use the scope of their parent + enumeration type, i.e. the name of the enumeration type is not + prepended to the enumerator. + + There are two complexities. One is DW_AT_specification; in this + case "parent" means the parent of the target of the specification, + instead of the direct parent of the DIE. The other is compilers + which do not emit DW_TAG_namespace; in this case we try to guess + the fully qualified name of structure types from their members' + linkage names. This must be done using the DIE's children rather + than the children of any DW_AT_specification target. We only need + to do this for structures at the top level, i.e. if the target of + any DW_AT_specification (if any; otherwise the DIE itself) does not + have a parent. */ + +/* Compute the scope prefix associated with PDI's parent, in + compilation unit CU. The result will be allocated on CU's + comp_unit_obstack, or a copy of the already allocated PDI->NAME + field. NULL is returned if no prefix is necessary. */ +static const char * +partial_die_parent_scope (struct partial_die_info *pdi, + struct dwarf2_cu *cu) { - bfd *abfd = cu->objfile->obfd; - unsigned int abbrev_number; - struct abbrev_info *abbrev; + const char *grandparent_scope; + struct partial_die_info *parent, *real_pdi; - abbrev_number = read_unsigned_leb128 (abfd, info_ptr, bytes_read); + /* We need to look at our parent DIE; if we have a DW_AT_specification, + then this means the parent of the specification DIE. */ - if (abbrev_number == 0) + real_pdi = pdi; + while (real_pdi->has_specification) + real_pdi = find_partial_die (real_pdi->spec_offset, + real_pdi->spec_is_dwz, cu); + + parent = real_pdi->die_parent; + if (parent == NULL) return NULL; - abbrev = dwarf2_lookup_abbrev (abbrev_number, cu); - if (!abbrev) - { - error (_("Dwarf Error: Could not find abbrev number %d [in module %s]"), - abbrev_number, bfd_get_filename (abfd)); - } + if (parent->scope_set) + return parent->scope; - return abbrev; -} + fixup_partial_die (parent, cu); -/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER. - Returns a pointer to the end of a series of DIEs, terminated by an empty - DIE. Any children of the skipped DIEs will also be skipped. */ + grandparent_scope = partial_die_parent_scope (parent, cu); -static gdb_byte * -skip_children (gdb_byte *buffer, gdb_byte *info_ptr, struct dwarf2_cu *cu) -{ - struct abbrev_info *abbrev; - unsigned int bytes_read; + /* GCC 4.0 and 4.1 had a bug (PR c++/28460) where they generated bogus + DW_TAG_namespace DIEs with a name of "::" for the global namespace. + Work around this problem here. */ + if (cu->language == language_cplus + && parent->tag == DW_TAG_namespace + && strcmp (parent->name, "::") == 0 + && grandparent_scope == NULL) + { + parent->scope = NULL; + parent->scope_set = 1; + return NULL; + } - while (1) + 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 + || parent->tag == DW_TAG_interface_type + || parent->tag == DW_TAG_union_type + || parent->tag == DW_TAG_enumeration_type) { - abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu); - if (abbrev == NULL) - return info_ptr + bytes_read; + if (grandparent_scope == NULL) + parent->scope = parent->name; else - info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu); + parent->scope = typename_concat (&cu->comp_unit_obstack, + grandparent_scope, + parent->name, 0, cu); + } + else + { + /* FIXME drow/2004-04-01: What should we be doing with + function-local names? For partial symbols, we should probably be + ignoring them. */ + complaint (&symfile_complaints, + _("unhandled containing DIE tag %d for DIE at %d"), + parent->tag, pdi->offset.sect_off); + parent->scope = grandparent_scope; } + + parent->scope_set = 1; + return parent->scope; } -/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER. - INFO_PTR should point just after the initial uleb128 of a DIE, and the - abbrev corresponding to that skipped uleb128 should be passed in - ABBREV. Returns a pointer to this DIE's sibling, skipping any - children. */ +/* Return the fully scoped name associated with PDI, from compilation unit + CU. The result will be allocated with malloc. */ -static gdb_byte * -skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr, - struct abbrev_info *abbrev, struct dwarf2_cu *cu) +static char * +partial_die_full_name (struct partial_die_info *pdi, + struct dwarf2_cu *cu) { - unsigned int bytes_read; - struct attribute attr; - bfd *abfd = cu->objfile->obfd; - unsigned int form, i; + const char *parent_scope; - for (i = 0; i < abbrev->num_attrs; i++) + /* If this is a template instantiation, we can not work out the + template arguments from partial DIEs. So, unfortunately, we have + to go through the full DIEs. At least any work we do building + types here will be reused if full symbols are loaded later. */ + if (pdi->has_template_arguments) { - /* 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); - if (attr.form == DW_FORM_ref_addr) - complaint (&symfile_complaints, - _("ignoring absolute DW_AT_sibling")); - else - return buffer + dwarf2_get_ref_die_offset (&attr); - } + fixup_partial_die (pdi, cu); - /* If it isn't DW_AT_sibling, skip this attribute. */ - form = abbrev->attrs[i].form; - skip_attribute: - switch (form) + if (pdi->name != NULL && strchr (pdi->name, '<') == NULL) + { + struct die_info *die; + 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.unsnd = pdi->offset.sect_off; + die = follow_die_ref (NULL, &attr, &ref_cu); + + return xstrdup (dwarf2_full_name (NULL, die, ref_cu)); + } + } + + parent_scope = partial_die_parent_scope (pdi, cu); + if (parent_scope == NULL) + return NULL; + else + return typename_concat (NULL, parent_scope, pdi->name, 0, cu); +} + +static void +add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) +{ + struct objfile *objfile = cu->objfile; + CORE_ADDR addr = 0; + const char *actual_name = NULL; + CORE_ADDR baseaddr; + char *built_actual_name; + + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + built_actual_name = partial_die_full_name (pdi, cu); + if (built_actual_name != NULL) + actual_name = built_actual_name; + + if (actual_name == NULL) + actual_name = pdi->name; + + switch (pdi->tag) + { + case DW_TAG_subprogram: + if (pdi->is_external || cu->language == language_ada) + { + /* brobecker/2007-12-26: Normally, only "external" DIEs are part + of the global scope. But in Ada, we want to be able to access + nested procedures globally. So all Ada subprograms are stored + in the global scope. */ + /* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr, + mst_text, objfile); */ + add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name != NULL, + VAR_DOMAIN, LOC_BLOCK, + &objfile->global_psymbols, + 0, pdi->lowpc + baseaddr, + cu->language, objfile); + } + else + { + /* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr, + mst_file_text, objfile); */ + add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name != NULL, + VAR_DOMAIN, LOC_BLOCK, + &objfile->static_psymbols, + 0, pdi->lowpc + baseaddr, + cu->language, objfile); + } + break; + case DW_TAG_constant: + { + struct psymbol_allocation_list *list; + + if (pdi->is_external) + list = &objfile->global_psymbols; + else + list = &objfile->static_psymbols; + add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC, + list, 0, 0, cu->language, objfile); + } + break; + case DW_TAG_variable: + if (pdi->d.locdesc) + addr = decode_locdesc (pdi->d.locdesc, cu); + + if (pdi->d.locdesc + && addr == 0 + && !dwarf2_per_objfile->has_section_at_zero) + { + /* A global or static variable may also have been stripped + out by the linker if unused, in which case its address + will be nullified; do not add such variables into partial + symbol table then. */ + } + else if (pdi->is_external) + { + /* Global Variable. + Don't enter into the minimal symbol tables as there is + a minimal symbol table entry from the ELF symbols already. + Enter into partial symbol table if it has a location + descriptor or a type. + If the location descriptor is missing, new_symbol will create + a LOC_UNRESOLVED symbol, the address of the variable will then + be determined from the minimal symbol table whenever the variable + is referenced. + The address for the partial symbol table entry is not + used by GDB, but it comes in handy for debugging partial symbol + table building. */ + + if (pdi->d.locdesc || pdi->has_type) + add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name != NULL, + VAR_DOMAIN, LOC_STATIC, + &objfile->global_psymbols, + 0, addr + baseaddr, + cu->language, objfile); + } + else + { + /* Static Variable. Skip symbols without location descriptors. */ + if (pdi->d.locdesc == NULL) + { + xfree (built_actual_name); + return; + } + /* prim_record_minimal_symbol (actual_name, addr + baseaddr, + mst_file_data, objfile); */ + add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name != NULL, + VAR_DOMAIN, LOC_STATIC, + &objfile->static_psymbols, + 0, addr + baseaddr, + cu->language, objfile); + } + break; + case DW_TAG_typedef: + case DW_TAG_base_type: + case DW_TAG_subrange_type: + add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name != NULL, + VAR_DOMAIN, LOC_TYPEDEF, + &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); + break; + case DW_TAG_namespace: + add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name != NULL, + VAR_DOMAIN, LOC_TYPEDEF, + &objfile->global_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); + break; + case DW_TAG_class_type: + case DW_TAG_interface_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + /* Skip external references. The DWARF standard says in the section + about "Structure, Union, and Class Type Entries": "An incomplete + structure, union or class type is represented by a structure, + union or class entry that does not have a byte size attribute + and that has a DW_AT_declaration attribute." */ + if (!pdi->has_byte_size && pdi->is_declaration) + { + xfree (built_actual_name); + return; + } + + /* NOTE: carlton/2003-10-07: See comment in new_symbol about + static vs. global. */ + add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name != NULL, + STRUCT_DOMAIN, LOC_TYPEDEF, + (cu->language == language_cplus + || cu->language == language_java) + ? &objfile->global_psymbols + : &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); + + break; + case DW_TAG_enumerator: + add_psymbol_to_list (actual_name, strlen (actual_name), + built_actual_name != NULL, + VAR_DOMAIN, LOC_CONST, + (cu->language == language_cplus + || cu->language == language_java) + ? &objfile->global_psymbols + : &objfile->static_psymbols, + 0, (CORE_ADDR) 0, cu->language, objfile); + break; + default: + break; + } + + xfree (built_actual_name); +} + +/* Read a partial die corresponding to a namespace; also, add a symbol + corresponding to that namespace to the symbol table. NAMESPACE is + the name of the enclosing namespace. */ + +static void +add_partial_namespace (struct partial_die_info *pdi, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + int need_pc, struct dwarf2_cu *cu) +{ + /* Add a symbol for the namespace. */ + + add_partial_symbol (pdi, cu); + + /* Now scan partial symbols in that namespace. */ + + if (pdi->has_children) + scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu); +} + +/* Read a partial die corresponding to a Fortran module. */ + +static void +add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc, + CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu) +{ + /* Now scan partial symbols in that module. */ + + if (pdi->has_children) + scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu); +} + +/* Read a partial die corresponding to a subprogram and create a partial + symbol for that subprogram. When the CU language allows it, this + routine also defines a partial symbol for each nested subprogram + that this subprogram contains. + + DIE my also be a lexical block, in which case we simply search + recursively for suprograms defined inside that lexical block. + Again, this is only performed when the CU language allows this + type of definitions. */ + +static void +add_partial_subprogram (struct partial_die_info *pdi, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + int need_pc, struct dwarf2_cu *cu) +{ + if (pdi->tag == DW_TAG_subprogram) + { + if (pdi->has_pc_info) + { + if (pdi->lowpc < *lowpc) + *lowpc = pdi->lowpc; + if (pdi->highpc > *highpc) + *highpc = pdi->highpc; + if (need_pc) + { + CORE_ADDR baseaddr; + struct objfile *objfile = cu->objfile; + + baseaddr = ANOFFSET (objfile->section_offsets, + SECT_OFF_TEXT (objfile)); + addrmap_set_empty (objfile->psymtabs_addrmap, + pdi->lowpc + baseaddr, + 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 + do so when we convert this psymtab into a symtab. */ + if (pdi->name) + add_partial_symbol (pdi, cu); + } + } + + if (! pdi->has_children) + return; + + if (cu->language == language_ada) + { + pdi = pdi->die_child; + while (pdi != NULL) + { + fixup_partial_die (pdi, cu); + if (pdi->tag == DW_TAG_subprogram + || pdi->tag == DW_TAG_lexical_block) + add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu); + pdi = pdi->die_sibling; + } + } +} + +/* Read a partial die corresponding to an enumeration type. */ + +static void +add_partial_enumeration (struct partial_die_info *enum_pdi, + struct dwarf2_cu *cu) +{ + struct partial_die_info *pdi; + + if (enum_pdi->name != NULL) + add_partial_symbol (enum_pdi, cu); + + pdi = enum_pdi->die_child; + while (pdi) + { + if (pdi->tag != DW_TAG_enumerator || pdi->name == NULL) + complaint (&symfile_complaints, _("malformed enumerator DIE ignored")); + else + add_partial_symbol (pdi, cu); + pdi = pdi->die_sibling; + } +} + +/* 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 + the initial number. */ + +static struct abbrev_info * +peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read, + struct dwarf2_cu *cu) +{ + bfd *abfd = cu->objfile->obfd; + unsigned int abbrev_number; + struct abbrev_info *abbrev; + + abbrev_number = read_unsigned_leb128 (abfd, info_ptr, bytes_read); + + if (abbrev_number == 0) + return NULL; + + abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number); + if (!abbrev) + { + error (_("Dwarf Error: Could not find abbrev number %d [in module %s]"), + abbrev_number, bfd_get_filename (abfd)); + } + + return abbrev; +} + +/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER. + Returns a pointer to the end of a series of DIEs, terminated by an empty + DIE. Any children of the skipped DIEs will also be skipped. */ + +static gdb_byte * +skip_children (const struct die_reader_specs *reader, gdb_byte *info_ptr) +{ + struct dwarf2_cu *cu = reader->cu; + struct abbrev_info *abbrev; + unsigned int bytes_read; + + while (1) + { + abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu); + if (abbrev == NULL) + return info_ptr + bytes_read; + else + info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev); + } +} + +/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER. + INFO_PTR should point just after the initial uleb128 of a DIE, and the + abbrev corresponding to that skipped uleb128 should be passed in + ABBREV. Returns a pointer to this DIE's sibling, skipping any + children. */ + +static gdb_byte * +skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr, + struct abbrev_info *abbrev) +{ + unsigned int bytes_read; + struct attribute attr; + bfd *abfd = reader->abfd; + struct dwarf2_cu *cu = reader->cu; + gdb_byte *buffer = reader->buffer; + const gdb_byte *buffer_end = reader->buffer_end; + gdb_byte *start_info_ptr = info_ptr; + unsigned int form, i; + + for (i = 0; i < abbrev->num_attrs; i++) + { + /* The only abbrev we care about is DW_AT_sibling. */ + if (abbrev->attrs[i].name == DW_AT_sibling) + { + 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).sect_off; + } + + /* If it isn't DW_AT_sibling, skip this attribute. */ + form = abbrev->attrs[i].form; + skip_attribute: + switch (form) { case DW_FORM_ref_addr: /* In DWARF 2, DW_FORM_ref_addr is address sized; in DWARF 3 @@ -4449,1432 +6306,2988 @@ skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr, if (cu->header.version == 2) info_ptr += cu->header.addr_size; else - info_ptr += cu->header.offset_size; - break; - case DW_FORM_addr: - info_ptr += cu->header.addr_size; - break; - case DW_FORM_data1: - case DW_FORM_ref1: - case DW_FORM_flag: - info_ptr += 1; - break; - case DW_FORM_flag_present: - break; - case DW_FORM_data2: - case DW_FORM_ref2: - info_ptr += 2; - break; - case DW_FORM_data4: - case DW_FORM_ref4: - info_ptr += 4; - break; - case DW_FORM_data8: - case DW_FORM_ref8: - case DW_FORM_ref_sig8: - info_ptr += 8; - break; - case DW_FORM_string: - read_direct_string (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - break; - case DW_FORM_sec_offset: - case DW_FORM_strp: - info_ptr += cu->header.offset_size; - break; - case DW_FORM_exprloc: - case DW_FORM_block: - info_ptr += read_unsigned_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - break; - case DW_FORM_block1: - info_ptr += 1 + read_1_byte (abfd, info_ptr); - break; - case DW_FORM_block2: - info_ptr += 2 + read_2_bytes (abfd, info_ptr); - break; - case DW_FORM_block4: - info_ptr += 4 + read_4_bytes (abfd, info_ptr); - break; - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_ref_udata: - info_ptr = skip_leb128 (abfd, info_ptr); - break; - case DW_FORM_indirect: - form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); - info_ptr += bytes_read; - /* We need to continue parsing from here, so just go back to - the top. */ - goto skip_attribute; + info_ptr += cu->header.offset_size; + break; + case DW_FORM_GNU_ref_alt: + info_ptr += cu->header.offset_size; + break; + case DW_FORM_addr: + info_ptr += cu->header.addr_size; + break; + case DW_FORM_data1: + case DW_FORM_ref1: + case DW_FORM_flag: + info_ptr += 1; + break; + case DW_FORM_flag_present: + break; + case DW_FORM_data2: + case DW_FORM_ref2: + info_ptr += 2; + break; + case DW_FORM_data4: + case DW_FORM_ref4: + info_ptr += 4; + break; + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + info_ptr += 8; + break; + case DW_FORM_string: + read_direct_string (abfd, info_ptr, &bytes_read); + info_ptr += bytes_read; + break; + case DW_FORM_sec_offset: + case DW_FORM_strp: + case DW_FORM_GNU_strp_alt: + info_ptr += cu->header.offset_size; + break; + case DW_FORM_exprloc: + case DW_FORM_block: + info_ptr += read_unsigned_leb128 (abfd, info_ptr, &bytes_read); + info_ptr += bytes_read; + break; + case DW_FORM_block1: + info_ptr += 1 + read_1_byte (abfd, info_ptr); + break; + case DW_FORM_block2: + info_ptr += 2 + read_2_bytes (abfd, info_ptr); + break; + case DW_FORM_block4: + info_ptr += 4 + read_4_bytes (abfd, info_ptr); + break; + 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 = (gdb_byte *) safe_skip_leb128 (info_ptr, buffer_end); + break; + case DW_FORM_indirect: + form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); + info_ptr += bytes_read; + /* We need to continue parsing from here, so just go back to + the top. */ + goto skip_attribute; + + default: + error (_("Dwarf Error: Cannot handle %s " + "in DWARF reader [in module %s]"), + dwarf_form_name (form), + bfd_get_filename (abfd)); + } + } + + if (abbrev->has_children) + 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. */ + +static gdb_byte * +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? */ + + if (orig_pdi->sibling) + return orig_pdi->sibling; + + /* Are there any children to deal with? */ + + if (!orig_pdi->has_children) + return info_ptr; + + /* Skip the children the long way. */ + + return skip_children (reader, info_ptr); +} + +/* Expand this partial symbol table into a full symbol table. SELF is + not NULL. */ + +static void +dwarf2_read_symtab (struct partial_symtab *self, + struct objfile *objfile) +{ + if (self->readin) + { + warning (_("bug: psymtab for %s is already read in."), + self->filename); + } + else + { + if (info_verbose) + { + printf_filtered (_("Reading in symbols for %s..."), + self->filename); + gdb_flush (gdb_stdout); + } + + /* Restore our global data. */ + dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key); + + /* If this psymtab is constructed from a debug-only objfile, the + has_section_at_zero flag will not necessarily be correct. We + can get the correct value for this flag by looking at the data + associated with the (presumably stripped) associated objfile. */ + if (objfile->separate_debug_objfile_backlink) + { + struct dwarf2_per_objfile *dpo_backlink + = objfile_data (objfile->separate_debug_objfile_backlink, + dwarf2_objfile_data_key); + + dwarf2_per_objfile->has_section_at_zero + = dpo_backlink->has_section_at_zero; + } + + dwarf2_per_objfile->reading_partial_symbols = 0; + + psymtab_to_symtab_1 (self); + + /* Finish up the debug error message. */ + if (info_verbose) + 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, + 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) + dwarf2_queue = item; + else + dwarf2_queue_tail->next = item; + + dwarf2_queue_tail = item; +} + +/* THIS_CU has a reference to PER_CU. If necessary, load the new compilation + unit and add it to our queue. + The result is non-zero if PER_CU was queued, otherwise the result is zero + meaning either PER_CU is already queued or it is already loaded. */ + +static int +maybe_queue_comp_unit (struct dwarf2_cu *this_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 + not queue PER_CU, just tell our caller to load its DIEs. */ + if (dwarf2_per_objfile->reading_partial_symbols) + { + if (per_cu->cu == NULL || per_cu->cu->dies == NULL) + return 1; + return 0; + } + + /* Mark the dependence relation so that we don't flush PER_CU + too early. */ + dwarf2_add_dependence (this_cu, per_cu); + + /* If it's already on the queue, we have nothing to do. */ + if (per_cu->queued) + return 0; + + /* If the compilation unit is already loaded, just mark it as + used. */ + if (per_cu->cu != NULL) + { + per_cu->cu->last_used = 0; + return 0; + } + + /* Add it to the queue. */ + queue_comp_unit (per_cu, pretend_language); + + return 1; +} + +/* Process the queue. */ + +static void +process_queue (void) +{ + struct dwarf2_queue_item *item, *next_item; + + if (dwarf2_read_debug) + { + fprintf_unfiltered (gdb_stdlog, + "Expanding one or more symtabs of objfile %s ...\n", + dwarf2_per_objfile->objfile->name); + } + + /* The queue starts out with one item, but following a DIE reference + may load a new CU, adding it to the end of the queue. */ + for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item) + { + if (dwarf2_per_objfile->using_index + ? !item->per_cu->v.quick->symtab + : (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin)) + { + struct dwarf2_per_cu_data *per_cu = item->per_cu; + + if (dwarf2_read_debug) + { + fprintf_unfiltered (gdb_stdlog, + "Expanding symtab of %s at offset 0x%x\n", + per_cu->is_debug_types ? "TU" : "CU", + per_cu->offset.sect_off); + } + + if (per_cu->is_debug_types) + process_full_type_unit (per_cu, item->pretend_language); + else + process_full_comp_unit (per_cu, item->pretend_language); + + if (dwarf2_read_debug) + { + fprintf_unfiltered (gdb_stdlog, + "Done expanding %s at offset 0x%x\n", + per_cu->is_debug_types ? "TU" : "CU", + per_cu->offset.sect_off); + } + } + + item->per_cu->queued = 0; + next_item = item->next; + xfree (item); + } + + dwarf2_queue_tail = NULL; + + if (dwarf2_read_debug) + { + fprintf_unfiltered (gdb_stdlog, "Done expanding symtabs of %s.\n", + dwarf2_per_objfile->objfile->name); + } +} + +/* Free all allocated queue entries. This function only releases anything if + an error was thrown; if the queue was processed then it would have been + freed as we went along. */ + +static void +dwarf2_release_queue (void *dummy) +{ + struct dwarf2_queue_item *item, *last; + + item = dwarf2_queue; + while (item) + { + /* Anything still marked queued is likely to be in an + inconsistent state, so discard it. */ + if (item->per_cu->queued) + { + if (item->per_cu->cu != NULL) + free_one_cached_comp_unit (item->per_cu); + item->per_cu->queued = 0; + } + + last = item; + item = item->next; + xfree (last); + } + + dwarf2_queue = dwarf2_queue_tail = NULL; +} + +/* Read in full symbols for PST, and anything it depends on. */ + +static void +psymtab_to_symtab_1 (struct partial_symtab *pst) +{ + struct dwarf2_per_cu_data *per_cu; + int i; + + if (pst->readin) + return; + + for (i = 0; i < pst->number_of_dependencies; i++) + if (!pst->dependencies[i]->readin + && pst->dependencies[i]->user == NULL) + { + /* Inform about additional files that need to be read in. */ + if (info_verbose) + { + /* FIXME: i18n: Need to make this a single string. */ + fputs_filtered (" ", gdb_stdout); + wrap_here (""); + fputs_filtered ("and ", gdb_stdout); + wrap_here (""); + printf_filtered ("%s...", pst->dependencies[i]->filename); + wrap_here (""); /* Flush output. */ + gdb_flush (gdb_stdout); + } + psymtab_to_symtab_1 (pst->dependencies[i]); + } + + per_cu = pst->read_symtab_private; + + if (per_cu == NULL) + { + /* It's an include file, no symbols to read for it. + Everything is in the parent symtab. */ + pst->readin = 1; + return; + } + + dw2_do_instantiate_symtab (per_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.sect_off; +} + +/* 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.sect_off == die_rhs->offset.sect_off; +} + +/* die_reader_func for load_full_comp_unit. + This is identical to read_signatured_type_reader, + but is kept separate for now. */ + +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; + enum language *language_ptr = data; + + 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); + + 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 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. + Similarly, if we do not read the producer, we can not apply + producer-specific interpretation. */ + prepare_one_comp_unit (cu, cu->dies, *language_ptr); +} + +/* Load the DIEs associated with PER_CU into memory. */ + +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, NULL, 1, 1, + load_full_comp_unit_reader, &pretend_language); +} + +/* Add a DIE to the delayed physname list. */ + +static void +add_to_method_list (struct type *type, int fnfield_index, int index, + const char *name, struct die_info *die, + struct dwarf2_cu *cu) +{ + struct delayed_method_info mi; + mi.type = type; + mi.fnfield_index = fnfield_index; + mi.index = index; + mi.name = name; + mi.die = die; + VEC_safe_push (delayed_method_info, cu->method_list, &mi); +} + +/* A cleanup for freeing the delayed method list. */ + +static void +free_delayed_list (void *ptr) +{ + struct dwarf2_cu *cu = (struct dwarf2_cu *) ptr; + if (cu->method_list != NULL) + { + VEC_free (delayed_method_info, cu->method_list); + cu->method_list = NULL; + } +} + +/* Compute the physnames of any methods on the CU's method list. + + The computation of method physnames is delayed in order to avoid the + (bad) condition that one of the method's formal parameters is of an as yet + incomplete type. */ + +static void +compute_delayed_physnames (struct dwarf2_cu *cu) +{ + int i; + struct delayed_method_info *mi; + for (i = 0; VEC_iterate (delayed_method_info, cu->method_list, i, mi) ; ++i) + { + const char *physname; + struct fn_fieldlist *fn_flp + = &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index); + physname = dwarf2_physname (mi->name, mi->die, cu); + fn_flp->fn_fields[mi->index].physname = physname ? physname : ""; + } +} + +/* 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 void +fixup_go_packaging (struct dwarf2_cu *cu) +{ + char *package_name = NULL; + struct pending *list; + int i; + + for (list = global_symbols; list != NULL; list = list->next) + { + for (i = 0; i < list->nsyms; ++i) + { + struct symbol *sym = list->symbol[i]; + + if (SYMBOL_LANGUAGE (sym) == language_go + && SYMBOL_CLASS (sym) == LOC_BLOCK) + { + char *this_package_name = go_symbol_package_name (sym); + + 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"), + (SYMBOL_SYMTAB (sym) + ? symtab_to_filename_for_display (SYMBOL_SYMTAB (sym)) + : cu->objfile->name), + this_package_name, package_name); + xfree (this_package_name); + } + } + } + } + + if (package_name != NULL) + { + struct objfile *objfile = cu->objfile; + const char *saved_package_name = obstack_copy0 (&objfile->objfile_obstack, + package_name, + strlen (package_name)); + struct type *type = init_type (TYPE_CODE_MODULE, 0, 0, + saved_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, saved_package_name, + strlen (saved_package_name), 0, 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 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; + } + + *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) +{ + gdb_assert (! per_cu->is_debug_types); + + if (!VEC_empty (dwarf2_per_cu_ptr, per_cu->imported_symtabs)) + { + 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, and + for .gdb_index version 7 the included TUs, 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; + + 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) + { + if (! iter->is_debug_types) + compute_symtab_includes (iter); + } + + VEC_free (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus); +} + +/* 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, + enum language pretend_language) +{ + struct dwarf2_cu *cu = per_cu->cu; + struct objfile *objfile = per_cu->objfile; + CORE_ADDR lowpc, highpc; + struct symtab *symtab; + struct cleanup *back_to, *delayed_list_cleanup; + CORE_ADDR baseaddr; + struct block *static_block; + + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + + buildsym_init (); + back_to = make_cleanup (really_free_pendings, NULL); + delayed_list_cleanup = make_cleanup (free_delayed_list, 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. */ + compute_delayed_physnames (cu); + do_cleanups (delayed_list_cleanup); + + /* Some compilers don't define a DW_AT_high_pc attribute for the + compilation unit. If the DW_AT_high_pc is missing, synthesize + it, by scanning the DIE's below the compilation unit. */ + get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu); + + static_block + = end_symtab_get_static_block (highpc + baseaddr, objfile, 0, + per_cu->imported_symtabs != NULL); + + /* If the comp unit has DW_AT_ranges, it may have discontiguous ranges. + Also, DW_AT_ranges may record ranges not belonging to any child DIEs + (such as virtual method tables). Record the ranges in STATIC_BLOCK's + addrmap to help ensure it has an accurate map of pc values belonging to + this comp unit. */ + dwarf2_record_block_ranges (cu->dies, static_block, baseaddr, cu); + + symtab = end_symtab_from_static_block (static_block, objfile, + SECT_OFF_TEXT (objfile), 0); + + if (symtab != NULL) + { + 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 + not set the language if it was already deduced by start_subfile. */ + if (!(cu->language == language_c && symtab->language != language_c)) + symtab->language = cu->language; + + /* 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. 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. + + 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 >= 5) + symtab->locations_valid = 1; + + if (gcc_4_minor >= 5) + symtab->epilogue_unwind_valid = 1; + + symtab->call_site_htab = cu->call_site_htab; + } + + if (dwarf2_per_objfile->using_index) + per_cu->v.quick->symtab = symtab; + else + { + struct partial_symtab *pst = per_cu->v.psymtab; + pst->symtab = symtab; + 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); +} + +/* Generate full symbol information for type unit PER_CU, whose DIEs have + already been loaded into memory. */ + +static void +process_full_type_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; + struct symtab *symtab; + struct cleanup *back_to, *delayed_list_cleanup; + + buildsym_init (); + back_to = make_cleanup (really_free_pendings, NULL); + delayed_list_cleanup = make_cleanup (free_delayed_list, cu); + + cu->list_in_scope = &file_symbols; + + cu->language = pretend_language; + cu->language_defn = language_def (cu->language); + + /* The symbol tables are set up in read_type_unit_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. */ + compute_delayed_physnames (cu); + do_cleanups (delayed_list_cleanup); + + /* TUs share symbol tables. + If this is the first TU to use this symtab, complete the construction + of it with end_expandable_symtab. Otherwise, complete the addition of + this TU's symbols to the existing symtab. */ + if (per_cu->type_unit_group->primary_symtab == NULL) + { + symtab = end_expandable_symtab (0, objfile, SECT_OFF_TEXT (objfile)); + per_cu->type_unit_group->primary_symtab = symtab; + + if (symtab != NULL) + { + /* Set symtab language to language from DW_AT_language. If the + compilation is from a C file generated by language preprocessors, + do not set the language if it was already deduced by + start_subfile. */ + if (!(cu->language == language_c && symtab->language != language_c)) + symtab->language = cu->language; + } + } + else + { + augment_type_symtab (objfile, + per_cu->type_unit_group->primary_symtab); + symtab = per_cu->type_unit_group->primary_symtab; + } + + if (dwarf2_per_objfile->using_index) + per_cu->v.quick->symtab = symtab; + else + { + struct partial_symtab *pst = per_cu->v.psymtab; + pst->symtab = symtab; + pst->readin = 1; + } + + 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; + + /* For now we don't handle imported units in type units. */ + if (cu->per_cu->is_debug_types) + { + error (_("Dwarf Error: DW_TAG_imported_unit is not" + " supported in type units [in module %s]"), + cu->objfile->name); + } + + 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; + int is_dwz; + + offset = dwarf2_get_ref_die_offset (attr); + is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz); + per_cu = dwarf2_find_containing_comp_unit (offset, is_dwz, 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 +process_die (struct die_info *die, struct dwarf2_cu *cu) +{ + switch (die->tag) + { + 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: + read_type_unit_scope (die, cu); + break; + case DW_TAG_subprogram: + case DW_TAG_inlined_subroutine: + read_func_scope (die, cu); + break; + case DW_TAG_lexical_block: + case DW_TAG_try_block: + 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: + case DW_TAG_union_type: + process_structure_scope (die, cu); + break; + case DW_TAG_enumeration_type: + process_enumeration_scope (die, cu); + break; + + /* These dies have a type, but processing them does not create + a symbol or recurse to process the children. Therefore we can + read them on-demand through read_type_die. */ + case DW_TAG_subroutine_type: + case DW_TAG_set_type: + case DW_TAG_array_type: + case DW_TAG_pointer_type: + case DW_TAG_ptr_to_member_type: + case DW_TAG_reference_type: + case DW_TAG_string_type: + break; + + case DW_TAG_base_type: + case DW_TAG_subrange_type: + case DW_TAG_typedef: + /* Add a typedef symbol for the type definition, if it has a + DW_AT_name. */ + new_symbol (die, read_type_die (die, cu), cu); + break; + case DW_TAG_common_block: + read_common_block (die, cu); + break; + case DW_TAG_common_inclusion: + break; + case DW_TAG_namespace: + cu->processing_has_namespace_info = 1; + read_namespace (die, cu); + break; + case DW_TAG_module: + cu->processing_has_namespace_info = 1; + read_module (die, cu); + break; + case DW_TAG_imported_declaration: + case DW_TAG_imported_module: + cu->processing_has_namespace_info = 1; + if (die->child != NULL && (die->tag == DW_TAG_imported_declaration + || cu->language != language_fortran)) + complaint (&symfile_complaints, _("Tag '%s' has unexpected children"), + 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; + } +} + +/* A helper function for dwarf2_compute_name which determines whether DIE + needs to have the name of the scope prepended to the name listed in the + die. */ + +static int +die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu) +{ + struct attribute *attr; + + switch (die->tag) + { + case DW_TAG_namespace: + case DW_TAG_typedef: + case DW_TAG_class_type: + case DW_TAG_interface_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + case DW_TAG_enumerator: + case DW_TAG_subprogram: + case DW_TAG_member: + return 1; + + case DW_TAG_variable: + case DW_TAG_constant: + /* We only need to prefix "globally" visible variables. These include + any variable marked with DW_AT_external or any variable that + lives in a namespace. [Variables in anonymous namespaces + require prefixing, but they are not DW_AT_external.] */ + + if (dwarf2_attr (die, DW_AT_specification, cu)) + { + struct dwarf2_cu *spec_cu = cu; + + return die_needs_namespace (die_specification (die, &spec_cu), + spec_cu); + } + + attr = dwarf2_attr (die, DW_AT_external, cu); + if (attr == NULL && die->parent->tag != DW_TAG_namespace + && die->parent->tag != DW_TAG_module) + return 0; + /* A variable in a lexical block of some kind does not need a + namespace, even though in C++ such variables may be external + and have a mangled name. */ + if (die->parent->tag == DW_TAG_lexical_block + || die->parent->tag == DW_TAG_try_block + || die->parent->tag == DW_TAG_catch_block + || die->parent->tag == DW_TAG_subprogram) + return 0; + return 1; + + default: + return 0; + } +} + +/* Retrieve the last character from a mem_file. */ + +static void +do_ui_file_peek_last (void *object, const char *buffer, long length) +{ + char *last_char_p = (char *) object; + + if (length > 0) + *last_char_p = buffer[length - 1]; +} + +/* 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), + - 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.. + + The result is allocated on the objfile_obstack and canonicalized. */ + +static const char * +dwarf2_compute_name (const char *name, + struct die_info *die, struct dwarf2_cu *cu, + int physname) +{ + 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 + compute it by typename_concat inside GDB. */ + if (cu->language == language_ada + || (cu->language == language_fortran && physname)) + { + /* For Ada unit, we prefer the linkage name over the name, as + the former contains the exported name, which the user expects + to be able to reference. Ideally, we want the user to be able + to reference this entity using either natural or linkage name, + but we haven't started looking at this enhancement yet. */ + struct attribute *attr; + + attr = dwarf2_attr (die, DW_AT_linkage_name, cu); + if (attr == NULL) + attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); + if (attr && DW_STRING (attr)) + return DW_STRING (attr); + } + + /* These are the only languages we know how to qualify names in. */ + if (name != NULL + && (cu->language == language_cplus || cu->language == language_java + || cu->language == language_fortran)) + { + if (die_needs_namespace (die, cu)) + { + long length; + const char *prefix; + struct ui_file *buf; + + prefix = determine_prefix (die, cu); + buf = mem_fileopen (); + if (*prefix != '\0') + { + char *prefixed_name = typename_concat (NULL, prefix, name, + physname, cu); + + fputs_unfiltered (prefixed_name, buf); + xfree (prefixed_name); + } + else + fputs_unfiltered (name, buf); + + /* Template parameters may be specified in the DIE's DW_AT_name, or + as children with DW_TAG_template_type_param or + DW_TAG_value_type_param. If the latter, add them to the name + here. If the name already has template parameters, then + skip this step; some versions of GCC emit both, and + it is more efficient to use the pre-computed name. + + Something to keep in mind about this process: it is very + unlikely, or in some cases downright impossible, to produce + something that will match the mangled name of a function. + If the definition of the function has the same debug info, + we should be able to match up with it anyway. But fallbacks + using the minimal symbol, for instance to find a method + implemented in a stripped copy of libstdc++, will not work. + If we do not have debug info for the definition, we will have to + match them up some other way. + + When we do name matching there is a related problem with function + templates; two instantiated function templates are allowed to + differ only by their return types, which we do not add here. */ + + if (cu->language == language_cplus && strchr (name, '<') == NULL) + { + struct attribute *attr; + struct die_info *child; + int first = 1; + + die->building_fullname = 1; + + for (child = die->child; child != NULL; child = child->sibling) + { + struct type *type; + LONGEST value; + gdb_byte *bytes; + struct dwarf2_locexpr_baton *baton; + struct value *v; + + if (child->tag != DW_TAG_template_type_param + && child->tag != DW_TAG_template_value_param) + continue; + + if (first) + { + fputs_unfiltered ("<", buf); + first = 0; + } + else + fputs_unfiltered (", ", buf); + + attr = dwarf2_attr (child, DW_AT_type, cu); + if (attr == NULL) + { + complaint (&symfile_complaints, + _("template parameter missing DW_AT_type")); + fputs_unfiltered ("UNKNOWN_TYPE", buf); + continue; + } + type = die_type (child, cu); + + if (child->tag == DW_TAG_template_type_param) + { + c_print_type (type, "", buf, -1, 0, &type_print_raw_options); + continue; + } + + attr = dwarf2_attr (child, DW_AT_const_value, cu); + if (attr == NULL) + { + complaint (&symfile_complaints, + _("template parameter missing " + "DW_AT_const_value")); + fputs_unfiltered ("UNKNOWN_VALUE", buf); + continue; + } + + dwarf2_const_value_attr (attr, type, name, + &cu->comp_unit_obstack, cu, + &value, &bytes, &baton); + + if (TYPE_NOSIGN (type)) + /* GDB prints characters as NUMBER 'CHAR'. If that's + changed, this can use value_print instead. */ + c_printchar (value, type, buf); + else + { + struct value_print_options opts; + + if (baton != NULL) + v = dwarf2_evaluate_loc_desc (type, NULL, + baton->data, + baton->size, + baton->per_cu); + else if (bytes != NULL) + { + v = allocate_value (type); + memcpy (value_contents_writeable (v), bytes, + TYPE_LENGTH (type)); + } + else + v = value_from_longest (type, value); + + /* Specify decimal so that we do not depend on + the radix. */ + get_formatted_print_options (&opts, 'd'); + opts.raw = 1; + value_print (v, buf, &opts); + release_value (v); + value_free (v); + } + } - default: - error (_("Dwarf Error: Cannot handle %s " - "in DWARF reader [in module %s]"), - dwarf_form_name (form), - bfd_get_filename (abfd)); + die->building_fullname = 0; + + if (!first) + { + /* Close the argument list, with a space if necessary + (nested templates). */ + char last_char = '\0'; + ui_file_put (buf, do_ui_file_peek_last, &last_char); + if (last_char == '>') + fputs_unfiltered (" >", buf); + else + fputs_unfiltered (">", buf); + } + } + + /* For Java and C++ methods, append formal parameter type + information, if PHYSNAME. */ + + if (physname && die->tag == DW_TAG_subprogram + && (cu->language == language_cplus + || cu->language == language_java)) + { + struct type *type = read_type_die (die, cu); + + c_type_print_args (type, buf, 1, cu->language, + &type_print_raw_options); + + if (cu->language == language_java) + { + /* For java, we must append the return type to method + names. */ + if (die->tag == DW_TAG_subprogram) + java_print_type (TYPE_TARGET_TYPE (type), "", buf, + 0, 0, &type_print_raw_options); + } + else if (cu->language == language_cplus) + { + /* Assume that an artificial first parameter is + "this", but do not crash if it is not. RealView + marks unnamed (and thus unused) parameters as + artificial; there is no way to differentiate + the two cases. */ + if (TYPE_NFIELDS (type) > 0 + && TYPE_FIELD_ARTIFICIAL (type, 0) + && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_PTR + && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, + 0)))) + fputs_unfiltered (" const", buf); + } + } + + name = ui_file_obsavestring (buf, &objfile->objfile_obstack, + &length); + ui_file_delete (buf); + + if (cu->language == language_cplus) + { + const char *cname + = dwarf2_canonicalize_name (name, cu, + &objfile->objfile_obstack); + + if (cname != NULL) + name = cname; + } } } - if (abbrev->has_children) - return skip_children (buffer, info_ptr, cu); - else - return info_ptr; + return name; } -/* Locate ORIG_PDI's sibling. - INFO_PTR should point to the start of the next DIE after ORIG_PDI - in BUFFER. */ +/* Return the fully qualified name of DIE, based on its DW_AT_name. + If scope qualifiers are appropriate they will be added. The result + will be allocated on the objfile_obstack, or NULL if the DIE does + not have a name. NAME may either be from a previous call to + dwarf2_name or NULL. -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) + The output string will be canonicalized (if C++/Java). */ + +static const char * +dwarf2_full_name (const char *name, struct die_info *die, struct dwarf2_cu *cu) { - /* Do we know the sibling already? */ + return dwarf2_compute_name (name, die, cu, 0); +} - if (orig_pdi->sibling) - return orig_pdi->sibling; +/* Construct a physname for the given DIE in CU. NAME may either be + from a previous call to dwarf2_name or NULL. The result will be + allocated on the objfile_objstack or NULL if the DIE does not have a + name. - /* Are there any children to deal with? */ + The output string will be canonicalized (if C++/Java). */ - if (!orig_pdi->has_children) - return info_ptr; +static const char * +dwarf2_physname (const 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; + int need_copy = 1; - /* Skip the children the long way. */ + /* In this case dwarf2_compute_name is just a shortcut not building anything + on its own. */ + if (!die_needs_namespace (die, cu)) + return dwarf2_compute_name (name, die, cu, 1); - return skip_children (buffer, info_ptr, cu); -} + back_to = make_cleanup (null_cleanup, NULL); -/* Expand this partial symbol table into a full symbol table. */ + attr = dwarf2_attr (die, DW_AT_linkage_name, cu); + if (!attr) + attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); -static void -dwarf2_psymtab_to_symtab (struct partial_symtab *pst) -{ - if (pst != NULL) + /* DW_AT_linkage_name is missing in some cases - depend on what GDB + has computed. */ + if (attr && DW_STRING (attr)) + { + char *demangled; + + mangled = DW_STRING (attr); + + /* Use DMGL_RET_DROP for C++ template functions to suppress their return + type. It is easier for GDB users to search for such functions as + `name(params)' than `long name(params)'. In such case the minimal + symbol names do not match the full symbol names but for template + functions there is never a need to look up their definition from their + declaration so the only disadvantage remains the minimal symbol + variant `long name(params)' does not have the proper inferior type. + */ + + 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); + canon = demangled; + } + else + { + canon = mangled; + need_copy = 0; + } + } + + if (canon == NULL || check_physname) { - if (pst->readin) + const char *physname = dwarf2_compute_name (name, die, cu, 1); + + if (canon != NULL && strcmp (physname, canon) != 0) { - warning (_("bug: psymtab for %s is already read in."), - pst->filename); + /* It may not mean a bug in GDB. The compiler could also + compute DW_AT_linkage_name incorrectly. But in such case + GDB would need to be bug-to-bug compatible. */ + + 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.sect_off, objfile->name); + + /* Prefer DW_AT_linkage_name (in the CANON form) - when it + is available here - over computed PHYSNAME. It is safer + against both buggy GDB and buggy compilers. */ + + retval = canon; } else { - if (info_verbose) - { - printf_filtered (_("Reading in symbols for %s..."), - pst->filename); - gdb_flush (gdb_stdout); - } + retval = physname; + need_copy = 0; + } + } + else + retval = canon; + + if (need_copy) + retval = obstack_copy0 (&objfile->objfile_obstack, retval, strlen (retval)); + + do_cleanups (back_to); + return retval; +} + +/* Read the import statement specified by the given die and record it. */ + +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; + const char *imported_name; + const char *imported_name_prefix; + const char *canonical_name; + const char *import_alias; + const char *imported_declaration = NULL; + const char *import_prefix; + VEC (const_char_ptr) *excludes = NULL; + struct cleanup *cleanups; + + import_attr = dwarf2_attr (die, DW_AT_import, cu); + if (import_attr == NULL) + { + complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"), + dwarf_tag_name (die->tag)); + return; + } + + imported_cu = cu; + imported_die = follow_die_ref_or_sig (die, import_attr, &imported_cu); + imported_name = dwarf2_name (imported_die, imported_cu); + if (imported_name == NULL) + { + /* GCC bug: https://bugzilla.redhat.com/show_bug.cgi?id=506524 + + The import in the following code: + namespace A + { + typedef int B; + } + + int main () + { + using A::B; + B b; + return b; + } + + ... + <2><51>: Abbrev Number: 3 (DW_TAG_imported_declaration) + <52> DW_AT_decl_file : 1 + <53> DW_AT_decl_line : 6 + <54> DW_AT_import : <0x75> + <2><58>: Abbrev Number: 4 (DW_TAG_typedef) + <59> DW_AT_name : B + <5b> DW_AT_decl_file : 1 + <5c> DW_AT_decl_line : 2 + <5d> DW_AT_type : <0x6e> + ... + <1><75>: Abbrev Number: 7 (DW_TAG_base_type) + <76> DW_AT_byte_size : 4 + <77> DW_AT_encoding : 5 (signed) + + imports the wrong die ( 0x75 instead of 0x58 ). + This case will be ignored until the gcc bug is fixed. */ + return; + } + + /* Figure out the local name after import. */ + import_alias = dwarf2_name (die, cu); - /* Restore our global data. */ - dwarf2_per_objfile = objfile_data (pst->objfile, - dwarf2_objfile_data_key); + /* Figure out where the statement is being imported to. */ + import_prefix = determine_prefix (die, cu); + + /* Figure out what the scope of the imported die is and prepend it + to the name of the imported die. */ + imported_name_prefix = determine_prefix (imported_die, imported_cu); - /* If this psymtab is constructed from a debug-only objfile, the - has_section_at_zero flag will not necessarily be correct. We - can get the correct value for this flag by looking at the data - associated with the (presumably stripped) associated objfile. */ - if (pst->objfile->separate_debug_objfile_backlink) - { - struct dwarf2_per_objfile *dpo_backlink - = objfile_data (pst->objfile->separate_debug_objfile_backlink, - dwarf2_objfile_data_key); + if (imported_die->tag != DW_TAG_namespace + && imported_die->tag != DW_TAG_module) + { + imported_declaration = imported_name; + canonical_name = imported_name_prefix; + } + else if (strlen (imported_name_prefix) > 0) + canonical_name = obconcat (&objfile->objfile_obstack, + imported_name_prefix, "::", imported_name, + (char *) NULL); + else + canonical_name = imported_name; - dwarf2_per_objfile->has_section_at_zero - = dpo_backlink->has_section_at_zero; - } + cleanups = make_cleanup (VEC_cleanup (const_char_ptr), &excludes); - dwarf2_per_objfile->reading_partial_symbols = 0; + if (die->tag == DW_TAG_imported_module && cu->language == language_fortran) + for (child_die = die->child; child_die && child_die->tag; + child_die = sibling_die (child_die)) + { + /* DWARF-4: A Fortran use statement with a “rename list” may be + represented by an imported module entry with an import attribute + referring to the module and owned entries corresponding to those + entities that are renamed as part of being imported. */ - psymtab_to_symtab_1 (pst); + if (child_die->tag != DW_TAG_imported_declaration) + { + complaint (&symfile_complaints, + _("child DW_TAG_imported_declaration expected " + "- DIE at 0x%x [in module %s]"), + child_die->offset.sect_off, objfile->name); + continue; + } - /* Finish up the debug error message. */ - if (info_verbose) - printf_filtered (_("done.\n")); - } - } -} + import_attr = dwarf2_attr (child_die, DW_AT_import, cu); + if (import_attr == NULL) + { + complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"), + dwarf_tag_name (child_die->tag)); + continue; + } -/* Add PER_CU to the queue. */ + imported_cu = cu; + imported_die = follow_die_ref_or_sig (child_die, import_attr, + &imported_cu); + imported_name = dwarf2_name (imported_die, imported_cu); + if (imported_name == NULL) + { + complaint (&symfile_complaints, + _("child DW_TAG_imported_declaration has unknown " + "imported name - DIE at 0x%x [in module %s]"), + child_die->offset.sect_off, objfile->name); + continue; + } -static void -queue_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile) -{ - struct dwarf2_queue_item *item; + VEC_safe_push (const_char_ptr, excludes, imported_name); - per_cu->queued = 1; - item = xmalloc (sizeof (*item)); - item->per_cu = per_cu; - item->next = NULL; + process_die (child_die, cu); + } - if (dwarf2_queue == NULL) - dwarf2_queue = item; - else - dwarf2_queue_tail->next = item; + cp_add_using_directive (import_prefix, + canonical_name, + import_alias, + imported_declaration, + excludes, + 0, + &objfile->objfile_obstack); - dwarf2_queue_tail = item; + do_cleanups (cleanups); } -/* Process the queue. */ +/* Cleanup function for handle_DW_AT_stmt_list. */ static void -process_queue (struct objfile *objfile) +free_cu_line_header (void *arg) { - struct dwarf2_queue_item *item, *next_item; - - /* The queue starts out with one item, but following a DIE reference - may load a new CU, adding it to the end of the queue. */ - for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item) - { - 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); - - item->per_cu->queued = 0; - next_item = item->next; - xfree (item); - } + struct dwarf2_cu *cu = arg; - dwarf2_queue_tail = NULL; + free_line_header (cu->line_header); + cu->line_header = NULL; } -/* Free all allocated queue entries. This function only releases anything if - an error was thrown; if the queue was processed then it would have been - freed as we went along. */ +/* Check for possibly missing DW_AT_comp_dir with relative .debug_line + directory paths. GCC SVN r127613 (new option -fdebug-prefix-map) fixed + this, it was first present in GCC release 4.3.0. */ -static void -dwarf2_release_queue (void *dummy) +static int +producer_is_gcc_lt_4_3 (struct dwarf2_cu *cu) { - struct dwarf2_queue_item *item, *last; - - item = dwarf2_queue; - while (item) - { - /* Anything still marked queued is likely to be in an - inconsistent state, so discard it. */ - if (item->per_cu->queued) - { - if (item->per_cu->cu != NULL) - free_one_cached_comp_unit (item->per_cu->cu); - item->per_cu->queued = 0; - } - - last = item; - item = item->next; - xfree (last); - } + if (!cu->checked_producer) + check_producer (cu); - dwarf2_queue = dwarf2_queue_tail = NULL; + return cu->producer_is_gcc_lt_4_3; } -/* Read in full symbols for PST, and anything it depends on. */ - static void -psymtab_to_symtab_1 (struct partial_symtab *pst) +find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu, + const char **name, const char **comp_dir) { - struct dwarf2_per_cu_data *per_cu; - struct cleanup *back_to; - int i; + struct attribute *attr; - for (i = 0; i < pst->number_of_dependencies; i++) - if (!pst->dependencies[i]->readin) - { - /* Inform about additional files that need to be read in. */ - if (info_verbose) - { - /* FIXME: i18n: Need to make this a single string. */ - fputs_filtered (" ", gdb_stdout); - wrap_here (""); - fputs_filtered ("and ", gdb_stdout); - wrap_here (""); - printf_filtered ("%s...", pst->dependencies[i]->filename); - wrap_here (""); /* Flush output. */ - gdb_flush (gdb_stdout); - } - psymtab_to_symtab_1 (pst->dependencies[i]); - } + *name = NULL; + *comp_dir = NULL; - per_cu = pst->read_symtab_private; + /* Find the filename. Do not use dwarf2_name here, since the filename + is not a source language identifier. */ + attr = dwarf2_attr (die, DW_AT_name, cu); + if (attr) + { + *name = DW_STRING (attr); + } - if (per_cu == NULL) + attr = dwarf2_attr (die, DW_AT_comp_dir, cu); + if (attr) + *comp_dir = DW_STRING (attr); + else if (producer_is_gcc_lt_4_3 (cu) && *name != NULL + && IS_ABSOLUTE_PATH (*name)) { - /* It's an include file, no symbols to read for it. - Everything is in the parent symtab. */ - pst->readin = 1; - return; + char *d = ldirname (*name); + + *comp_dir = d; + if (d != NULL) + make_cleanup (xfree, d); + } + if (*comp_dir != NULL) + { + /* Irix 6.2 native cc prepends .: to the compilation + directory, get rid of it. */ + char *cp = strchr (*comp_dir, ':'); + + if (cp && cp != *comp_dir && cp[-1] == '.' && cp[1] == '/') + *comp_dir = cp + 1; } - dw2_do_instantiate_symtab (pst->objfile, per_cu); + if (*name == NULL) + *name = ""; } -/* Load the DIEs associated with PER_CU into memory. */ +/* Handle DW_AT_stmt_list for a compilation unit. + DIE is the DW_TAG_compile_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 -load_full_comp_unit (struct dwarf2_per_cu_data *per_cu, - struct objfile *objfile) +handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, + const char *comp_dir) { - 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_types_section); + gdb_assert (! cu->per_cu->is_debug_types); - /* 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) + attr = dwarf2_attr (die, DW_AT_stmt_list, cu); + if (attr) { - 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); - - /* Read in the comp_unit header. */ - info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd); + unsigned int line_offset = DW_UNSND (attr); + struct line_header *line_header + = dwarf_decode_line_header (line_offset, cu); - /* Skip dummy compilation units. */ - if (info_ptr >= (dwarf2_per_objfile->info.buffer - + dwarf2_per_objfile->info.size) - || peek_abbrev_code (abfd, info_ptr) == 0) + if (line_header) { - do_cleanups (free_cu_cleanup); - return; + cu->line_header = line_header; + make_cleanup (free_cu_line_header, cu); + dwarf_decode_lines (line_header, comp_dir, cu, NULL, 1); } + } +} - /* Complete the cu_header. */ - cu->header.offset = offset; - cu->header.first_die_offset = info_ptr - beg_of_comp_unit; - - /* Read the abbrevs for this compilation unit. */ - dwarf2_read_abbrevs (abfd, cu); - free_abbrevs_cleanup = make_cleanup (dwarf2_free_abbrev_table, cu); +/* Process DW_TAG_compile_unit or DW_TAG_partial_unit. */ - /* Link this compilation unit into the compilation unit tree. */ - per_cu->cu = cu; - cu->per_cu = per_cu; +static void +read_file_scope (struct die_info *die, struct dwarf2_cu *cu) +{ + 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); + struct attribute *attr; + const char *name = NULL; + const char *comp_dir = NULL; + struct die_info *child_die; + bfd *abfd = objfile->obfd; + CORE_ADDR baseaddr; - /* 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; - } + baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - cu->dies = read_comp_unit (info_ptr, cu); + get_scope_pc_bounds (die, &lowpc, &highpc, cu); - /* We try not to read any attributes in this function, because not - all objfiles needed for references have been loaded yet, and symbol - table processing isn't initialized. But we have to set the CU language, - or we won't be able to build types correctly. */ - prepare_one_comp_unit (cu, cu->dies); + /* If we didn't find a lowpc, set it to highpc to avoid complaints + from finish_block. */ + if (lowpc == ((CORE_ADDR) -1)) + lowpc = highpc; + lowpc += baseaddr; + highpc += baseaddr; - /* 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); + find_file_and_directory (die, cu, &name, &comp_dir); - if (read_cu) - { - do_cleanups (free_abbrevs_cleanup); + prepare_one_comp_unit (cu, die, cu->language); - /* We've successfully allocated this compilation unit. Let our - caller clean it up when finished with it. */ - discard_cleanups (free_cu_cleanup); - } -} + /* The XLCL doesn't generate DW_LANG_OpenCL because this attribute is not + standardised yet. As a workaround for the language detection we fall + back to the DW_AT_producer string. */ + if (cu->producer && strstr (cu->producer, "IBM XL C for OpenCL") != NULL) + cu->language = language_opencl; -/* Add a DIE to the delayed physname list. */ + /* Similar hack for Go. */ + if (cu->producer && strstr (cu->producer, "GNU Go ") != NULL) + set_cu_language (DW_LANG_Go, cu); -static void -add_to_method_list (struct type *type, int fnfield_index, int index, - const char *name, struct die_info *die, - struct dwarf2_cu *cu) -{ - struct delayed_method_info mi; - mi.type = type; - mi.fnfield_index = fnfield_index; - mi.index = index; - mi.name = name; - mi.die = die; - VEC_safe_push (delayed_method_info, cu->method_list, &mi); -} + dwarf2_start_symtab (cu, name, comp_dir, lowpc); -/* A cleanup for freeing the delayed method list. */ + /* 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); -static void -free_delayed_list (void *ptr) -{ - struct dwarf2_cu *cu = (struct dwarf2_cu *) ptr; - if (cu->method_list != NULL) + /* Process all dies in compilation unit. */ + if (die->child != NULL) { - VEC_free (delayed_method_info, cu->method_list); - cu->method_list = NULL; + child_die = die->child; + while (child_die && child_die->tag) + { + process_die (child_die, cu); + child_die = sibling_die (child_die); + } } -} - -/* Compute the physnames of any methods on the CU's method list. - The computation of method physnames is delayed in order to avoid the - (bad) condition that one of the method's formal parameters is of an as yet - incomplete type. */ + /* Decode macro information, if present. Dwarf 2 macro information + refers to information in the line number info statement program + header, so we can only read it if we've read the header + successfully. */ + attr = dwarf2_attr (die, DW_AT_GNU_macros, cu); + if (attr && cu->line_header) + { + if (dwarf2_attr (die, DW_AT_macro_info, cu)) + complaint (&symfile_complaints, + _("CU refers to both DW_AT_GNU_macros and DW_AT_macro_info")); -static void -compute_delayed_physnames (struct dwarf2_cu *cu) -{ - int i; - struct delayed_method_info *mi; - for (i = 0; VEC_iterate (delayed_method_info, cu->method_list, i, mi) ; ++i) + dwarf_decode_macros (cu, DW_UNSND (attr), comp_dir, 1); + } + else { - const char *physname; - struct fn_fieldlist *fn_flp - = &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index); - physname = dwarf2_physname ((char *) mi->name, mi->die, cu); - fn_flp->fn_fields[mi->index].physname = physname ? physname : ""; + attr = dwarf2_attr (die, DW_AT_macro_info, cu); + if (attr && cu->line_header) + { + unsigned int macro_offset = DW_UNSND (attr); + + dwarf_decode_macros (cu, macro_offset, comp_dir, 0); + } } + + do_cleanups (back_to); } -/* Generate full symbol information for PST and CU, whose DIEs have - already been loaded into memory. */ +/* TU version of handle_DW_AT_stmt_list for read_type_unit_scope. + Create the set of symtabs used by this TU, or if this TU is sharing + symtabs with another TU and the symtabs have already been created + then restore those symtabs in the line header. + We don't need the pc/line-number mapping for type units. */ static void -process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) +setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu) { - struct dwarf2_cu *cu = per_cu->cu; - struct objfile *objfile = per_cu->objfile; - CORE_ADDR lowpc, highpc; - struct symtab *symtab; - struct cleanup *back_to, *delayed_list_cleanup; - CORE_ADDR baseaddr; - - baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwarf2_per_cu_data *per_cu = cu->per_cu; + struct type_unit_group *tu_group; + int first_time; + struct line_header *lh; + struct attribute *attr; + unsigned int i, line_offset; - buildsym_init (); - back_to = make_cleanup (really_free_pendings, NULL); - delayed_list_cleanup = make_cleanup (free_delayed_list, cu); + gdb_assert (per_cu->is_debug_types); - cu->list_in_scope = &file_symbols; + attr = dwarf2_attr (die, DW_AT_stmt_list, cu); - /* Do line number decoding in read_file_scope () */ - process_die (cu->dies, cu); + /* If we're using .gdb_index (includes -readnow) then + per_cu->s.type_unit_group may not have been set up yet. */ + if (per_cu->type_unit_group == NULL) + per_cu->type_unit_group = get_type_unit_group (cu, attr); + tu_group = per_cu->type_unit_group; - /* 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. */ - compute_delayed_physnames (cu); - do_cleanups (delayed_list_cleanup); + /* If we've already processed this stmt_list there's no real need to + do it again, we could fake it and just recreate the part we need + (file name,index -> symtab mapping). If data shows this optimization + is useful we can do it then. */ + first_time = tu_group->primary_symtab == NULL; - /* Some compilers don't define a DW_AT_high_pc attribute for the - compilation unit. If the DW_AT_high_pc is missing, synthesize - it, by scanning the DIE's below the compilation unit. */ - get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu); + /* We have to handle the case of both a missing DW_AT_stmt_list or bad + debug info. */ + lh = NULL; + if (attr != NULL) + { + line_offset = DW_UNSND (attr); + lh = dwarf_decode_line_header (line_offset, cu); + } + if (lh == NULL) + { + if (first_time) + dwarf2_start_symtab (cu, "", NULL, 0); + else + { + gdb_assert (tu_group->symtabs == NULL); + restart_symtab (0); + } + /* Note: The primary symtab will get allocated at the end. */ + return; + } - symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile)); + cu->line_header = lh; + make_cleanup (free_cu_line_header, cu); - if (symtab != NULL) + if (first_time) { - int gcc_4_minor = producer_is_gcc_ge_4 (cu->producer); + dwarf2_start_symtab (cu, "", NULL, 0); - /* Set symtab language to language from DW_AT_language. If the - compilation is from a C file generated by language preprocessors, do - not set the language if it was already deduced by start_subfile. */ - if (!(cu->language == language_c && symtab->language != language_c)) - symtab->language = cu->language; + tu_group->num_symtabs = lh->num_file_names; + tu_group->symtabs = XNEWVEC (struct symtab *, lh->num_file_names); - /* 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. + for (i = 0; i < lh->num_file_names; ++i) + { + char *dir = NULL; + struct file_entry *fe = &lh->file_names[i]; - For -gdwarf-4 type units LOCATIONS_VALID indication is fortunately not - needed, it would be wrong due to missing DW_AT_producer there. + if (fe->dir_index) + dir = lh->include_dirs[fe->dir_index - 1]; + dwarf2_start_subfile (fe->name, dir, NULL); - 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) - symtab->locations_valid = 1; + /* Note: We don't have to watch for the main subfile here, type units + don't have DW_AT_name. */ - if (gcc_4_minor >= 5) - symtab->epilogue_unwind_valid = 1; + if (current_subfile->symtab == NULL) + { + /* NOTE: start_subfile will recognize when it's been passed + a file it has already seen. So we can't assume there's a + simple mapping from lh->file_names to subfiles, + lh->file_names may contain dups. */ + current_subfile->symtab = allocate_symtab (current_subfile->name, + objfile); + } - symtab->call_site_htab = cu->call_site_htab; + fe->symtab = current_subfile->symtab; + tu_group->symtabs[i] = fe->symtab; + } } - - if (dwarf2_per_objfile->using_index) - per_cu->v.quick->symtab = symtab; else { - struct partial_symtab *pst = per_cu->v.psymtab; - pst->symtab = symtab; - pst->readin = 1; + restart_symtab (0); + + for (i = 0; i < lh->num_file_names; ++i) + { + struct file_entry *fe = &lh->file_names[i]; + + fe->symtab = tu_group->symtabs[i]; + } } - do_cleanups (back_to); + /* The main symtab is allocated last. Type units don't have DW_AT_name + so they don't have a "real" (so to speak) symtab anyway. + There is later code that will assign the main symtab to all symbols + that don't have one. We need to handle the case of a symbol with a + missing symtab (DW_AT_decl_file) anyway. */ } -/* Process a die and its children. */ +/* Process DW_TAG_type_unit. + For TUs we want to skip the first top level sibling if it's not the + actual type being defined by this TU. In this case the first top + level sibling is there to provide context only. */ static void -process_die (struct die_info *die, struct dwarf2_cu *cu) +read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu) { - switch (die->tag) - { - case DW_TAG_padding: - break; - case DW_TAG_compile_unit: - read_file_scope (die, cu); - break; - case DW_TAG_type_unit: - read_type_unit_scope (die, cu); - break; - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: - read_func_scope (die, cu); - break; - case DW_TAG_lexical_block: - case DW_TAG_try_block: - 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: - case DW_TAG_union_type: - process_structure_scope (die, cu); - break; - case DW_TAG_enumeration_type: - process_enumeration_scope (die, cu); - break; + struct die_info *child_die; - /* These dies have a type, but processing them does not create - a symbol or recurse to process the children. Therefore we can - read them on-demand through read_type_die. */ - case DW_TAG_subroutine_type: - case DW_TAG_set_type: - case DW_TAG_array_type: - case DW_TAG_pointer_type: - case DW_TAG_ptr_to_member_type: - case DW_TAG_reference_type: - case DW_TAG_string_type: - break; + prepare_one_comp_unit (cu, die, language_minimal); - case DW_TAG_base_type: - case DW_TAG_subrange_type: - case DW_TAG_typedef: - /* Add a typedef symbol for the type definition, if it has a - DW_AT_name. */ - new_symbol (die, read_type_die (die, cu), cu); - break; - case DW_TAG_common_block: - read_common_block (die, cu); - break; - case DW_TAG_common_inclusion: - break; - case DW_TAG_namespace: - processing_has_namespace_info = 1; - read_namespace (die, cu); - break; - case DW_TAG_module: - processing_has_namespace_info = 1; - read_module (die, cu); - break; - case DW_TAG_imported_declaration: - case DW_TAG_imported_module: - processing_has_namespace_info = 1; - if (die->child != NULL && (die->tag == DW_TAG_imported_declaration - || cu->language != language_fortran)) - complaint (&symfile_complaints, _("Tag '%s' has unexpected children"), - dwarf_tag_name (die->tag)); - read_import_statement (die, cu); - break; - default: - new_symbol (die, NULL, cu); - break; + /* Initialize (or reinitialize) the machinery for building symtabs. + We do this before processing child DIEs, so that the line header table + is available for DW_AT_decl_file. */ + setup_type_unit_groups (die, cu); + + if (die->child != NULL) + { + child_die = die->child; + while (child_die && child_die->tag) + { + process_die (child_die, cu); + child_die = sibling_die (child_die); + } } } + +/* DWO/DWP files. -/* A helper function for dwarf2_compute_name which determines whether DIE - needs to have the name of the scope prepended to the name listed in the - die. */ + http://gcc.gnu.org/wiki/DebugFission + http://gcc.gnu.org/wiki/DebugFissionDWP + + To simplify handling of both DWO files ("object" files with the DWARF info) + and DWP files (a file with the DWOs packaged up into one file), we treat + DWP files as having a collection of virtual DWO files. */ + +static hashval_t +hash_dwo_file (const void *item) +{ + const struct dwo_file *dwo_file = item; + + return htab_hash_string (dwo_file->name); +} static int -die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu) +eq_dwo_file (const void *item_lhs, const void *item_rhs) { - struct attribute *attr; + const struct dwo_file *lhs = item_lhs; + const struct dwo_file *rhs = item_rhs; - switch (die->tag) - { - case DW_TAG_namespace: - case DW_TAG_typedef: - case DW_TAG_class_type: - case DW_TAG_interface_type: - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_enumeration_type: - case DW_TAG_enumerator: - case DW_TAG_subprogram: - case DW_TAG_member: - return 1; + return strcmp (lhs->name, rhs->name) == 0; +} - case DW_TAG_variable: - case DW_TAG_constant: - /* We only need to prefix "globally" visible variables. These include - any variable marked with DW_AT_external or any variable that - lives in a namespace. [Variables in anonymous namespaces - require prefixing, but they are not DW_AT_external.] */ +/* Allocate a hash table for DWO files. */ - if (dwarf2_attr (die, DW_AT_specification, cu)) - { - struct dwarf2_cu *spec_cu = cu; +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); +} + +/* Lookup DWO file DWO_NAME. */ - return die_needs_namespace (die_specification (die, &spec_cu), - spec_cu); - } +static void ** +lookup_dwo_file_slot (const char *dwo_name) +{ + struct dwo_file find_entry; + void **slot; - attr = dwarf2_attr (die, DW_AT_external, cu); - if (attr == NULL && die->parent->tag != DW_TAG_namespace - && die->parent->tag != DW_TAG_module) - return 0; - /* A variable in a lexical block of some kind does not need a - namespace, even though in C++ such variables may be external - and have a mangled name. */ - if (die->parent->tag == DW_TAG_lexical_block - || die->parent->tag == DW_TAG_try_block - || die->parent->tag == DW_TAG_catch_block - || die->parent->tag == DW_TAG_subprogram) - return 0; - return 1; + if (dwarf2_per_objfile->dwo_files == NULL) + dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table (); - default: - return 0; - } + memset (&find_entry, 0, sizeof (find_entry)); + find_entry.name = dwo_name; + slot = htab_find_slot (dwarf2_per_objfile->dwo_files, &find_entry, INSERT); + + return slot; } -/* Retrieve the last character from a mem_file. */ +static hashval_t +hash_dwo_unit (const void *item) +{ + const struct dwo_unit *dwo_unit = item; -static void -do_ui_file_peek_last (void *object, const char *buffer, long length) + /* 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) { - char *last_char_p = (char *) object; + const struct dwo_unit *lhs = item_lhs; + const struct dwo_unit *rhs = item_rhs; - if (length > 0) - *last_char_p = buffer[length - 1]; + /* 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; } -/* 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). +/* Allocate a hash table for DWO CUs,TUs. + There is one of these tables for each of CUs,TUs for each DWO file. */ - For Ada, return the DIE's linkage name rather than the fully qualified - name. PHYSNAME is ignored.. +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); +} - The result is allocated on the objfile_obstack and canonicalized. */ +/* Structure used to pass data to create_dwo_debug_info_hash_table_reader. */ -static const char * -dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, - int physname) +struct create_dwo_info_table_data { - if (name == NULL) - name = dwarf2_name (die, cu); + struct dwo_file *dwo_file; + htab_t cu_htab; +}; - /* For Fortran GDB prefers DW_AT_*linkage_name if present but otherwise - compute it by typename_concat inside GDB. */ - if (cu->language == language_ada - || (cu->language == language_fortran && physname)) - { - /* For Ada unit, we prefer the linkage name over the name, as - the former contains the exported name, which the user expects - to be able to reference. Ideally, we want the user to be able - to reference this entity using either natural or linkage name, - but we haven't started looking at this enhancement yet. */ - struct attribute *attr; +/* die_reader_func for create_dwo_debug_info_hash_table. */ - attr = dwarf2_attr (die, DW_AT_linkage_name, cu); - if (attr == NULL) - attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); - if (attr && DW_STRING (attr)) - return DW_STRING (attr); +static void +create_dwo_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 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; + + 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->name); + return; } - /* These are the only languages we know how to qualify names in. */ - if (name != NULL - && (cu->language == language_cplus || cu->language == language_java - || cu->language == language_fortran)) + 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) { - if (die_needs_namespace (die, cu)) - { - long length; - char *prefix; - struct ui_file *buf; + const struct dwo_unit *dup_dwo_unit = *slot; - prefix = determine_prefix (die, cu); - buf = mem_fileopen (); - if (*prefix != '\0') - { - char *prefixed_name = typename_concat (NULL, prefix, name, - physname, cu); + 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->name); + } + else + *slot = dwo_unit; - fputs_unfiltered (prefixed_name, buf); - xfree (prefixed_name); - } - else - fputs_unfiltered (name, buf); + if (dwarf2_read_debug) + fprintf_unfiltered (gdb_stdlog, " offset 0x%x, dwo_id 0x%s\n", + offset.sect_off, + phex (dwo_unit->signature, + sizeof (dwo_unit->signature))); +} - /* Template parameters may be specified in the DIE's DW_AT_name, or - as children with DW_TAG_template_type_param or - DW_TAG_value_type_param. If the latter, add them to the name - here. If the name already has template parameters, then - skip this step; some versions of GCC emit both, and - it is more efficient to use the pre-computed name. +/* Create a hash table to map DWO IDs to their CU entry in + .debug_info.dwo in DWO_FILE. + Note: This function processes DWO files only, not DWP files. */ - Something to keep in mind about this process: it is very - unlikely, or in some cases downright impossible, to produce - something that will match the mangled name of a function. - If the definition of the function has the same debug info, - we should be able to match up with it anyway. But fallbacks - using the minimal symbol, for instance to find a method - implemented in a stripped copy of libstdc++, will not work. - If we do not have debug info for the definition, we will have to - match them up some other way. +static htab_t +create_dwo_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; - When we do name matching there is a related problem with function - templates; two instantiated function templates are allowed to - differ only by their return types, which we do not add here. */ + dwarf2_read_section (objfile, section); + info_ptr = section->buffer; - if (cu->language == language_cplus && strchr (name, '<') == NULL) - { - struct attribute *attr; - struct die_info *child; - int first = 1; + if (info_ptr == NULL) + return NULL; - die->building_fullname = 1; + /* 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; - for (child = die->child; child != NULL; child = child->sibling) - { - struct type *type; - long value; - gdb_byte *bytes; - struct dwarf2_locexpr_baton *baton; - struct value *v; + if (dwarf2_read_debug) + fprintf_unfiltered (gdb_stdlog, "Reading .debug_info.dwo for %s:\n", + bfd_get_filename (abfd)); - if (child->tag != DW_TAG_template_type_param - && child->tag != DW_TAG_template_value_param) - continue; + cu_htab = allocate_dwo_unit_table (objfile); - if (first) - { - fputs_unfiltered ("<", buf); - first = 0; - } - else - fputs_unfiltered (", ", buf); + create_dwo_info_table_data.dwo_file = dwo_file; + create_dwo_info_table_data.cu_htab = cu_htab; - attr = dwarf2_attr (child, DW_AT_type, cu); - if (attr == NULL) - { - complaint (&symfile_complaints, - _("template parameter missing DW_AT_type")); - fputs_unfiltered ("UNKNOWN_TYPE", buf); - continue; - } - type = die_type (child, cu); + end_ptr = info_ptr + section->size; + while (info_ptr < end_ptr) + { + struct dwarf2_per_cu_data per_cu; - if (child->tag == DW_TAG_template_type_param) - { - c_print_type (type, "", buf, -1, 0); - continue; - } + 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; - attr = dwarf2_attr (child, DW_AT_const_value, cu); - if (attr == NULL) - { - complaint (&symfile_complaints, - _("template parameter missing " - "DW_AT_const_value")); - fputs_unfiltered ("UNKNOWN_VALUE", buf); - continue; - } + init_cutu_and_read_dies_no_follow (&per_cu, + &dwo_file->sections.abbrev, + dwo_file, + create_dwo_debug_info_hash_table_reader, + &create_dwo_info_table_data); - dwarf2_const_value_attr (attr, type, name, - &cu->comp_unit_obstack, cu, - &value, &bytes, &baton); + info_ptr += per_cu.length; + } - if (TYPE_NOSIGN (type)) - /* GDB prints characters as NUMBER 'CHAR'. If that's - changed, this can use value_print instead. */ - c_printchar (value, type, buf); - else - { - struct value_print_options opts; + return cu_htab; +} - if (baton != NULL) - v = dwarf2_evaluate_loc_desc (type, NULL, - baton->data, - baton->size, - baton->per_cu); - else if (bytes != NULL) - { - v = allocate_value (type); - memcpy (value_contents_writeable (v), bytes, - TYPE_LENGTH (type)); - } - else - v = value_from_longest (type, value); +/* DWP file .debug_{cu,tu}_index section format: + [ref: http://gcc.gnu.org/wiki/DebugFissionDWP] - /* Specify decimal so that we do not depend on - the radix. */ - get_formatted_print_options (&opts, 'd'); - opts.raw = 1; - value_print (v, buf, &opts); - release_value (v); - value_free (v); - } - } + Both index sections have the same format, and serve to map a 64-bit + signature to a set of section numbers. Each section begins with a header, + followed by a hash table of 64-bit signatures, a parallel table of 32-bit + indexes, and a pool of 32-bit section numbers. The index sections will be + aligned at 8-byte boundaries in the file. - die->building_fullname = 0; + The index section header contains two unsigned 32-bit values (using the + byte order of the application binary): - if (!first) - { - /* Close the argument list, with a space if necessary - (nested templates). */ - char last_char = '\0'; - ui_file_put (buf, do_ui_file_peek_last, &last_char); - if (last_char == '>') - fputs_unfiltered (" >", buf); - else - fputs_unfiltered (">", buf); - } - } + N, the number of compilation units or type units in the index + M, the number of slots in the hash table - /* For Java and C++ methods, append formal parameter type - information, if PHYSNAME. */ + (We assume that N and M will not exceed 2^32 - 1.) - if (physname && die->tag == DW_TAG_subprogram - && (cu->language == language_cplus - || cu->language == language_java)) - { - struct type *type = read_type_die (die, cu); + The size of the hash table, M, must be 2^k such that 2^k > 3*N/2. - c_type_print_args (type, buf, 1, cu->language); + The hash table begins at offset 8 in the section, and consists of an array + of M 64-bit slots. Each slot contains a 64-bit signature (using the byte + order of the application binary). Unused slots in the hash table are 0. + (We rely on the extreme unlikeliness of a signature being exactly 0.) - if (cu->language == language_java) - { - /* For java, we must append the return type to method - names. */ - if (die->tag == DW_TAG_subprogram) - java_print_type (TYPE_TARGET_TYPE (type), "", buf, - 0, 0); - } - else if (cu->language == language_cplus) - { - /* Assume that an artificial first parameter is - "this", but do not crash if it is not. RealView - marks unnamed (and thus unused) parameters as - artificial; there is no way to differentiate - the two cases. */ - if (TYPE_NFIELDS (type) > 0 - && TYPE_FIELD_ARTIFICIAL (type, 0) - && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_PTR - && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, - 0)))) - fputs_unfiltered (" const", buf); - } - } + The parallel table begins immediately after the hash table + (at offset 8 + 8 * M from the beginning of the section), and consists of an + array of 32-bit indexes (using the byte order of the application binary), + corresponding 1-1 with slots in the hash table. Each entry in the parallel + table contains a 32-bit index into the pool of section numbers. For unused + hash table slots, the corresponding entry in the parallel table will be 0. - name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, - &length); - ui_file_delete (buf); + Given a 64-bit compilation unit signature or a type signature S, an entry + in the hash table is located as follows: + + 1) Calculate a primary hash H = S & MASK(k), where MASK(k) is a mask with + the low-order k bits all set to 1. + + 2) Calculate a secondary hash H' = (((S >> 32) & MASK(k)) | 1). + + 3) If the hash table entry at index H matches the signature, use that + entry. If the hash table entry at index H is unused (all zeroes), + terminate the search: the signature is not present in the table. + + 4) Let H = (H + H') modulo M. Repeat at Step 3. + + Because M > N and H' and M are relatively prime, the search is guaranteed + to stop at an unused slot or find the match. + + The pool of section numbers begins immediately following the hash table + (at offset 8 + 12 * M from the beginning of the section). The pool of + section numbers consists of an array of 32-bit words (using the byte order + of the application binary). Each item in the array is indexed starting + from 0. The hash table entry provides the index of the first section + number in the set. Additional section numbers in the set follow, and the + set is terminated by a 0 entry (section number 0 is not used in ELF). + + In each set of section numbers, the .debug_info.dwo or .debug_types.dwo + section must be the first entry in the set, and the .debug_abbrev.dwo must + be the second entry. Other members of the set may follow in any order. */ + +/* Create a hash table to map DWO IDs to their CU/TU entry in + .debug_{info,types}.dwo in DWP_FILE. + Returns NULL if there isn't one. + Note: This function processes DWP files only, not DWO files. */ + +static struct dwp_hash_table * +create_dwp_hash_table (struct dwp_file *dwp_file, int is_debug_types) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + bfd *dbfd = dwp_file->dbfd; + char *index_ptr, *index_end; + struct dwarf2_section_info *index; + uint32_t version, nr_units, nr_slots; + struct dwp_hash_table *htab; - if (cu->language == language_cplus) - { - char *cname - = dwarf2_canonicalize_name (name, cu, - &cu->objfile->objfile_obstack); + if (is_debug_types) + index = &dwp_file->sections.tu_index; + else + index = &dwp_file->sections.cu_index; - if (cname != NULL) - name = cname; - } - } - } + if (dwarf2_section_empty_p (index)) + return NULL; + dwarf2_read_section (objfile, index); - return name; -} + index_ptr = index->buffer; + index_end = index_ptr + index->size; -/* Return the fully qualified name of DIE, based on its DW_AT_name. - If scope qualifiers are appropriate they will be added. The result - will be allocated on the objfile_obstack, or NULL if the DIE does - not have a name. NAME may either be from a previous call to - dwarf2_name or NULL. + version = read_4_bytes (dbfd, index_ptr); + index_ptr += 8; /* Skip the unused word. */ + nr_units = read_4_bytes (dbfd, index_ptr); + index_ptr += 4; + nr_slots = read_4_bytes (dbfd, index_ptr); + index_ptr += 4; - The output string will be canonicalized (if C++/Java). */ + if (version != 1) + { + error (_("Dwarf Error: unsupported DWP file version (%u)" + " [in module %s]"), + version, dwp_file->name); + } + if (nr_slots != (nr_slots & -nr_slots)) + { + error (_("Dwarf Error: number of slots in DWP hash table (%u)" + " is not power of 2 [in module %s]"), + nr_slots, dwp_file->name); + } -static const char * -dwarf2_full_name (char *name, struct die_info *die, struct dwarf2_cu *cu) -{ - return dwarf2_compute_name (name, die, cu, 0); + htab = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_hash_table); + htab->nr_units = nr_units; + htab->nr_slots = nr_slots; + htab->hash_table = index_ptr; + htab->unit_table = htab->hash_table + sizeof (uint64_t) * nr_slots; + htab->section_pool = htab->unit_table + sizeof (uint32_t) * nr_slots; + + return htab; } -/* Construct a physname for the given DIE in CU. NAME may either be - from a previous call to dwarf2_name or NULL. The result will be - allocated on the objfile_objstack or NULL if the DIE does not have a - name. +/* Update SECTIONS with the data from SECTP. - The output string will be canonicalized (if C++/Java). */ + This function is like the other "locate" section routines that are + passed to bfd_map_over_sections, but in this context the sections to + read comes from the DWP hash table, not the full ELF section table. -static const char * -dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu) + The result is non-zero for success, or zero if an error was found. */ + +static int +locate_virtual_dwo_sections (asection *sectp, + struct virtual_dwo_sections *sections) { - struct attribute *attr; - const char *retval, *mangled = NULL, *canon = NULL; - struct cleanup *back_to; - int need_copy = 1; + const struct dwop_section_names *names = &dwop_section_names; - /* In this case dwarf2_compute_name is just a shortcut not building anything - on its own. */ - if (!die_needs_namespace (die, cu)) - return dwarf2_compute_name (name, die, cu, 1); + if (section_is_p (sectp->name, &names->abbrev_dwo)) + { + /* There can be only one. */ + if (sections->abbrev.asection != NULL) + return 0; + sections->abbrev.asection = sectp; + sections->abbrev.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->info_dwo) + || section_is_p (sectp->name, &names->types_dwo)) + { + /* There can be only one. */ + if (sections->info_or_types.asection != NULL) + return 0; + sections->info_or_types.asection = sectp; + sections->info_or_types.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->line_dwo)) + { + /* There can be only one. */ + if (sections->line.asection != NULL) + return 0; + sections->line.asection = sectp; + sections->line.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->loc_dwo)) + { + /* There can be only one. */ + if (sections->loc.asection != NULL) + return 0; + sections->loc.asection = sectp; + sections->loc.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->macinfo_dwo)) + { + /* There can be only one. */ + if (sections->macinfo.asection != NULL) + return 0; + sections->macinfo.asection = sectp; + sections->macinfo.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->macro_dwo)) + { + /* There can be only one. */ + if (sections->macro.asection != NULL) + return 0; + sections->macro.asection = sectp; + sections->macro.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->str_offsets_dwo)) + { + /* There can be only one. */ + if (sections->str_offsets.asection != NULL) + return 0; + sections->str_offsets.asection = sectp; + sections->str_offsets.size = bfd_get_section_size (sectp); + } + else + { + /* No other kind of section is valid. */ + return 0; + } - back_to = make_cleanup (null_cleanup, NULL); + return 1; +} - attr = dwarf2_attr (die, DW_AT_linkage_name, cu); - if (!attr) - attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); +/* Create a dwo_unit object for the DWO with signature SIGNATURE. + HTAB is the hash table from the DWP file. + SECTION_INDEX is the index of the DWO in HTAB. */ + +static struct dwo_unit * +create_dwo_in_dwp (struct dwp_file *dwp_file, + const struct dwp_hash_table *htab, + uint32_t section_index, + ULONGEST signature, int is_debug_types) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + bfd *dbfd = dwp_file->dbfd; + const char *kind = is_debug_types ? "TU" : "CU"; + struct dwo_file *dwo_file; + struct dwo_unit *dwo_unit; + struct virtual_dwo_sections sections; + void **dwo_file_slot; + char *virtual_dwo_name; + struct dwarf2_section_info *cutu; + struct cleanup *cleanups; + int i; - /* DW_AT_linkage_name is missing in some cases - depend on what GDB - has computed. */ - if (attr && DW_STRING (attr)) + if (dwarf2_read_debug) { - char *demangled; + fprintf_unfiltered (gdb_stdlog, "Reading %s %u/0x%s in DWP file: %s\n", + kind, + section_index, phex (signature, sizeof (signature)), + dwp_file->name); + } - mangled = DW_STRING (attr); + /* Fetch the sections of this DWO. + Put a limit on the number of sections we look for so that bad data + doesn't cause us to loop forever. */ - /* Use DMGL_RET_DROP for C++ template functions to suppress their return - type. It is easier for GDB users to search for such functions as - `name(params)' than `long name(params)'. In such case the minimal - symbol names do not match the full symbol names but for template - functions there is never a need to look up their definition from their - declaration so the only disadvantage remains the minimal symbol - variant `long name(params)' does not have the proper inferior type. - */ +#define MAX_NR_DWO_SECTIONS \ + (1 /* .debug_info or .debug_types */ \ + + 1 /* .debug_abbrev */ \ + + 1 /* .debug_line */ \ + + 1 /* .debug_loc */ \ + + 1 /* .debug_str_offsets */ \ + + 1 /* .debug_macro */ \ + + 1 /* .debug_macinfo */ \ + + 1 /* trailing zero */) - demangled = cplus_demangle (mangled, (DMGL_PARAMS | DMGL_ANSI - | (cu->language == language_java - ? DMGL_JAVA | DMGL_RET_POSTFIX - : DMGL_RET_DROP))); - if (demangled) + memset (§ions, 0, sizeof (sections)); + cleanups = make_cleanup (null_cleanup, 0); + + for (i = 0; i < MAX_NR_DWO_SECTIONS; ++i) + { + asection *sectp; + uint32_t section_nr = + read_4_bytes (dbfd, + htab->section_pool + + (section_index + i) * sizeof (uint32_t)); + + if (section_nr == 0) + break; + if (section_nr >= dwp_file->num_sections) { - make_cleanup (xfree, demangled); - canon = demangled; + error (_("Dwarf Error: bad DWP hash table, section number too large" + " [in module %s]"), + dwp_file->name); } - else + + sectp = dwp_file->elf_sections[section_nr]; + if (! locate_virtual_dwo_sections (sectp, §ions)) { - canon = mangled; - need_copy = 0; + error (_("Dwarf Error: bad DWP hash table, invalid section found" + " [in module %s]"), + dwp_file->name); } } - if (canon == NULL || check_physname) + if (i < 2 + || sections.info_or_types.asection == NULL + || sections.abbrev.asection == NULL) { - const char *physname = dwarf2_compute_name (name, die, cu, 1); - - if (canon != NULL && strcmp (physname, canon) != 0) - { - /* It may not mean a bug in GDB. The compiler could also - compute DW_AT_linkage_name incorrectly. But in such case - GDB would need to be bug-to-bug compatible. */ + error (_("Dwarf Error: bad DWP hash table, missing DWO sections" + " [in module %s]"), + dwp_file->name); + } + if (i == MAX_NR_DWO_SECTIONS) + { + error (_("Dwarf Error: bad DWP hash table, too many DWO sections" + " [in module %s]"), + dwp_file->name); + } - 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); + /* It's easier for the rest of the code if we fake a struct dwo_file and + have dwo_unit "live" in that. At least for now. - /* Prefer DW_AT_linkage_name (in the CANON form) - when it - is available here - over computed PHYSNAME. It is safer - against both buggy GDB and buggy compilers. */ + The DWP file can be made up of a random collection of CUs and TUs. + However, for each CU + set of TUs that came from the same original DWO + file, we want to combine them back into a virtual DWO file to save space + (fewer struct dwo_file objects to allocated). Remember that for really + large apps there can be on the order of 8K CUs and 200K TUs, or more. */ - retval = canon; - } - else + virtual_dwo_name = + xstrprintf ("virtual-dwo/%d-%d-%d-%d", + sections.abbrev.asection ? sections.abbrev.asection->id : 0, + sections.line.asection ? sections.line.asection->id : 0, + sections.loc.asection ? sections.loc.asection->id : 0, + (sections.str_offsets.asection + ? sections.str_offsets.asection->id + : 0)); + make_cleanup (xfree, virtual_dwo_name); + /* Can we use an existing virtual DWO file? */ + dwo_file_slot = lookup_dwo_file_slot (virtual_dwo_name); + /* Create one if necessary. */ + if (*dwo_file_slot == NULL) + { + if (dwarf2_read_debug) { - retval = physname; - need_copy = 0; + fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n", + virtual_dwo_name); } + dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file); + dwo_file->name = obstack_copy0 (&objfile->objfile_obstack, + virtual_dwo_name, + strlen (virtual_dwo_name)); + dwo_file->sections.abbrev = sections.abbrev; + dwo_file->sections.line = sections.line; + dwo_file->sections.loc = sections.loc; + dwo_file->sections.macinfo = sections.macinfo; + dwo_file->sections.macro = sections.macro; + dwo_file->sections.str_offsets = sections.str_offsets; + /* The "str" section is global to the entire DWP file. */ + dwo_file->sections.str = dwp_file->sections.str; + /* The info or types section is assigned later to dwo_unit, + there's no need to record it in dwo_file. + Also, we can't simply record type sections in dwo_file because + we record a pointer into the vector in dwo_unit. As we collect more + types we'll grow the vector and eventually have to reallocate space + for it, invalidating all the pointers into the current copy. */ + *dwo_file_slot = dwo_file; } else - retval = canon; + { + if (dwarf2_read_debug) + { + fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n", + virtual_dwo_name); + } + dwo_file = *dwo_file_slot; + } + do_cleanups (cleanups); - if (need_copy) - retval = obsavestring (retval, strlen (retval), - &cu->objfile->objfile_obstack); + dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit); + dwo_unit->dwo_file = dwo_file; + dwo_unit->signature = signature; + dwo_unit->info_or_types_section = + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct dwarf2_section_info)); + *dwo_unit->info_or_types_section = sections.info_or_types; + /* offset, length, type_offset_in_tu are set later. */ - do_cleanups (back_to); - return retval; + return dwo_unit; } -/* Read the import statement specified by the given die and record it. */ +/* Lookup the DWO with SIGNATURE in DWP_FILE. */ -static void -read_import_statement (struct die_info *die, struct dwarf2_cu *cu) +static struct dwo_unit * +lookup_dwo_in_dwp (struct dwp_file *dwp_file, + const struct dwp_hash_table *htab, + ULONGEST signature, int is_debug_types) { - struct attribute *import_attr; - struct die_info *imported_die, *child_die; - struct dwarf2_cu *imported_cu; - const char *imported_name; - const char *imported_name_prefix; - const char *canonical_name; - const char *import_alias; - const char *imported_declaration = NULL; - const char *import_prefix; - VEC (const_char_ptr) *excludes = NULL; - struct cleanup *cleanups; + bfd *dbfd = dwp_file->dbfd; + uint32_t mask = htab->nr_slots - 1; + uint32_t hash = signature & mask; + uint32_t hash2 = ((signature >> 32) & mask) | 1; + unsigned int i; + void **slot; + struct dwo_unit find_dwo_cu, *dwo_cu; - char *temp; + memset (&find_dwo_cu, 0, sizeof (find_dwo_cu)); + find_dwo_cu.signature = signature; + slot = htab_find_slot (dwp_file->loaded_cutus, &find_dwo_cu, INSERT); - import_attr = dwarf2_attr (die, DW_AT_import, cu); - if (import_attr == NULL) - { - complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"), - dwarf_tag_name (die->tag)); - return; - } + if (*slot != NULL) + return *slot; - imported_cu = cu; - imported_die = follow_die_ref_or_sig (die, import_attr, &imported_cu); - imported_name = dwarf2_name (imported_die, imported_cu); - if (imported_name == NULL) + /* Use a for loop so that we don't loop forever on bad debug info. */ + for (i = 0; i < htab->nr_slots; ++i) { - /* GCC bug: https://bugzilla.redhat.com/show_bug.cgi?id=506524 - - The import in the following code: - namespace A - { - typedef int B; - } + ULONGEST signature_in_table; - int main () - { - using A::B; - B b; - return b; - } - - ... - <2><51>: Abbrev Number: 3 (DW_TAG_imported_declaration) - <52> DW_AT_decl_file : 1 - <53> DW_AT_decl_line : 6 - <54> DW_AT_import : <0x75> - <2><58>: Abbrev Number: 4 (DW_TAG_typedef) - <59> DW_AT_name : B - <5b> DW_AT_decl_file : 1 - <5c> DW_AT_decl_line : 2 - <5d> DW_AT_type : <0x6e> - ... - <1><75>: Abbrev Number: 7 (DW_TAG_base_type) - <76> DW_AT_byte_size : 4 - <77> DW_AT_encoding : 5 (signed) + signature_in_table = + read_8_bytes (dbfd, htab->hash_table + hash * sizeof (uint64_t)); + if (signature_in_table == signature) + { + uint32_t section_index = + read_4_bytes (dbfd, htab->unit_table + hash * sizeof (uint32_t)); - imports the wrong die ( 0x75 instead of 0x58 ). - This case will be ignored until the gcc bug is fixed. */ - return; + *slot = create_dwo_in_dwp (dwp_file, htab, section_index, + signature, is_debug_types); + return *slot; + } + if (signature_in_table == 0) + return NULL; + hash = (hash + hash2) & mask; } - /* Figure out the local name after import. */ - import_alias = dwarf2_name (die, cu); + error (_("Dwarf Error: bad DWP hash table, lookup didn't terminate" + " [in module %s]"), + dwp_file->name); +} - /* Figure out where the statement is being imported to. */ - import_prefix = determine_prefix (die, cu); +/* Subroutine of open_dwop_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. + If IS_DWP is TRUE, we're opening a DWP file, otherwise a DWO file. + In case of trouble, return NULL. + NOTE: This function is derived from symfile_bfd_open. */ - /* Figure out what the scope of the imported die is and prepend it - to the name of the imported die. */ - imported_name_prefix = determine_prefix (imported_die, imported_cu); +static bfd * +try_open_dwop_file (const char *file_name, int is_dwp) +{ + bfd *sym_bfd; + int desc, flags; + char *absolute_name; - if (imported_die->tag != DW_TAG_namespace - && imported_die->tag != DW_TAG_module) + flags = OPF_TRY_CWD_FIRST; + if (is_dwp) + flags |= OPF_SEARCH_IN_PATH; + desc = openp (debug_file_directory, flags, file_name, + O_RDONLY | O_BINARY, &absolute_name); + if (desc < 0) + return NULL; + + sym_bfd = gdb_bfd_open (absolute_name, gnutarget, desc); + if (!sym_bfd) { - imported_declaration = imported_name; - canonical_name = imported_name_prefix; + xfree (absolute_name); + return NULL; } - else if (strlen (imported_name_prefix) > 0) + xfree (absolute_name); + bfd_set_cacheable (sym_bfd, 1); + + if (!bfd_check_format (sym_bfd, bfd_object)) { - temp = alloca (strlen (imported_name_prefix) - + 2 + strlen (imported_name) + 1); - strcpy (temp, imported_name_prefix); - strcat (temp, "::"); - strcat (temp, imported_name); - canonical_name = temp; + gdb_bfd_unref (sym_bfd); /* This also closes desc. */ + return NULL; } - else - canonical_name = imported_name; - cleanups = make_cleanup (VEC_cleanup (const_char_ptr), &excludes); + return sym_bfd; +} - if (die->tag == DW_TAG_imported_module && cu->language == language_fortran) - for (child_die = die->child; child_die && child_die->tag; - child_die = sibling_die (child_die)) - { - /* DWARF-4: A Fortran use statement with a “rename list” may be - represented by an imported module entry with an import attribute - referring to the module and owned entries corresponding to those - entities that are renamed as part of being imported. */ +/* Try to open DWO/DWP file FILE_NAME. + COMP_DIR is the DW_AT_comp_dir attribute. + If IS_DWP is TRUE, we're opening a DWP file, otherwise a DWO file. + 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. */ - if (child_die->tag != DW_TAG_imported_declaration) - { - complaint (&symfile_complaints, - _("child DW_TAG_imported_declaration expected " - "- DIE at 0x%x [in module %s]"), - child_die->offset, cu->objfile->name); - continue; - } +static bfd * +open_dwop_file (const char *file_name, const char *comp_dir, int is_dwp) +{ + bfd *abfd; - import_attr = dwarf2_attr (child_die, DW_AT_import, cu); - if (import_attr == NULL) - { - complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"), - dwarf_tag_name (child_die->tag)); - continue; - } + if (IS_ABSOLUTE_PATH (file_name)) + return try_open_dwop_file (file_name, is_dwp); - imported_cu = cu; - imported_die = follow_die_ref_or_sig (child_die, import_attr, - &imported_cu); - imported_name = dwarf2_name (imported_die, imported_cu); - if (imported_name == NULL) - { - 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); - continue; - } + /* Before trying the search path, try DWO_NAME in COMP_DIR. */ - VEC_safe_push (const_char_ptr, excludes, imported_name); + if (comp_dir != NULL) + { + char *path_to_try = concat (comp_dir, SLASH_STRING, file_name, NULL); + + /* NOTE: If comp_dir is a relative path, this will also try the + search path, which seems useful. */ + abfd = try_open_dwop_file (path_to_try, is_dwp); + xfree (path_to_try); + if (abfd != NULL) + return abfd; + } - process_die (child_die, cu); - } + /* That didn't work, try debug-file-directory, which, despite its name, + is a list of paths. */ - cp_add_using_directive (import_prefix, - canonical_name, - import_alias, - imported_declaration, - excludes, - &cu->objfile->objfile_obstack); + if (*debug_file_directory == '\0') + return NULL; - do_cleanups (cleanups); + return try_open_dwop_file (file_name, is_dwp); } +/* 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 -initialize_cu_func_list (struct dwarf2_cu *cu) +dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp, void *dwo_sections_ptr) { - cu->first_fn = cu->last_fn = cu->cached_fn = NULL; + struct dwo_sections *dwo_sections = dwo_sections_ptr; + const struct dwop_section_names *names = &dwop_section_names; + + if (section_is_p (sectp->name, &names->abbrev_dwo)) + { + dwo_sections->abbrev.asection = sectp; + dwo_sections->abbrev.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->info_dwo)) + { + dwo_sections->info.asection = sectp; + dwo_sections->info.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->line_dwo)) + { + dwo_sections->line.asection = sectp; + dwo_sections->line.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->loc_dwo)) + { + dwo_sections->loc.asection = sectp; + dwo_sections->loc.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->macinfo_dwo)) + { + dwo_sections->macinfo.asection = sectp; + dwo_sections->macinfo.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->macro_dwo)) + { + dwo_sections->macro.asection = sectp; + dwo_sections->macro.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->str_dwo)) + { + dwo_sections->str.asection = sectp; + dwo_sections->str.size = bfd_get_section_size (sectp); + } + else if (section_is_p (sectp->name, &names->str_offsets_dwo)) + { + dwo_sections->str_offsets.asection = sectp; + dwo_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_sections->types, + &type_section); + } } -/* Cleanup function for read_file_scope. */ +/* Initialize the use of the DWO file specified by DWO_NAME. + The result is NULL if DWO_NAME can't be found. */ -static void -free_cu_line_header (void *arg) +static struct dwo_file * +open_and_init_dwo_file (const char *dwo_name, const char *comp_dir) { - struct dwarf2_cu *cu = arg; + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwo_file *dwo_file; + bfd *dbfd; + struct cleanup *cleanups; - free_line_header (cu->line_header); - cu->line_header = NULL; + dbfd = open_dwop_file (dwo_name, comp_dir, 0); + if (dbfd == NULL) + { + if (dwarf2_read_debug) + fprintf_unfiltered (gdb_stdlog, "DWO file not found: %s\n", dwo_name); + return NULL; + } + dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file); + dwo_file->name = obstack_copy0 (&objfile->objfile_obstack, + dwo_name, strlen (dwo_name)); + dwo_file->dbfd = dbfd; + + cleanups = make_cleanup (free_dwo_file_cleanup, dwo_file); + + bfd_map_over_sections (dbfd, dwarf2_locate_dwo_sections, &dwo_file->sections); + + dwo_file->cus = create_dwo_debug_info_hash_table (dwo_file); + + dwo_file->tus = create_debug_types_hash_table (dwo_file, + dwo_file->sections.types); + + discard_cleanups (cleanups); + + if (dwarf2_read_debug) + fprintf_unfiltered (gdb_stdlog, "DWO file found: %s\n", dwo_name); + + return dwo_file; } +/* This function is mapped across the sections and remembers the offset and + size of each of the DWP debugging sections we are interested in. */ + static void -find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu, - char **name, char **comp_dir) +dwarf2_locate_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr) { - struct attribute *attr; + struct dwp_file *dwp_file = dwp_file_ptr; + const struct dwop_section_names *names = &dwop_section_names; + unsigned int elf_section_nr = elf_section_data (sectp)->this_idx; - *name = NULL; - *comp_dir = NULL; + /* Record the ELF section number for later lookup: this is what the + .debug_cu_index,.debug_tu_index tables use. */ + gdb_assert (elf_section_nr < dwp_file->num_sections); + dwp_file->elf_sections[elf_section_nr] = sectp; - /* Find the filename. Do not use dwarf2_name here, since the filename - is not a source language identifier. */ - attr = dwarf2_attr (die, DW_AT_name, cu); - if (attr) + /* Look for specific sections that we need. */ + if (section_is_p (sectp->name, &names->str_dwo)) { - *name = DW_STRING (attr); + dwp_file->sections.str.asection = sectp; + dwp_file->sections.str.size = bfd_get_section_size (sectp); } - - attr = dwarf2_attr (die, DW_AT_comp_dir, cu); - if (attr) - *comp_dir = DW_STRING (attr); - else if (*name != NULL && IS_ABSOLUTE_PATH (*name)) + else if (section_is_p (sectp->name, &names->cu_index)) { - *comp_dir = ldirname (*name); - if (*comp_dir != NULL) - make_cleanup (xfree, *comp_dir); + dwp_file->sections.cu_index.asection = sectp; + dwp_file->sections.cu_index.size = bfd_get_section_size (sectp); } - if (*comp_dir != NULL) + else if (section_is_p (sectp->name, &names->tu_index)) { - /* Irix 6.2 native cc prepends .: to the compilation - directory, get rid of it. */ - char *cp = strchr (*comp_dir, ':'); - - if (cp && cp != *comp_dir && cp[-1] == '.' && cp[1] == '/') - *comp_dir = cp + 1; + dwp_file->sections.tu_index.asection = sectp; + dwp_file->sections.tu_index.size = bfd_get_section_size (sectp); } +} - if (*name == NULL) - *name = ""; +/* Hash function for dwp_file loaded CUs/TUs. */ + +static hashval_t +hash_dwp_loaded_cutus (const void *item) +{ + const struct dwo_unit *dwo_unit = item; + + /* This drops the top 32 bits of the signature, but is ok for a hash. */ + return dwo_unit->signature; } -/* 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. */ +/* Equality function for dwp_file loaded CUs/TUs. */ -static void -handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, - const char *comp_dir, int want_line_info) +static int +eq_dwp_loaded_cutus (const void *a, const void *b) { - struct attribute *attr; - struct objfile *objfile = cu->objfile; - bfd *abfd = objfile->obfd; + const struct dwo_unit *dua = a; + const struct dwo_unit *dub = b; - 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); + return dua->signature == dub->signature; +} - if (line_header) - { - cu->line_header = line_header; - make_cleanup (free_cu_line_header, cu); - dwarf_decode_lines (line_header, comp_dir, cu, NULL, want_line_info); - } - } +/* Allocate a hash table for dwp_file loaded CUs/TUs. */ + +static htab_t +allocate_dwp_loaded_cutus_table (struct objfile *objfile) +{ + return htab_create_alloc_ex (3, + hash_dwp_loaded_cutus, + eq_dwp_loaded_cutus, + NULL, + &objfile->objfile_obstack, + hashtab_obstack_allocate, + dummy_obstack_deallocate); } -/* Process DW_TAG_compile_unit. */ +/* Initialize the use of the DWP file for the current objfile. + By convention the name of the DWP file is ${objfile}.dwp. + The result is NULL if it can't be found. */ -static void -read_file_scope (struct die_info *die, struct dwarf2_cu *cu) +static struct dwp_file * +open_and_init_dwp_file (const char *comp_dir) { - struct objfile *objfile = cu->objfile; - struct cleanup *back_to = make_cleanup (null_cleanup, 0); - CORE_ADDR lowpc = ((CORE_ADDR) -1); - CORE_ADDR highpc = ((CORE_ADDR) 0); - struct attribute *attr; - char *name = NULL; - char *comp_dir = NULL; - struct die_info *child_die; - bfd *abfd = objfile->obfd; - CORE_ADDR baseaddr; + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwp_file *dwp_file; + char *dwp_name; + bfd *dbfd; + struct cleanup *cleanups; - baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); + dwp_name = xstrprintf ("%s.dwp", dwarf2_per_objfile->objfile->name); + cleanups = make_cleanup (xfree, dwp_name); - get_scope_pc_bounds (die, &lowpc, &highpc, cu); + dbfd = open_dwop_file (dwp_name, comp_dir, 1); + if (dbfd == NULL) + { + if (dwarf2_read_debug) + fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name); + do_cleanups (cleanups); + return NULL; + } + dwp_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_file); + dwp_file->name = obstack_copy0 (&objfile->objfile_obstack, + dwp_name, strlen (dwp_name)); + dwp_file->dbfd = dbfd; + do_cleanups (cleanups); - /* If we didn't find a lowpc, set it to highpc to avoid complaints - from finish_block. */ - if (lowpc == ((CORE_ADDR) -1)) - lowpc = highpc; - lowpc += baseaddr; - highpc += baseaddr; + /* +1: section 0 is unused */ + dwp_file->num_sections = bfd_count_sections (dbfd) + 1; + dwp_file->elf_sections = + OBSTACK_CALLOC (&objfile->objfile_obstack, + dwp_file->num_sections, asection *); - find_file_and_directory (die, cu, &name, &comp_dir); + bfd_map_over_sections (dbfd, dwarf2_locate_dwp_sections, dwp_file); - attr = dwarf2_attr (die, DW_AT_language, cu); - if (attr) + dwp_file->cus = create_dwp_hash_table (dwp_file, 0); + + dwp_file->tus = create_dwp_hash_table (dwp_file, 1); + + dwp_file->loaded_cutus = allocate_dwp_loaded_cutus_table (objfile); + + if (dwarf2_read_debug) { - set_cu_language (DW_UNSND (attr), cu); + fprintf_unfiltered (gdb_stdlog, "DWP file found: %s\n", dwp_file->name); + fprintf_unfiltered (gdb_stdlog, + " %u CUs, %u TUs\n", + dwp_file->cus ? dwp_file->cus->nr_units : 0, + dwp_file->tus ? dwp_file->tus->nr_units : 0); } - attr = dwarf2_attr (die, DW_AT_producer, cu); - if (attr) - cu->producer = DW_STRING (attr); + return dwp_file; +} - /* The XLCL doesn't generate DW_LANG_OpenCL because this attribute is not - standardised yet. As a workaround for the language detection we fall - back to the DW_AT_producer string. */ - if (cu->producer && strstr (cu->producer, "IBM XL C for OpenCL") != NULL) - cu->language = language_opencl; +/* Subroutine of lookup_dwo_comp_unit, lookup_dwo_type_unit. + Look up the CU/TU with signature SIGNATURE, either in DWO file DWO_NAME + or in the DWP file for the objfile, referenced by THIS_UNIT. + If non-NULL, comp_dir is the DW_AT_comp_dir attribute. + IS_DEBUG_TYPES is non-zero if reading a TU, otherwise read a CU. - /* We assume that we're processing GCC output. */ - processing_gcc_compilation = 2; + This is called, for example, when wanting to read a variable with a + complex location. Therefore we don't want to do file i/o for every call. + Therefore we don't want to look for a DWO file on every call. + Therefore we first see if we've already seen SIGNATURE in a DWP file, + then we check if we've already seen DWO_NAME, and only THEN do we check + for a DWO file. - processing_has_namespace_info = 0; + The result is a pointer to the dwo_unit object or NULL if we didn't find it + (dwo_id mismatch or couldn't find the DWO/DWP file). */ - start_symtab (name, comp_dir, lowpc); - record_debugformat ("DWARF 2"); - record_producer (cu->producer); +static struct dwo_unit * +lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit, + const char *dwo_name, const char *comp_dir, + ULONGEST signature, int is_debug_types) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + const char *kind = is_debug_types ? "TU" : "CU"; + void **dwo_file_slot; + struct dwo_file *dwo_file; + struct dwp_file *dwp_file; - initialize_cu_func_list (cu); + /* Have we already read SIGNATURE from a DWP file? */ - /* 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); + if (! dwarf2_per_objfile->dwp_checked) + { + dwarf2_per_objfile->dwp_file = open_and_init_dwp_file (comp_dir); + dwarf2_per_objfile->dwp_checked = 1; + } + dwp_file = dwarf2_per_objfile->dwp_file; - /* Process all dies in compilation unit. */ - if (die->child != NULL) + if (dwp_file != NULL) { - child_die = die->child; - while (child_die && child_die->tag) + const struct dwp_hash_table *dwp_htab = + is_debug_types ? dwp_file->tus : dwp_file->cus; + + if (dwp_htab != NULL) { - process_die (child_die, cu); - child_die = sibling_die (child_die); + struct dwo_unit *dwo_cutu = + lookup_dwo_in_dwp (dwp_file, dwp_htab, signature, is_debug_types); + + if (dwo_cutu != NULL) + { + if (dwarf2_read_debug) + { + fprintf_unfiltered (gdb_stdlog, + "Virtual DWO %s %s found: @%s\n", + kind, hex_string (signature), + host_address_to_string (dwo_cutu)); + } + return dwo_cutu; + } } } - /* Decode macro information, if present. Dwarf 2 macro information - refers to information in the line number info statement program - header, so we can only read it if we've read the header - successfully. */ - attr = dwarf2_attr (die, DW_AT_GNU_macros, cu); - if (attr && cu->line_header) - { - if (dwarf2_attr (die, DW_AT_macro_info, cu)) - complaint (&symfile_complaints, - _("CU refers to both DW_AT_GNU_macros and DW_AT_macro_info")); + /* Have we already seen DWO_NAME? */ - dwarf_decode_macros (cu->line_header, DW_UNSND (attr), - comp_dir, abfd, cu, - &dwarf2_per_objfile->macro, 1); + dwo_file_slot = lookup_dwo_file_slot (dwo_name); + if (*dwo_file_slot == NULL) + { + /* Read in the file and build a table of the DWOs it contains. */ + *dwo_file_slot = open_and_init_dwo_file (dwo_name, comp_dir); } - else + /* NOTE: This will be NULL if unable to open the file. */ + dwo_file = *dwo_file_slot; + + if (dwo_file != NULL) { - attr = dwarf2_attr (die, DW_AT_macro_info, cu); - if (attr && cu->line_header) + htab_t htab = is_debug_types ? dwo_file->tus : dwo_file->cus; + + if (htab != NULL) { - unsigned int macro_offset = DW_UNSND (attr); + struct dwo_unit find_dwo_cutu, *dwo_cutu; + + memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu)); + find_dwo_cutu.signature = signature; + dwo_cutu = htab_find (htab, &find_dwo_cutu); - dwarf_decode_macros (cu->line_header, macro_offset, - comp_dir, abfd, cu, - &dwarf2_per_objfile->macinfo, 0); + if (dwo_cutu != NULL) + { + if (dwarf2_read_debug) + { + fprintf_unfiltered (gdb_stdlog, "DWO %s %s(%s) found: @%s\n", + kind, dwo_name, hex_string (signature), + host_address_to_string (dwo_cutu)); + } + return dwo_cutu; + } } } - do_cleanups (back_to); -} - -/* Process DW_TAG_type_unit. - For TUs we want to skip the first top level sibling if it's not the - actual type being defined by this TU. In this case the first top - level sibling is there to provide context only. */ - -static void -read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu) -{ - struct objfile *objfile = cu->objfile; - struct cleanup *back_to = make_cleanup (null_cleanup, 0); - CORE_ADDR lowpc; - struct attribute *attr; - char *name = NULL; - char *comp_dir = NULL; - struct die_info *child_die; - bfd *abfd = objfile->obfd; - - /* start_symtab needs a low pc, but we don't really have one. - Do what read_file_scope would do in the absence of such info. */ - lowpc = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - /* Find the filename. Do not use dwarf2_name here, since the filename - is not a source language identifier. */ - attr = dwarf2_attr (die, DW_AT_name, cu); - if (attr) - name = DW_STRING (attr); + /* We didn't find it. This could mean a dwo_id mismatch, or + someone deleted the DWO/DWP file, or the search path isn't set up + correctly to find the file. */ - attr = dwarf2_attr (die, DW_AT_comp_dir, cu); - if (attr) - comp_dir = DW_STRING (attr); - else if (name != NULL && IS_ABSOLUTE_PATH (name)) + if (dwarf2_read_debug) { - comp_dir = ldirname (name); - if (comp_dir != NULL) - make_cleanup (xfree, comp_dir); + fprintf_unfiltered (gdb_stdlog, "DWO %s %s(%s) not found\n", + kind, dwo_name, hex_string (signature)); } - if (name == NULL) - name = ""; + complaint (&symfile_complaints, + _("Could not find DWO CU referenced by CU at offset 0x%x" + " [in module %s]"), + this_unit->offset.sect_off, objfile->name); + return NULL; +} - attr = dwarf2_attr (die, DW_AT_language, cu); - if (attr) - set_cu_language (DW_UNSND (attr), cu); +/* Lookup the DWO CU DWO_NAME/SIGNATURE referenced from THIS_CU. + See lookup_dwo_cutu_unit for details. */ - /* 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); +static struct dwo_unit * +lookup_dwo_comp_unit (struct dwarf2_per_cu_data *this_cu, + const char *dwo_name, const char *comp_dir, + ULONGEST signature) +{ + return lookup_dwo_cutu (this_cu, dwo_name, comp_dir, signature, 0); +} - /* We assume that we're processing GCC output. */ - processing_gcc_compilation = 2; +/* Lookup the DWO TU DWO_NAME/SIGNATURE referenced from THIS_TU. + See lookup_dwo_cutu_unit for details. */ - processing_has_namespace_info = 0; +static struct dwo_unit * +lookup_dwo_type_unit (struct signatured_type *this_tu, + const char *dwo_name, const char *comp_dir) +{ + return lookup_dwo_cutu (&this_tu->per_cu, dwo_name, comp_dir, this_tu->signature, 1); +} - start_symtab (name, comp_dir, lowpc); - record_debugformat ("DWARF 2"); - record_producer (cu->producer); +/* Free all resources associated with DWO_FILE. + Close the DWO file and munmap the sections. + All memory should be on the objfile obstack. */ - /* 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); +static void +free_dwo_file (struct dwo_file *dwo_file, struct objfile *objfile) +{ + int ix; + struct dwarf2_section_info *section; - /* Process the dies in the type unit. */ - if (die->child == NULL) - { - dump_die_for_error (die); - error (_("Dwarf Error: Missing children for type unit [in module %s]"), - bfd_get_filename (abfd)); - } + /* Note: dbfd is NULL for virtual DWO files. */ + gdb_bfd_unref (dwo_file->dbfd); - child_die = die->child; + VEC_free (dwarf2_section_info_def, dwo_file->sections.types); +} - while (child_die && child_die->tag) - { - process_die (child_die, cu); +/* Wrapper for free_dwo_file for use in cleanups. */ - child_die = sibling_die (child_die); - } +static void +free_dwo_file_cleanup (void *arg) +{ + struct dwo_file *dwo_file = (struct dwo_file *) arg; + struct objfile *objfile = dwarf2_per_objfile->objfile; - do_cleanups (back_to); + free_dwo_file (dwo_file, objfile); } -static void -add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc, - struct dwarf2_cu *cu) +/* Traversal function for free_dwo_files. */ + +static int +free_dwo_file_from_slot (void **slot, void *info) { - struct function_range *thisfn; + struct dwo_file *dwo_file = (struct dwo_file *) *slot; + struct objfile *objfile = (struct objfile *) info; + + free_dwo_file (dwo_file, objfile); - 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; + return 1; +} - if (cu->last_fn == NULL) - cu->first_fn = thisfn; - else - cu->last_fn->next = thisfn; +/* Free all resources associated with DWO_FILES. */ - cu->last_fn = thisfn; +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. */ @@ -5898,8 +9311,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. */ @@ -5929,7 +9342,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; @@ -5972,13 +9385,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; } @@ -5987,20 +9400,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); @@ -6021,7 +9436,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) CORE_ADDR highpc; struct die_info *child_die; struct attribute *attr, *call_line, *call_file; - char *name; + const char *name; CORE_ADDR baseaddr; struct block *block; int inlined_func = (die->tag == DW_TAG_inlined_subroutine); @@ -6051,7 +9466,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; } @@ -6063,16 +9479,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)) @@ -6160,10 +9573,10 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) lowpc, highpc, objfile); /* For C++, set the block's scope. */ - if (cu->language == language_cplus || cu->language == language_fortran) - cp_set_block_scope (new->name, block, &objfile->objfile_obstack, - determine_prefix (die, cu), - processing_has_namespace_info); + if ((cu->language == language_cplus || cu->language == language_fortran) + && cu->processing_has_namespace_info) + block_set_scope (block, determine_prefix (die, cu), + &objfile->objfile_obstack); /* If we have address ranges, record them. */ dwarf2_record_block_ranges (die, block, baseaddr, cu); @@ -6189,7 +9602,6 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) when we finish processing a function scope, we may need to go back to building a containing block's symbol lists. */ local_symbols = new->locals; - param_symbols = new->params; using_directives = new->using_directives; /* If we've finished processing a top-level function, subsequent @@ -6278,7 +9690,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("missing DW_AT_low_pc for DW_TAG_GNU_call_site " "DIE 0x%x [in module %s]"), - die->offset, cu->objfile->name); + die->offset.sect_off, objfile->name); return; } pc = DW_ADDR (attr) + baseaddr; @@ -6294,7 +9706,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("Duplicate PC %s for DW_TAG_GNU_call_site " "DIE 0x%x [in module %s]"), - paddress (gdbarch, pc), die->offset, cu->objfile->name); + paddress (gdbarch, pc), die->offset.sect_off, objfile->name); return; } @@ -6309,7 +9721,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) 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, cu->objfile->name); + child_die->tag, child_die->offset.sect_off, objfile->name); continue; } @@ -6367,7 +9779,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) complaint (&symfile_complaints, _("Cannot find function owning DW_TAG_GNU_call_site " "DIE 0x%x [in module %s]"), - die->offset, cu->objfile->name); + die->offset.sect_off, objfile->name); } } @@ -6390,7 +9802,6 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) } else if (is_ref_attr (attr)) { - struct objfile *objfile = cu->objfile; struct dwarf2_cu *target_cu = cu; struct die_info *target_die; @@ -6398,16 +9809,25 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *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); + const char *target_physname = NULL; + struct attribute *target_attr; + + /* Prefer the mangled name; otherwise compute the demangled one. */ + target_attr = dwarf2_attr (target_die, DW_AT_linkage_name, target_cu); + if (target_attr == NULL) + target_attr = dwarf2_attr (target_die, DW_AT_MIPS_linkage_name, + target_cu); + if (target_attr != NULL && DW_STRING (target_attr) != NULL) + target_physname = DW_STRING (target_attr); + else + 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, cu->objfile->name); + die->offset.sect_off, objfile->name); else - SET_FIELD_PHYSNAME (call_site->target, (char *) target_physname); + SET_FIELD_PHYSNAME (call_site->target, target_physname); } else { @@ -6418,7 +9838,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) 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, cu->objfile->name); + die->offset.sect_off, objfile->name); else SET_FIELD_PHYSADDR (call_site->target, lowpc + baseaddr); } @@ -6427,7 +9847,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) 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, cu->objfile->name); + die->offset.sect_off, objfile->name); call_site->per_cu = cu->per_cu; @@ -6435,8 +9855,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) child_die && child_die->tag; child_die = sibling_die (child_die)) { - struct dwarf2_locexpr_baton *dlbaton; struct call_site_parameter *parameter; + struct attribute *loc, *origin; if (child_die->tag != DW_TAG_GNU_call_site_parameter) { @@ -6447,31 +9867,61 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) 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. */ + /* DW_AT_location specifies the register number or DW_AT_abstract_origin + specifies DW_TAG_formal_parameter. 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)) + loc = dwarf2_attr (child_die, DW_AT_location, cu); + origin = dwarf2_attr (child_die, DW_AT_abstract_origin, cu); + if (loc == NULL && origin != NULL && is_ref_attr (origin)) + { + sect_offset offset; + + parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET; + offset = dwarf2_get_ref_die_offset (origin); + if (!offset_in_cu_p (&cu->header, offset)) + { + /* As DW_OP_GNU_parameter_ref uses CU-relative offset this + binding can be done only inside one CU. Such referenced DIE + therefore cannot be even moved to DW_TAG_partial_unit. */ + complaint (&symfile_complaints, + _("DW_AT_abstract_origin offset is not in CU for " + "DW_TAG_GNU_call_site child DIE 0x%x " + "[in module %s]"), + child_die->offset.sect_off, objfile->name); + continue; + } + parameter->u.param_offset.cu_off = (offset.sect_off + - cu->header.offset.sect_off); + } + else if (loc == NULL || origin != NULL || !attr_form_is_block (loc)) { 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, cu->objfile->name); + 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)) + else { - 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, cu->objfile->name); - continue; + parameter->u.dwarf_reg = dwarf_block_to_dwarf_reg + (DW_BLOCK (loc)->data, &DW_BLOCK (loc)->data[DW_BLOCK (loc)->size]); + if (parameter->u.dwarf_reg != -1) + parameter->kind = CALL_SITE_PARAMETER_DWARF_REG; + else if (dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (loc)->data, + &DW_BLOCK (loc)->data[DW_BLOCK (loc)->size], + ¶meter->u.fb_offset)) + parameter->kind = CALL_SITE_PARAMETER_FB_OFFSET; + else + { + complaint (&symfile_complaints, + _("Only single DW_OP_reg or DW_OP_fbreg is supported " + "for DW_FORM_block* DW_AT_location is supported 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); @@ -6480,7 +9930,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) 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, cu->objfile->name); + child_die->offset.sect_off, objfile->name); continue; } parameter->value = DW_BLOCK (attr)->data; @@ -6498,7 +9948,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) 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, cu->objfile->name); + child_die->offset.sect_off, objfile->name); else { parameter->data_value = DW_BLOCK (attr)->data; @@ -6613,6 +10063,17 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return, range_beginning += base; range_end += base; + /* A not-uncommon case of bad debug info. + Don't pollute the addrmap with bad data. */ + if (range_beginning + baseaddr == 0 + && !dwarf2_per_objfile->has_section_at_zero) + { + complaint (&symfile_complaints, + _(".debug_ranges entry has start address of zero" + " [in module %s]"), objfile->name); + continue; + } + if (ranges_pst != NULL) addrmap_set_empty (objfile->psymtabs_addrmap, range_beginning + baseaddr, @@ -6653,23 +10114,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; @@ -6682,9 +10151,18 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc, attr = dwarf2_attr (die, DW_AT_ranges, cu); if (attr != NULL) { + /* DW_AT_ranges_base does not apply to DIEs from the DWO skeleton. + We take advantage of the fact that DW_AT_ranges does not appear + in DW_TAG_compile_unit of DWO files. */ + int need_ranges_base = die->tag != DW_TAG_compile_unit; + unsigned int ranges_offset = (DW_UNSND (attr) + + (need_ranges_base + ? cu->ranges_base + : 0)); + /* Value of the DW_AT_ranges attribute is the offset in the .debug_ranges section. */ - if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, pst)) + if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst)) return 0; /* Found discontinuous range of addresses. */ ret = -1; @@ -6810,21 +10288,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); } @@ -6833,11 +10318,16 @@ 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; + /* DW_AT_ranges_base does not apply to DIEs from the DWO skeleton. + We take advantage of the fact that DW_AT_ranges does not appear + in DW_TAG_compile_unit of DWO files. */ + int need_ranges_base = die->tag != DW_TAG_compile_unit; /* The value of the DW_AT_ranges attribute is the offset of the address range list in the .debug_ranges section. */ - unsigned long offset = DW_UNSND (attr); + unsigned long offset = (DW_UNSND (attr) + + (need_ranges_base ? cu->ranges_base : 0)); gdb_byte *buffer = dwarf2_per_objfile->ranges.buffer + offset; /* For some target architectures, but not others, the @@ -6911,20 +10401,30 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block, if (start == end) continue; - record_block_range (block, - baseaddr + base + start, - baseaddr + base + end - 1); + start += base + baseaddr; + end += base + baseaddr; + + /* A not-uncommon case of bad debug info. + Don't pollute the addrmap with bad data. */ + if (start == 0 && !dwarf2_per_objfile->has_section_at_zero) + { + complaint (&symfile_complaints, + _(".debug_ranges entry has start address of zero" + " [in module %s]"), objfile->name); + continue; + } + + record_block_range (block, start, end - 1); } } } } -/* Check for GCC PR debug/45124 fix which is not present in any G++ version up - to 4.5.any while it is present already in G++ 4.6.0 - the PR has been fixed - during 4.6.0 experimental. */ +/* Check whether the producer field indicates either of GCC < 4.6, or the + Intel C/C++ compiler, and cache the result in CU. */ -static int -producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu) +static void +check_producer (struct dwarf2_cu *cu) { const char *cs; int major, minor, release; @@ -6939,30 +10439,46 @@ producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu) for their space efficiency GDB cannot workaround gcc-4.5.x -gdwarf-4 combination. gcc-4.5.x -gdwarf-4 binaries have DW_AT_accessibility interpreted incorrectly by GDB now - GCC PR debug/48229. */ - - return 0; } - - /* Skip any identifier after "GNU " - such as "C++" or "Java". */ - - if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0) + else if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) == 0) { - /* For non-GCC compilers expect their behavior is DWARF version - compliant. */ + /* Skip any identifier after "GNU " - such as "C++" or "Java". */ - 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 + { + cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6); + cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3); + } } - cs = &cu->producer[strlen ("GNU ")]; - while (*cs && !isdigit (*cs)) - cs++; - if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3) + else if (strncmp (cu->producer, "Intel(R) C", strlen ("Intel(R) C")) == 0) + cu->producer_is_icc = 1; + else { - /* Not recognized as GCC. */ - - return 0; + /* For other non-GCC compilers, expect their behavior is DWARF version + compliant. */ } - return major < 4 || (major == 4 && minor < 6); + cu->checked_producer = 1; +} + +/* Check for GCC PR debug/45124 fix which is not present in any G++ version up + to 4.5.any while it is present already in G++ 4.6.0 - the PR has been fixed + during 4.6.0 experimental. */ + +static int +producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu) +{ + if (!cu->checked_producer) + check_producer (cu); + + return cu->producer_is_gxx_lt_4_6; } /* Return the default accessibility type if it is not overriden by @@ -7040,7 +10556,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, struct nextfield *new_field; struct attribute *attr; struct field *fp; - char *fieldname = ""; + const char *fieldname = ""; /* Allocate a new field list entry and link it in. */ new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield)); @@ -7110,7 +10626,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 { @@ -7139,8 +10655,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))); } } @@ -7349,6 +10867,34 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type, } } +/* Return true if this member function is a constructor, false + otherwise. */ + +static int +dwarf2_is_constructor (struct die_info *die, struct dwarf2_cu *cu) +{ + const char *fieldname; + const char *typename; + int len; + + if (die->parent == NULL) + return 0; + + if (die->parent->tag != DW_TAG_structure_type + && die->parent->tag != DW_TAG_union_type + && die->parent->tag != DW_TAG_class_type) + return 0; + + fieldname = dwarf2_name (die, cu); + typename = dwarf2_name (die->parent, cu); + if (fieldname == NULL || typename == NULL) + return 0; + + len = strlen (fieldname); + return (strncmp (fieldname, typename, len) == 0 + && (typename[len] == '\0' || typename[len] == '<')); +} + /* Add a member function to the proper fieldlist. */ static void @@ -7360,7 +10906,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, struct fnfieldlist *flp; int i; struct fn_field *fnp; - char *fieldname; + const char *fieldname; struct nextfnfield *new_fnfield; struct type *this_type; enum dwarf_access_attribute accessibility; @@ -7480,6 +11026,8 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, if (attr && DW_UNSND (attr) != 0) fnp->is_artificial = 1; + fnp->is_constructor = dwarf2_is_constructor (die, cu); + /* Get index in virtual function table if it is a virtual member function. For older versions of GCC, this is an offset in the appropriate virtual table, as specified by DW_AT_containing_type. @@ -7540,7 +11088,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; } @@ -7554,7 +11102,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) @@ -7576,12 +11123,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 @@ -7647,6 +11191,18 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile) smash_to_methodptr_type (type, new_type); } +/* Return non-zero if the CU's PRODUCER string matches the Intel C/C++ compiler + (icc). */ + +static int +producer_is_icc (struct dwarf2_cu *cu) +{ + if (!cu->checked_producer) + check_producer (cu); + + return cu->producer_is_icc; +} + /* Called when we find the DIE that starts a structure or union scope (definition) to create a type for the structure or union. Fill in the type's name and general properties; the members will not be @@ -7670,12 +11226,12 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) struct objfile *objfile = cu->objfile; struct type *type; struct attribute *attr; - char *name; + const char *name; /* If the definition of this type lives in .debug_types, read that type. Don't follow DW_AT_specification though, that will take us back up the chain and we want to go down. */ - attr = dwarf2_attr_no_follow (die, DW_AT_signature, cu); + attr = dwarf2_attr_no_follow (die, DW_AT_signature); if (attr) { struct dwarf2_cu *type_cu = cu; @@ -7701,7 +11257,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) if (cu->language == language_cplus || cu->language == language_java) { - char *full_name = (char *) dwarf2_full_name (name, die, cu); + const char *full_name = dwarf2_full_name (name, die, cu); /* dwarf2_full_name might have already finished building the DIE's type. If so, there is no need to continue. */ @@ -7717,7 +11273,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) { /* The name is already allocated along with this objfile, so we don't need to duplicate it for the type. */ - TYPE_TAG_NAME (type) = (char *) name; + TYPE_TAG_NAME (type) = name; if (die->tag == DW_TAG_class_type) TYPE_NAME (type) = TYPE_TAG_NAME (type); } @@ -7749,7 +11305,14 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) TYPE_LENGTH (type) = 0; } - TYPE_STUB_SUPPORTED (type) = 1; + if (producer_is_icc (cu)) + { + /* ICC does not output the required DW_AT_declaration + on incomplete types, but gives them a size of zero. */ + } + else + TYPE_STUB_SUPPORTED (type) = 1; + if (die_is_declaration (die, cu)) TYPE_STUB (type) = 1; else if (attr == NULL && die->child == NULL @@ -7873,7 +11436,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)) { @@ -7948,7 +11511,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 @@ -7995,7 +11558,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) /* If the definition of this type lives in .debug_types, read that type. Don't follow DW_AT_specification though, that will take us back up the chain and we want to go down. */ - attr = dwarf2_attr_no_follow (die, DW_AT_signature, cu); + attr = dwarf2_attr_no_follow (die, DW_AT_signature); if (attr) { struct dwarf2_cu *type_cu = cu; @@ -8013,7 +11576,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu) TYPE_CODE (type) = TYPE_CODE_ENUM; name = dwarf2_full_name (NULL, die, cu); if (name != NULL) - TYPE_TAG_NAME (type) = (char *) name; + TYPE_TAG_NAME (type) = name; attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) @@ -8058,7 +11621,9 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) struct field *fields = NULL; int num_fields = 0; int unsigned_enum = 1; - char *name; + const char *name; + int flag_enum = 1; + ULONGEST mask = 0; child_die = die->child; while (child_die && child_die->tag) @@ -8074,7 +11639,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) { @@ -8086,7 +11658,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++; @@ -8107,6 +11679,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 @@ -8117,16 +11691,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_types_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_types_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; } @@ -8148,7 +11723,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) struct attribute *attr; int ndim = 0; struct cleanup *back_to; - char *name; + const char *name; element_type = die_type (die, cu); @@ -8307,15 +11882,89 @@ read_set_type (struct die_info *die, struct dwarf2_cu *cu) return set_die_type (die, set_type, cu); } -/* First cut: install each common block member as a global variable. */ +/* A helper for read_common_block that creates a locexpr baton. + SYM is the symbol which we are marking as computed. + COMMON_DIE is the DIE for the common block. + COMMON_LOC is the location expression attribute for the common + block itself. + MEMBER_LOC is the location expression attribute for the particular + member of the common block that we are processing. + CU is the CU from which the above come. */ + +static void +mark_common_block_symbol_computed (struct symbol *sym, + struct die_info *common_die, + struct attribute *common_loc, + struct attribute *member_loc, + struct dwarf2_cu *cu) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwarf2_locexpr_baton *baton; + gdb_byte *ptr; + unsigned int cu_off; + enum bfd_endian byte_order = gdbarch_byte_order (get_objfile_arch (objfile)); + LONGEST offset = 0; + + gdb_assert (common_loc && member_loc); + gdb_assert (attr_form_is_block (common_loc)); + gdb_assert (attr_form_is_block (member_loc) + || attr_form_is_constant (member_loc)); + + baton = obstack_alloc (&objfile->objfile_obstack, + sizeof (struct dwarf2_locexpr_baton)); + baton->per_cu = cu->per_cu; + gdb_assert (baton->per_cu); + + baton->size = 5 /* DW_OP_call4 */ + 1 /* DW_OP_plus */; + + if (attr_form_is_constant (member_loc)) + { + offset = dwarf2_get_attr_constant_value (member_loc, 0); + baton->size += 1 /* DW_OP_addr */ + cu->header.addr_size; + } + else + baton->size += DW_BLOCK (member_loc)->size; + + ptr = obstack_alloc (&objfile->objfile_obstack, baton->size); + baton->data = ptr; + + *ptr++ = DW_OP_call4; + cu_off = common_die->offset.sect_off - cu->per_cu->offset.sect_off; + store_unsigned_integer (ptr, 4, byte_order, cu_off); + ptr += 4; + + if (attr_form_is_constant (member_loc)) + { + *ptr++ = DW_OP_addr; + store_unsigned_integer (ptr, cu->header.addr_size, byte_order, offset); + ptr += cu->header.addr_size; + } + else + { + /* We have to copy the data here, because DW_OP_call4 will only + use a DW_AT_location attribute. */ + memcpy (ptr, DW_BLOCK (member_loc)->data, DW_BLOCK (member_loc)->size); + ptr += DW_BLOCK (member_loc)->size; + } + + *ptr++ = DW_OP_plus; + gdb_assert (ptr - baton->data == baton->size); + + SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs; + SYMBOL_LOCATION_BATON (sym) = baton; + SYMBOL_CLASS (sym) = LOC_COMPUTED; +} + +/* Create appropriate locally-scoped variables for all the + DW_TAG_common_block entries. Also create a struct common_block + listing all such variables for `info common'. COMMON_BLOCK_DOMAIN + is used to sepate the common blocks name namespace from regular + variable names. */ static void read_common_block (struct die_info *die, struct dwarf2_cu *cu) { - struct die_info *child_die; struct attribute *attr; - struct symbol *sym; - CORE_ADDR base = (CORE_ADDR) 0; attr = dwarf2_attr (die, DW_AT_location, cu); if (attr) @@ -8323,34 +11972,84 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu) /* Support the .debug_loc offsets. */ if (attr_form_is_block (attr)) { - base = decode_locdesc (DW_BLOCK (attr), cu); + /* Ok. */ } else if (attr_form_is_section_offset (attr)) { dwarf2_complex_location_expr_complaint (); + attr = NULL; } else { dwarf2_invalid_attrib_class_complaint ("DW_AT_location", "common block member"); + attr = NULL; } } + if (die->child != NULL) { - child_die = die->child; - while (child_die && child_die->tag) - { - LONGEST offset; + struct objfile *objfile = cu->objfile; + struct die_info *child_die; + size_t n_entries = 0, size; + struct common_block *common_block; + struct symbol *sym; + + for (child_die = die->child; + child_die && child_die->tag; + child_die = sibling_die (child_die)) + ++n_entries; + size = (sizeof (struct common_block) + + (n_entries - 1) * sizeof (struct symbol *)); + common_block = obstack_alloc (&objfile->objfile_obstack, size); + memset (common_block->contents, 0, n_entries * sizeof (struct symbol *)); + common_block->n_entries = 0; + + for (child_die = die->child; + child_die && child_die->tag; + child_die = sibling_die (child_die)) + { + /* Create the symbol in the DW_TAG_common_block block in the current + symbol scope. */ sym = new_symbol (child_die, NULL, cu); - if (sym != NULL - && handle_data_member_location (child_die, cu, &offset)) + if (sym != NULL) { - SYMBOL_VALUE_ADDRESS (sym) = base + offset; - add_symbol_to_list (sym, &global_symbols); + struct attribute *member_loc; + + common_block->contents[common_block->n_entries++] = sym; + + member_loc = dwarf2_attr (child_die, DW_AT_data_member_location, + cu); + if (member_loc) + { + /* GDB has handled this for a long time, but it is + not specified by DWARF. It seems to have been + emitted by gfortran at least as recently as: + http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23057. */ + complaint (&symfile_complaints, + _("Variable in common block has " + "DW_AT_data_member_location " + "- DIE at 0x%x [in module %s]"), + child_die->offset.sect_off, cu->objfile->name); + + if (attr_form_is_section_offset (member_loc)) + dwarf2_complex_location_expr_complaint (); + else if (attr_form_is_constant (member_loc) + || attr_form_is_block (member_loc)) + { + if (attr) + mark_common_block_symbol_computed (sym, die, attr, + member_loc, cu); + } + else + dwarf2_complex_location_expr_complaint (); + } } - child_die = sibling_die (child_die); } + + sym = new_symbol (die, objfile_type (objfile)->builtin_void, cu); + SYMBOL_VALUE_COMMON_BLOCK (sym) = common_block; } } @@ -8390,7 +12089,7 @@ read_namespace_type (struct die_info *die, struct dwarf2_cu *cu) /* Create the type. */ type = init_type (TYPE_CODE_NAMESPACE, 0, 0, NULL, objfile); - TYPE_NAME (type) = (char *) name; + TYPE_NAME (type) = name; TYPE_TAG_NAME (type) = TYPE_NAME (type); return set_die_type (die, type, cu); @@ -8421,7 +12120,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu) const char *previous_prefix = determine_prefix (die, cu); cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL, - NULL, NULL, &objfile->objfile_obstack); + NULL, NULL, 0, &objfile->objfile_obstack); } } @@ -8445,14 +12144,14 @@ static struct type * read_module_type (struct die_info *die, struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; - char *module_name; + const char *module_name; struct type *type; module_name = dwarf2_name (die, 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. */ @@ -8590,6 +12289,15 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu) if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_METHOD) type = lookup_methodptr_type (to_type); + else if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_FUNC) + { + struct type *new_type = alloc_type (cu->objfile); + + smash_to_method_type (new_type, domain, TYPE_TARGET_TYPE (to_type), + TYPE_FIELDS (to_type), TYPE_NFIELDS (to_type), + TYPE_VARARGS (to_type)); + type = lookup_methodptr_type (new_type); + } else type = lookup_memberptr_type (to_type, domain); @@ -8681,6 +12389,24 @@ read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu) return set_die_type (die, cv_type, cu); } +/* Handle DW_TAG_restrict_type. */ + +static struct type * +read_tag_restrict_type (struct die_info *die, struct dwarf2_cu *cu) +{ + struct type *base_type, *cv_type; + + base_type = die_type (die, cu); + + /* The die_type call above may have already set the type for this DIE. */ + cv_type = get_die_type (die, cu); + if (cv_type) + return cv_type; + + cv_type = make_restrict_type (base_type); + return set_die_type (die, cv_type, cu); +} + /* Extract all information from a DW_TAG_string_type DIE and add to the user defined type vector. It isn't really a user defined type, but it behaves like one, with other DIE's using an AT_user_def_type @@ -8735,6 +12461,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; @@ -8780,7 +12507,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; @@ -8890,14 +12617,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; + TYPE_NAME (this_type) = 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; } @@ -8911,7 +12650,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) struct type *type; struct attribute *attr; int encoding = 0, size = 0; - char *name; + const char *name; enum type_code code = TYPE_CODE_INT; int type_flags = 0; struct type *target_type = NULL; @@ -9003,27 +12742,55 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) static struct type * read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) { - struct type *base_type; + struct type *base_type, *orig_base_type; struct type *range_type; struct attribute *attr; - LONGEST low = 0; - LONGEST high = -1; - char *name; + LONGEST low, high; + int low_default_is_valid; + const char *name; LONGEST negative_mask; - base_type = die_type (die, cu); - /* Preserve BASE_TYPE's original type, just set its LENGTH. */ - check_typedef (base_type); + orig_base_type = die_type (die, cu); + /* If ORIG_BASE_TYPE is a typedef, it will not be TYPE_UNSIGNED, + whereas the real type might be. So, we use ORIG_BASE_TYPE when + creating the range type, but we use the result of check_typedef + when examining properties of the type. */ + base_type = check_typedef (orig_base_type); /* The die_type call above may have already set the type for this DIE. */ range_type = get_die_type (die, 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 @@ -9031,7 +12798,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) @@ -9114,131 +12885,45 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) if (!TYPE_UNSIGNED (base_type) && (high & negative_mask)) high |= negative_mask; - range_type = create_range_type (NULL, base_type, low, high); + range_type = create_range_type (NULL, orig_base_type, low, high); /* Mark arrays with dynamic length at least as an array of unspecified length. GDB could check the boundary but before it gets implemented at least allow accessing the array elements. */ if (attr && attr_form_is_block (attr)) - TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1; - - /* Ada expects an empty array on no boundary attributes. */ - if (attr == NULL && cu->language != language_ada) - TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1; - - name = dwarf2_name (die, cu); - if (name) - TYPE_NAME (range_type) = name; - - attr = dwarf2_attr (die, DW_AT_byte_size, cu); - if (attr) - TYPE_LENGTH (range_type) = DW_UNSND (attr); - - set_die_type (die, range_type, cu); - - /* set_die_type should be already done. */ - set_descriptive_type (range_type, die, cu); - - return range_type; -} - -static struct type * -read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu) -{ - struct type *type; - - /* For now, we only support the C meaning of an unspecified type: void. */ - - type = init_type (TYPE_CODE_VOID, 0, 0, NULL, cu->objfile); - TYPE_NAME (type) = dwarf2_name (die, 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; + TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1; - if (cu->dwarf2_abbrevs == NULL) - { - dwarf2_read_abbrevs (cu->objfile->obfd, cu); - back_to = make_cleanup (dwarf2_free_abbrev_table, cu); - read_abbrevs = 1; - } + /* Ada expects an empty array on no boundary attributes. */ + if (attr == NULL && cu->language != language_ada) + TYPE_HIGH_BOUND_UNDEFINED (range_type) = 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); + name = dwarf2_name (die, cu); + if (name) + TYPE_NAME (range_type) = name; - init_cu_die_reader (&reader_specs, cu); + attr = dwarf2_attr (die, DW_AT_byte_size, cu); + if (attr) + TYPE_LENGTH (range_type) = DW_UNSND (attr); - die = read_die_and_children (&reader_specs, info_ptr, &info_ptr, NULL); + set_die_type (die, range_type, cu); - if (read_abbrevs) - do_cleanups (back_to); + /* set_die_type should be already done. */ + set_descriptive_type (range_type, die, cu); - return die; + return range_type; } -/* 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) +static struct type * +read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu) { - struct die_info *result = read_die_and_children_1 (reader, info_ptr, - new_info_ptr, parent); + struct type *type; - if (dwarf2_die_debug) - { - fprintf_unfiltered (gdb_stdlog, - "\nRead die from %s of %s:\n", - (reader->cu->per_cu->debug_types_section - ? ".debug_types" - : ".debug_info"), - reader->abfd->filename); - dump_die (result, dwarf2_die_debug); - } + /* For now, we only support the C meaning of an unspecified type: void. */ - return result; + type = init_type (TYPE_CODE_VOID, 0, 0, NULL, cu->objfile); + TYPE_NAME (type) = dwarf2_name (die, cu); + + return set_die_type (die, type, cu); } /* Read a single die and all its descendents. Set the die's sibling @@ -9248,10 +12933,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; @@ -9297,7 +12982,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) { @@ -9314,23 +12999,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) @@ -9340,56 +13029,127 @@ read_full_die (const struct die_reader_specs *reader, return info_ptr; } - abbrev = dwarf2_lookup_abbrev (abbrev_number, cu); + abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number); if (!abbrev) error (_("Dwarf Error: could not find abbrev number %d [in module %s]"), abbrev_number, bfd_get_filename (abfd)); - die = dwarf_alloc_die (cu, abbrev->num_attrs); + die = 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; } -/* In DWARF version 2, the description of the debugging information is +/* 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); +} + +/* Abbreviation tables. + + 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 - in a hash table. This function also sets flags in CU describing - the data found in the abbrev table. */ + in a hash table. */ + +/* Allocate space for a struct abbrev_info object in ABBREV_TABLE. */ + +static struct abbrev_info * +abbrev_table_alloc_abbrev (struct abbrev_table *abbrev_table) +{ + struct abbrev_info *abbrev; + + abbrev = (struct abbrev_info *) + obstack_alloc (&abbrev_table->abbrev_obstack, sizeof (struct abbrev_info)); + memset (abbrev, 0, sizeof (struct abbrev_info)); + return abbrev; +} + +/* Add an abbreviation to the table. */ static void -dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) +abbrev_table_add_abbrev (struct abbrev_table *abbrev_table, + unsigned int abbrev_number, + struct abbrev_info *abbrev) { - struct comp_unit_head *cu_header = &cu->header; + unsigned int hash_number; + + hash_number = abbrev_number % ABBREV_HASH_SIZE; + abbrev->next = abbrev_table->abbrevs[hash_number]; + abbrev_table->abbrevs[hash_number] = abbrev; +} + +/* Look up an abbrev in the table. + Returns NULL if the abbrev is not found. */ + +static struct abbrev_info * +abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table, + unsigned int abbrev_number) +{ + unsigned int hash_number; + struct abbrev_info *abbrev; + + hash_number = abbrev_number % ABBREV_HASH_SIZE; + abbrev = abbrev_table->abbrevs[hash_number]; + + while (abbrev) + { + if (abbrev->number == abbrev_number) + return abbrev; + abbrev = abbrev->next; + } + return NULL; +} + +/* Read in an abbrev table. */ + +static struct abbrev_table * +abbrev_table_read_table (struct dwarf2_section_info *section, + sect_offset offset) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + bfd *abfd = section->asection->owner; + struct abbrev_table *abbrev_table; gdb_byte *abbrev_ptr; struct abbrev_info *cur_abbrev; unsigned int abbrev_number, bytes_read, abbrev_name; - unsigned int abbrev_form, hash_number; + unsigned int abbrev_form; struct attr_abbrev *cur_attrs; unsigned int allocated_attrs; - /* Initialize dwarf2 abbrevs. */ - obstack_init (&cu->abbrev_obstack); - cu->dwarf2_abbrevs = obstack_alloc (&cu->abbrev_obstack, - (ABBREV_HASH_SIZE - * sizeof (struct abbrev_info *))); - 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; + abbrev_table = XMALLOC (struct abbrev_table); + abbrev_table->offset = offset; + obstack_init (&abbrev_table->abbrev_obstack); + abbrev_table->abbrevs = obstack_alloc (&abbrev_table->abbrev_obstack, + (ABBREV_HASH_SIZE + * sizeof (struct abbrev_info *))); + memset (abbrev_table->abbrevs, 0, + ABBREV_HASH_SIZE * sizeof (struct abbrev_info *)); + + dwarf2_read_section (objfile, section); + abbrev_ptr = section->buffer + offset.sect_off; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; @@ -9399,7 +13159,7 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) /* Loop until we reach an abbrev number of 0. */ while (abbrev_number) { - cur_abbrev = dwarf_alloc_abbrev (cu); + cur_abbrev = abbrev_table_alloc_abbrev (abbrev_table); /* read in abbrev header */ cur_abbrev->number = abbrev_number; @@ -9408,9 +13168,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; @@ -9426,16 +13183,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); @@ -9444,15 +13191,13 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu) abbrev_ptr += bytes_read; } - cur_abbrev->attrs = obstack_alloc (&cu->abbrev_obstack, + cur_abbrev->attrs = obstack_alloc (&abbrev_table->abbrev_obstack, (cur_abbrev->num_attrs * sizeof (struct attr_abbrev))); memcpy (cur_abbrev->attrs, cur_attrs, cur_abbrev->num_attrs * sizeof (struct attr_abbrev)); - hash_number = abbrev_number % ABBREV_HASH_SIZE; - cur_abbrev->next = cu->dwarf2_abbrevs[hash_number]; - cu->dwarf2_abbrevs[hash_number] = cur_abbrev; + abbrev_table_add_abbrev (abbrev_table, abbrev_number, cur_abbrev); /* Get next abbreviation. Under Irix6 the abbreviations for a compilation unit are not @@ -9461,50 +13206,65 @@ 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 - section->buffer) >= section->size) break; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; - if (dwarf2_lookup_abbrev (abbrev_number, cu) != NULL) + if (abbrev_table_lookup_abbrev (abbrev_table, abbrev_number) != NULL) break; } xfree (cur_attrs); + return abbrev_table; } -/* Release the memory used by the abbrev table for a compilation unit. */ +/* Free the resources held by ABBREV_TABLE. */ static void -dwarf2_free_abbrev_table (void *ptr_to_cu) +abbrev_table_free (struct abbrev_table *abbrev_table) { - struct dwarf2_cu *cu = ptr_to_cu; - - obstack_free (&cu->abbrev_obstack, NULL); - cu->dwarf2_abbrevs = NULL; + obstack_free (&abbrev_table->abbrev_obstack, NULL); + xfree (abbrev_table); } -/* Lookup an abbrev_info structure in the abbrev hash table. */ +/* Same as abbrev_table_free but as a cleanup. + We pass in a pointer to the pointer to the table so that we can + set the pointer to NULL when we're done. It also simplifies + build_type_unit_groups. */ -static struct abbrev_info * -dwarf2_lookup_abbrev (unsigned int number, struct dwarf2_cu *cu) +static void +abbrev_table_free_cleanup (void *table_ptr) { - unsigned int hash_number; - struct abbrev_info *abbrev; + struct abbrev_table **abbrev_table_ptr = table_ptr; + + if (*abbrev_table_ptr != NULL) + abbrev_table_free (*abbrev_table_ptr); + *abbrev_table_ptr = NULL; +} - hash_number = number % ABBREV_HASH_SIZE; - abbrev = cu->dwarf2_abbrevs[hash_number]; +/* Read the abbrev table for CU from ABBREV_SECTION. */ - while (abbrev) - { - if (abbrev->number == number) - return abbrev; - else - abbrev = abbrev->next; - } - return NULL; +static void +dwarf2_read_abbrevs (struct dwarf2_cu *cu, + struct dwarf2_section_info *abbrev_section) +{ + cu->abbrev_table = + abbrev_table_read_table (abbrev_section, cu->header.abbrev_offset); } +/* Release the memory used by the abbrev table for a compilation unit. */ + +static void +dwarf2_free_abbrev_table (void *ptr_to_cu) +{ + struct dwarf2_cu *cu = ptr_to_cu; + + abbrev_table_free (cu->abbrev_table); + /* Set this to NULL so that we SEGV if we try to read it later, + and also because free_comp_unit verifies this is NULL. */ + cu->abbrev_table = NULL; +} + /* Returns nonzero if TAG represents a type that we might generate a partial symbol for. */ @@ -9540,21 +13300,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 @@ -9604,20 +13366,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; } @@ -9634,15 +13395,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 @@ -9670,9 +13432,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; } @@ -9688,7 +13450,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 @@ -9708,11 +13470,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; } @@ -9762,7 +13524,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; } @@ -9805,7 +13567,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. */ } @@ -9814,20 +13576,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; @@ -9839,7 +13604,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. */ @@ -9849,6 +13614,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. */ @@ -9861,7 +13627,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; @@ -9880,13 +13646,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)) { @@ -9912,6 +13685,8 @@ read_partial_die (struct partial_die_info *part_die, case DW_AT_extension: part_die->has_specification = 1; part_die->spec_offset = dwarf2_get_ref_die_offset (&attr); + part_die->spec_is_dwz = (attr.form == DW_FORM_GNU_ref_alt + || cu->per_cu->is_dwz); break; case DW_AT_sibling: /* Ignore absolute siblings, they might point outside of @@ -9920,7 +13695,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; @@ -9950,11 +13725,29 @@ 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); + part_die->is_dwz = (attr.form == DW_FORM_GNU_ref_alt + || cu->per_cu->is_dwz); + } + 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 @@ -9967,25 +13760,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; @@ -9997,13 +13790,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; } @@ -10014,75 +13808,65 @@ 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, int offset_in_dwz, 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_types_section) + if (offset_in_dwz == cu->per_cu->is_dwz + && offset_in_cu_p (&cu->header, offset)) { pd = find_partial_die_in_comp_unit (offset, cu); if (pd != NULL) return pd; - goto not_found; + /* We missed recording what we needed. + Load all dies and try again. */ + per_cu = cu->per_cu; } - - if (offset_in_cu_p (&cu->header, offset)) + else { - pd = find_partial_die_in_comp_unit (offset, cu); - if (pd != NULL) - return pd; - } + /* 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, offset_in_dwz, + 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; } @@ -10109,7 +13893,8 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi, real_pdi = struct_pdi; while (real_pdi->has_specification) - real_pdi = find_partial_die (real_pdi->spec_offset, cu); + real_pdi = find_partial_die (real_pdi->spec_offset, + real_pdi->spec_is_dwz, cu); if (real_pdi->die_parent != NULL) return; @@ -10127,9 +13912,9 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi, if (actual_class_name != NULL) { struct_pdi->name - = obsavestring (actual_class_name, - strlen (actual_class_name), - &cu->objfile->objfile_obstack); + = obstack_copy0 (&cu->objfile->objfile_obstack, + actual_class_name, + strlen (actual_class_name)); xfree (actual_class_name); } break; @@ -10157,7 +13942,8 @@ fixup_partial_die (struct partial_die_info *part_die, { struct partial_die_info *spec_die; - spec_die = find_partial_die (part_die->spec_offset, cu); + spec_die = find_partial_die (part_die->spec_offset, + part_die->spec_is_dwz, cu); fixup_partial_die (spec_die, cu); @@ -10178,9 +13964,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 @@ -10214,8 +13998,8 @@ fixup_partial_die (struct partial_die_info *part_die, else base = demangled; - part_die->name = obsavestring (base, strlen (base), - &cu->objfile->objfile_obstack); + part_die->name = obstack_copy0 (&cu->objfile->objfile_obstack, + base, strlen (base)); xfree (demangled); } } @@ -10226,10 +14010,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; @@ -10239,10 +14025,14 @@ 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_GNU_ref_alt: + DW_UNSND (attr) = read_offset (abfd, info_ptr, &cu->header, &bytes_read); info_ptr += bytes_read; break; case DW_FORM_addr: @@ -10287,10 +14077,25 @@ read_attribute_value (struct attribute *attr, unsigned form, info_ptr += bytes_read; break; case DW_FORM_strp: - DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header, - &bytes_read); - DW_STRING_IS_CANONICAL (attr) = 0; - info_ptr += bytes_read; + if (!cu->per_cu->is_dwz) + { + DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header, + &bytes_read); + DW_STRING_IS_CANONICAL (attr) = 0; + info_ptr += bytes_read; + break; + } + /* FALLTHROUGH */ + case DW_FORM_GNU_strp_alt: + { + struct dwz_file *dwz = dwarf2_get_dwz_file (); + LONGEST str_offset = read_offset (abfd, info_ptr, cu_header, + &bytes_read); + + DW_STRING (attr) = read_indirect_string_from_dwz (dwz, str_offset); + DW_STRING_IS_CANONICAL (attr) = 0; + info_ptr += bytes_read; + } break; case DW_FORM_exprloc: case DW_FORM_block: @@ -10329,19 +14134,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: @@ -10349,18 +14158,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]"), @@ -10368,6 +14207,10 @@ read_attribute_value (struct attribute *attr, unsigned form, bfd_get_filename (abfd)); } + /* Super hack. */ + if (cu->per_cu->is_dwz && is_ref_attr (attr)) + attr->form = DW_FORM_GNU_ref_alt; + /* We have seen instances where the compiler tried to emit a byte size attribute of -1 which ended up being encoded as an unsigned 0xffffffff. Although 0xffffffff is technically a valid size value, @@ -10391,53 +14234,54 @@ 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. */ static unsigned int -read_1_byte (bfd *abfd, gdb_byte *buf) +read_1_byte (bfd *abfd, const gdb_byte *buf) { return bfd_get_8 (abfd, buf); } static int -read_1_signed_byte (bfd *abfd, gdb_byte *buf) +read_1_signed_byte (bfd *abfd, const gdb_byte *buf) { return bfd_get_signed_8 (abfd, buf); } static unsigned int -read_2_bytes (bfd *abfd, gdb_byte *buf) +read_2_bytes (bfd *abfd, const gdb_byte *buf) { return bfd_get_16 (abfd, buf); } static int -read_2_signed_bytes (bfd *abfd, gdb_byte *buf) +read_2_signed_bytes (bfd *abfd, const gdb_byte *buf) { return bfd_get_signed_16 (abfd, buf); } static unsigned int -read_4_bytes (bfd *abfd, gdb_byte *buf) +read_4_bytes (bfd *abfd, const gdb_byte *buf) { return bfd_get_32 (abfd, buf); } static int -read_4_signed_bytes (bfd *abfd, gdb_byte *buf) +read_4_signed_bytes (bfd *abfd, const gdb_byte *buf) { return bfd_get_signed_32 (abfd, buf); } static ULONGEST -read_8_bytes (bfd *abfd, gdb_byte *buf) +read_8_bytes (bfd *abfd, const gdb_byte *buf) { return bfd_get_64 (abfd, buf); } @@ -10663,6 +14507,30 @@ read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset) return (char *) (dwarf2_per_objfile->str.buffer + str_offset); } +/* Read a string at offset STR_OFFSET in the .debug_str section from + the .dwz file DWZ. Throw an error if the offset is too large. If + the string consists of a single NUL byte, return NULL; otherwise + return a pointer to the string. */ + +static char * +read_indirect_string_from_dwz (struct dwz_file *dwz, LONGEST str_offset) +{ + dwarf2_read_section (dwarf2_per_objfile->objfile, &dwz->str); + + if (dwz->str.buffer == NULL) + error (_("DW_FORM_GNU_strp_alt used without .debug_str " + "section [in module %s]"), + bfd_get_filename (dwz->dwz_bfd)); + if (str_offset >= dwz->str.size) + error (_("DW_FORM_GNU_strp_alt pointing outside of " + ".debug_str section [in module %s]"), + bfd_get_filename (dwz->dwz_bfd)); + gdb_assert (HOST_CHAR_BIT == 8); + if (dwz->str.buffer[str_offset] == '\0') + return NULL; + return (char *) (dwz->str.buffer + str_offset); +} + static char * read_indirect_string (bfd *abfd, gdb_byte *buf, const struct comp_unit_head *cu_header, @@ -10673,10 +14541,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; @@ -10690,7 +14558,7 @@ 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; @@ -10701,10 +14569,10 @@ read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr) return result; } -static long +static LONGEST read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr) { - long result; + LONGEST result; int i, shift, num_read; unsigned char byte; @@ -10717,7 +14585,7 @@ read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr) byte = bfd_get_8 (abfd, buf); buf++; num_read++; - result |= ((long)(byte & 127) << shift); + result |= ((LONGEST) (byte & 127) << shift); shift += 7; if ((byte & 128) == 0) { @@ -10725,24 +14593,190 @@ read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr) } } if ((shift < 8 * sizeof (result)) && (byte & 0x40)) - result |= -(((long)1) << shift); + result |= -(((LONGEST) 1) << shift); *bytes_read_ptr = num_read; return result; } -/* Return a pointer to just past the end of an LEB128 number in BUF. */ +/* 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. + For now we skip this optimization. */ + + if (cu != NULL) + { + addr_base = cu->addr_base; + addr_size = cu->header.addr_size; + } + else + { + struct dwarf2_read_addr_index_data aidata; + + /* Note: We can't use init_cutu_and_read_dies_simple here, + we need addr_base. */ + init_cutu_and_read_dies (per_cu, NULL, 0, 0, + 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); +} + +/* Given a DW_AT_str_index, fetch the string. */ + +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 the length of an LEB128 number in BUF. */ -static gdb_byte * -skip_leb128 (bfd *abfd, gdb_byte *buf) +static int +leb128_size (const gdb_byte *buf) { - int byte; + const gdb_byte *begin = buf; + gdb_byte byte; while (1) { - byte = bfd_get_8 (abfd, buf); - buf++; + byte = *buf++; if ((byte & 128) == 0) - return buf; + return buf - begin; } } @@ -10767,6 +14801,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; @@ -10800,22 +14837,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; @@ -10828,8 +14867,7 @@ dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu) back up the chain, and we want to go down. */ static struct attribute * -dwarf2_attr_no_follow (struct die_info *die, unsigned int name, - struct dwarf2_cu *cu) +dwarf2_attr_no_follow (struct die_info *die, unsigned int name) { unsigned int i; @@ -10967,17 +15005,40 @@ add_file_name (struct line_header *lh, fe->symtab = NULL; } +/* A convenience function to find the proper .debug_line section for a + CU. */ + +static struct dwarf2_section_info * +get_debug_line_section (struct dwarf2_cu *cu) +{ + struct dwarf2_section_info *section; + + /* 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 if (cu->per_cu->is_dwz) + { + struct dwz_file *dwz = dwarf2_get_dwz_file (); + + section = &dwz->line; + } + else + section = &dwarf2_per_objfile->line; + + return section; +} + /* 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; @@ -10985,17 +15046,27 @@ 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; - dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->line); - if (dwarf2_per_objfile->line.buffer == NULL) + section = get_debug_line_section (cu); + 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; @@ -11006,15 +15077,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; @@ -11086,8 +15156,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")); @@ -11096,58 +15165,14 @@ 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. COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown. If space for the result is malloc'd, it will be freed by a cleanup. - Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename. */ + Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename. + + The function creates dangling cleanup registration. */ static char * psymtab_include_file_name (const struct line_header *lh, int file_index, @@ -11321,8 +15346,7 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir, 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); } } @@ -11352,12 +15376,12 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir, GCd by the linker. Ignore it. PR gdb/12528 */ long line_offset - = line_ptr - dwarf2_per_objfile->line.buffer; + = line_ptr - get_debug_line_section (cu)->buffer; 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; } @@ -11420,8 +15444,7 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir, (*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); } } @@ -11601,7 +15624,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, if (current_subfile->symtab == NULL) current_subfile->symtab = allocate_symtab (current_subfile->name, - cu->objfile); + objfile); fe->symtab = current_subfile->symtab; } } @@ -11658,6 +15681,23 @@ dwarf2_start_subfile (char *filename, const char *dirname, xfree (fullname); } +/* Start a symtab for DWARF. + NAME, COMP_DIR, LOW_PC are passed to start_symtab. */ + +static void +dwarf2_start_symtab (struct dwarf2_cu *cu, + const char *name, const char *comp_dir, CORE_ADDR low_pc) +{ + start_symtab (name, comp_dir, low_pc); + record_debugformat ("DWARF 2"); + record_producer (cu->producer); + + /* We assume that we're processing GCC output. */ + processing_gcc_compilation = 2; + + cu->processing_has_namespace_info = 0; +} + static void var_decode_location (struct attribute *attr, struct symbol *sym, struct dwarf2_cu *cu) @@ -11685,17 +15725,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, @@ -11731,7 +15778,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, { struct objfile *objfile = cu->objfile; struct symbol *sym = NULL; - char *name; + const char *name; struct attribute *attr = NULL; struct attribute *attr2 = NULL; CORE_ADDR baseaddr; @@ -11763,7 +15810,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, if (cu->language == language_fortran && symbol_get_demangled_name (&(sym->ginfo)) == NULL) symbol_set_demangled_name (&(sym->ginfo), - (char *) dwarf2_full_name (name, die, cu), + dwarf2_full_name (name, die, cu), NULL); /* Default assumptions. @@ -11841,8 +15888,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; @@ -11885,6 +15931,13 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, { var_decode_location (attr, sym, cu); attr2 = dwarf2_attr (die, DW_AT_external, cu); + + /* Fortran explicitly imports any global symbols to the local + scope by DW_TAG_common_block. */ + if (cu->language == language_fortran && die->parent + && die->parent->tag == DW_TAG_common_block) + attr2 = NULL; + if (SYMBOL_CLASS (sym) == LOC_STATIC && SYMBOL_VALUE_ADDRESS (sym) == 0 && !dwarf2_per_objfile->has_section_at_zero) @@ -11927,8 +15980,19 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, the minimal symbol table whenever the variable is referenced. */ attr2 = dwarf2_attr (die, DW_AT_external, cu); - if (attr2 && (DW_UNSND (attr2) != 0) - && dwarf2_attr (die, DW_AT_type, cu) != NULL) + + /* Fortran explicitly imports any global symbols to the local + scope by DW_TAG_common_block. */ + if (cu->language == language_fortran && die->parent + && die->parent->tag == DW_TAG_common_block) + { + /* SYMBOL_CLASS doesn't matter here because + read_common_block is going to reset it. */ + if (!suppress_add) + list_to_add = cu->list_in_scope; + } + else if (attr2 && (DW_UNSND (attr2) != 0) + && dwarf2_attr (die, DW_AT_type, cu) != NULL) { /* A variable with DW_AT_external is never static, but it may be block-scoped. */ @@ -12049,6 +16113,11 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, SYMBOL_CLASS (sym) = LOC_TYPEDEF; list_to_add = &global_symbols; break; + case DW_TAG_common_block: + SYMBOL_CLASS (sym) = LOC_COMMON_BLOCK; + SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN; + add_symbol_to_list (sym, cu->list_in_scope); + break; default: /* Not a tag we recognize. Hopefully we aren't processing trash data, but since we must specifically ignore things @@ -12071,7 +16140,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, /* For the benefit of old versions of GCC, check for anonymous namespaces based on the demangled name. */ - if (!processing_has_namespace_info + if (!cu->processing_has_namespace_info && cu->language == language_cplus) cp_scan_for_anonymous_namespaces (sym, objfile); } @@ -12097,7 +16166,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) ? @@ -12131,7 +16200,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; @@ -12147,6 +16216,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; @@ -12174,6 +16244,8 @@ 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: + case DW_FORM_GNU_strp_alt: /* DW_STRING is already allocated on the objfile obstack, point directly to it. */ *bytes = (gdb_byte *) DW_STRING (attr); @@ -12238,7 +16310,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; @@ -12355,38 +16427,52 @@ 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)) + if (attr->form == DW_FORM_GNU_ref_alt) + { + struct dwarf2_per_cu_data *per_cu; + sect_offset offset = dwarf2_get_ref_die_offset (attr); + + per_cu = dwarf2_find_containing_comp_unit (offset, 1, cu->objfile); + this_type = get_die_type_at_offset (offset, per_cu); + } + else 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_types_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. */ @@ -12397,9 +16483,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. */ @@ -12410,14 +16499,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; @@ -12488,6 +16577,9 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu) case DW_TAG_volatile_type: this_type = read_tag_volatile_type (die, cu); break; + case DW_TAG_restrict_type: + this_type = read_tag_restrict_type (die, cu); + break; case DW_TAG_string_type: this_type = read_tag_string_type (die, cu); break; @@ -12562,7 +16654,7 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu) if (actual_name != NULL) { - char *die_name = dwarf2_name (die, cu); + const char *die_name = dwarf2_name (die, cu); if (die_name != NULL && strcmp (die_name, actual_name) != 0) @@ -12577,9 +16669,9 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu) && actual_name[actual_name_len - die_name_len - 1] == ':') name = - obsavestring (actual_name, - actual_name_len - die_name_len - 2, - &cu->objfile->objfile_obstack); + obstack_copy0 (&cu->objfile->objfile_obstack, + actual_name, + actual_name_len - die_name_len - 2); } } xfree (actual_name); @@ -12623,8 +16715,8 @@ anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu) 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 obstack_copy0 (&cu->objfile->objfile_obstack, + DW_STRING (attr), &base[-1] - DW_STRING (attr)); } /* Return the name of the namespace/class that DIE is defined within, @@ -12642,7 +16734,7 @@ anonymous_struct_prefix (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; @@ -12759,6 +16851,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) @@ -12841,8 +16934,8 @@ sibling_die (struct die_info *die) /* Get name of a die, return NULL if not found. */ -static char * -dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu, +static const char * +dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu, struct obstack *obstack) { if (name && cu->language == language_cplus) @@ -12852,8 +16945,7 @@ dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu, if (canon_name != NULL) { if (strcmp (canon_name, name) != 0) - name = obsavestring (canon_name, strlen (canon_name), - obstack); + name = obstack_copy0 (obstack, canon_name, strlen (canon_name)); xfree (canon_name); } } @@ -12863,7 +16955,7 @@ dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu, /* Get name of a die, return NULL if not found. */ -static char * +static const char * dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) { struct attribute *attr; @@ -12879,6 +16971,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: @@ -12912,7 +17005,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; @@ -12952,8 +17046,8 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) 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) = obstack_copy0 (&cu->objfile->objfile_obstack, + demangled, strlen (demangled)); DW_STRING_IS_CANONICAL (attr) = 1; xfree (demangled); @@ -13000,843 +17094,51 @@ dwarf2_extension (struct die_info *die, struct dwarf2_cu **ext_cu) /* Convert a DIE tag into its string name. */ -static char * +static const 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"; - case DW_TAG_GNU_call_site: - return "DW_TAG_GNU_call_site"; - default: - return "DW_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 char * +static const 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. */ + const char *name; + #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"; + 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 - 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_"; - } + + 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 char * +static const 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; - } + const char *name = get_DW_FORM_name (form); + + if (name == NULL) + return "DW_FORM_"; + + return name; } static char * @@ -13850,143 +17152,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) @@ -13995,13 +17170,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); @@ -14020,8 +17195,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; @@ -14029,18 +17204,28 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die) case DW_FORM_block4: case DW_FORM_block: case DW_FORM_block1: - fprintf_unfiltered (f, "block: size %d", - DW_BLOCK (&die->attrs[i])->size); + fprintf_unfiltered (f, "block: size %s", + pulongest (DW_BLOCK (&die->attrs[i])->size)); break; case DW_FORM_exprloc: - fprintf_unfiltered (f, "expression: size %u", - DW_BLOCK (&die->attrs[i])->size); + fprintf_unfiltered (f, "expression: size %s", + pulongest (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_GNU_ref_alt: + fprintf_unfiltered (f, "alt 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: @@ -14058,12 +17243,14 @@ 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: + case DW_FORM_GNU_strp_alt: fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)", DW_STRING (&die->attrs[i]) ? DW_STRING (&die->attrs[i]) : "", @@ -14147,11 +17334,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) { @@ -14163,22 +17354,29 @@ is_ref_attr (struct attribute *attr) case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: + case DW_FORM_GNU_ref_alt: return 1; default: return 0; } } -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 @@ -14196,53 +17394,12 @@ dwarf2_get_attr_constant_value (struct attribute *attr, int default_value) || attr->form == DW_FORM_data8) return DW_UNSND (attr); else - { - complaint (&symfile_complaints, - _("Attribute value is not a constant (%s)"), - dwarf_form_name (attr->form)); - return default_value; - } -} - -/* THIS_CU has a reference to PER_CU. If necessary, load the new compilation - unit and add it to our queue. - The result is non-zero if PER_CU was queued, otherwise the result is zero - meaning either PER_CU is already queued or it is already loaded. */ - -static int -maybe_queue_comp_unit (struct dwarf2_cu *this_cu, - struct dwarf2_per_cu_data *per_cu) -{ - /* We may arrive here during partial symbol reading, if we need full - DIEs to process an unusual case (e.g. template arguments). Do - not queue PER_CU, just tell our caller to load its DIEs. */ - if (dwarf2_per_objfile->reading_partial_symbols) - { - if (per_cu->cu == NULL || per_cu->cu->dies == NULL) - return 1; - return 0; - } - - /* Mark the dependence relation so that we don't flush PER_CU - too early. */ - dwarf2_add_dependence (this_cu, per_cu); - - /* If it's already on the queue, we have nothing to do. */ - if (per_cu->queued) - return 0; - - /* If the compilation unit is already loaded, just mark it as - used. */ - if (per_cu->cu != NULL) - { - per_cu->cu->last_used = 0; - return 0; + { + complaint (&symfile_complaints, + _("Attribute value is not a constant (%s)"), + dwarf_form_name (attr->form)); + return default_value; } - - /* Add it to the queue. */ - queue_comp_unit (per_cu, this_cu->objfile); - - return 1; } /* Follow reference or signature attribute ATTR of SRC_DIE. @@ -14275,7 +17432,8 @@ 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, int offset_in_dwz, + struct dwarf2_cu **ref_cu) { struct die_info temp_die; struct dwarf2_cu *target_cu, *cu = *ref_cu; @@ -14284,7 +17442,7 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu) target_cu = cu; - if (cu->per_cu->debug_types_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 @@ -14292,15 +17450,17 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu) if (! offset_in_cu_p (&cu->header, offset)) return NULL; } - else if (! offset_in_cu_p (&cu->header, offset)) + else if (offset_in_dwz != cu->per_cu->is_dwz + || ! offset_in_cu_p (&cu->header, offset)) { struct dwarf2_per_cu_data *per_cu; - per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile); + per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz, + 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; } @@ -14308,12 +17468,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. @@ -14324,15 +17484,18 @@ 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; - die = follow_die_offset (offset, ref_cu); + die = follow_die_offset (offset, + (attr->form == DW_FORM_GNU_ref_alt + || cu->per_cu->is_dwz), + ref_cu); 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; } @@ -14342,10 +17505,10 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr, dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE. */ struct dwarf2_locexpr_baton -dwarf2_fetch_die_location_block (unsigned int offset, - struct dwarf2_per_cu_data *per_cu, - CORE_ADDR (*get_frame_pc) (void *baton), - void *baton) +dwarf2_fetch_die_loc_sect_off (sect_offset offset, + struct dwarf2_per_cu_data *per_cu, + CORE_ADDR (*get_frame_pc) (void *baton), + void *baton) { struct dwarf2_cu *cu; struct die_info *die; @@ -14358,10 +17521,10 @@ dwarf2_fetch_die_location_block (unsigned int offset, load_cu (per_cu); cu = per_cu->cu; - die = follow_die_offset (offset, &cu); + die = follow_die_offset (offset, per_cu->is_dwz, &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) @@ -14389,7 +17552,7 @@ 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; @@ -14401,15 +17564,33 @@ dwarf2_fetch_die_location_block (unsigned int offset, return retval; } +/* Like dwarf2_fetch_die_loc_sect_off, but take a CU + offset. */ + +struct dwarf2_locexpr_baton +dwarf2_fetch_die_loc_cu_off (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 }; + + return dwarf2_fetch_die_loc_sect_off (offset, per_cu, get_frame_pc, baton); +} + /* Return the type of the DIE at DIE_OFFSET in the CU named by 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. @@ -14431,27 +17612,39 @@ 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) { + /* For .gdb_index version 7 keep track of included TUs. + http://sourceware.org/bugzilla/show_bug.cgi?id=15021. */ + if (dwarf2_per_objfile->index_table != NULL + && dwarf2_per_objfile->index_table->version <= 7) + { + VEC_safe_push (dwarf2_per_cu_ptr, + (*ref_cu)->per_cu->imported_symtabs, + sig_cu->per_cu); + } + *ref_cu = sig_cu; return die; } error (_("Dwarf Error: Cannot find signatured DIE at 0x%x referenced " "from DIE at 0x%x [in module %s]"), - sig_type->type_offset, src_die->offset, objfile->name); + temp_die.offset.sect_off, src_die->offset.sect_off, objfile->name); } /* Given an offset of a signatured type, return its signatured_type. */ @@ -14459,12 +17652,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 @@ -14472,100 +17665,90 @@ 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 signatured_type *sig_type; - dwarf2_read_section (objfile, sect); + /* Caller is responsible for ensuring type_unit_groups don't get here. */ + gdb_assert (! IS_TYPE_UNIT_GROUP (per_cu)); - /* 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); + /* We have the per_cu, but we need the signatured_type. + Fortunately this is an easy translation. */ + gdb_assert (per_cu->is_debug_types); + sig_type = (struct signatured_type *) per_cu; - gdb_assert (type_sig->per_cu.cu == NULL); + gdb_assert (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 (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_types_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; - 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); + 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); +} - do_cleanups (back_to); +/* 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 +read_signatured_type (struct signatured_type *sig_type) +{ + struct dwarf2_per_cu_data *per_cu = &sig_type->per_cu; - /* We've successfully allocated this compilation unit. Let our caller - clean it up when finished with it. */ - discard_cleanups (free_cu_cleanup); + gdb_assert (per_cu->is_debug_types); + gdb_assert (per_cu->cu == NULL); - type_sig->per_cu.cu->read_in_chain = dwarf2_per_objfile->read_in_chain; - dwarf2_per_objfile->read_in_chain = &type_sig->per_cu; + init_cutu_and_read_dies (per_cu, NULL, 0, 1, + read_signatured_type_reader, NULL); } /* Decode simple location descriptions. @@ -14593,8 +17776,8 @@ static CORE_ADDR decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; - int i; - int size = blk->size; + size_t i; + size_t size = blk->size; gdb_byte *data = blk->data; CORE_ADDR stack[64]; int stacki; @@ -14790,9 +17973,16 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu) case DW_OP_GNU_uninit: break; + case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: + stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i], + &bytes_read); + i += bytes_read; + break; + default: { - const char *name = dwarf_stack_op_name (op); + const char *name = get_DW_OP_name (op); if (name) complaint (&symfile_complaints, _("unsupported stack op: '%s'"), @@ -14836,17 +18026,6 @@ dwarf_alloc_block (struct dwarf2_cu *cu) return (blk); } -static struct abbrev_info * -dwarf_alloc_abbrev (struct dwarf2_cu *cu) -{ - struct abbrev_info *abbrev; - - abbrev = (struct abbrev_info *) - obstack_alloc (&cu->abbrev_obstack, sizeof (struct abbrev_info)); - memset (abbrev, 0, sizeof (struct abbrev_info)); - return (abbrev); -} - static struct die_info * dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs) { @@ -14864,12 +18043,12 @@ dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs) /* Macro support. */ -/* Return the full name of file number I in *LH's file name table. - Use COMP_DIR as the name of the current directory of the - compilation. The result is allocated using xmalloc; the caller is +/* Return file name relative to the compilation directory of file number I in + *LH's file name table. The result is allocated using xmalloc; the caller is responsible for freeing it. */ + static char * -file_full_name (int file, struct line_header *lh, const char *comp_dir) +file_file_name (int file, struct line_header *lh) { /* Is the file number a valid index into the line header's file name table? Remember that file numbers start with one, not zero. */ @@ -14877,31 +18056,10 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir) { struct file_entry *fe = &lh->file_names[file - 1]; - if (IS_ABSOLUTE_PATH (fe->name)) + if (IS_ABSOLUTE_PATH (fe->name) || fe->dir_index == 0) return xstrdup (fe->name); - else - { - const char *dir; - int dir_len; - char *full_name; - - if (fe->dir_index) - dir = lh->include_dirs[fe->dir_index - 1]; - else - dir = comp_dir; - - if (dir) - { - dir_len = strlen (dir); - full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1); - strcpy (full_name, dir); - full_name[dir_len] = '/'; - strcpy (full_name + dir_len + 1, fe->name); - return full_name; - } - else - return xstrdup (fe->name); - } + return concat (lh->include_dirs[fe->dir_index - 1], SLASH_STRING, + fe->name, NULL); } else { @@ -14910,7 +18068,8 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir) won't be able to find the file by name. */ char fake_name[80]; - sprintf (fake_name, "", file); + xsnprintf (fake_name, sizeof (fake_name), + "", file); complaint (&symfile_complaints, _("bad file number in macro information (%d)"), @@ -14920,6 +18079,27 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir) } } +/* Return the full name of file number I in *LH's file name table. + Use COMP_DIR as the name of the current directory of the + compilation. The result is allocated using xmalloc; the caller is + responsible for freeing it. */ +static char * +file_full_name (int file, struct line_header *lh, const char *comp_dir) +{ + /* Is the file number a valid index into the line header's file name + table? Remember that file numbers start with one, not zero. */ + if (1 <= file && file <= lh->num_file_names) + { + char *relative = file_file_name (file, lh); + + if (IS_ABSOLUTE_PATH (relative) || comp_dir == NULL) + return relative; + return reconcat (relative, comp_dir, SLASH_STRING, relative, NULL); + } + else + return file_file_name (file, lh); +} + static struct macro_source_file * macro_start_file (int file, int line, @@ -14927,23 +18107,27 @@ macro_start_file (int file, int line, const char *comp_dir, struct line_header *lh, struct objfile *objfile) { - /* The full name of this source file. */ - char *full_name = file_full_name (file, lh, comp_dir); + /* File name relative to the compilation directory of this source file. */ + char *file_name = file_file_name (file, lh); /* We don't create a macro table for this compilation unit at all until we actually get a filename. */ if (! pending_macros) - pending_macros = new_macro_table (&objfile->objfile_obstack, - objfile->macro_cache); + pending_macros = new_macro_table (&objfile->per_bfd->storage_obstack, + objfile->per_bfd->macro_cache, + comp_dir); 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, file_name); + macro_define_special (pending_macros); + } else - current_file = macro_include (current_file, line, full_name); + current_file = macro_include (current_file, line, file_name); - xfree (full_name); + xfree (file_name); return current_file; } @@ -15124,7 +18308,7 @@ parse_macro_definition (struct macro_source_file *file, int line, Returns the new pointer. */ static gdb_byte * -skip_form_bytes (bfd *abfd, gdb_byte *bytes, +skip_form_bytes (bfd *abfd, gdb_byte *bytes, gdb_byte *buffer_end, enum dwarf_form form, unsigned int offset_size, struct dwarf2_section_info *section) @@ -15157,6 +18341,7 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, case DW_FORM_sec_offset: case DW_FORM_strp: + case DW_FORM_GNU_strp_alt: bytes += offset_size; break; @@ -15177,7 +18362,14 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, case DW_FORM_sdata: case DW_FORM_udata: - bytes = skip_leb128 (abfd, bytes); + case DW_FORM_GNU_addr_index: + case DW_FORM_GNU_str_index: + bytes = (gdb_byte *) gdb_skip_leb128 (bytes, buffer_end); + if (bytes == NULL) + { + dwarf2_section_buffer_overflow_complaint (section); + return NULL; + } break; default: @@ -15201,7 +18393,7 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, static gdb_byte * skip_unknown_opcode (unsigned int opcode, gdb_byte **opcode_definitions, - gdb_byte *mac_ptr, + gdb_byte *mac_ptr, gdb_byte *mac_end, bfd *abfd, unsigned int offset_size, struct dwarf2_section_info *section) @@ -15224,7 +18416,8 @@ skip_unknown_opcode (unsigned int opcode, for (i = 0; i < arg; ++i) { - mac_ptr = skip_form_bytes (abfd, mac_ptr, defn[i], offset_size, section); + mac_ptr = skip_form_bytes (abfd, mac_ptr, mac_end, defn[i], offset_size, + section); if (mac_ptr == NULL) { /* skip_form_bytes already issued the complaint. */ @@ -15297,16 +18490,17 @@ 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, struct macro_source_file *current_file, - struct line_header *lh, char *comp_dir, + struct line_header *lh, const char *comp_dir, struct dwarf2_section_info *section, - int section_is_gnu, + int section_is_gnu, int section_is_dwz, unsigned int offset_size, - struct objfile *objfile) + struct objfile *objfile, + htab_t include_hash) { enum dwarf_macro_record_type macinfo_type; int at_commandline; @@ -15334,7 +18528,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, /* Do we at least have room for a macinfo type byte? */ if (mac_ptr >= mac_end) { - dwarf2_macros_too_long_complaint (section); + dwarf2_section_buffer_overflow_complaint (section); break; } @@ -15354,6 +18548,8 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, case DW_MACRO_GNU_undef: case DW_MACRO_GNU_define_indirect: case DW_MACRO_GNU_undef_indirect: + case DW_MACRO_GNU_define_indirect_alt: + case DW_MACRO_GNU_undef_indirect_alt: { unsigned int bytes_read; int line; @@ -15376,11 +18572,21 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, str_offset = read_offset_1 (abfd, mac_ptr, offset_size); mac_ptr += offset_size; - body = read_indirect_string_at_offset (abfd, str_offset); + if (macinfo_type == DW_MACRO_GNU_define_indirect_alt + || macinfo_type == DW_MACRO_GNU_undef_indirect_alt + || section_is_dwz) + { + struct dwz_file *dwz = dwarf2_get_dwz_file (); + + body = read_indirect_string_from_dwz (dwz, str_offset); + } + else + body = read_indirect_string_at_offset (abfd, str_offset); } is_define = (macinfo_type == DW_MACRO_GNU_define - || macinfo_type == DW_MACRO_GNU_define_indirect); + || macinfo_type == DW_MACRO_GNU_define_indirect + || macinfo_type == DW_MACRO_GNU_define_indirect_alt); if (! current_file) { /* DWARF violation as no main source is present. */ @@ -15404,7 +18610,8 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, else { gdb_assert (macinfo_type == DW_MACRO_GNU_undef - || macinfo_type == DW_MACRO_GNU_undef_indirect); + || macinfo_type == DW_MACRO_GNU_undef_indirect + || macinfo_type == DW_MACRO_GNU_undef_indirect_alt); macro_undef (current_file, line, body); } } @@ -15461,7 +18668,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, /* Do we at least have room for a macinfo type byte? */ if (mac_ptr >= mac_end) { - dwarf2_macros_too_long_complaint (section); + dwarf2_section_buffer_overflow_complaint (section); return; } @@ -15479,18 +18686,56 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, break; case DW_MACRO_GNU_transparent_include: + case DW_MACRO_GNU_transparent_include_alt: { LONGEST offset; + void **slot; + bfd *include_bfd = abfd; + struct dwarf2_section_info *include_section = section; + struct dwarf2_section_info alt_section; + gdb_byte *include_mac_end = mac_end; + int is_dwz = section_is_dwz; + gdb_byte *new_mac_ptr; 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); + if (macinfo_type == DW_MACRO_GNU_transparent_include_alt) + { + struct dwz_file *dwz = dwarf2_get_dwz_file (); + + dwarf2_read_section (dwarf2_per_objfile->objfile, + &dwz->macro); + + include_bfd = dwz->macro.asection->owner; + include_section = &dwz->macro; + include_mac_end = dwz->macro.buffer + dwz->macro.size; + is_dwz = 1; + } + + new_mac_ptr = include_section->buffer + offset; + slot = htab_find_slot (include_hash, new_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 = new_mac_ptr; + + dwarf_decode_macro_bytes (include_bfd, new_mac_ptr, + include_mac_end, current_file, + lh, comp_dir, + section, section_is_gnu, is_dwz, + offset_size, objfile, include_hash); + + htab_remove_elt (include_hash, new_mac_ptr); + } } break; @@ -15512,7 +18757,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, default: mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions, - mac_ptr, abfd, offset_size, + mac_ptr, mac_end, abfd, offset_size, section); if (mac_ptr == NULL) return; @@ -15522,25 +18767,57 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end, } static void -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) +dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset, + const char *comp_dir, int section_is_gnu) { + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct line_header *lh = cu->line_header; + bfd *abfd; 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; + struct dwarf2_section_info *section; + const char *section_name; - dwarf2_read_section (dwarf2_per_objfile->objfile, section); + if (cu->dwo_unit != NULL) + { + if (section_is_gnu) + { + section = &cu->dwo_unit->dwo_file->sections.macro; + section_name = ".debug_macro.dwo"; + } + else + { + section = &cu->dwo_unit->dwo_file->sections.macinfo; + section_name = ".debug_macinfo.dwo"; + } + } + else + { + if (section_is_gnu) + { + section = &dwarf2_per_objfile->macro; + section_name = ".debug_macro"; + } + else + { + section = &dwarf2_per_objfile->macinfo; + section_name = ".debug_macinfo"; + } + } + + 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; } + abfd = section->asection->owner; /* First pass: Find the name of the base filename. This filename is needed in order to process all macros whose definition @@ -15611,7 +18888,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; @@ -15621,6 +18898,8 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, case DW_MACRO_GNU_define_indirect: case DW_MACRO_GNU_undef_indirect: + case DW_MACRO_GNU_define_indirect_alt: + case DW_MACRO_GNU_undef_indirect_alt: { unsigned int bytes_read; @@ -15631,6 +18910,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, break; case DW_MACRO_GNU_transparent_include: + case DW_MACRO_GNU_transparent_include_alt: /* Note that, according to the spec, a transparent include chain cannot call DW_MACRO_GNU_start_file. So, we can just skip this opcode. */ @@ -15652,7 +18932,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset, default: mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions, - mac_ptr, abfd, offset_size, + mac_ptr, mac_end, abfd, offset_size, section); if (mac_ptr == NULL) return; @@ -15666,13 +18946,22 @@ 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, - current_file, lh, comp_dir, section, section_is_gnu, - offset_size, cu->objfile); + 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, 0, + 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) { @@ -15692,6 +18981,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) { @@ -15700,7 +18990,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. @@ -15713,6 +19002,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) { @@ -15730,6 +19020,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 @@ -15737,32 +19038,36 @@ 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; + baton->from_dwo = cu->dwo_unit != NULL; } 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); @@ -15779,7 +19084,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); @@ -15831,26 +19136,22 @@ 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; + info_ptr = per_cu->info_or_types_section->buffer + per_cu->offset.sect_off; memset (cu_headerp, 0, sizeof (*cu_headerp)); - read_comp_unit_head (cu_headerp, info_ptr, objfile->obfd); + read_comp_unit_head (cu_headerp, info_ptr, per_cu->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) { struct comp_unit_head cu_header_local; @@ -15907,73 +19208,72 @@ 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, + unsigned int offset_in_dwz, struct objfile *objfile) { struct dwarf2_per_cu_data *this_cu; int low, high; + const sect_offset *cu_off; low = 0; high = dwarf2_per_objfile->n_comp_units - 1; while (high > low) { + struct dwarf2_per_cu_data *mid_cu; int mid = low + (high - low) / 2; - if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset) + mid_cu = dwarf2_per_objfile->all_comp_units[mid]; + cu_off = &mid_cu->offset; + if (mid_cu->is_dwz > offset_in_dwz + || (mid_cu->is_dwz == offset_in_dwz + && cu_off->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) + this_cu = dwarf2_per_objfile->all_comp_units[low]; + cu_off = &this_cu->offset; + if (this_cu->is_dwz != offset_in_dwz || cu_off->sect_off > offset.sect_off) { - if (low == 0) + if (low == 0 || this_cu->is_dwz != offset_in_dwz) 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; @@ -15983,9 +19283,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 @@ -15995,12 +19299,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); @@ -16010,30 +19314,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. */ @@ -16051,7 +19344,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; @@ -16086,7 +19379,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 @@ -16099,7 +19392,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; @@ -16111,9 +19404,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; } @@ -16143,35 +19437,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. + + 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_offset_and_type +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 @@ -16195,9 +19499,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 @@ -16212,55 +19515,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_types_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_types_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 @@ -16354,7 +19649,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 @@ -16366,7 +19661,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; @@ -16384,54 +19679,31 @@ show_dwarf2_cmd (char *args, int from_tty) cmd_show_list (show_dwarf2_cmdlist, from_tty, ""); } -/* If section described by INFO was mmapped, munmap it now. */ - -static void -munmap_section_buffer (struct dwarf2_section_info *info) -{ - if (info->map_addr != NULL) - { -#ifdef HAVE_MMAP - int res; - - res = munmap (info->map_addr, info->map_len); - gdb_assert (res == 0); -#else - /* Without HAVE_MMAP, we should never be here to begin with. */ - gdb_assert_not_reached ("no mmap support"); -#endif - } -} - -/* munmap debug sections for OBJFILE, if necessary. */ +/* Free data associated with OBJFILE, if necessary. */ static void dwarf2_per_objfile_free (struct objfile *objfile, void *d) { struct dwarf2_per_objfile *data = d; int ix; - struct dwarf2_section_info *section; - /* This is sorted according to the order they're defined in to make it easier - to keep in sync. */ - munmap_section_buffer (&data->info); - munmap_section_buffer (&data->abbrev); - munmap_section_buffer (&data->line); - munmap_section_buffer (&data->loc); - munmap_section_buffer (&data->macinfo); - munmap_section_buffer (&data->macro); - munmap_section_buffer (&data->str); - munmap_section_buffer (&data->ranges); - munmap_section_buffer (&data->frame); - munmap_section_buffer (&data->eh_frame); - munmap_section_buffer (&data->gdb_index); + 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); - for (ix = 0; - VEC_iterate (dwarf2_section_info_def, data->types, ix, section); - ++ix) - munmap_section_buffer (section); + for (ix = 0; ix < dwarf2_per_objfile->n_type_units; ++ix) + VEC_free (dwarf2_per_cu_ptr, + dwarf2_per_objfile->all_type_units[ix]->per_cu.imported_symtabs); VEC_free (dwarf2_section_info_def, data->types); + + if (data->dwo_files) + free_dwo_files (data->dwo_files, objfile); + if (data->dwp_file) + gdb_bfd_unref (data->dwp_file->dbfd); + + if (data->dwz_file && data->dwz_file->dwz_bfd) + gdb_bfd_unref (data->dwz_file->dwz_bfd); } @@ -16638,14 +19910,17 @@ hash_expand (struct mapped_symtab *symtab) xfree (old_entries); } -/* Add an entry to SYMTAB. NAME is the name of the symbol. CU_INDEX - is the index of the CU in which the symbol appears. */ +/* Add an entry to SYMTAB. NAME is the name of the symbol. + CU_INDEX is the index of the CU in which the symbol appears. + IS_STATIC is one if the symbol is static, otherwise zero (global). */ static void add_index_entry (struct mapped_symtab *symtab, const char *name, + int is_static, gdb_index_symbol_kind kind, offset_type cu_index) { struct symtab_index_entry **slot; + offset_type cu_index_and_attrs; ++symtab->n_elements; if (4 * symtab->n_elements / 3 >= symtab->size) @@ -16656,13 +19931,76 @@ add_index_entry (struct mapped_symtab *symtab, const char *name, { *slot = XNEW (struct symtab_index_entry); (*slot)->name = name; + /* index_offset is set later. */ (*slot)->cu_indices = NULL; } - /* Don't push an index twice. Due to how we add entries we only - have to check the last one. */ - if (VEC_empty (offset_type, (*slot)->cu_indices) - || VEC_last (offset_type, (*slot)->cu_indices) != cu_index) - VEC_safe_push (offset_type, (*slot)->cu_indices, cu_index); + + cu_index_and_attrs = 0; + DW2_GDB_INDEX_CU_SET_VALUE (cu_index_and_attrs, cu_index); + DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE (cu_index_and_attrs, is_static); + DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE (cu_index_and_attrs, kind); + + /* We don't want to record an index value twice as we want to avoid the + duplication. + We process all global symbols and then all static symbols + (which would allow us to avoid the duplication by only having to check + the last entry pushed), but a symbol could have multiple kinds in one CU. + To keep things simple we don't worry about the duplication here and + sort and uniqufy the list after we've processed all symbols. */ + VEC_safe_push (offset_type, (*slot)->cu_indices, cu_index_and_attrs); +} + +/* qsort helper routine for uniquify_cu_indices. */ + +static int +offset_type_compare (const void *ap, const void *bp) +{ + offset_type a = *(offset_type *) ap; + offset_type b = *(offset_type *) bp; + + return (a > b) - (b > a); +} + +/* Sort and remove duplicates of all symbols' cu_indices lists. */ + +static void +uniquify_cu_indices (struct mapped_symtab *symtab) +{ + int i; + + for (i = 0; i < symtab->size; ++i) + { + struct symtab_index_entry *entry = symtab->data[i]; + + if (entry + && entry->cu_indices != NULL) + { + unsigned int next_to_insert, next_to_check; + offset_type last_value; + + qsort (VEC_address (offset_type, entry->cu_indices), + VEC_length (offset_type, entry->cu_indices), + sizeof (offset_type), offset_type_compare); + + last_value = VEC_index (offset_type, entry->cu_indices, 0); + next_to_insert = 1; + for (next_to_check = 1; + next_to_check < VEC_length (offset_type, entry->cu_indices); + ++next_to_check) + { + if (VEC_index (offset_type, entry->cu_indices, next_to_check) + != last_value) + { + last_value = VEC_index (offset_type, entry->cu_indices, + next_to_check); + VEC_replace (offset_type, entry->cu_indices, next_to_insert, + last_value); + ++next_to_insert; + } + } + VEC_truncate (offset_type, entry->cu_indices, next_to_insert); + } + } } /* Add a vector of indices to the constant pool. */ @@ -16821,8 +20159,6 @@ add_address_entry_worker (void *datap, CORE_ADDR start_addr, void *obj) { struct addrmap_index_data *data = datap; struct partial_symtab *pst = obj; - offset_type cu_index; - void **slot; if (data->previous_valid) add_address_entry (data->objfile, data->addr_obstack, @@ -16878,6 +20214,44 @@ write_address_map (struct objfile *objfile, struct obstack *obstack, addrmap_index_data.previous_cu_index); } +/* Return the symbol kind of PSYM. */ + +static gdb_index_symbol_kind +symbol_kind (struct partial_symbol *psym) +{ + domain_enum domain = PSYMBOL_DOMAIN (psym); + enum address_class aclass = PSYMBOL_CLASS (psym); + + switch (domain) + { + case VAR_DOMAIN: + switch (aclass) + { + case LOC_BLOCK: + return GDB_INDEX_SYMBOL_KIND_FUNCTION; + case LOC_TYPEDEF: + return GDB_INDEX_SYMBOL_KIND_TYPE; + case LOC_COMPUTED: + case LOC_CONST_BYTES: + case LOC_OPTIMIZED_OUT: + case LOC_STATIC: + return GDB_INDEX_SYMBOL_KIND_VARIABLE; + case LOC_CONST: + /* Note: It's currently impossible to recognize psyms as enum values + short of reading the type info. For now punt. */ + return GDB_INDEX_SYMBOL_KIND_VARIABLE; + default: + /* There are other LOC_FOO values that one might want to classify + as variables, but dwarf2read.c doesn't currently use them. */ + return GDB_INDEX_SYMBOL_KIND_OTHER; + } + case STRUCT_DOMAIN: + return GDB_INDEX_SYMBOL_KIND_TYPE; + default: + return GDB_INDEX_SYMBOL_KIND_OTHER; + } +} + /* Add a list of partial symbols to SYMTAB. */ static void @@ -16890,29 +20264,21 @@ write_psymbols (struct mapped_symtab *symtab, { for (; count-- > 0; ++psymp) { - void **slot, *lookup; + struct partial_symbol *psym = *psymp; + void **slot; - if (SYMBOL_LANGUAGE (*psymp) == language_ada) + if (SYMBOL_LANGUAGE (psym) == language_ada) error (_("Ada is not currently supported by the index")); - /* We only want to add a given psymbol once. However, we also - want to account for whether it is global or static. So, we - may add it twice, using slightly different values. */ - if (is_static) - { - uintptr_t val = 1 | (uintptr_t) *psymp; - - lookup = (void *) val; - } - else - lookup = *psymp; - /* Only add a given psymbol once. */ - slot = htab_find_slot (psyms_seen, lookup, INSERT); + slot = htab_find_slot (psyms_seen, psym, INSERT); if (!*slot) { - *slot = lookup; - add_index_entry (symtab, SYMBOL_NATURAL_NAME (*psymp), cu_index); + gdb_index_symbol_kind kind = symbol_kind (psym); + + *slot = psym; + add_index_entry (symtab, SYMBOL_SEARCH_NAME (psym), + is_static, kind, cu_index); } } } @@ -16974,9 +20340,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); @@ -16986,6 +20354,35 @@ write_one_signatured_type (void **slot, void *d) return 1; } +/* Recurse into all "included" dependencies and write their symbols as + if they appeared in this psymtab. */ + +static void +recursively_write_psymbols (struct objfile *objfile, + struct partial_symtab *psymtab, + struct mapped_symtab *symtab, + htab_t psyms_seen, + offset_type cu_index) +{ + 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. */ static void @@ -17000,7 +20397,6 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) struct mapped_symtab *symtab; offset_type val, size_of_contents, total_len; struct stat st; - char buf[8]; htab_t psyms_seen; htab_t cu_index_htab; struct psymtab_cu_index_map *psymtab_cu_index_map; @@ -17070,16 +20466,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; @@ -17089,7 +20477,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); @@ -17112,6 +20501,10 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) write_one_signatured_type, &sig_data); } + /* Now that we've processed all symbols we can shrink their cu_indices + lists. */ + uniquify_cu_indices (symtab); + obstack_init (&constant_pool); make_cleanup_obstack_free (&constant_pool); obstack_init (&symtab_obstack); @@ -17124,7 +20517,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 (8); obstack_grow (&contents, &val, sizeof (val)); /* The offset of the CU list from the start of the file. */ @@ -17277,14 +20670,23 @@ conversational style, when possible."), &set_dwarf2_cmdlist, &show_dwarf2_cmdlist); - add_setshow_zinteger_cmd ("dwarf2-die", no_class, &dwarf2_die_debug, _("\ + add_setshow_boolean_cmd ("dwarf2-read", no_class, &dwarf2_read_debug, _("\ +Set debugging of the dwarf2 reader."), _("\ +Show debugging of the dwarf2 reader."), _("\ +When enabled, debugging messages are printed during dwarf2 reading\n\ +and symtab expansion."), + NULL, + NULL, + &setdebuglist, &showdebuglist); + + add_setshow_zuinteger_cmd ("dwarf2-die", no_class, &dwarf2_die_debug, _("\ Set debugging of the dwarf2 DIE reader."), _("\ Show debugging of the dwarf2 DIE reader."), _("\ When enabled (non-zero), DIEs are dumped after they are read in.\n\ The value is the maximum depth to print."), - NULL, - NULL, - &setdebuglist, &showdebuglist); + NULL, + NULL, + &setdebuglist, &showdebuglist); add_setshow_boolean_cmd ("check-physname", no_class, &check_physname, _("\ Set cross-checking of \"physname\" code against demangler."), _("\ @@ -17294,6 +20696,18 @@ the demangler."), NULL, show_check_physname, &setdebuglist, &showdebuglist); + add_setshow_boolean_cmd ("use-deprecated-index-sections", + no_class, &use_deprecated_index_sections, _("\ +Set whether to use deprecated gdb_index sections."), _("\ +Show whether to use deprecated gdb_index sections."), _("\ +When enabled, deprecated .gdb_index sections are used anyway.\n\ +Normally they are ignored either because of a missing feature or\n\ +performance issue.\n\ +Warning: This option must be enabled before gdb reads the file."), + NULL, + NULL, + &setlist, &showlist); + c = add_cmd ("gdb-index", class_files, save_gdb_index_command, _("\ Save a gdb-index file.\n\