| /* DWARF 2 debugging format support for GDB. |
| |
| Copyright (C) 1994-2012 Free Software Foundation, Inc. |
| |
| Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology, |
| Inc. with support from Florida State University (under contract |
| with the Ada Joint Program Office), and Silicon Graphics, Inc. |
| Initial contribution by Brent Benson, Harris Computer Systems, Inc., |
| based on Fred Fish's (Cygnus Support) implementation of DWARF 1 |
| support. |
| |
| This file is part of GDB. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| |
| /* FIXME: Various die-reading functions need to be more careful with |
| reading off the end of the section. |
| E.g., load_partial_dies, read_partial_die. */ |
| |
| #include "defs.h" |
| #include "bfd.h" |
| #include "symtab.h" |
| #include "gdbtypes.h" |
| #include "objfiles.h" |
| #include "dwarf2.h" |
| #include "buildsym.h" |
| #include "demangle.h" |
| #include "gdb-demangle.h" |
| #include "expression.h" |
| #include "filenames.h" /* for DOSish file names */ |
| #include "macrotab.h" |
| #include "language.h" |
| #include "complaints.h" |
| #include "bcache.h" |
| #include "dwarf2expr.h" |
| #include "dwarf2loc.h" |
| #include "cp-support.h" |
| #include "hashtab.h" |
| #include "command.h" |
| #include "gdbcmd.h" |
| #include "block.h" |
| #include "addrmap.h" |
| #include "typeprint.h" |
| #include "jv-lang.h" |
| #include "psympriv.h" |
| #include "exceptions.h" |
| #include "gdb_stat.h" |
| #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 <ctype.h> |
| |
| #include <fcntl.h> |
| #include "gdb_string.h" |
| #include "gdb_assert.h" |
| #include <sys/types.h> |
| #ifdef HAVE_ZLIB_H |
| #include <zlib.h> |
| #endif |
| #ifdef HAVE_MMAP |
| #include <sys/mman.h> |
| #ifndef MAP_FAILED |
| #define MAP_FAILED ((void *) -1) |
| #endif |
| #endif |
| |
| typedef struct symbol *symbolp; |
| DEF_VEC_P (symbolp); |
| |
| /* 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; |
| |
| /* When non-zero, cross-check physname against demangler. */ |
| static int check_physname = 0; |
| |
| /* When non-zero, do not reject deprecated .gdb_index sections. */ |
| static int use_deprecated_index_sections = 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; |
| |
| static const struct objfile_data *dwarf2_objfile_data_key; |
| |
| 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; |
| }; |
| |
| typedef struct dwarf2_section_info dwarf2_section_info_def; |
| DEF_VEC_O (dwarf2_section_info_def); |
| |
| /* All offsets in the index are of this type. It must be |
| architecture-independent. */ |
| 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 |
| { |
| /* Index data format version. */ |
| int version; |
| |
| /* The total length of the buffer. */ |
| off_t total_size; |
| |
| /* A pointer to the address table data. */ |
| const gdb_byte *address_table; |
| |
| /* Size of the address table data in bytes. */ |
| offset_type address_table_size; |
| |
| /* The symbol table, implemented as a hash table. */ |
| const offset_type *symbol_table; |
| |
| /* Size in slots, each slot is 2 offset_types. */ |
| offset_type symbol_table_slots; |
| |
| /* A pointer to the constant pool. */ |
| 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; |
| 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 ranges; |
| struct dwarf2_section_info addr; |
| struct dwarf2_section_info frame; |
| struct dwarf2_section_info eh_frame; |
| struct dwarf2_section_info gdb_index; |
| |
| VEC (dwarf2_section_info_def) *types; |
| |
| /* Back link. */ |
| struct objfile *objfile; |
| |
| /* 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; |
| |
| /* The number of compilation units in ALL_COMP_UNITS. */ |
| int n_comp_units; |
| |
| /* The number of .debug_types-related CUs. */ |
| int n_type_units; |
| |
| /* The .debug_types-related CUs (TUs). */ |
| struct signatured_type **all_type_units; |
| |
| /* 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; |
| |
| /* A flag indicating wether this objfile has a section loaded at a |
| VMA of 0. */ |
| int has_section_at_zero; |
| |
| /* True if we are using the mapped index, |
| or we are faking it for OBJF_READNOW's sake. */ |
| unsigned char using_index; |
| |
| /* The mapped index, or NULL if .gdb_index is missing or not being used. */ |
| 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. */ |
| htab_t quick_file_names_table; |
| |
| /* Set during partial symbol reading, to prevent queueing of full |
| symbols. */ |
| int reading_partial_symbols; |
| |
| /* Table mapping type DIEs to their struct type *. |
| This is NULL if not allocated yet. |
| The mapping is done via (CU/TU signature + DIE offset) -> type. */ |
| htab_t die_type_hash; |
| |
| /* The CUs we recently read. */ |
| VEC (dwarf2_per_cu_ptr) *just_read_cus; |
| }; |
| |
| static struct dwarf2_per_objfile *dwarf2_per_objfile; |
| |
| /* Default names of the debugging sections. */ |
| |
| /* 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 = |
| { |
| { ".debug_info", ".zdebug_info" }, |
| { ".debug_abbrev", ".zdebug_abbrev" }, |
| { ".debug_line", ".zdebug_line" }, |
| { ".debug_loc", ".zdebug_loc" }, |
| { ".debug_macinfo", ".zdebug_macinfo" }, |
| { ".debug_macro", ".zdebug_macro" }, |
| { ".debug_str", ".zdebug_str" }, |
| { ".debug_ranges", ".zdebug_ranges" }, |
| { ".debug_types", ".zdebug_types" }, |
| { ".debug_addr", ".zdebug_addr" }, |
| { ".debug_frame", ".zdebug_frame" }, |
| { ".eh_frame", NULL }, |
| { ".gdb_index", ".zgdb_index" }, |
| 23 |
| }; |
| |
| /* List of DWO sections. */ |
| |
| static const struct dwo_section_names |
| { |
| struct dwarf2_section_names abbrev_dwo; |
| struct dwarf2_section_names info_dwo; |
| struct dwarf2_section_names line_dwo; |
| struct dwarf2_section_names loc_dwo; |
| struct dwarf2_section_names 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; |
| } |
| dwo_section_names = |
| { |
| { ".debug_abbrev.dwo", ".zdebug_abbrev.dwo" }, |
| { ".debug_info.dwo", ".zdebug_info.dwo" }, |
| { ".debug_line.dwo", ".zdebug_line.dwo" }, |
| { ".debug_loc.dwo", ".zdebug_loc.dwo" }, |
| { ".debug_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" }, |
| }; |
| |
| /* local data types */ |
| |
| /* The data in a compilation unit header, after target2host |
| translation, looks like this. */ |
| struct comp_unit_head |
| { |
| unsigned int length; |
| short version; |
| unsigned char addr_size; |
| unsigned char signed_addr_p; |
| sect_offset abbrev_offset; |
| |
| /* Size of file offsets; either 4 or 8. */ |
| unsigned int offset_size; |
| |
| /* Size of the length field; either 4 or 12. */ |
| unsigned int initial_length_size; |
| |
| /* Offset to the first byte of this compilation unit header in the |
| .debug_info section, for resolving relative reference dies. */ |
| 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. */ |
| cu_offset first_die_offset; |
| }; |
| |
| /* Type used for delaying computation of method physnames. |
| See comments for compute_delayed_physnames. */ |
| struct delayed_method_info |
| { |
| /* The type to which the method is attached, i.e., its parent class. */ |
| struct type *type; |
| |
| /* The index of the method in the type's function fieldlists. */ |
| int fnfield_index; |
| |
| /* The index of the method in the fieldlist. */ |
| int index; |
| |
| /* The name of the DIE. */ |
| const char *name; |
| |
| /* The DIE associated with this method. */ |
| struct die_info *die; |
| }; |
| |
| typedef struct delayed_method_info delayed_method_info; |
| DEF_VEC_O (delayed_method_info); |
| |
| /* Internal state when decoding a particular compilation unit. */ |
| struct dwarf2_cu |
| { |
| /* The objfile containing this compilation unit. */ |
| struct objfile *objfile; |
| |
| /* The header of the compilation unit. */ |
| struct comp_unit_head header; |
| |
| /* Base address of this compilation unit. */ |
| CORE_ADDR base_address; |
| |
| /* Non-zero if base_address has been set. */ |
| int base_known; |
| |
| /* The language we are debugging. */ |
| enum language language; |
| const struct language_defn *language_defn; |
| |
| const char *producer; |
| |
| /* The generic symbol table building routines have separate lists for |
| file scope symbols and all all other scopes (local scopes). So |
| we need to select the right one to pass to add_symbol_to_list(). |
| We do it by keeping a pointer to the correct list in list_in_scope. |
| |
| FIXME: The original dwarf code just treated the file scope as the |
| first local scope, and all other local scopes as nested local |
| scopes, and worked fine. Check to see if we really need to |
| distinguish these in buildsym.c. */ |
| struct pending **list_in_scope; |
| |
| /* 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 |
| with partial_die->offset.SECT_OFF as hash. */ |
| htab_t partial_dies; |
| |
| /* Storage for things with the same lifetime as this read-in compilation |
| unit, including partial DIEs. */ |
| struct obstack comp_unit_obstack; |
| |
| /* When multiple dwarf2_cu structures are living in memory, this field |
| chains them all together, so that they can be released efficiently. |
| We will probably also want a generation counter so that most-recently-used |
| compilation units are cached... */ |
| struct dwarf2_per_cu_data *read_in_chain; |
| |
| /* Backchain to our per_cu entry if the tree has been built. */ |
| struct dwarf2_per_cu_data *per_cu; |
| |
| /* How many compilation units ago was this CU last referenced? */ |
| int last_used; |
| |
| /* 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. */ |
| struct die_info *dies; |
| |
| /* A set of pointers to dwarf2_per_cu_data objects for compilation |
| units referenced by this one. Only set during full symbol processing; |
| partial symbol tables do not have dependencies. */ |
| htab_t dependencies; |
| |
| /* Header data from the line table, during full symbol processing. */ |
| struct line_header *line_header; |
| |
| /* A list of methods which need to have physnames computed |
| after all type information has been read. */ |
| VEC (delayed_method_info) *method_list; |
| |
| /* 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. */ |
| ULONGEST ranges_base; |
| |
| /* Mark used when releasing cached dies. */ |
| unsigned int mark : 1; |
| |
| /* This CU references .debug_loc. See the symtab->locations_valid field. |
| This test is imperfect as there may exist optimized debug code not using |
| any location list and still facing inlining issues if handled as |
| unoptimized code. For a future better test see GCC PR other/32998. */ |
| unsigned int has_loclist : 1; |
| |
| /* These cache the results for producer_is_gxx_lt_4_6 and producer_is_icc. |
| CHECKED_PRODUCER is set if both PRODUCER_IS_GXX_LT_4_6 and PRODUCER_IS_ICC |
| 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_icc : 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. */ |
| |
| 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. |
| NOTE: Unlike comp_unit_head.length, this length includes |
| initial_length_size. |
| If the DIE refers to a DWO file, this is always of the original die, |
| not the DWO file. */ |
| sect_offset offset; |
| unsigned int length : 29; |
| |
| /* Flag indicating this compilation unit will be read in before |
| any of the current compilation units are processed. */ |
| unsigned int queued : 1; |
| |
| /* This flag will be set 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-zero if this CU is from .debug_types. */ |
| unsigned int is_debug_types : 1; |
| |
| /* The section this CU/TU lives in. |
| If the DIE refers to a DWO file, this is always the original die, |
| not the DWO file. */ |
| struct dwarf2_section_info *info_or_types_section; |
| |
| /* Set to non-NULL iff this CU is currently loaded. When it gets freed out |
| of the CU cache it gets reset to NULL again. */ |
| struct dwarf2_cu *cu; |
| |
| /* The corresponding objfile. |
| 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. |
| Otherwise the 'quick' field is active. */ |
| union |
| { |
| /* The partial symbol table associated with this compilation unit, |
| or NULL for unread partial units. */ |
| struct partial_symtab *psymtab; |
| |
| /* Data needed by the "quick" functions. */ |
| struct dwarf2_per_cu_quick_data *quick; |
| } v; |
| |
| union |
| { |
| /* The CUs we import using DW_TAG_imported_unit. This is filled in |
| while reading psymtabs, used to compute the psymtab dependencies, |
| and then cleared. Then it is filled in again while reading full |
| symbols, and only deleted when the objfile is destroyed. */ |
| VEC (dwarf2_per_cu_ptr) *imported_symtabs; |
| |
| /* 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; |
| } s; |
| }; |
| |
| /* 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 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. */ |
| |
| 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 info; |
| 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; |
| VEC (dwarf2_section_info_def) *types; |
| }; |
| |
| /* Common bits of DWO CUs/TUs. */ |
| |
| struct dwo_unit |
| { |
| /* Backlink to the containing struct dwo_file. */ |
| struct dwo_file *dwo_file; |
| |
| /* The "id" that distinguishes this CU/TU. |
| .debug_info calls this "dwo_id", .debug_types calls this "signature". |
| Since signatures came first, we stick with it for consistency. */ |
| ULONGEST signature; |
| |
| /* The section this CU/TU lives in, in the DWO file. */ |
| struct dwarf2_section_info *info_or_types_section; |
| |
| /* Same as dwarf2_per_cu_data:{offset,length} but for the DWO section. */ |
| sect_offset offset; |
| unsigned int length; |
| |
| /* For types, offset in the type's DIE of the type defined by this TU. */ |
| cu_offset type_offset_in_tu; |
| }; |
| |
| /* Data for one DWO file. */ |
| |
| struct dwo_file |
| { |
| /* The DW_AT_GNU_dwo_name attribute. |
| We don't manage space for this, it's an attribute. */ |
| const char *dwo_name; |
| |
| /* The bfd, when the file is open. Otherwise this is NULL. */ |
| bfd *dwo_bfd; |
| |
| /* Section info for this file. */ |
| struct dwo_sections sections; |
| |
| /* Table of CUs in the file. |
| Each element is a struct dwo_unit. */ |
| htab_t cus; |
| |
| /* Table of TUs in the file. |
| Each element is a struct dwo_unit. */ |
| htab_t tus; |
| }; |
| |
| /* Struct used to pass misc. parameters to read_die_and_children, et |
| al. which are used for both .debug_info and .debug_types dies. |
| All parameters here are unchanging for the life of the call. This |
| struct exists to abstract away the constant parameters of die reading. */ |
| |
| struct die_reader_specs |
| { |
| /* die_section->asection->owner. */ |
| bfd* abfd; |
| |
| /* The CU of the DIE we are parsing. */ |
| struct dwarf2_cu *cu; |
| |
| /* Non-NULL if reading a DWO file. */ |
| struct dwo_file *dwo_file; |
| |
| /* The section the die comes from. |
| This is either .debug_info or .debug_types, or the .dwo variants. */ |
| struct dwarf2_section_info *die_section; |
| |
| /* die_section->buffer. */ |
| gdb_byte *buffer; |
| |
| /* 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. */ |
| struct line_header |
| { |
| unsigned int total_length; |
| unsigned short version; |
| unsigned int header_length; |
| unsigned char minimum_instruction_length; |
| unsigned char maximum_ops_per_instruction; |
| unsigned char default_is_stmt; |
| int line_base; |
| unsigned char line_range; |
| unsigned char opcode_base; |
| |
| /* standard_opcode_lengths[i] is the number of operands for the |
| standard opcode whose value is i. This means that |
| standard_opcode_lengths[0] is unused, and the last meaningful |
| element is standard_opcode_lengths[opcode_base - 1]. */ |
| unsigned char *standard_opcode_lengths; |
| |
| /* The include_directories table. NOTE! These strings are not |
| allocated with xmalloc; instead, they are pointers into |
| debug_line_buffer. If you try to free them, `free' will get |
| indigestion. */ |
| unsigned int num_include_dirs, include_dirs_size; |
| char **include_dirs; |
| |
| /* The file_names table. NOTE! These strings are not allocated |
| with xmalloc; instead, they are pointers into debug_line_buffer. |
| Don't try to free them directly. */ |
| unsigned int num_file_names, file_names_size; |
| struct file_entry |
| { |
| char *name; |
| unsigned int dir_index; |
| unsigned int mod_time; |
| unsigned int length; |
| int included_p; /* Non-zero if referenced by the Line Number Program. */ |
| struct symtab *symtab; /* The associated symbol table, if any. */ |
| } *file_names; |
| |
| /* The start and end of the statement program following this |
| header. These point into dwarf2_per_objfile->line_buffer. */ |
| gdb_byte *statement_program_start, *statement_program_end; |
| }; |
| |
| /* When we construct a partial symbol table entry we only |
| need this much information. */ |
| struct partial_die_info |
| { |
| /* Offset of this DIE. */ |
| sect_offset offset; |
| |
| /* DWARF-2 tag for this DIE. */ |
| ENUM_BITFIELD(dwarf_tag) tag : 16; |
| |
| /* Assorted flags describing the data found in this DIE. */ |
| unsigned int has_children : 1; |
| unsigned int is_external : 1; |
| unsigned int is_declaration : 1; |
| unsigned int has_type : 1; |
| unsigned int has_specification : 1; |
| unsigned int has_pc_info : 1; |
| unsigned int may_be_inlined : 1; |
| |
| /* Flag set if the SCOPE field of this structure has been |
| computed. */ |
| unsigned int scope_set : 1; |
| |
| /* Flag set if the DIE has a byte_size attribute. */ |
| unsigned int has_byte_size : 1; |
| |
| /* Flag set if any of the DIE's children are template arguments. */ |
| unsigned int has_template_arguments : 1; |
| |
| /* Flag set if fixup_partial_die has been called on this die. */ |
| unsigned int fixup_called : 1; |
| |
| /* The name of this DIE. Normally the value of DW_AT_name, but |
| sometimes a default name for unnamed DIEs. */ |
| char *name; |
| |
| /* The linkage name, if present. */ |
| const char *linkage_name; |
| |
| /* 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; |
| |
| /* 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; |
| CORE_ADDR highpc; |
| |
| /* Pointer into the info_buffer (or types_buffer) pointing at the target of |
| DW_AT_sibling, if any. */ |
| /* NOTE: This member isn't strictly necessary, read_partial_die could |
| return DW_AT_sibling values to its caller load_partial_dies. */ |
| gdb_byte *sibling; |
| |
| /* If HAS_SPECIFICATION, the offset of the DIE referred to by |
| DW_AT_specification (or DW_AT_abstract_origin or |
| DW_AT_extension). */ |
| sect_offset spec_offset; |
| |
| /* Pointers to this DIE's parent, first child, and next sibling, |
| if any. */ |
| struct partial_die_info *die_parent, *die_child, *die_sibling; |
| }; |
| |
| /* This data structure holds the information of an abbrev. */ |
| struct abbrev_info |
| { |
| unsigned int number; /* number identifying abbrev */ |
| enum dwarf_tag tag; /* dwarf tag */ |
| unsigned short has_children; /* boolean */ |
| unsigned short num_attrs; /* number of attributes */ |
| struct attr_abbrev *attrs; /* an array of attribute descriptions */ |
| struct abbrev_info *next; /* next in chain */ |
| }; |
| |
| struct attr_abbrev |
| { |
| ENUM_BITFIELD(dwarf_attribute) name : 16; |
| 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 |
| { |
| ENUM_BITFIELD(dwarf_attribute) name : 16; |
| ENUM_BITFIELD(dwarf_form) form : 15; |
| |
| /* Has DW_STRING already been updated by dwarf2_canonicalize_name? This |
| field should be in u.str (existing only for DW_STRING) but it is kept |
| here for better struct attribute alignment. */ |
| unsigned int string_is_canonical : 1; |
| |
| union |
| { |
| char *str; |
| struct dwarf_block *blk; |
| ULONGEST unsnd; |
| LONGEST snd; |
| CORE_ADDR addr; |
| struct signatured_type *signatured_type; |
| } |
| u; |
| }; |
| |
| /* This data structure holds a complete die structure. */ |
| struct die_info |
| { |
| /* DWARF-2 tag for this DIE. */ |
| ENUM_BITFIELD(dwarf_tag) tag : 16; |
| |
| /* Number of attributes */ |
| unsigned char num_attrs; |
| |
| /* True if we're presently building the full type name for the |
| type derived from this DIE. */ |
| unsigned char building_fullname : 1; |
| |
| /* Abbrev number */ |
| unsigned int abbrev; |
| |
| /* Offset in .debug_info or .debug_types section. */ |
| 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 |
| this node; and all the children of a given node are chained |
| together via their SIBLING fields. */ |
| struct die_info *child; /* Its first child, if any. */ |
| struct die_info *sibling; /* Its next sibling, if any. */ |
| struct die_info *parent; /* Its parent, if any. */ |
| |
| /* An array of attributes, with NUM_ATTRS elements. There may be |
| zero, but it's not common and zero-sized arrays are not |
| sufficiently portable C. */ |
| struct attribute attrs[1]; |
| }; |
| |
| /* Get at parts of an attribute structure. */ |
| |
| #define DW_STRING(attr) ((attr)->u.str) |
| #define DW_STRING_IS_CANONICAL(attr) ((attr)->string_is_canonical) |
| #define DW_UNSND(attr) ((attr)->u.unsnd) |
| #define DW_BLOCK(attr) ((attr)->u.blk) |
| #define DW_SND(attr) ((attr)->u.snd) |
| #define DW_ADDR(attr) ((attr)->u.addr) |
| #define DW_SIGNATURED_TYPE(attr) ((attr)->u.signatured_type) |
| |
| /* Blocks are a bunch of untyped bytes. */ |
| struct dwarf_block |
| { |
| unsigned int size; |
| |
| /* Valid only if SIZE is not zero. */ |
| gdb_byte *data; |
| }; |
| |
| #ifndef ATTR_ALLOC_CHUNK |
| #define ATTR_ALLOC_CHUNK 4 |
| #endif |
| |
| /* Allocate fields for structs, unions and enums in this size. */ |
| #ifndef DW_FIELD_ALLOC_CHUNK |
| #define DW_FIELD_ALLOC_CHUNK 4 |
| #endif |
| |
| /* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte, |
| but this would require a corresponding change in unpack_field_as_long |
| and friends. */ |
| static int bits_per_byte = 8; |
| |
| /* The routines that read and process dies for a C struct or C++ class |
| pass lists of data member fields and lists of member function fields |
| in an instance of a field_info structure, as defined below. */ |
| struct field_info |
| { |
| /* List of data member and baseclasses fields. */ |
| struct nextfield |
| { |
| struct nextfield *next; |
| int accessibility; |
| int virtuality; |
| struct field field; |
| } |
| *fields, *baseclasses; |
| |
| /* Number of fields (including baseclasses). */ |
| int nfields; |
| |
| /* Number of baseclasses. */ |
| int nbaseclasses; |
| |
| /* Set if the accesibility of one of the fields is not public. */ |
| int non_public_fields; |
| |
| /* Member function fields array, entries are allocated in the order they |
| are encountered in the object file. */ |
| struct nextfnfield |
| { |
| struct nextfnfield *next; |
| struct fn_field fnfield; |
| } |
| *fnfields; |
| |
| /* Member function fieldlist array, contains name of possibly overloaded |
| member function, number of overloaded member functions and a pointer |
| to the head of the member function field chain. */ |
| struct fnfieldlist |
| { |
| char *name; |
| int length; |
| struct nextfnfield *head; |
| } |
| *fnfieldlists; |
| |
| /* Number of entries in the fnfieldlists array. */ |
| int nfnfields; |
| |
| /* typedefs defined inside this class. TYPEDEF_FIELD_LIST contains head of |
| a NULL terminated list of TYPEDEF_FIELD_LIST_COUNT elements. */ |
| struct typedef_field_list |
| { |
| struct typedef_field field; |
| struct typedef_field_list *next; |
| } |
| *typedef_field_list; |
| unsigned typedef_field_list_count; |
| }; |
| |
| /* One item on the queue of compilation units to read in full symbols |
| for. */ |
| struct dwarf2_queue_item |
| { |
| struct dwarf2_per_cu_data *per_cu; |
| enum language pretend_language; |
| struct dwarf2_queue_item *next; |
| }; |
| |
| /* The current queue. */ |
| static struct dwarf2_queue_item *dwarf2_queue, *dwarf2_queue_tail; |
| |
| /* Loaded secondary compilation units are kept in memory until they |
| have not been referenced for the processing of this many |
| compilation units. Set this to zero to disable caching. Cache |
| sizes of up to at least twenty will improve startup time for |
| typical inter-CU-reference binaries, at an obvious memory cost. */ |
| static int dwarf2_max_cache_age = 5; |
| static void |
| show_dwarf2_max_cache_age (struct ui_file *file, int from_tty, |
| struct cmd_list_element *c, const char *value) |
| { |
| fprintf_filtered (file, _("The upper bound on the age of cached " |
| "dwarf2 compilation units is %s.\n"), |
| value); |
| } |
| |
| |
| /* Various complaints about symbol reading that don't abort the process. */ |
| |
| static void |
| dwarf2_statement_list_fits_in_line_number_section_complaint (void) |
| { |
| complaint (&symfile_complaints, |
| _("statement list doesn't fit in .debug_line section")); |
| } |
| |
| static void |
| dwarf2_debug_line_missing_file_complaint (void) |
| { |
| complaint (&symfile_complaints, |
| _(".debug_line section has line data without a file")); |
| } |
| |
| static void |
| dwarf2_debug_line_missing_end_sequence_complaint (void) |
| { |
| complaint (&symfile_complaints, |
| _(".debug_line section has line " |
| "program sequence without an end")); |
| } |
| |
| static void |
| dwarf2_complex_location_expr_complaint (void) |
| { |
| complaint (&symfile_complaints, _("location expression too complex")); |
| } |
| |
| static void |
| dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2, |
| int arg3) |
| { |
| complaint (&symfile_complaints, |
| _("const value length mismatch for '%s', got %d, expected %d"), |
| arg1, arg2, arg3); |
| } |
| |
| static void |
| dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section) |
| { |
| complaint (&symfile_complaints, |
| _("debug info runs off end of %s section" |
| " [in module %s]"), |
| section->asection->name, |
| bfd_get_filename (section->asection->owner)); |
| } |
| |
| static void |
| dwarf2_macro_malformed_definition_complaint (const char *arg1) |
| { |
| complaint (&symfile_complaints, |
| _("macro debug info contains a " |
| "malformed macro definition:\n`%s'"), |
| arg1); |
| } |
| |
| static void |
| dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2) |
| { |
| complaint (&symfile_complaints, |
| _("invalid attribute class or form for '%s' in '%s'"), |
| arg1, arg2); |
| } |
| |
| /* local function prototypes */ |
| |
| static void dwarf2_locate_sections (bfd *, asection *, void *); |
| |
| static void dwarf2_create_include_psymtab (char *, struct partial_symtab *, |
| struct objfile *); |
| |
| static void dwarf2_find_base_address (struct die_info *die, |
| struct dwarf2_cu *cu); |
| |
| static void dwarf2_build_psymtabs_hard (struct objfile *); |
| |
| static void scan_partial_symbols (struct partial_die_info *, |
| CORE_ADDR *, CORE_ADDR *, |
| int, struct dwarf2_cu *); |
| |
| static void add_partial_symbol (struct partial_die_info *, |
| struct dwarf2_cu *); |
| |
| static void add_partial_namespace (struct partial_die_info *pdi, |
| CORE_ADDR *lowpc, CORE_ADDR *highpc, |
| int need_pc, struct dwarf2_cu *cu); |
| |
| static void add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc, |
| CORE_ADDR *highpc, int need_pc, |
| struct dwarf2_cu *cu); |
| |
| static void add_partial_enumeration (struct partial_die_info *enum_pdi, |
| struct dwarf2_cu *cu); |
| |
| static void add_partial_subprogram (struct partial_die_info *pdi, |
| CORE_ADDR *lowpc, CORE_ADDR *highpc, |
| int need_pc, struct dwarf2_cu *cu); |
| |
| static void dwarf2_psymtab_to_symtab (struct partial_symtab *); |
| |
| static void psymtab_to_symtab_1 (struct partial_symtab *); |
| |
| static struct abbrev_info *abbrev_table_lookup_abbrev |
| (const struct abbrev_table *, unsigned int); |
| |
| static struct abbrev_table *abbrev_table_read_table |
| (struct dwarf2_section_info *, sect_offset); |
| |
| static void abbrev_table_free (struct abbrev_table *); |
| |
| static void abbrev_table_free_cleanup (void *); |
| |
| static void dwarf2_read_abbrevs (struct dwarf2_cu *, |
| struct dwarf2_section_info *); |
| |
| static void dwarf2_free_abbrev_table (void *); |
| |
| static unsigned int peek_abbrev_code (bfd *, gdb_byte *); |
| |
| static struct partial_die_info *load_partial_dies |
| (const struct die_reader_specs *, gdb_byte *, int); |
| |
| 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 (sect_offset, |
| struct dwarf2_cu *); |
| |
| static void fixup_partial_die (struct partial_die_info *, |
| 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 int read_1_signed_byte (bfd *, gdb_byte *); |
| |
| static unsigned int read_2_bytes (bfd *, gdb_byte *); |
| |
| static unsigned int read_4_bytes (bfd *, gdb_byte *); |
| |
| static ULONGEST read_8_bytes (bfd *, gdb_byte *); |
| |
| static CORE_ADDR read_address (bfd *, gdb_byte *ptr, struct dwarf2_cu *, |
| unsigned int *); |
| |
| static LONGEST read_initial_length (bfd *, gdb_byte *, unsigned int *); |
| |
| static LONGEST read_checked_initial_length_and_offset |
| (bfd *, gdb_byte *, const struct comp_unit_head *, |
| unsigned int *, unsigned int *); |
| |
| static LONGEST read_offset (bfd *, gdb_byte *, const struct comp_unit_head *, |
| unsigned int *); |
| |
| 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 *); |
| |
| static char *read_indirect_string (bfd *, gdb_byte *, |
| const struct comp_unit_head *, |
| unsigned int *); |
| |
| static ULONGEST read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *); |
| |
| static LONGEST read_signed_leb128 (bfd *, gdb_byte *, unsigned int *); |
| |
| static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *, gdb_byte *, |
| unsigned int *); |
| |
| static char *read_str_index (const struct die_reader_specs *reader, |
| struct dwarf2_cu *cu, ULONGEST str_index); |
| |
| static void set_cu_language (unsigned int, struct dwarf2_cu *); |
| |
| static struct attribute *dwarf2_attr (struct die_info *, unsigned int, |
| struct dwarf2_cu *); |
| |
| static struct attribute *dwarf2_attr_no_follow (struct die_info *, |
| unsigned int); |
| |
| static int dwarf2_flag_true_p (struct die_info *die, unsigned name, |
| struct dwarf2_cu *cu); |
| |
| static int die_is_declaration (struct die_info *, struct dwarf2_cu *cu); |
| |
| static struct die_info *die_specification (struct die_info *die, |
| struct dwarf2_cu **); |
| |
| 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, |
| struct dwarf2_cu *cu); |
| |
| static void dwarf_decode_lines (struct line_header *, const char *, |
| struct dwarf2_cu *, struct partial_symtab *, |
| int); |
| |
| static void dwarf2_start_subfile (char *, const char *, const char *); |
| |
| static void dwarf2_start_symtab (struct dwarf2_cu *, |
| char *, char *, CORE_ADDR); |
| |
| static struct symbol *new_symbol (struct die_info *, struct type *, |
| struct dwarf2_cu *); |
| |
| static struct symbol *new_symbol_full (struct die_info *, struct type *, |
| struct dwarf2_cu *, struct symbol *); |
| |
| static void dwarf2_const_value (struct attribute *, struct symbol *, |
| struct dwarf2_cu *); |
| |
| static void dwarf2_const_value_attr (struct attribute *attr, |
| struct type *type, |
| const char *name, |
| struct obstack *obstack, |
| struct dwarf2_cu *cu, LONGEST *value, |
| gdb_byte **bytes, |
| struct dwarf2_locexpr_baton **baton); |
| |
| static struct type *die_type (struct die_info *, struct dwarf2_cu *); |
| |
| static int need_gnat_info (struct dwarf2_cu *); |
| |
| static struct type *die_descriptive_type (struct die_info *, |
| struct dwarf2_cu *); |
| |
| static void set_descriptive_type (struct type *, struct die_info *, |
| struct dwarf2_cu *); |
| |
| static struct type *die_containing_type (struct die_info *, |
| struct dwarf2_cu *); |
| |
| static struct type *lookup_die_type (struct die_info *, struct attribute *, |
| struct dwarf2_cu *); |
| |
| 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 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, |
| struct dwarf2_cu *cu); |
| |
| static void read_file_scope (struct die_info *, struct dwarf2_cu *); |
| |
| static void read_type_unit_scope (struct die_info *, struct dwarf2_cu *); |
| |
| static void read_func_scope (struct die_info *, struct dwarf2_cu *); |
| |
| static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *); |
| |
| static void read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu); |
| |
| static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *, |
| struct dwarf2_cu *, struct partial_symtab *); |
| |
| static int dwarf2_get_pc_bounds (struct die_info *, |
| CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *, |
| struct partial_symtab *); |
| |
| static void get_scope_pc_bounds (struct die_info *, |
| CORE_ADDR *, CORE_ADDR *, |
| struct dwarf2_cu *); |
| |
| static void dwarf2_record_block_ranges (struct die_info *, struct block *, |
| CORE_ADDR, struct dwarf2_cu *); |
| |
| static void dwarf2_add_field (struct field_info *, struct die_info *, |
| struct dwarf2_cu *); |
| |
| static void dwarf2_attach_fields_to_type (struct field_info *, |
| struct type *, struct dwarf2_cu *); |
| |
| static void dwarf2_add_member_fn (struct field_info *, |
| struct die_info *, struct type *, |
| struct dwarf2_cu *); |
| |
| static void dwarf2_attach_fn_fields_to_type (struct field_info *, |
| struct type *, |
| struct dwarf2_cu *); |
| |
| static void process_structure_scope (struct die_info *, struct dwarf2_cu *); |
| |
| static void read_common_block (struct die_info *, struct dwarf2_cu *); |
| |
| static void read_namespace (struct die_info *die, struct dwarf2_cu *); |
| |
| static void read_module (struct die_info *die, struct dwarf2_cu *cu); |
| |
| static void read_import_statement (struct die_info *die, struct dwarf2_cu *); |
| |
| static struct type *read_module_type (struct die_info *die, |
| struct dwarf2_cu *cu); |
| |
| static const char *namespace_name (struct die_info *die, |
| int *is_anonymous, struct dwarf2_cu *); |
| |
| static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *); |
| |
| 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_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 *, |
| gdb_byte *info_ptr, |
| gdb_byte **new_info_ptr, |
| struct die_info *parent); |
| |
| 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 char *dwarf2_name (struct die_info *die, struct dwarf2_cu *); |
| |
| static const char *dwarf2_full_name (char *name, |
| struct die_info *die, |
| struct dwarf2_cu *cu); |
| |
| static struct die_info *dwarf2_extension (struct die_info *die, |
| struct dwarf2_cu **); |
| |
| static const char *dwarf_tag_name (unsigned int); |
| |
| static const char *dwarf_attr_name (unsigned int); |
| |
| static const char *dwarf_form_name (unsigned int); |
| |
| static char *dwarf_bool_name (unsigned int); |
| |
| static const char *dwarf_type_encoding_name (unsigned int); |
| |
| static struct die_info *sibling_die (struct die_info *); |
| |
| static void dump_die_shallow (struct ui_file *, int indent, struct die_info *); |
| |
| static void dump_die_for_error (struct die_info *); |
| |
| static void dump_die_1 (struct ui_file *, int level, int max_level, |
| struct die_info *); |
| |
| /*static*/ void dump_die (struct die_info *, int max_level); |
| |
| static void store_in_ref_table (struct die_info *, |
| struct dwarf2_cu *); |
| |
| static int is_ref_attr (struct attribute *); |
| |
| static sect_offset dwarf2_get_ref_die_offset (struct attribute *); |
| |
| static LONGEST dwarf2_get_attr_constant_value (struct attribute *, int); |
| |
| static struct die_info *follow_die_ref_or_sig (struct die_info *, |
| struct attribute *, |
| struct dwarf2_cu **); |
| |
| static struct die_info *follow_die_ref (struct die_info *, |
| struct attribute *, |
| struct dwarf2_cu **); |
| |
| static struct die_info *follow_die_sig (struct die_info *, |
| struct attribute *, |
| struct dwarf2_cu **); |
| |
| static struct signatured_type *lookup_signatured_type_at_offset |
| (struct objfile *objfile, |
| struct dwarf2_section_info *section, sect_offset offset); |
| |
| static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu); |
| |
| 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 die_info *dwarf_alloc_die (struct dwarf2_cu *, int); |
| |
| static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int, |
| char *, int); |
| |
| static int attr_form_is_block (struct attribute *); |
| |
| static int attr_form_is_section_offset (struct attribute *); |
| |
| static int attr_form_is_constant (struct attribute *); |
| |
| static void fill_in_loclist_baton (struct dwarf2_cu *cu, |
| struct dwarf2_loclist_baton *baton, |
| struct attribute *attr); |
| |
| static void dwarf2_symbol_mark_computed (struct attribute *attr, |
| struct symbol *sym, |
| 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 *); |
| |
| 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 |
| (sect_offset offset, struct objfile *objfile); |
| |
| static void init_one_comp_unit (struct dwarf2_cu *cu, |
| struct dwarf2_per_cu_data *per_cu); |
| |
| static void prepare_one_comp_unit (struct dwarf2_cu *cu, |
| struct die_info *comp_unit_die, |
| enum language pretend_language); |
| |
| 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 (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_all_type_units (struct objfile *); |
| |
| static void load_full_comp_unit (struct dwarf2_per_cu_data *, |
| enum language); |
| |
| static void process_full_comp_unit (struct dwarf2_per_cu_data *, |
| enum language); |
| |
| 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 *); |
| |
| 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 (sect_offset, |
| struct dwarf2_per_cu_data *per_cu); |
| |
| 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, |
| enum language pretend_language); |
| |
| 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); |
| |
| static char *file_full_name (int file, struct line_header *lh, |
| const char *comp_dir); |
| |
| 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 *, char *, const char *, ULONGEST); |
| |
| static struct dwo_unit *lookup_dwo_type_unit |
| (struct signatured_type *, char *, const char *); |
| |
| static void free_dwo_file_cleanup (void *); |
| |
| static void munmap_section_buffer (struct dwarf2_section_info *); |
| |
| static void process_cu_includes (void); |
| |
| #if WORDS_BIGENDIAN |
| |
| /* Convert VALUE between big- and little-endian. */ |
| static offset_type |
| byte_swap (offset_type value) |
| { |
| offset_type result; |
| |
| result = (value & 0xff) << 24; |
| result |= (value & 0xff00) << 8; |
| result |= (value & 0xff0000) >> 8; |
| result |= (value & 0xff000000) >> 24; |
| return result; |
| } |
| |
| #define MAYBE_SWAP(V) byte_swap (V) |
| |
| #else |
| #define MAYBE_SWAP(V) (V) |
| #endif /* WORDS_BIGENDIAN */ |
| |
| /* The suffix for an index file. */ |
| #define INDEX_SUFFIX ".gdb-index" |
| |
| static const char *dwarf2_physname (char *name, struct die_info *die, |
| struct dwarf2_cu *cu); |
| |
| /* Try to locate the sections we need for DWARF 2 debugging |
| information and return true if we have enough to do something. |
| NAMES points to the dwarf2 section names, or is NULL if the standard |
| ELF names are used. */ |
| |
| int |
| dwarf2_has_info (struct objfile *objfile, |
| const struct dwarf2_debug_sections *names) |
| { |
| dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key); |
| if (!dwarf2_per_objfile) |
| { |
| /* Initialize per-objfile state. */ |
| struct dwarf2_per_objfile *data |
| = obstack_alloc (&objfile->objfile_obstack, sizeof (*data)); |
| |
| memset (data, 0, sizeof (*data)); |
| set_objfile_data (objfile, dwarf2_objfile_data_key, data); |
| dwarf2_per_objfile = data; |
| |
| bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, |
| (void *) names); |
| dwarf2_per_objfile->objfile = objfile; |
| } |
| return (dwarf2_per_objfile->info.asection != NULL |
| && dwarf2_per_objfile->abbrev.asection != NULL); |
| } |
| |
| /* When loading sections, we look either for uncompressed section or for |
| compressed section names. */ |
| |
| static int |
| section_is_p (const char *section_name, |
| const struct dwarf2_section_names *names) |
| { |
| if (names->normal != NULL |
| && strcmp (section_name, names->normal) == 0) |
| return 1; |
| if (names->compressed != NULL |
| && strcmp (section_name, names->compressed) == 0) |
| return 1; |
| return 0; |
| } |
| |
| /* This function is mapped across the sections and remembers the |
| offset and size of each of the debugging sections we are interested |
| in. */ |
| |
| static void |
| dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames) |
| { |
| const struct dwarf2_debug_sections *names; |
| |
| if (vnames == NULL) |
| names = &dwarf2_elf_names; |
| else |
| names = (const struct dwarf2_debug_sections *) vnames; |
| |
| if (section_is_p (sectp->name, &names->info)) |
| { |
| dwarf2_per_objfile->info.asection = sectp; |
| dwarf2_per_objfile->info.size = bfd_get_section_size (sectp); |
| } |
| else if (section_is_p (sectp->name, &names->abbrev)) |
| { |
| dwarf2_per_objfile->abbrev.asection = sectp; |
| dwarf2_per_objfile->abbrev.size = bfd_get_section_size (sectp); |
| } |
| else if (section_is_p (sectp->name, &names->line)) |
| { |
| dwarf2_per_objfile->line.asection = sectp; |
| dwarf2_per_objfile->line.size = bfd_get_section_size (sectp); |
| } |
| else if (section_is_p (sectp->name, &names->loc)) |
| { |
| dwarf2_per_objfile->loc.asection = sectp; |
| dwarf2_per_objfile->loc.size = bfd_get_section_size (sectp); |
| } |
| else if (section_is_p (sectp->name, &names->macinfo)) |
| { |
| dwarf2_per_objfile->macinfo.asection = sectp; |
| dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp); |
| } |
| else if (section_is_p (sectp->name, &names->macro)) |
| { |
| dwarf2_per_objfile->macro.asection = sectp; |
| dwarf2_per_objfile->macro.size = bfd_get_section_size (sectp); |
| } |
| else if (section_is_p (sectp->name, &names->str)) |
| { |
| 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; |
| dwarf2_per_objfile->frame.size = bfd_get_section_size (sectp); |
| } |
| else if (section_is_p (sectp->name, &names->eh_frame)) |
| { |
| flagword aflag = bfd_get_section_flags (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); |
| } |
| } |
| else if (section_is_p (sectp->name, &names->ranges)) |
| { |
| dwarf2_per_objfile->ranges.asection = sectp; |
| dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp); |
| } |
| else if (section_is_p (sectp->name, &names->types)) |
| { |
| 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, dwarf2_per_objfile->types, |
| &type_section); |
| } |
| else if (section_is_p (sectp->name, &names->gdb_index)) |
| { |
| dwarf2_per_objfile->gdb_index.asection = sectp; |
| dwarf2_per_objfile->gdb_index.size = bfd_get_section_size (sectp); |
| } |
| |
| if ((bfd_get_section_flags (abfd, sectp) & SEC_LOAD) |
| && bfd_section_vma (abfd, sectp) == 0) |
| 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 = sectp->owner; |
| #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, |
| or not present. */ |
| |
| static int |
| dwarf2_section_empty_p (struct dwarf2_section_info *info) |
| { |
| return info->asection == NULL || info->size == 0; |
| } |
| |
| /* 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) |
| { |
| 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; |
| |
| /* Note that ABFD may not be from OBJFILE, e.g. a DWO section. */ |
| abfd = sectp->owner; |
| |
| /* Check if the file has a 4-byte header indicating compression. */ |
| if (info->size > sizeof (header) |
| && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0 |
| && 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 (); |
| |
| /* 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) |
| { |
| info->buffer = bfd_mmap (abfd, 0, info->size, PROT_READ, |
| MAP_PRIVATE, sectp->filepos, |
| &info->map_addr, &info->map_len); |
| |
| if ((caddr_t)info->buffer != MAP_FAILED) |
| { |
| #if HAVE_POSIX_MADVISE |
| posix_madvise (info->map_addr, info->map_len, POSIX_MADV_WILLNEED); |
| #endif |
| return; |
| } |
| } |
| #endif |
| |
| /* If we get here, we are a normal, not-compressed section. */ |
| info->buffer = buf |
| = obstack_alloc (&objfile->objfile_obstack, info->size); |
| |
| /* When debugging .o files, we may need to apply relocations; see |
| http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html . |
| We never compress sections in .o files, so we only need to |
| try this when the section is not compressed. */ |
| retbuf = symfile_relocate_debug_section (objfile, sectp, buf); |
| if (retbuf != NULL) |
| { |
| info->buffer = retbuf; |
| return; |
| } |
| |
| if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 |
| || bfd_bread (buf, info->size, abfd) != info->size) |
| error (_("Dwarf Error: Can't read DWARF data from '%s'"), |
| bfd_get_filename (abfd)); |
| } |
| |
| /* A helper function that returns the size of a section in a safe way. |
| If you are positive that the section has been read before using the |
| size, then it is safe to refer to the dwarf2_section_info object's |
| "size" field directly. In other cases, you must call this |
| function, because for compressed sections the size field is not set |
| correctly until the section has been read. */ |
| |
| static bfd_size_type |
| dwarf2_section_size (struct objfile *objfile, |
| struct dwarf2_section_info *info) |
| { |
| if (!info->readin) |
| dwarf2_read_section (objfile, info); |
| return info->size; |
| } |
| |
| /* Fill in SECTP, BUFP and SIZEP with section info, given OBJFILE and |
| SECTION_NAME. */ |
| |
| void |
| dwarf2_get_section_info (struct objfile *objfile, |
| enum dwarf2_section_enum sect, |
| asection **sectp, gdb_byte **bufp, |
| bfd_size_type *sizep) |
| { |
| struct dwarf2_per_objfile *data |
| = objfile_data (objfile, dwarf2_objfile_data_key); |
| struct dwarf2_section_info *info; |
| |
| /* We may see an objfile without any DWARF, in which case we just |
| return nothing. */ |
| if (data == NULL) |
| { |
| *sectp = NULL; |
| *bufp = NULL; |
| *sizep = 0; |
| return; |
| } |
| switch (sect) |
| { |
| case DWARF2_DEBUG_FRAME: |
| info = &data->frame; |
| break; |
| case DWARF2_EH_FRAME: |
| info = &data->eh_frame; |
| break; |
| default: |
| gdb_assert_not_reached ("unexpected section"); |
| } |
| |
| dwarf2_read_section (objfile, info); |
| |
| *sectp = info->asection; |
| *bufp = info->buffer; |
| *sizep = info->size; |
| } |
| |
| |
| /* 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; |
| |
| /* The file names from the line table after being run through |
| gdb_realpath. These are computed lazily. */ |
| const char **real_names; |
| }; |
| |
| /* When using the index (and thus not using psymtabs), each CU has an |
| object of this type. This is used to hold information needed by |
| the various "quick" methods. */ |
| struct dwarf2_per_cu_quick_data |
| { |
| /* The file table. This can be NULL if there was no file table |
| or it's currently not read in. |
| NOTE: This points into dwarf2_per_objfile->quick_file_names_table. */ |
| struct quick_file_names *file_names; |
| |
| /* The corresponding symbol table. This is NULL if symbols for this |
| CU have not yet been read. */ |
| struct symtab *symtab; |
| |
| /* A temporary mark bit used when iterating over all CUs in |
| expand_symtabs_matching. */ |
| unsigned int mark : 1; |
| |
| /* True if we've tried to read the file table and found there isn't one. |
| There will be no point in trying to read it again next time. */ |
| 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 |
| hash_file_name_entry (const void *e) |
| { |
| const struct quick_file_names *file_data = e; |
| |
| return hash_stmt_list_entry (&file_data->hash); |
| } |
| |
| /* Equality function for a quick_file_names. */ |
| |
| static int |
| 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 eq_stmt_list_entry (&ea->hash, &eb->hash); |
| } |
| |
| /* Delete function for a quick_file_names. */ |
| |
| static void |
| delete_file_name_entry (void *e) |
| { |
| struct quick_file_names *file_data = e; |
| int i; |
| |
| for (i = 0; i < file_data->num_file_names; ++i) |
| { |
| xfree ((void*) file_data->file_names[i]); |
| if (file_data->real_names) |
| xfree ((void*) file_data->real_names[i]); |
| } |
| |
| /* The space for the struct itself lives on objfile_obstack, |
| so we don't free it here. */ |
| } |
| |
| /* Create a quick_file_names hash table. */ |
| |
| static htab_t |
| create_quick_file_names_table (unsigned int nr_initial_entries) |
| { |
| return htab_create_alloc (nr_initial_entries, |
| hash_file_name_entry, eq_file_name_entry, |
| delete_file_name_entry, xcalloc, xfree); |
| } |
| |
| /* Read in PER_CU->CU. This function is unrelated to symtabs, symtab would |
| have to be created afterwards. You should call age_cached_comp_units after |
| processing PER_CU->CU. dw2_setup must have been already called. */ |
| |
| static void |
| load_cu (struct dwarf2_per_cu_data *per_cu) |
| { |
| if (per_cu->is_debug_types) |
| load_full_type_unit (per_cu); |
| else |
| 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. */ |
| |
| static void |
| dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu) |
| { |
| struct cleanup *back_to; |
| |
| /* Skip type_unit_groups, reading the type units they contain |
| is handled elsewhere. */ |
| if (IS_TYPE_UNIT_GROUP (per_cu)) |
| return; |
| |
| back_to = make_cleanup (dwarf2_release_queue, NULL); |
| |
| 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 (); |
| |
| /* Age the cache, releasing compilation units that have not |
| been used recently. */ |
| age_cached_comp_units (); |
| |
| do_cleanups (back_to); |
| } |
| |
| /* Ensure that the symbols for PER_CU have been read in. OBJFILE is |
| the objfile from which this CU came. Returns the resulting symbol |
| table. */ |
| |
| static struct symtab * |
| 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 (per_cu); |
| process_cu_includes (); |
| do_cleanups (back_to); |
| } |
| return per_cu->v.quick->symtab; |
| } |
| |
| /* 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) |
| { |
| if (index >= dwarf2_per_objfile->n_comp_units) |
| { |
| index -= dwarf2_per_objfile->n_comp_units; |
| 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]; |
| } |
| |
| /* 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. |
| |
| This is intended for loops like: |
| |
| 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); |
| |
| ...; |
| } |
| */ |
| |
| 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; |
| } |
| |
| 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. */ |
| |
| static int |
| extract_cu_value (const char *bytes, ULONGEST *result) |
| { |
| if (sizeof (ULONGEST) < 8) |
| { |
| int i; |
| |
| /* Ignore the upper 4 bytes if they are all zero. */ |
| for (i = 0; i < 4; ++i) |
| if (bytes[i + 4] != 0) |
| return 0; |
| |
| *result = extract_unsigned_integer (bytes, 4, BFD_ENDIAN_LITTLE); |
| } |
| else |
| *result = extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE); |
| return 1; |
| } |
| |
| /* 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. */ |
| |
| static int |
| create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list, |
| offset_type cu_list_elements) |
| { |
| 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) |
| { |
| 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; |
| cu_list += 2 * 8; |
| |
| the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack, |
| struct dwarf2_per_cu_data); |
| the_cu->offset.sect_off = offset; |
| the_cu->length = length; |
| the_cu->objfile = objfile; |
| the_cu->info_or_types_section = &dwarf2_per_objfile->info; |
| the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack, |
| struct dwarf2_per_cu_quick_data); |
| dwarf2_per_objfile->all_comp_units[i / 2] = the_cu; |
| } |
| |
| return 1; |
| } |
| |
| /* Create the signatured type hash table from the index. */ |
| |
| static int |
| create_signatured_type_table_from_index (struct objfile *objfile, |
| struct dwarf2_section_info *section, |
| const gdb_byte *bytes, |
| offset_type elements) |
| { |
| offset_type i; |
| htab_t sig_types_hash; |
| |
| dwarf2_per_objfile->n_type_units = elements / 3; |
| dwarf2_per_objfile->all_type_units |
| = obstack_alloc (&objfile->objfile_obstack, |
| 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 *sig_type; |
| ULONGEST offset, type_offset_in_tu, signature; |
| void **slot; |
| |
| if (!extract_cu_value (bytes, &offset) |
| || !extract_cu_value (bytes + 8, &type_offset_in_tu)) |
| return 0; |
| signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE); |
| bytes += 3 * 8; |
| |
| sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack, |
| struct signatured_type); |
| 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, sig_type, INSERT); |
| *slot = sig_type; |
| |
| 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 |
| populate the objfile's psymtabs_addrmap. */ |
| |
| static void |
| create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index) |
| { |
| const gdb_byte *iter, *end; |
| struct obstack temp_obstack; |
| struct addrmap *mutable_map; |
| struct cleanup *cleanup; |
| CORE_ADDR baseaddr; |
| |
| obstack_init (&temp_obstack); |
| cleanup = make_cleanup_obstack_free (&temp_obstack); |
| mutable_map = addrmap_create_mutable (&temp_obstack); |
| |
| iter = index->address_table; |
| end = iter + index->address_table_size; |
| |
| baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); |
| |
| while (iter < end) |
| { |
| ULONGEST hi, lo, cu_index; |
| lo = extract_unsigned_integer (iter, 8, BFD_ENDIAN_LITTLE); |
| iter += 8; |
| hi = extract_unsigned_integer (iter, 8, BFD_ENDIAN_LITTLE); |
| iter += 8; |
| cu_index = extract_unsigned_integer (iter, 4, BFD_ENDIAN_LITTLE); |
| iter += 4; |
| |
| addrmap_set_empty (mutable_map, lo + baseaddr, hi + baseaddr - 1, |
| dw2_get_cu (cu_index)); |
| } |
| |
| objfile->psymtabs_addrmap = addrmap_create_fixed (mutable_map, |
| &objfile->objfile_obstack); |
| do_cleanups (cleanup); |
| } |
| |
| /* The hash function for strings in the mapped index. This is the same as |
| SYMBOL_HASH_NEXT, but we keep a separate copy to maintain control over the |
| implementation. This is necessary because the hash function is tied to the |
| format of the mapped index file. The hash values do not have to match with |
| SYMBOL_HASH_NEXT. |
| |
| Use INT_MAX for INDEX_VERSION if you generate the current index format. */ |
| |
| static hashval_t |
| mapped_index_string_hash (int index_version, const void *p) |
| { |
| const unsigned char *str = (const unsigned char *) p; |
| hashval_t r = 0; |
| unsigned char c; |
| |
| while ((c = *str++) != 0) |
| { |
| if (index_version >= 5) |
| c = tolower (c); |
| r = r * 67 + c - 113; |
| } |
| |
| return r; |
| } |
| |
| /* Find a slot in the mapped index INDEX for the object named NAME. |
| If NAME is found, set *VEC_OUT to point to the CU vector in the |
| constant pool and return 1. If NAME cannot be found, return 0. */ |
| |
| static int |
| find_slot_in_mapped_hash (struct mapped_index *index, const char *name, |
| offset_type **vec_out) |
| { |
| struct cleanup *back_to = make_cleanup (null_cleanup, 0); |
| offset_type hash; |
| offset_type slot, step; |
| int (*cmp) (const char *, const char *); |
| |
| if (current_language->la_language == language_cplus |
| || current_language->la_language == language_java |
| || current_language->la_language == language_fortran) |
| { |
| /* NAME is already canonical. Drop any qualifiers as .gdb_index does |
| not contain any. */ |
| const char *paren = strchr (name, '('); |
| |
| if (paren) |
| { |
| char *dup; |
| |
| dup = xmalloc (paren - name + 1); |
| memcpy (dup, name, paren - name); |
| dup[paren - name] = 0; |
| |
| make_cleanup (xfree, dup); |
| name = dup; |
| } |
| } |
| |
| /* Index version 4 did not support case insensitive searches. But the |
| 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 |
| ? 5 : index->version), |
| name); |
| |
| slot = hash & (index->symbol_table_slots - 1); |
| step = ((hash * 17) & (index->symbol_table_slots - 1)) | 1; |
| cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp); |
| |
| for (;;) |
| { |
| /* Convert a slot number to an offset into the table. */ |
| offset_type i = 2 * slot; |
| const char *str; |
| if (index->symbol_table[i] == 0 && index->symbol_table[i + 1] == 0) |
| { |
| do_cleanups (back_to); |
| return 0; |
| } |
| |
| str = index->constant_pool + MAYBE_SWAP (index->symbol_table[i]); |
| if (!cmp (name, str)) |
| { |
| *vec_out = (offset_type *) (index->constant_pool |
| + MAYBE_SWAP (index->symbol_table[i + 1])); |
| do_cleanups (back_to); |
| return 1; |
| } |
| |
| slot = (slot + step) & (index->symbol_table_slots - 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) |
| { |
| char *addr; |
| struct mapped_index *map; |
| 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)) |
| 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) |
| return 0; |
| |
| dwarf2_read_section (objfile, &dwarf2_per_objfile->gdb_index); |
| |
| addr = dwarf2_per_objfile->gdb_index.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. */ |
| if (version < 4) |
| { |
| static int warning_printed = 0; |
| if (!warning_printed) |
| { |
| warning (_("Skipping obsolete .gdb_index section in %s."), |
| objfile->name); |
| warning_printed = 1; |
| } |
| return 0; |
| } |
| /* Index version 4 uses a different hash function than index version |
| 5 and later. |
| |
| Versions earlier than 6 did not emit psymbols for inlined |
| functions. Using these files will cause GDB not to be able to |
| set breakpoints on inlined functions by name, so we ignore these |
| indices unless the user has done |
| "set use-deprecated-index-sections on". */ |
| if (version < 6 && !use_deprecated_index_sections) |
| { |
| 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."), |
| objfile->name); |
| warning_printed = 1; |
| } |
| return 0; |
| } |
| /* Indexes with higher version than the one supported by GDB may be no |
| longer backward compatible. */ |
| if (version > 7) |
| return 0; |
| |
| map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index); |
| map->version = version; |
| map->total_size = dwarf2_per_objfile->gdb_index.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); |
| ++i; |
| |
| 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]); |
| map->address_table_size = (MAYBE_SWAP (metadata[i + 1]) |
| - MAYBE_SWAP (metadata[i])); |
| ++i; |
| |
| map->symbol_table = (offset_type *) (addr + MAYBE_SWAP (metadata[i])); |
| map->symbol_table_slots = ((MAYBE_SWAP (metadata[i + 1]) |
| - MAYBE_SWAP (metadata[i])) |
| / (2 * sizeof (offset_type))); |
| ++i; |
| |
| map->constant_pool = addr + MAYBE_SWAP (metadata[i]); |
| |
| /* Don't use the index if it's empty. */ |
| if (map->symbol_table_slots == 0) |
| return 0; |
| |
| if (!create_cus_from_index (objfile, cu_list, cu_list_elements)) |
| return 0; |
| |
| if (types_list_elements) |
| { |
| struct dwarf2_section_info *section; |
| |
| /* We can only handle a single .debug_types when we have an |
| index. */ |
| if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) != 1) |
| return 0; |
| |
| 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_addrmap_from_index (objfile, map); |
| |
| dwarf2_per_objfile->index_table = map; |
| dwarf2_per_objfile->using_index = 1; |
| dwarf2_per_objfile->quick_file_names_table = |
| create_quick_file_names_table (dwarf2_per_objfile->n_comp_units); |
| |
| return 1; |
| } |
| |
| /* A helper for the "quick" functions which sets the global |
| dwarf2_per_objfile according to OBJFILE. */ |
| |
| static void |
| dw2_setup (struct objfile *objfile) |
| { |
| dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key); |
| gdb_assert (dwarf2_per_objfile); |
| } |
| |
| /* Reader function for dw2_build_type_unit_groups. */ |
| |
| static void |
| dw2_build_type_unit_groups_reader (const struct die_reader_specs *reader, |
| gdb_byte *info_ptr, |
| struct die_info *type_unit_die, |
| int has_children, |
| void *data) |
| { |
| struct dwarf2_cu *cu = reader->cu; |
| struct attribute *attr; |
| struct type_unit_group *tu_group; |
| |
| gdb_assert (data == NULL); |
| |
| if (! has_children) |
| return; |
| |
| attr = dwarf2_attr_no_follow (type_unit_die, DW_AT_stmt_list); |
| /* Call this for its side-effect of creating the associated |
| struct type_unit_group if it doesn't already exist. */ |
| tu_group = get_type_unit_group (cu, attr); |
| } |
| |
| /* Build dwarf2_per_objfile->type_unit_groups. |
| This function may be called multiple times. */ |
| |
| static void |
| dw2_build_type_unit_groups (void) |
| { |
| if (dwarf2_per_objfile->type_unit_groups == NULL) |
| build_type_unit_groups (dw2_build_type_unit_groups_reader, NULL); |
| } |
| |
| /* die_reader_func for dw2_get_file_names. */ |
| |
| 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) |
| { |
| 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; |
| int i; |
| char *name, *comp_dir; |
| void **slot; |
| struct quick_file_names *qfn; |
| unsigned int line_offset; |
| |
| /* 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) |
| { |
| this_cu->v.quick->no_file_data = 1; |
| return; |
| } |
| |
| /* 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; |
| |
| 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); |
| if (attr) |
| { |
| struct quick_file_names find_entry; |
| |
| line_offset = DW_UNSND (attr); |
| |
| /* We may have already read in this line header (TU line header sharing). |
| If we have we're done. */ |
| 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) |
| { |
| lh_cu->v.quick->file_names = *slot; |
| return; |
| } |
| |
| lh = dwarf_decode_line_header (line_offset, cu); |
| } |
| if (lh == NULL) |
| { |
| lh_cu->v.quick->no_file_data = 1; |
| return; |
| } |
| |
| qfn = obstack_alloc (&objfile->objfile_obstack, sizeof (*qfn)); |
| 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); |
| |
| qfn->num_file_names = lh->num_file_names; |
| qfn->file_names = obstack_alloc (&objfile->objfile_obstack, |
| lh->num_file_names * sizeof (char *)); |
| for (i = 0; i < lh->num_file_names; ++i) |
| qfn->file_names[i] = file_full_name (i + 1, lh, comp_dir); |
| qfn->real_names = NULL; |
| |
| free_line_header (lh); |
| |
| 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->s.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 |
| real path for a given file name from the line table. */ |
| |
| static const char * |
| dw2_get_real_path (struct objfile *objfile, |
| struct quick_file_names *qfn, int index) |
| { |
| if (qfn->real_names == NULL) |
| qfn->real_names = OBSTACK_CALLOC (&objfile->objfile_obstack, |
| qfn->num_file_names, sizeof (char *)); |
| |
| if (qfn->real_names[index] == NULL) |
| qfn->real_names[index] = gdb_realpath (qfn->file_names[index]); |
| |
| return qfn->real_names[index]; |
| } |
| |
| static struct symtab * |
| dw2_find_last_source_symtab (struct objfile *objfile) |
| { |
| int index; |
| |
| dw2_setup (objfile); |
| index = dwarf2_per_objfile->n_comp_units - 1; |
| return dw2_instantiate_symtab (dw2_get_cu (index)); |
| } |
| |
| /* Traversal function for dw2_forget_cached_source_info. */ |
| |
| static int |
| dw2_free_cached_file_names (void **slot, void *info) |
| { |
| struct quick_file_names *file_data = (struct quick_file_names *) *slot; |
| |
| if (file_data->real_names) |
| { |
| int i; |
| |
| for (i = 0; i < file_data->num_file_names; ++i) |
| { |
| xfree ((void*) file_data->real_names[i]); |
| file_data->real_names[i] = NULL; |
| } |
| } |
| |
| return 1; |
| } |
| |
| static void |
| dw2_forget_cached_source_info (struct objfile *objfile) |
| { |
| dw2_setup (objfile); |
| |
| htab_traverse_noresize (dwarf2_per_objfile->quick_file_names_table, |
| dw2_free_cached_file_names, NULL); |
| } |
| |
| /* Helper function for dw2_map_symtabs_matching_filename that expands |
| the symtabs and calls the iterator. */ |
| |
| static int |
| dw2_map_expand_apply (struct objfile *objfile, |
| struct dwarf2_per_cu_data *per_cu, |
| const char *name, |
| const char *full_path, const char *real_path, |
| int (*callback) (struct symtab *, void *), |
| void *data) |
| { |
| struct symtab *last_made = objfile->symtabs; |
| |
| /* Don't visit already-expanded CUs. */ |
| if (per_cu->v.quick->symtab) |
| return 0; |
| |
| /* This may expand more than one symtab, and we want to iterate over |
| all of them. */ |
| dw2_instantiate_symtab (per_cu); |
| |
| return iterate_over_some_symtabs (name, full_path, real_path, callback, data, |
| objfile->symtabs, last_made); |
| } |
| |
| /* Implementation of the map_symtabs_matching_filename method. */ |
| |
| static int |
| dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name, |
| const char *full_path, const char *real_path, |
| int (*callback) (struct symtab *, void *), |
| void *data) |
| { |
| int i; |
| const char *name_basename = lbasename (name); |
| int name_len = strlen (name); |
| int is_abs = IS_ABSOLUTE_PATH (name); |
| |
| dw2_setup (objfile); |
| |
| dw2_build_type_unit_groups (); |
| |
| for (i = 0; i < (dwarf2_per_objfile->n_comp_units |
| + dwarf2_per_objfile->n_type_unit_groups); ++i) |
| { |
| int j; |
| 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. */ |
| if (per_cu->v.quick->symtab) |
| continue; |
| |
| file_data = dw2_get_file_names (objfile, per_cu); |
| if (file_data == NULL) |
| continue; |
| |
| for (j = 0; j < file_data->num_file_names; ++j) |
| { |
| const char *this_name = file_data->file_names[j]; |
| |
| if (FILENAME_CMP (name, this_name) == 0 |
| || (!is_abs && compare_filenames_for_search (this_name, |
| name, name_len))) |
| { |
| if (dw2_map_expand_apply (objfile, per_cu, |
| name, full_path, real_path, |
| callback, data)) |
| return 1; |
| } |
| |
| /* 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) |
| { |
| 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 |
| || (!is_abs |
| && compare_filenames_for_search (this_real_name, |
| name, name_len)))) |
| { |
| if (dw2_map_expand_apply (objfile, per_cu, |
| name, full_path, real_path, |
| callback, data)) |
| return 1; |
| } |
| } |
| |
| if (real_path != NULL) |
| { |
| const char *this_real_name = dw2_get_real_path (objfile, |
| file_data, j); |
| |
| if (this_real_name != NULL |
| && (FILENAME_CMP (real_path, this_real_name) == 0 |
| || (!is_abs |
| && compare_filenames_for_search (this_real_name, |
| name, name_len)))) |
| { |
| if (dw2_map_expand_apply (objfile, per_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) |
| { |
| /* We do all the work in the pre_expand_symtabs_matching hook |
| instead. */ |
| return NULL; |
| } |
| |
| /* A helper function that expands all symtabs that hold an object |
| named NAME. If WANT_SPECIFIC_BLOCK is non-zero, only look for |
| symbols in block BLOCK_KIND. */ |
| |
| static void |
| dw2_do_expand_symtabs_matching (struct objfile *objfile, |
| int want_specific_block, |
| enum block_enum block_kind, |
| const char *name, domain_enum domain) |
| { |
| struct mapped_index *index; |
| |
| dw2_setup (objfile); |
| |
| index = dwarf2_per_objfile->index_table; |
| |
| /* index_table is NULL if OBJF_READNOW. */ |
| if (index) |
| { |
| offset_type *vec; |
| |
| if (find_slot_in_mapped_hash (index, name, &vec)) |
| { |
| offset_type i, len = MAYBE_SWAP (*vec); |
| for (i = 0; i < len; ++i) |
| { |
| offset_type cu_index_and_attrs = MAYBE_SWAP (vec[i + 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 = block_kind != 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); |
| |
| if (want_specific_block |
| && index->version >= 7 |
| && want_static != is_static) |
| 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 (domain) |
| { |
| 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; |
| } |
| } |
| |
| dw2_instantiate_symtab (per_cu); |
| } |
| } |
| } |
| } |
| |
| static void |
| dw2_pre_expand_symtabs_matching (struct objfile *objfile, |
| enum block_enum block_kind, const char *name, |
| domain_enum domain) |
| { |
| dw2_do_expand_symtabs_matching (objfile, 1, block_kind, name, domain); |
| } |
| |
| static void |
| dw2_print_stats (struct objfile *objfile) |
| { |
| int i, count; |
| |
| dw2_setup (objfile); |
| count = 0; |
| 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); |
| |
| if (!per_cu->v.quick->symtab) |
| ++count; |
| } |
| printf_filtered (_(" Number of unread CUs: %d\n"), count); |
| } |
| |
| static void |
| dw2_dump (struct objfile *objfile) |
| { |
| /* Nothing worth printing. */ |
| } |
| |
| static void |
| dw2_relocate (struct objfile *objfile, struct section_offsets *new_offsets, |
| struct section_offsets *delta) |
| { |
| /* There's nothing to relocate here. */ |
| } |
| |
| static void |
| dw2_expand_symtabs_for_function (struct objfile *objfile, |
| const char *func_name) |
| { |
| /* Note: It doesn't matter what we pass for block_kind here. */ |
| dw2_do_expand_symtabs_matching (objfile, 0, GLOBAL_BLOCK, func_name, |
| VAR_DOMAIN); |
| } |
| |
| static void |
| dw2_expand_all_symtabs (struct objfile *objfile) |
| { |
| int i; |
| |
| dw2_setup (objfile); |
| |
| 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); |
| |
| dw2_instantiate_symtab (per_cu); |
| } |
| } |
| |
| static void |
| dw2_expand_symtabs_with_filename (struct objfile *objfile, |
| const char *filename) |
| { |
| int i; |
| |
| dw2_setup (objfile); |
| |
| /* We don't need to consider type units here. |
| This is only called for examining code, e.g. expand_line_sal. |
| There can be an order of magnitude (or more) more type units |
| than comp units, and we avoid them if we can. */ |
| |
| 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 quick_file_names *file_data; |
| |
| /* 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; |
| |
| 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) |
| { |
| 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); |
| |
| /* index_table is NULL if OBJF_READNOW. */ |
| if (!dwarf2_per_objfile->index_table) |
| { |
| struct symtab *s; |
| |
| 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; |
| } |
| return NULL; |
| } |
| |
| if (!find_slot_in_mapped_hash (dwarf2_per_objfile->index_table, |
| name, &vec)) |
| return NULL; |
| |
| /* Note that this just looks at the very first one named NAME -- but |
| actually we are looking for a function. find_main_filename |
| 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 (GDB_INDEX_CU_VALUE (MAYBE_SWAP (vec[1]))); |
| |
| if (per_cu->v.quick->symtab != NULL) |
| return per_cu->v.quick->symtab->filename; |
| |
| init_cutu_and_read_dies (per_cu, NULL, 0, 0, |
| dw2_get_primary_filename_reader, &filename); |
| |
| return filename; |
| } |
| |
| static void |
| dw2_map_matching_symbols (const char * name, domain_enum namespace, |
| struct objfile |