X-Git-Url: https://gitweb.dragonflybsd.org/~tuxillo/dragonfly.git/blobdiff_plain/6b445a628d016cb98daa614ade67aed0ed1d4ec0..ef5ccd6c41237a870dd7242b72b006d6bd42cd07:/contrib/gdb-7/gdb/dwarf2read.c
diff --git a/contrib/gdb-7/gdb/dwarf2read.c b/contrib/gdb-7/gdb/dwarf2read.c
index 8c81c8a78d..6151b3d515 100644
--- a/contrib/gdb-7/gdb/dwarf2read.c
+++ b/contrib/gdb-7/gdb/dwarf2read.c
@@ -1,6 +1,6 @@
/* DWARF 2 debugging format support for GDB.
- Copyright (C) 1994-2012 Free Software Foundation, Inc.
+ Copyright (C) 1994-2013 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
@@ -24,8 +24,13 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
+/* FIXME: Various die-reading functions need to be more careful with
+ reading off the end of the section.
+ E.g., load_partial_dies, read_partial_die. */
+
#include "defs.h"
#include "bfd.h"
+#include "elf-bfd.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "objfiles.h"
@@ -55,79 +60,35 @@
#include "completer.h"
#include "vec.h"
#include "c-lang.h"
+#include "go-lang.h"
#include "valprint.h"
+#include "gdbcore.h" /* for gnutarget */
+#include "gdb/gdb-index.h"
#include
+#include "gdb_bfd.h"
+#include "f-lang.h"
+#include "source.h"
#include
#include "gdb_string.h"
#include "gdb_assert.h"
#include
-#ifdef HAVE_ZLIB_H
-#include
-#endif
-#ifdef HAVE_MMAP
-#include
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void *) -1)
-#endif
-#endif
typedef struct symbol *symbolp;
DEF_VEC_P (symbolp);
-#if 0
-/* .debug_info header for a compilation unit
- Because of alignment constraints, this structure has padding and cannot
- be mapped directly onto the beginning of the .debug_info section. */
-typedef struct comp_unit_header
- {
- unsigned int length; /* length of the .debug_info
- contribution */
- unsigned short version; /* version number -- 2 for DWARF
- version 2 */
- unsigned int abbrev_offset; /* offset into .debug_abbrev section */
- unsigned char addr_size; /* byte size of an address -- 4 */
- }
-_COMP_UNIT_HEADER;
-#define _ACTUAL_COMP_UNIT_HEADER_SIZE 11
-#endif
-
-/* .debug_line statement program prologue
- Because of alignment constraints, this structure has padding and cannot
- be mapped directly onto the beginning of the .debug_info section. */
-typedef struct statement_prologue
- {
- unsigned int total_length; /* byte length of the statement
- information */
- unsigned short version; /* version number -- 2 for DWARF
- version 2 */
- unsigned int prologue_length; /* # bytes between prologue &
- stmt program */
- unsigned char minimum_instruction_length; /* byte size of
- smallest instr */
- unsigned char default_is_stmt; /* initial value of is_stmt
- register */
- char line_base;
- unsigned char line_range;
- unsigned char opcode_base; /* number assigned to first special
- opcode */
- unsigned char *standard_opcode_lengths;
- }
-_STATEMENT_PROLOGUE;
+/* When non-zero, print basic high level tracing messages.
+ This is in contrast to the low level DIE reading of dwarf2_die_debug. */
+static int dwarf2_read_debug = 0;
/* When non-zero, dump DIEs after they are read in. */
-static int dwarf2_die_debug = 0;
+static unsigned int dwarf2_die_debug = 0;
/* When non-zero, cross-check physname against demangler. */
static int check_physname = 0;
-static int pagesize;
-
-/* When set, the file that we're processing is known to have debugging
- info for C++ namespaces. GCC 3.3.x did not produce this information,
- but later versions do. */
-
-static int processing_has_namespace_info;
+/* When non-zero, do not reject deprecated .gdb_index sections. */
+static int use_deprecated_index_sections = 0;
static const struct objfile_data *dwarf2_objfile_data_key;
@@ -136,10 +97,6 @@ struct dwarf2_section_info
asection *asection;
gdb_byte *buffer;
bfd_size_type size;
- /* Not NULL if the section was actually mmapped. */
- void *map_addr;
- /* Page aligned size of mmapped area. */
- bfd_size_type map_len;
/* True if we have tried to read this section. */
int readin;
};
@@ -153,6 +110,28 @@ typedef uint32_t offset_type;
DEF_VEC_I (offset_type);
+/* Ensure only legit values are used. */
+#define DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE(cu_index, value) \
+ do { \
+ gdb_assert ((unsigned int) (value) <= 1); \
+ GDB_INDEX_SYMBOL_STATIC_SET_VALUE((cu_index), (value)); \
+ } while (0)
+
+/* Ensure only legit values are used. */
+#define DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE(cu_index, value) \
+ do { \
+ gdb_assert ((value) >= GDB_INDEX_SYMBOL_KIND_TYPE \
+ && (value) <= GDB_INDEX_SYMBOL_KIND_OTHER); \
+ GDB_INDEX_SYMBOL_KIND_SET_VALUE((cu_index), (value)); \
+ } while (0)
+
+/* Ensure we don't use more than the alloted nuber of bits for the CU. */
+#define DW2_GDB_INDEX_CU_SET_VALUE(cu_index, value) \
+ do { \
+ gdb_assert (((value) & ~GDB_INDEX_CU_MASK) == 0); \
+ GDB_INDEX_CU_SET_VALUE((cu_index), (value)); \
+ } while (0)
+
/* A description of the mapped index. The file format is described in
a comment by the code that writes the index. */
struct mapped_index
@@ -179,6 +158,12 @@ struct mapped_index
const char *constant_pool;
};
+typedef struct dwarf2_per_cu_data *dwarf2_per_cu_ptr;
+DEF_VEC_P (dwarf2_per_cu_ptr);
+
+/* Collection of data recorded per objfile.
+ This hangs off of dwarf2_objfile_data_key. */
+
struct dwarf2_per_objfile
{
struct dwarf2_section_info info;
@@ -189,6 +174,7 @@ struct dwarf2_per_objfile
struct dwarf2_section_info macro;
struct dwarf2_section_info str;
struct dwarf2_section_info ranges;
+ struct dwarf2_section_info addr;
struct dwarf2_section_info frame;
struct dwarf2_section_info eh_frame;
struct dwarf2_section_info gdb_index;
@@ -198,7 +184,7 @@ struct dwarf2_per_objfile
/* Back link. */
struct objfile *objfile;
- /* A list of all the compilation units. This is used to locate
+ /* Table of all the compilation units. This is used to locate
the target compilation unit of a particular reference. */
struct dwarf2_per_cu_data **all_comp_units;
@@ -206,19 +192,54 @@ struct dwarf2_per_objfile
int n_comp_units;
/* The number of .debug_types-related CUs. */
- int n_type_comp_units;
+ int n_type_units;
- /* The .debug_types-related CUs. */
- struct dwarf2_per_cu_data **type_comp_units;
+ /* The .debug_types-related CUs (TUs). */
+ struct signatured_type **all_type_units;
- /* A chain of compilation units that are currently read in, so that
- they can be freed later. */
- struct dwarf2_per_cu_data *read_in_chain;
+ /* The number of entries in all_type_unit_groups. */
+ int n_type_unit_groups;
+
+ /* Table of type unit groups.
+ This exists to make it easy to iterate over all CUs and TU groups. */
+ struct type_unit_group **all_type_unit_groups;
+
+ /* Table of struct type_unit_group objects.
+ The hash key is the DW_AT_stmt_list value. */
+ htab_t type_unit_groups;
/* A table mapping .debug_types signatures to its signatured_type entry.
This is NULL if the .debug_types section hasn't been read in yet. */
htab_t signatured_types;
+ /* Type unit statistics, to see how well the scaling improvements
+ are doing. */
+ struct tu_stats
+ {
+ int nr_uniq_abbrev_tables;
+ int nr_symtabs;
+ int nr_symtab_sharers;
+ int nr_stmt_less_type_units;
+ } tu_stats;
+
+ /* A chain of compilation units that are currently read in, so that
+ they can be freed later. */
+ struct dwarf2_per_cu_data *read_in_chain;
+
+ /* A table mapping DW_AT_dwo_name values to struct dwo_file objects.
+ This is NULL if the table hasn't been allocated yet. */
+ htab_t dwo_files;
+
+ /* Non-zero if we've check for whether there is a DWP file. */
+ int dwp_checked;
+
+ /* The DWP file if there is one, or NULL. */
+ struct dwp_file *dwp_file;
+
+ /* The shared '.dwz' file, if one exists. This is used when the
+ original data was compressed using 'dwz -m'. */
+ struct dwz_file *dwz_file;
+
/* A flag indicating wether this objfile has a section loaded at a
VMA of 0. */
int has_section_at_zero;
@@ -231,24 +252,25 @@ struct dwarf2_per_objfile
struct mapped_index *index_table;
/* When using index_table, this keeps track of all quick_file_names entries.
- TUs can share line table entries with CUs or other TUs, and there can be
- a lot more TUs than unique line tables, so we maintain a separate table
- of all line table entries to support the sharing. */
+ TUs typically share line table entries with a CU, so we maintain a
+ separate table of all line table entries to support the sharing.
+ Note that while there can be way more TUs than CUs, we've already
+ sorted all the TUs into "type unit groups", grouped by their
+ DW_AT_stmt_list value. Therefore the only sharing done here is with a
+ CU and its associated TU group if there is one. */
htab_t quick_file_names_table;
/* Set during partial symbol reading, to prevent queueing of full
symbols. */
int reading_partial_symbols;
- /* Table mapping type .debug_info DIE offsets to types.
+ /* Table mapping type DIEs to their struct type *.
This is NULL if not allocated yet.
- It (currently) makes sense to allocate debug_types_type_hash lazily.
- To keep things simple we allocate both lazily. */
- htab_t debug_info_type_hash;
+ The mapping is done via (CU/TU signature + DIE offset) -> type. */
+ htab_t die_type_hash;
- /* Table mapping type .debug_types DIE offsets to types.
- This is NULL if not allocated yet. */
- htab_t debug_types_type_hash;
+ /* The CUs we recently read. */
+ VEC (dwarf2_per_cu_ptr) *just_read_cus;
};
static struct dwarf2_per_objfile *dwarf2_per_objfile;
@@ -258,7 +280,8 @@ static struct dwarf2_per_objfile *dwarf2_per_objfile;
/* Note that if the debugging section has been compressed, it might
have a name like .zdebug_info. */
-static const struct dwarf2_debug_sections dwarf2_elf_names = {
+static const struct dwarf2_debug_sections dwarf2_elf_names =
+{
{ ".debug_info", ".zdebug_info" },
{ ".debug_abbrev", ".zdebug_abbrev" },
{ ".debug_line", ".zdebug_line" },
@@ -268,18 +291,45 @@ static const struct dwarf2_debug_sections dwarf2_elf_names = {
{ ".debug_str", ".zdebug_str" },
{ ".debug_ranges", ".zdebug_ranges" },
{ ".debug_types", ".zdebug_types" },
+ { ".debug_addr", ".zdebug_addr" },
{ ".debug_frame", ".zdebug_frame" },
{ ".eh_frame", NULL },
{ ".gdb_index", ".zgdb_index" },
23
};
-/* local data types */
+/* List of DWO/DWP sections. */
+
+static const struct dwop_section_names
+{
+ struct dwarf2_section_names abbrev_dwo;
+ struct dwarf2_section_names info_dwo;
+ struct dwarf2_section_names line_dwo;
+ struct dwarf2_section_names loc_dwo;
+ struct dwarf2_section_names macinfo_dwo;
+ struct dwarf2_section_names macro_dwo;
+ struct dwarf2_section_names str_dwo;
+ struct dwarf2_section_names str_offsets_dwo;
+ struct dwarf2_section_names types_dwo;
+ struct dwarf2_section_names cu_index;
+ struct dwarf2_section_names tu_index;
+}
+dwop_section_names =
+{
+ { ".debug_abbrev.dwo", ".zdebug_abbrev.dwo" },
+ { ".debug_info.dwo", ".zdebug_info.dwo" },
+ { ".debug_line.dwo", ".zdebug_line.dwo" },
+ { ".debug_loc.dwo", ".zdebug_loc.dwo" },
+ { ".debug_macinfo.dwo", ".zdebug_macinfo.dwo" },
+ { ".debug_macro.dwo", ".zdebug_macro.dwo" },
+ { ".debug_str.dwo", ".zdebug_str.dwo" },
+ { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo" },
+ { ".debug_types.dwo", ".zdebug_types.dwo" },
+ { ".debug_cu_index", ".zdebug_cu_index" },
+ { ".debug_tu_index", ".zdebug_tu_index" },
+};
-/* We hold several abbreviation tables in memory at the same time. */
-#ifndef ABBREV_HASH_SIZE
-#define ABBREV_HASH_SIZE 121
-#endif
+/* local data types */
/* The data in a compilation unit header, after target2host
translation, looks like this. */
@@ -289,7 +339,7 @@ struct comp_unit_head
short version;
unsigned char addr_size;
unsigned char signed_addr_p;
- unsigned int abbrev_offset;
+ sect_offset abbrev_offset;
/* Size of file offsets; either 4 or 8. */
unsigned int offset_size;
@@ -299,11 +349,11 @@ struct comp_unit_head
/* Offset to the first byte of this compilation unit header in the
.debug_info section, for resolving relative reference dies. */
- unsigned int offset;
+ sect_offset offset;
/* Offset to first die in this cu from the start of the cu.
This will be the first byte following the compilation unit header. */
- unsigned int first_die_offset;
+ cu_offset first_die_offset;
};
/* Type used for delaying computation of method physnames.
@@ -344,8 +394,6 @@ struct dwarf2_cu
/* Non-zero if base_address has been set. */
int base_known;
- struct function_range *first_fn, *last_fn, *cached_fn;
-
/* The language we are debugging. */
enum language language;
const struct language_defn *language_defn;
@@ -363,13 +411,13 @@ struct dwarf2_cu
distinguish these in buildsym.c. */
struct pending **list_in_scope;
- /* DWARF abbreviation table associated with this compilation unit. */
- struct abbrev_info **dwarf2_abbrevs;
-
- /* Storage for the abbrev table. */
- struct obstack abbrev_obstack;
+ /* The abbrev table for this CU.
+ Normally this points to the abbrev table in the objfile.
+ But if DWO_UNIT is non-NULL this is the abbrev table in the DWO file. */
+ struct abbrev_table *abbrev_table;
- /* Hash table holding all the loaded partial DIEs. */
+ /* Hash table holding all the loaded partial DIEs
+ with partial_die->offset.SECT_OFF as hash. */
htab_t partial_dies;
/* Storage for things with the same lifetime as this read-in compilation
@@ -388,7 +436,8 @@ struct dwarf2_cu
/* How many compilation units ago was this CU last referenced? */
int last_used;
- /* A hash table of die offsets for following references. */
+ /* A hash table of DIE cu_offset for following references with
+ die_info->offset.sect_off as hash. */
htab_t die_hash;
/* Full DIEs if read in. */
@@ -409,62 +458,101 @@ struct dwarf2_cu
/* To be copied to symtab->call_site_htab. */
htab_t call_site_htab;
+ /* Non-NULL if this CU came from a DWO file.
+ There is an invariant here that is important to remember:
+ Except for attributes copied from the top level DIE in the "main"
+ (or "stub") file in preparation for reading the DWO file
+ (e.g., DW_AT_GNU_addr_base), we KISS: there is only *one* CU.
+ Either there isn't a DWO file (in which case this is NULL and the point
+ is moot), or there is and either we're not going to read it (in which
+ case this is NULL) or there is and we are reading it (in which case this
+ is non-NULL). */
+ struct dwo_unit *dwo_unit;
+
+ /* The DW_AT_addr_base attribute if present, zero otherwise
+ (zero is a valid value though).
+ Note this value comes from the stub CU/TU's DIE. */
+ ULONGEST addr_base;
+
+ /* The DW_AT_ranges_base attribute if present, zero otherwise
+ (zero is a valid value though).
+ Note this value comes from the stub CU/TU's DIE.
+ Also note that the value is zero in the non-DWO case so this value can
+ be used without needing to know whether DWO files are in use or not.
+ N.B. This does not apply to DW_AT_ranges appearing in
+ DW_TAG_compile_unit dies. This is a bit of a wart, consider if ever
+ DW_AT_ranges appeared in the DW_TAG_compile_unit of DWO DIEs: then
+ DW_AT_ranges_base *would* have to be applied, and we'd have to care
+ whether the DW_AT_ranges attribute came from the skeleton or DWO. */
+ ULONGEST ranges_base;
+
/* Mark used when releasing cached dies. */
unsigned int mark : 1;
- /* This flag will be set if this compilation unit might include
- inter-compilation-unit references. */
- unsigned int has_form_ref_addr : 1;
-
- /* This flag will be set if this compilation unit includes any
- DW_TAG_namespace DIEs. If we know that there are explicit
- DIEs for namespaces, we don't need to try to infer them
- from mangled names. */
- unsigned int has_namespace_info : 1;
-
/* This CU references .debug_loc. See the symtab->locations_valid field.
This test is imperfect as there may exist optimized debug code not using
any location list and still facing inlining issues if handled as
unoptimized code. For a future better test see GCC PR other/32998. */
-
unsigned int has_loclist : 1;
+
+ /* These cache the results for producer_is_* fields. CHECKED_PRODUCER is set
+ if all the producer_is_* fields are valid. This information is cached
+ because profiling CU expansion showed excessive time spent in
+ producer_is_gxx_lt_4_6. */
+ unsigned int checked_producer : 1;
+ unsigned int producer_is_gxx_lt_4_6 : 1;
+ unsigned int producer_is_gcc_lt_4_3 : 1;
+ unsigned int producer_is_icc : 1;
+
+ /* When set, the file that we're processing is known to have
+ debugging info for C++ namespaces. GCC 3.3.x did not produce
+ this information, but later versions do. */
+
+ unsigned int processing_has_namespace_info : 1;
};
/* Persistent data held for a compilation unit, even when not
processing it. We put a pointer to this structure in the
- read_symtab_private field of the psymtab. If we encounter
- inter-compilation-unit references, we also maintain a sorted
- list of all compilation units. */
+ read_symtab_private field of the psymtab. */
struct dwarf2_per_cu_data
{
- /* The start offset and length of this compilation unit. 2**29-1
- bytes should suffice to store the length of any compilation unit
- - if it doesn't, GDB will fall over anyway.
+ /* The start offset and length of this compilation unit.
NOTE: Unlike comp_unit_head.length, this length includes
- initial_length_size. */
- unsigned int offset;
- unsigned int length : 29;
+ initial_length_size.
+ If the DIE refers to a DWO file, this is always of the original die,
+ not the DWO file. */
+ sect_offset offset;
+ unsigned int length;
/* Flag indicating this compilation unit will be read in before
any of the current compilation units are processed. */
unsigned int queued : 1;
- /* This flag will be set if we need to load absolutely all DIEs
- for this compilation unit, instead of just the ones we think
- are interesting. It gets set if we look for a DIE in the
+ /* This flag will be set when reading partial DIEs if we need to load
+ absolutely all DIEs for this compilation unit, instead of just the ones
+ we think are interesting. It gets set if we look for a DIE in the
hash table and don't find it. */
unsigned int load_all_dies : 1;
- /* Non-null if this CU is from .debug_types; in which case it points
- to the section. Otherwise it's from .debug_info. */
- struct dwarf2_section_info *debug_types_section;
+ /* Non-zero if this CU is from .debug_types. */
+ unsigned int is_debug_types : 1;
+
+ /* Non-zero if this CU is from the .dwz file. */
+ unsigned int is_dwz : 1;
+
+ /* The section this CU/TU lives in.
+ If the DIE refers to a DWO file, this is always the original die,
+ not the DWO file. */
+ struct dwarf2_section_info *info_or_types_section;
/* Set to non-NULL iff this CU is currently loaded. When it gets freed out
of the CU cache it gets reset to NULL again. */
struct dwarf2_cu *cu;
- /* The corresponding objfile. */
+ /* The corresponding objfile.
+ Normally we can get the objfile from dwarf2_per_objfile.
+ However we can enter this file with just a "per_cu" handle. */
struct objfile *objfile;
/* When using partial symbol tables, the 'psymtab' field is active.
@@ -472,47 +560,301 @@ struct dwarf2_per_cu_data
union
{
/* The partial symbol table associated with this compilation unit,
- or NULL for partial units (which do not have an associated
- symtab). */
+ or NULL for unread partial units. */
struct partial_symtab *psymtab;
/* Data needed by the "quick" functions. */
struct dwarf2_per_cu_quick_data *quick;
} v;
+
+ /* The CUs we import using DW_TAG_imported_unit. This is filled in
+ while reading psymtabs, used to compute the psymtab dependencies,
+ and then cleared. Then it is filled in again while reading full
+ symbols, and only deleted when the objfile is destroyed.
+
+ This is also used to work around a difference between the way gold
+ generates .gdb_index version <=7 and the way gdb does. Arguably this
+ is a gold bug. For symbols coming from TUs, gold records in the index
+ the CU that includes the TU instead of the TU itself. This breaks
+ dw2_lookup_symbol: It assumes that if the index says symbol X lives
+ in CU/TU Y, then one need only expand Y and a subsequent lookup in Y
+ will find X. Alas TUs live in their own symtab, so after expanding CU Y
+ we need to look in TU Z to find X. Fortunately, this is akin to
+ DW_TAG_imported_unit, so we just use the same mechanism: For
+ .gdb_index version <=7 this also records the TUs that the CU referred
+ to. Concurrently with this change gdb was modified to emit version 8
+ indices so we only pay a price for gold generated indices. */
+ VEC (dwarf2_per_cu_ptr) *imported_symtabs;
+
+ /* Type units are grouped by their DW_AT_stmt_list entry so that they
+ can share them. If this is a TU, this points to the containing
+ symtab. */
+ struct type_unit_group *type_unit_group;
};
/* Entry in the signatured_types hash table. */
struct signatured_type
{
+ /* The "per_cu" object of this type.
+ N.B.: This is the first member so that it's easy to convert pointers
+ between them. */
+ struct dwarf2_per_cu_data per_cu;
+
+ /* The type's signature. */
ULONGEST signature;
- /* Offset in .debug_types of the type defined by this TU. */
- unsigned int type_offset;
+ /* Offset in the TU of the type's DIE, as read from the TU header.
+ If the definition lives in a DWO file, this value is unusable. */
+ cu_offset type_offset_in_tu;
+
+ /* Offset in the section of the type's DIE.
+ If the definition lives in a DWO file, this is the offset in the
+ .debug_types.dwo section.
+ The value is zero until the actual value is known.
+ Zero is otherwise not a valid section offset. */
+ sect_offset type_offset_in_section;
+};
+
+/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list.
+ This includes type_unit_group and quick_file_names. */
+
+struct stmt_list_hash
+{
+ /* The DWO unit this table is from or NULL if there is none. */
+ struct dwo_unit *dwo_unit;
+
+ /* Offset in .debug_line or .debug_line.dwo. */
+ sect_offset line_offset;
+};
+
+/* Each element of dwarf2_per_objfile->type_unit_groups is a pointer to
+ an object of this type. */
- /* The CU(/TU) of this type. */
+struct type_unit_group
+{
+ /* dwarf2read.c's main "handle" on the symtab.
+ To simplify things we create an artificial CU that "includes" all the
+ type units using this stmt_list so that the rest of the code still has
+ a "per_cu" handle on the symtab.
+ This PER_CU is recognized by having no section. */
+#define IS_TYPE_UNIT_GROUP(per_cu) ((per_cu)->info_or_types_section == NULL)
struct dwarf2_per_cu_data per_cu;
+
+ union
+ {
+ /* The TUs that share this DW_AT_stmt_list entry.
+ This is added to while parsing type units to build partial symtabs,
+ and is deleted afterwards and not used again. */
+ VEC (dwarf2_per_cu_ptr) *tus;
+
+ /* When reading the line table in "quick" functions, we need a real TU.
+ Any will do, we know they all share the same DW_AT_stmt_list entry.
+ For simplicity's sake, we pick the first one. */
+ struct dwarf2_per_cu_data *first_tu;
+ } t;
+
+ /* The primary symtab.
+ Type units in a group needn't all be defined in the same source file,
+ so we create an essentially anonymous symtab as the primary symtab. */
+ struct symtab *primary_symtab;
+
+ /* The data used to construct the hash key. */
+ struct stmt_list_hash hash;
+
+ /* The number of symtabs from the line header.
+ The value here must match line_header.num_file_names. */
+ unsigned int num_symtabs;
+
+ /* The symbol tables for this TU (obtained from the files listed in
+ DW_AT_stmt_list).
+ WARNING: The order of entries here must match the order of entries
+ in the line header. After the first TU using this type_unit_group, the
+ line header for the subsequent TUs is recreated from this. This is done
+ because we need to use the same symtabs for each TU using the same
+ DW_AT_stmt_list value. Also note that symtabs may be repeated here,
+ there's no guarantee the line header doesn't have duplicate entries. */
+ struct symtab **symtabs;
+};
+
+/* These sections are what may appear in a DWO file. */
+
+struct dwo_sections
+{
+ struct dwarf2_section_info abbrev;
+ struct dwarf2_section_info line;
+ struct dwarf2_section_info loc;
+ struct dwarf2_section_info macinfo;
+ struct dwarf2_section_info macro;
+ struct dwarf2_section_info str;
+ struct dwarf2_section_info str_offsets;
+ /* In the case of a virtual DWO file, these two are unused. */
+ struct dwarf2_section_info info;
+ VEC (dwarf2_section_info_def) *types;
+};
+
+/* Common bits of DWO CUs/TUs. */
+
+struct dwo_unit
+{
+ /* Backlink to the containing struct dwo_file. */
+ struct dwo_file *dwo_file;
+
+ /* The "id" that distinguishes this CU/TU.
+ .debug_info calls this "dwo_id", .debug_types calls this "signature".
+ Since signatures came first, we stick with it for consistency. */
+ ULONGEST signature;
+
+ /* The section this CU/TU lives in, in the DWO file. */
+ struct dwarf2_section_info *info_or_types_section;
+
+ /* Same as dwarf2_per_cu_data:{offset,length} but for the DWO section. */
+ sect_offset offset;
+ unsigned int length;
+
+ /* For types, offset in the type's DIE of the type defined by this TU. */
+ cu_offset type_offset_in_tu;
+};
+
+/* Data for one DWO file.
+ This includes virtual DWO files that have been packaged into a
+ DWP file. */
+
+struct dwo_file
+{
+ /* The DW_AT_GNU_dwo_name attribute. This is the hash key.
+ For virtual DWO files the name is constructed from the section offsets
+ of abbrev,line,loc,str_offsets so that we combine virtual DWO files
+ from related CU+TUs. */
+ const char *name;
+
+ /* The bfd, when the file is open. Otherwise this is NULL.
+ This is unused(NULL) for virtual DWO files where we use dwp_file.dbfd. */
+ bfd *dbfd;
+
+ /* Section info for this file. */
+ struct dwo_sections sections;
+
+ /* Table of CUs in the file.
+ Each element is a struct dwo_unit. */
+ htab_t cus;
+
+ /* Table of TUs in the file.
+ Each element is a struct dwo_unit. */
+ htab_t tus;
+};
+
+/* These sections are what may appear in a DWP file. */
+
+struct dwp_sections
+{
+ struct dwarf2_section_info str;
+ struct dwarf2_section_info cu_index;
+ struct dwarf2_section_info tu_index;
+ /* The .debug_info.dwo, .debug_types.dwo, and other sections are referenced
+ by section number. We don't need to record them here. */
+};
+
+/* These sections are what may appear in a virtual DWO file. */
+
+struct virtual_dwo_sections
+{
+ struct dwarf2_section_info abbrev;
+ struct dwarf2_section_info line;
+ struct dwarf2_section_info loc;
+ struct dwarf2_section_info macinfo;
+ struct dwarf2_section_info macro;
+ struct dwarf2_section_info str_offsets;
+ /* Each DWP hash table entry records one CU or one TU.
+ That is recorded here, and copied to dwo_unit.info_or_types_section. */
+ struct dwarf2_section_info info_or_types;
+};
+
+/* Contents of DWP hash tables. */
+
+struct dwp_hash_table
+{
+ uint32_t nr_units, nr_slots;
+ const gdb_byte *hash_table, *unit_table, *section_pool;
+};
+
+/* Data for one DWP file. */
+
+struct dwp_file
+{
+ /* Name of the file. */
+ const char *name;
+
+ /* The bfd, when the file is open. Otherwise this is NULL. */
+ bfd *dbfd;
+
+ /* Section info for this file. */
+ struct dwp_sections sections;
+
+ /* Table of CUs in the file. */
+ const struct dwp_hash_table *cus;
+
+ /* Table of TUs in the file. */
+ const struct dwp_hash_table *tus;
+
+ /* Table of loaded CUs/TUs. Each entry is a struct dwo_unit *. */
+ htab_t loaded_cutus;
+
+ /* Table to map ELF section numbers to their sections. */
+ unsigned int num_sections;
+ asection **elf_sections;
+};
+
+/* This represents a '.dwz' file. */
+
+struct dwz_file
+{
+ /* A dwz file can only contain a few sections. */
+ struct dwarf2_section_info abbrev;
+ struct dwarf2_section_info info;
+ struct dwarf2_section_info str;
+ struct dwarf2_section_info line;
+ struct dwarf2_section_info macro;
+ struct dwarf2_section_info gdb_index;
+
+ /* The dwz's BFD. */
+ bfd *dwz_bfd;
};
/* Struct used to pass misc. parameters to read_die_and_children, et
al. which are used for both .debug_info and .debug_types dies.
All parameters here are unchanging for the life of the call. This
- struct exists to abstract away the constant parameters of die
- reading. */
+ struct exists to abstract away the constant parameters of die reading. */
struct die_reader_specs
{
- /* The bfd of this objfile. */
+ /* die_section->asection->owner. */
bfd* abfd;
/* The CU of the DIE we are parsing. */
struct dwarf2_cu *cu;
- /* Pointer to start of section buffer.
- This is either the start of .debug_info or .debug_types. */
- const gdb_byte *buffer;
+ /* Non-NULL if reading a DWO file (including one packaged into a DWP). */
+ struct dwo_file *dwo_file;
+
+ /* The section the die comes from.
+ This is either .debug_info or .debug_types, or the .dwo variants. */
+ struct dwarf2_section_info *die_section;
+
+ /* die_section->buffer. */
+ gdb_byte *buffer;
+
+ /* The end of the buffer. */
+ const gdb_byte *buffer_end;
};
+/* Type of function passed to init_cutu_and_read_dies, et.al. */
+typedef void (die_reader_func_ftype) (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data);
+
/* The line number information for a compilation unit (found in the
.debug_line section) begins with a "statement program header",
which contains the following information. */
@@ -565,7 +907,7 @@ struct line_header
struct partial_die_info
{
/* Offset of this DIE. */
- unsigned int offset;
+ sect_offset offset;
/* DWARF-2 tag for this DIE. */
ENUM_BITFIELD(dwarf_tag) tag : 16;
@@ -577,6 +919,7 @@ struct partial_die_info
unsigned int has_type : 1;
unsigned int has_specification : 1;
unsigned int has_pc_info : 1;
+ unsigned int may_be_inlined : 1;
/* Flag set if the SCOPE field of this structure has been
computed. */
@@ -591,9 +934,15 @@ struct partial_die_info
/* Flag set if fixup_partial_die has been called on this die. */
unsigned int fixup_called : 1;
+ /* Flag set if DW_TAG_imported_unit uses DW_FORM_GNU_ref_alt. */
+ unsigned int is_dwz : 1;
+
+ /* Flag set if spec_offset uses DW_FORM_GNU_ref_alt. */
+ unsigned int spec_is_dwz : 1;
+
/* The name of this DIE. Normally the value of DW_AT_name, but
sometimes a default name for unnamed DIEs. */
- char *name;
+ const char *name;
/* The linkage name, if present. */
const char *linkage_name;
@@ -601,10 +950,17 @@ struct partial_die_info
/* The scope to prepend to our children. This is generally
allocated on the comp_unit_obstack, so will disappear
when this compilation unit leaves the cache. */
- char *scope;
+ const char *scope;
- /* The location description associated with this DIE, if any. */
- struct dwarf_block *locdesc;
+ /* Some data associated with the partial DIE. The tag determines
+ which field is live. */
+ union
+ {
+ /* The location description associated with this DIE, if any. */
+ struct dwarf_block *locdesc;
+ /* The offset of an import, for DW_TAG_imported_unit. */
+ sect_offset offset;
+ } d;
/* If HAS_PC_INFO, the PC range associated with this DIE. */
CORE_ADDR lowpc;
@@ -619,7 +975,7 @@ struct partial_die_info
/* If HAS_SPECIFICATION, the offset of the DIE referred to by
DW_AT_specification (or DW_AT_abstract_origin or
DW_AT_extension). */
- unsigned int spec_offset;
+ sect_offset spec_offset;
/* Pointers to this DIE's parent, first child, and next sibling,
if any. */
@@ -643,6 +999,27 @@ struct attr_abbrev
ENUM_BITFIELD(dwarf_form) form : 16;
};
+/* Size of abbrev_table.abbrev_hash_table. */
+#define ABBREV_HASH_SIZE 121
+
+/* Top level data structure to contain an abbreviation table. */
+
+struct abbrev_table
+{
+ /* Where the abbrev table came from.
+ This is used as a sanity check when the table is used. */
+ sect_offset offset;
+
+ /* Storage for the abbrev table. */
+ struct obstack abbrev_obstack;
+
+ /* Hash table of abbrevs.
+ This is an array of size ABBREV_HASH_SIZE allocated in abbrev_obstack.
+ It could be statically allocated, but the previous code didn't so we
+ don't either. */
+ struct abbrev_info **abbrevs;
+};
+
/* Attributes have a name and a value. */
struct attribute
{
@@ -656,7 +1033,7 @@ struct attribute
union
{
- char *str;
+ const char *str;
struct dwarf_block *blk;
ULONGEST unsnd;
LONGEST snd;
@@ -683,7 +1060,7 @@ struct die_info
unsigned int abbrev;
/* Offset in .debug_info or .debug_types section. */
- unsigned int offset;
+ sect_offset offset;
/* The dies in a compilation unit form an n-ary tree. PARENT
points to this die's parent; CHILD points to the first child of
@@ -699,14 +1076,6 @@ struct die_info
struct attribute attrs[1];
};
-struct function_range
-{
- const char *name;
- CORE_ADDR lowpc, highpc;
- int seen_line;
- struct function_range *next;
-};
-
/* Get at parts of an attribute structure. */
#define DW_STRING(attr) ((attr)->u.str)
@@ -720,7 +1089,7 @@ struct function_range
/* Blocks are a bunch of untyped bytes. */
struct dwarf_block
{
- unsigned int size;
+ size_t size;
/* Valid only if SIZE is not zero. */
gdb_byte *data;
@@ -778,7 +1147,7 @@ struct field_info
to the head of the member function field chain. */
struct fnfieldlist
{
- char *name;
+ const char *name;
int length;
struct nextfnfield *head;
}
@@ -803,6 +1172,7 @@ struct field_info
struct dwarf2_queue_item
{
struct dwarf2_per_cu_data *per_cu;
+ enum language pretend_language;
struct dwarf2_queue_item *next;
};
@@ -865,11 +1235,13 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
}
static void
-dwarf2_macros_too_long_complaint (struct dwarf2_section_info *section)
+dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section)
{
complaint (&symfile_complaints,
- _("macro info runs off end of `%s' section"),
- section->asection->name);
+ _("debug info runs off end of %s section"
+ " [in module %s]"),
+ section->asection->name,
+ bfd_get_filename (section->asection->owner));
}
static void
@@ -923,57 +1295,56 @@ static void add_partial_subprogram (struct partial_die_info *pdi,
CORE_ADDR *lowpc, CORE_ADDR *highpc,
int need_pc, struct dwarf2_cu *cu);
-static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi,
- gdb_byte *buffer, gdb_byte *info_ptr,
- bfd *abfd, struct dwarf2_cu *cu);
-
-static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
+static void dwarf2_read_symtab (struct partial_symtab *,
+ struct objfile *);
static void psymtab_to_symtab_1 (struct partial_symtab *);
-static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
+static struct abbrev_info *abbrev_table_lookup_abbrev
+ (const struct abbrev_table *, unsigned int);
-static void dwarf2_free_abbrev_table (void *);
+static struct abbrev_table *abbrev_table_read_table
+ (struct dwarf2_section_info *, sect_offset);
-static unsigned int peek_abbrev_code (bfd *, gdb_byte *);
+static void abbrev_table_free (struct abbrev_table *);
+
+static void abbrev_table_free_cleanup (void *);
-static struct abbrev_info *peek_die_abbrev (gdb_byte *, unsigned int *,
- struct dwarf2_cu *);
+static void dwarf2_read_abbrevs (struct dwarf2_cu *,
+ struct dwarf2_section_info *);
+
+static void dwarf2_free_abbrev_table (void *);
-static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
- struct dwarf2_cu *);
+static unsigned int peek_abbrev_code (bfd *, gdb_byte *);
-static struct partial_die_info *load_partial_dies (bfd *,
- gdb_byte *, gdb_byte *,
- int, struct dwarf2_cu *);
+static struct partial_die_info *load_partial_dies
+ (const struct die_reader_specs *, gdb_byte *, int);
-static gdb_byte *read_partial_die (struct partial_die_info *,
- struct abbrev_info *abbrev,
- unsigned int, bfd *,
- gdb_byte *, gdb_byte *,
- struct dwarf2_cu *);
+static gdb_byte *read_partial_die (const struct die_reader_specs *,
+ struct partial_die_info *,
+ struct abbrev_info *,
+ unsigned int,
+ gdb_byte *);
-static struct partial_die_info *find_partial_die (unsigned int,
+static struct partial_die_info *find_partial_die (sect_offset, int,
struct dwarf2_cu *);
static void fixup_partial_die (struct partial_die_info *,
struct dwarf2_cu *);
-static gdb_byte *read_attribute (struct attribute *, struct attr_abbrev *,
- bfd *, gdb_byte *, struct dwarf2_cu *);
-
-static gdb_byte *read_attribute_value (struct attribute *, unsigned,
- bfd *, gdb_byte *, struct dwarf2_cu *);
+static gdb_byte *read_attribute (const struct die_reader_specs *,
+ struct attribute *, struct attr_abbrev *,
+ gdb_byte *);
-static unsigned int read_1_byte (bfd *, gdb_byte *);
+static unsigned int read_1_byte (bfd *, const gdb_byte *);
-static int read_1_signed_byte (bfd *, gdb_byte *);
+static int read_1_signed_byte (bfd *, const gdb_byte *);
-static unsigned int read_2_bytes (bfd *, gdb_byte *);
+static unsigned int read_2_bytes (bfd *, const gdb_byte *);
-static unsigned int read_4_bytes (bfd *, gdb_byte *);
+static unsigned int read_4_bytes (bfd *, const gdb_byte *);
-static ULONGEST read_8_bytes (bfd *, gdb_byte *);
+static ULONGEST read_8_bytes (bfd *, const gdb_byte *);
static CORE_ADDR read_address (bfd *, gdb_byte *ptr, struct dwarf2_cu *,
unsigned int *);
@@ -989,6 +1360,9 @@ static LONGEST read_offset (bfd *, gdb_byte *, const struct comp_unit_head *,
static LONGEST read_offset_1 (bfd *, gdb_byte *, unsigned int);
+static sect_offset read_abbrev_offset (struct dwarf2_section_info *,
+ sect_offset);
+
static gdb_byte *read_n_bytes (bfd *, gdb_byte *, unsigned int);
static char *read_direct_string (bfd *, gdb_byte *, unsigned int *);
@@ -997,11 +1371,17 @@ static char *read_indirect_string (bfd *, gdb_byte *,
const struct comp_unit_head *,
unsigned int *);
-static unsigned long read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *);
+static char *read_indirect_string_from_dwz (struct dwz_file *, LONGEST);
+
+static ULONGEST read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *);
-static long read_signed_leb128 (bfd *, gdb_byte *, unsigned int *);
+static LONGEST read_signed_leb128 (bfd *, gdb_byte *, unsigned int *);
-static gdb_byte *skip_leb128 (bfd *, gdb_byte *);
+static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *, gdb_byte *,
+ unsigned int *);
+
+static char *read_str_index (const struct die_reader_specs *reader,
+ struct dwarf2_cu *cu, ULONGEST str_index);
static void set_cu_language (unsigned int, struct dwarf2_cu *);
@@ -1009,8 +1389,7 @@ static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
struct dwarf2_cu *);
static struct attribute *dwarf2_attr_no_follow (struct die_info *,
- unsigned int,
- struct dwarf2_cu *);
+ unsigned int);
static int dwarf2_flag_true_p (struct die_info *die, unsigned name,
struct dwarf2_cu *cu);
@@ -1025,9 +1404,8 @@ static void free_line_header (struct line_header *lh);
static void add_file_name (struct line_header *, char *, unsigned int,
unsigned int, unsigned int);
-static struct line_header *(dwarf_decode_line_header
- (unsigned int offset,
- bfd *abfd, struct dwarf2_cu *cu));
+static struct line_header *dwarf_decode_line_header (unsigned int offset,
+ struct dwarf2_cu *cu);
static void dwarf_decode_lines (struct line_header *, const char *,
struct dwarf2_cu *, struct partial_symtab *,
@@ -1035,6 +1413,9 @@ static void dwarf_decode_lines (struct line_header *, const char *,
static void dwarf2_start_subfile (char *, const char *, const char *);
+static void dwarf2_start_symtab (struct dwarf2_cu *,
+ const char *, const char *, CORE_ADDR);
+
static struct symbol *new_symbol (struct die_info *, struct type *,
struct dwarf2_cu *);
@@ -1048,7 +1429,7 @@ static void dwarf2_const_value_attr (struct attribute *attr,
struct type *type,
const char *name,
struct obstack *obstack,
- struct dwarf2_cu *cu, long *value,
+ struct dwarf2_cu *cu, LONGEST *value,
gdb_byte **bytes,
struct dwarf2_locexpr_baton **baton);
@@ -1072,7 +1453,7 @@ static struct type *read_type_die (struct die_info *, struct dwarf2_cu *);
static struct type *read_type_die_1 (struct die_info *, struct dwarf2_cu *);
-static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
+static const char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
static char *typename_concat (struct obstack *obs, const char *prefix,
const char *suffix, int physname,
@@ -1139,54 +1520,45 @@ static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
struct dwarf2_cu *);
-static struct die_info *read_comp_unit (gdb_byte *, struct dwarf2_cu *);
-
-static struct die_info *read_die_and_children_1 (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- gdb_byte **new_info_ptr,
- struct die_info *parent);
-
-static struct die_info *read_die_and_children (const struct die_reader_specs *reader,
+static struct die_info *read_die_and_children (const struct die_reader_specs *,
gdb_byte *info_ptr,
gdb_byte **new_info_ptr,
struct die_info *parent);
-static struct die_info *read_die_and_siblings (const struct die_reader_specs *reader,
+static struct die_info *read_die_and_siblings (const struct die_reader_specs *,
gdb_byte *info_ptr,
gdb_byte **new_info_ptr,
struct die_info *parent);
-static gdb_byte *read_full_die (const struct die_reader_specs *reader,
- struct die_info **, gdb_byte *,
- int *);
+static gdb_byte *read_full_die_1 (const struct die_reader_specs *,
+ struct die_info **, gdb_byte *, int *, int);
+
+static gdb_byte *read_full_die (const struct die_reader_specs *,
+ struct die_info **, gdb_byte *, int *);
static void process_die (struct die_info *, struct dwarf2_cu *);
-static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *,
- struct obstack *);
+static const char *dwarf2_canonicalize_name (const char *, struct dwarf2_cu *,
+ struct obstack *);
-static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
+static const char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
-static const char *dwarf2_full_name (char *name,
+static const char *dwarf2_full_name (const char *name,
struct die_info *die,
struct dwarf2_cu *cu);
static struct die_info *dwarf2_extension (struct die_info *die,
struct dwarf2_cu **);
-static char *dwarf_tag_name (unsigned int);
+static const char *dwarf_tag_name (unsigned int);
-static char *dwarf_attr_name (unsigned int);
+static const char *dwarf_attr_name (unsigned int);
-static char *dwarf_form_name (unsigned int);
+static const char *dwarf_form_name (unsigned int);
static char *dwarf_bool_name (unsigned int);
-static char *dwarf_type_encoding_name (unsigned int);
-
-#if 0
-static char *dwarf_cfi_name (unsigned int);
-#endif
+static const char *dwarf_type_encoding_name (unsigned int);
static struct die_info *sibling_die (struct die_info *);
@@ -1204,7 +1576,7 @@ static void store_in_ref_table (struct die_info *,
static int is_ref_attr (struct attribute *);
-static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+static sect_offset dwarf2_get_ref_die_offset (struct attribute *);
static LONGEST dwarf2_get_attr_constant_value (struct attribute *, int);
@@ -1222,33 +1594,25 @@ static struct die_info *follow_die_sig (struct die_info *,
static struct signatured_type *lookup_signatured_type_at_offset
(struct objfile *objfile,
- struct dwarf2_section_info *section,
- unsigned int offset);
+ struct dwarf2_section_info *section, sect_offset offset);
-static void read_signatured_type_at_offset (struct objfile *objfile,
- struct dwarf2_section_info *sect,
- unsigned int offset);
+static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu);
-static void read_signatured_type (struct objfile *,
- struct signatured_type *type_sig);
+static void read_signatured_type (struct signatured_type *);
+
+static struct type_unit_group *get_type_unit_group
+ (struct dwarf2_cu *, struct attribute *);
+
+static void build_type_unit_groups (die_reader_func_ftype *, void *);
/* memory allocation interface */
static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
-static struct abbrev_info *dwarf_alloc_abbrev (struct dwarf2_cu *);
-
static struct die_info *dwarf_alloc_die (struct dwarf2_cu *, int);
-static void initialize_cu_func_list (struct dwarf2_cu *);
-
-static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR,
- struct dwarf2_cu *);
-
-static void dwarf_decode_macros (struct line_header *, unsigned int,
- char *, bfd *, struct dwarf2_cu *,
- struct dwarf2_section_info *,
- int);
+static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int,
+ const char *, int);
static int attr_form_is_block (struct attribute *);
@@ -1264,9 +1628,9 @@ static void dwarf2_symbol_mark_computed (struct attribute *attr,
struct symbol *sym,
struct dwarf2_cu *cu);
-static gdb_byte *skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
- struct abbrev_info *abbrev,
- struct dwarf2_cu *cu);
+static gdb_byte *skip_one_die (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct abbrev_info *abbrev);
static void free_stack_comp_unit (void *);
@@ -1275,36 +1639,38 @@ static hashval_t partial_die_hash (const void *item);
static int partial_die_eq (const void *item_lhs, const void *item_rhs);
static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
- (unsigned int offset, struct objfile *objfile);
-
-static struct dwarf2_per_cu_data *dwarf2_find_comp_unit
- (unsigned int offset, struct objfile *objfile);
+ (sect_offset offset, unsigned int offset_in_dwz, struct objfile *objfile);
static void init_one_comp_unit (struct dwarf2_cu *cu,
- struct objfile *objfile);
+ struct dwarf2_per_cu_data *per_cu);
static void prepare_one_comp_unit (struct dwarf2_cu *cu,
- struct die_info *comp_unit_die);
+ struct die_info *comp_unit_die,
+ enum language pretend_language);
-static void free_one_comp_unit (void *);
+static void free_heap_comp_unit (void *);
static void free_cached_comp_units (void *);
static void age_cached_comp_units (void);
-static void free_one_cached_comp_unit (void *);
+static void free_one_cached_comp_unit (struct dwarf2_per_cu_data *);
static struct type *set_die_type (struct die_info *, struct type *,
struct dwarf2_cu *);
static void create_all_comp_units (struct objfile *);
-static int create_debug_types_hash_table (struct objfile *objfile);
+static int create_all_type_units (struct objfile *);
static void load_full_comp_unit (struct dwarf2_per_cu_data *,
- struct objfile *);
+ enum language);
+
+static void process_full_comp_unit (struct dwarf2_per_cu_data *,
+ enum language);
-static void process_full_comp_unit (struct dwarf2_per_cu_data *);
+static void process_full_type_unit (struct dwarf2_per_cu_data *,
+ enum language);
static void dwarf2_add_dependence (struct dwarf2_cu *,
struct dwarf2_per_cu_data *);
@@ -1313,7 +1679,7 @@ static void dwarf2_mark (struct dwarf2_cu *);
static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
-static struct type *get_die_type_at_offset (unsigned int,
+static struct type *get_die_type_at_offset (sect_offset,
struct dwarf2_per_cu_data *per_cu);
static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
@@ -1321,29 +1687,52 @@ static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
static void dwarf2_release_queue (void *dummy);
static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
- struct objfile *objfile);
+ enum language pretend_language);
-static void process_queue (struct objfile *objfile);
+static int maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
+ struct dwarf2_per_cu_data *per_cu,
+ enum language pretend_language);
+
+static void process_queue (void);
static void find_file_and_directory (struct die_info *die,
struct dwarf2_cu *cu,
- char **name, char **comp_dir);
+ const char **name, const char **comp_dir);
static char *file_full_name (int file, struct line_header *lh,
const char *comp_dir);
-static gdb_byte *partial_read_comp_unit_head (struct comp_unit_head *header,
- gdb_byte *info_ptr,
- gdb_byte *buffer,
- unsigned int buffer_size,
- bfd *abfd,
- int is_debug_types_section);
+static gdb_byte *read_and_check_comp_unit_head
+ (struct comp_unit_head *header,
+ struct dwarf2_section_info *section,
+ struct dwarf2_section_info *abbrev_section, gdb_byte *info_ptr,
+ int is_debug_types_section);
-static void init_cu_die_reader (struct die_reader_specs *reader,
- struct dwarf2_cu *cu);
+static void init_cutu_and_read_dies
+ (struct dwarf2_per_cu_data *this_cu, struct abbrev_table *abbrev_table,
+ int use_existing_cu, int keep,
+ die_reader_func_ftype *die_reader_func, void *data);
+
+static void init_cutu_and_read_dies_simple
+ (struct dwarf2_per_cu_data *this_cu,
+ die_reader_func_ftype *die_reader_func, void *data);
static htab_t allocate_signatured_type_table (struct objfile *objfile);
+static htab_t allocate_dwo_unit_table (struct objfile *objfile);
+
+static struct dwo_unit *lookup_dwo_comp_unit
+ (struct dwarf2_per_cu_data *, const char *, const char *, ULONGEST);
+
+static struct dwo_unit *lookup_dwo_type_unit
+ (struct signatured_type *, const char *, const char *);
+
+static void free_dwo_file_cleanup (void *);
+
+static void process_cu_includes (void);
+
+static void check_producer (struct dwarf2_cu *cu);
+
#if WORDS_BIGENDIAN
/* Convert VALUE between big- and little-endian. */
@@ -1368,7 +1757,7 @@ byte_swap (offset_type value)
/* The suffix for an index file. */
#define INDEX_SUFFIX ".gdb-index"
-static const char *dwarf2_physname (char *name, struct die_info *die,
+static const char *dwarf2_physname (const char *name, struct die_info *die,
struct dwarf2_cu *cu);
/* Try to locate the sections we need for DWARF 2 debugging
@@ -1423,13 +1812,17 @@ static void
dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
{
const struct dwarf2_debug_sections *names;
+ flagword aflag = bfd_get_section_flags (abfd, sectp);
if (vnames == NULL)
names = &dwarf2_elf_names;
else
names = (const struct dwarf2_debug_sections *) vnames;
- if (section_is_p (sectp->name, &names->info))
+ if ((aflag & SEC_HAS_CONTENTS) == 0)
+ {
+ }
+ else if (section_is_p (sectp->name, &names->info))
{
dwarf2_per_objfile->info.asection = sectp;
dwarf2_per_objfile->info.size = bfd_get_section_size (sectp);
@@ -1464,6 +1857,11 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
dwarf2_per_objfile->str.asection = sectp;
dwarf2_per_objfile->str.size = bfd_get_section_size (sectp);
}
+ else if (section_is_p (sectp->name, &names->addr))
+ {
+ dwarf2_per_objfile->addr.asection = sectp;
+ dwarf2_per_objfile->addr.size = bfd_get_section_size (sectp);
+ }
else if (section_is_p (sectp->name, &names->frame))
{
dwarf2_per_objfile->frame.asection = sectp;
@@ -1471,13 +1869,8 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
}
else if (section_is_p (sectp->name, &names->eh_frame))
{
- flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
-
- if (aflag & SEC_HAS_CONTENTS)
- {
- dwarf2_per_objfile->eh_frame.asection = sectp;
- dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp);
- }
+ dwarf2_per_objfile->eh_frame.asection = sectp;
+ dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->ranges))
{
@@ -1506,86 +1899,8 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
dwarf2_per_objfile->has_section_at_zero = 1;
}
-/* Decompress a section that was compressed using zlib. Store the
- decompressed buffer, and its size, in OUTBUF and OUTSIZE. */
-
-static void
-zlib_decompress_section (struct objfile *objfile, asection *sectp,
- gdb_byte **outbuf, bfd_size_type *outsize)
-{
- bfd *abfd = objfile->obfd;
-#ifndef HAVE_ZLIB_H
- error (_("Support for zlib-compressed DWARF data (from '%s') "
- "is disabled in this copy of GDB"),
- bfd_get_filename (abfd));
-#else
- bfd_size_type compressed_size = bfd_get_section_size (sectp);
- gdb_byte *compressed_buffer = xmalloc (compressed_size);
- struct cleanup *cleanup = make_cleanup (xfree, compressed_buffer);
- bfd_size_type uncompressed_size;
- gdb_byte *uncompressed_buffer;
- z_stream strm;
- int rc;
- int header_size = 12;
-
- if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
- || bfd_bread (compressed_buffer,
- compressed_size, abfd) != compressed_size)
- error (_("Dwarf Error: Can't read DWARF data from '%s'"),
- bfd_get_filename (abfd));
-
- /* Read the zlib header. In this case, it should be "ZLIB" followed
- by the uncompressed section size, 8 bytes in big-endian order. */
- if (compressed_size < header_size
- || strncmp (compressed_buffer, "ZLIB", 4) != 0)
- error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"),
- bfd_get_filename (abfd));
- uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[11];
-
- /* It is possible the section consists of several compressed
- buffers concatenated together, so we uncompress in a loop. */
- strm.zalloc = NULL;
- strm.zfree = NULL;
- strm.opaque = NULL;
- strm.avail_in = compressed_size - header_size;
- strm.next_in = (Bytef*) compressed_buffer + header_size;
- strm.avail_out = uncompressed_size;
- uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack,
- uncompressed_size);
- rc = inflateInit (&strm);
- while (strm.avail_in > 0)
- {
- if (rc != Z_OK)
- error (_("Dwarf Error: setting up DWARF uncompression in '%s': %d"),
- bfd_get_filename (abfd), rc);
- strm.next_out = ((Bytef*) uncompressed_buffer
- + (uncompressed_size - strm.avail_out));
- rc = inflate (&strm, Z_FINISH);
- if (rc != Z_STREAM_END)
- error (_("Dwarf Error: zlib error uncompressing from '%s': %d"),
- bfd_get_filename (abfd), rc);
- rc = inflateReset (&strm);
- }
- rc = inflateEnd (&strm);
- if (rc != Z_OK
- || strm.avail_out != 0)
- error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
- bfd_get_filename (abfd), rc);
-
- do_cleanups (cleanup);
- *outbuf = uncompressed_buffer;
- *outsize = uncompressed_size;
-#endif
-}
-
-/* A helper function that decides whether a section is empty. */
+/* A helper function that decides whether a section is empty,
+ or not present. */
static int
dwarf2_section_empty_p (struct dwarf2_section_info *info)
@@ -1593,68 +1908,44 @@ dwarf2_section_empty_p (struct dwarf2_section_info *info)
return info->asection == NULL || info->size == 0;
}
-/* Read the contents of the section SECTP from object file specified by
- OBJFILE, store info about the section into INFO.
+/* Read the contents of the section INFO.
+ OBJFILE is the main object file, but not necessarily the file where
+ the section comes from. E.g., for DWO files INFO->asection->owner
+ is the bfd of the DWO file.
If the section is compressed, uncompress it before returning. */
static void
dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
{
- bfd *abfd = objfile->obfd;
asection *sectp = info->asection;
+ bfd *abfd;
gdb_byte *buf, *retbuf;
unsigned char header[4];
if (info->readin)
return;
info->buffer = NULL;
- info->map_addr = NULL;
info->readin = 1;
if (dwarf2_section_empty_p (info))
return;
- /* Check if the file has a 4-byte header indicating compression. */
- if (info->size > sizeof (header)
- && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
- && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
- {
- /* Upon decompression, update the buffer and its size. */
- if (strncmp (header, "ZLIB", sizeof (header)) == 0)
- {
- zlib_decompress_section (objfile, sectp, &info->buffer,
- &info->size);
- return;
- }
- }
-
-#ifdef HAVE_MMAP
- if (pagesize == 0)
- pagesize = getpagesize ();
+ abfd = sectp->owner;
- /* Only try to mmap sections which are large enough: we don't want to
- waste space due to fragmentation. Also, only try mmap for sections
- without relocations. */
-
- if (info->size > 4 * pagesize && (sectp->flags & SEC_RELOC) == 0)
+ /* If the section has relocations, we must read it ourselves.
+ Otherwise we attach it to the BFD. */
+ if ((sectp->flags & SEC_RELOC) == 0)
{
- info->buffer = bfd_mmap (abfd, 0, info->size, PROT_READ,
- MAP_PRIVATE, sectp->filepos,
- &info->map_addr, &info->map_len);
+ const gdb_byte *bytes = gdb_bfd_map_section (sectp, &info->size);
- if ((caddr_t)info->buffer != MAP_FAILED)
- {
-#if HAVE_POSIX_MADVISE
- posix_madvise (info->map_addr, info->map_len, POSIX_MADV_WILLNEED);
-#endif
- return;
- }
+ /* We have to cast away const here for historical reasons.
+ Fixing dwarf2read to be const-correct would be quite nice. */
+ info->buffer = (gdb_byte *) bytes;
+ return;
}
-#endif
- /* If we get here, we are a normal, not-compressed section. */
- info->buffer = buf
- = obstack_alloc (&objfile->objfile_obstack, info->size);
+ buf = obstack_alloc (&objfile->objfile_obstack, info->size);
+ info->buffer = buf;
/* When debugging .o files, we may need to apply relocations; see
http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
@@ -1730,23 +2021,129 @@ dwarf2_get_section_info (struct objfile *objfile,
*sizep = info->size;
}
-
-/* DWARF quick_symbols_functions support. */
+/* A helper function to find the sections for a .dwz file. */
-/* TUs can share .debug_line entries, and there can be a lot more TUs than
- unique line tables, so we maintain a separate table of all .debug_line
- derived entries to support the sharing.
- All the quick functions need is the list of file names. We discard the
- line_header when we're done and don't need to record it here. */
-struct quick_file_names
+static void
+locate_dwz_sections (bfd *abfd, asection *sectp, void *arg)
{
- /* The offset in .debug_line of the line table. We hash on this. */
- unsigned int offset;
+ struct dwz_file *dwz_file = arg;
- /* The number of entries in file_names, real_names. */
- unsigned int num_file_names;
+ /* Note that we only support the standard ELF names, because .dwz
+ is ELF-only (at the time of writing). */
+ if (section_is_p (sectp->name, &dwarf2_elf_names.abbrev))
+ {
+ dwz_file->abbrev.asection = sectp;
+ dwz_file->abbrev.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &dwarf2_elf_names.info))
+ {
+ dwz_file->info.asection = sectp;
+ dwz_file->info.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &dwarf2_elf_names.str))
+ {
+ dwz_file->str.asection = sectp;
+ dwz_file->str.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &dwarf2_elf_names.line))
+ {
+ dwz_file->line.asection = sectp;
+ dwz_file->line.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &dwarf2_elf_names.macro))
+ {
+ dwz_file->macro.asection = sectp;
+ dwz_file->macro.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &dwarf2_elf_names.gdb_index))
+ {
+ dwz_file->gdb_index.asection = sectp;
+ dwz_file->gdb_index.size = bfd_get_section_size (sectp);
+ }
+}
- /* The file names from the line table, after being run through
+/* Open the separate '.dwz' debug file, if needed. Error if the file
+ cannot be found. */
+
+static struct dwz_file *
+dwarf2_get_dwz_file (void)
+{
+ bfd *abfd, *dwz_bfd;
+ asection *section;
+ gdb_byte *data;
+ struct cleanup *cleanup;
+ const char *filename;
+ struct dwz_file *result;
+
+ if (dwarf2_per_objfile->dwz_file != NULL)
+ return dwarf2_per_objfile->dwz_file;
+
+ abfd = dwarf2_per_objfile->objfile->obfd;
+ section = bfd_get_section_by_name (abfd, ".gnu_debugaltlink");
+ if (section == NULL)
+ error (_("could not find '.gnu_debugaltlink' section"));
+ if (!bfd_malloc_and_get_section (abfd, section, &data))
+ error (_("could not read '.gnu_debugaltlink' section: %s"),
+ bfd_errmsg (bfd_get_error ()));
+ cleanup = make_cleanup (xfree, data);
+
+ filename = data;
+ if (!IS_ABSOLUTE_PATH (filename))
+ {
+ char *abs = gdb_realpath (dwarf2_per_objfile->objfile->name);
+ char *rel;
+
+ make_cleanup (xfree, abs);
+ abs = ldirname (abs);
+ make_cleanup (xfree, abs);
+
+ rel = concat (abs, SLASH_STRING, filename, (char *) NULL);
+ make_cleanup (xfree, rel);
+ filename = rel;
+ }
+
+ /* The format is just a NUL-terminated file name, followed by the
+ build-id. For now, though, we ignore the build-id. */
+ dwz_bfd = gdb_bfd_open (filename, gnutarget, -1);
+ if (dwz_bfd == NULL)
+ error (_("could not read '%s': %s"), filename,
+ bfd_errmsg (bfd_get_error ()));
+
+ if (!bfd_check_format (dwz_bfd, bfd_object))
+ {
+ gdb_bfd_unref (dwz_bfd);
+ error (_("file '%s' was not usable: %s"), filename,
+ bfd_errmsg (bfd_get_error ()));
+ }
+
+ result = OBSTACK_ZALLOC (&dwarf2_per_objfile->objfile->objfile_obstack,
+ struct dwz_file);
+ result->dwz_bfd = dwz_bfd;
+
+ bfd_map_over_sections (dwz_bfd, locate_dwz_sections, result);
+
+ do_cleanups (cleanup);
+
+ dwarf2_per_objfile->dwz_file = result;
+ return result;
+}
+
+/* DWARF quick_symbols_functions support. */
+
+/* TUs can share .debug_line entries, and there can be a lot more TUs than
+ unique line tables, so we maintain a separate table of all .debug_line
+ derived entries to support the sharing.
+ All the quick functions need is the list of file names. We discard the
+ line_header when we're done and don't need to record it here. */
+struct quick_file_names
+{
+ /* The data used to construct the hash key. */
+ struct stmt_list_hash hash;
+
+ /* The number of entries in file_names, real_names. */
+ unsigned int num_file_names;
+
+ /* The file names from the line table, after being run through
file_full_name. */
const char **file_names;
@@ -1778,6 +2175,34 @@ struct dwarf2_per_cu_quick_data
unsigned int no_file_data : 1;
};
+/* Utility hash function for a stmt_list_hash. */
+
+static hashval_t
+hash_stmt_list_entry (const struct stmt_list_hash *stmt_list_hash)
+{
+ hashval_t v = 0;
+
+ if (stmt_list_hash->dwo_unit != NULL)
+ v += (uintptr_t) stmt_list_hash->dwo_unit->dwo_file;
+ v += stmt_list_hash->line_offset.sect_off;
+ return v;
+}
+
+/* Utility equality function for a stmt_list_hash. */
+
+static int
+eq_stmt_list_entry (const struct stmt_list_hash *lhs,
+ const struct stmt_list_hash *rhs)
+{
+ if ((lhs->dwo_unit != NULL) != (rhs->dwo_unit != NULL))
+ return 0;
+ if (lhs->dwo_unit != NULL
+ && lhs->dwo_unit->dwo_file != rhs->dwo_unit->dwo_file)
+ return 0;
+
+ return lhs->line_offset.sect_off == rhs->line_offset.sect_off;
+}
+
/* Hash function for a quick_file_names. */
static hashval_t
@@ -1785,7 +2210,7 @@ hash_file_name_entry (const void *e)
{
const struct quick_file_names *file_data = e;
- return file_data->offset;
+ return hash_stmt_list_entry (&file_data->hash);
}
/* Equality function for a quick_file_names. */
@@ -1796,7 +2221,7 @@ eq_file_name_entry (const void *a, const void *b)
const struct quick_file_names *ea = a;
const struct quick_file_names *eb = b;
- return ea->offset == eb->offset;
+ return eq_stmt_list_entry (&ea->hash, &eb->hash);
}
/* Delete function for a quick_file_names. */
@@ -1835,34 +2260,39 @@ create_quick_file_names_table (unsigned int nr_initial_entries)
static void
load_cu (struct dwarf2_per_cu_data *per_cu)
{
- if (per_cu->debug_types_section)
- read_signatured_type_at_offset (per_cu->objfile,
- per_cu->debug_types_section,
- per_cu->offset);
+ if (per_cu->is_debug_types)
+ load_full_type_unit (per_cu);
else
- load_full_comp_unit (per_cu, per_cu->objfile);
-
- dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
+ load_full_comp_unit (per_cu, language_minimal);
gdb_assert (per_cu->cu != NULL);
+
+ dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
}
-/* Read in the symbols for PER_CU. OBJFILE is the objfile from which
- this CU came. */
+/* Read in the symbols for PER_CU. */
static void
-dw2_do_instantiate_symtab (struct objfile *objfile,
- struct dwarf2_per_cu_data *per_cu)
+dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
{
struct cleanup *back_to;
- back_to = make_cleanup (dwarf2_release_queue, NULL);
+ /* Skip type_unit_groups, reading the type units they contain
+ is handled elsewhere. */
+ if (IS_TYPE_UNIT_GROUP (per_cu))
+ return;
- queue_comp_unit (per_cu, objfile);
+ back_to = make_cleanup (dwarf2_release_queue, NULL);
- load_cu (per_cu);
+ if (dwarf2_per_objfile->using_index
+ ? per_cu->v.quick->symtab == NULL
+ : (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin))
+ {
+ queue_comp_unit (per_cu, language_minimal);
+ load_cu (per_cu);
+ }
- process_queue (objfile);
+ process_queue ();
/* Age the cache, releasing compilation units that have not
been used recently. */
@@ -1876,20 +2306,32 @@ dw2_do_instantiate_symtab (struct objfile *objfile,
table. */
static struct symtab *
-dw2_instantiate_symtab (struct objfile *objfile,
- struct dwarf2_per_cu_data *per_cu)
+dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
{
+ gdb_assert (dwarf2_per_objfile->using_index);
if (!per_cu->v.quick->symtab)
{
struct cleanup *back_to = make_cleanup (free_cached_comp_units, NULL);
increment_reading_symtab ();
- dw2_do_instantiate_symtab (objfile, per_cu);
+ dw2_do_instantiate_symtab (per_cu);
+ process_cu_includes ();
do_cleanups (back_to);
}
return per_cu->v.quick->symtab;
}
-/* Return the CU given its index. */
+/* Return the CU given its index.
+
+ This is intended for loops like:
+
+ for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_type_units); ++i)
+ {
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+
+ ...;
+ }
+*/
static struct dwarf2_per_cu_data *
dw2_get_cu (int index)
@@ -1897,76 +2339,106 @@ dw2_get_cu (int index)
if (index >= dwarf2_per_objfile->n_comp_units)
{
index -= dwarf2_per_objfile->n_comp_units;
- return dwarf2_per_objfile->type_comp_units[index];
+ gdb_assert (index < dwarf2_per_objfile->n_type_units);
+ return &dwarf2_per_objfile->all_type_units[index]->per_cu;
}
+
return dwarf2_per_objfile->all_comp_units[index];
}
-/* A helper function that knows how to read a 64-bit value in a way
- that doesn't make gdb die. Returns 1 if the conversion went ok, 0
- otherwise. */
+/* Return the primary CU given its index.
+ The difference between this function and dw2_get_cu is in the handling
+ of type units (TUs). Here we return the type_unit_group object.
-static int
-extract_cu_value (const char *bytes, ULONGEST *result)
-{
- if (sizeof (ULONGEST) < 8)
- {
- int i;
+ This is intended for loops like:
- /* Ignore the upper 4 bytes if they are all zero. */
- for (i = 0; i < 4; ++i)
- if (bytes[i + 4] != 0)
- return 0;
+ for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_type_unit_groups); ++i)
+ {
+ struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i);
+
+ ...;
+ }
+*/
- *result = extract_unsigned_integer (bytes, 4, BFD_ENDIAN_LITTLE);
+static struct dwarf2_per_cu_data *
+dw2_get_primary_cu (int index)
+{
+ if (index >= dwarf2_per_objfile->n_comp_units)
+ {
+ index -= dwarf2_per_objfile->n_comp_units;
+ gdb_assert (index < dwarf2_per_objfile->n_type_unit_groups);
+ return &dwarf2_per_objfile->all_type_unit_groups[index]->per_cu;
}
- else
- *result = extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE);
- return 1;
+
+ return dwarf2_per_objfile->all_comp_units[index];
}
-/* Read the CU list from the mapped index, and use it to create all
- the CU objects for this objfile. Return 0 if something went wrong,
- 1 if everything went ok. */
+/* A helper for create_cus_from_index that handles a given list of
+ CUs. */
-static int
-create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list,
- offset_type cu_list_elements)
+static void
+create_cus_from_index_list (struct objfile *objfile,
+ const gdb_byte *cu_list, offset_type n_elements,
+ struct dwarf2_section_info *section,
+ int is_dwz,
+ int base_offset)
{
offset_type i;
- dwarf2_per_objfile->n_comp_units = cu_list_elements / 2;
- dwarf2_per_objfile->all_comp_units
- = obstack_alloc (&objfile->objfile_obstack,
- dwarf2_per_objfile->n_comp_units
- * sizeof (struct dwarf2_per_cu_data *));
-
- for (i = 0; i < cu_list_elements; i += 2)
+ for (i = 0; i < n_elements; i += 2)
{
struct dwarf2_per_cu_data *the_cu;
ULONGEST offset, length;
- if (!extract_cu_value (cu_list, &offset)
- || !extract_cu_value (cu_list + 8, &length))
- return 0;
+ gdb_static_assert (sizeof (ULONGEST) >= 8);
+ offset = extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE);
+ length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
cu_list += 2 * 8;
the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_data);
- the_cu->offset = offset;
+ the_cu->offset.sect_off = offset;
the_cu->length = length;
the_cu->objfile = objfile;
+ the_cu->info_or_types_section = section;
the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_quick_data);
- dwarf2_per_objfile->all_comp_units[i / 2] = the_cu;
+ the_cu->is_dwz = is_dwz;
+ dwarf2_per_objfile->all_comp_units[base_offset + i / 2] = the_cu;
}
+}
- return 1;
+/* Read the CU list from the mapped index, and use it to create all
+ the CU objects for this objfile. */
+
+static void
+create_cus_from_index (struct objfile *objfile,
+ const gdb_byte *cu_list, offset_type cu_list_elements,
+ const gdb_byte *dwz_list, offset_type dwz_elements)
+{
+ struct dwz_file *dwz;
+
+ dwarf2_per_objfile->n_comp_units = (cu_list_elements + dwz_elements) / 2;
+ dwarf2_per_objfile->all_comp_units
+ = obstack_alloc (&objfile->objfile_obstack,
+ dwarf2_per_objfile->n_comp_units
+ * sizeof (struct dwarf2_per_cu_data *));
+
+ create_cus_from_index_list (objfile, cu_list, cu_list_elements,
+ &dwarf2_per_objfile->info, 0, 0);
+
+ if (dwz_elements == 0)
+ return;
+
+ dwz = dwarf2_get_dwz_file ();
+ create_cus_from_index_list (objfile, dwz_list, dwz_elements, &dwz->info, 1,
+ cu_list_elements / 2);
}
/* Create the signatured type hash table from the index. */
-static int
+static void
create_signatured_type_table_from_index (struct objfile *objfile,
struct dwarf2_section_info *section,
const gdb_byte *bytes,
@@ -1975,46 +2447,46 @@ create_signatured_type_table_from_index (struct objfile *objfile,
offset_type i;
htab_t sig_types_hash;
- dwarf2_per_objfile->n_type_comp_units = elements / 3;
- dwarf2_per_objfile->type_comp_units
+ dwarf2_per_objfile->n_type_units = elements / 3;
+ dwarf2_per_objfile->all_type_units
= obstack_alloc (&objfile->objfile_obstack,
- dwarf2_per_objfile->n_type_comp_units
- * sizeof (struct dwarf2_per_cu_data *));
+ dwarf2_per_objfile->n_type_units
+ * sizeof (struct signatured_type *));
sig_types_hash = allocate_signatured_type_table (objfile);
for (i = 0; i < elements; i += 3)
{
- struct signatured_type *type_sig;
- ULONGEST offset, type_offset, signature;
+ struct signatured_type *sig_type;
+ ULONGEST offset, type_offset_in_tu, signature;
void **slot;
- if (!extract_cu_value (bytes, &offset)
- || !extract_cu_value (bytes + 8, &type_offset))
- return 0;
+ gdb_static_assert (sizeof (ULONGEST) >= 8);
+ offset = extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE);
+ type_offset_in_tu = extract_unsigned_integer (bytes + 8, 8,
+ BFD_ENDIAN_LITTLE);
signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
bytes += 3 * 8;
- type_sig = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct signatured_type);
- type_sig->signature = signature;
- type_sig->type_offset = type_offset;
- type_sig->per_cu.debug_types_section = section;
- type_sig->per_cu.offset = offset;
- type_sig->per_cu.objfile = objfile;
- type_sig->per_cu.v.quick
+ sig_type->signature = signature;
+ sig_type->type_offset_in_tu.cu_off = type_offset_in_tu;
+ sig_type->per_cu.is_debug_types = 1;
+ sig_type->per_cu.info_or_types_section = section;
+ sig_type->per_cu.offset.sect_off = offset;
+ sig_type->per_cu.objfile = objfile;
+ sig_type->per_cu.v.quick
= OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_quick_data);
- slot = htab_find_slot (sig_types_hash, type_sig, INSERT);
- *slot = type_sig;
+ slot = htab_find_slot (sig_types_hash, sig_type, INSERT);
+ *slot = sig_type;
- dwarf2_per_objfile->type_comp_units[i / 3] = &type_sig->per_cu;
+ dwarf2_per_objfile->all_type_units[i / 3] = sig_type;
}
dwarf2_per_objfile->signatured_types = sig_types_hash;
-
- return 1;
}
/* Read the address map data from the mapped index, and use it to
@@ -2117,7 +2589,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
}
/* Index version 4 did not support case insensitive searches. But the
- indexes for case insensitive languages are built in lowercase, therefore
+ indices for case insensitive languages are built in lowercase, therefore
simulate our NAME being searched is also lowercased. */
hash = mapped_index_string_hash ((index->version == 4
&& case_sensitivity == case_sensitive_off
@@ -2152,63 +2624,108 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
}
}
-/* Read the index file. If everything went ok, initialize the "quick"
- elements of all the CUs and return 1. Otherwise, return 0. */
+/* A helper function that reads the .gdb_index from SECTION and fills
+ in MAP. FILENAME is the name of the file containing the section;
+ it is used for error reporting. DEPRECATED_OK is nonzero if it is
+ ok to use deprecated sections.
+
+ CU_LIST, CU_LIST_ELEMENTS, TYPES_LIST, and TYPES_LIST_ELEMENTS are
+ out parameters that are filled in with information about the CU and
+ TU lists in the section.
+
+ Returns 1 if all went well, 0 otherwise. */
static int
-dwarf2_read_index (struct objfile *objfile)
+read_index_from_section (struct objfile *objfile,
+ const char *filename,
+ int deprecated_ok,
+ struct dwarf2_section_info *section,
+ struct mapped_index *map,
+ const gdb_byte **cu_list,
+ offset_type *cu_list_elements,
+ const gdb_byte **types_list,
+ offset_type *types_list_elements)
{
char *addr;
- struct mapped_index *map;
+ offset_type version;
offset_type *metadata;
- const gdb_byte *cu_list;
- const gdb_byte *types_list = NULL;
- offset_type version, cu_list_elements;
- offset_type types_list_elements = 0;
int i;
- if (dwarf2_section_empty_p (&dwarf2_per_objfile->gdb_index))
+ if (dwarf2_section_empty_p (section))
return 0;
/* Older elfutils strip versions could keep the section in the main
executable while splitting it for the separate debug info file. */
- if ((bfd_get_file_flags (dwarf2_per_objfile->gdb_index.asection)
- & SEC_HAS_CONTENTS) == 0)
+ if ((bfd_get_file_flags (section->asection) & SEC_HAS_CONTENTS) == 0)
return 0;
- dwarf2_read_section (objfile, &dwarf2_per_objfile->gdb_index);
+ dwarf2_read_section (objfile, section);
- addr = dwarf2_per_objfile->gdb_index.buffer;
+ addr = section->buffer;
/* Version check. */
version = MAYBE_SWAP (*(offset_type *) addr);
/* Versions earlier than 3 emitted every copy of a psymbol. This
causes the index to behave very poorly for certain requests. Version 3
contained incomplete addrmap. So, it seems better to just ignore such
- indices. Index version 4 uses a different hash function than index
- version 5 and later. */
+ indices. */
if (version < 4)
- return 0;
+ {
+ static int warning_printed = 0;
+ if (!warning_printed)
+ {
+ warning (_("Skipping obsolete .gdb_index section in %s."),
+ filename);
+ warning_printed = 1;
+ }
+ return 0;
+ }
+ /* Index version 4 uses a different hash function than index version
+ 5 and later.
+
+ Versions earlier than 6 did not emit psymbols for inlined
+ functions. Using these files will cause GDB not to be able to
+ set breakpoints on inlined functions by name, so we ignore these
+ indices unless the user has done
+ "set use-deprecated-index-sections on". */
+ if (version < 6 && !deprecated_ok)
+ {
+ static int warning_printed = 0;
+ if (!warning_printed)
+ {
+ warning (_("\
+Skipping deprecated .gdb_index section in %s.\n\
+Do \"set use-deprecated-index-sections on\" before the file is read\n\
+to use the section anyway."),
+ filename);
+ warning_printed = 1;
+ }
+ return 0;
+ }
+ /* Version 7 indices generated by gold refer to the CU for a symbol instead
+ of the TU (for symbols coming from TUs). It's just a performance bug, and
+ we can't distinguish gdb-generated indices from gold-generated ones, so
+ nothing to do here. */
+
/* Indexes with higher version than the one supported by GDB may be no
longer backward compatible. */
- if (version > 5)
+ if (version > 8)
return 0;
- map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
map->version = version;
- map->total_size = dwarf2_per_objfile->gdb_index.size;
+ map->total_size = section->size;
metadata = (offset_type *) (addr + sizeof (offset_type));
i = 0;
- cu_list = addr + MAYBE_SWAP (metadata[i]);
- cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
- / 8);
+ *cu_list = addr + MAYBE_SWAP (metadata[i]);
+ *cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
+ / 8);
++i;
- types_list = addr + MAYBE_SWAP (metadata[i]);
- types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
- - MAYBE_SWAP (metadata[i]))
- / 8);
+ *types_list = addr + MAYBE_SWAP (metadata[i]);
+ *types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
+ - MAYBE_SWAP (metadata[i]))
+ / 8);
++i;
map->address_table = addr + MAYBE_SWAP (metadata[i]);
@@ -2224,9 +2741,56 @@ dwarf2_read_index (struct objfile *objfile)
map->constant_pool = addr + MAYBE_SWAP (metadata[i]);
- if (!create_cus_from_index (objfile, cu_list, cu_list_elements))
+ return 1;
+}
+
+
+/* Read the index file. If everything went ok, initialize the "quick"
+ elements of all the CUs and return 1. Otherwise, return 0. */
+
+static int
+dwarf2_read_index (struct objfile *objfile)
+{
+ struct mapped_index local_map, *map;
+ const gdb_byte *cu_list, *types_list, *dwz_list = NULL;
+ offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0;
+
+ if (!read_index_from_section (objfile, objfile->name,
+ use_deprecated_index_sections,
+ &dwarf2_per_objfile->gdb_index, &local_map,
+ &cu_list, &cu_list_elements,
+ &types_list, &types_list_elements))
+ return 0;
+
+ /* Don't use the index if it's empty. */
+ if (local_map.symbol_table_slots == 0)
return 0;
+ /* If there is a .dwz file, read it so we can get its CU list as
+ well. */
+ if (bfd_get_section_by_name (objfile->obfd, ".gnu_debugaltlink") != NULL)
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+ struct mapped_index dwz_map;
+ const gdb_byte *dwz_types_ignore;
+ offset_type dwz_types_elements_ignore;
+
+ if (!read_index_from_section (objfile, bfd_get_filename (dwz->dwz_bfd),
+ 1,
+ &dwz->gdb_index, &dwz_map,
+ &dwz_list, &dwz_list_elements,
+ &dwz_types_ignore,
+ &dwz_types_elements_ignore))
+ {
+ warning (_("could not read '.gdb_index' section from %s; skipping"),
+ bfd_get_filename (dwz->dwz_bfd));
+ return 0;
+ }
+ }
+
+ create_cus_from_index (objfile, cu_list, cu_list_elements, dwz_list,
+ dwz_list_elements);
+
if (types_list_elements)
{
struct dwarf2_section_info *section;
@@ -2239,13 +2803,14 @@ dwarf2_read_index (struct objfile *objfile)
section = VEC_index (dwarf2_section_info_def,
dwarf2_per_objfile->types, 0);
- if (!create_signatured_type_table_from_index (objfile, section,
- types_list,
- types_list_elements))
- return 0;
+ create_signatured_type_table_from_index (objfile, section, types_list,
+ types_list_elements);
}
- create_addrmap_from_index (objfile, map);
+ create_addrmap_from_index (objfile, &local_map);
+
+ map = obstack_alloc (&objfile->objfile_obstack, sizeof (struct mapped_index));
+ *map = local_map;
dwarf2_per_objfile->index_table = map;
dwarf2_per_objfile->using_index = 1;
@@ -2265,74 +2830,52 @@ dw2_setup (struct objfile *objfile)
gdb_assert (dwarf2_per_objfile);
}
-/* A helper for the "quick" functions which attempts to read the line
- table for THIS_CU. */
+/* die_reader_func for dw2_get_file_names. */
-static struct quick_file_names *
-dw2_get_file_names (struct objfile *objfile,
- struct dwarf2_per_cu_data *this_cu)
+static void
+dw2_get_file_names_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
{
- bfd *abfd = objfile->obfd;
+ struct dwarf2_cu *cu = reader->cu;
+ struct dwarf2_per_cu_data *this_cu = cu->per_cu;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_per_cu_data *lh_cu;
struct line_header *lh;
struct attribute *attr;
- struct cleanup *cleanups;
- struct die_info *comp_unit_die;
- struct dwarf2_section_info* sec;
- gdb_byte *info_ptr, *buffer;
- int has_children, i;
- struct dwarf2_cu cu;
- unsigned int bytes_read, buffer_size;
- struct die_reader_specs reader_specs;
- char *name, *comp_dir;
+ int i;
+ const char *name, *comp_dir;
void **slot;
struct quick_file_names *qfn;
unsigned int line_offset;
- if (this_cu->v.quick->file_names != NULL)
- return this_cu->v.quick->file_names;
- /* If we know there is no line data, no point in looking again. */
- if (this_cu->v.quick->no_file_data)
- return NULL;
-
- init_one_comp_unit (&cu, objfile);
- cleanups = make_cleanup (free_stack_comp_unit, &cu);
-
- if (this_cu->debug_types_section)
- sec = this_cu->debug_types_section;
- else
- sec = &dwarf2_per_objfile->info;
- dwarf2_read_section (objfile, sec);
- buffer_size = sec->size;
- buffer = sec->buffer;
- info_ptr = buffer + this_cu->offset;
-
- info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr,
- buffer, buffer_size,
- abfd,
- this_cu->debug_types_section != NULL);
-
- /* Skip dummy compilation units. */
- if (info_ptr >= buffer + buffer_size
- || peek_abbrev_code (abfd, info_ptr) == 0)
+ /* Our callers never want to match partial units -- instead they
+ will match the enclosing full CU. */
+ if (comp_unit_die->tag == DW_TAG_partial_unit)
{
- do_cleanups (cleanups);
- return NULL;
+ this_cu->v.quick->no_file_data = 1;
+ return;
}
- this_cu->cu = &cu;
- cu.per_cu = this_cu;
-
- dwarf2_read_abbrevs (abfd, &cu);
- make_cleanup (dwarf2_free_abbrev_table, &cu);
+ /* If we're reading the line header for TUs, store it in the "per_cu"
+ for tu_group. */
+ if (this_cu->is_debug_types)
+ {
+ struct type_unit_group *tu_group = data;
- init_cu_die_reader (&reader_specs, &cu);
- read_full_die (&reader_specs, &comp_unit_die, info_ptr,
- &has_children);
+ gdb_assert (tu_group != NULL);
+ lh_cu = &tu_group->per_cu;
+ }
+ else
+ lh_cu = this_cu;
lh = NULL;
slot = NULL;
line_offset = 0;
- attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, &cu);
+
+ attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
if (attr)
{
struct quick_file_names find_entry;
@@ -2341,31 +2884,31 @@ dw2_get_file_names (struct objfile *objfile,
/* We may have already read in this line header (TU line header sharing).
If we have we're done. */
- find_entry.offset = line_offset;
+ find_entry.hash.dwo_unit = cu->dwo_unit;
+ find_entry.hash.line_offset.sect_off = line_offset;
slot = htab_find_slot (dwarf2_per_objfile->quick_file_names_table,
&find_entry, INSERT);
if (*slot != NULL)
{
- do_cleanups (cleanups);
- this_cu->v.quick->file_names = *slot;
- return *slot;
+ lh_cu->v.quick->file_names = *slot;
+ return;
}
- lh = dwarf_decode_line_header (line_offset, abfd, &cu);
+ lh = dwarf_decode_line_header (line_offset, cu);
}
if (lh == NULL)
{
- do_cleanups (cleanups);
- this_cu->v.quick->no_file_data = 1;
- return NULL;
+ lh_cu->v.quick->no_file_data = 1;
+ return;
}
qfn = obstack_alloc (&objfile->objfile_obstack, sizeof (*qfn));
- qfn->offset = line_offset;
+ qfn->hash.dwo_unit = cu->dwo_unit;
+ qfn->hash.line_offset.sect_off = line_offset;
gdb_assert (slot != NULL);
*slot = qfn;
- find_file_and_directory (comp_unit_die, &cu, &name, &comp_dir);
+ find_file_and_directory (comp_unit_die, cu, &name, &comp_dir);
qfn->num_file_names = lh->num_file_names;
qfn->file_names = obstack_alloc (&objfile->objfile_obstack,
@@ -2375,10 +2918,44 @@ dw2_get_file_names (struct objfile *objfile,
qfn->real_names = NULL;
free_line_header (lh);
- do_cleanups (cleanups);
- this_cu->v.quick->file_names = qfn;
- return qfn;
+ lh_cu->v.quick->file_names = qfn;
+}
+
+/* A helper for the "quick" functions which attempts to read the line
+ table for THIS_CU. */
+
+static struct quick_file_names *
+dw2_get_file_names (struct objfile *objfile,
+ struct dwarf2_per_cu_data *this_cu)
+{
+ /* For TUs this should only be called on the parent group. */
+ if (this_cu->is_debug_types)
+ gdb_assert (IS_TYPE_UNIT_GROUP (this_cu));
+
+ if (this_cu->v.quick->file_names != NULL)
+ return this_cu->v.quick->file_names;
+ /* If we know there is no line data, no point in looking again. */
+ if (this_cu->v.quick->no_file_data)
+ return NULL;
+
+ /* If DWO files are in use, we can still find the DW_AT_stmt_list attribute
+ in the stub for CUs, there's is no need to lookup the DWO file.
+ However, that's not the case for TUs where DW_AT_stmt_list lives in the
+ DWO file. */
+ if (this_cu->is_debug_types)
+ {
+ struct type_unit_group *tu_group = this_cu->type_unit_group;
+
+ init_cutu_and_read_dies (tu_group->t.first_tu, NULL, 0, 0,
+ dw2_get_file_names_reader, tu_group);
+ }
+ else
+ init_cutu_and_read_dies_simple (this_cu, dw2_get_file_names_reader, NULL);
+
+ if (this_cu->v.quick->no_file_data)
+ return NULL;
+ return this_cu->v.quick->file_names;
}
/* A helper for the "quick" functions which computes and caches the
@@ -2405,7 +2982,7 @@ dw2_find_last_source_symtab (struct objfile *objfile)
dw2_setup (objfile);
index = dwarf2_per_objfile->n_comp_units - 1;
- return dw2_instantiate_symtab (objfile, dw2_get_cu (index));
+ return dw2_instantiate_symtab (dw2_get_cu (index));
}
/* Traversal function for dw2_forget_cached_source_info. */
@@ -2444,8 +3021,7 @@ dw2_forget_cached_source_info (struct objfile *objfile)
static int
dw2_map_expand_apply (struct objfile *objfile,
struct dwarf2_per_cu_data *per_cu,
- const char *name,
- const char *full_path, const char *real_path,
+ const char *name, const char *real_path,
int (*callback) (struct symtab *, void *),
void *data)
{
@@ -2457,9 +3033,9 @@ dw2_map_expand_apply (struct objfile *objfile,
/* This may expand more than one symtab, and we want to iterate over
all of them. */
- dw2_instantiate_symtab (objfile, per_cu);
+ dw2_instantiate_symtab (per_cu);
- return iterate_over_some_symtabs (name, full_path, real_path, callback, data,
+ return iterate_over_some_symtabs (name, real_path, callback, data,
objfile->symtabs, last_made);
}
@@ -2467,22 +3043,22 @@ dw2_map_expand_apply (struct objfile *objfile,
static int
dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
- const char *full_path, const char *real_path,
+ const char *real_path,
int (*callback) (struct symtab *, void *),
void *data)
{
int i;
const char *name_basename = lbasename (name);
- int check_basename = name_basename == name;
- struct dwarf2_per_cu_data *base_cu = NULL;
dw2_setup (objfile);
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ /* The rule is CUs specify all the files, including those used by
+ any TU, so there's no need to scan TUs here. */
+
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
int j;
- struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+ struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i);
struct quick_file_names *file_data;
/* We only need to look at symtabs not already expanded. */
@@ -2496,50 +3072,37 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
for (j = 0; j < file_data->num_file_names; ++j)
{
const char *this_name = file_data->file_names[j];
+ const char *this_real_name;
- if (FILENAME_CMP (name, this_name) == 0)
+ if (compare_filenames_for_search (this_name, name))
{
- if (dw2_map_expand_apply (objfile, per_cu,
- name, full_path, real_path,
+ if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
callback, data))
return 1;
}
- if (check_basename && ! base_cu
- && FILENAME_CMP (lbasename (this_name), name) == 0)
- base_cu = per_cu;
-
/* Before we invoke realpath, which can get expensive when many
files are involved, do a quick comparison of the basenames. */
if (! basenames_may_differ
&& FILENAME_CMP (lbasename (this_name), name_basename) != 0)
continue;
- if (full_path != NULL)
+ this_real_name = dw2_get_real_path (objfile, file_data, j);
+ if (compare_filenames_for_search (this_real_name, name))
{
- const char *this_real_name = dw2_get_real_path (objfile,
- file_data, j);
-
- if (this_real_name != NULL
- && FILENAME_CMP (full_path, this_real_name) == 0)
- {
- if (dw2_map_expand_apply (objfile, per_cu,
- name, full_path, real_path,
- callback, data))
- return 1;
- }
+ if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
+ callback, data))
+ return 1;
}
if (real_path != NULL)
{
- const char *this_real_name = dw2_get_real_path (objfile,
- file_data, j);
-
+ gdb_assert (IS_ABSOLUTE_PATH (real_path));
+ gdb_assert (IS_ABSOLUTE_PATH (name));
if (this_real_name != NULL
&& FILENAME_CMP (real_path, this_real_name) == 0)
{
- if (dw2_map_expand_apply (objfile, per_cu,
- name, full_path, real_path,
+ if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
callback, data))
return 1;
}
@@ -2547,60 +3110,171 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
}
}
- if (base_cu)
- {
- if (dw2_map_expand_apply (objfile, base_cu,
- name, full_path, real_path,
- callback, data))
- return 1;
- }
-
return 0;
}
-static struct symtab *
-dw2_lookup_symbol (struct objfile *objfile, int block_index,
- const char *name, domain_enum domain)
+/* Struct used to manage iterating over all CUs looking for a symbol. */
+
+struct dw2_symtab_iterator
{
- /* We do all the work in the pre_expand_symtabs_matching hook
- instead. */
- return NULL;
-}
+ /* The internalized form of .gdb_index. */
+ struct mapped_index *index;
+ /* If non-zero, only look for symbols that match BLOCK_INDEX. */
+ int want_specific_block;
+ /* One of GLOBAL_BLOCK or STATIC_BLOCK.
+ Unused if !WANT_SPECIFIC_BLOCK. */
+ int block_index;
+ /* The kind of symbol we're looking for. */
+ domain_enum domain;
+ /* The list of CUs from the index entry of the symbol,
+ or NULL if not found. */
+ offset_type *vec;
+ /* The next element in VEC to look at. */
+ int next;
+ /* The number of elements in VEC, or zero if there is no match. */
+ int length;
+};
-/* A helper function that expands all symtabs that hold an object
- named NAME. */
+/* Initialize the index symtab iterator ITER.
+ If WANT_SPECIFIC_BLOCK is non-zero, only look for symbols
+ in block BLOCK_INDEX. Otherwise BLOCK_INDEX is ignored. */
static void
-dw2_do_expand_symtabs_matching (struct objfile *objfile, const char *name)
-{
- dw2_setup (objfile);
-
- /* index_table is NULL if OBJF_READNOW. */
- if (dwarf2_per_objfile->index_table)
+dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
+ struct mapped_index *index,
+ int want_specific_block,
+ int block_index,
+ domain_enum domain,
+ const char *name)
+{
+ iter->index = index;
+ iter->want_specific_block = want_specific_block;
+ iter->block_index = block_index;
+ iter->domain = domain;
+ iter->next = 0;
+
+ if (find_slot_in_mapped_hash (index, name, &iter->vec))
+ iter->length = MAYBE_SWAP (*iter->vec);
+ else
{
- offset_type *vec;
+ iter->vec = NULL;
+ iter->length = 0;
+ }
+}
- if (find_slot_in_mapped_hash (dwarf2_per_objfile->index_table,
- name, &vec))
+/* Return the next matching CU or NULL if there are no more. */
+
+static struct dwarf2_per_cu_data *
+dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
+{
+ for ( ; iter->next < iter->length; ++iter->next)
+ {
+ offset_type cu_index_and_attrs =
+ MAYBE_SWAP (iter->vec[iter->next + 1]);
+ offset_type cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (cu_index);
+ int want_static = iter->block_index != GLOBAL_BLOCK;
+ /* This value is only valid for index versions >= 7. */
+ int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
+ gdb_index_symbol_kind symbol_kind =
+ GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
+ /* Only check the symbol attributes if they're present.
+ Indices prior to version 7 don't record them,
+ and indices >= 7 may elide them for certain symbols
+ (gold does this). */
+ int attrs_valid =
+ (iter->index->version >= 7
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
+
+ /* Skip if already read in. */
+ if (per_cu->v.quick->symtab)
+ continue;
+
+ if (attrs_valid
+ && iter->want_specific_block
+ && want_static != is_static)
+ continue;
+
+ /* Only check the symbol's kind if it has one. */
+ if (attrs_valid)
{
- offset_type i, len = MAYBE_SWAP (*vec);
- for (i = 0; i < len; ++i)
+ switch (iter->domain)
{
- offset_type cu_index = MAYBE_SWAP (vec[i + 1]);
- struct dwarf2_per_cu_data *per_cu = dw2_get_cu (cu_index);
-
- dw2_instantiate_symtab (objfile, per_cu);
+ case VAR_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION
+ /* Some types are also in VAR_DOMAIN. */
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+ continue;
+ break;
+ case STRUCT_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+ continue;
+ break;
+ case LABEL_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER)
+ continue;
+ break;
+ default:
+ break;
}
}
+
+ ++iter->next;
+ return per_cu;
}
+
+ return NULL;
}
-static void
-dw2_pre_expand_symtabs_matching (struct objfile *objfile,
- enum block_enum block_kind, const char *name,
- domain_enum domain)
+static struct symtab *
+dw2_lookup_symbol (struct objfile *objfile, int block_index,
+ const char *name, domain_enum domain)
{
- dw2_do_expand_symtabs_matching (objfile, name);
+ struct symtab *stab_best = NULL;
+ struct mapped_index *index;
+
+ dw2_setup (objfile);
+
+ index = dwarf2_per_objfile->index_table;
+
+ /* index is NULL if OBJF_READNOW. */
+ if (index)
+ {
+ struct dw2_symtab_iterator iter;
+ struct dwarf2_per_cu_data *per_cu;
+
+ dw2_symtab_iter_init (&iter, index, 1, block_index, domain, name);
+
+ while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
+ {
+ struct symbol *sym = NULL;
+ struct symtab *stab = dw2_instantiate_symtab (per_cu);
+
+ /* Some caution must be observed with overloaded functions
+ and methods, since the index will not contain any overload
+ information (but NAME might contain it). */
+ if (stab->primary)
+ {
+ struct blockvector *bv = BLOCKVECTOR (stab);
+ struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
+
+ sym = lookup_block_symbol (block, name, domain);
+ }
+
+ if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
+ {
+ if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ return stab;
+
+ stab_best = stab;
+ }
+
+ /* Keep looking through other CUs. */
+ }
+ }
+
+ return stab_best;
}
static void
@@ -2611,7 +3285,7 @@ dw2_print_stats (struct objfile *objfile)
dw2_setup (objfile);
count = 0;
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
@@ -2638,7 +3312,25 @@ static void
dw2_expand_symtabs_for_function (struct objfile *objfile,
const char *func_name)
{
- dw2_do_expand_symtabs_matching (objfile, func_name);
+ struct mapped_index *index;
+
+ dw2_setup (objfile);
+
+ index = dwarf2_per_objfile->index_table;
+
+ /* index is NULL if OBJF_READNOW. */
+ if (index)
+ {
+ struct dw2_symtab_iterator iter;
+ struct dwarf2_per_cu_data *per_cu;
+
+ /* Note: It doesn't matter what we pass for block_index here. */
+ dw2_symtab_iter_init (&iter, index, 0, GLOBAL_BLOCK, VAR_DOMAIN,
+ func_name);
+
+ while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
+ dw2_instantiate_symtab (per_cu);
+ }
}
static void
@@ -2649,17 +3341,17 @@ dw2_expand_all_symtabs (struct objfile *objfile)
dw2_setup (objfile);
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
- dw2_instantiate_symtab (objfile, per_cu);
+ dw2_instantiate_symtab (per_cu);
}
}
static void
-dw2_expand_symtabs_with_filename (struct objfile *objfile,
- const char *filename)
+dw2_expand_symtabs_with_fullname (struct objfile *objfile,
+ const char *fullname)
{
int i;
@@ -2686,22 +3378,44 @@ dw2_expand_symtabs_with_filename (struct objfile *objfile,
for (j = 0; j < file_data->num_file_names; ++j)
{
- const char *this_name = file_data->file_names[j];
- if (FILENAME_CMP (this_name, filename) == 0)
+ const char *this_fullname = file_data->file_names[j];
+
+ if (filename_cmp (this_fullname, fullname) == 0)
{
- dw2_instantiate_symtab (objfile, per_cu);
+ dw2_instantiate_symtab (per_cu);
break;
}
}
}
}
+/* A helper function for dw2_find_symbol_file that finds the primary
+ file name for a given CU. This is a die_reader_func. */
+
+static void
+dw2_get_primary_filename_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
+{
+ const char **result_ptr = data;
+ struct dwarf2_cu *cu = reader->cu;
+ struct attribute *attr;
+
+ attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
+ if (attr == NULL)
+ *result_ptr = NULL;
+ else
+ *result_ptr = DW_STRING (attr);
+}
+
static const char *
dw2_find_symbol_file (struct objfile *objfile, const char *name)
{
struct dwarf2_per_cu_data *per_cu;
offset_type *vec;
- struct quick_file_names *file_data;
+ const char *filename;
dw2_setup (objfile);
@@ -2710,16 +3424,18 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name)
{
struct symtab *s;
- ALL_OBJFILE_SYMTABS (objfile, s)
- if (s->primary)
- {
- struct blockvector *bv = BLOCKVECTOR (s);
- const struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- struct symbol *sym = lookup_block_symbol (block, name, VAR_DOMAIN);
+ ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s)
+ {
+ struct blockvector *bv = BLOCKVECTOR (s);
+ const struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ struct symbol *sym = lookup_block_symbol (block, name, VAR_DOMAIN);
- if (sym)
- return sym->symtab->filename;
- }
+ if (sym)
+ {
+ /* Only file extension of returned filename is recognized. */
+ return SYMBOL_SYMTAB (sym)->filename;
+ }
+ }
return NULL;
}
@@ -2732,13 +3448,19 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name)
should be rewritten so that it doesn't require a custom hook. It
could just use the ordinary symbol tables. */
/* vec[0] is the length, which must always be >0. */
- per_cu = dw2_get_cu (MAYBE_SWAP (vec[1]));
+ per_cu = dw2_get_cu (GDB_INDEX_CU_VALUE (MAYBE_SWAP (vec[1])));
- file_data = dw2_get_file_names (objfile, per_cu);
- if (file_data == NULL)
- return NULL;
+ if (per_cu->v.quick->symtab != NULL)
+ {
+ /* Only file extension of returned filename is recognized. */
+ return per_cu->v.quick->symtab->filename;
+ }
+
+ init_cutu_and_read_dies (per_cu, NULL, 0, 0,
+ dw2_get_primary_filename_reader, &filename);
- return file_data->file_names[file_data->num_file_names - 1];
+ /* Only file extension of returned filename is recognized. */
+ return filename;
}
static void
@@ -2757,8 +3479,8 @@ dw2_map_matching_symbols (const char * name, domain_enum namespace,
static void
dw2_expand_symtabs_matching
(struct objfile *objfile,
- int (*file_matcher) (const char *, void *),
- int (*name_matcher) (const struct language_defn *, const char *, void *),
+ int (*file_matcher) (const char *, void *, int basenames),
+ int (*name_matcher) (const char *, void *),
enum search_domain kind,
void *data)
{
@@ -2774,32 +3496,81 @@ dw2_expand_symtabs_matching
index = dwarf2_per_objfile->index_table;
if (file_matcher != NULL)
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
- {
- int j;
- struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
- struct quick_file_names *file_data;
+ {
+ struct cleanup *cleanup;
+ htab_t visited_found, visited_not_found;
- per_cu->v.quick->mark = 0;
+ visited_found = htab_create_alloc (10,
+ htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (visited_found);
+ visited_not_found = htab_create_alloc (10,
+ htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ make_cleanup_htab_delete (visited_not_found);
- /* We only need to look at symtabs not already expanded. */
- if (per_cu->v.quick->symtab)
- continue;
+ /* The rule is CUs specify all the files, including those used by
+ any TU, so there's no need to scan TUs here. */
- file_data = dw2_get_file_names (objfile, per_cu);
- if (file_data == NULL)
- continue;
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ {
+ int j;
+ struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i);
+ struct quick_file_names *file_data;
+ void **slot;
- for (j = 0; j < file_data->num_file_names; ++j)
- {
- if (file_matcher (file_data->file_names[j], data))
- {
- per_cu->v.quick->mark = 1;
- break;
- }
- }
- }
+ per_cu->v.quick->mark = 0;
+
+ /* We only need to look at symtabs not already expanded. */
+ if (per_cu->v.quick->symtab)
+ continue;
+
+ file_data = dw2_get_file_names (objfile, per_cu);
+ if (file_data == NULL)
+ continue;
+
+ if (htab_find (visited_not_found, file_data) != NULL)
+ continue;
+ else if (htab_find (visited_found, file_data) != NULL)
+ {
+ per_cu->v.quick->mark = 1;
+ continue;
+ }
+
+ for (j = 0; j < file_data->num_file_names; ++j)
+ {
+ const char *this_real_name;
+
+ if (file_matcher (file_data->file_names[j], data, 0))
+ {
+ per_cu->v.quick->mark = 1;
+ break;
+ }
+
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (!basenames_may_differ
+ && !file_matcher (lbasename (file_data->file_names[j]),
+ data, 1))
+ continue;
+
+ this_real_name = dw2_get_real_path (objfile, file_data, j);
+ if (file_matcher (this_real_name, data, 0))
+ {
+ per_cu->v.quick->mark = 1;
+ break;
+ }
+ }
+
+ slot = htab_find_slot (per_cu->v.quick->mark
+ ? visited_found
+ : visited_not_found,
+ file_data, INSERT);
+ *slot = file_data;
+ }
+
+ do_cleanups (cleanup);
+ }
for (iter = 0; iter < index->symbol_table_slots; ++iter)
{
@@ -2812,7 +3583,7 @@ dw2_expand_symtabs_matching
name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
- if (! (*name_matcher) (current_language, name, data))
+ if (! (*name_matcher) (name, data))
continue;
/* The name was matched, now expand corresponding CUs that were
@@ -2823,14 +3594,73 @@ dw2_expand_symtabs_matching
for (vec_idx = 0; vec_idx < vec_len; ++vec_idx)
{
struct dwarf2_per_cu_data *per_cu;
+ offset_type cu_index_and_attrs = MAYBE_SWAP (vec[vec_idx + 1]);
+ gdb_index_symbol_kind symbol_kind =
+ GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
+ int cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
+
+ /* Don't crash on bad data. */
+ if (cu_index >= (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_type_units))
+ continue;
+
+ /* Only check the symbol's kind if it has one.
+ Indices prior to version 7 don't record it. */
+ if (index->version >= 7)
+ {
+ switch (kind)
+ {
+ case VARIABLES_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE)
+ continue;
+ break;
+ case FUNCTIONS_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION)
+ continue;
+ break;
+ case TYPES_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
- per_cu = dw2_get_cu (MAYBE_SWAP (vec[vec_idx + 1]));
+ per_cu = dw2_get_cu (cu_index);
if (file_matcher == NULL || per_cu->v.quick->mark)
- dw2_instantiate_symtab (objfile, per_cu);
+ dw2_instantiate_symtab (per_cu);
}
}
}
+/* A helper for dw2_find_pc_sect_symtab which finds the most specific
+ symtab. */
+
+static struct symtab *
+recursively_find_pc_sect_symtab (struct symtab *symtab, CORE_ADDR pc)
+{
+ int i;
+
+ if (BLOCKVECTOR (symtab) != NULL
+ && blockvector_contains_pc (BLOCKVECTOR (symtab), pc))
+ return symtab;
+
+ if (symtab->includes == NULL)
+ return NULL;
+
+ for (i = 0; symtab->includes[i]; ++i)
+ {
+ struct symtab *s = symtab->includes[i];
+
+ s = recursively_find_pc_sect_symtab (s, pc);
+ if (s != NULL)
+ return s;
+ }
+
+ return NULL;
+}
+
static struct symtab *
dw2_find_pc_sect_symtab (struct objfile *objfile,
struct minimal_symbol *msymbol,
@@ -2839,6 +3669,7 @@ dw2_find_pc_sect_symtab (struct objfile *objfile,
int warn_if_readin)
{
struct dwarf2_per_cu_data *data;
+ struct symtab *result;
dw2_setup (objfile);
@@ -2853,7 +3684,9 @@ dw2_find_pc_sect_symtab (struct objfile *objfile,
warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
paddress (get_objfile_arch (objfile), pc));
- return dw2_instantiate_symtab (objfile, data);
+ result = recursively_find_pc_sect_symtab (dw2_instantiate_symtab (data), pc);
+ gdb_assert (result != NULL);
+ return result;
}
static void
@@ -2861,15 +3694,36 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
void *data, int need_fullname)
{
int i;
+ struct cleanup *cleanup;
+ htab_t visited = htab_create_alloc (10, htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (visited);
dw2_setup (objfile);
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ /* The rule is CUs specify all the files, including those used by
+ any TU, so there's no need to scan TUs here.
+ We can ignore file names coming from already-expanded CUs. */
+
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
- int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+
+ if (per_cu->v.quick->symtab)
+ {
+ void **slot = htab_find_slot (visited, per_cu->v.quick->file_names,
+ INSERT);
+
+ *slot = per_cu->v.quick->file_names;
+ }
+ }
+
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ {
+ int j;
+ struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i);
struct quick_file_names *file_data;
+ void **slot;
/* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->symtab)
@@ -2879,6 +3733,14 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
if (file_data == NULL)
continue;
+ slot = htab_find_slot (visited, file_data, INSERT);
+ if (*slot)
+ {
+ /* Already visited. */
+ continue;
+ }
+ *slot = file_data;
+
for (j = 0; j < file_data->num_file_names; ++j)
{
const char *this_real_name;
@@ -2890,6 +3752,8 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
(*fun) (file_data->file_names[j], this_real_name, data);
}
}
+
+ do_cleanups (cleanup);
}
static int
@@ -2905,13 +3769,12 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions =
dw2_forget_cached_source_info,
dw2_map_symtabs_matching_filename,
dw2_lookup_symbol,
- dw2_pre_expand_symtabs_matching,
dw2_print_stats,
dw2_dump,
dw2_relocate,
dw2_expand_symtabs_for_function,
dw2_expand_all_symtabs,
- dw2_expand_symtabs_with_filename,
+ dw2_expand_symtabs_with_fullname,
dw2_find_symbol_file,
dw2_map_matching_symbols,
dw2_expand_symtabs_matching,
@@ -2935,12 +3798,12 @@ dwarf2_initialize_objfile (struct objfile *objfile)
dwarf2_per_objfile->using_index = 1;
create_all_comp_units (objfile);
- create_debug_types_hash_table (objfile);
+ create_all_type_units (objfile);
dwarf2_per_objfile->quick_file_names_table =
create_quick_file_names_table (dwarf2_per_objfile->n_comp_units);
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
@@ -2967,25 +3830,75 @@ dwarf2_initialize_objfile (struct objfile *objfile)
void
dwarf2_build_psymtabs (struct objfile *objfile)
{
+ volatile struct gdb_exception except;
+
if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)
{
init_psymbol_list (objfile, 1024);
}
- dwarf2_build_psymtabs_hard (objfile);
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ /* This isn't really ideal: all the data we allocate on the
+ objfile's obstack is still uselessly kept around. However,
+ freeing it seems unsafe. */
+ struct cleanup *cleanups = make_cleanup_discard_psymtabs (objfile);
+
+ dwarf2_build_psymtabs_hard (objfile);
+ discard_cleanups (cleanups);
+ }
+ if (except.reason < 0)
+ exception_print (gdb_stderr, except);
+}
+
+/* Return the total length of the CU described by HEADER. */
+
+static unsigned int
+get_cu_length (const struct comp_unit_head *header)
+{
+ return header->initial_length_size + header->length;
}
/* Return TRUE if OFFSET is within CU_HEADER. */
static inline int
-offset_in_cu_p (const struct comp_unit_head *cu_header, unsigned int offset)
+offset_in_cu_p (const struct comp_unit_head *cu_header, sect_offset offset)
+{
+ sect_offset bottom = { cu_header->offset.sect_off };
+ sect_offset top = { cu_header->offset.sect_off + get_cu_length (cu_header) };
+
+ return (offset.sect_off >= bottom.sect_off && offset.sect_off < top.sect_off);
+}
+
+/* Find the base address of the compilation unit for range lists and
+ location lists. It will normally be specified by DW_AT_low_pc.
+ In DWARF-3 draft 4, the base address could be overridden by
+ DW_AT_entry_pc. It's been removed, but GCC still uses this for
+ compilation units with discontinuous ranges. */
+
+static void
+dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
{
- unsigned int bottom = cu_header->offset;
- unsigned int top = (cu_header->offset
- + cu_header->length
- + cu_header->initial_length_size);
+ struct attribute *attr;
- return (offset >= bottom && offset < top);
+ cu->base_known = 0;
+ cu->base_address = 0;
+
+ attr = dwarf2_attr (die, DW_AT_entry_pc, cu);
+ if (attr)
+ {
+ cu->base_address = DW_ADDR (attr);
+ cu->base_known = 1;
+ }
+ else
+ {
+ attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+ if (attr)
+ {
+ cu->base_address = DW_ADDR (attr);
+ cu->base_known = 1;
+ }
+ }
}
/* Read in the comp unit header information from the debug_info at info_ptr.
@@ -3005,8 +3918,8 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
info_ptr += bytes_read;
cu_header->version = read_2_bytes (abfd, info_ptr);
info_ptr += 2;
- cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header,
- &bytes_read);
+ cu_header->abbrev_offset.sect_off = read_offset (abfd, info_ptr, cu_header,
+ &bytes_read);
info_ptr += bytes_read;
cu_header->addr_size = read_1_byte (abfd, info_ptr);
info_ptr += 1;
@@ -3019,47 +3932,82 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
return info_ptr;
}
-/* Read in a CU header and perform some basic error checking. */
+/* Helper function that returns the proper abbrev section for
+ THIS_CU. */
-static gdb_byte *
-partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr,
- gdb_byte *buffer, unsigned int buffer_size,
- bfd *abfd, int is_debug_types_section)
+static struct dwarf2_section_info *
+get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
{
- gdb_byte *beg_of_comp_unit = info_ptr;
+ struct dwarf2_section_info *abbrev;
- header->offset = beg_of_comp_unit - buffer;
+ if (this_cu->is_dwz)
+ abbrev = &dwarf2_get_dwz_file ()->abbrev;
+ else
+ abbrev = &dwarf2_per_objfile->abbrev;
- info_ptr = read_comp_unit_head (header, info_ptr, abfd);
+ return abbrev;
+}
- /* If we're reading a type unit, skip over the signature and
- type_offset fields. */
- if (is_debug_types_section)
- info_ptr += 8 /*signature*/ + header->offset_size;
+/* Subroutine of read_and_check_comp_unit_head and
+ read_and_check_type_unit_head to simplify them.
+ Perform various error checking on the header. */
- header->first_die_offset = info_ptr - beg_of_comp_unit;
+static void
+error_check_comp_unit_head (struct comp_unit_head *header,
+ struct dwarf2_section_info *section,
+ struct dwarf2_section_info *abbrev_section)
+{
+ bfd *abfd = section->asection->owner;
+ const char *filename = bfd_get_filename (abfd);
if (header->version != 2 && header->version != 3 && header->version != 4)
error (_("Dwarf Error: wrong version in compilation unit header "
"(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
- bfd_get_filename (abfd));
+ filename);
- if (header->abbrev_offset
- >= dwarf2_section_size (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->abbrev))
+ if (header->abbrev_offset.sect_off
+ >= dwarf2_section_size (dwarf2_per_objfile->objfile, abbrev_section))
error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
"(offset 0x%lx + 6) [in module %s]"),
- (long) header->abbrev_offset,
- (long) (beg_of_comp_unit - buffer),
- bfd_get_filename (abfd));
+ (long) header->abbrev_offset.sect_off, (long) header->offset.sect_off,
+ filename);
- if (beg_of_comp_unit + header->length + header->initial_length_size
- > buffer + buffer_size)
+ /* Cast to unsigned long to use 64-bit arithmetic when possible to
+ avoid potential 32-bit overflow. */
+ if (((unsigned long) header->offset.sect_off + get_cu_length (header))
+ > section->size)
error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
"(offset 0x%lx + 0) [in module %s]"),
- (long) header->length,
- (long) (beg_of_comp_unit - buffer),
- bfd_get_filename (abfd));
+ (long) header->length, (long) header->offset.sect_off,
+ filename);
+}
+
+/* Read in a CU/TU header and perform some basic error checking.
+ The contents of the header are stored in HEADER.
+ The result is a pointer to the start of the first DIE. */
+
+static gdb_byte *
+read_and_check_comp_unit_head (struct comp_unit_head *header,
+ struct dwarf2_section_info *section,
+ struct dwarf2_section_info *abbrev_section,
+ gdb_byte *info_ptr,
+ int is_debug_types_section)
+{
+ gdb_byte *beg_of_comp_unit = info_ptr;
+ bfd *abfd = section->asection->owner;
+
+ header->offset.sect_off = beg_of_comp_unit - section->buffer;
+
+ info_ptr = read_comp_unit_head (header, info_ptr, abfd);
+
+ /* If we're reading a type unit, skip over the signature and
+ type_offset fields. */
+ if (is_debug_types_section)
+ info_ptr += 8 /*signature*/ + header->offset_size;
+
+ header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
+
+ error_check_comp_unit_head (header, section, abbrev_section);
return info_ptr;
}
@@ -3068,35 +4016,72 @@ partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr,
types_ptr. The result is a pointer to one past the end of the header. */
static gdb_byte *
-read_type_comp_unit_head (struct comp_unit_head *cu_header,
- struct dwarf2_section_info *section,
- ULONGEST *signature,
- gdb_byte *types_ptr, bfd *abfd)
+read_and_check_type_unit_head (struct comp_unit_head *header,
+ struct dwarf2_section_info *section,
+ struct dwarf2_section_info *abbrev_section,
+ gdb_byte *info_ptr,
+ ULONGEST *signature,
+ cu_offset *type_offset_in_tu)
{
- gdb_byte *initial_types_ptr = types_ptr;
+ gdb_byte *beg_of_comp_unit = info_ptr;
+ bfd *abfd = section->asection->owner;
- dwarf2_read_section (dwarf2_per_objfile->objfile, section);
- cu_header->offset = types_ptr - section->buffer;
+ header->offset.sect_off = beg_of_comp_unit - section->buffer;
+
+ info_ptr = read_comp_unit_head (header, info_ptr, abfd);
+
+ /* If we're reading a type unit, skip over the signature and
+ type_offset fields. */
+ if (signature != NULL)
+ *signature = read_8_bytes (abfd, info_ptr);
+ info_ptr += 8;
+ if (type_offset_in_tu != NULL)
+ type_offset_in_tu->cu_off = read_offset_1 (abfd, info_ptr,
+ header->offset_size);
+ info_ptr += header->offset_size;
- types_ptr = read_comp_unit_head (cu_header, types_ptr, abfd);
+ header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
- *signature = read_8_bytes (abfd, types_ptr);
- types_ptr += 8;
- types_ptr += cu_header->offset_size;
- cu_header->first_die_offset = types_ptr - initial_types_ptr;
+ error_check_comp_unit_head (header, section, abbrev_section);
- return types_ptr;
+ return info_ptr;
}
-/* Allocate a new partial symtab for file named NAME and mark this new
- partial symtab as being an include of PST. */
+/* Fetch the abbreviation table offset from a comp or type unit header. */
-static void
-dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst,
- struct objfile *objfile)
+static sect_offset
+read_abbrev_offset (struct dwarf2_section_info *section,
+ sect_offset offset)
+{
+ bfd *abfd = section->asection->owner;
+ gdb_byte *info_ptr;
+ unsigned int length, initial_length_size, offset_size;
+ sect_offset abbrev_offset;
+
+ dwarf2_read_section (dwarf2_per_objfile->objfile, section);
+ info_ptr = section->buffer + offset.sect_off;
+ length = read_initial_length (abfd, info_ptr, &initial_length_size);
+ offset_size = initial_length_size == 4 ? 4 : 8;
+ info_ptr += initial_length_size + 2 /*version*/;
+ abbrev_offset.sect_off = read_offset_1 (abfd, info_ptr, offset_size);
+ return abbrev_offset;
+}
+
+/* Allocate a new partial symtab for file named NAME and mark this new
+ partial symtab as being an include of PST. */
+
+static void
+dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst,
+ struct objfile *objfile)
{
struct partial_symtab *subpst = allocate_psymtab (name, objfile);
+ if (!IS_ABSOLUTE_PATH (subpst->filename))
+ {
+ /* It shares objfile->objfile_obstack. */
+ subpst->dirname = pst->dirname;
+ }
+
subpst->section_offsets = pst->section_offsets;
subpst->textlow = 0;
subpst->texthigh = 0;
@@ -3127,21 +4112,15 @@ dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst,
static void
dwarf2_build_include_psymtabs (struct dwarf2_cu *cu,
- struct die_info *die,
- struct partial_symtab *pst)
+ struct die_info *die,
+ struct partial_symtab *pst)
{
- struct objfile *objfile = cu->objfile;
- bfd *abfd = objfile->obfd;
struct line_header *lh = NULL;
struct attribute *attr;
attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
if (attr)
- {
- unsigned int line_offset = DW_UNSND (attr);
-
- lh = dwarf_decode_line_header (line_offset, abfd, cu);
- }
+ lh = dwarf_decode_line_header (DW_UNSND (attr), cu);
if (lh == NULL)
return; /* No linetable, so no includes. */
@@ -3152,16 +4131,16 @@ dwarf2_build_include_psymtabs (struct dwarf2_cu *cu,
}
static hashval_t
-hash_type_signature (const void *item)
+hash_signatured_type (const void *item)
{
- const struct signatured_type *type_sig = item;
+ const struct signatured_type *sig_type = item;
/* This drops the top 32 bits of the signature, but is ok for a hash. */
- return type_sig->signature;
+ return sig_type->signature;
}
static int
-eq_type_signature (const void *item_lhs, const void *item_rhs)
+eq_signatured_type (const void *item_lhs, const void *item_rhs)
{
const struct signatured_type *lhs = item_lhs;
const struct signatured_type *rhs = item_rhs;
@@ -3175,52 +4154,64 @@ static htab_t
allocate_signatured_type_table (struct objfile *objfile)
{
return htab_create_alloc_ex (41,
- hash_type_signature,
- eq_type_signature,
+ hash_signatured_type,
+ eq_signatured_type,
NULL,
&objfile->objfile_obstack,
hashtab_obstack_allocate,
dummy_obstack_deallocate);
}
-/* A helper function to add a signatured type CU to a list. */
+/* A helper function to add a signatured type CU to a table. */
static int
-add_signatured_type_cu_to_list (void **slot, void *datum)
+add_signatured_type_cu_to_table (void **slot, void *datum)
{
struct signatured_type *sigt = *slot;
- struct dwarf2_per_cu_data ***datap = datum;
+ struct signatured_type ***datap = datum;
- **datap = &sigt->per_cu;
+ **datap = sigt;
++*datap;
return 1;
}
/* Create the hash table of all entries in the .debug_types section.
- The result is zero if there is an error (e.g. missing .debug_types section),
- otherwise non-zero. */
+ DWO_FILE is a pointer to the DWO file for .debug_types.dwo,
+ NULL otherwise.
+ Note: This function processes DWO files only, not DWP files.
+ The result is a pointer to the hash table or NULL if there are
+ no types. */
-static int
-create_debug_types_hash_table (struct objfile *objfile)
+static htab_t
+create_debug_types_hash_table (struct dwo_file *dwo_file,
+ VEC (dwarf2_section_info_def) *types)
{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
htab_t types_htab = NULL;
- struct dwarf2_per_cu_data **iter;
int ix;
struct dwarf2_section_info *section;
+ struct dwarf2_section_info *abbrev_section;
- if (VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types))
- {
- dwarf2_per_objfile->signatured_types = NULL;
- return 0;
- }
+ if (VEC_empty (dwarf2_section_info_def, types))
+ return NULL;
+
+ abbrev_section = (dwo_file != NULL
+ ? &dwo_file->sections.abbrev
+ : &dwarf2_per_objfile->abbrev);
+
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "Reading .debug_types%s for %s:\n",
+ dwo_file ? ".dwo" : "",
+ bfd_get_filename (abbrev_section->asection->owner));
for (ix = 0;
- VEC_iterate (dwarf2_section_info_def, dwarf2_per_objfile->types,
- ix, section);
+ VEC_iterate (dwarf2_section_info_def, types, ix, section);
++ix)
{
+ bfd *abfd;
gdb_byte *info_ptr, *end_ptr;
+ struct dwarf2_section_info *abbrev_section;
dwarf2_read_section (objfile, section);
info_ptr = section->buffer;
@@ -3228,110 +4219,166 @@ create_debug_types_hash_table (struct objfile *objfile)
if (info_ptr == NULL)
continue;
+ /* We can't set abfd until now because the section may be empty or
+ not present, in which case section->asection will be NULL. */
+ abfd = section->asection->owner;
+
+ if (dwo_file)
+ abbrev_section = &dwo_file->sections.abbrev;
+ else
+ abbrev_section = &dwarf2_per_objfile->abbrev;
+
if (types_htab == NULL)
- types_htab = allocate_signatured_type_table (objfile);
+ {
+ if (dwo_file)
+ types_htab = allocate_dwo_unit_table (objfile);
+ else
+ types_htab = allocate_signatured_type_table (objfile);
+ }
- if (dwarf2_die_debug)
- fprintf_unfiltered (gdb_stdlog, "Signatured types:\n");
+ /* We don't use init_cutu_and_read_dies_simple, or some such, here
+ because we don't need to read any dies: the signature is in the
+ header. */
end_ptr = info_ptr + section->size;
while (info_ptr < end_ptr)
{
- unsigned int offset;
- unsigned int offset_size;
- unsigned int type_offset;
- unsigned int length, initial_length_size;
- unsigned short version;
+ sect_offset offset;
+ cu_offset type_offset_in_tu;
ULONGEST signature;
- struct signatured_type *type_sig;
+ struct signatured_type *sig_type;
+ struct dwo_unit *dwo_tu;
void **slot;
gdb_byte *ptr = info_ptr;
+ struct comp_unit_head header;
+ unsigned int length;
- offset = ptr - section->buffer;
+ offset.sect_off = ptr - section->buffer;
/* We need to read the type's signature in order to build the hash
- table, but we don't need to read anything else just yet. */
+ table, but we don't need anything else just yet. */
- /* Sanity check to ensure entire cu is present. */
- length = read_initial_length (objfile->obfd, ptr,
- &initial_length_size);
- if (ptr + length + initial_length_size > end_ptr)
- {
- complaint (&symfile_complaints,
- _("debug type entry runs off end "
- "of `.debug_types' section, ignored"));
- break;
- }
+ ptr = read_and_check_type_unit_head (&header, section,
+ abbrev_section, ptr,
+ &signature, &type_offset_in_tu);
- offset_size = initial_length_size == 4 ? 4 : 8;
- ptr += initial_length_size;
- version = bfd_get_16 (objfile->obfd, ptr);
- ptr += 2;
- ptr += offset_size; /* abbrev offset */
- ptr += 1; /* address size */
- signature = bfd_get_64 (objfile->obfd, ptr);
- ptr += 8;
- type_offset = read_offset_1 (objfile->obfd, ptr, offset_size);
- ptr += offset_size;
+ length = get_cu_length (&header);
/* Skip dummy type units. */
- if (ptr >= end_ptr || peek_abbrev_code (objfile->obfd, ptr) == 0)
+ if (ptr >= info_ptr + length
+ || peek_abbrev_code (abfd, ptr) == 0)
{
- info_ptr = info_ptr + initial_length_size + length;
+ info_ptr += length;
continue;
}
- type_sig = obstack_alloc (&objfile->objfile_obstack, sizeof (*type_sig));
- memset (type_sig, 0, sizeof (*type_sig));
- type_sig->signature = signature;
- type_sig->type_offset = type_offset;
- type_sig->per_cu.objfile = objfile;
- type_sig->per_cu.debug_types_section = section;
- type_sig->per_cu.offset = offset;
+ if (dwo_file)
+ {
+ sig_type = NULL;
+ dwo_tu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwo_unit);
+ dwo_tu->dwo_file = dwo_file;
+ dwo_tu->signature = signature;
+ dwo_tu->type_offset_in_tu = type_offset_in_tu;
+ dwo_tu->info_or_types_section = section;
+ dwo_tu->offset = offset;
+ dwo_tu->length = length;
+ }
+ else
+ {
+ /* N.B.: type_offset is not usable if this type uses a DWO file.
+ The real type_offset is in the DWO file. */
+ dwo_tu = NULL;
+ sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct signatured_type);
+ sig_type->signature = signature;
+ sig_type->type_offset_in_tu = type_offset_in_tu;
+ sig_type->per_cu.objfile = objfile;
+ sig_type->per_cu.is_debug_types = 1;
+ sig_type->per_cu.info_or_types_section = section;
+ sig_type->per_cu.offset = offset;
+ sig_type->per_cu.length = length;
+ }
- slot = htab_find_slot (types_htab, type_sig, INSERT);
+ slot = htab_find_slot (types_htab,
+ dwo_file ? (void*) dwo_tu : (void *) sig_type,
+ INSERT);
gdb_assert (slot != NULL);
if (*slot != NULL)
{
- const struct signatured_type *dup_sig = *slot;
+ sect_offset dup_offset;
+
+ if (dwo_file)
+ {
+ const struct dwo_unit *dup_tu = *slot;
+
+ dup_offset = dup_tu->offset;
+ }
+ else
+ {
+ const struct signatured_type *dup_tu = *slot;
+
+ dup_offset = dup_tu->per_cu.offset;
+ }
complaint (&symfile_complaints,
_("debug type entry at offset 0x%x is duplicate to the "
"entry at offset 0x%x, signature 0x%s"),
- offset, dup_sig->per_cu.offset,
+ offset.sect_off, dup_offset.sect_off,
phex (signature, sizeof (signature)));
- gdb_assert (signature == dup_sig->signature);
}
- *slot = type_sig;
+ *slot = dwo_file ? (void *) dwo_tu : (void *) sig_type;
- if (dwarf2_die_debug)
+ if (dwarf2_read_debug)
fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n",
- offset, phex (signature, sizeof (signature)));
+ offset.sect_off,
+ phex (signature, sizeof (signature)));
- info_ptr = info_ptr + initial_length_size + length;
+ info_ptr += length;
}
}
+ return types_htab;
+}
+
+/* Create the hash table of all entries in the .debug_types section,
+ and initialize all_type_units.
+ The result is zero if there is an error (e.g. missing .debug_types section),
+ otherwise non-zero. */
+
+static int
+create_all_type_units (struct objfile *objfile)
+{
+ htab_t types_htab;
+ struct signatured_type **iter;
+
+ types_htab = create_debug_types_hash_table (NULL, dwarf2_per_objfile->types);
+ if (types_htab == NULL)
+ {
+ dwarf2_per_objfile->signatured_types = NULL;
+ return 0;
+ }
+
dwarf2_per_objfile->signatured_types = types_htab;
- dwarf2_per_objfile->n_type_comp_units = htab_elements (types_htab);
- dwarf2_per_objfile->type_comp_units
+ dwarf2_per_objfile->n_type_units = htab_elements (types_htab);
+ dwarf2_per_objfile->all_type_units
= obstack_alloc (&objfile->objfile_obstack,
- dwarf2_per_objfile->n_type_comp_units
- * sizeof (struct dwarf2_per_cu_data *));
- iter = &dwarf2_per_objfile->type_comp_units[0];
- htab_traverse_noresize (types_htab, add_signatured_type_cu_to_list, &iter);
- gdb_assert (iter - &dwarf2_per_objfile->type_comp_units[0]
- == dwarf2_per_objfile->n_type_comp_units);
+ dwarf2_per_objfile->n_type_units
+ * sizeof (struct signatured_type *));
+ iter = &dwarf2_per_objfile->all_type_units[0];
+ htab_traverse_noresize (types_htab, add_signatured_type_cu_to_table, &iter);
+ gdb_assert (iter - &dwarf2_per_objfile->all_type_units[0]
+ == dwarf2_per_objfile->n_type_units);
return 1;
}
-/* Lookup a signature based type.
- Returns NULL if SIG is not present in the table. */
+/* Lookup a signature based type for DW_FORM_ref_sig8.
+ Returns NULL if signature SIG is not present in the table. */
static struct signatured_type *
-lookup_signatured_type (struct objfile *objfile, ULONGEST sig)
+lookup_signatured_type (ULONGEST sig)
{
struct signatured_type find_entry, *entry;
@@ -3339,1109 +4386,1919 @@ lookup_signatured_type (struct objfile *objfile, ULONGEST sig)
{
complaint (&symfile_complaints,
_("missing `.debug_types' section for DW_FORM_ref_sig8 die"));
- return 0;
+ return NULL;
}
find_entry.signature = sig;
entry = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
return entry;
}
+
+/* Low level DIE reading support. */
/* Initialize a die_reader_specs struct from a dwarf2_cu struct. */
static void
init_cu_die_reader (struct die_reader_specs *reader,
- struct dwarf2_cu *cu)
+ struct dwarf2_cu *cu,
+ struct dwarf2_section_info *section,
+ struct dwo_file *dwo_file)
{
- reader->abfd = cu->objfile->obfd;
+ gdb_assert (section->readin && section->buffer != NULL);
+ reader->abfd = section->asection->owner;
reader->cu = cu;
- if (cu->per_cu->debug_types_section)
- {
- gdb_assert (cu->per_cu->debug_types_section->readin);
- reader->buffer = cu->per_cu->debug_types_section->buffer;
- }
- else
- {
- gdb_assert (dwarf2_per_objfile->info.readin);
- reader->buffer = dwarf2_per_objfile->info.buffer;
- }
+ reader->dwo_file = dwo_file;
+ reader->die_section = section;
+ reader->buffer = section->buffer;
+ reader->buffer_end = section->buffer + section->size;
}
-/* Find the base address of the compilation unit for range lists and
- location lists. It will normally be specified by DW_AT_low_pc.
- In DWARF-3 draft 4, the base address could be overridden by
- DW_AT_entry_pc. It's been removed, but GCC still uses this for
- compilation units with discontinuous ranges. */
+/* Initialize a CU (or TU) and read its DIEs.
+ If the CU defers to a DWO file, read the DWO file as well.
+
+ ABBREV_TABLE, if non-NULL, is the abbreviation table to use.
+ Otherwise the table specified in the comp unit header is read in and used.
+ This is an optimization for when we already have the abbrev table.
+
+ If USE_EXISTING_CU is non-zero, and THIS_CU->cu is non-NULL, then use it.
+ Otherwise, a new CU is allocated with xmalloc.
+
+ If KEEP is non-zero, then if we allocated a dwarf2_cu we add it to
+ read_in_chain. Otherwise the dwarf2_cu data is freed at the end.
+
+ WARNING: If THIS_CU is a "dummy CU" (used as filler by the incremental
+ linker) then DIE_READER_FUNC will not get called. */
static void
-dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
-{
+init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
+ struct abbrev_table *abbrev_table,
+ int use_existing_cu, int keep,
+ die_reader_func_ftype *die_reader_func,
+ void *data)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_section_info *section = this_cu->info_or_types_section;
+ bfd *abfd = section->asection->owner;
+ struct dwarf2_cu *cu;
+ gdb_byte *begin_info_ptr, *info_ptr;
+ struct die_reader_specs reader;
+ struct die_info *comp_unit_die;
+ int has_children;
struct attribute *attr;
+ struct cleanup *cleanups, *free_cu_cleanup = NULL;
+ struct signatured_type *sig_type = NULL;
+ struct dwarf2_section_info *abbrev_section;
+ /* Non-zero if CU currently points to a DWO file and we need to
+ reread it. When this happens we need to reread the skeleton die
+ before we can reread the DWO file. */
+ int rereading_dwo_cu = 0;
- cu->base_known = 0;
- cu->base_address = 0;
+ if (dwarf2_die_debug)
+ fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset 0x%x\n",
+ this_cu->is_debug_types ? "type" : "comp",
+ this_cu->offset.sect_off);
- attr = dwarf2_attr (die, DW_AT_entry_pc, cu);
- if (attr)
+ if (use_existing_cu)
+ gdb_assert (keep);
+
+ cleanups = make_cleanup (null_cleanup, NULL);
+
+ /* This is cheap if the section is already read in. */
+ dwarf2_read_section (objfile, section);
+
+ begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
+
+ abbrev_section = get_abbrev_section_for_cu (this_cu);
+
+ if (use_existing_cu && this_cu->cu != NULL)
{
- cu->base_address = DW_ADDR (attr);
- cu->base_known = 1;
+ cu = this_cu->cu;
+
+ /* If this CU is from a DWO file we need to start over, we need to
+ refetch the attributes from the skeleton CU.
+ This could be optimized by retrieving those attributes from when we
+ were here the first time: the previous comp_unit_die was stored in
+ comp_unit_obstack. But there's no data yet that we need this
+ optimization. */
+ if (cu->dwo_unit != NULL)
+ rereading_dwo_cu = 1;
}
else
{
- attr = dwarf2_attr (die, DW_AT_low_pc, cu);
- if (attr)
- {
- cu->base_address = DW_ADDR (attr);
- cu->base_known = 1;
- }
- }
-}
+ /* If !use_existing_cu, this_cu->cu must be NULL. */
+ gdb_assert (this_cu->cu == NULL);
-/* Subroutine of process_type_comp_unit and dwarf2_build_psymtabs_hard
- to combine the common parts.
- Process a compilation unit for a psymtab.
- BUFFER is a pointer to the beginning of the dwarf section buffer,
- either .debug_info or debug_types.
- INFO_PTR is a pointer to the start of the CU.
- Returns a pointer to the next CU. */
+ cu = xmalloc (sizeof (*cu));
+ init_one_comp_unit (cu, this_cu);
-static gdb_byte *
-process_psymtab_comp_unit (struct objfile *objfile,
- struct dwarf2_per_cu_data *this_cu,
- gdb_byte *buffer, gdb_byte *info_ptr,
- unsigned int buffer_size)
-{
- bfd *abfd = objfile->obfd;
- gdb_byte *beg_of_comp_unit = info_ptr;
- struct die_info *comp_unit_die;
- struct partial_symtab *pst;
- CORE_ADDR baseaddr;
- struct cleanup *back_to_inner;
- struct dwarf2_cu cu;
- int has_children, has_pc_info;
- struct attribute *attr;
- CORE_ADDR best_lowpc = 0, best_highpc = 0;
- struct die_reader_specs reader_specs;
- const char *filename;
+ /* If an error occurs while loading, release our storage. */
+ free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu);
+ }
- init_one_comp_unit (&cu, objfile);
- back_to_inner = make_cleanup (free_stack_comp_unit, &cu);
+ if (cu->header.first_die_offset.cu_off != 0 && ! rereading_dwo_cu)
+ {
+ /* We already have the header, there's no need to read it in again. */
+ info_ptr += cu->header.first_die_offset.cu_off;
+ }
+ else
+ {
+ if (this_cu->is_debug_types)
+ {
+ ULONGEST signature;
+ cu_offset type_offset_in_tu;
+
+ info_ptr = read_and_check_type_unit_head (&cu->header, section,
+ abbrev_section, info_ptr,
+ &signature,
+ &type_offset_in_tu);
+
+ /* Since per_cu is the first member of struct signatured_type,
+ we can go from a pointer to one to a pointer to the other. */
+ sig_type = (struct signatured_type *) this_cu;
+ gdb_assert (sig_type->signature == signature);
+ gdb_assert (sig_type->type_offset_in_tu.cu_off
+ == type_offset_in_tu.cu_off);
+ gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
+
+ /* LENGTH has not been set yet for type units if we're
+ using .gdb_index. */
+ this_cu->length = get_cu_length (&cu->header);
+
+ /* Establish the type offset that can be used to lookup the type. */
+ sig_type->type_offset_in_section.sect_off =
+ this_cu->offset.sect_off + sig_type->type_offset_in_tu.cu_off;
+ }
+ else
+ {
+ info_ptr = read_and_check_comp_unit_head (&cu->header, section,
+ abbrev_section,
+ info_ptr, 0);
- info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr,
- buffer, buffer_size,
- abfd,
- this_cu->debug_types_section != NULL);
+ gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
+ gdb_assert (this_cu->length == get_cu_length (&cu->header));
+ }
+ }
/* Skip dummy compilation units. */
- if (info_ptr >= buffer + buffer_size
+ if (info_ptr >= begin_info_ptr + this_cu->length
|| peek_abbrev_code (abfd, info_ptr) == 0)
{
- info_ptr = (beg_of_comp_unit + cu.header.length
- + cu.header.initial_length_size);
- do_cleanups (back_to_inner);
- return info_ptr;
+ do_cleanups (cleanups);
+ return;
}
- cu.list_in_scope = &file_symbols;
-
- /* If this compilation unit was already read in, free the
- cached copy in order to read it in again. This is
- necessary because we skipped some symbols when we first
- read in the compilation unit (see load_partial_dies).
- This problem could be avoided, but the benefit is
- unclear. */
- if (this_cu->cu != NULL)
- free_one_cached_comp_unit (this_cu->cu);
-
- /* Note that this is a pointer to our stack frame, being
- added to a global data structure. It will be cleaned up
- in free_stack_comp_unit when we finish with this
- compilation unit. */
- this_cu->cu = &cu;
- cu.per_cu = this_cu;
-
- /* Read the abbrevs for this compilation unit into a table. */
- dwarf2_read_abbrevs (abfd, &cu);
- make_cleanup (dwarf2_free_abbrev_table, &cu);
-
- /* Read the compilation unit die. */
- init_cu_die_reader (&reader_specs, &cu);
- info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr,
- &has_children);
-
- if (this_cu->debug_types_section)
+ /* If we don't have them yet, read the abbrevs for this compilation unit.
+ And if we need to read them now, make sure they're freed when we're
+ done. Note that it's important that if the CU had an abbrev table
+ on entry we don't free it when we're done: Somewhere up the call stack
+ it may be in use. */
+ if (abbrev_table != NULL)
{
- /* LENGTH has not been set yet for type units. */
- gdb_assert (this_cu->offset == cu.header.offset);
- this_cu->length = cu.header.length + cu.header.initial_length_size;
+ gdb_assert (cu->abbrev_table == NULL);
+ gdb_assert (cu->header.abbrev_offset.sect_off
+ == abbrev_table->offset.sect_off);
+ cu->abbrev_table = abbrev_table;
}
- else if (comp_unit_die->tag == DW_TAG_partial_unit)
+ else if (cu->abbrev_table == NULL)
{
- info_ptr = (beg_of_comp_unit + cu.header.length
- + cu.header.initial_length_size);
- do_cleanups (back_to_inner);
- return info_ptr;
+ dwarf2_read_abbrevs (cu, abbrev_section);
+ make_cleanup (dwarf2_free_abbrev_table, cu);
+ }
+ else if (rereading_dwo_cu)
+ {
+ dwarf2_free_abbrev_table (cu);
+ dwarf2_read_abbrevs (cu, abbrev_section);
}
- prepare_one_comp_unit (&cu, comp_unit_die);
-
- /* Allocate a new partial symbol table structure. */
- attr = dwarf2_attr (comp_unit_die, DW_AT_name, &cu);
- if (attr == NULL || !DW_STRING (attr))
- filename = "";
- else
- filename = DW_STRING (attr);
- pst = start_psymtab_common (objfile, objfile->section_offsets,
- filename,
- /* TEXTLOW and TEXTHIGH are set below. */
- 0,
- objfile->global_psymbols.next,
- objfile->static_psymbols.next);
- pst->psymtabs_addrmap_supported = 1;
-
- attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, &cu);
- if (attr != NULL)
- pst->dirname = DW_STRING (attr);
-
- pst->read_symtab_private = this_cu;
+ /* Read the top level CU/TU die. */
+ init_cu_die_reader (&reader, cu, section, NULL);
+ info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
- baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ /* If we have a DWO stub, process it and then read in the DWO file.
+ Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains
+ a DWO CU, that this test will fail. */
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu);
+ if (attr)
+ {
+ const char *dwo_name = DW_STRING (attr);
+ const char *comp_dir_string;
+ struct dwo_unit *dwo_unit;
+ ULONGEST signature; /* Or dwo_id. */
+ struct attribute *comp_dir, *stmt_list, *low_pc, *high_pc, *ranges;
+ int i,num_extra_attrs;
+ struct dwarf2_section_info *dwo_abbrev_section;
+
+ if (has_children)
+ error (_("Dwarf Error: compilation unit with DW_AT_GNU_dwo_name"
+ " has children (offset 0x%x) [in module %s]"),
+ this_cu->offset.sect_off, bfd_get_filename (abfd));
+
+ /* These attributes aren't processed until later:
+ DW_AT_stmt_list, DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges.
+ However, the attribute is found in the stub which we won't have later.
+ In order to not impose this complication on the rest of the code,
+ we read them here and copy them to the DWO CU/TU die. */
+
+ /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
+ DWO file. */
+ stmt_list = NULL;
+ if (! this_cu->is_debug_types)
+ stmt_list = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
+ low_pc = dwarf2_attr (comp_unit_die, DW_AT_low_pc, cu);
+ high_pc = dwarf2_attr (comp_unit_die, DW_AT_high_pc, cu);
+ ranges = dwarf2_attr (comp_unit_die, DW_AT_ranges, cu);
+ comp_dir = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
+
+ /* There should be a DW_AT_addr_base attribute here (if needed).
+ We need the value before we can process DW_FORM_GNU_addr_index. */
+ cu->addr_base = 0;
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_addr_base, cu);
+ if (attr)
+ cu->addr_base = DW_UNSND (attr);
- /* Store the function that reads in the rest of the symbol table. */
- pst->read_symtab = dwarf2_psymtab_to_symtab;
+ /* There should be a DW_AT_ranges_base attribute here (if needed).
+ We need the value before we can process DW_AT_ranges. */
+ cu->ranges_base = 0;
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_ranges_base, cu);
+ if (attr)
+ cu->ranges_base = DW_UNSND (attr);
- this_cu->v.psymtab = pst;
+ if (this_cu->is_debug_types)
+ {
+ gdb_assert (sig_type != NULL);
+ signature = sig_type->signature;
+ }
+ else
+ {
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu);
+ if (! attr)
+ error (_("Dwarf Error: missing dwo_id [in module %s]"),
+ dwo_name);
+ signature = DW_UNSND (attr);
+ }
- dwarf2_find_base_address (comp_unit_die, &cu);
+ /* We may need the comp_dir in order to find the DWO file. */
+ comp_dir_string = NULL;
+ if (comp_dir)
+ comp_dir_string = DW_STRING (comp_dir);
- /* Possibly set the default values of LOWPC and HIGHPC from
- `DW_AT_ranges'. */
- has_pc_info = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc,
- &best_highpc, &cu, pst);
- if (has_pc_info == 1 && best_lowpc < best_highpc)
- /* Store the contiguous range if it is not empty; it can be empty for
- CUs with no code. */
- addrmap_set_empty (objfile->psymtabs_addrmap,
- best_lowpc + baseaddr,
- best_highpc + baseaddr - 1, pst);
+ if (this_cu->is_debug_types)
+ dwo_unit = lookup_dwo_type_unit (sig_type, dwo_name, comp_dir_string);
+ else
+ dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir_string,
+ signature);
- /* Check if comp unit has_children.
- If so, read the rest of the partial symbols from this comp unit.
- If not, there's no more debug_info for this comp unit. */
- if (has_children)
- {
- struct partial_die_info *first_die;
- CORE_ADDR lowpc, highpc;
+ if (dwo_unit == NULL)
+ {
+ error (_("Dwarf Error: CU at offset 0x%x references unknown DWO"
+ " with ID %s [in module %s]"),
+ this_cu->offset.sect_off,
+ phex (signature, sizeof (signature)),
+ objfile->name);
+ }
- lowpc = ((CORE_ADDR) -1);
- highpc = ((CORE_ADDR) 0);
+ /* Set up for reading the DWO CU/TU. */
+ cu->dwo_unit = dwo_unit;
+ section = dwo_unit->info_or_types_section;
+ dwarf2_read_section (objfile, section);
+ begin_info_ptr = info_ptr = section->buffer + dwo_unit->offset.sect_off;
+ dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
+ init_cu_die_reader (&reader, cu, section, dwo_unit->dwo_file);
- first_die = load_partial_dies (abfd, buffer, info_ptr, 1, &cu);
+ if (this_cu->is_debug_types)
+ {
+ ULONGEST signature;
+ cu_offset type_offset_in_tu;
+
+ info_ptr = read_and_check_type_unit_head (&cu->header, section,
+ dwo_abbrev_section,
+ info_ptr,
+ &signature,
+ &type_offset_in_tu);
+ gdb_assert (sig_type->signature == signature);
+ gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+ /* For DWOs coming from DWP files, we don't know the CU length
+ nor the type's offset in the TU until now. */
+ dwo_unit->length = get_cu_length (&cu->header);
+ dwo_unit->type_offset_in_tu = type_offset_in_tu;
+
+ /* Establish the type offset that can be used to lookup the type.
+ For DWO files, we don't know it until now. */
+ sig_type->type_offset_in_section.sect_off =
+ dwo_unit->offset.sect_off + dwo_unit->type_offset_in_tu.cu_off;
+ }
+ else
+ {
+ info_ptr = read_and_check_comp_unit_head (&cu->header, section,
+ dwo_abbrev_section,
+ info_ptr, 0);
+ gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+ /* For DWOs coming from DWP files, we don't know the CU length
+ until now. */
+ dwo_unit->length = get_cu_length (&cu->header);
+ }
- scan_partial_symbols (first_die, &lowpc, &highpc,
- ! has_pc_info, &cu);
+ /* Discard the original CU's abbrev table, and read the DWO's. */
+ if (abbrev_table == NULL)
+ {
+ dwarf2_free_abbrev_table (cu);
+ dwarf2_read_abbrevs (cu, dwo_abbrev_section);
+ }
+ else
+ {
+ dwarf2_read_abbrevs (cu, dwo_abbrev_section);
+ make_cleanup (dwarf2_free_abbrev_table, cu);
+ }
- /* If we didn't find a lowpc, set it to highpc to avoid
- complaints from `maint check'. */
- if (lowpc == ((CORE_ADDR) -1))
- lowpc = highpc;
+ /* Read in the die, but leave space to copy over the attributes
+ from the stub. This has the benefit of simplifying the rest of
+ the code - all the real work is done here. */
+ num_extra_attrs = ((stmt_list != NULL)
+ + (low_pc != NULL)
+ + (high_pc != NULL)
+ + (ranges != NULL)
+ + (comp_dir != NULL));
+ info_ptr = read_full_die_1 (&reader, &comp_unit_die, info_ptr,
+ &has_children, num_extra_attrs);
+
+ /* Copy over the attributes from the stub to the DWO die. */
+ i = comp_unit_die->num_attrs;
+ if (stmt_list != NULL)
+ comp_unit_die->attrs[i++] = *stmt_list;
+ if (low_pc != NULL)
+ comp_unit_die->attrs[i++] = *low_pc;
+ if (high_pc != NULL)
+ comp_unit_die->attrs[i++] = *high_pc;
+ if (ranges != NULL)
+ comp_unit_die->attrs[i++] = *ranges;
+ if (comp_dir != NULL)
+ comp_unit_die->attrs[i++] = *comp_dir;
+ comp_unit_die->num_attrs += num_extra_attrs;
- /* If the compilation unit didn't have an explicit address range,
- then use the information extracted from its child dies. */
- if (! has_pc_info)
+ /* Skip dummy compilation units. */
+ if (info_ptr >= begin_info_ptr + dwo_unit->length
+ || peek_abbrev_code (abfd, info_ptr) == 0)
{
- best_lowpc = lowpc;
- best_highpc = highpc;
+ do_cleanups (cleanups);
+ return;
}
}
- pst->textlow = best_lowpc + baseaddr;
- pst->texthigh = best_highpc + baseaddr;
-
- pst->n_global_syms = objfile->global_psymbols.next -
- (objfile->global_psymbols.list + pst->globals_offset);
- pst->n_static_syms = objfile->static_psymbols.next -
- (objfile->static_psymbols.list + pst->statics_offset);
- sort_pst_symbols (pst);
- info_ptr = (beg_of_comp_unit + cu.header.length
- + cu.header.initial_length_size);
+ die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
- if (this_cu->debug_types_section)
+ if (free_cu_cleanup != NULL)
{
- /* It's not clear we want to do anything with stmt lists here.
- Waiting to see what gcc ultimately does. */
- }
- else
- {
- /* Get the list of files included in the current compilation unit,
- and build a psymtab for each of them. */
- dwarf2_build_include_psymtabs (&cu, comp_unit_die, pst);
- }
+ if (keep)
+ {
+ /* We've successfully allocated this compilation unit. Let our
+ caller clean it up when finished with it. */
+ discard_cleanups (free_cu_cleanup);
- do_cleanups (back_to_inner);
+ /* We can only discard free_cu_cleanup and all subsequent cleanups.
+ So we have to manually free the abbrev table. */
+ dwarf2_free_abbrev_table (cu);
- return info_ptr;
+ /* Link this CU into read_in_chain. */
+ this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+ dwarf2_per_objfile->read_in_chain = this_cu;
+ }
+ else
+ do_cleanups (free_cu_cleanup);
+ }
+
+ do_cleanups (cleanups);
}
-/* Traversal function for htab_traverse_noresize.
- Process one .debug_types comp-unit. */
+/* Read CU/TU THIS_CU in section SECTION,
+ but do not follow DW_AT_GNU_dwo_name if present.
+ DWOP_FILE, if non-NULL, is the DWO/DWP file to read (the caller is assumed
+ to have already done the lookup to find the DWO/DWP file).
-static int
-process_type_comp_unit (void **slot, void *info)
-{
- struct signatured_type *entry = (struct signatured_type *) *slot;
- struct objfile *objfile = (struct objfile *) info;
- struct dwarf2_per_cu_data *this_cu;
+ The caller is required to fill in THIS_CU->section, THIS_CU->offset, and
+ THIS_CU->is_debug_types, but nothing else.
- this_cu = &entry->per_cu;
+ We fill in THIS_CU->length.
- gdb_assert (this_cu->debug_types_section->readin);
- process_psymtab_comp_unit (objfile, this_cu,
- this_cu->debug_types_section->buffer,
- (this_cu->debug_types_section->buffer
- + this_cu->offset),
- this_cu->debug_types_section->size);
+ WARNING: If THIS_CU is a "dummy CU" (used as filler by the incremental
+ linker) then DIE_READER_FUNC will not get called.
- return 1;
-}
-
-/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
- Build partial symbol tables for the .debug_types comp-units. */
+ THIS_CU->cu is always freed when done.
+ This is done in order to not leave THIS_CU->cu in a state where we have
+ to care whether it refers to the "main" CU or the DWO CU. */
static void
-build_type_psymtabs (struct objfile *objfile)
+init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
+ struct dwarf2_section_info *abbrev_section,
+ struct dwo_file *dwo_file,
+ die_reader_func_ftype *die_reader_func,
+ void *data)
{
- if (! create_debug_types_hash_table (objfile))
- return;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_section_info *section = this_cu->info_or_types_section;
+ bfd *abfd = section->asection->owner;
+ struct dwarf2_cu cu;
+ gdb_byte *begin_info_ptr, *info_ptr;
+ struct die_reader_specs reader;
+ struct cleanup *cleanups;
+ struct die_info *comp_unit_die;
+ int has_children;
- htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
- process_type_comp_unit, objfile);
-}
+ if (dwarf2_die_debug)
+ fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset 0x%x\n",
+ this_cu->is_debug_types ? "type" : "comp",
+ this_cu->offset.sect_off);
-/* A cleanup function that clears objfile's psymtabs_addrmap field. */
+ gdb_assert (this_cu->cu == NULL);
-static void
-psymtabs_addrmap_cleanup (void *o)
-{
- struct objfile *objfile = o;
+ /* This is cheap if the section is already read in. */
+ dwarf2_read_section (objfile, section);
- objfile->psymtabs_addrmap = NULL;
-}
+ init_one_comp_unit (&cu, this_cu);
-/* Build the partial symbol table by doing a quick pass through the
- .debug_info and .debug_abbrev sections. */
+ cleanups = make_cleanup (free_stack_comp_unit, &cu);
-static void
-dwarf2_build_psymtabs_hard (struct objfile *objfile)
-{
- gdb_byte *info_ptr;
- struct cleanup *back_to, *addrmap_cleanup;
- struct obstack temp_obstack;
+ begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
+ info_ptr = read_and_check_comp_unit_head (&cu.header, section,
+ abbrev_section, info_ptr,
+ this_cu->is_debug_types);
- dwarf2_per_objfile->reading_partial_symbols = 1;
+ this_cu->length = get_cu_length (&cu.header);
- dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
- info_ptr = dwarf2_per_objfile->info.buffer;
+ /* Skip dummy compilation units. */
+ if (info_ptr >= begin_info_ptr + this_cu->length
+ || peek_abbrev_code (abfd, info_ptr) == 0)
+ {
+ do_cleanups (cleanups);
+ return;
+ }
- /* Any cached compilation units will be linked by the per-objfile
- read_in_chain. Make sure to free them when we're done. */
- back_to = make_cleanup (free_cached_comp_units, NULL);
+ dwarf2_read_abbrevs (&cu, abbrev_section);
+ make_cleanup (dwarf2_free_abbrev_table, &cu);
- build_type_psymtabs (objfile);
+ init_cu_die_reader (&reader, &cu, section, dwo_file);
+ info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
- create_all_comp_units (objfile);
+ die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
- /* Create a temporary address map on a temporary obstack. We later
- copy this to the final obstack. */
- obstack_init (&temp_obstack);
- make_cleanup_obstack_free (&temp_obstack);
- objfile->psymtabs_addrmap = addrmap_create_mutable (&temp_obstack);
- addrmap_cleanup = make_cleanup (psymtabs_addrmap_cleanup, objfile);
+ do_cleanups (cleanups);
+}
- /* Since the objects we're extracting from .debug_info vary in
- length, only the individual functions to extract them (like
- read_comp_unit_head and load_partial_die) can really know whether
- the buffer is large enough to hold another complete object.
+/* Read a CU/TU, except that this does not look for DW_AT_GNU_dwo_name and
+ does not lookup the specified DWO file.
+ This cannot be used to read DWO files.
- At the moment, they don't actually check that. If .debug_info
- holds just one extra byte after the last compilation unit's dies,
- then read_comp_unit_head will happily read off the end of the
- buffer. read_partial_die is similarly casual. Those functions
- should be fixed.
+ THIS_CU->cu is always freed when done.
+ This is done in order to not leave THIS_CU->cu in a state where we have
+ to care whether it refers to the "main" CU or the DWO CU.
+ We can revisit this if the data shows there's a performance issue. */
- For this loop condition, simply checking whether there's any data
- left at all should be sufficient. */
+static void
+init_cutu_and_read_dies_simple (struct dwarf2_per_cu_data *this_cu,
+ die_reader_func_ftype *die_reader_func,
+ void *data)
+{
+ init_cutu_and_read_dies_no_follow (this_cu,
+ get_abbrev_section_for_cu (this_cu),
+ NULL,
+ die_reader_func, data);
+}
- while (info_ptr < (dwarf2_per_objfile->info.buffer
- + dwarf2_per_objfile->info.size))
- {
- struct dwarf2_per_cu_data *this_cu;
+/* Create a psymtab named NAME and assign it to PER_CU.
- this_cu = dwarf2_find_comp_unit (info_ptr
- - dwarf2_per_objfile->info.buffer,
- objfile);
+ The caller must fill in the following details:
+ dirname, textlow, texthigh. */
- info_ptr = process_psymtab_comp_unit (objfile, this_cu,
- dwarf2_per_objfile->info.buffer,
- info_ptr,
- dwarf2_per_objfile->info.size);
- }
+static struct partial_symtab *
+create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name)
+{
+ struct objfile *objfile = per_cu->objfile;
+ struct partial_symtab *pst;
- objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
- &objfile->objfile_obstack);
- discard_cleanups (addrmap_cleanup);
+ pst = start_psymtab_common (objfile, objfile->section_offsets,
+ name, 0,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
- do_cleanups (back_to);
+ pst->psymtabs_addrmap_supported = 1;
+
+ /* This is the glue that links PST into GDB's symbol API. */
+ pst->read_symtab_private = per_cu;
+ pst->read_symtab = dwarf2_read_symtab;
+ per_cu->v.psymtab = pst;
+
+ return pst;
}
-/* Load the partial DIEs for a secondary CU into memory. */
+/* die_reader_func for process_psymtab_comp_unit. */
static void
-load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu,
- struct objfile *objfile)
+process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
{
- bfd *abfd = objfile->obfd;
- gdb_byte *info_ptr;
- struct die_info *comp_unit_die;
- struct dwarf2_cu *cu;
- struct cleanup *free_abbrevs_cleanup, *free_cu_cleanup = NULL;
- int has_children;
- struct die_reader_specs reader_specs;
- int read_cu = 0;
+ struct dwarf2_cu *cu = reader->cu;
+ struct objfile *objfile = cu->objfile;
+ struct dwarf2_per_cu_data *per_cu = cu->per_cu;
+ struct attribute *attr;
+ CORE_ADDR baseaddr;
+ CORE_ADDR best_lowpc = 0, best_highpc = 0;
+ struct partial_symtab *pst;
+ int has_pc_info;
+ const char *filename;
+ int *want_partial_unit_ptr = data;
+
+ if (comp_unit_die->tag == DW_TAG_partial_unit
+ && (want_partial_unit_ptr == NULL
+ || !*want_partial_unit_ptr))
+ return;
+
+ gdb_assert (! per_cu->is_debug_types);
+
+ prepare_one_comp_unit (cu, comp_unit_die, language_minimal);
+
+ cu->list_in_scope = &file_symbols;
+
+ /* Allocate a new partial symbol table structure. */
+ attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
+ if (attr == NULL || !DW_STRING (attr))
+ filename = "";
+ else
+ filename = DW_STRING (attr);
+
+ pst = create_partial_symtab (per_cu, filename);
+
+ /* This must be done before calling dwarf2_build_include_psymtabs. */
+ attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
+ if (attr != NULL)
+ pst->dirname = DW_STRING (attr);
- gdb_assert (! this_cu->debug_types_section);
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ dwarf2_find_base_address (comp_unit_die, cu);
- gdb_assert (dwarf2_per_objfile->info.readin);
- info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset;
+ /* Possibly set the default values of LOWPC and HIGHPC from
+ `DW_AT_ranges'. */
+ has_pc_info = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc,
+ &best_highpc, cu, pst);
+ if (has_pc_info == 1 && best_lowpc < best_highpc)
+ /* Store the contiguous range if it is not empty; it can be empty for
+ CUs with no code. */
+ addrmap_set_empty (objfile->psymtabs_addrmap,
+ best_lowpc + baseaddr,
+ best_highpc + baseaddr - 1, pst);
- if (this_cu->cu == NULL)
+ /* Check if comp unit has_children.
+ If so, read the rest of the partial symbols from this comp unit.
+ If not, there's no more debug_info for this comp unit. */
+ if (has_children)
{
- cu = xmalloc (sizeof (*cu));
- init_one_comp_unit (cu, objfile);
+ struct partial_die_info *first_die;
+ CORE_ADDR lowpc, highpc;
- read_cu = 1;
+ lowpc = ((CORE_ADDR) -1);
+ highpc = ((CORE_ADDR) 0);
- /* If an error occurs while loading, release our storage. */
- free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
+ first_die = load_partial_dies (reader, info_ptr, 1);
- info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr,
- dwarf2_per_objfile->info.buffer,
- dwarf2_per_objfile->info.size,
- abfd, 0);
+ scan_partial_symbols (first_die, &lowpc, &highpc,
+ ! has_pc_info, cu);
- /* Skip dummy compilation units. */
- if (info_ptr >= (dwarf2_per_objfile->info.buffer
- + dwarf2_per_objfile->info.size)
- || peek_abbrev_code (abfd, info_ptr) == 0)
+ /* If we didn't find a lowpc, set it to highpc to avoid
+ complaints from `maint check'. */
+ if (lowpc == ((CORE_ADDR) -1))
+ lowpc = highpc;
+
+ /* If the compilation unit didn't have an explicit address range,
+ then use the information extracted from its child dies. */
+ if (! has_pc_info)
{
- do_cleanups (free_cu_cleanup);
- return;
+ best_lowpc = lowpc;
+ best_highpc = highpc;
}
+ }
+ pst->textlow = best_lowpc + baseaddr;
+ pst->texthigh = best_highpc + baseaddr;
+
+ pst->n_global_syms = objfile->global_psymbols.next -
+ (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms = objfile->static_psymbols.next -
+ (objfile->static_psymbols.list + pst->statics_offset);
+ sort_pst_symbols (objfile, pst);
- /* Link this compilation unit into the compilation unit tree. */
- this_cu->cu = cu;
- cu->per_cu = this_cu;
+ if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs))
+ {
+ int i;
+ int len = VEC_length (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
+ struct dwarf2_per_cu_data *iter;
+
+ /* Fill in 'dependencies' here; we fill in 'users' in a
+ post-pass. */
+ pst->number_of_dependencies = len;
+ pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
+ len * sizeof (struct symtab *));
+ for (i = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
+ i, iter);
+ ++i)
+ pst->dependencies[i] = iter->v.psymtab;
- /* Link this CU into read_in_chain. */
- this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
- dwarf2_per_objfile->read_in_chain = this_cu;
+ VEC_free (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
}
- else
+
+ /* Get the list of files included in the current compilation unit,
+ and build a psymtab for each of them. */
+ dwarf2_build_include_psymtabs (cu, comp_unit_die, pst);
+
+ if (dwarf2_read_debug)
{
- cu = this_cu->cu;
- info_ptr += cu->header.first_die_offset;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "Psymtab for %s unit @0x%x: %s - %s"
+ ", %d global, %d static syms\n",
+ per_cu->is_debug_types ? "type" : "comp",
+ per_cu->offset.sect_off,
+ paddress (gdbarch, pst->textlow),
+ paddress (gdbarch, pst->texthigh),
+ pst->n_global_syms, pst->n_static_syms);
}
+}
- /* Read the abbrevs for this compilation unit into a table. */
- gdb_assert (cu->dwarf2_abbrevs == NULL);
- dwarf2_read_abbrevs (abfd, cu);
- free_abbrevs_cleanup = make_cleanup (dwarf2_free_abbrev_table, cu);
+/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
+ Process compilation unit THIS_CU for a psymtab. */
- /* Read the compilation unit die. */
- init_cu_die_reader (&reader_specs, cu);
- info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr,
- &has_children);
+static void
+process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
+ int want_partial_unit)
+{
+ /* If this compilation unit was already read in, free the
+ cached copy in order to read it in again. This is
+ necessary because we skipped some symbols when we first
+ read in the compilation unit (see load_partial_dies).
+ This problem could be avoided, but the benefit is unclear. */
+ if (this_cu->cu != NULL)
+ free_one_cached_comp_unit (this_cu);
- prepare_one_comp_unit (cu, comp_unit_die);
+ gdb_assert (! this_cu->is_debug_types);
+ init_cutu_and_read_dies (this_cu, NULL, 0, 0,
+ process_psymtab_comp_unit_reader,
+ &want_partial_unit);
- /* Check if comp unit has_children.
- If so, read the rest of the partial symbols from this comp unit.
- If not, there's no more debug_info for this comp unit. */
- if (has_children)
- load_partial_dies (abfd, dwarf2_per_objfile->info.buffer, info_ptr, 0, cu);
+ /* Age out any secondary CUs. */
+ age_cached_comp_units ();
+}
- do_cleanups (free_abbrevs_cleanup);
+static hashval_t
+hash_type_unit_group (const void *item)
+{
+ const struct type_unit_group *tu_group = item;
- if (read_cu)
- {
- /* We've successfully allocated this compilation unit. Let our
- caller clean it up when finished with it. */
- discard_cleanups (free_cu_cleanup);
- }
+ return hash_stmt_list_entry (&tu_group->hash);
}
-/* Create a list of all compilation units in OBJFILE. We do this only
- if an inter-comp-unit reference is found; presumably if there is one,
- there will be many, and one will occur early in the .debug_info section.
- So there's no point in building this list incrementally. */
+static int
+eq_type_unit_group (const void *item_lhs, const void *item_rhs)
+{
+ const struct type_unit_group *lhs = item_lhs;
+ const struct type_unit_group *rhs = item_rhs;
-static void
-create_all_comp_units (struct objfile *objfile)
+ return eq_stmt_list_entry (&lhs->hash, &rhs->hash);
+}
+
+/* Allocate a hash table for type unit groups. */
+
+static htab_t
+allocate_type_unit_groups_table (void)
{
- int n_allocated;
- int n_comp_units;
- struct dwarf2_per_cu_data **all_comp_units;
- gdb_byte *info_ptr;
+ return htab_create_alloc_ex (3,
+ hash_type_unit_group,
+ eq_type_unit_group,
+ NULL,
+ &dwarf2_per_objfile->objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+}
- dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
- info_ptr = dwarf2_per_objfile->info.buffer;
+/* Type units that don't have DW_AT_stmt_list are grouped into their own
+ partial symtabs. We combine several TUs per psymtab to not let the size
+ of any one psymtab grow too big. */
+#define NO_STMT_LIST_TYPE_UNIT_PSYMTAB (1 << 31)
+#define NO_STMT_LIST_TYPE_UNIT_PSYMTAB_SIZE 10
- n_comp_units = 0;
- n_allocated = 10;
- all_comp_units = xmalloc (n_allocated
- * sizeof (struct dwarf2_per_cu_data *));
+/* Helper routine for get_type_unit_group.
+ Create the type_unit_group object used to hold one or more TUs. */
- while (info_ptr < dwarf2_per_objfile->info.buffer
- + dwarf2_per_objfile->info.size)
- {
- unsigned int length, initial_length_size;
- struct dwarf2_per_cu_data *this_cu;
- unsigned int offset;
+static struct type_unit_group *
+create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_per_cu_data *per_cu;
+ struct type_unit_group *tu_group;
- offset = info_ptr - dwarf2_per_objfile->info.buffer;
+ tu_group = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct type_unit_group);
+ per_cu = &tu_group->per_cu;
+ per_cu->objfile = objfile;
+ per_cu->is_debug_types = 1;
+ per_cu->type_unit_group = tu_group;
- /* Read just enough information to find out where the next
- compilation unit is. */
- length = read_initial_length (objfile->obfd, info_ptr,
- &initial_length_size);
+ if (dwarf2_per_objfile->using_index)
+ {
+ per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwarf2_per_cu_quick_data);
+ tu_group->t.first_tu = cu->per_cu;
+ }
+ else
+ {
+ unsigned int line_offset = line_offset_struct.sect_off;
+ struct partial_symtab *pst;
+ char *name;
- /* Save the compilation unit for later lookup. */
- this_cu = obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct dwarf2_per_cu_data));
- memset (this_cu, 0, sizeof (*this_cu));
- this_cu->offset = offset;
- this_cu->length = length + initial_length_size;
- this_cu->objfile = objfile;
+ /* Give the symtab a useful name for debug purposes. */
+ if ((line_offset & NO_STMT_LIST_TYPE_UNIT_PSYMTAB) != 0)
+ name = xstrprintf ("",
+ (line_offset & ~NO_STMT_LIST_TYPE_UNIT_PSYMTAB));
+ else
+ name = xstrprintf ("", line_offset);
- if (n_comp_units == n_allocated)
- {
- n_allocated *= 2;
- all_comp_units = xrealloc (all_comp_units,
- n_allocated
- * sizeof (struct dwarf2_per_cu_data *));
- }
- all_comp_units[n_comp_units++] = this_cu;
+ pst = create_partial_symtab (per_cu, name);
+ pst->anonymous = 1;
- info_ptr = info_ptr + this_cu->length;
+ xfree (name);
}
- dwarf2_per_objfile->all_comp_units
- = obstack_alloc (&objfile->objfile_obstack,
- n_comp_units * sizeof (struct dwarf2_per_cu_data *));
- memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units,
- n_comp_units * sizeof (struct dwarf2_per_cu_data *));
- xfree (all_comp_units);
- dwarf2_per_objfile->n_comp_units = n_comp_units;
+ tu_group->hash.dwo_unit = cu->dwo_unit;
+ tu_group->hash.line_offset = line_offset_struct;
+
+ return tu_group;
}
-/* Process all loaded DIEs for compilation unit CU, starting at
- FIRST_DIE. The caller should pass NEED_PC == 1 if the compilation
- unit DIE did not have PC info (DW_AT_low_pc and DW_AT_high_pc, or
- DW_AT_ranges). If NEED_PC is set, then this function will set
- *LOWPC and *HIGHPC to the lowest and highest PC values found in CU
- and record the covered ranges in the addrmap. */
+/* Look up the type_unit_group for type unit CU, and create it if necessary.
+ STMT_LIST is a DW_AT_stmt_list attribute. */
-static void
-scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
- CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu)
+static struct type_unit_group *
+get_type_unit_group (struct dwarf2_cu *cu, struct attribute *stmt_list)
{
- struct partial_die_info *pdi;
+ struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
+ struct type_unit_group *tu_group;
+ void **slot;
+ unsigned int line_offset;
+ struct type_unit_group type_unit_group_for_lookup;
- /* Now, march along the PDI's, descending into ones which have
- interesting children but skipping the children of the other ones,
- until we reach the end of the compilation unit. */
+ if (dwarf2_per_objfile->type_unit_groups == NULL)
+ {
+ dwarf2_per_objfile->type_unit_groups =
+ allocate_type_unit_groups_table ();
+ }
- pdi = first_die;
+ /* Do we need to create a new group, or can we use an existing one? */
- while (pdi != NULL)
+ if (stmt_list)
{
- fixup_partial_die (pdi, cu);
+ line_offset = DW_UNSND (stmt_list);
+ ++tu_stats->nr_symtab_sharers;
+ }
+ else
+ {
+ /* Ugh, no stmt_list. Rare, but we have to handle it.
+ We can do various things here like create one group per TU or
+ spread them over multiple groups to split up the expansion work.
+ To avoid worst case scenarios (too many groups or too large groups)
+ we, umm, group them in bunches. */
+ line_offset = (NO_STMT_LIST_TYPE_UNIT_PSYMTAB
+ | (tu_stats->nr_stmt_less_type_units
+ / NO_STMT_LIST_TYPE_UNIT_PSYMTAB_SIZE));
+ ++tu_stats->nr_stmt_less_type_units;
+ }
+
+ type_unit_group_for_lookup.hash.dwo_unit = cu->dwo_unit;
+ type_unit_group_for_lookup.hash.line_offset.sect_off = line_offset;
+ slot = htab_find_slot (dwarf2_per_objfile->type_unit_groups,
+ &type_unit_group_for_lookup, INSERT);
+ if (*slot != NULL)
+ {
+ tu_group = *slot;
+ gdb_assert (tu_group != NULL);
+ }
+ else
+ {
+ sect_offset line_offset_struct;
- /* Anonymous namespaces or modules have no name but have interesting
- children, so we need to look at them. Ditto for anonymous
- enums. */
+ line_offset_struct.sect_off = line_offset;
+ tu_group = create_type_unit_group (cu, line_offset_struct);
+ *slot = tu_group;
+ ++tu_stats->nr_symtabs;
+ }
- if (pdi->name != NULL || pdi->tag == DW_TAG_namespace
- || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type)
- {
- switch (pdi->tag)
- {
- case DW_TAG_subprogram:
- add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu);
- break;
- case DW_TAG_constant:
- case DW_TAG_variable:
- case DW_TAG_typedef:
- case DW_TAG_union_type:
- if (!pdi->is_declaration)
- {
- add_partial_symbol (pdi, cu);
- }
- break;
- case DW_TAG_class_type:
- case DW_TAG_interface_type:
- case DW_TAG_structure_type:
- if (!pdi->is_declaration)
- {
- add_partial_symbol (pdi, cu);
- }
- break;
- case DW_TAG_enumeration_type:
- if (!pdi->is_declaration)
- add_partial_enumeration (pdi, cu);
- break;
- case DW_TAG_base_type:
- case DW_TAG_subrange_type:
- /* File scope base type definitions are added to the partial
- symbol table. */
- add_partial_symbol (pdi, cu);
- break;
- case DW_TAG_namespace:
- add_partial_namespace (pdi, lowpc, highpc, need_pc, cu);
- break;
- case DW_TAG_module:
- add_partial_module (pdi, lowpc, highpc, need_pc, cu);
- break;
- default:
- break;
- }
- }
+ return tu_group;
+}
- /* If the die has a sibling, skip to the sibling. */
+/* Struct used to sort TUs by their abbreviation table offset. */
- pdi = pdi->die_sibling;
- }
+struct tu_abbrev_offset
+{
+ struct signatured_type *sig_type;
+ sect_offset abbrev_offset;
+};
+
+/* Helper routine for build_type_unit_groups, passed to qsort. */
+
+static int
+sort_tu_by_abbrev_offset (const void *ap, const void *bp)
+{
+ const struct tu_abbrev_offset * const *a = ap;
+ const struct tu_abbrev_offset * const *b = bp;
+ unsigned int aoff = (*a)->abbrev_offset.sect_off;
+ unsigned int boff = (*b)->abbrev_offset.sect_off;
+
+ return (aoff > boff) - (aoff < boff);
}
-/* Functions used to compute the fully scoped name of a partial DIE.
+/* A helper function to add a type_unit_group to a table. */
- Normally, this is simple. For C++, the parent DIE's fully scoped
- name is concatenated with "::" and the partial DIE's name. For
- Java, the same thing occurs except that "." is used instead of "::".
- Enumerators are an exception; they use the scope of their parent
- enumeration type, i.e. the name of the enumeration type is not
- prepended to the enumerator.
+static int
+add_type_unit_group_to_table (void **slot, void *datum)
+{
+ struct type_unit_group *tu_group = *slot;
+ struct type_unit_group ***datap = datum;
- There are two complexities. One is DW_AT_specification; in this
- case "parent" means the parent of the target of the specification,
- instead of the direct parent of the DIE. The other is compilers
- which do not emit DW_TAG_namespace; in this case we try to guess
- the fully qualified name of structure types from their members'
- linkage names. This must be done using the DIE's children rather
- than the children of any DW_AT_specification target. We only need
- to do this for structures at the top level, i.e. if the target of
- any DW_AT_specification (if any; otherwise the DIE itself) does not
- have a parent. */
+ **datap = tu_group;
+ ++*datap;
-/* Compute the scope prefix associated with PDI's parent, in
- compilation unit CU. The result will be allocated on CU's
- comp_unit_obstack, or a copy of the already allocated PDI->NAME
- field. NULL is returned if no prefix is necessary. */
-static char *
-partial_die_parent_scope (struct partial_die_info *pdi,
- struct dwarf2_cu *cu)
+ return 1;
+}
+
+/* Efficiently read all the type units, calling init_cutu_and_read_dies on
+ each one passing FUNC,DATA.
+
+ The efficiency is because we sort TUs by the abbrev table they use and
+ only read each abbrev table once. In one program there are 200K TUs
+ sharing 8K abbrev tables.
+
+ The main purpose of this function is to support building the
+ dwarf2_per_objfile->type_unit_groups table.
+ TUs typically share the DW_AT_stmt_list of the CU they came from, so we
+ can collapse the search space by grouping them by stmt_list.
+ The savings can be significant, in the same program from above the 200K TUs
+ share 8K stmt_list tables.
+
+ FUNC is expected to call get_type_unit_group, which will create the
+ struct type_unit_group if necessary and add it to
+ dwarf2_per_objfile->type_unit_groups. */
+
+static void
+build_type_unit_groups (die_reader_func_ftype *func, void *data)
{
- char *grandparent_scope;
- struct partial_die_info *parent, *real_pdi;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
+ struct cleanup *cleanups;
+ struct abbrev_table *abbrev_table;
+ sect_offset abbrev_offset;
+ struct tu_abbrev_offset *sorted_by_abbrev;
+ struct type_unit_group **iter;
+ int i;
- /* We need to look at our parent DIE; if we have a DW_AT_specification,
- then this means the parent of the specification DIE. */
+ /* It's up to the caller to not call us multiple times. */
+ gdb_assert (dwarf2_per_objfile->type_unit_groups == NULL);
- real_pdi = pdi;
- while (real_pdi->has_specification)
- real_pdi = find_partial_die (real_pdi->spec_offset, cu);
+ if (dwarf2_per_objfile->n_type_units == 0)
+ return;
- parent = real_pdi->die_parent;
- if (parent == NULL)
- return NULL;
+ /* TUs typically share abbrev tables, and there can be way more TUs than
+ abbrev tables. Sort by abbrev table to reduce the number of times we
+ read each abbrev table in.
+ Alternatives are to punt or to maintain a cache of abbrev tables.
+ This is simpler and efficient enough for now.
- if (parent->scope_set)
- return parent->scope;
+ Later we group TUs by their DW_AT_stmt_list value (as this defines the
+ symtab to use). Typically TUs with the same abbrev offset have the same
+ stmt_list value too so in practice this should work well.
- fixup_partial_die (parent, cu);
+ The basic algorithm here is:
- grandparent_scope = partial_die_parent_scope (parent, cu);
+ sort TUs by abbrev table
+ for each TU with same abbrev table:
+ read abbrev table if first user
+ read TU top level DIE
+ [IWBN if DWO skeletons had DW_AT_stmt_list]
+ call FUNC */
- /* GCC 4.0 and 4.1 had a bug (PR c++/28460) where they generated bogus
- DW_TAG_namespace DIEs with a name of "::" for the global namespace.
- Work around this problem here. */
- if (cu->language == language_cplus
- && parent->tag == DW_TAG_namespace
- && strcmp (parent->name, "::") == 0
- && grandparent_scope == NULL)
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "Building type unit groups ...\n");
+
+ /* Sort in a separate table to maintain the order of all_type_units
+ for .gdb_index: TU indices directly index all_type_units. */
+ sorted_by_abbrev = XNEWVEC (struct tu_abbrev_offset,
+ dwarf2_per_objfile->n_type_units);
+ for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i)
{
- parent->scope = NULL;
- parent->scope_set = 1;
- return NULL;
+ struct signatured_type *sig_type = dwarf2_per_objfile->all_type_units[i];
+
+ sorted_by_abbrev[i].sig_type = sig_type;
+ sorted_by_abbrev[i].abbrev_offset =
+ read_abbrev_offset (sig_type->per_cu.info_or_types_section,
+ sig_type->per_cu.offset);
}
+ cleanups = make_cleanup (xfree, sorted_by_abbrev);
+ qsort (sorted_by_abbrev, dwarf2_per_objfile->n_type_units,
+ sizeof (struct tu_abbrev_offset), sort_tu_by_abbrev_offset);
- if (pdi->tag == DW_TAG_enumerator)
- /* Enumerators should not get the name of the enumeration as a prefix. */
- parent->scope = grandparent_scope;
- else if (parent->tag == DW_TAG_namespace
- || parent->tag == DW_TAG_module
- || parent->tag == DW_TAG_structure_type
- || parent->tag == DW_TAG_class_type
- || parent->tag == DW_TAG_interface_type
- || parent->tag == DW_TAG_union_type
- || parent->tag == DW_TAG_enumeration_type)
+ /* Note: In the .gdb_index case, get_type_unit_group may have already been
+ called any number of times, so we don't reset tu_stats here. */
+
+ abbrev_offset.sect_off = ~(unsigned) 0;
+ abbrev_table = NULL;
+ make_cleanup (abbrev_table_free_cleanup, &abbrev_table);
+
+ for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i)
{
- if (grandparent_scope == NULL)
- parent->scope = parent->name;
- else
- parent->scope = typename_concat (&cu->comp_unit_obstack,
- grandparent_scope,
- parent->name, 0, cu);
+ const struct tu_abbrev_offset *tu = &sorted_by_abbrev[i];
+
+ /* Switch to the next abbrev table if necessary. */
+ if (abbrev_table == NULL
+ || tu->abbrev_offset.sect_off != abbrev_offset.sect_off)
+ {
+ if (abbrev_table != NULL)
+ {
+ abbrev_table_free (abbrev_table);
+ /* Reset to NULL in case abbrev_table_read_table throws
+ an error: abbrev_table_free_cleanup will get called. */
+ abbrev_table = NULL;
+ }
+ abbrev_offset = tu->abbrev_offset;
+ abbrev_table =
+ abbrev_table_read_table (&dwarf2_per_objfile->abbrev,
+ abbrev_offset);
+ ++tu_stats->nr_uniq_abbrev_tables;
+ }
+
+ init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table, 0, 0,
+ func, data);
}
- else
+
+ /* Create a vector of pointers to primary type units to make it easy to
+ iterate over them and CUs. See dw2_get_primary_cu. */
+ dwarf2_per_objfile->n_type_unit_groups =
+ htab_elements (dwarf2_per_objfile->type_unit_groups);
+ dwarf2_per_objfile->all_type_unit_groups =
+ obstack_alloc (&objfile->objfile_obstack,
+ dwarf2_per_objfile->n_type_unit_groups
+ * sizeof (struct type_unit_group *));
+ iter = &dwarf2_per_objfile->all_type_unit_groups[0];
+ htab_traverse_noresize (dwarf2_per_objfile->type_unit_groups,
+ add_type_unit_group_to_table, &iter);
+ gdb_assert (iter - &dwarf2_per_objfile->all_type_unit_groups[0]
+ == dwarf2_per_objfile->n_type_unit_groups);
+
+ do_cleanups (cleanups);
+
+ if (dwarf2_read_debug)
{
- /* FIXME drow/2004-04-01: What should we be doing with
- function-local names? For partial symbols, we should probably be
- ignoring them. */
- complaint (&symfile_complaints,
- _("unhandled containing DIE tag %d for DIE at %d"),
- parent->tag, pdi->offset);
- parent->scope = grandparent_scope;
+ fprintf_unfiltered (gdb_stdlog, "Done building type unit groups:\n");
+ fprintf_unfiltered (gdb_stdlog, " %d TUs\n",
+ dwarf2_per_objfile->n_type_units);
+ fprintf_unfiltered (gdb_stdlog, " %d uniq abbrev tables\n",
+ tu_stats->nr_uniq_abbrev_tables);
+ fprintf_unfiltered (gdb_stdlog, " %d symtabs from stmt_list entries\n",
+ tu_stats->nr_symtabs);
+ fprintf_unfiltered (gdb_stdlog, " %d symtab sharers\n",
+ tu_stats->nr_symtab_sharers);
+ fprintf_unfiltered (gdb_stdlog, " %d type units without a stmt_list\n",
+ tu_stats->nr_stmt_less_type_units);
}
-
- parent->scope_set = 1;
- return parent->scope;
}
-/* Return the fully scoped name associated with PDI, from compilation unit
- CU. The result will be allocated with malloc. */
-static char *
-partial_die_full_name (struct partial_die_info *pdi,
- struct dwarf2_cu *cu)
+/* Reader function for build_type_psymtabs. */
+
+static void
+build_type_psymtabs_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *type_unit_die,
+ int has_children,
+ void *data)
{
- char *parent_scope;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_cu *cu = reader->cu;
+ struct dwarf2_per_cu_data *per_cu = cu->per_cu;
+ struct type_unit_group *tu_group;
+ struct attribute *attr;
+ struct partial_die_info *first_die;
+ CORE_ADDR lowpc, highpc;
+ struct partial_symtab *pst;
- /* If this is a template instantiation, we can not work out the
- template arguments from partial DIEs. So, unfortunately, we have
- to go through the full DIEs. At least any work we do building
- types here will be reused if full symbols are loaded later. */
- if (pdi->has_template_arguments)
- {
- fixup_partial_die (pdi, cu);
+ gdb_assert (data == NULL);
- if (pdi->name != NULL && strchr (pdi->name, '<') == NULL)
- {
- struct die_info *die;
- struct attribute attr;
- struct dwarf2_cu *ref_cu = cu;
+ if (! has_children)
+ return;
- attr.name = 0;
- attr.form = DW_FORM_ref_addr;
- attr.u.addr = pdi->offset;
- die = follow_die_ref (NULL, &attr, &ref_cu);
+ attr = dwarf2_attr_no_follow (type_unit_die, DW_AT_stmt_list);
+ tu_group = get_type_unit_group (cu, attr);
- return xstrdup (dwarf2_full_name (NULL, die, ref_cu));
- }
+ VEC_safe_push (dwarf2_per_cu_ptr, tu_group->t.tus, per_cu);
+
+ prepare_one_comp_unit (cu, type_unit_die, language_minimal);
+ cu->list_in_scope = &file_symbols;
+ pst = create_partial_symtab (per_cu, "");
+ pst->anonymous = 1;
+
+ first_die = load_partial_dies (reader, info_ptr, 1);
+
+ lowpc = (CORE_ADDR) -1;
+ highpc = (CORE_ADDR) 0;
+ scan_partial_symbols (first_die, &lowpc, &highpc, 0, cu);
+
+ pst->n_global_syms = objfile->global_psymbols.next -
+ (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms = objfile->static_psymbols.next -
+ (objfile->static_psymbols.list + pst->statics_offset);
+ sort_pst_symbols (objfile, pst);
+}
+
+/* Traversal function for build_type_psymtabs. */
+
+static int
+build_type_psymtab_dependencies (void **slot, void *info)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct type_unit_group *tu_group = (struct type_unit_group *) *slot;
+ struct dwarf2_per_cu_data *per_cu = &tu_group->per_cu;
+ struct partial_symtab *pst = per_cu->v.psymtab;
+ int len = VEC_length (dwarf2_per_cu_ptr, tu_group->t.tus);
+ struct dwarf2_per_cu_data *iter;
+ int i;
+
+ gdb_assert (len > 0);
+
+ pst->number_of_dependencies = len;
+ pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
+ len * sizeof (struct psymtab *));
+ for (i = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, tu_group->t.tus, i, iter);
+ ++i)
+ {
+ pst->dependencies[i] = iter->v.psymtab;
+ iter->type_unit_group = tu_group;
}
- parent_scope = partial_die_parent_scope (pdi, cu);
- if (parent_scope == NULL)
- return NULL;
- else
- return typename_concat (NULL, parent_scope, pdi->name, 0, cu);
+ VEC_free (dwarf2_per_cu_ptr, tu_group->t.tus);
+
+ return 1;
}
+/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
+ Build partial symbol tables for the .debug_types comp-units. */
+
static void
-add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
+build_type_psymtabs (struct objfile *objfile)
{
- struct objfile *objfile = cu->objfile;
- CORE_ADDR addr = 0;
- char *actual_name = NULL;
- const struct partial_symbol *psym = NULL;
- CORE_ADDR baseaddr;
- int built_actual_name = 0;
+ if (! create_all_type_units (objfile))
+ return;
- baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ build_type_unit_groups (build_type_psymtabs_reader, NULL);
- actual_name = partial_die_full_name (pdi, cu);
- if (actual_name)
- built_actual_name = 1;
+ /* Now that all TUs have been processed we can fill in the dependencies. */
+ htab_traverse_noresize (dwarf2_per_objfile->type_unit_groups,
+ build_type_psymtab_dependencies, NULL);
+}
- if (actual_name == NULL)
- actual_name = pdi->name;
+/* A cleanup function that clears objfile's psymtabs_addrmap field. */
- switch (pdi->tag)
+static void
+psymtabs_addrmap_cleanup (void *o)
+{
+ struct objfile *objfile = o;
+
+ objfile->psymtabs_addrmap = NULL;
+}
+
+/* Compute the 'user' field for each psymtab in OBJFILE. */
+
+static void
+set_partial_user (struct objfile *objfile)
+{
+ int i;
+
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
- case DW_TAG_subprogram:
- if (pdi->is_external || cu->language == language_ada)
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+ struct partial_symtab *pst = per_cu->v.psymtab;
+ int j;
+
+ if (pst == NULL)
+ continue;
+
+ for (j = 0; j < pst->number_of_dependencies; ++j)
{
- /* brobecker/2007-12-26: Normally, only "external" DIEs are part
- of the global scope. But in Ada, we want to be able to access
- nested procedures globally. So all Ada subprograms are stored
- in the global scope. */
- /* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
- mst_text, objfile); */
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
- VAR_DOMAIN, LOC_BLOCK,
- &objfile->global_psymbols,
- 0, pdi->lowpc + baseaddr,
- cu->language, objfile);
- }
- else
- {
- /* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
- mst_file_text, objfile); */
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
- VAR_DOMAIN, LOC_BLOCK,
- &objfile->static_psymbols,
- 0, pdi->lowpc + baseaddr,
- cu->language, objfile);
+ /* Set the 'user' field only if it is not already set. */
+ if (pst->dependencies[j]->user == NULL)
+ pst->dependencies[j]->user = pst;
}
- break;
- case DW_TAG_constant:
- {
- struct psymbol_allocation_list *list;
+ }
+}
- if (pdi->is_external)
- list = &objfile->global_psymbols;
- else
- list = &objfile->static_psymbols;
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name, VAR_DOMAIN, LOC_STATIC,
- list, 0, 0, cu->language, objfile);
- }
- break;
- case DW_TAG_variable:
- if (pdi->locdesc)
- addr = decode_locdesc (pdi->locdesc, cu);
+/* Build the partial symbol table by doing a quick pass through the
+ .debug_info and .debug_abbrev sections. */
- if (pdi->locdesc
- && addr == 0
- && !dwarf2_per_objfile->has_section_at_zero)
- {
- /* A global or static variable may also have been stripped
- out by the linker if unused, in which case its address
- will be nullified; do not add such variables into partial
- symbol table then. */
- }
- else if (pdi->is_external)
- {
- /* Global Variable.
- Don't enter into the minimal symbol tables as there is
- a minimal symbol table entry from the ELF symbols already.
- Enter into partial symbol table if it has a location
- descriptor or a type.
- If the location descriptor is missing, new_symbol will create
- a LOC_UNRESOLVED symbol, the address of the variable will then
- be determined from the minimal symbol table whenever the variable
- is referenced.
- The address for the partial symbol table entry is not
- used by GDB, but it comes in handy for debugging partial symbol
- table building. */
+static void
+dwarf2_build_psymtabs_hard (struct objfile *objfile)
+{
+ struct cleanup *back_to, *addrmap_cleanup;
+ struct obstack temp_obstack;
+ int i;
- if (pdi->locdesc || pdi->has_type)
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
- VAR_DOMAIN, LOC_STATIC,
- &objfile->global_psymbols,
- 0, addr + baseaddr,
- cu->language, objfile);
- }
- else
- {
- /* Static Variable. Skip symbols without location descriptors. */
- if (pdi->locdesc == NULL)
- {
- if (built_actual_name)
- xfree (actual_name);
- return;
- }
- /* prim_record_minimal_symbol (actual_name, addr + baseaddr,
- mst_file_data, objfile); */
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
- VAR_DOMAIN, LOC_STATIC,
- &objfile->static_psymbols,
- 0, addr + baseaddr,
- cu->language, objfile);
- }
- break;
- case DW_TAG_typedef:
- case DW_TAG_base_type:
- case DW_TAG_subrange_type:
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
- VAR_DOMAIN, LOC_TYPEDEF,
- &objfile->static_psymbols,
- 0, (CORE_ADDR) 0, cu->language, objfile);
- break;
- case DW_TAG_namespace:
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
- VAR_DOMAIN, LOC_TYPEDEF,
- &objfile->global_psymbols,
- 0, (CORE_ADDR) 0, cu->language, objfile);
- break;
- case DW_TAG_class_type:
- case DW_TAG_interface_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_enumeration_type:
- /* Skip external references. The DWARF standard says in the section
- about "Structure, Union, and Class Type Entries": "An incomplete
- structure, union or class type is represented by a structure,
- union or class entry that does not have a byte size attribute
- and that has a DW_AT_declaration attribute." */
- if (!pdi->has_byte_size && pdi->is_declaration)
- {
- if (built_actual_name)
- xfree (actual_name);
- return;
- }
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Building psymtabs of objfile %s ...\n",
+ objfile->name);
+ }
- /* NOTE: carlton/2003-10-07: See comment in new_symbol about
- static vs. global. */
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
- STRUCT_DOMAIN, LOC_TYPEDEF,
- (cu->language == language_cplus
- || cu->language == language_java)
- ? &objfile->global_psymbols
- : &objfile->static_psymbols,
- 0, (CORE_ADDR) 0, cu->language, objfile);
+ dwarf2_per_objfile->reading_partial_symbols = 1;
- break;
- case DW_TAG_enumerator:
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
- VAR_DOMAIN, LOC_CONST,
- (cu->language == language_cplus
- || cu->language == language_java)
- ? &objfile->global_psymbols
- : &objfile->static_psymbols,
- 0, (CORE_ADDR) 0, cu->language, objfile);
- break;
- default:
- break;
- }
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
- if (built_actual_name)
- xfree (actual_name);
-}
+ /* Any cached compilation units will be linked by the per-objfile
+ read_in_chain. Make sure to free them when we're done. */
+ back_to = make_cleanup (free_cached_comp_units, NULL);
-/* Read a partial die corresponding to a namespace; also, add a symbol
- corresponding to that namespace to the symbol table. NAMESPACE is
- the name of the enclosing namespace. */
+ build_type_psymtabs (objfile);
-static void
-add_partial_namespace (struct partial_die_info *pdi,
- CORE_ADDR *lowpc, CORE_ADDR *highpc,
- int need_pc, struct dwarf2_cu *cu)
-{
- /* Add a symbol for the namespace. */
+ create_all_comp_units (objfile);
- add_partial_symbol (pdi, cu);
+ /* Create a temporary address map on a temporary obstack. We later
+ copy this to the final obstack. */
+ obstack_init (&temp_obstack);
+ make_cleanup_obstack_free (&temp_obstack);
+ objfile->psymtabs_addrmap = addrmap_create_mutable (&temp_obstack);
+ addrmap_cleanup = make_cleanup (psymtabs_addrmap_cleanup, objfile);
- /* Now scan partial symbols in that namespace. */
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ {
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
- if (pdi->has_children)
- scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu);
+ process_psymtab_comp_unit (per_cu, 0);
+ }
+
+ set_partial_user (objfile);
+
+ objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
+ &objfile->objfile_obstack);
+ discard_cleanups (addrmap_cleanup);
+
+ do_cleanups (back_to);
+
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "Done building psymtabs of %s\n",
+ objfile->name);
}
-/* Read a partial die corresponding to a Fortran module. */
+/* die_reader_func for load_partial_comp_unit. */
static void
-add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc,
- CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu)
+load_partial_comp_unit_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
{
- /* Now scan partial symbols in that module. */
+ struct dwarf2_cu *cu = reader->cu;
- if (pdi->has_children)
- scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu);
+ prepare_one_comp_unit (cu, comp_unit_die, language_minimal);
+
+ /* Check if comp unit has_children.
+ If so, read the rest of the partial symbols from this comp unit.
+ If not, there's no more debug_info for this comp unit. */
+ if (has_children)
+ load_partial_dies (reader, info_ptr, 0);
}
-/* Read a partial die corresponding to a subprogram and create a partial
- symbol for that subprogram. When the CU language allows it, this
- routine also defines a partial symbol for each nested subprogram
- that this subprogram contains.
+/* Load the partial DIEs for a secondary CU into memory.
+ This is also used when rereading a primary CU with load_all_dies. */
- DIE my also be a lexical block, in which case we simply search
- recursively for suprograms defined inside that lexical block.
- Again, this is only performed when the CU language allows this
- type of definitions. */
+static void
+load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
+{
+ init_cutu_and_read_dies (this_cu, NULL, 1, 1,
+ load_partial_comp_unit_reader, NULL);
+}
static void
-add_partial_subprogram (struct partial_die_info *pdi,
- CORE_ADDR *lowpc, CORE_ADDR *highpc,
- int need_pc, struct dwarf2_cu *cu)
+read_comp_units_from_section (struct objfile *objfile,
+ struct dwarf2_section_info *section,
+ unsigned int is_dwz,
+ int *n_allocated,
+ int *n_comp_units,
+ struct dwarf2_per_cu_data ***all_comp_units)
{
- if (pdi->tag == DW_TAG_subprogram)
- {
- if (pdi->has_pc_info)
- {
- if (pdi->lowpc < *lowpc)
- *lowpc = pdi->lowpc;
- if (pdi->highpc > *highpc)
- *highpc = pdi->highpc;
- if (need_pc)
- {
- CORE_ADDR baseaddr;
- struct objfile *objfile = cu->objfile;
+ gdb_byte *info_ptr;
+ bfd *abfd = section->asection->owner;
- baseaddr = ANOFFSET (objfile->section_offsets,
- SECT_OFF_TEXT (objfile));
- addrmap_set_empty (objfile->psymtabs_addrmap,
- pdi->lowpc + baseaddr,
- pdi->highpc - 1 + baseaddr,
- cu->per_cu->v.psymtab);
- }
- if (!pdi->is_declaration)
- /* Ignore subprogram DIEs that do not have a name, they are
- illegal. Do not emit a complaint at this point, we will
- do so when we convert this psymtab into a symtab. */
- if (pdi->name)
- add_partial_symbol (pdi, cu);
- }
- }
+ dwarf2_read_section (objfile, section);
- if (! pdi->has_children)
- return;
+ info_ptr = section->buffer;
- if (cu->language == language_ada)
+ while (info_ptr < section->buffer + section->size)
{
- pdi = pdi->die_child;
- while (pdi != NULL)
+ unsigned int length, initial_length_size;
+ struct dwarf2_per_cu_data *this_cu;
+ sect_offset offset;
+
+ offset.sect_off = info_ptr - section->buffer;
+
+ /* Read just enough information to find out where the next
+ compilation unit is. */
+ length = read_initial_length (abfd, info_ptr, &initial_length_size);
+
+ /* Save the compilation unit for later lookup. */
+ this_cu = obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct dwarf2_per_cu_data));
+ memset (this_cu, 0, sizeof (*this_cu));
+ this_cu->offset = offset;
+ this_cu->length = length + initial_length_size;
+ this_cu->is_dwz = is_dwz;
+ this_cu->objfile = objfile;
+ this_cu->info_or_types_section = section;
+
+ if (*n_comp_units == *n_allocated)
{
- fixup_partial_die (pdi, cu);
- if (pdi->tag == DW_TAG_subprogram
- || pdi->tag == DW_TAG_lexical_block)
- add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu);
- pdi = pdi->die_sibling;
+ *n_allocated *= 2;
+ *all_comp_units = xrealloc (*all_comp_units,
+ *n_allocated
+ * sizeof (struct dwarf2_per_cu_data *));
}
+ (*all_comp_units)[*n_comp_units] = this_cu;
+ ++*n_comp_units;
+
+ info_ptr = info_ptr + this_cu->length;
}
}
-/* Read a partial die corresponding to an enumeration type. */
+/* Create a list of all compilation units in OBJFILE.
+ This is only done for -readnow and building partial symtabs. */
static void
-add_partial_enumeration (struct partial_die_info *enum_pdi,
- struct dwarf2_cu *cu)
+create_all_comp_units (struct objfile *objfile)
{
- struct partial_die_info *pdi;
-
- if (enum_pdi->name != NULL)
- add_partial_symbol (enum_pdi, cu);
+ int n_allocated;
+ int n_comp_units;
+ struct dwarf2_per_cu_data **all_comp_units;
- pdi = enum_pdi->die_child;
- while (pdi)
+ n_comp_units = 0;
+ n_allocated = 10;
+ all_comp_units = xmalloc (n_allocated
+ * sizeof (struct dwarf2_per_cu_data *));
+
+ read_comp_units_from_section (objfile, &dwarf2_per_objfile->info, 0,
+ &n_allocated, &n_comp_units, &all_comp_units);
+
+ if (bfd_get_section_by_name (objfile->obfd, ".gnu_debugaltlink") != NULL)
{
- if (pdi->tag != DW_TAG_enumerator || pdi->name == NULL)
- complaint (&symfile_complaints, _("malformed enumerator DIE ignored"));
- else
- add_partial_symbol (pdi, cu);
- pdi = pdi->die_sibling;
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+
+ read_comp_units_from_section (objfile, &dwz->info, 1,
+ &n_allocated, &n_comp_units,
+ &all_comp_units);
}
+
+ dwarf2_per_objfile->all_comp_units
+ = obstack_alloc (&objfile->objfile_obstack,
+ n_comp_units * sizeof (struct dwarf2_per_cu_data *));
+ memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units,
+ n_comp_units * sizeof (struct dwarf2_per_cu_data *));
+ xfree (all_comp_units);
+ dwarf2_per_objfile->n_comp_units = n_comp_units;
}
-/* Return the initial uleb128 in the die at INFO_PTR. */
+/* Process all loaded DIEs for compilation unit CU, starting at
+ FIRST_DIE. The caller should pass NEED_PC == 1 if the compilation
+ unit DIE did not have PC info (DW_AT_low_pc and DW_AT_high_pc, or
+ DW_AT_ranges). If NEED_PC is set, then this function will set
+ *LOWPC and *HIGHPC to the lowest and highest PC values found in CU
+ and record the covered ranges in the addrmap. */
-static unsigned int
-peek_abbrev_code (bfd *abfd, gdb_byte *info_ptr)
+static void
+scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
+ CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu)
{
- unsigned int bytes_read;
+ struct partial_die_info *pdi;
- return read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ /* Now, march along the PDI's, descending into ones which have
+ interesting children but skipping the children of the other ones,
+ until we reach the end of the compilation unit. */
+
+ pdi = first_die;
+
+ while (pdi != NULL)
+ {
+ fixup_partial_die (pdi, cu);
+
+ /* Anonymous namespaces or modules have no name but have interesting
+ children, so we need to look at them. Ditto for anonymous
+ enums. */
+
+ if (pdi->name != NULL || pdi->tag == DW_TAG_namespace
+ || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type
+ || pdi->tag == DW_TAG_imported_unit)
+ {
+ switch (pdi->tag)
+ {
+ case DW_TAG_subprogram:
+ add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu);
+ break;
+ case DW_TAG_constant:
+ case DW_TAG_variable:
+ case DW_TAG_typedef:
+ case DW_TAG_union_type:
+ if (!pdi->is_declaration)
+ {
+ add_partial_symbol (pdi, cu);
+ }
+ break;
+ case DW_TAG_class_type:
+ case DW_TAG_interface_type:
+ case DW_TAG_structure_type:
+ if (!pdi->is_declaration)
+ {
+ add_partial_symbol (pdi, cu);
+ }
+ break;
+ case DW_TAG_enumeration_type:
+ if (!pdi->is_declaration)
+ add_partial_enumeration (pdi, cu);
+ break;
+ case DW_TAG_base_type:
+ case DW_TAG_subrange_type:
+ /* File scope base type definitions are added to the partial
+ symbol table. */
+ add_partial_symbol (pdi, cu);
+ break;
+ case DW_TAG_namespace:
+ add_partial_namespace (pdi, lowpc, highpc, need_pc, cu);
+ break;
+ case DW_TAG_module:
+ add_partial_module (pdi, lowpc, highpc, need_pc, cu);
+ break;
+ case DW_TAG_imported_unit:
+ {
+ struct dwarf2_per_cu_data *per_cu;
+
+ /* For now we don't handle imported units in type units. */
+ if (cu->per_cu->is_debug_types)
+ {
+ error (_("Dwarf Error: DW_TAG_imported_unit is not"
+ " supported in type units [in module %s]"),
+ cu->objfile->name);
+ }
+
+ per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset,
+ pdi->is_dwz,
+ cu->objfile);
+
+ /* Go read the partial unit, if needed. */
+ if (per_cu->v.psymtab == NULL)
+ process_psymtab_comp_unit (per_cu, 1);
+
+ VEC_safe_push (dwarf2_per_cu_ptr,
+ cu->per_cu->imported_symtabs, per_cu);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* If the die has a sibling, skip to the sibling. */
+
+ pdi = pdi->die_sibling;
+ }
}
-/* Read the initial uleb128 in the die at INFO_PTR in compilation unit CU.
- Return the corresponding abbrev, or NULL if the number is zero (indicating
- an empty DIE). In either case *BYTES_READ will be set to the length of
- the initial number. */
+/* Functions used to compute the fully scoped name of a partial DIE.
-static struct abbrev_info *
-peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read,
- struct dwarf2_cu *cu)
+ Normally, this is simple. For C++, the parent DIE's fully scoped
+ name is concatenated with "::" and the partial DIE's name. For
+ Java, the same thing occurs except that "." is used instead of "::".
+ Enumerators are an exception; they use the scope of their parent
+ enumeration type, i.e. the name of the enumeration type is not
+ prepended to the enumerator.
+
+ There are two complexities. One is DW_AT_specification; in this
+ case "parent" means the parent of the target of the specification,
+ instead of the direct parent of the DIE. The other is compilers
+ which do not emit DW_TAG_namespace; in this case we try to guess
+ the fully qualified name of structure types from their members'
+ linkage names. This must be done using the DIE's children rather
+ than the children of any DW_AT_specification target. We only need
+ to do this for structures at the top level, i.e. if the target of
+ any DW_AT_specification (if any; otherwise the DIE itself) does not
+ have a parent. */
+
+/* Compute the scope prefix associated with PDI's parent, in
+ compilation unit CU. The result will be allocated on CU's
+ comp_unit_obstack, or a copy of the already allocated PDI->NAME
+ field. NULL is returned if no prefix is necessary. */
+static const char *
+partial_die_parent_scope (struct partial_die_info *pdi,
+ struct dwarf2_cu *cu)
{
- bfd *abfd = cu->objfile->obfd;
- unsigned int abbrev_number;
- struct abbrev_info *abbrev;
+ const char *grandparent_scope;
+ struct partial_die_info *parent, *real_pdi;
- abbrev_number = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
+ /* We need to look at our parent DIE; if we have a DW_AT_specification,
+ then this means the parent of the specification DIE. */
- if (abbrev_number == 0)
+ real_pdi = pdi;
+ while (real_pdi->has_specification)
+ real_pdi = find_partial_die (real_pdi->spec_offset,
+ real_pdi->spec_is_dwz, cu);
+
+ parent = real_pdi->die_parent;
+ if (parent == NULL)
return NULL;
- abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
- if (!abbrev)
- {
- error (_("Dwarf Error: Could not find abbrev number %d [in module %s]"),
- abbrev_number, bfd_get_filename (abfd));
- }
+ if (parent->scope_set)
+ return parent->scope;
- return abbrev;
-}
+ fixup_partial_die (parent, cu);
-/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER.
- Returns a pointer to the end of a series of DIEs, terminated by an empty
- DIE. Any children of the skipped DIEs will also be skipped. */
+ grandparent_scope = partial_die_parent_scope (parent, cu);
-static gdb_byte *
-skip_children (gdb_byte *buffer, gdb_byte *info_ptr, struct dwarf2_cu *cu)
-{
- struct abbrev_info *abbrev;
- unsigned int bytes_read;
+ /* GCC 4.0 and 4.1 had a bug (PR c++/28460) where they generated bogus
+ DW_TAG_namespace DIEs with a name of "::" for the global namespace.
+ Work around this problem here. */
+ if (cu->language == language_cplus
+ && parent->tag == DW_TAG_namespace
+ && strcmp (parent->name, "::") == 0
+ && grandparent_scope == NULL)
+ {
+ parent->scope = NULL;
+ parent->scope_set = 1;
+ return NULL;
+ }
- while (1)
+ if (pdi->tag == DW_TAG_enumerator)
+ /* Enumerators should not get the name of the enumeration as a prefix. */
+ parent->scope = grandparent_scope;
+ else if (parent->tag == DW_TAG_namespace
+ || parent->tag == DW_TAG_module
+ || parent->tag == DW_TAG_structure_type
+ || parent->tag == DW_TAG_class_type
+ || parent->tag == DW_TAG_interface_type
+ || parent->tag == DW_TAG_union_type
+ || parent->tag == DW_TAG_enumeration_type)
{
- abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
- if (abbrev == NULL)
- return info_ptr + bytes_read;
+ if (grandparent_scope == NULL)
+ parent->scope = parent->name;
else
- info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu);
+ parent->scope = typename_concat (&cu->comp_unit_obstack,
+ grandparent_scope,
+ parent->name, 0, cu);
+ }
+ else
+ {
+ /* FIXME drow/2004-04-01: What should we be doing with
+ function-local names? For partial symbols, we should probably be
+ ignoring them. */
+ complaint (&symfile_complaints,
+ _("unhandled containing DIE tag %d for DIE at %d"),
+ parent->tag, pdi->offset.sect_off);
+ parent->scope = grandparent_scope;
}
+
+ parent->scope_set = 1;
+ return parent->scope;
}
-/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER.
- INFO_PTR should point just after the initial uleb128 of a DIE, and the
- abbrev corresponding to that skipped uleb128 should be passed in
- ABBREV. Returns a pointer to this DIE's sibling, skipping any
- children. */
+/* Return the fully scoped name associated with PDI, from compilation unit
+ CU. The result will be allocated with malloc. */
-static gdb_byte *
-skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
- struct abbrev_info *abbrev, struct dwarf2_cu *cu)
+static char *
+partial_die_full_name (struct partial_die_info *pdi,
+ struct dwarf2_cu *cu)
{
- unsigned int bytes_read;
- struct attribute attr;
- bfd *abfd = cu->objfile->obfd;
- unsigned int form, i;
+ const char *parent_scope;
- for (i = 0; i < abbrev->num_attrs; i++)
+ /* If this is a template instantiation, we can not work out the
+ template arguments from partial DIEs. So, unfortunately, we have
+ to go through the full DIEs. At least any work we do building
+ types here will be reused if full symbols are loaded later. */
+ if (pdi->has_template_arguments)
{
- /* The only abbrev we care about is DW_AT_sibling. */
- if (abbrev->attrs[i].name == DW_AT_sibling)
- {
- read_attribute (&attr, &abbrev->attrs[i],
- abfd, info_ptr, cu);
- if (attr.form == DW_FORM_ref_addr)
- complaint (&symfile_complaints,
- _("ignoring absolute DW_AT_sibling"));
- else
- return buffer + dwarf2_get_ref_die_offset (&attr);
- }
+ fixup_partial_die (pdi, cu);
- /* If it isn't DW_AT_sibling, skip this attribute. */
- form = abbrev->attrs[i].form;
- skip_attribute:
- switch (form)
+ if (pdi->name != NULL && strchr (pdi->name, '<') == NULL)
+ {
+ struct die_info *die;
+ struct attribute attr;
+ struct dwarf2_cu *ref_cu = cu;
+
+ /* DW_FORM_ref_addr is using section offset. */
+ attr.name = 0;
+ attr.form = DW_FORM_ref_addr;
+ attr.u.unsnd = pdi->offset.sect_off;
+ die = follow_die_ref (NULL, &attr, &ref_cu);
+
+ return xstrdup (dwarf2_full_name (NULL, die, ref_cu));
+ }
+ }
+
+ parent_scope = partial_die_parent_scope (pdi, cu);
+ if (parent_scope == NULL)
+ return NULL;
+ else
+ return typename_concat (NULL, parent_scope, pdi->name, 0, cu);
+}
+
+static void
+add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = cu->objfile;
+ CORE_ADDR addr = 0;
+ const char *actual_name = NULL;
+ CORE_ADDR baseaddr;
+ char *built_actual_name;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ built_actual_name = partial_die_full_name (pdi, cu);
+ if (built_actual_name != NULL)
+ actual_name = built_actual_name;
+
+ if (actual_name == NULL)
+ actual_name = pdi->name;
+
+ switch (pdi->tag)
+ {
+ case DW_TAG_subprogram:
+ if (pdi->is_external || cu->language == language_ada)
+ {
+ /* brobecker/2007-12-26: Normally, only "external" DIEs are part
+ of the global scope. But in Ada, we want to be able to access
+ nested procedures globally. So all Ada subprograms are stored
+ in the global scope. */
+ /* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
+ mst_text, objfile); */
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL,
+ VAR_DOMAIN, LOC_BLOCK,
+ &objfile->global_psymbols,
+ 0, pdi->lowpc + baseaddr,
+ cu->language, objfile);
+ }
+ else
+ {
+ /* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
+ mst_file_text, objfile); */
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL,
+ VAR_DOMAIN, LOC_BLOCK,
+ &objfile->static_psymbols,
+ 0, pdi->lowpc + baseaddr,
+ cu->language, objfile);
+ }
+ break;
+ case DW_TAG_constant:
+ {
+ struct psymbol_allocation_list *list;
+
+ if (pdi->is_external)
+ list = &objfile->global_psymbols;
+ else
+ list = &objfile->static_psymbols;
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC,
+ list, 0, 0, cu->language, objfile);
+ }
+ break;
+ case DW_TAG_variable:
+ if (pdi->d.locdesc)
+ addr = decode_locdesc (pdi->d.locdesc, cu);
+
+ if (pdi->d.locdesc
+ && addr == 0
+ && !dwarf2_per_objfile->has_section_at_zero)
+ {
+ /* A global or static variable may also have been stripped
+ out by the linker if unused, in which case its address
+ will be nullified; do not add such variables into partial
+ symbol table then. */
+ }
+ else if (pdi->is_external)
+ {
+ /* Global Variable.
+ Don't enter into the minimal symbol tables as there is
+ a minimal symbol table entry from the ELF symbols already.
+ Enter into partial symbol table if it has a location
+ descriptor or a type.
+ If the location descriptor is missing, new_symbol will create
+ a LOC_UNRESOLVED symbol, the address of the variable will then
+ be determined from the minimal symbol table whenever the variable
+ is referenced.
+ The address for the partial symbol table entry is not
+ used by GDB, but it comes in handy for debugging partial symbol
+ table building. */
+
+ if (pdi->d.locdesc || pdi->has_type)
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL,
+ VAR_DOMAIN, LOC_STATIC,
+ &objfile->global_psymbols,
+ 0, addr + baseaddr,
+ cu->language, objfile);
+ }
+ else
+ {
+ /* Static Variable. Skip symbols without location descriptors. */
+ if (pdi->d.locdesc == NULL)
+ {
+ xfree (built_actual_name);
+ return;
+ }
+ /* prim_record_minimal_symbol (actual_name, addr + baseaddr,
+ mst_file_data, objfile); */
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL,
+ VAR_DOMAIN, LOC_STATIC,
+ &objfile->static_psymbols,
+ 0, addr + baseaddr,
+ cu->language, objfile);
+ }
+ break;
+ case DW_TAG_typedef:
+ case DW_TAG_base_type:
+ case DW_TAG_subrange_type:
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL,
+ VAR_DOMAIN, LOC_TYPEDEF,
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu->language, objfile);
+ break;
+ case DW_TAG_namespace:
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL,
+ VAR_DOMAIN, LOC_TYPEDEF,
+ &objfile->global_psymbols,
+ 0, (CORE_ADDR) 0, cu->language, objfile);
+ break;
+ case DW_TAG_class_type:
+ case DW_TAG_interface_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_enumeration_type:
+ /* Skip external references. The DWARF standard says in the section
+ about "Structure, Union, and Class Type Entries": "An incomplete
+ structure, union or class type is represented by a structure,
+ union or class entry that does not have a byte size attribute
+ and that has a DW_AT_declaration attribute." */
+ if (!pdi->has_byte_size && pdi->is_declaration)
+ {
+ xfree (built_actual_name);
+ return;
+ }
+
+ /* NOTE: carlton/2003-10-07: See comment in new_symbol about
+ static vs. global. */
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL,
+ STRUCT_DOMAIN, LOC_TYPEDEF,
+ (cu->language == language_cplus
+ || cu->language == language_java)
+ ? &objfile->global_psymbols
+ : &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu->language, objfile);
+
+ break;
+ case DW_TAG_enumerator:
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL,
+ VAR_DOMAIN, LOC_CONST,
+ (cu->language == language_cplus
+ || cu->language == language_java)
+ ? &objfile->global_psymbols
+ : &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu->language, objfile);
+ break;
+ default:
+ break;
+ }
+
+ xfree (built_actual_name);
+}
+
+/* Read a partial die corresponding to a namespace; also, add a symbol
+ corresponding to that namespace to the symbol table. NAMESPACE is
+ the name of the enclosing namespace. */
+
+static void
+add_partial_namespace (struct partial_die_info *pdi,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ int need_pc, struct dwarf2_cu *cu)
+{
+ /* Add a symbol for the namespace. */
+
+ add_partial_symbol (pdi, cu);
+
+ /* Now scan partial symbols in that namespace. */
+
+ if (pdi->has_children)
+ scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu);
+}
+
+/* Read a partial die corresponding to a Fortran module. */
+
+static void
+add_partial_module (struct partial_die_info *pdi, CORE_ADDR *lowpc,
+ CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu)
+{
+ /* Now scan partial symbols in that module. */
+
+ if (pdi->has_children)
+ scan_partial_symbols (pdi->die_child, lowpc, highpc, need_pc, cu);
+}
+
+/* Read a partial die corresponding to a subprogram and create a partial
+ symbol for that subprogram. When the CU language allows it, this
+ routine also defines a partial symbol for each nested subprogram
+ that this subprogram contains.
+
+ DIE my also be a lexical block, in which case we simply search
+ recursively for suprograms defined inside that lexical block.
+ Again, this is only performed when the CU language allows this
+ type of definitions. */
+
+static void
+add_partial_subprogram (struct partial_die_info *pdi,
+ CORE_ADDR *lowpc, CORE_ADDR *highpc,
+ int need_pc, struct dwarf2_cu *cu)
+{
+ if (pdi->tag == DW_TAG_subprogram)
+ {
+ if (pdi->has_pc_info)
+ {
+ if (pdi->lowpc < *lowpc)
+ *lowpc = pdi->lowpc;
+ if (pdi->highpc > *highpc)
+ *highpc = pdi->highpc;
+ if (need_pc)
+ {
+ CORE_ADDR baseaddr;
+ struct objfile *objfile = cu->objfile;
+
+ baseaddr = ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ addrmap_set_empty (objfile->psymtabs_addrmap,
+ pdi->lowpc + baseaddr,
+ pdi->highpc - 1 + baseaddr,
+ cu->per_cu->v.psymtab);
+ }
+ }
+
+ if (pdi->has_pc_info || (!pdi->is_external && pdi->may_be_inlined))
+ {
+ if (!pdi->is_declaration)
+ /* Ignore subprogram DIEs that do not have a name, they are
+ illegal. Do not emit a complaint at this point, we will
+ do so when we convert this psymtab into a symtab. */
+ if (pdi->name)
+ add_partial_symbol (pdi, cu);
+ }
+ }
+
+ if (! pdi->has_children)
+ return;
+
+ if (cu->language == language_ada)
+ {
+ pdi = pdi->die_child;
+ while (pdi != NULL)
+ {
+ fixup_partial_die (pdi, cu);
+ if (pdi->tag == DW_TAG_subprogram
+ || pdi->tag == DW_TAG_lexical_block)
+ add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu);
+ pdi = pdi->die_sibling;
+ }
+ }
+}
+
+/* Read a partial die corresponding to an enumeration type. */
+
+static void
+add_partial_enumeration (struct partial_die_info *enum_pdi,
+ struct dwarf2_cu *cu)
+{
+ struct partial_die_info *pdi;
+
+ if (enum_pdi->name != NULL)
+ add_partial_symbol (enum_pdi, cu);
+
+ pdi = enum_pdi->die_child;
+ while (pdi)
+ {
+ if (pdi->tag != DW_TAG_enumerator || pdi->name == NULL)
+ complaint (&symfile_complaints, _("malformed enumerator DIE ignored"));
+ else
+ add_partial_symbol (pdi, cu);
+ pdi = pdi->die_sibling;
+ }
+}
+
+/* Return the initial uleb128 in the die at INFO_PTR. */
+
+static unsigned int
+peek_abbrev_code (bfd *abfd, gdb_byte *info_ptr)
+{
+ unsigned int bytes_read;
+
+ return read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+}
+
+/* Read the initial uleb128 in the die at INFO_PTR in compilation unit CU.
+ Return the corresponding abbrev, or NULL if the number is zero (indicating
+ an empty DIE). In either case *BYTES_READ will be set to the length of
+ the initial number. */
+
+static struct abbrev_info *
+peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read,
+ struct dwarf2_cu *cu)
+{
+ bfd *abfd = cu->objfile->obfd;
+ unsigned int abbrev_number;
+ struct abbrev_info *abbrev;
+
+ abbrev_number = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
+
+ if (abbrev_number == 0)
+ return NULL;
+
+ abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number);
+ if (!abbrev)
+ {
+ error (_("Dwarf Error: Could not find abbrev number %d [in module %s]"),
+ abbrev_number, bfd_get_filename (abfd));
+ }
+
+ return abbrev;
+}
+
+/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER.
+ Returns a pointer to the end of a series of DIEs, terminated by an empty
+ DIE. Any children of the skipped DIEs will also be skipped. */
+
+static gdb_byte *
+skip_children (const struct die_reader_specs *reader, gdb_byte *info_ptr)
+{
+ struct dwarf2_cu *cu = reader->cu;
+ struct abbrev_info *abbrev;
+ unsigned int bytes_read;
+
+ while (1)
+ {
+ abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
+ if (abbrev == NULL)
+ return info_ptr + bytes_read;
+ else
+ info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
+ }
+}
+
+/* Scan the debug information for CU starting at INFO_PTR in buffer BUFFER.
+ INFO_PTR should point just after the initial uleb128 of a DIE, and the
+ abbrev corresponding to that skipped uleb128 should be passed in
+ ABBREV. Returns a pointer to this DIE's sibling, skipping any
+ children. */
+
+static gdb_byte *
+skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr,
+ struct abbrev_info *abbrev)
+{
+ unsigned int bytes_read;
+ struct attribute attr;
+ bfd *abfd = reader->abfd;
+ struct dwarf2_cu *cu = reader->cu;
+ gdb_byte *buffer = reader->buffer;
+ const gdb_byte *buffer_end = reader->buffer_end;
+ gdb_byte *start_info_ptr = info_ptr;
+ unsigned int form, i;
+
+ for (i = 0; i < abbrev->num_attrs; i++)
+ {
+ /* The only abbrev we care about is DW_AT_sibling. */
+ if (abbrev->attrs[i].name == DW_AT_sibling)
+ {
+ read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
+ if (attr.form == DW_FORM_ref_addr)
+ complaint (&symfile_complaints,
+ _("ignoring absolute DW_AT_sibling"));
+ else
+ return buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
+ }
+
+ /* If it isn't DW_AT_sibling, skip this attribute. */
+ form = abbrev->attrs[i].form;
+ skip_attribute:
+ switch (form)
{
case DW_FORM_ref_addr:
/* In DWARF 2, DW_FORM_ref_addr is address sized; in DWARF 3
@@ -4449,1432 +6306,2988 @@ skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
if (cu->header.version == 2)
info_ptr += cu->header.addr_size;
else
- info_ptr += cu->header.offset_size;
- break;
- case DW_FORM_addr:
- info_ptr += cu->header.addr_size;
- break;
- case DW_FORM_data1:
- case DW_FORM_ref1:
- case DW_FORM_flag:
- info_ptr += 1;
- break;
- case DW_FORM_flag_present:
- break;
- case DW_FORM_data2:
- case DW_FORM_ref2:
- info_ptr += 2;
- break;
- case DW_FORM_data4:
- case DW_FORM_ref4:
- info_ptr += 4;
- break;
- case DW_FORM_data8:
- case DW_FORM_ref8:
- case DW_FORM_ref_sig8:
- info_ptr += 8;
- break;
- case DW_FORM_string:
- read_direct_string (abfd, info_ptr, &bytes_read);
- info_ptr += bytes_read;
- break;
- case DW_FORM_sec_offset:
- case DW_FORM_strp:
- info_ptr += cu->header.offset_size;
- break;
- case DW_FORM_exprloc:
- case DW_FORM_block:
- info_ptr += read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
- info_ptr += bytes_read;
- break;
- case DW_FORM_block1:
- info_ptr += 1 + read_1_byte (abfd, info_ptr);
- break;
- case DW_FORM_block2:
- info_ptr += 2 + read_2_bytes (abfd, info_ptr);
- break;
- case DW_FORM_block4:
- info_ptr += 4 + read_4_bytes (abfd, info_ptr);
- break;
- case DW_FORM_sdata:
- case DW_FORM_udata:
- case DW_FORM_ref_udata:
- info_ptr = skip_leb128 (abfd, info_ptr);
- break;
- case DW_FORM_indirect:
- form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
- info_ptr += bytes_read;
- /* We need to continue parsing from here, so just go back to
- the top. */
- goto skip_attribute;
+ info_ptr += cu->header.offset_size;
+ break;
+ case DW_FORM_GNU_ref_alt:
+ info_ptr += cu->header.offset_size;
+ break;
+ case DW_FORM_addr:
+ info_ptr += cu->header.addr_size;
+ break;
+ case DW_FORM_data1:
+ case DW_FORM_ref1:
+ case DW_FORM_flag:
+ info_ptr += 1;
+ break;
+ case DW_FORM_flag_present:
+ break;
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ info_ptr += 2;
+ break;
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ info_ptr += 4;
+ break;
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ info_ptr += 8;
+ break;
+ case DW_FORM_string:
+ read_direct_string (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
+ case DW_FORM_GNU_strp_alt:
+ info_ptr += cu->header.offset_size;
+ break;
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ info_ptr += read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_block1:
+ info_ptr += 1 + read_1_byte (abfd, info_ptr);
+ break;
+ case DW_FORM_block2:
+ info_ptr += 2 + read_2_bytes (abfd, info_ptr);
+ break;
+ case DW_FORM_block4:
+ info_ptr += 4 + read_4_bytes (abfd, info_ptr);
+ break;
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ info_ptr = (gdb_byte *) safe_skip_leb128 (info_ptr, buffer_end);
+ break;
+ case DW_FORM_indirect:
+ form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ /* We need to continue parsing from here, so just go back to
+ the top. */
+ goto skip_attribute;
+
+ default:
+ error (_("Dwarf Error: Cannot handle %s "
+ "in DWARF reader [in module %s]"),
+ dwarf_form_name (form),
+ bfd_get_filename (abfd));
+ }
+ }
+
+ if (abbrev->has_children)
+ return skip_children (reader, info_ptr);
+ else
+ return info_ptr;
+}
+
+/* Locate ORIG_PDI's sibling.
+ INFO_PTR should point to the start of the next DIE after ORIG_PDI. */
+
+static gdb_byte *
+locate_pdi_sibling (const struct die_reader_specs *reader,
+ struct partial_die_info *orig_pdi,
+ gdb_byte *info_ptr)
+{
+ /* Do we know the sibling already? */
+
+ if (orig_pdi->sibling)
+ return orig_pdi->sibling;
+
+ /* Are there any children to deal with? */
+
+ if (!orig_pdi->has_children)
+ return info_ptr;
+
+ /* Skip the children the long way. */
+
+ return skip_children (reader, info_ptr);
+}
+
+/* Expand this partial symbol table into a full symbol table. SELF is
+ not NULL. */
+
+static void
+dwarf2_read_symtab (struct partial_symtab *self,
+ struct objfile *objfile)
+{
+ if (self->readin)
+ {
+ warning (_("bug: psymtab for %s is already read in."),
+ self->filename);
+ }
+ else
+ {
+ if (info_verbose)
+ {
+ printf_filtered (_("Reading in symbols for %s..."),
+ self->filename);
+ gdb_flush (gdb_stdout);
+ }
+
+ /* Restore our global data. */
+ dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+
+ /* If this psymtab is constructed from a debug-only objfile, the
+ has_section_at_zero flag will not necessarily be correct. We
+ can get the correct value for this flag by looking at the data
+ associated with the (presumably stripped) associated objfile. */
+ if (objfile->separate_debug_objfile_backlink)
+ {
+ struct dwarf2_per_objfile *dpo_backlink
+ = objfile_data (objfile->separate_debug_objfile_backlink,
+ dwarf2_objfile_data_key);
+
+ dwarf2_per_objfile->has_section_at_zero
+ = dpo_backlink->has_section_at_zero;
+ }
+
+ dwarf2_per_objfile->reading_partial_symbols = 0;
+
+ psymtab_to_symtab_1 (self);
+
+ /* Finish up the debug error message. */
+ if (info_verbose)
+ printf_filtered (_("done.\n"));
+ }
+
+ process_cu_includes ();
+}
+
+/* Reading in full CUs. */
+
+/* Add PER_CU to the queue. */
+
+static void
+queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
+ enum language pretend_language)
+{
+ struct dwarf2_queue_item *item;
+
+ per_cu->queued = 1;
+ item = xmalloc (sizeof (*item));
+ item->per_cu = per_cu;
+ item->pretend_language = pretend_language;
+ item->next = NULL;
+
+ if (dwarf2_queue == NULL)
+ dwarf2_queue = item;
+ else
+ dwarf2_queue_tail->next = item;
+
+ dwarf2_queue_tail = item;
+}
+
+/* THIS_CU has a reference to PER_CU. If necessary, load the new compilation
+ unit and add it to our queue.
+ The result is non-zero if PER_CU was queued, otherwise the result is zero
+ meaning either PER_CU is already queued or it is already loaded. */
+
+static int
+maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
+ struct dwarf2_per_cu_data *per_cu,
+ enum language pretend_language)
+{
+ /* We may arrive here during partial symbol reading, if we need full
+ DIEs to process an unusual case (e.g. template arguments). Do
+ not queue PER_CU, just tell our caller to load its DIEs. */
+ if (dwarf2_per_objfile->reading_partial_symbols)
+ {
+ if (per_cu->cu == NULL || per_cu->cu->dies == NULL)
+ return 1;
+ return 0;
+ }
+
+ /* Mark the dependence relation so that we don't flush PER_CU
+ too early. */
+ dwarf2_add_dependence (this_cu, per_cu);
+
+ /* If it's already on the queue, we have nothing to do. */
+ if (per_cu->queued)
+ return 0;
+
+ /* If the compilation unit is already loaded, just mark it as
+ used. */
+ if (per_cu->cu != NULL)
+ {
+ per_cu->cu->last_used = 0;
+ return 0;
+ }
+
+ /* Add it to the queue. */
+ queue_comp_unit (per_cu, pretend_language);
+
+ return 1;
+}
+
+/* Process the queue. */
+
+static void
+process_queue (void)
+{
+ struct dwarf2_queue_item *item, *next_item;
+
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Expanding one or more symtabs of objfile %s ...\n",
+ dwarf2_per_objfile->objfile->name);
+ }
+
+ /* The queue starts out with one item, but following a DIE reference
+ may load a new CU, adding it to the end of the queue. */
+ for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item)
+ {
+ if (dwarf2_per_objfile->using_index
+ ? !item->per_cu->v.quick->symtab
+ : (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin))
+ {
+ struct dwarf2_per_cu_data *per_cu = item->per_cu;
+
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Expanding symtab of %s at offset 0x%x\n",
+ per_cu->is_debug_types ? "TU" : "CU",
+ per_cu->offset.sect_off);
+ }
+
+ if (per_cu->is_debug_types)
+ process_full_type_unit (per_cu, item->pretend_language);
+ else
+ process_full_comp_unit (per_cu, item->pretend_language);
+
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Done expanding %s at offset 0x%x\n",
+ per_cu->is_debug_types ? "TU" : "CU",
+ per_cu->offset.sect_off);
+ }
+ }
+
+ item->per_cu->queued = 0;
+ next_item = item->next;
+ xfree (item);
+ }
+
+ dwarf2_queue_tail = NULL;
+
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Done expanding symtabs of %s.\n",
+ dwarf2_per_objfile->objfile->name);
+ }
+}
+
+/* Free all allocated queue entries. This function only releases anything if
+ an error was thrown; if the queue was processed then it would have been
+ freed as we went along. */
+
+static void
+dwarf2_release_queue (void *dummy)
+{
+ struct dwarf2_queue_item *item, *last;
+
+ item = dwarf2_queue;
+ while (item)
+ {
+ /* Anything still marked queued is likely to be in an
+ inconsistent state, so discard it. */
+ if (item->per_cu->queued)
+ {
+ if (item->per_cu->cu != NULL)
+ free_one_cached_comp_unit (item->per_cu);
+ item->per_cu->queued = 0;
+ }
+
+ last = item;
+ item = item->next;
+ xfree (last);
+ }
+
+ dwarf2_queue = dwarf2_queue_tail = NULL;
+}
+
+/* Read in full symbols for PST, and anything it depends on. */
+
+static void
+psymtab_to_symtab_1 (struct partial_symtab *pst)
+{
+ struct dwarf2_per_cu_data *per_cu;
+ int i;
+
+ if (pst->readin)
+ return;
+
+ for (i = 0; i < pst->number_of_dependencies; i++)
+ if (!pst->dependencies[i]->readin
+ && pst->dependencies[i]->user == NULL)
+ {
+ /* Inform about additional files that need to be read in. */
+ if (info_verbose)
+ {
+ /* FIXME: i18n: Need to make this a single string. */
+ fputs_filtered (" ", gdb_stdout);
+ wrap_here ("");
+ fputs_filtered ("and ", gdb_stdout);
+ wrap_here ("");
+ printf_filtered ("%s...", pst->dependencies[i]->filename);
+ wrap_here (""); /* Flush output. */
+ gdb_flush (gdb_stdout);
+ }
+ psymtab_to_symtab_1 (pst->dependencies[i]);
+ }
+
+ per_cu = pst->read_symtab_private;
+
+ if (per_cu == NULL)
+ {
+ /* It's an include file, no symbols to read for it.
+ Everything is in the parent symtab. */
+ pst->readin = 1;
+ return;
+ }
+
+ dw2_do_instantiate_symtab (per_cu);
+}
+
+/* Trivial hash function for die_info: the hash value of a DIE
+ is its offset in .debug_info for this objfile. */
+
+static hashval_t
+die_hash (const void *item)
+{
+ const struct die_info *die = item;
+
+ return die->offset.sect_off;
+}
+
+/* Trivial comparison function for die_info structures: two DIEs
+ are equal if they have the same offset. */
+
+static int
+die_eq (const void *item_lhs, const void *item_rhs)
+{
+ const struct die_info *die_lhs = item_lhs;
+ const struct die_info *die_rhs = item_rhs;
+
+ return die_lhs->offset.sect_off == die_rhs->offset.sect_off;
+}
+
+/* die_reader_func for load_full_comp_unit.
+ This is identical to read_signatured_type_reader,
+ but is kept separate for now. */
+
+static void
+load_full_comp_unit_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
+{
+ struct dwarf2_cu *cu = reader->cu;
+ enum language *language_ptr = data;
+
+ gdb_assert (cu->die_hash == NULL);
+ cu->die_hash =
+ htab_create_alloc_ex (cu->header.length / 12,
+ die_hash,
+ die_eq,
+ NULL,
+ &cu->comp_unit_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+
+ if (has_children)
+ comp_unit_die->child = read_die_and_siblings (reader, info_ptr,
+ &info_ptr, comp_unit_die);
+ cu->dies = comp_unit_die;
+ /* comp_unit_die is not stored in die_hash, no need. */
+
+ /* We try not to read any attributes in this function, because not
+ all CUs needed for references have been loaded yet, and symbol
+ table processing isn't initialized. But we have to set the CU language,
+ or we won't be able to build types correctly.
+ Similarly, if we do not read the producer, we can not apply
+ producer-specific interpretation. */
+ prepare_one_comp_unit (cu, cu->dies, *language_ptr);
+}
+
+/* Load the DIEs associated with PER_CU into memory. */
+
+static void
+load_full_comp_unit (struct dwarf2_per_cu_data *this_cu,
+ enum language pretend_language)
+{
+ gdb_assert (! this_cu->is_debug_types);
+
+ init_cutu_and_read_dies (this_cu, NULL, 1, 1,
+ load_full_comp_unit_reader, &pretend_language);
+}
+
+/* Add a DIE to the delayed physname list. */
+
+static void
+add_to_method_list (struct type *type, int fnfield_index, int index,
+ const char *name, struct die_info *die,
+ struct dwarf2_cu *cu)
+{
+ struct delayed_method_info mi;
+ mi.type = type;
+ mi.fnfield_index = fnfield_index;
+ mi.index = index;
+ mi.name = name;
+ mi.die = die;
+ VEC_safe_push (delayed_method_info, cu->method_list, &mi);
+}
+
+/* A cleanup for freeing the delayed method list. */
+
+static void
+free_delayed_list (void *ptr)
+{
+ struct dwarf2_cu *cu = (struct dwarf2_cu *) ptr;
+ if (cu->method_list != NULL)
+ {
+ VEC_free (delayed_method_info, cu->method_list);
+ cu->method_list = NULL;
+ }
+}
+
+/* Compute the physnames of any methods on the CU's method list.
+
+ The computation of method physnames is delayed in order to avoid the
+ (bad) condition that one of the method's formal parameters is of an as yet
+ incomplete type. */
+
+static void
+compute_delayed_physnames (struct dwarf2_cu *cu)
+{
+ int i;
+ struct delayed_method_info *mi;
+ for (i = 0; VEC_iterate (delayed_method_info, cu->method_list, i, mi) ; ++i)
+ {
+ const char *physname;
+ struct fn_fieldlist *fn_flp
+ = &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
+ physname = dwarf2_physname (mi->name, mi->die, cu);
+ fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
+ }
+}
+
+/* Go objects should be embedded in a DW_TAG_module DIE,
+ and it's not clear if/how imported objects will appear.
+ To keep Go support simple until that's worked out,
+ go back through what we've read and create something usable.
+ We could do this while processing each DIE, and feels kinda cleaner,
+ but that way is more invasive.
+ This is to, for example, allow the user to type "p var" or "b main"
+ without having to specify the package name, and allow lookups
+ of module.object to work in contexts that use the expression
+ parser. */
+
+static void
+fixup_go_packaging (struct dwarf2_cu *cu)
+{
+ char *package_name = NULL;
+ struct pending *list;
+ int i;
+
+ for (list = global_symbols; list != NULL; list = list->next)
+ {
+ for (i = 0; i < list->nsyms; ++i)
+ {
+ struct symbol *sym = list->symbol[i];
+
+ if (SYMBOL_LANGUAGE (sym) == language_go
+ && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ {
+ char *this_package_name = go_symbol_package_name (sym);
+
+ if (this_package_name == NULL)
+ continue;
+ if (package_name == NULL)
+ package_name = this_package_name;
+ else
+ {
+ if (strcmp (package_name, this_package_name) != 0)
+ complaint (&symfile_complaints,
+ _("Symtab %s has objects from two different Go packages: %s and %s"),
+ (SYMBOL_SYMTAB (sym)
+ ? symtab_to_filename_for_display (SYMBOL_SYMTAB (sym))
+ : cu->objfile->name),
+ this_package_name, package_name);
+ xfree (this_package_name);
+ }
+ }
+ }
+ }
+
+ if (package_name != NULL)
+ {
+ struct objfile *objfile = cu->objfile;
+ const char *saved_package_name = obstack_copy0 (&objfile->objfile_obstack,
+ package_name,
+ strlen (package_name));
+ struct type *type = init_type (TYPE_CODE_MODULE, 0, 0,
+ saved_package_name, objfile);
+ struct symbol *sym;
+
+ TYPE_TAG_NAME (type) = TYPE_NAME (type);
+
+ sym = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
+ SYMBOL_SET_LANGUAGE (sym, language_go);
+ SYMBOL_SET_NAMES (sym, saved_package_name,
+ strlen (saved_package_name), 0, objfile);
+ /* This is not VAR_DOMAIN because we want a way to ensure a lookup of,
+ e.g., "main" finds the "main" module and not C's main(). */
+ SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_TYPE (sym) = type;
+
+ add_symbol_to_list (sym, &global_symbols);
+
+ xfree (package_name);
+ }
+}
+
+static void compute_symtab_includes (struct dwarf2_per_cu_data *per_cu);
+
+/* Return the symtab for PER_CU. This works properly regardless of
+ whether we're using the index or psymtabs. */
+
+static struct symtab *
+get_symtab (struct dwarf2_per_cu_data *per_cu)
+{
+ return (dwarf2_per_objfile->using_index
+ ? per_cu->v.quick->symtab
+ : per_cu->v.psymtab->symtab);
+}
+
+/* A helper function for computing the list of all symbol tables
+ included by PER_CU. */
+
+static void
+recursively_compute_inclusions (VEC (dwarf2_per_cu_ptr) **result,
+ htab_t all_children,
+ struct dwarf2_per_cu_data *per_cu)
+{
+ void **slot;
+ int ix;
+ struct dwarf2_per_cu_data *iter;
+
+ slot = htab_find_slot (all_children, per_cu, INSERT);
+ if (*slot != NULL)
+ {
+ /* This inclusion and its children have been processed. */
+ return;
+ }
+
+ *slot = per_cu;
+ /* Only add a CU if it has a symbol table. */
+ if (get_symtab (per_cu) != NULL)
+ VEC_safe_push (dwarf2_per_cu_ptr, *result, per_cu);
+
+ for (ix = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs, ix, iter);
+ ++ix)
+ recursively_compute_inclusions (result, all_children, iter);
+}
+
+/* Compute the symtab 'includes' fields for the symtab related to
+ PER_CU. */
+
+static void
+compute_symtab_includes (struct dwarf2_per_cu_data *per_cu)
+{
+ gdb_assert (! per_cu->is_debug_types);
+
+ if (!VEC_empty (dwarf2_per_cu_ptr, per_cu->imported_symtabs))
+ {
+ int ix, len;
+ struct dwarf2_per_cu_data *iter;
+ VEC (dwarf2_per_cu_ptr) *result_children = NULL;
+ htab_t all_children;
+ struct symtab *symtab = get_symtab (per_cu);
+
+ /* If we don't have a symtab, we can just skip this case. */
+ if (symtab == NULL)
+ return;
+
+ all_children = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+
+ for (ix = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs,
+ ix, iter);
+ ++ix)
+ recursively_compute_inclusions (&result_children, all_children, iter);
+
+ /* Now we have a transitive closure of all the included CUs, and
+ for .gdb_index version 7 the included TUs, so we can convert it
+ to a list of symtabs. */
+ len = VEC_length (dwarf2_per_cu_ptr, result_children);
+ symtab->includes
+ = obstack_alloc (&dwarf2_per_objfile->objfile->objfile_obstack,
+ (len + 1) * sizeof (struct symtab *));
+ for (ix = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, result_children, ix, iter);
+ ++ix)
+ symtab->includes[ix] = get_symtab (iter);
+ symtab->includes[len] = NULL;
+
+ VEC_free (dwarf2_per_cu_ptr, result_children);
+ htab_delete (all_children);
+ }
+}
+
+/* Compute the 'includes' field for the symtabs of all the CUs we just
+ read. */
+
+static void
+process_cu_includes (void)
+{
+ int ix;
+ struct dwarf2_per_cu_data *iter;
+
+ for (ix = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus,
+ ix, iter);
+ ++ix)
+ {
+ if (! iter->is_debug_types)
+ compute_symtab_includes (iter);
+ }
+
+ VEC_free (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus);
+}
+
+/* Generate full symbol information for PER_CU, whose DIEs have
+ already been loaded into memory. */
+
+static void
+process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
+ enum language pretend_language)
+{
+ struct dwarf2_cu *cu = per_cu->cu;
+ struct objfile *objfile = per_cu->objfile;
+ CORE_ADDR lowpc, highpc;
+ struct symtab *symtab;
+ struct cleanup *back_to, *delayed_list_cleanup;
+ CORE_ADDR baseaddr;
+ struct block *static_block;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ buildsym_init ();
+ back_to = make_cleanup (really_free_pendings, NULL);
+ delayed_list_cleanup = make_cleanup (free_delayed_list, cu);
+
+ cu->list_in_scope = &file_symbols;
+
+ cu->language = pretend_language;
+ cu->language_defn = language_def (cu->language);
+
+ /* Do line number decoding in read_file_scope () */
+ process_die (cu->dies, cu);
+
+ /* For now fudge the Go package. */
+ if (cu->language == language_go)
+ fixup_go_packaging (cu);
+
+ /* Now that we have processed all the DIEs in the CU, all the types
+ should be complete, and it should now be safe to compute all of the
+ physnames. */
+ compute_delayed_physnames (cu);
+ do_cleanups (delayed_list_cleanup);
+
+ /* Some compilers don't define a DW_AT_high_pc attribute for the
+ compilation unit. If the DW_AT_high_pc is missing, synthesize
+ it, by scanning the DIE's below the compilation unit. */
+ get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
+
+ static_block
+ = end_symtab_get_static_block (highpc + baseaddr, objfile, 0,
+ per_cu->imported_symtabs != NULL);
+
+ /* If the comp unit has DW_AT_ranges, it may have discontiguous ranges.
+ Also, DW_AT_ranges may record ranges not belonging to any child DIEs
+ (such as virtual method tables). Record the ranges in STATIC_BLOCK's
+ addrmap to help ensure it has an accurate map of pc values belonging to
+ this comp unit. */
+ dwarf2_record_block_ranges (cu->dies, static_block, baseaddr, cu);
+
+ symtab = end_symtab_from_static_block (static_block, objfile,
+ SECT_OFF_TEXT (objfile), 0);
+
+ if (symtab != NULL)
+ {
+ int gcc_4_minor = producer_is_gcc_ge_4 (cu->producer);
+
+ /* Set symtab language to language from DW_AT_language. If the
+ compilation is from a C file generated by language preprocessors, do
+ not set the language if it was already deduced by start_subfile. */
+ if (!(cu->language == language_c && symtab->language != language_c))
+ symtab->language = cu->language;
+
+ /* GCC-4.0 has started to support -fvar-tracking. GCC-3.x still can
+ produce DW_AT_location with location lists but it can be possibly
+ invalid without -fvar-tracking. Still up to GCC-4.4.x incl. 4.4.0
+ there were bugs in prologue debug info, fixed later in GCC-4.5
+ by "unwind info for epilogues" patch (which is not directly related).
+
+ For -gdwarf-4 type units LOCATIONS_VALID indication is fortunately not
+ needed, it would be wrong due to missing DW_AT_producer there.
+
+ Still one can confuse GDB by using non-standard GCC compilation
+ options - this waits on GCC PR other/32998 (-frecord-gcc-switches).
+ */
+ if (cu->has_loclist && gcc_4_minor >= 5)
+ symtab->locations_valid = 1;
+
+ if (gcc_4_minor >= 5)
+ symtab->epilogue_unwind_valid = 1;
+
+ symtab->call_site_htab = cu->call_site_htab;
+ }
+
+ if (dwarf2_per_objfile->using_index)
+ per_cu->v.quick->symtab = symtab;
+ else
+ {
+ struct partial_symtab *pst = per_cu->v.psymtab;
+ pst->symtab = symtab;
+ pst->readin = 1;
+ }
+
+ /* Push it for inclusion processing later. */
+ VEC_safe_push (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus, per_cu);
+
+ do_cleanups (back_to);
+}
+
+/* Generate full symbol information for type unit PER_CU, whose DIEs have
+ already been loaded into memory. */
+
+static void
+process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
+ enum language pretend_language)
+{
+ struct dwarf2_cu *cu = per_cu->cu;
+ struct objfile *objfile = per_cu->objfile;
+ struct symtab *symtab;
+ struct cleanup *back_to, *delayed_list_cleanup;
+
+ buildsym_init ();
+ back_to = make_cleanup (really_free_pendings, NULL);
+ delayed_list_cleanup = make_cleanup (free_delayed_list, cu);
+
+ cu->list_in_scope = &file_symbols;
+
+ cu->language = pretend_language;
+ cu->language_defn = language_def (cu->language);
+
+ /* The symbol tables are set up in read_type_unit_scope. */
+ process_die (cu->dies, cu);
+
+ /* For now fudge the Go package. */
+ if (cu->language == language_go)
+ fixup_go_packaging (cu);
+
+ /* Now that we have processed all the DIEs in the CU, all the types
+ should be complete, and it should now be safe to compute all of the
+ physnames. */
+ compute_delayed_physnames (cu);
+ do_cleanups (delayed_list_cleanup);
+
+ /* TUs share symbol tables.
+ If this is the first TU to use this symtab, complete the construction
+ of it with end_expandable_symtab. Otherwise, complete the addition of
+ this TU's symbols to the existing symtab. */
+ if (per_cu->type_unit_group->primary_symtab == NULL)
+ {
+ symtab = end_expandable_symtab (0, objfile, SECT_OFF_TEXT (objfile));
+ per_cu->type_unit_group->primary_symtab = symtab;
+
+ if (symtab != NULL)
+ {
+ /* Set symtab language to language from DW_AT_language. If the
+ compilation is from a C file generated by language preprocessors,
+ do not set the language if it was already deduced by
+ start_subfile. */
+ if (!(cu->language == language_c && symtab->language != language_c))
+ symtab->language = cu->language;
+ }
+ }
+ else
+ {
+ augment_type_symtab (objfile,
+ per_cu->type_unit_group->primary_symtab);
+ symtab = per_cu->type_unit_group->primary_symtab;
+ }
+
+ if (dwarf2_per_objfile->using_index)
+ per_cu->v.quick->symtab = symtab;
+ else
+ {
+ struct partial_symtab *pst = per_cu->v.psymtab;
+ pst->symtab = symtab;
+ pst->readin = 1;
+ }
+
+ do_cleanups (back_to);
+}
+
+/* Process an imported unit DIE. */
+
+static void
+process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *attr;
+
+ /* For now we don't handle imported units in type units. */
+ if (cu->per_cu->is_debug_types)
+ {
+ error (_("Dwarf Error: DW_TAG_imported_unit is not"
+ " supported in type units [in module %s]"),
+ cu->objfile->name);
+ }
+
+ attr = dwarf2_attr (die, DW_AT_import, cu);
+ if (attr != NULL)
+ {
+ struct dwarf2_per_cu_data *per_cu;
+ struct symtab *imported_symtab;
+ sect_offset offset;
+ int is_dwz;
+
+ offset = dwarf2_get_ref_die_offset (attr);
+ is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
+ per_cu = dwarf2_find_containing_comp_unit (offset, is_dwz, cu->objfile);
+
+ /* Queue the unit, if needed. */
+ if (maybe_queue_comp_unit (cu, per_cu, cu->language))
+ load_full_comp_unit (per_cu, cu->language);
+
+ VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
+ per_cu);
+ }
+}
+
+/* Process a die and its children. */
+
+static void
+process_die (struct die_info *die, struct dwarf2_cu *cu)
+{
+ switch (die->tag)
+ {
+ case DW_TAG_padding:
+ break;
+ case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
+ read_file_scope (die, cu);
+ break;
+ case DW_TAG_type_unit:
+ read_type_unit_scope (die, cu);
+ break;
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ read_func_scope (die, cu);
+ break;
+ case DW_TAG_lexical_block:
+ case DW_TAG_try_block:
+ case DW_TAG_catch_block:
+ read_lexical_block_scope (die, cu);
+ break;
+ case DW_TAG_GNU_call_site:
+ read_call_site_scope (die, cu);
+ break;
+ case DW_TAG_class_type:
+ case DW_TAG_interface_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ process_structure_scope (die, cu);
+ break;
+ case DW_TAG_enumeration_type:
+ process_enumeration_scope (die, cu);
+ break;
+
+ /* These dies have a type, but processing them does not create
+ a symbol or recurse to process the children. Therefore we can
+ read them on-demand through read_type_die. */
+ case DW_TAG_subroutine_type:
+ case DW_TAG_set_type:
+ case DW_TAG_array_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_ptr_to_member_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_string_type:
+ break;
+
+ case DW_TAG_base_type:
+ case DW_TAG_subrange_type:
+ case DW_TAG_typedef:
+ /* Add a typedef symbol for the type definition, if it has a
+ DW_AT_name. */
+ new_symbol (die, read_type_die (die, cu), cu);
+ break;
+ case DW_TAG_common_block:
+ read_common_block (die, cu);
+ break;
+ case DW_TAG_common_inclusion:
+ break;
+ case DW_TAG_namespace:
+ cu->processing_has_namespace_info = 1;
+ read_namespace (die, cu);
+ break;
+ case DW_TAG_module:
+ cu->processing_has_namespace_info = 1;
+ read_module (die, cu);
+ break;
+ case DW_TAG_imported_declaration:
+ case DW_TAG_imported_module:
+ cu->processing_has_namespace_info = 1;
+ if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
+ || cu->language != language_fortran))
+ complaint (&symfile_complaints, _("Tag '%s' has unexpected children"),
+ dwarf_tag_name (die->tag));
+ read_import_statement (die, cu);
+ break;
+
+ case DW_TAG_imported_unit:
+ process_imported_unit_die (die, cu);
+ break;
+
+ default:
+ new_symbol (die, NULL, cu);
+ break;
+ }
+}
+
+/* A helper function for dwarf2_compute_name which determines whether DIE
+ needs to have the name of the scope prepended to the name listed in the
+ die. */
+
+static int
+die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *attr;
+
+ switch (die->tag)
+ {
+ case DW_TAG_namespace:
+ case DW_TAG_typedef:
+ case DW_TAG_class_type:
+ case DW_TAG_interface_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_enumerator:
+ case DW_TAG_subprogram:
+ case DW_TAG_member:
+ return 1;
+
+ case DW_TAG_variable:
+ case DW_TAG_constant:
+ /* We only need to prefix "globally" visible variables. These include
+ any variable marked with DW_AT_external or any variable that
+ lives in a namespace. [Variables in anonymous namespaces
+ require prefixing, but they are not DW_AT_external.] */
+
+ if (dwarf2_attr (die, DW_AT_specification, cu))
+ {
+ struct dwarf2_cu *spec_cu = cu;
+
+ return die_needs_namespace (die_specification (die, &spec_cu),
+ spec_cu);
+ }
+
+ attr = dwarf2_attr (die, DW_AT_external, cu);
+ if (attr == NULL && die->parent->tag != DW_TAG_namespace
+ && die->parent->tag != DW_TAG_module)
+ return 0;
+ /* A variable in a lexical block of some kind does not need a
+ namespace, even though in C++ such variables may be external
+ and have a mangled name. */
+ if (die->parent->tag == DW_TAG_lexical_block
+ || die->parent->tag == DW_TAG_try_block
+ || die->parent->tag == DW_TAG_catch_block
+ || die->parent->tag == DW_TAG_subprogram)
+ return 0;
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+/* Retrieve the last character from a mem_file. */
+
+static void
+do_ui_file_peek_last (void *object, const char *buffer, long length)
+{
+ char *last_char_p = (char *) object;
+
+ if (length > 0)
+ *last_char_p = buffer[length - 1];
+}
+
+/* Compute the fully qualified name of DIE in CU. If PHYSNAME is nonzero,
+ compute the physname for the object, which include a method's:
+ - formal parameters (C++/Java),
+ - receiver type (Go),
+ - return type (Java).
+
+ The term "physname" is a bit confusing.
+ For C++, for example, it is the demangled name.
+ For Go, for example, it's the mangled name.
+
+ For Ada, return the DIE's linkage name rather than the fully qualified
+ name. PHYSNAME is ignored..
+
+ The result is allocated on the objfile_obstack and canonicalized. */
+
+static const char *
+dwarf2_compute_name (const char *name,
+ struct die_info *die, struct dwarf2_cu *cu,
+ int physname)
+{
+ struct objfile *objfile = cu->objfile;
+
+ if (name == NULL)
+ name = dwarf2_name (die, cu);
+
+ /* For Fortran GDB prefers DW_AT_*linkage_name if present but otherwise
+ compute it by typename_concat inside GDB. */
+ if (cu->language == language_ada
+ || (cu->language == language_fortran && physname))
+ {
+ /* For Ada unit, we prefer the linkage name over the name, as
+ the former contains the exported name, which the user expects
+ to be able to reference. Ideally, we want the user to be able
+ to reference this entity using either natural or linkage name,
+ but we haven't started looking at this enhancement yet. */
+ struct attribute *attr;
+
+ attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
+ if (attr && DW_STRING (attr))
+ return DW_STRING (attr);
+ }
+
+ /* These are the only languages we know how to qualify names in. */
+ if (name != NULL
+ && (cu->language == language_cplus || cu->language == language_java
+ || cu->language == language_fortran))
+ {
+ if (die_needs_namespace (die, cu))
+ {
+ long length;
+ const char *prefix;
+ struct ui_file *buf;
+
+ prefix = determine_prefix (die, cu);
+ buf = mem_fileopen ();
+ if (*prefix != '\0')
+ {
+ char *prefixed_name = typename_concat (NULL, prefix, name,
+ physname, cu);
+
+ fputs_unfiltered (prefixed_name, buf);
+ xfree (prefixed_name);
+ }
+ else
+ fputs_unfiltered (name, buf);
+
+ /* Template parameters may be specified in the DIE's DW_AT_name, or
+ as children with DW_TAG_template_type_param or
+ DW_TAG_value_type_param. If the latter, add them to the name
+ here. If the name already has template parameters, then
+ skip this step; some versions of GCC emit both, and
+ it is more efficient to use the pre-computed name.
+
+ Something to keep in mind about this process: it is very
+ unlikely, or in some cases downright impossible, to produce
+ something that will match the mangled name of a function.
+ If the definition of the function has the same debug info,
+ we should be able to match up with it anyway. But fallbacks
+ using the minimal symbol, for instance to find a method
+ implemented in a stripped copy of libstdc++, will not work.
+ If we do not have debug info for the definition, we will have to
+ match them up some other way.
+
+ When we do name matching there is a related problem with function
+ templates; two instantiated function templates are allowed to
+ differ only by their return types, which we do not add here. */
+
+ if (cu->language == language_cplus && strchr (name, '<') == NULL)
+ {
+ struct attribute *attr;
+ struct die_info *child;
+ int first = 1;
+
+ die->building_fullname = 1;
+
+ for (child = die->child; child != NULL; child = child->sibling)
+ {
+ struct type *type;
+ LONGEST value;
+ gdb_byte *bytes;
+ struct dwarf2_locexpr_baton *baton;
+ struct value *v;
+
+ if (child->tag != DW_TAG_template_type_param
+ && child->tag != DW_TAG_template_value_param)
+ continue;
+
+ if (first)
+ {
+ fputs_unfiltered ("<", buf);
+ first = 0;
+ }
+ else
+ fputs_unfiltered (", ", buf);
+
+ attr = dwarf2_attr (child, DW_AT_type, cu);
+ if (attr == NULL)
+ {
+ complaint (&symfile_complaints,
+ _("template parameter missing DW_AT_type"));
+ fputs_unfiltered ("UNKNOWN_TYPE", buf);
+ continue;
+ }
+ type = die_type (child, cu);
+
+ if (child->tag == DW_TAG_template_type_param)
+ {
+ c_print_type (type, "", buf, -1, 0, &type_print_raw_options);
+ continue;
+ }
+
+ attr = dwarf2_attr (child, DW_AT_const_value, cu);
+ if (attr == NULL)
+ {
+ complaint (&symfile_complaints,
+ _("template parameter missing "
+ "DW_AT_const_value"));
+ fputs_unfiltered ("UNKNOWN_VALUE", buf);
+ continue;
+ }
+
+ dwarf2_const_value_attr (attr, type, name,
+ &cu->comp_unit_obstack, cu,
+ &value, &bytes, &baton);
+
+ if (TYPE_NOSIGN (type))
+ /* GDB prints characters as NUMBER 'CHAR'. If that's
+ changed, this can use value_print instead. */
+ c_printchar (value, type, buf);
+ else
+ {
+ struct value_print_options opts;
+
+ if (baton != NULL)
+ v = dwarf2_evaluate_loc_desc (type, NULL,
+ baton->data,
+ baton->size,
+ baton->per_cu);
+ else if (bytes != NULL)
+ {
+ v = allocate_value (type);
+ memcpy (value_contents_writeable (v), bytes,
+ TYPE_LENGTH (type));
+ }
+ else
+ v = value_from_longest (type, value);
+
+ /* Specify decimal so that we do not depend on
+ the radix. */
+ get_formatted_print_options (&opts, 'd');
+ opts.raw = 1;
+ value_print (v, buf, &opts);
+ release_value (v);
+ value_free (v);
+ }
+ }
- default:
- error (_("Dwarf Error: Cannot handle %s "
- "in DWARF reader [in module %s]"),
- dwarf_form_name (form),
- bfd_get_filename (abfd));
+ die->building_fullname = 0;
+
+ if (!first)
+ {
+ /* Close the argument list, with a space if necessary
+ (nested templates). */
+ char last_char = '\0';
+ ui_file_put (buf, do_ui_file_peek_last, &last_char);
+ if (last_char == '>')
+ fputs_unfiltered (" >", buf);
+ else
+ fputs_unfiltered (">", buf);
+ }
+ }
+
+ /* For Java and C++ methods, append formal parameter type
+ information, if PHYSNAME. */
+
+ if (physname && die->tag == DW_TAG_subprogram
+ && (cu->language == language_cplus
+ || cu->language == language_java))
+ {
+ struct type *type = read_type_die (die, cu);
+
+ c_type_print_args (type, buf, 1, cu->language,
+ &type_print_raw_options);
+
+ if (cu->language == language_java)
+ {
+ /* For java, we must append the return type to method
+ names. */
+ if (die->tag == DW_TAG_subprogram)
+ java_print_type (TYPE_TARGET_TYPE (type), "", buf,
+ 0, 0, &type_print_raw_options);
+ }
+ else if (cu->language == language_cplus)
+ {
+ /* Assume that an artificial first parameter is
+ "this", but do not crash if it is not. RealView
+ marks unnamed (and thus unused) parameters as
+ artificial; there is no way to differentiate
+ the two cases. */
+ if (TYPE_NFIELDS (type) > 0
+ && TYPE_FIELD_ARTIFICIAL (type, 0)
+ && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_PTR
+ && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type,
+ 0))))
+ fputs_unfiltered (" const", buf);
+ }
+ }
+
+ name = ui_file_obsavestring (buf, &objfile->objfile_obstack,
+ &length);
+ ui_file_delete (buf);
+
+ if (cu->language == language_cplus)
+ {
+ const char *cname
+ = dwarf2_canonicalize_name (name, cu,
+ &objfile->objfile_obstack);
+
+ if (cname != NULL)
+ name = cname;
+ }
}
}
- if (abbrev->has_children)
- return skip_children (buffer, info_ptr, cu);
- else
- return info_ptr;
+ return name;
}
-/* Locate ORIG_PDI's sibling.
- INFO_PTR should point to the start of the next DIE after ORIG_PDI
- in BUFFER. */
+/* Return the fully qualified name of DIE, based on its DW_AT_name.
+ If scope qualifiers are appropriate they will be added. The result
+ will be allocated on the objfile_obstack, or NULL if the DIE does
+ not have a name. NAME may either be from a previous call to
+ dwarf2_name or NULL.
-static gdb_byte *
-locate_pdi_sibling (struct partial_die_info *orig_pdi,
- gdb_byte *buffer, gdb_byte *info_ptr,
- bfd *abfd, struct dwarf2_cu *cu)
+ The output string will be canonicalized (if C++/Java). */
+
+static const char *
+dwarf2_full_name (const char *name, struct die_info *die, struct dwarf2_cu *cu)
{
- /* Do we know the sibling already? */
+ return dwarf2_compute_name (name, die, cu, 0);
+}
- if (orig_pdi->sibling)
- return orig_pdi->sibling;
+/* Construct a physname for the given DIE in CU. NAME may either be
+ from a previous call to dwarf2_name or NULL. The result will be
+ allocated on the objfile_objstack or NULL if the DIE does not have a
+ name.
- /* Are there any children to deal with? */
+ The output string will be canonicalized (if C++/Java). */
- if (!orig_pdi->has_children)
- return info_ptr;
+static const char *
+dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = cu->objfile;
+ struct attribute *attr;
+ const char *retval, *mangled = NULL, *canon = NULL;
+ struct cleanup *back_to;
+ int need_copy = 1;
- /* Skip the children the long way. */
+ /* In this case dwarf2_compute_name is just a shortcut not building anything
+ on its own. */
+ if (!die_needs_namespace (die, cu))
+ return dwarf2_compute_name (name, die, cu, 1);
- return skip_children (buffer, info_ptr, cu);
-}
+ back_to = make_cleanup (null_cleanup, NULL);
-/* Expand this partial symbol table into a full symbol table. */
+ attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
+ if (!attr)
+ attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
-static void
-dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
-{
- if (pst != NULL)
+ /* DW_AT_linkage_name is missing in some cases - depend on what GDB
+ has computed. */
+ if (attr && DW_STRING (attr))
+ {
+ char *demangled;
+
+ mangled = DW_STRING (attr);
+
+ /* Use DMGL_RET_DROP for C++ template functions to suppress their return
+ type. It is easier for GDB users to search for such functions as
+ `name(params)' than `long name(params)'. In such case the minimal
+ symbol names do not match the full symbol names but for template
+ functions there is never a need to look up their definition from their
+ declaration so the only disadvantage remains the minimal symbol
+ variant `long name(params)' does not have the proper inferior type.
+ */
+
+ if (cu->language == language_go)
+ {
+ /* This is a lie, but we already lie to the caller new_symbol_full.
+ new_symbol_full assumes we return the mangled name.
+ This just undoes that lie until things are cleaned up. */
+ demangled = NULL;
+ }
+ else
+ {
+ demangled = cplus_demangle (mangled,
+ (DMGL_PARAMS | DMGL_ANSI
+ | (cu->language == language_java
+ ? DMGL_JAVA | DMGL_RET_POSTFIX
+ : DMGL_RET_DROP)));
+ }
+ if (demangled)
+ {
+ make_cleanup (xfree, demangled);
+ canon = demangled;
+ }
+ else
+ {
+ canon = mangled;
+ need_copy = 0;
+ }
+ }
+
+ if (canon == NULL || check_physname)
{
- if (pst->readin)
+ const char *physname = dwarf2_compute_name (name, die, cu, 1);
+
+ if (canon != NULL && strcmp (physname, canon) != 0)
{
- warning (_("bug: psymtab for %s is already read in."),
- pst->filename);
+ /* It may not mean a bug in GDB. The compiler could also
+ compute DW_AT_linkage_name incorrectly. But in such case
+ GDB would need to be bug-to-bug compatible. */
+
+ complaint (&symfile_complaints,
+ _("Computed physname <%s> does not match demangled <%s> "
+ "(from linkage <%s>) - DIE at 0x%x [in module %s]"),
+ physname, canon, mangled, die->offset.sect_off, objfile->name);
+
+ /* Prefer DW_AT_linkage_name (in the CANON form) - when it
+ is available here - over computed PHYSNAME. It is safer
+ against both buggy GDB and buggy compilers. */
+
+ retval = canon;
}
else
{
- if (info_verbose)
- {
- printf_filtered (_("Reading in symbols for %s..."),
- pst->filename);
- gdb_flush (gdb_stdout);
- }
+ retval = physname;
+ need_copy = 0;
+ }
+ }
+ else
+ retval = canon;
+
+ if (need_copy)
+ retval = obstack_copy0 (&objfile->objfile_obstack, retval, strlen (retval));
+
+ do_cleanups (back_to);
+ return retval;
+}
+
+/* Read the import statement specified by the given die and record it. */
+
+static void
+read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = cu->objfile;
+ struct attribute *import_attr;
+ struct die_info *imported_die, *child_die;
+ struct dwarf2_cu *imported_cu;
+ const char *imported_name;
+ const char *imported_name_prefix;
+ const char *canonical_name;
+ const char *import_alias;
+ const char *imported_declaration = NULL;
+ const char *import_prefix;
+ VEC (const_char_ptr) *excludes = NULL;
+ struct cleanup *cleanups;
+
+ import_attr = dwarf2_attr (die, DW_AT_import, cu);
+ if (import_attr == NULL)
+ {
+ complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
+ dwarf_tag_name (die->tag));
+ return;
+ }
+
+ imported_cu = cu;
+ imported_die = follow_die_ref_or_sig (die, import_attr, &imported_cu);
+ imported_name = dwarf2_name (imported_die, imported_cu);
+ if (imported_name == NULL)
+ {
+ /* GCC bug: https://bugzilla.redhat.com/show_bug.cgi?id=506524
+
+ The import in the following code:
+ namespace A
+ {
+ typedef int B;
+ }
+
+ int main ()
+ {
+ using A::B;
+ B b;
+ return b;
+ }
+
+ ...
+ <2><51>: Abbrev Number: 3 (DW_TAG_imported_declaration)
+ <52> DW_AT_decl_file : 1
+ <53> DW_AT_decl_line : 6
+ <54> DW_AT_import : <0x75>
+ <2><58>: Abbrev Number: 4 (DW_TAG_typedef)
+ <59> DW_AT_name : B
+ <5b> DW_AT_decl_file : 1
+ <5c> DW_AT_decl_line : 2
+ <5d> DW_AT_type : <0x6e>
+ ...
+ <1><75>: Abbrev Number: 7 (DW_TAG_base_type)
+ <76> DW_AT_byte_size : 4
+ <77> DW_AT_encoding : 5 (signed)
+
+ imports the wrong die ( 0x75 instead of 0x58 ).
+ This case will be ignored until the gcc bug is fixed. */
+ return;
+ }
+
+ /* Figure out the local name after import. */
+ import_alias = dwarf2_name (die, cu);
- /* Restore our global data. */
- dwarf2_per_objfile = objfile_data (pst->objfile,
- dwarf2_objfile_data_key);
+ /* Figure out where the statement is being imported to. */
+ import_prefix = determine_prefix (die, cu);
+
+ /* Figure out what the scope of the imported die is and prepend it
+ to the name of the imported die. */
+ imported_name_prefix = determine_prefix (imported_die, imported_cu);
- /* If this psymtab is constructed from a debug-only objfile, the
- has_section_at_zero flag will not necessarily be correct. We
- can get the correct value for this flag by looking at the data
- associated with the (presumably stripped) associated objfile. */
- if (pst->objfile->separate_debug_objfile_backlink)
- {
- struct dwarf2_per_objfile *dpo_backlink
- = objfile_data (pst->objfile->separate_debug_objfile_backlink,
- dwarf2_objfile_data_key);
+ if (imported_die->tag != DW_TAG_namespace
+ && imported_die->tag != DW_TAG_module)
+ {
+ imported_declaration = imported_name;
+ canonical_name = imported_name_prefix;
+ }
+ else if (strlen (imported_name_prefix) > 0)
+ canonical_name = obconcat (&objfile->objfile_obstack,
+ imported_name_prefix, "::", imported_name,
+ (char *) NULL);
+ else
+ canonical_name = imported_name;
- dwarf2_per_objfile->has_section_at_zero
- = dpo_backlink->has_section_at_zero;
- }
+ cleanups = make_cleanup (VEC_cleanup (const_char_ptr), &excludes);
- dwarf2_per_objfile->reading_partial_symbols = 0;
+ if (die->tag == DW_TAG_imported_module && cu->language == language_fortran)
+ for (child_die = die->child; child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ {
+ /* DWARF-4: A Fortran use statement with a ârename listâ may be
+ represented by an imported module entry with an import attribute
+ referring to the module and owned entries corresponding to those
+ entities that are renamed as part of being imported. */
- psymtab_to_symtab_1 (pst);
+ if (child_die->tag != DW_TAG_imported_declaration)
+ {
+ complaint (&symfile_complaints,
+ _("child DW_TAG_imported_declaration expected "
+ "- DIE at 0x%x [in module %s]"),
+ child_die->offset.sect_off, objfile->name);
+ continue;
+ }
- /* Finish up the debug error message. */
- if (info_verbose)
- printf_filtered (_("done.\n"));
- }
- }
-}
+ import_attr = dwarf2_attr (child_die, DW_AT_import, cu);
+ if (import_attr == NULL)
+ {
+ complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
+ dwarf_tag_name (child_die->tag));
+ continue;
+ }
-/* Add PER_CU to the queue. */
+ imported_cu = cu;
+ imported_die = follow_die_ref_or_sig (child_die, import_attr,
+ &imported_cu);
+ imported_name = dwarf2_name (imported_die, imported_cu);
+ if (imported_name == NULL)
+ {
+ complaint (&symfile_complaints,
+ _("child DW_TAG_imported_declaration has unknown "
+ "imported name - DIE at 0x%x [in module %s]"),
+ child_die->offset.sect_off, objfile->name);
+ continue;
+ }
-static void
-queue_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile)
-{
- struct dwarf2_queue_item *item;
+ VEC_safe_push (const_char_ptr, excludes, imported_name);
- per_cu->queued = 1;
- item = xmalloc (sizeof (*item));
- item->per_cu = per_cu;
- item->next = NULL;
+ process_die (child_die, cu);
+ }
- if (dwarf2_queue == NULL)
- dwarf2_queue = item;
- else
- dwarf2_queue_tail->next = item;
+ cp_add_using_directive (import_prefix,
+ canonical_name,
+ import_alias,
+ imported_declaration,
+ excludes,
+ 0,
+ &objfile->objfile_obstack);
- dwarf2_queue_tail = item;
+ do_cleanups (cleanups);
}
-/* Process the queue. */
+/* Cleanup function for handle_DW_AT_stmt_list. */
static void
-process_queue (struct objfile *objfile)
+free_cu_line_header (void *arg)
{
- struct dwarf2_queue_item *item, *next_item;
-
- /* The queue starts out with one item, but following a DIE reference
- may load a new CU, adding it to the end of the queue. */
- for (item = dwarf2_queue; item != NULL; dwarf2_queue = item = next_item)
- {
- if (dwarf2_per_objfile->using_index
- ? !item->per_cu->v.quick->symtab
- : (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin))
- process_full_comp_unit (item->per_cu);
-
- item->per_cu->queued = 0;
- next_item = item->next;
- xfree (item);
- }
+ struct dwarf2_cu *cu = arg;
- dwarf2_queue_tail = NULL;
+ free_line_header (cu->line_header);
+ cu->line_header = NULL;
}
-/* Free all allocated queue entries. This function only releases anything if
- an error was thrown; if the queue was processed then it would have been
- freed as we went along. */
+/* Check for possibly missing DW_AT_comp_dir with relative .debug_line
+ directory paths. GCC SVN r127613 (new option -fdebug-prefix-map) fixed
+ this, it was first present in GCC release 4.3.0. */
-static void
-dwarf2_release_queue (void *dummy)
+static int
+producer_is_gcc_lt_4_3 (struct dwarf2_cu *cu)
{
- struct dwarf2_queue_item *item, *last;
-
- item = dwarf2_queue;
- while (item)
- {
- /* Anything still marked queued is likely to be in an
- inconsistent state, so discard it. */
- if (item->per_cu->queued)
- {
- if (item->per_cu->cu != NULL)
- free_one_cached_comp_unit (item->per_cu->cu);
- item->per_cu->queued = 0;
- }
-
- last = item;
- item = item->next;
- xfree (last);
- }
+ if (!cu->checked_producer)
+ check_producer (cu);
- dwarf2_queue = dwarf2_queue_tail = NULL;
+ return cu->producer_is_gcc_lt_4_3;
}
-/* Read in full symbols for PST, and anything it depends on. */
-
static void
-psymtab_to_symtab_1 (struct partial_symtab *pst)
+find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
+ const char **name, const char **comp_dir)
{
- struct dwarf2_per_cu_data *per_cu;
- struct cleanup *back_to;
- int i;
+ struct attribute *attr;
- for (i = 0; i < pst->number_of_dependencies; i++)
- if (!pst->dependencies[i]->readin)
- {
- /* Inform about additional files that need to be read in. */
- if (info_verbose)
- {
- /* FIXME: i18n: Need to make this a single string. */
- fputs_filtered (" ", gdb_stdout);
- wrap_here ("");
- fputs_filtered ("and ", gdb_stdout);
- wrap_here ("");
- printf_filtered ("%s...", pst->dependencies[i]->filename);
- wrap_here (""); /* Flush output. */
- gdb_flush (gdb_stdout);
- }
- psymtab_to_symtab_1 (pst->dependencies[i]);
- }
+ *name = NULL;
+ *comp_dir = NULL;
- per_cu = pst->read_symtab_private;
+ /* Find the filename. Do not use dwarf2_name here, since the filename
+ is not a source language identifier. */
+ attr = dwarf2_attr (die, DW_AT_name, cu);
+ if (attr)
+ {
+ *name = DW_STRING (attr);
+ }
- if (per_cu == NULL)
+ attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
+ if (attr)
+ *comp_dir = DW_STRING (attr);
+ else if (producer_is_gcc_lt_4_3 (cu) && *name != NULL
+ && IS_ABSOLUTE_PATH (*name))
{
- /* It's an include file, no symbols to read for it.
- Everything is in the parent symtab. */
- pst->readin = 1;
- return;
+ char *d = ldirname (*name);
+
+ *comp_dir = d;
+ if (d != NULL)
+ make_cleanup (xfree, d);
+ }
+ if (*comp_dir != NULL)
+ {
+ /* Irix 6.2 native cc prepends .: to the compilation
+ directory, get rid of it. */
+ char *cp = strchr (*comp_dir, ':');
+
+ if (cp && cp != *comp_dir && cp[-1] == '.' && cp[1] == '/')
+ *comp_dir = cp + 1;
}
- dw2_do_instantiate_symtab (pst->objfile, per_cu);
+ if (*name == NULL)
+ *name = "";
}
-/* Load the DIEs associated with PER_CU into memory. */
+/* Handle DW_AT_stmt_list for a compilation unit.
+ DIE is the DW_TAG_compile_unit die for CU.
+ COMP_DIR is the compilation directory.
+ WANT_LINE_INFO is non-zero if the pc/line-number mapping is needed. */
static void
-load_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
- struct objfile *objfile)
+handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
+ const char *comp_dir)
{
- bfd *abfd = objfile->obfd;
- struct dwarf2_cu *cu;
- unsigned int offset;
- gdb_byte *info_ptr, *beg_of_comp_unit;
- struct cleanup *free_abbrevs_cleanup = NULL, *free_cu_cleanup = NULL;
struct attribute *attr;
- int read_cu = 0;
- gdb_assert (! per_cu->debug_types_section);
+ gdb_assert (! cu->per_cu->is_debug_types);
- /* Set local variables from the partial symbol table info. */
- offset = per_cu->offset;
-
- dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
- info_ptr = dwarf2_per_objfile->info.buffer + offset;
- beg_of_comp_unit = info_ptr;
-
- if (per_cu->cu == NULL)
+ attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
+ if (attr)
{
- cu = xmalloc (sizeof (*cu));
- init_one_comp_unit (cu, objfile);
-
- read_cu = 1;
-
- /* If an error occurs while loading, release our storage. */
- free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
-
- /* Read in the comp_unit header. */
- info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd);
+ unsigned int line_offset = DW_UNSND (attr);
+ struct line_header *line_header
+ = dwarf_decode_line_header (line_offset, cu);
- /* Skip dummy compilation units. */
- if (info_ptr >= (dwarf2_per_objfile->info.buffer
- + dwarf2_per_objfile->info.size)
- || peek_abbrev_code (abfd, info_ptr) == 0)
+ if (line_header)
{
- do_cleanups (free_cu_cleanup);
- return;
+ cu->line_header = line_header;
+ make_cleanup (free_cu_line_header, cu);
+ dwarf_decode_lines (line_header, comp_dir, cu, NULL, 1);
}
+ }
+}
- /* Complete the cu_header. */
- cu->header.offset = offset;
- cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
-
- /* Read the abbrevs for this compilation unit. */
- dwarf2_read_abbrevs (abfd, cu);
- free_abbrevs_cleanup = make_cleanup (dwarf2_free_abbrev_table, cu);
+/* Process DW_TAG_compile_unit or DW_TAG_partial_unit. */
- /* Link this compilation unit into the compilation unit tree. */
- per_cu->cu = cu;
- cu->per_cu = per_cu;
+static void
+read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct cleanup *back_to = make_cleanup (null_cleanup, 0);
+ CORE_ADDR lowpc = ((CORE_ADDR) -1);
+ CORE_ADDR highpc = ((CORE_ADDR) 0);
+ struct attribute *attr;
+ const char *name = NULL;
+ const char *comp_dir = NULL;
+ struct die_info *child_die;
+ bfd *abfd = objfile->obfd;
+ CORE_ADDR baseaddr;
- /* Link this CU into read_in_chain. */
- per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
- dwarf2_per_objfile->read_in_chain = per_cu;
- }
- else
- {
- cu = per_cu->cu;
- info_ptr += cu->header.first_die_offset;
- }
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- cu->dies = read_comp_unit (info_ptr, cu);
+ get_scope_pc_bounds (die, &lowpc, &highpc, cu);
- /* We try not to read any attributes in this function, because not
- all objfiles needed for references have been loaded yet, and symbol
- table processing isn't initialized. But we have to set the CU language,
- or we won't be able to build types correctly. */
- prepare_one_comp_unit (cu, cu->dies);
+ /* If we didn't find a lowpc, set it to highpc to avoid complaints
+ from finish_block. */
+ if (lowpc == ((CORE_ADDR) -1))
+ lowpc = highpc;
+ lowpc += baseaddr;
+ highpc += baseaddr;
- /* Similarly, if we do not read the producer, we can not apply
- producer-specific interpretation. */
- attr = dwarf2_attr (cu->dies, DW_AT_producer, cu);
- if (attr)
- cu->producer = DW_STRING (attr);
+ find_file_and_directory (die, cu, &name, &comp_dir);
- if (read_cu)
- {
- do_cleanups (free_abbrevs_cleanup);
+ prepare_one_comp_unit (cu, die, cu->language);
- /* We've successfully allocated this compilation unit. Let our
- caller clean it up when finished with it. */
- discard_cleanups (free_cu_cleanup);
- }
-}
+ /* The XLCL doesn't generate DW_LANG_OpenCL because this attribute is not
+ standardised yet. As a workaround for the language detection we fall
+ back to the DW_AT_producer string. */
+ if (cu->producer && strstr (cu->producer, "IBM XL C for OpenCL") != NULL)
+ cu->language = language_opencl;
-/* Add a DIE to the delayed physname list. */
+ /* Similar hack for Go. */
+ if (cu->producer && strstr (cu->producer, "GNU Go ") != NULL)
+ set_cu_language (DW_LANG_Go, cu);
-static void
-add_to_method_list (struct type *type, int fnfield_index, int index,
- const char *name, struct die_info *die,
- struct dwarf2_cu *cu)
-{
- struct delayed_method_info mi;
- mi.type = type;
- mi.fnfield_index = fnfield_index;
- mi.index = index;
- mi.name = name;
- mi.die = die;
- VEC_safe_push (delayed_method_info, cu->method_list, &mi);
-}
+ dwarf2_start_symtab (cu, name, comp_dir, lowpc);
-/* A cleanup for freeing the delayed method list. */
+ /* Decode line number information if present. We do this before
+ processing child DIEs, so that the line header table is available
+ for DW_AT_decl_file. */
+ handle_DW_AT_stmt_list (die, cu, comp_dir);
-static void
-free_delayed_list (void *ptr)
-{
- struct dwarf2_cu *cu = (struct dwarf2_cu *) ptr;
- if (cu->method_list != NULL)
+ /* Process all dies in compilation unit. */
+ if (die->child != NULL)
{
- VEC_free (delayed_method_info, cu->method_list);
- cu->method_list = NULL;
+ child_die = die->child;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, cu);
+ child_die = sibling_die (child_die);
+ }
}
-}
-
-/* Compute the physnames of any methods on the CU's method list.
- The computation of method physnames is delayed in order to avoid the
- (bad) condition that one of the method's formal parameters is of an as yet
- incomplete type. */
+ /* Decode macro information, if present. Dwarf 2 macro information
+ refers to information in the line number info statement program
+ header, so we can only read it if we've read the header
+ successfully. */
+ attr = dwarf2_attr (die, DW_AT_GNU_macros, cu);
+ if (attr && cu->line_header)
+ {
+ if (dwarf2_attr (die, DW_AT_macro_info, cu))
+ complaint (&symfile_complaints,
+ _("CU refers to both DW_AT_GNU_macros and DW_AT_macro_info"));
-static void
-compute_delayed_physnames (struct dwarf2_cu *cu)
-{
- int i;
- struct delayed_method_info *mi;
- for (i = 0; VEC_iterate (delayed_method_info, cu->method_list, i, mi) ; ++i)
+ dwarf_decode_macros (cu, DW_UNSND (attr), comp_dir, 1);
+ }
+ else
{
- const char *physname;
- struct fn_fieldlist *fn_flp
- = &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
- physname = dwarf2_physname ((char *) mi->name, mi->die, cu);
- fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
+ attr = dwarf2_attr (die, DW_AT_macro_info, cu);
+ if (attr && cu->line_header)
+ {
+ unsigned int macro_offset = DW_UNSND (attr);
+
+ dwarf_decode_macros (cu, macro_offset, comp_dir, 0);
+ }
}
+
+ do_cleanups (back_to);
}
-/* Generate full symbol information for PST and CU, whose DIEs have
- already been loaded into memory. */
+/* TU version of handle_DW_AT_stmt_list for read_type_unit_scope.
+ Create the set of symtabs used by this TU, or if this TU is sharing
+ symtabs with another TU and the symtabs have already been created
+ then restore those symtabs in the line header.
+ We don't need the pc/line-number mapping for type units. */
static void
-process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
+setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
{
- struct dwarf2_cu *cu = per_cu->cu;
- struct objfile *objfile = per_cu->objfile;
- CORE_ADDR lowpc, highpc;
- struct symtab *symtab;
- struct cleanup *back_to, *delayed_list_cleanup;
- CORE_ADDR baseaddr;
-
- baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_per_cu_data *per_cu = cu->per_cu;
+ struct type_unit_group *tu_group;
+ int first_time;
+ struct line_header *lh;
+ struct attribute *attr;
+ unsigned int i, line_offset;
- buildsym_init ();
- back_to = make_cleanup (really_free_pendings, NULL);
- delayed_list_cleanup = make_cleanup (free_delayed_list, cu);
+ gdb_assert (per_cu->is_debug_types);
- cu->list_in_scope = &file_symbols;
+ attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
- /* Do line number decoding in read_file_scope () */
- process_die (cu->dies, cu);
+ /* If we're using .gdb_index (includes -readnow) then
+ per_cu->s.type_unit_group may not have been set up yet. */
+ if (per_cu->type_unit_group == NULL)
+ per_cu->type_unit_group = get_type_unit_group (cu, attr);
+ tu_group = per_cu->type_unit_group;
- /* Now that we have processed all the DIEs in the CU, all the types
- should be complete, and it should now be safe to compute all of the
- physnames. */
- compute_delayed_physnames (cu);
- do_cleanups (delayed_list_cleanup);
+ /* If we've already processed this stmt_list there's no real need to
+ do it again, we could fake it and just recreate the part we need
+ (file name,index -> symtab mapping). If data shows this optimization
+ is useful we can do it then. */
+ first_time = tu_group->primary_symtab == NULL;
- /* Some compilers don't define a DW_AT_high_pc attribute for the
- compilation unit. If the DW_AT_high_pc is missing, synthesize
- it, by scanning the DIE's below the compilation unit. */
- get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
+ /* We have to handle the case of both a missing DW_AT_stmt_list or bad
+ debug info. */
+ lh = NULL;
+ if (attr != NULL)
+ {
+ line_offset = DW_UNSND (attr);
+ lh = dwarf_decode_line_header (line_offset, cu);
+ }
+ if (lh == NULL)
+ {
+ if (first_time)
+ dwarf2_start_symtab (cu, "", NULL, 0);
+ else
+ {
+ gdb_assert (tu_group->symtabs == NULL);
+ restart_symtab (0);
+ }
+ /* Note: The primary symtab will get allocated at the end. */
+ return;
+ }
- symtab = end_symtab (highpc + baseaddr, objfile, SECT_OFF_TEXT (objfile));
+ cu->line_header = lh;
+ make_cleanup (free_cu_line_header, cu);
- if (symtab != NULL)
+ if (first_time)
{
- int gcc_4_minor = producer_is_gcc_ge_4 (cu->producer);
+ dwarf2_start_symtab (cu, "", NULL, 0);
- /* Set symtab language to language from DW_AT_language. If the
- compilation is from a C file generated by language preprocessors, do
- not set the language if it was already deduced by start_subfile. */
- if (!(cu->language == language_c && symtab->language != language_c))
- symtab->language = cu->language;
+ tu_group->num_symtabs = lh->num_file_names;
+ tu_group->symtabs = XNEWVEC (struct symtab *, lh->num_file_names);
- /* GCC-4.0 has started to support -fvar-tracking. GCC-3.x still can
- produce DW_AT_location with location lists but it can be possibly
- invalid without -fvar-tracking.
+ for (i = 0; i < lh->num_file_names; ++i)
+ {
+ char *dir = NULL;
+ struct file_entry *fe = &lh->file_names[i];
- For -gdwarf-4 type units LOCATIONS_VALID indication is fortunately not
- needed, it would be wrong due to missing DW_AT_producer there.
+ if (fe->dir_index)
+ dir = lh->include_dirs[fe->dir_index - 1];
+ dwarf2_start_subfile (fe->name, dir, NULL);
- Still one can confuse GDB by using non-standard GCC compilation
- options - this waits on GCC PR other/32998 (-frecord-gcc-switches).
- */
- if (cu->has_loclist && gcc_4_minor >= 0)
- symtab->locations_valid = 1;
+ /* Note: We don't have to watch for the main subfile here, type units
+ don't have DW_AT_name. */
- if (gcc_4_minor >= 5)
- symtab->epilogue_unwind_valid = 1;
+ if (current_subfile->symtab == NULL)
+ {
+ /* NOTE: start_subfile will recognize when it's been passed
+ a file it has already seen. So we can't assume there's a
+ simple mapping from lh->file_names to subfiles,
+ lh->file_names may contain dups. */
+ current_subfile->symtab = allocate_symtab (current_subfile->name,
+ objfile);
+ }
- symtab->call_site_htab = cu->call_site_htab;
+ fe->symtab = current_subfile->symtab;
+ tu_group->symtabs[i] = fe->symtab;
+ }
}
-
- if (dwarf2_per_objfile->using_index)
- per_cu->v.quick->symtab = symtab;
else
{
- struct partial_symtab *pst = per_cu->v.psymtab;
- pst->symtab = symtab;
- pst->readin = 1;
+ restart_symtab (0);
+
+ for (i = 0; i < lh->num_file_names; ++i)
+ {
+ struct file_entry *fe = &lh->file_names[i];
+
+ fe->symtab = tu_group->symtabs[i];
+ }
}
- do_cleanups (back_to);
+ /* The main symtab is allocated last. Type units don't have DW_AT_name
+ so they don't have a "real" (so to speak) symtab anyway.
+ There is later code that will assign the main symtab to all symbols
+ that don't have one. We need to handle the case of a symbol with a
+ missing symtab (DW_AT_decl_file) anyway. */
}
-/* Process a die and its children. */
+/* Process DW_TAG_type_unit.
+ For TUs we want to skip the first top level sibling if it's not the
+ actual type being defined by this TU. In this case the first top
+ level sibling is there to provide context only. */
static void
-process_die (struct die_info *die, struct dwarf2_cu *cu)
+read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
{
- switch (die->tag)
- {
- case DW_TAG_padding:
- break;
- case DW_TAG_compile_unit:
- read_file_scope (die, cu);
- break;
- case DW_TAG_type_unit:
- read_type_unit_scope (die, cu);
- break;
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- read_func_scope (die, cu);
- break;
- case DW_TAG_lexical_block:
- case DW_TAG_try_block:
- case DW_TAG_catch_block:
- read_lexical_block_scope (die, cu);
- break;
- case DW_TAG_GNU_call_site:
- read_call_site_scope (die, cu);
- break;
- case DW_TAG_class_type:
- case DW_TAG_interface_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- process_structure_scope (die, cu);
- break;
- case DW_TAG_enumeration_type:
- process_enumeration_scope (die, cu);
- break;
+ struct die_info *child_die;
- /* These dies have a type, but processing them does not create
- a symbol or recurse to process the children. Therefore we can
- read them on-demand through read_type_die. */
- case DW_TAG_subroutine_type:
- case DW_TAG_set_type:
- case DW_TAG_array_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
- case DW_TAG_reference_type:
- case DW_TAG_string_type:
- break;
+ prepare_one_comp_unit (cu, die, language_minimal);
- case DW_TAG_base_type:
- case DW_TAG_subrange_type:
- case DW_TAG_typedef:
- /* Add a typedef symbol for the type definition, if it has a
- DW_AT_name. */
- new_symbol (die, read_type_die (die, cu), cu);
- break;
- case DW_TAG_common_block:
- read_common_block (die, cu);
- break;
- case DW_TAG_common_inclusion:
- break;
- case DW_TAG_namespace:
- processing_has_namespace_info = 1;
- read_namespace (die, cu);
- break;
- case DW_TAG_module:
- processing_has_namespace_info = 1;
- read_module (die, cu);
- break;
- case DW_TAG_imported_declaration:
- case DW_TAG_imported_module:
- processing_has_namespace_info = 1;
- if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
- || cu->language != language_fortran))
- complaint (&symfile_complaints, _("Tag '%s' has unexpected children"),
- dwarf_tag_name (die->tag));
- read_import_statement (die, cu);
- break;
- default:
- new_symbol (die, NULL, cu);
- break;
+ /* Initialize (or reinitialize) the machinery for building symtabs.
+ We do this before processing child DIEs, so that the line header table
+ is available for DW_AT_decl_file. */
+ setup_type_unit_groups (die, cu);
+
+ if (die->child != NULL)
+ {
+ child_die = die->child;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, cu);
+ child_die = sibling_die (child_die);
+ }
}
}
+
+/* DWO/DWP files.
-/* A helper function for dwarf2_compute_name which determines whether DIE
- needs to have the name of the scope prepended to the name listed in the
- die. */
+ http://gcc.gnu.org/wiki/DebugFission
+ http://gcc.gnu.org/wiki/DebugFissionDWP
+
+ To simplify handling of both DWO files ("object" files with the DWARF info)
+ and DWP files (a file with the DWOs packaged up into one file), we treat
+ DWP files as having a collection of virtual DWO files. */
+
+static hashval_t
+hash_dwo_file (const void *item)
+{
+ const struct dwo_file *dwo_file = item;
+
+ return htab_hash_string (dwo_file->name);
+}
static int
-die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
+eq_dwo_file (const void *item_lhs, const void *item_rhs)
{
- struct attribute *attr;
+ const struct dwo_file *lhs = item_lhs;
+ const struct dwo_file *rhs = item_rhs;
- switch (die->tag)
- {
- case DW_TAG_namespace:
- case DW_TAG_typedef:
- case DW_TAG_class_type:
- case DW_TAG_interface_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_enumeration_type:
- case DW_TAG_enumerator:
- case DW_TAG_subprogram:
- case DW_TAG_member:
- return 1;
+ return strcmp (lhs->name, rhs->name) == 0;
+}
- case DW_TAG_variable:
- case DW_TAG_constant:
- /* We only need to prefix "globally" visible variables. These include
- any variable marked with DW_AT_external or any variable that
- lives in a namespace. [Variables in anonymous namespaces
- require prefixing, but they are not DW_AT_external.] */
+/* Allocate a hash table for DWO files. */
- if (dwarf2_attr (die, DW_AT_specification, cu))
- {
- struct dwarf2_cu *spec_cu = cu;
+static htab_t
+allocate_dwo_file_hash_table (void)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+
+ return htab_create_alloc_ex (41,
+ hash_dwo_file,
+ eq_dwo_file,
+ NULL,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+}
+
+/* Lookup DWO file DWO_NAME. */
- return die_needs_namespace (die_specification (die, &spec_cu),
- spec_cu);
- }
+static void **
+lookup_dwo_file_slot (const char *dwo_name)
+{
+ struct dwo_file find_entry;
+ void **slot;
- attr = dwarf2_attr (die, DW_AT_external, cu);
- if (attr == NULL && die->parent->tag != DW_TAG_namespace
- && die->parent->tag != DW_TAG_module)
- return 0;
- /* A variable in a lexical block of some kind does not need a
- namespace, even though in C++ such variables may be external
- and have a mangled name. */
- if (die->parent->tag == DW_TAG_lexical_block
- || die->parent->tag == DW_TAG_try_block
- || die->parent->tag == DW_TAG_catch_block
- || die->parent->tag == DW_TAG_subprogram)
- return 0;
- return 1;
+ if (dwarf2_per_objfile->dwo_files == NULL)
+ dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table ();
- default:
- return 0;
- }
+ memset (&find_entry, 0, sizeof (find_entry));
+ find_entry.name = dwo_name;
+ slot = htab_find_slot (dwarf2_per_objfile->dwo_files, &find_entry, INSERT);
+
+ return slot;
}
-/* Retrieve the last character from a mem_file. */
+static hashval_t
+hash_dwo_unit (const void *item)
+{
+ const struct dwo_unit *dwo_unit = item;
-static void
-do_ui_file_peek_last (void *object, const char *buffer, long length)
+ /* This drops the top 32 bits of the id, but is ok for a hash. */
+ return dwo_unit->signature;
+}
+
+static int
+eq_dwo_unit (const void *item_lhs, const void *item_rhs)
{
- char *last_char_p = (char *) object;
+ const struct dwo_unit *lhs = item_lhs;
+ const struct dwo_unit *rhs = item_rhs;
- if (length > 0)
- *last_char_p = buffer[length - 1];
+ /* The signature is assumed to be unique within the DWO file.
+ So while object file CU dwo_id's always have the value zero,
+ that's OK, assuming each object file DWO file has only one CU,
+ and that's the rule for now. */
+ return lhs->signature == rhs->signature;
}
-/* Compute the fully qualified name of DIE in CU. If PHYSNAME is nonzero,
- compute the physname for the object, which include a method's
- formal parameters (C++/Java) and return type (Java).
+/* Allocate a hash table for DWO CUs,TUs.
+ There is one of these tables for each of CUs,TUs for each DWO file. */
- For Ada, return the DIE's linkage name rather than the fully qualified
- name. PHYSNAME is ignored..
+static htab_t
+allocate_dwo_unit_table (struct objfile *objfile)
+{
+ /* Start out with a pretty small number.
+ Generally DWO files contain only one CU and maybe some TUs. */
+ return htab_create_alloc_ex (3,
+ hash_dwo_unit,
+ eq_dwo_unit,
+ NULL,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+}
- The result is allocated on the objfile_obstack and canonicalized. */
+/* Structure used to pass data to create_dwo_debug_info_hash_table_reader. */
-static const char *
-dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
- int physname)
+struct create_dwo_info_table_data
{
- if (name == NULL)
- name = dwarf2_name (die, cu);
+ struct dwo_file *dwo_file;
+ htab_t cu_htab;
+};
- /* For Fortran GDB prefers DW_AT_*linkage_name if present but otherwise
- compute it by typename_concat inside GDB. */
- if (cu->language == language_ada
- || (cu->language == language_fortran && physname))
- {
- /* For Ada unit, we prefer the linkage name over the name, as
- the former contains the exported name, which the user expects
- to be able to reference. Ideally, we want the user to be able
- to reference this entity using either natural or linkage name,
- but we haven't started looking at this enhancement yet. */
- struct attribute *attr;
+/* die_reader_func for create_dwo_debug_info_hash_table. */
- attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
- if (attr == NULL)
- attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
- if (attr && DW_STRING (attr))
- return DW_STRING (attr);
+static void
+create_dwo_debug_info_hash_table_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *datap)
+{
+ struct dwarf2_cu *cu = reader->cu;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ sect_offset offset = cu->per_cu->offset;
+ struct dwarf2_section_info *section = cu->per_cu->info_or_types_section;
+ struct create_dwo_info_table_data *data = datap;
+ struct dwo_file *dwo_file = data->dwo_file;
+ htab_t cu_htab = data->cu_htab;
+ void **slot;
+ struct attribute *attr;
+ struct dwo_unit *dwo_unit;
+
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu);
+ if (attr == NULL)
+ {
+ error (_("Dwarf Error: debug entry at offset 0x%x is missing"
+ " its dwo_id [in module %s]"),
+ offset.sect_off, dwo_file->name);
+ return;
}
- /* These are the only languages we know how to qualify names in. */
- if (name != NULL
- && (cu->language == language_cplus || cu->language == language_java
- || cu->language == language_fortran))
+ dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ dwo_unit->dwo_file = dwo_file;
+ dwo_unit->signature = DW_UNSND (attr);
+ dwo_unit->info_or_types_section = section;
+ dwo_unit->offset = offset;
+ dwo_unit->length = cu->per_cu->length;
+
+ slot = htab_find_slot (cu_htab, dwo_unit, INSERT);
+ gdb_assert (slot != NULL);
+ if (*slot != NULL)
{
- if (die_needs_namespace (die, cu))
- {
- long length;
- char *prefix;
- struct ui_file *buf;
+ const struct dwo_unit *dup_dwo_unit = *slot;
- prefix = determine_prefix (die, cu);
- buf = mem_fileopen ();
- if (*prefix != '\0')
- {
- char *prefixed_name = typename_concat (NULL, prefix, name,
- physname, cu);
+ complaint (&symfile_complaints,
+ _("debug entry at offset 0x%x is duplicate to the entry at"
+ " offset 0x%x, dwo_id 0x%s [in module %s]"),
+ offset.sect_off, dup_dwo_unit->offset.sect_off,
+ phex (dwo_unit->signature, sizeof (dwo_unit->signature)),
+ dwo_file->name);
+ }
+ else
+ *slot = dwo_unit;
- fputs_unfiltered (prefixed_name, buf);
- xfree (prefixed_name);
- }
- else
- fputs_unfiltered (name, buf);
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, " offset 0x%x, dwo_id 0x%s\n",
+ offset.sect_off,
+ phex (dwo_unit->signature,
+ sizeof (dwo_unit->signature)));
+}
- /* Template parameters may be specified in the DIE's DW_AT_name, or
- as children with DW_TAG_template_type_param or
- DW_TAG_value_type_param. If the latter, add them to the name
- here. If the name already has template parameters, then
- skip this step; some versions of GCC emit both, and
- it is more efficient to use the pre-computed name.
+/* Create a hash table to map DWO IDs to their CU entry in
+ .debug_info.dwo in DWO_FILE.
+ Note: This function processes DWO files only, not DWP files. */
- Something to keep in mind about this process: it is very
- unlikely, or in some cases downright impossible, to produce
- something that will match the mangled name of a function.
- If the definition of the function has the same debug info,
- we should be able to match up with it anyway. But fallbacks
- using the minimal symbol, for instance to find a method
- implemented in a stripped copy of libstdc++, will not work.
- If we do not have debug info for the definition, we will have to
- match them up some other way.
+static htab_t
+create_dwo_debug_info_hash_table (struct dwo_file *dwo_file)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_section_info *section = &dwo_file->sections.info;
+ bfd *abfd;
+ htab_t cu_htab;
+ gdb_byte *info_ptr, *end_ptr;
+ struct create_dwo_info_table_data create_dwo_info_table_data;
- When we do name matching there is a related problem with function
- templates; two instantiated function templates are allowed to
- differ only by their return types, which we do not add here. */
+ dwarf2_read_section (objfile, section);
+ info_ptr = section->buffer;
- if (cu->language == language_cplus && strchr (name, '<') == NULL)
- {
- struct attribute *attr;
- struct die_info *child;
- int first = 1;
+ if (info_ptr == NULL)
+ return NULL;
- die->building_fullname = 1;
+ /* We can't set abfd until now because the section may be empty or
+ not present, in which case section->asection will be NULL. */
+ abfd = section->asection->owner;
- for (child = die->child; child != NULL; child = child->sibling)
- {
- struct type *type;
- long value;
- gdb_byte *bytes;
- struct dwarf2_locexpr_baton *baton;
- struct value *v;
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "Reading .debug_info.dwo for %s:\n",
+ bfd_get_filename (abfd));
- if (child->tag != DW_TAG_template_type_param
- && child->tag != DW_TAG_template_value_param)
- continue;
+ cu_htab = allocate_dwo_unit_table (objfile);
- if (first)
- {
- fputs_unfiltered ("<", buf);
- first = 0;
- }
- else
- fputs_unfiltered (", ", buf);
+ create_dwo_info_table_data.dwo_file = dwo_file;
+ create_dwo_info_table_data.cu_htab = cu_htab;
- attr = dwarf2_attr (child, DW_AT_type, cu);
- if (attr == NULL)
- {
- complaint (&symfile_complaints,
- _("template parameter missing DW_AT_type"));
- fputs_unfiltered ("UNKNOWN_TYPE", buf);
- continue;
- }
- type = die_type (child, cu);
+ end_ptr = info_ptr + section->size;
+ while (info_ptr < end_ptr)
+ {
+ struct dwarf2_per_cu_data per_cu;
- if (child->tag == DW_TAG_template_type_param)
- {
- c_print_type (type, "", buf, -1, 0);
- continue;
- }
+ memset (&per_cu, 0, sizeof (per_cu));
+ per_cu.objfile = objfile;
+ per_cu.is_debug_types = 0;
+ per_cu.offset.sect_off = info_ptr - section->buffer;
+ per_cu.info_or_types_section = section;
- attr = dwarf2_attr (child, DW_AT_const_value, cu);
- if (attr == NULL)
- {
- complaint (&symfile_complaints,
- _("template parameter missing "
- "DW_AT_const_value"));
- fputs_unfiltered ("UNKNOWN_VALUE", buf);
- continue;
- }
+ init_cutu_and_read_dies_no_follow (&per_cu,
+ &dwo_file->sections.abbrev,
+ dwo_file,
+ create_dwo_debug_info_hash_table_reader,
+ &create_dwo_info_table_data);
- dwarf2_const_value_attr (attr, type, name,
- &cu->comp_unit_obstack, cu,
- &value, &bytes, &baton);
+ info_ptr += per_cu.length;
+ }
- if (TYPE_NOSIGN (type))
- /* GDB prints characters as NUMBER 'CHAR'. If that's
- changed, this can use value_print instead. */
- c_printchar (value, type, buf);
- else
- {
- struct value_print_options opts;
+ return cu_htab;
+}
- if (baton != NULL)
- v = dwarf2_evaluate_loc_desc (type, NULL,
- baton->data,
- baton->size,
- baton->per_cu);
- else if (bytes != NULL)
- {
- v = allocate_value (type);
- memcpy (value_contents_writeable (v), bytes,
- TYPE_LENGTH (type));
- }
- else
- v = value_from_longest (type, value);
+/* DWP file .debug_{cu,tu}_index section format:
+ [ref: http://gcc.gnu.org/wiki/DebugFissionDWP]
- /* Specify decimal so that we do not depend on
- the radix. */
- get_formatted_print_options (&opts, 'd');
- opts.raw = 1;
- value_print (v, buf, &opts);
- release_value (v);
- value_free (v);
- }
- }
+ Both index sections have the same format, and serve to map a 64-bit
+ signature to a set of section numbers. Each section begins with a header,
+ followed by a hash table of 64-bit signatures, a parallel table of 32-bit
+ indexes, and a pool of 32-bit section numbers. The index sections will be
+ aligned at 8-byte boundaries in the file.
- die->building_fullname = 0;
+ The index section header contains two unsigned 32-bit values (using the
+ byte order of the application binary):
- if (!first)
- {
- /* Close the argument list, with a space if necessary
- (nested templates). */
- char last_char = '\0';
- ui_file_put (buf, do_ui_file_peek_last, &last_char);
- if (last_char == '>')
- fputs_unfiltered (" >", buf);
- else
- fputs_unfiltered (">", buf);
- }
- }
+ N, the number of compilation units or type units in the index
+ M, the number of slots in the hash table
- /* For Java and C++ methods, append formal parameter type
- information, if PHYSNAME. */
+ (We assume that N and M will not exceed 2^32 - 1.)
- if (physname && die->tag == DW_TAG_subprogram
- && (cu->language == language_cplus
- || cu->language == language_java))
- {
- struct type *type = read_type_die (die, cu);
+ The size of the hash table, M, must be 2^k such that 2^k > 3*N/2.
- c_type_print_args (type, buf, 1, cu->language);
+ The hash table begins at offset 8 in the section, and consists of an array
+ of M 64-bit slots. Each slot contains a 64-bit signature (using the byte
+ order of the application binary). Unused slots in the hash table are 0.
+ (We rely on the extreme unlikeliness of a signature being exactly 0.)
- if (cu->language == language_java)
- {
- /* For java, we must append the return type to method
- names. */
- if (die->tag == DW_TAG_subprogram)
- java_print_type (TYPE_TARGET_TYPE (type), "", buf,
- 0, 0);
- }
- else if (cu->language == language_cplus)
- {
- /* Assume that an artificial first parameter is
- "this", but do not crash if it is not. RealView
- marks unnamed (and thus unused) parameters as
- artificial; there is no way to differentiate
- the two cases. */
- if (TYPE_NFIELDS (type) > 0
- && TYPE_FIELD_ARTIFICIAL (type, 0)
- && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_PTR
- && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type,
- 0))))
- fputs_unfiltered (" const", buf);
- }
- }
+ The parallel table begins immediately after the hash table
+ (at offset 8 + 8 * M from the beginning of the section), and consists of an
+ array of 32-bit indexes (using the byte order of the application binary),
+ corresponding 1-1 with slots in the hash table. Each entry in the parallel
+ table contains a 32-bit index into the pool of section numbers. For unused
+ hash table slots, the corresponding entry in the parallel table will be 0.
- name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
- &length);
- ui_file_delete (buf);
+ Given a 64-bit compilation unit signature or a type signature S, an entry
+ in the hash table is located as follows:
+
+ 1) Calculate a primary hash H = S & MASK(k), where MASK(k) is a mask with
+ the low-order k bits all set to 1.
+
+ 2) Calculate a secondary hash H' = (((S >> 32) & MASK(k)) | 1).
+
+ 3) If the hash table entry at index H matches the signature, use that
+ entry. If the hash table entry at index H is unused (all zeroes),
+ terminate the search: the signature is not present in the table.
+
+ 4) Let H = (H + H') modulo M. Repeat at Step 3.
+
+ Because M > N and H' and M are relatively prime, the search is guaranteed
+ to stop at an unused slot or find the match.
+
+ The pool of section numbers begins immediately following the hash table
+ (at offset 8 + 12 * M from the beginning of the section). The pool of
+ section numbers consists of an array of 32-bit words (using the byte order
+ of the application binary). Each item in the array is indexed starting
+ from 0. The hash table entry provides the index of the first section
+ number in the set. Additional section numbers in the set follow, and the
+ set is terminated by a 0 entry (section number 0 is not used in ELF).
+
+ In each set of section numbers, the .debug_info.dwo or .debug_types.dwo
+ section must be the first entry in the set, and the .debug_abbrev.dwo must
+ be the second entry. Other members of the set may follow in any order. */
+
+/* Create a hash table to map DWO IDs to their CU/TU entry in
+ .debug_{info,types}.dwo in DWP_FILE.
+ Returns NULL if there isn't one.
+ Note: This function processes DWP files only, not DWO files. */
+
+static struct dwp_hash_table *
+create_dwp_hash_table (struct dwp_file *dwp_file, int is_debug_types)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *dbfd = dwp_file->dbfd;
+ char *index_ptr, *index_end;
+ struct dwarf2_section_info *index;
+ uint32_t version, nr_units, nr_slots;
+ struct dwp_hash_table *htab;
- if (cu->language == language_cplus)
- {
- char *cname
- = dwarf2_canonicalize_name (name, cu,
- &cu->objfile->objfile_obstack);
+ if (is_debug_types)
+ index = &dwp_file->sections.tu_index;
+ else
+ index = &dwp_file->sections.cu_index;
- if (cname != NULL)
- name = cname;
- }
- }
- }
+ if (dwarf2_section_empty_p (index))
+ return NULL;
+ dwarf2_read_section (objfile, index);
- return name;
-}
+ index_ptr = index->buffer;
+ index_end = index_ptr + index->size;
-/* Return the fully qualified name of DIE, based on its DW_AT_name.
- If scope qualifiers are appropriate they will be added. The result
- will be allocated on the objfile_obstack, or NULL if the DIE does
- not have a name. NAME may either be from a previous call to
- dwarf2_name or NULL.
+ version = read_4_bytes (dbfd, index_ptr);
+ index_ptr += 8; /* Skip the unused word. */
+ nr_units = read_4_bytes (dbfd, index_ptr);
+ index_ptr += 4;
+ nr_slots = read_4_bytes (dbfd, index_ptr);
+ index_ptr += 4;
- The output string will be canonicalized (if C++/Java). */
+ if (version != 1)
+ {
+ error (_("Dwarf Error: unsupported DWP file version (%u)"
+ " [in module %s]"),
+ version, dwp_file->name);
+ }
+ if (nr_slots != (nr_slots & -nr_slots))
+ {
+ error (_("Dwarf Error: number of slots in DWP hash table (%u)"
+ " is not power of 2 [in module %s]"),
+ nr_slots, dwp_file->name);
+ }
-static const char *
-dwarf2_full_name (char *name, struct die_info *die, struct dwarf2_cu *cu)
-{
- return dwarf2_compute_name (name, die, cu, 0);
+ htab = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_hash_table);
+ htab->nr_units = nr_units;
+ htab->nr_slots = nr_slots;
+ htab->hash_table = index_ptr;
+ htab->unit_table = htab->hash_table + sizeof (uint64_t) * nr_slots;
+ htab->section_pool = htab->unit_table + sizeof (uint32_t) * nr_slots;
+
+ return htab;
}
-/* Construct a physname for the given DIE in CU. NAME may either be
- from a previous call to dwarf2_name or NULL. The result will be
- allocated on the objfile_objstack or NULL if the DIE does not have a
- name.
+/* Update SECTIONS with the data from SECTP.
- The output string will be canonicalized (if C++/Java). */
+ This function is like the other "locate" section routines that are
+ passed to bfd_map_over_sections, but in this context the sections to
+ read comes from the DWP hash table, not the full ELF section table.
-static const char *
-dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
+ The result is non-zero for success, or zero if an error was found. */
+
+static int
+locate_virtual_dwo_sections (asection *sectp,
+ struct virtual_dwo_sections *sections)
{
- struct attribute *attr;
- const char *retval, *mangled = NULL, *canon = NULL;
- struct cleanup *back_to;
- int need_copy = 1;
+ const struct dwop_section_names *names = &dwop_section_names;
- /* In this case dwarf2_compute_name is just a shortcut not building anything
- on its own. */
- if (!die_needs_namespace (die, cu))
- return dwarf2_compute_name (name, die, cu, 1);
+ if (section_is_p (sectp->name, &names->abbrev_dwo))
+ {
+ /* There can be only one. */
+ if (sections->abbrev.asection != NULL)
+ return 0;
+ sections->abbrev.asection = sectp;
+ sections->abbrev.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->info_dwo)
+ || section_is_p (sectp->name, &names->types_dwo))
+ {
+ /* There can be only one. */
+ if (sections->info_or_types.asection != NULL)
+ return 0;
+ sections->info_or_types.asection = sectp;
+ sections->info_or_types.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->line_dwo))
+ {
+ /* There can be only one. */
+ if (sections->line.asection != NULL)
+ return 0;
+ sections->line.asection = sectp;
+ sections->line.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->loc_dwo))
+ {
+ /* There can be only one. */
+ if (sections->loc.asection != NULL)
+ return 0;
+ sections->loc.asection = sectp;
+ sections->loc.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macinfo_dwo))
+ {
+ /* There can be only one. */
+ if (sections->macinfo.asection != NULL)
+ return 0;
+ sections->macinfo.asection = sectp;
+ sections->macinfo.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macro_dwo))
+ {
+ /* There can be only one. */
+ if (sections->macro.asection != NULL)
+ return 0;
+ sections->macro.asection = sectp;
+ sections->macro.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+ {
+ /* There can be only one. */
+ if (sections->str_offsets.asection != NULL)
+ return 0;
+ sections->str_offsets.asection = sectp;
+ sections->str_offsets.size = bfd_get_section_size (sectp);
+ }
+ else
+ {
+ /* No other kind of section is valid. */
+ return 0;
+ }
- back_to = make_cleanup (null_cleanup, NULL);
+ return 1;
+}
- attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
- if (!attr)
- attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
+/* Create a dwo_unit object for the DWO with signature SIGNATURE.
+ HTAB is the hash table from the DWP file.
+ SECTION_INDEX is the index of the DWO in HTAB. */
+
+static struct dwo_unit *
+create_dwo_in_dwp (struct dwp_file *dwp_file,
+ const struct dwp_hash_table *htab,
+ uint32_t section_index,
+ ULONGEST signature, int is_debug_types)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *dbfd = dwp_file->dbfd;
+ const char *kind = is_debug_types ? "TU" : "CU";
+ struct dwo_file *dwo_file;
+ struct dwo_unit *dwo_unit;
+ struct virtual_dwo_sections sections;
+ void **dwo_file_slot;
+ char *virtual_dwo_name;
+ struct dwarf2_section_info *cutu;
+ struct cleanup *cleanups;
+ int i;
- /* DW_AT_linkage_name is missing in some cases - depend on what GDB
- has computed. */
- if (attr && DW_STRING (attr))
+ if (dwarf2_read_debug)
{
- char *demangled;
+ fprintf_unfiltered (gdb_stdlog, "Reading %s %u/0x%s in DWP file: %s\n",
+ kind,
+ section_index, phex (signature, sizeof (signature)),
+ dwp_file->name);
+ }
- mangled = DW_STRING (attr);
+ /* Fetch the sections of this DWO.
+ Put a limit on the number of sections we look for so that bad data
+ doesn't cause us to loop forever. */
- /* Use DMGL_RET_DROP for C++ template functions to suppress their return
- type. It is easier for GDB users to search for such functions as
- `name(params)' than `long name(params)'. In such case the minimal
- symbol names do not match the full symbol names but for template
- functions there is never a need to look up their definition from their
- declaration so the only disadvantage remains the minimal symbol
- variant `long name(params)' does not have the proper inferior type.
- */
+#define MAX_NR_DWO_SECTIONS \
+ (1 /* .debug_info or .debug_types */ \
+ + 1 /* .debug_abbrev */ \
+ + 1 /* .debug_line */ \
+ + 1 /* .debug_loc */ \
+ + 1 /* .debug_str_offsets */ \
+ + 1 /* .debug_macro */ \
+ + 1 /* .debug_macinfo */ \
+ + 1 /* trailing zero */)
- demangled = cplus_demangle (mangled, (DMGL_PARAMS | DMGL_ANSI
- | (cu->language == language_java
- ? DMGL_JAVA | DMGL_RET_POSTFIX
- : DMGL_RET_DROP)));
- if (demangled)
+ memset (§ions, 0, sizeof (sections));
+ cleanups = make_cleanup (null_cleanup, 0);
+
+ for (i = 0; i < MAX_NR_DWO_SECTIONS; ++i)
+ {
+ asection *sectp;
+ uint32_t section_nr =
+ read_4_bytes (dbfd,
+ htab->section_pool
+ + (section_index + i) * sizeof (uint32_t));
+
+ if (section_nr == 0)
+ break;
+ if (section_nr >= dwp_file->num_sections)
{
- make_cleanup (xfree, demangled);
- canon = demangled;
+ error (_("Dwarf Error: bad DWP hash table, section number too large"
+ " [in module %s]"),
+ dwp_file->name);
}
- else
+
+ sectp = dwp_file->elf_sections[section_nr];
+ if (! locate_virtual_dwo_sections (sectp, §ions))
{
- canon = mangled;
- need_copy = 0;
+ error (_("Dwarf Error: bad DWP hash table, invalid section found"
+ " [in module %s]"),
+ dwp_file->name);
}
}
- if (canon == NULL || check_physname)
+ if (i < 2
+ || sections.info_or_types.asection == NULL
+ || sections.abbrev.asection == NULL)
{
- const char *physname = dwarf2_compute_name (name, die, cu, 1);
-
- if (canon != NULL && strcmp (physname, canon) != 0)
- {
- /* It may not mean a bug in GDB. The compiler could also
- compute DW_AT_linkage_name incorrectly. But in such case
- GDB would need to be bug-to-bug compatible. */
+ error (_("Dwarf Error: bad DWP hash table, missing DWO sections"
+ " [in module %s]"),
+ dwp_file->name);
+ }
+ if (i == MAX_NR_DWO_SECTIONS)
+ {
+ error (_("Dwarf Error: bad DWP hash table, too many DWO sections"
+ " [in module %s]"),
+ dwp_file->name);
+ }
- complaint (&symfile_complaints,
- _("Computed physname <%s> does not match demangled <%s> "
- "(from linkage <%s>) - DIE at 0x%x [in module %s]"),
- physname, canon, mangled, die->offset, cu->objfile->name);
+ /* It's easier for the rest of the code if we fake a struct dwo_file and
+ have dwo_unit "live" in that. At least for now.
- /* Prefer DW_AT_linkage_name (in the CANON form) - when it
- is available here - over computed PHYSNAME. It is safer
- against both buggy GDB and buggy compilers. */
+ The DWP file can be made up of a random collection of CUs and TUs.
+ However, for each CU + set of TUs that came from the same original DWO
+ file, we want to combine them back into a virtual DWO file to save space
+ (fewer struct dwo_file objects to allocated). Remember that for really
+ large apps there can be on the order of 8K CUs and 200K TUs, or more. */
- retval = canon;
- }
- else
+ virtual_dwo_name =
+ xstrprintf ("virtual-dwo/%d-%d-%d-%d",
+ sections.abbrev.asection ? sections.abbrev.asection->id : 0,
+ sections.line.asection ? sections.line.asection->id : 0,
+ sections.loc.asection ? sections.loc.asection->id : 0,
+ (sections.str_offsets.asection
+ ? sections.str_offsets.asection->id
+ : 0));
+ make_cleanup (xfree, virtual_dwo_name);
+ /* Can we use an existing virtual DWO file? */
+ dwo_file_slot = lookup_dwo_file_slot (virtual_dwo_name);
+ /* Create one if necessary. */
+ if (*dwo_file_slot == NULL)
+ {
+ if (dwarf2_read_debug)
{
- retval = physname;
- need_copy = 0;
+ fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
+ virtual_dwo_name);
}
+ dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
+ dwo_file->name = obstack_copy0 (&objfile->objfile_obstack,
+ virtual_dwo_name,
+ strlen (virtual_dwo_name));
+ dwo_file->sections.abbrev = sections.abbrev;
+ dwo_file->sections.line = sections.line;
+ dwo_file->sections.loc = sections.loc;
+ dwo_file->sections.macinfo = sections.macinfo;
+ dwo_file->sections.macro = sections.macro;
+ dwo_file->sections.str_offsets = sections.str_offsets;
+ /* The "str" section is global to the entire DWP file. */
+ dwo_file->sections.str = dwp_file->sections.str;
+ /* The info or types section is assigned later to dwo_unit,
+ there's no need to record it in dwo_file.
+ Also, we can't simply record type sections in dwo_file because
+ we record a pointer into the vector in dwo_unit. As we collect more
+ types we'll grow the vector and eventually have to reallocate space
+ for it, invalidating all the pointers into the current copy. */
+ *dwo_file_slot = dwo_file;
}
else
- retval = canon;
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
+ virtual_dwo_name);
+ }
+ dwo_file = *dwo_file_slot;
+ }
+ do_cleanups (cleanups);
- if (need_copy)
- retval = obsavestring (retval, strlen (retval),
- &cu->objfile->objfile_obstack);
+ dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ dwo_unit->dwo_file = dwo_file;
+ dwo_unit->signature = signature;
+ dwo_unit->info_or_types_section =
+ obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct dwarf2_section_info));
+ *dwo_unit->info_or_types_section = sections.info_or_types;
+ /* offset, length, type_offset_in_tu are set later. */
- do_cleanups (back_to);
- return retval;
+ return dwo_unit;
}
-/* Read the import statement specified by the given die and record it. */
+/* Lookup the DWO with SIGNATURE in DWP_FILE. */
-static void
-read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
+static struct dwo_unit *
+lookup_dwo_in_dwp (struct dwp_file *dwp_file,
+ const struct dwp_hash_table *htab,
+ ULONGEST signature, int is_debug_types)
{
- struct attribute *import_attr;
- struct die_info *imported_die, *child_die;
- struct dwarf2_cu *imported_cu;
- const char *imported_name;
- const char *imported_name_prefix;
- const char *canonical_name;
- const char *import_alias;
- const char *imported_declaration = NULL;
- const char *import_prefix;
- VEC (const_char_ptr) *excludes = NULL;
- struct cleanup *cleanups;
+ bfd *dbfd = dwp_file->dbfd;
+ uint32_t mask = htab->nr_slots - 1;
+ uint32_t hash = signature & mask;
+ uint32_t hash2 = ((signature >> 32) & mask) | 1;
+ unsigned int i;
+ void **slot;
+ struct dwo_unit find_dwo_cu, *dwo_cu;
- char *temp;
+ memset (&find_dwo_cu, 0, sizeof (find_dwo_cu));
+ find_dwo_cu.signature = signature;
+ slot = htab_find_slot (dwp_file->loaded_cutus, &find_dwo_cu, INSERT);
- import_attr = dwarf2_attr (die, DW_AT_import, cu);
- if (import_attr == NULL)
- {
- complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
- dwarf_tag_name (die->tag));
- return;
- }
+ if (*slot != NULL)
+ return *slot;
- imported_cu = cu;
- imported_die = follow_die_ref_or_sig (die, import_attr, &imported_cu);
- imported_name = dwarf2_name (imported_die, imported_cu);
- if (imported_name == NULL)
+ /* Use a for loop so that we don't loop forever on bad debug info. */
+ for (i = 0; i < htab->nr_slots; ++i)
{
- /* GCC bug: https://bugzilla.redhat.com/show_bug.cgi?id=506524
-
- The import in the following code:
- namespace A
- {
- typedef int B;
- }
+ ULONGEST signature_in_table;
- int main ()
- {
- using A::B;
- B b;
- return b;
- }
-
- ...
- <2><51>: Abbrev Number: 3 (DW_TAG_imported_declaration)
- <52> DW_AT_decl_file : 1
- <53> DW_AT_decl_line : 6
- <54> DW_AT_import : <0x75>
- <2><58>: Abbrev Number: 4 (DW_TAG_typedef)
- <59> DW_AT_name : B
- <5b> DW_AT_decl_file : 1
- <5c> DW_AT_decl_line : 2
- <5d> DW_AT_type : <0x6e>
- ...
- <1><75>: Abbrev Number: 7 (DW_TAG_base_type)
- <76> DW_AT_byte_size : 4
- <77> DW_AT_encoding : 5 (signed)
+ signature_in_table =
+ read_8_bytes (dbfd, htab->hash_table + hash * sizeof (uint64_t));
+ if (signature_in_table == signature)
+ {
+ uint32_t section_index =
+ read_4_bytes (dbfd, htab->unit_table + hash * sizeof (uint32_t));
- imports the wrong die ( 0x75 instead of 0x58 ).
- This case will be ignored until the gcc bug is fixed. */
- return;
+ *slot = create_dwo_in_dwp (dwp_file, htab, section_index,
+ signature, is_debug_types);
+ return *slot;
+ }
+ if (signature_in_table == 0)
+ return NULL;
+ hash = (hash + hash2) & mask;
}
- /* Figure out the local name after import. */
- import_alias = dwarf2_name (die, cu);
+ error (_("Dwarf Error: bad DWP hash table, lookup didn't terminate"
+ " [in module %s]"),
+ dwp_file->name);
+}
- /* Figure out where the statement is being imported to. */
- import_prefix = determine_prefix (die, cu);
+/* Subroutine of open_dwop_file to simplify it.
+ Open the file specified by FILE_NAME and hand it off to BFD for
+ preliminary analysis. Return a newly initialized bfd *, which
+ includes a canonicalized copy of FILE_NAME.
+ If IS_DWP is TRUE, we're opening a DWP file, otherwise a DWO file.
+ In case of trouble, return NULL.
+ NOTE: This function is derived from symfile_bfd_open. */
- /* Figure out what the scope of the imported die is and prepend it
- to the name of the imported die. */
- imported_name_prefix = determine_prefix (imported_die, imported_cu);
+static bfd *
+try_open_dwop_file (const char *file_name, int is_dwp)
+{
+ bfd *sym_bfd;
+ int desc, flags;
+ char *absolute_name;
- if (imported_die->tag != DW_TAG_namespace
- && imported_die->tag != DW_TAG_module)
+ flags = OPF_TRY_CWD_FIRST;
+ if (is_dwp)
+ flags |= OPF_SEARCH_IN_PATH;
+ desc = openp (debug_file_directory, flags, file_name,
+ O_RDONLY | O_BINARY, &absolute_name);
+ if (desc < 0)
+ return NULL;
+
+ sym_bfd = gdb_bfd_open (absolute_name, gnutarget, desc);
+ if (!sym_bfd)
{
- imported_declaration = imported_name;
- canonical_name = imported_name_prefix;
+ xfree (absolute_name);
+ return NULL;
}
- else if (strlen (imported_name_prefix) > 0)
+ xfree (absolute_name);
+ bfd_set_cacheable (sym_bfd, 1);
+
+ if (!bfd_check_format (sym_bfd, bfd_object))
{
- temp = alloca (strlen (imported_name_prefix)
- + 2 + strlen (imported_name) + 1);
- strcpy (temp, imported_name_prefix);
- strcat (temp, "::");
- strcat (temp, imported_name);
- canonical_name = temp;
+ gdb_bfd_unref (sym_bfd); /* This also closes desc. */
+ return NULL;
}
- else
- canonical_name = imported_name;
- cleanups = make_cleanup (VEC_cleanup (const_char_ptr), &excludes);
+ return sym_bfd;
+}
- if (die->tag == DW_TAG_imported_module && cu->language == language_fortran)
- for (child_die = die->child; child_die && child_die->tag;
- child_die = sibling_die (child_die))
- {
- /* DWARF-4: A Fortran use statement with a ârename listâ may be
- represented by an imported module entry with an import attribute
- referring to the module and owned entries corresponding to those
- entities that are renamed as part of being imported. */
+/* Try to open DWO/DWP file FILE_NAME.
+ COMP_DIR is the DW_AT_comp_dir attribute.
+ If IS_DWP is TRUE, we're opening a DWP file, otherwise a DWO file.
+ The result is the bfd handle of the file.
+ If there is a problem finding or opening the file, return NULL.
+ Upon success, the canonicalized path of the file is stored in the bfd,
+ same as symfile_bfd_open. */
- if (child_die->tag != DW_TAG_imported_declaration)
- {
- complaint (&symfile_complaints,
- _("child DW_TAG_imported_declaration expected "
- "- DIE at 0x%x [in module %s]"),
- child_die->offset, cu->objfile->name);
- continue;
- }
+static bfd *
+open_dwop_file (const char *file_name, const char *comp_dir, int is_dwp)
+{
+ bfd *abfd;
- import_attr = dwarf2_attr (child_die, DW_AT_import, cu);
- if (import_attr == NULL)
- {
- complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
- dwarf_tag_name (child_die->tag));
- continue;
- }
+ if (IS_ABSOLUTE_PATH (file_name))
+ return try_open_dwop_file (file_name, is_dwp);
- imported_cu = cu;
- imported_die = follow_die_ref_or_sig (child_die, import_attr,
- &imported_cu);
- imported_name = dwarf2_name (imported_die, imported_cu);
- if (imported_name == NULL)
- {
- complaint (&symfile_complaints,
- _("child DW_TAG_imported_declaration has unknown "
- "imported name - DIE at 0x%x [in module %s]"),
- child_die->offset, cu->objfile->name);
- continue;
- }
+ /* Before trying the search path, try DWO_NAME in COMP_DIR. */
- VEC_safe_push (const_char_ptr, excludes, imported_name);
+ if (comp_dir != NULL)
+ {
+ char *path_to_try = concat (comp_dir, SLASH_STRING, file_name, NULL);
+
+ /* NOTE: If comp_dir is a relative path, this will also try the
+ search path, which seems useful. */
+ abfd = try_open_dwop_file (path_to_try, is_dwp);
+ xfree (path_to_try);
+ if (abfd != NULL)
+ return abfd;
+ }
- process_die (child_die, cu);
- }
+ /* That didn't work, try debug-file-directory, which, despite its name,
+ is a list of paths. */
- cp_add_using_directive (import_prefix,
- canonical_name,
- import_alias,
- imported_declaration,
- excludes,
- &cu->objfile->objfile_obstack);
+ if (*debug_file_directory == '\0')
+ return NULL;
- do_cleanups (cleanups);
+ return try_open_dwop_file (file_name, is_dwp);
}
+/* This function is mapped across the sections and remembers the offset and
+ size of each of the DWO debugging sections we are interested in. */
+
static void
-initialize_cu_func_list (struct dwarf2_cu *cu)
+dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp, void *dwo_sections_ptr)
{
- cu->first_fn = cu->last_fn = cu->cached_fn = NULL;
+ struct dwo_sections *dwo_sections = dwo_sections_ptr;
+ const struct dwop_section_names *names = &dwop_section_names;
+
+ if (section_is_p (sectp->name, &names->abbrev_dwo))
+ {
+ dwo_sections->abbrev.asection = sectp;
+ dwo_sections->abbrev.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->info_dwo))
+ {
+ dwo_sections->info.asection = sectp;
+ dwo_sections->info.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->line_dwo))
+ {
+ dwo_sections->line.asection = sectp;
+ dwo_sections->line.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->loc_dwo))
+ {
+ dwo_sections->loc.asection = sectp;
+ dwo_sections->loc.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macinfo_dwo))
+ {
+ dwo_sections->macinfo.asection = sectp;
+ dwo_sections->macinfo.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macro_dwo))
+ {
+ dwo_sections->macro.asection = sectp;
+ dwo_sections->macro.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_dwo))
+ {
+ dwo_sections->str.asection = sectp;
+ dwo_sections->str.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+ {
+ dwo_sections->str_offsets.asection = sectp;
+ dwo_sections->str_offsets.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->types_dwo))
+ {
+ struct dwarf2_section_info type_section;
+
+ memset (&type_section, 0, sizeof (type_section));
+ type_section.asection = sectp;
+ type_section.size = bfd_get_section_size (sectp);
+ VEC_safe_push (dwarf2_section_info_def, dwo_sections->types,
+ &type_section);
+ }
}
-/* Cleanup function for read_file_scope. */
+/* Initialize the use of the DWO file specified by DWO_NAME.
+ The result is NULL if DWO_NAME can't be found. */
-static void
-free_cu_line_header (void *arg)
+static struct dwo_file *
+open_and_init_dwo_file (const char *dwo_name, const char *comp_dir)
{
- struct dwarf2_cu *cu = arg;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwo_file *dwo_file;
+ bfd *dbfd;
+ struct cleanup *cleanups;
- free_line_header (cu->line_header);
- cu->line_header = NULL;
+ dbfd = open_dwop_file (dwo_name, comp_dir, 0);
+ if (dbfd == NULL)
+ {
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "DWO file not found: %s\n", dwo_name);
+ return NULL;
+ }
+ dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
+ dwo_file->name = obstack_copy0 (&objfile->objfile_obstack,
+ dwo_name, strlen (dwo_name));
+ dwo_file->dbfd = dbfd;
+
+ cleanups = make_cleanup (free_dwo_file_cleanup, dwo_file);
+
+ bfd_map_over_sections (dbfd, dwarf2_locate_dwo_sections, &dwo_file->sections);
+
+ dwo_file->cus = create_dwo_debug_info_hash_table (dwo_file);
+
+ dwo_file->tus = create_debug_types_hash_table (dwo_file,
+ dwo_file->sections.types);
+
+ discard_cleanups (cleanups);
+
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "DWO file found: %s\n", dwo_name);
+
+ return dwo_file;
}
+/* This function is mapped across the sections and remembers the offset and
+ size of each of the DWP debugging sections we are interested in. */
+
static void
-find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
- char **name, char **comp_dir)
+dwarf2_locate_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
{
- struct attribute *attr;
+ struct dwp_file *dwp_file = dwp_file_ptr;
+ const struct dwop_section_names *names = &dwop_section_names;
+ unsigned int elf_section_nr = elf_section_data (sectp)->this_idx;
- *name = NULL;
- *comp_dir = NULL;
+ /* Record the ELF section number for later lookup: this is what the
+ .debug_cu_index,.debug_tu_index tables use. */
+ gdb_assert (elf_section_nr < dwp_file->num_sections);
+ dwp_file->elf_sections[elf_section_nr] = sectp;
- /* Find the filename. Do not use dwarf2_name here, since the filename
- is not a source language identifier. */
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr)
+ /* Look for specific sections that we need. */
+ if (section_is_p (sectp->name, &names->str_dwo))
{
- *name = DW_STRING (attr);
+ dwp_file->sections.str.asection = sectp;
+ dwp_file->sections.str.size = bfd_get_section_size (sectp);
}
-
- attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
- if (attr)
- *comp_dir = DW_STRING (attr);
- else if (*name != NULL && IS_ABSOLUTE_PATH (*name))
+ else if (section_is_p (sectp->name, &names->cu_index))
{
- *comp_dir = ldirname (*name);
- if (*comp_dir != NULL)
- make_cleanup (xfree, *comp_dir);
+ dwp_file->sections.cu_index.asection = sectp;
+ dwp_file->sections.cu_index.size = bfd_get_section_size (sectp);
}
- if (*comp_dir != NULL)
+ else if (section_is_p (sectp->name, &names->tu_index))
{
- /* Irix 6.2 native cc prepends .: to the compilation
- directory, get rid of it. */
- char *cp = strchr (*comp_dir, ':');
-
- if (cp && cp != *comp_dir && cp[-1] == '.' && cp[1] == '/')
- *comp_dir = cp + 1;
+ dwp_file->sections.tu_index.asection = sectp;
+ dwp_file->sections.tu_index.size = bfd_get_section_size (sectp);
}
+}
- if (*name == NULL)
- *name = "";
+/* Hash function for dwp_file loaded CUs/TUs. */
+
+static hashval_t
+hash_dwp_loaded_cutus (const void *item)
+{
+ const struct dwo_unit *dwo_unit = item;
+
+ /* This drops the top 32 bits of the signature, but is ok for a hash. */
+ return dwo_unit->signature;
}
-/* Handle DW_AT_stmt_list for a compilation unit or type unit.
- DIE is the DW_TAG_compile_unit or DW_TAG_type_unit die for CU.
- COMP_DIR is the compilation directory.
- WANT_LINE_INFO is non-zero if the pc/line-number mapping is needed. */
+/* Equality function for dwp_file loaded CUs/TUs. */
-static void
-handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
- const char *comp_dir, int want_line_info)
+static int
+eq_dwp_loaded_cutus (const void *a, const void *b)
{
- struct attribute *attr;
- struct objfile *objfile = cu->objfile;
- bfd *abfd = objfile->obfd;
+ const struct dwo_unit *dua = a;
+ const struct dwo_unit *dub = b;
- attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
- if (attr)
- {
- unsigned int line_offset = DW_UNSND (attr);
- struct line_header *line_header
- = dwarf_decode_line_header (line_offset, abfd, cu);
+ return dua->signature == dub->signature;
+}
- if (line_header)
- {
- cu->line_header = line_header;
- make_cleanup (free_cu_line_header, cu);
- dwarf_decode_lines (line_header, comp_dir, cu, NULL, want_line_info);
- }
- }
+/* Allocate a hash table for dwp_file loaded CUs/TUs. */
+
+static htab_t
+allocate_dwp_loaded_cutus_table (struct objfile *objfile)
+{
+ return htab_create_alloc_ex (3,
+ hash_dwp_loaded_cutus,
+ eq_dwp_loaded_cutus,
+ NULL,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
}
-/* Process DW_TAG_compile_unit. */
+/* Initialize the use of the DWP file for the current objfile.
+ By convention the name of the DWP file is ${objfile}.dwp.
+ The result is NULL if it can't be found. */
-static void
-read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
+static struct dwp_file *
+open_and_init_dwp_file (const char *comp_dir)
{
- struct objfile *objfile = cu->objfile;
- struct cleanup *back_to = make_cleanup (null_cleanup, 0);
- CORE_ADDR lowpc = ((CORE_ADDR) -1);
- CORE_ADDR highpc = ((CORE_ADDR) 0);
- struct attribute *attr;
- char *name = NULL;
- char *comp_dir = NULL;
- struct die_info *child_die;
- bfd *abfd = objfile->obfd;
- CORE_ADDR baseaddr;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwp_file *dwp_file;
+ char *dwp_name;
+ bfd *dbfd;
+ struct cleanup *cleanups;
- baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ dwp_name = xstrprintf ("%s.dwp", dwarf2_per_objfile->objfile->name);
+ cleanups = make_cleanup (xfree, dwp_name);
- get_scope_pc_bounds (die, &lowpc, &highpc, cu);
+ dbfd = open_dwop_file (dwp_name, comp_dir, 1);
+ if (dbfd == NULL)
+ {
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name);
+ do_cleanups (cleanups);
+ return NULL;
+ }
+ dwp_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_file);
+ dwp_file->name = obstack_copy0 (&objfile->objfile_obstack,
+ dwp_name, strlen (dwp_name));
+ dwp_file->dbfd = dbfd;
+ do_cleanups (cleanups);
- /* If we didn't find a lowpc, set it to highpc to avoid complaints
- from finish_block. */
- if (lowpc == ((CORE_ADDR) -1))
- lowpc = highpc;
- lowpc += baseaddr;
- highpc += baseaddr;
+ /* +1: section 0 is unused */
+ dwp_file->num_sections = bfd_count_sections (dbfd) + 1;
+ dwp_file->elf_sections =
+ OBSTACK_CALLOC (&objfile->objfile_obstack,
+ dwp_file->num_sections, asection *);
- find_file_and_directory (die, cu, &name, &comp_dir);
+ bfd_map_over_sections (dbfd, dwarf2_locate_dwp_sections, dwp_file);
- attr = dwarf2_attr (die, DW_AT_language, cu);
- if (attr)
+ dwp_file->cus = create_dwp_hash_table (dwp_file, 0);
+
+ dwp_file->tus = create_dwp_hash_table (dwp_file, 1);
+
+ dwp_file->loaded_cutus = allocate_dwp_loaded_cutus_table (objfile);
+
+ if (dwarf2_read_debug)
{
- set_cu_language (DW_UNSND (attr), cu);
+ fprintf_unfiltered (gdb_stdlog, "DWP file found: %s\n", dwp_file->name);
+ fprintf_unfiltered (gdb_stdlog,
+ " %u CUs, %u TUs\n",
+ dwp_file->cus ? dwp_file->cus->nr_units : 0,
+ dwp_file->tus ? dwp_file->tus->nr_units : 0);
}
- attr = dwarf2_attr (die, DW_AT_producer, cu);
- if (attr)
- cu->producer = DW_STRING (attr);
+ return dwp_file;
+}
- /* The XLCL doesn't generate DW_LANG_OpenCL because this attribute is not
- standardised yet. As a workaround for the language detection we fall
- back to the DW_AT_producer string. */
- if (cu->producer && strstr (cu->producer, "IBM XL C for OpenCL") != NULL)
- cu->language = language_opencl;
+/* Subroutine of lookup_dwo_comp_unit, lookup_dwo_type_unit.
+ Look up the CU/TU with signature SIGNATURE, either in DWO file DWO_NAME
+ or in the DWP file for the objfile, referenced by THIS_UNIT.
+ If non-NULL, comp_dir is the DW_AT_comp_dir attribute.
+ IS_DEBUG_TYPES is non-zero if reading a TU, otherwise read a CU.
- /* We assume that we're processing GCC output. */
- processing_gcc_compilation = 2;
+ This is called, for example, when wanting to read a variable with a
+ complex location. Therefore we don't want to do file i/o for every call.
+ Therefore we don't want to look for a DWO file on every call.
+ Therefore we first see if we've already seen SIGNATURE in a DWP file,
+ then we check if we've already seen DWO_NAME, and only THEN do we check
+ for a DWO file.
- processing_has_namespace_info = 0;
+ The result is a pointer to the dwo_unit object or NULL if we didn't find it
+ (dwo_id mismatch or couldn't find the DWO/DWP file). */
- start_symtab (name, comp_dir, lowpc);
- record_debugformat ("DWARF 2");
- record_producer (cu->producer);
+static struct dwo_unit *
+lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
+ const char *dwo_name, const char *comp_dir,
+ ULONGEST signature, int is_debug_types)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ const char *kind = is_debug_types ? "TU" : "CU";
+ void **dwo_file_slot;
+ struct dwo_file *dwo_file;
+ struct dwp_file *dwp_file;
- initialize_cu_func_list (cu);
+ /* Have we already read SIGNATURE from a DWP file? */
- /* Decode line number information if present. We do this before
- processing child DIEs, so that the line header table is available
- for DW_AT_decl_file. */
- handle_DW_AT_stmt_list (die, cu, comp_dir, 1);
+ if (! dwarf2_per_objfile->dwp_checked)
+ {
+ dwarf2_per_objfile->dwp_file = open_and_init_dwp_file (comp_dir);
+ dwarf2_per_objfile->dwp_checked = 1;
+ }
+ dwp_file = dwarf2_per_objfile->dwp_file;
- /* Process all dies in compilation unit. */
- if (die->child != NULL)
+ if (dwp_file != NULL)
{
- child_die = die->child;
- while (child_die && child_die->tag)
+ const struct dwp_hash_table *dwp_htab =
+ is_debug_types ? dwp_file->tus : dwp_file->cus;
+
+ if (dwp_htab != NULL)
{
- process_die (child_die, cu);
- child_die = sibling_die (child_die);
+ struct dwo_unit *dwo_cutu =
+ lookup_dwo_in_dwp (dwp_file, dwp_htab, signature, is_debug_types);
+
+ if (dwo_cutu != NULL)
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Virtual DWO %s %s found: @%s\n",
+ kind, hex_string (signature),
+ host_address_to_string (dwo_cutu));
+ }
+ return dwo_cutu;
+ }
}
}
- /* Decode macro information, if present. Dwarf 2 macro information
- refers to information in the line number info statement program
- header, so we can only read it if we've read the header
- successfully. */
- attr = dwarf2_attr (die, DW_AT_GNU_macros, cu);
- if (attr && cu->line_header)
- {
- if (dwarf2_attr (die, DW_AT_macro_info, cu))
- complaint (&symfile_complaints,
- _("CU refers to both DW_AT_GNU_macros and DW_AT_macro_info"));
+ /* Have we already seen DWO_NAME? */
- dwarf_decode_macros (cu->line_header, DW_UNSND (attr),
- comp_dir, abfd, cu,
- &dwarf2_per_objfile->macro, 1);
+ dwo_file_slot = lookup_dwo_file_slot (dwo_name);
+ if (*dwo_file_slot == NULL)
+ {
+ /* Read in the file and build a table of the DWOs it contains. */
+ *dwo_file_slot = open_and_init_dwo_file (dwo_name, comp_dir);
}
- else
+ /* NOTE: This will be NULL if unable to open the file. */
+ dwo_file = *dwo_file_slot;
+
+ if (dwo_file != NULL)
{
- attr = dwarf2_attr (die, DW_AT_macro_info, cu);
- if (attr && cu->line_header)
+ htab_t htab = is_debug_types ? dwo_file->tus : dwo_file->cus;
+
+ if (htab != NULL)
{
- unsigned int macro_offset = DW_UNSND (attr);
+ struct dwo_unit find_dwo_cutu, *dwo_cutu;
+
+ memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu));
+ find_dwo_cutu.signature = signature;
+ dwo_cutu = htab_find (htab, &find_dwo_cutu);
- dwarf_decode_macros (cu->line_header, macro_offset,
- comp_dir, abfd, cu,
- &dwarf2_per_objfile->macinfo, 0);
+ if (dwo_cutu != NULL)
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "DWO %s %s(%s) found: @%s\n",
+ kind, dwo_name, hex_string (signature),
+ host_address_to_string (dwo_cutu));
+ }
+ return dwo_cutu;
+ }
}
}
- do_cleanups (back_to);
-}
-
-/* Process DW_TAG_type_unit.
- For TUs we want to skip the first top level sibling if it's not the
- actual type being defined by this TU. In this case the first top
- level sibling is there to provide context only. */
-
-static void
-read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
-{
- struct objfile *objfile = cu->objfile;
- struct cleanup *back_to = make_cleanup (null_cleanup, 0);
- CORE_ADDR lowpc;
- struct attribute *attr;
- char *name = NULL;
- char *comp_dir = NULL;
- struct die_info *child_die;
- bfd *abfd = objfile->obfd;
-
- /* start_symtab needs a low pc, but we don't really have one.
- Do what read_file_scope would do in the absence of such info. */
- lowpc = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- /* Find the filename. Do not use dwarf2_name here, since the filename
- is not a source language identifier. */
- attr = dwarf2_attr (die, DW_AT_name, cu);
- if (attr)
- name = DW_STRING (attr);
+ /* We didn't find it. This could mean a dwo_id mismatch, or
+ someone deleted the DWO/DWP file, or the search path isn't set up
+ correctly to find the file. */
- attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
- if (attr)
- comp_dir = DW_STRING (attr);
- else if (name != NULL && IS_ABSOLUTE_PATH (name))
+ if (dwarf2_read_debug)
{
- comp_dir = ldirname (name);
- if (comp_dir != NULL)
- make_cleanup (xfree, comp_dir);
+ fprintf_unfiltered (gdb_stdlog, "DWO %s %s(%s) not found\n",
+ kind, dwo_name, hex_string (signature));
}
- if (name == NULL)
- name = "";
+ complaint (&symfile_complaints,
+ _("Could not find DWO CU referenced by CU at offset 0x%x"
+ " [in module %s]"),
+ this_unit->offset.sect_off, objfile->name);
+ return NULL;
+}
- attr = dwarf2_attr (die, DW_AT_language, cu);
- if (attr)
- set_cu_language (DW_UNSND (attr), cu);
+/* Lookup the DWO CU DWO_NAME/SIGNATURE referenced from THIS_CU.
+ See lookup_dwo_cutu_unit for details. */
- /* This isn't technically needed today. It is done for symmetry
- with read_file_scope. */
- attr = dwarf2_attr (die, DW_AT_producer, cu);
- if (attr)
- cu->producer = DW_STRING (attr);
+static struct dwo_unit *
+lookup_dwo_comp_unit (struct dwarf2_per_cu_data *this_cu,
+ const char *dwo_name, const char *comp_dir,
+ ULONGEST signature)
+{
+ return lookup_dwo_cutu (this_cu, dwo_name, comp_dir, signature, 0);
+}
- /* We assume that we're processing GCC output. */
- processing_gcc_compilation = 2;
+/* Lookup the DWO TU DWO_NAME/SIGNATURE referenced from THIS_TU.
+ See lookup_dwo_cutu_unit for details. */
- processing_has_namespace_info = 0;
+static struct dwo_unit *
+lookup_dwo_type_unit (struct signatured_type *this_tu,
+ const char *dwo_name, const char *comp_dir)
+{
+ return lookup_dwo_cutu (&this_tu->per_cu, dwo_name, comp_dir, this_tu->signature, 1);
+}
- start_symtab (name, comp_dir, lowpc);
- record_debugformat ("DWARF 2");
- record_producer (cu->producer);
+/* Free all resources associated with DWO_FILE.
+ Close the DWO file and munmap the sections.
+ All memory should be on the objfile obstack. */
- /* Decode line number information if present. We do this before
- processing child DIEs, so that the line header table is available
- for DW_AT_decl_file.
- We don't need the pc/line-number mapping for type units. */
- handle_DW_AT_stmt_list (die, cu, comp_dir, 0);
+static void
+free_dwo_file (struct dwo_file *dwo_file, struct objfile *objfile)
+{
+ int ix;
+ struct dwarf2_section_info *section;
- /* Process the dies in the type unit. */
- if (die->child == NULL)
- {
- dump_die_for_error (die);
- error (_("Dwarf Error: Missing children for type unit [in module %s]"),
- bfd_get_filename (abfd));
- }
+ /* Note: dbfd is NULL for virtual DWO files. */
+ gdb_bfd_unref (dwo_file->dbfd);
- child_die = die->child;
+ VEC_free (dwarf2_section_info_def, dwo_file->sections.types);
+}
- while (child_die && child_die->tag)
- {
- process_die (child_die, cu);
+/* Wrapper for free_dwo_file for use in cleanups. */
- child_die = sibling_die (child_die);
- }
+static void
+free_dwo_file_cleanup (void *arg)
+{
+ struct dwo_file *dwo_file = (struct dwo_file *) arg;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
- do_cleanups (back_to);
+ free_dwo_file (dwo_file, objfile);
}
-static void
-add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc,
- struct dwarf2_cu *cu)
+/* Traversal function for free_dwo_files. */
+
+static int
+free_dwo_file_from_slot (void **slot, void *info)
{
- struct function_range *thisfn;
+ struct dwo_file *dwo_file = (struct dwo_file *) *slot;
+ struct objfile *objfile = (struct objfile *) info;
+
+ free_dwo_file (dwo_file, objfile);
- thisfn = (struct function_range *)
- obstack_alloc (&cu->comp_unit_obstack, sizeof (struct function_range));
- thisfn->name = name;
- thisfn->lowpc = lowpc;
- thisfn->highpc = highpc;
- thisfn->seen_line = 0;
- thisfn->next = NULL;
+ return 1;
+}
- if (cu->last_fn == NULL)
- cu->first_fn = thisfn;
- else
- cu->last_fn->next = thisfn;
+/* Free all resources associated with DWO_FILES. */
- cu->last_fn = thisfn;
+static void
+free_dwo_files (htab_t dwo_files, struct objfile *objfile)
+{
+ htab_traverse_noresize (dwo_files, free_dwo_file_from_slot, objfile);
}
+
+/* Read in various DIEs. */
/* qsort helper for inherit_abstract_dies. */
@@ -5898,8 +9311,8 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
struct die_info *child_die;
unsigned die_children_count;
/* CU offsets which were referenced by children of the current DIE. */
- unsigned *offsets;
- unsigned *offsets_end, *offsetp;
+ sect_offset *offsets;
+ sect_offset *offsets_end, *offsetp;
/* Parent of DIE - referenced by DW_AT_abstract_origin. */
struct die_info *origin_die;
/* Iterator of the ORIGIN_DIE children. */
@@ -5929,7 +9342,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
&& origin_die->tag == DW_TAG_subprogram))
complaint (&symfile_complaints,
_("DIE 0x%x and its abstract origin 0x%x have different tags"),
- die->offset, origin_die->offset);
+ die->offset.sect_off, origin_die->offset.sect_off);
child_die = die->child;
die_children_count = 0;
@@ -5972,13 +9385,13 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
&& child_origin_die->tag == DW_TAG_subprogram))
complaint (&symfile_complaints,
_("Child DIE 0x%x and its abstract origin 0x%x have "
- "different tags"), child_die->offset,
- child_origin_die->offset);
+ "different tags"), child_die->offset.sect_off,
+ child_origin_die->offset.sect_off);
if (child_origin_die->parent != origin_die)
complaint (&symfile_complaints,
_("Child DIE 0x%x and its abstract origin 0x%x have "
- "different parents"), child_die->offset,
- child_origin_die->offset);
+ "different parents"), child_die->offset.sect_off,
+ child_origin_die->offset.sect_off);
else
*offsets_end++ = child_origin_die->offset;
}
@@ -5987,20 +9400,22 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
qsort (offsets, offsets_end - offsets, sizeof (*offsets),
unsigned_int_compar);
for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++)
- if (offsetp[-1] == *offsetp)
+ if (offsetp[-1].sect_off == offsetp->sect_off)
complaint (&symfile_complaints,
_("Multiple children of DIE 0x%x refer "
"to DIE 0x%x as their abstract origin"),
- die->offset, *offsetp);
+ die->offset.sect_off, offsetp->sect_off);
offsetp = offsets;
origin_child_die = origin_die->child;
while (origin_child_die && origin_child_die->tag)
{
/* Is ORIGIN_CHILD_DIE referenced by any of the DIE children? */
- while (offsetp < offsets_end && *offsetp < origin_child_die->offset)
+ while (offsetp < offsets_end
+ && offsetp->sect_off < origin_child_die->offset.sect_off)
offsetp++;
- if (offsetp >= offsets_end || *offsetp > origin_child_die->offset)
+ if (offsetp >= offsets_end
+ || offsetp->sect_off > origin_child_die->offset.sect_off)
{
/* Found that ORIGIN_CHILD_DIE is really not referenced. */
process_die (origin_child_die, origin_cu);
@@ -6021,7 +9436,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
CORE_ADDR highpc;
struct die_info *child_die;
struct attribute *attr, *call_line, *call_file;
- char *name;
+ const char *name;
CORE_ADDR baseaddr;
struct block *block;
int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
@@ -6051,7 +9466,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
if (name == NULL)
{
complaint (&symfile_complaints,
- _("missing name for subprogram DIE at %d"), die->offset);
+ _("missing name for subprogram DIE at %d"),
+ die->offset.sect_off);
return;
}
@@ -6063,16 +9479,13 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("cannot get low and high bounds "
"for subprogram DIE at %d"),
- die->offset);
+ die->offset.sect_off);
return;
}
lowpc += baseaddr;
highpc += baseaddr;
- /* Record the function range for dwarf_decode_lines. */
- add_to_cu_func_list (name, lowpc, highpc, cu);
-
/* If we have any template arguments, then we must allocate a
different sort of symbol. */
for (child_die = die->child; child_die; child_die = sibling_die (child_die))
@@ -6160,10 +9573,10 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
lowpc, highpc, objfile);
/* For C++, set the block's scope. */
- if (cu->language == language_cplus || cu->language == language_fortran)
- cp_set_block_scope (new->name, block, &objfile->objfile_obstack,
- determine_prefix (die, cu),
- processing_has_namespace_info);
+ if ((cu->language == language_cplus || cu->language == language_fortran)
+ && cu->processing_has_namespace_info)
+ block_set_scope (block, determine_prefix (die, cu),
+ &objfile->objfile_obstack);
/* If we have address ranges, record them. */
dwarf2_record_block_ranges (die, block, baseaddr, cu);
@@ -6189,7 +9602,6 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
when we finish processing a function scope, we may need to go
back to building a containing block's symbol lists. */
local_symbols = new->locals;
- param_symbols = new->params;
using_directives = new->using_directives;
/* If we've finished processing a top-level function, subsequent
@@ -6278,7 +9690,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("missing DW_AT_low_pc for DW_TAG_GNU_call_site "
"DIE 0x%x [in module %s]"),
- die->offset, cu->objfile->name);
+ die->offset.sect_off, objfile->name);
return;
}
pc = DW_ADDR (attr) + baseaddr;
@@ -6294,7 +9706,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("Duplicate PC %s for DW_TAG_GNU_call_site "
"DIE 0x%x [in module %s]"),
- paddress (gdbarch, pc), die->offset, cu->objfile->name);
+ paddress (gdbarch, pc), die->offset.sect_off, objfile->name);
return;
}
@@ -6309,7 +9721,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("Tag %d is not DW_TAG_GNU_call_site_parameter in "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->tag, child_die->offset, cu->objfile->name);
+ child_die->tag, child_die->offset.sect_off, objfile->name);
continue;
}
@@ -6367,7 +9779,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("Cannot find function owning DW_TAG_GNU_call_site "
"DIE 0x%x [in module %s]"),
- die->offset, cu->objfile->name);
+ die->offset.sect_off, objfile->name);
}
}
@@ -6390,7 +9802,6 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
}
else if (is_ref_attr (attr))
{
- struct objfile *objfile = cu->objfile;
struct dwarf2_cu *target_cu = cu;
struct die_info *target_die;
@@ -6398,16 +9809,25 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
gdb_assert (target_cu->objfile == objfile);
if (die_is_declaration (target_die, target_cu))
{
- const char *target_physname;
-
- target_physname = dwarf2_physname (NULL, target_die, target_cu);
+ const char *target_physname = NULL;
+ struct attribute *target_attr;
+
+ /* Prefer the mangled name; otherwise compute the demangled one. */
+ target_attr = dwarf2_attr (target_die, DW_AT_linkage_name, target_cu);
+ if (target_attr == NULL)
+ target_attr = dwarf2_attr (target_die, DW_AT_MIPS_linkage_name,
+ target_cu);
+ if (target_attr != NULL && DW_STRING (target_attr) != NULL)
+ target_physname = DW_STRING (target_attr);
+ else
+ target_physname = dwarf2_physname (NULL, target_die, target_cu);
if (target_physname == NULL)
complaint (&symfile_complaints,
_("DW_AT_GNU_call_site_target target DIE has invalid "
"physname, for referencing DIE 0x%x [in module %s]"),
- die->offset, cu->objfile->name);
+ die->offset.sect_off, objfile->name);
else
- SET_FIELD_PHYSNAME (call_site->target, (char *) target_physname);
+ SET_FIELD_PHYSNAME (call_site->target, target_physname);
}
else
{
@@ -6418,7 +9838,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("DW_AT_GNU_call_site_target target DIE has invalid "
"low pc, for referencing DIE 0x%x [in module %s]"),
- die->offset, cu->objfile->name);
+ die->offset.sect_off, objfile->name);
else
SET_FIELD_PHYSADDR (call_site->target, lowpc + baseaddr);
}
@@ -6427,7 +9847,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("DW_TAG_GNU_call_site DW_AT_GNU_call_site_target is neither "
"block nor reference, for DIE 0x%x [in module %s]"),
- die->offset, cu->objfile->name);
+ die->offset.sect_off, objfile->name);
call_site->per_cu = cu->per_cu;
@@ -6435,8 +9855,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
child_die && child_die->tag;
child_die = sibling_die (child_die))
{
- struct dwarf2_locexpr_baton *dlbaton;
struct call_site_parameter *parameter;
+ struct attribute *loc, *origin;
if (child_die->tag != DW_TAG_GNU_call_site_parameter)
{
@@ -6447,31 +9867,61 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
gdb_assert (call_site->parameter_count < nparams);
parameter = &call_site->parameter[call_site->parameter_count];
- /* DW_AT_location specifies the register number. Value of the data
- assumed for the register is contained in DW_AT_GNU_call_site_value. */
+ /* DW_AT_location specifies the register number or DW_AT_abstract_origin
+ specifies DW_TAG_formal_parameter. Value of the data assumed for the
+ register is contained in DW_AT_GNU_call_site_value. */
- attr = dwarf2_attr (child_die, DW_AT_location, cu);
- if (!attr || !attr_form_is_block (attr))
+ loc = dwarf2_attr (child_die, DW_AT_location, cu);
+ origin = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
+ if (loc == NULL && origin != NULL && is_ref_attr (origin))
+ {
+ sect_offset offset;
+
+ parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET;
+ offset = dwarf2_get_ref_die_offset (origin);
+ if (!offset_in_cu_p (&cu->header, offset))
+ {
+ /* As DW_OP_GNU_parameter_ref uses CU-relative offset this
+ binding can be done only inside one CU. Such referenced DIE
+ therefore cannot be even moved to DW_TAG_partial_unit. */
+ complaint (&symfile_complaints,
+ _("DW_AT_abstract_origin offset is not in CU for "
+ "DW_TAG_GNU_call_site child DIE 0x%x "
+ "[in module %s]"),
+ child_die->offset.sect_off, objfile->name);
+ continue;
+ }
+ parameter->u.param_offset.cu_off = (offset.sect_off
+ - cu->header.offset.sect_off);
+ }
+ else if (loc == NULL || origin != NULL || !attr_form_is_block (loc))
{
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_location for "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset, cu->objfile->name);
+ child_die->offset.sect_off, objfile->name);
continue;
}
- parameter->dwarf_reg = dwarf_block_to_dwarf_reg (DW_BLOCK (attr)->data,
- &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size]);
- if (parameter->dwarf_reg == -1
- && !dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (attr)->data,
- &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size],
- ¶meter->fb_offset))
+ else
{
- complaint (&symfile_complaints,
- _("Only single DW_OP_reg or DW_OP_fbreg is supported "
- "for DW_FORM_block* DW_AT_location for "
- "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset, cu->objfile->name);
- continue;
+ parameter->u.dwarf_reg = dwarf_block_to_dwarf_reg
+ (DW_BLOCK (loc)->data, &DW_BLOCK (loc)->data[DW_BLOCK (loc)->size]);
+ if (parameter->u.dwarf_reg != -1)
+ parameter->kind = CALL_SITE_PARAMETER_DWARF_REG;
+ else if (dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (loc)->data,
+ &DW_BLOCK (loc)->data[DW_BLOCK (loc)->size],
+ ¶meter->u.fb_offset))
+ parameter->kind = CALL_SITE_PARAMETER_FB_OFFSET;
+ else
+ {
+ complaint (&symfile_complaints,
+ _("Only single DW_OP_reg or DW_OP_fbreg is supported "
+ "for DW_FORM_block* DW_AT_location is supported for "
+ "DW_TAG_GNU_call_site child DIE 0x%x "
+ "[in module %s]"),
+ child_die->offset.sect_off, objfile->name);
+ continue;
+ }
}
attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
@@ -6480,7 +9930,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_GNU_call_site_value for "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset, cu->objfile->name);
+ child_die->offset.sect_off, objfile->name);
continue;
}
parameter->value = DW_BLOCK (attr)->data;
@@ -6498,7 +9948,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_GNU_call_site_data_value for "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset, cu->objfile->name);
+ child_die->offset.sect_off, objfile->name);
else
{
parameter->data_value = DW_BLOCK (attr)->data;
@@ -6613,6 +10063,17 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
range_beginning += base;
range_end += base;
+ /* A not-uncommon case of bad debug info.
+ Don't pollute the addrmap with bad data. */
+ if (range_beginning + baseaddr == 0
+ && !dwarf2_per_objfile->has_section_at_zero)
+ {
+ complaint (&symfile_complaints,
+ _(".debug_ranges entry has start address of zero"
+ " [in module %s]"), objfile->name);
+ continue;
+ }
+
if (ranges_pst != NULL)
addrmap_set_empty (objfile->psymtabs_addrmap,
range_beginning + baseaddr,
@@ -6653,23 +10114,31 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
/* Get low and high pc attributes from a die. Return 1 if the attributes
are present and valid, otherwise, return 0. Return -1 if the range is
discontinuous, i.e. derived from DW_AT_ranges information. */
+
static int
dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
CORE_ADDR *highpc, struct dwarf2_cu *cu,
struct partial_symtab *pst)
{
struct attribute *attr;
+ struct attribute *attr_high;
CORE_ADDR low = 0;
CORE_ADDR high = 0;
int ret = 0;
- attr = dwarf2_attr (die, DW_AT_high_pc, cu);
- if (attr)
+ attr_high = dwarf2_attr (die, DW_AT_high_pc, cu);
+ if (attr_high)
{
- high = DW_ADDR (attr);
attr = dwarf2_attr (die, DW_AT_low_pc, cu);
if (attr)
- low = DW_ADDR (attr);
+ {
+ low = DW_ADDR (attr);
+ if (attr_high->form == DW_FORM_addr
+ || attr_high->form == DW_FORM_GNU_addr_index)
+ high = DW_ADDR (attr_high);
+ else
+ high = low + DW_UNSND (attr_high);
+ }
else
/* Found high w/o low attribute. */
return 0;
@@ -6682,9 +10151,18 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
attr = dwarf2_attr (die, DW_AT_ranges, cu);
if (attr != NULL)
{
+ /* DW_AT_ranges_base does not apply to DIEs from the DWO skeleton.
+ We take advantage of the fact that DW_AT_ranges does not appear
+ in DW_TAG_compile_unit of DWO files. */
+ int need_ranges_base = die->tag != DW_TAG_compile_unit;
+ unsigned int ranges_offset = (DW_UNSND (attr)
+ + (need_ranges_base
+ ? cu->ranges_base
+ : 0));
+
/* Value of the DW_AT_ranges attribute is the offset in the
.debug_ranges section. */
- if (!dwarf2_ranges_read (DW_UNSND (attr), &low, &high, cu, pst))
+ if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst))
return 0;
/* Found discontinuous range of addresses. */
ret = -1;
@@ -6810,21 +10288,28 @@ get_scope_pc_bounds (struct die_info *die,
/* Record the address ranges for BLOCK, offset by BASEADDR, as given
in DIE. */
+
static void
dwarf2_record_block_ranges (struct die_info *die, struct block *block,
CORE_ADDR baseaddr, struct dwarf2_cu *cu)
{
+ struct objfile *objfile = cu->objfile;
struct attribute *attr;
+ struct attribute *attr_high;
- attr = dwarf2_attr (die, DW_AT_high_pc, cu);
- if (attr)
+ attr_high = dwarf2_attr (die, DW_AT_high_pc, cu);
+ if (attr_high)
{
- CORE_ADDR high = DW_ADDR (attr);
-
attr = dwarf2_attr (die, DW_AT_low_pc, cu);
if (attr)
{
CORE_ADDR low = DW_ADDR (attr);
+ CORE_ADDR high;
+ if (attr_high->form == DW_FORM_addr
+ || attr_high->form == DW_FORM_GNU_addr_index)
+ high = DW_ADDR (attr_high);
+ else
+ high = low + DW_UNSND (attr_high);
record_block_range (block, baseaddr + low, baseaddr + high - 1);
}
@@ -6833,11 +10318,16 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
attr = dwarf2_attr (die, DW_AT_ranges, cu);
if (attr)
{
- bfd *obfd = cu->objfile->obfd;
+ bfd *obfd = objfile->obfd;
+ /* DW_AT_ranges_base does not apply to DIEs from the DWO skeleton.
+ We take advantage of the fact that DW_AT_ranges does not appear
+ in DW_TAG_compile_unit of DWO files. */
+ int need_ranges_base = die->tag != DW_TAG_compile_unit;
/* The value of the DW_AT_ranges attribute is the offset of the
address range list in the .debug_ranges section. */
- unsigned long offset = DW_UNSND (attr);
+ unsigned long offset = (DW_UNSND (attr)
+ + (need_ranges_base ? cu->ranges_base : 0));
gdb_byte *buffer = dwarf2_per_objfile->ranges.buffer + offset;
/* For some target architectures, but not others, the
@@ -6911,20 +10401,30 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
if (start == end)
continue;
- record_block_range (block,
- baseaddr + base + start,
- baseaddr + base + end - 1);
+ start += base + baseaddr;
+ end += base + baseaddr;
+
+ /* A not-uncommon case of bad debug info.
+ Don't pollute the addrmap with bad data. */
+ if (start == 0 && !dwarf2_per_objfile->has_section_at_zero)
+ {
+ complaint (&symfile_complaints,
+ _(".debug_ranges entry has start address of zero"
+ " [in module %s]"), objfile->name);
+ continue;
+ }
+
+ record_block_range (block, start, end - 1);
}
}
}
}
-/* Check for GCC PR debug/45124 fix which is not present in any G++ version up
- to 4.5.any while it is present already in G++ 4.6.0 - the PR has been fixed
- during 4.6.0 experimental. */
+/* Check whether the producer field indicates either of GCC < 4.6, or the
+ Intel C/C++ compiler, and cache the result in CU. */
-static int
-producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu)
+static void
+check_producer (struct dwarf2_cu *cu)
{
const char *cs;
int major, minor, release;
@@ -6939,30 +10439,46 @@ producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu)
for their space efficiency GDB cannot workaround gcc-4.5.x -gdwarf-4
combination. gcc-4.5.x -gdwarf-4 binaries have DW_AT_accessibility
interpreted incorrectly by GDB now - GCC PR debug/48229. */
-
- return 0;
}
-
- /* Skip any identifier after "GNU " - such as "C++" or "Java". */
-
- if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0)
+ else if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) == 0)
{
- /* For non-GCC compilers expect their behavior is DWARF version
- compliant. */
+ /* Skip any identifier after "GNU " - such as "C++" or "Java". */
- return 0;
+ cs = &cu->producer[strlen ("GNU ")];
+ while (*cs && !isdigit (*cs))
+ cs++;
+ if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3)
+ {
+ /* Not recognized as GCC. */
+ }
+ else
+ {
+ cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
+ cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
+ }
}
- cs = &cu->producer[strlen ("GNU ")];
- while (*cs && !isdigit (*cs))
- cs++;
- if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3)
+ else if (strncmp (cu->producer, "Intel(R) C", strlen ("Intel(R) C")) == 0)
+ cu->producer_is_icc = 1;
+ else
{
- /* Not recognized as GCC. */
-
- return 0;
+ /* For other non-GCC compilers, expect their behavior is DWARF version
+ compliant. */
}
- return major < 4 || (major == 4 && minor < 6);
+ cu->checked_producer = 1;
+}
+
+/* Check for GCC PR debug/45124 fix which is not present in any G++ version up
+ to 4.5.any while it is present already in G++ 4.6.0 - the PR has been fixed
+ during 4.6.0 experimental. */
+
+static int
+producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu)
+{
+ if (!cu->checked_producer)
+ check_producer (cu);
+
+ return cu->producer_is_gxx_lt_4_6;
}
/* Return the default accessibility type if it is not overriden by
@@ -7040,7 +10556,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
struct nextfield *new_field;
struct attribute *attr;
struct field *fp;
- char *fieldname = "";
+ const char *fieldname = "";
/* Allocate a new field list entry and link it in. */
new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield));
@@ -7110,7 +10626,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
anonymous object to the MSB of the field. We don't
have to do anything special since we don't need to
know the size of the anonymous object. */
- FIELD_BITPOS (*fp) += DW_UNSND (attr);
+ SET_FIELD_BITPOS (*fp, FIELD_BITPOS (*fp) + DW_UNSND (attr));
}
else
{
@@ -7139,8 +10655,10 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
bit field. */
anonymous_size = TYPE_LENGTH (fp->type);
}
- FIELD_BITPOS (*fp) += anonymous_size * bits_per_byte
- - bit_offset - FIELD_BITSIZE (*fp);
+ SET_FIELD_BITPOS (*fp,
+ (FIELD_BITPOS (*fp)
+ + anonymous_size * bits_per_byte
+ - bit_offset - FIELD_BITSIZE (*fp)));
}
}
@@ -7349,6 +10867,34 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
}
}
+/* Return true if this member function is a constructor, false
+ otherwise. */
+
+static int
+dwarf2_is_constructor (struct die_info *die, struct dwarf2_cu *cu)
+{
+ const char *fieldname;
+ const char *typename;
+ int len;
+
+ if (die->parent == NULL)
+ return 0;
+
+ if (die->parent->tag != DW_TAG_structure_type
+ && die->parent->tag != DW_TAG_union_type
+ && die->parent->tag != DW_TAG_class_type)
+ return 0;
+
+ fieldname = dwarf2_name (die, cu);
+ typename = dwarf2_name (die->parent, cu);
+ if (fieldname == NULL || typename == NULL)
+ return 0;
+
+ len = strlen (fieldname);
+ return (strncmp (fieldname, typename, len) == 0
+ && (typename[len] == '\0' || typename[len] == '<'));
+}
+
/* Add a member function to the proper fieldlist. */
static void
@@ -7360,7 +10906,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
struct fnfieldlist *flp;
int i;
struct fn_field *fnp;
- char *fieldname;
+ const char *fieldname;
struct nextfnfield *new_fnfield;
struct type *this_type;
enum dwarf_access_attribute accessibility;
@@ -7480,6 +11026,8 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
if (attr && DW_UNSND (attr) != 0)
fnp->is_artificial = 1;
+ fnp->is_constructor = dwarf2_is_constructor (die, cu);
+
/* Get index in virtual function table if it is a virtual member
function. For older versions of GCC, this is an offset in the
appropriate virtual table, as specified by DW_AT_containing_type.
@@ -7540,7 +11088,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
complaint (&symfile_complaints,
_("Member function \"%s\" (offset %d) is virtual "
"but the vtable offset is not specified"),
- fieldname, die->offset);
+ fieldname, die->offset.sect_off);
ALLOCATE_CPLUS_STRUCT_TYPE (type);
TYPE_CPLUS_DYNAMIC (type) = 1;
}
@@ -7554,7 +11102,6 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
struct dwarf2_cu *cu)
{
struct fnfieldlist *flp;
- int total_length = 0;
int i;
if (cu->language == language_ada)
@@ -7576,12 +11123,9 @@ dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
TYPE_ALLOC (type, sizeof (struct fn_field) * flp->length);
for (k = flp->length; (k--, nfp); nfp = nfp->next)
fn_flp->fn_fields[k] = nfp->fnfield;
-
- total_length += flp->length;
}
TYPE_NFN_FIELDS (type) = fip->nfnfields;
- TYPE_NFN_FIELDS_TOTAL (type) = total_length;
}
/* Returns non-zero if NAME is the name of a vtable member in CU's
@@ -7647,6 +11191,18 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
smash_to_methodptr_type (type, new_type);
}
+/* Return non-zero if the CU's PRODUCER string matches the Intel C/C++ compiler
+ (icc). */
+
+static int
+producer_is_icc (struct dwarf2_cu *cu)
+{
+ if (!cu->checked_producer)
+ check_producer (cu);
+
+ return cu->producer_is_icc;
+}
+
/* Called when we find the DIE that starts a structure or union scope
(definition) to create a type for the structure or union. Fill in
the type's name and general properties; the members will not be
@@ -7670,12 +11226,12 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
struct objfile *objfile = cu->objfile;
struct type *type;
struct attribute *attr;
- char *name;
+ const char *name;
/* If the definition of this type lives in .debug_types, read that type.
Don't follow DW_AT_specification though, that will take us back up
the chain and we want to go down. */
- attr = dwarf2_attr_no_follow (die, DW_AT_signature, cu);
+ attr = dwarf2_attr_no_follow (die, DW_AT_signature);
if (attr)
{
struct dwarf2_cu *type_cu = cu;
@@ -7701,7 +11257,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
if (cu->language == language_cplus
|| cu->language == language_java)
{
- char *full_name = (char *) dwarf2_full_name (name, die, cu);
+ const char *full_name = dwarf2_full_name (name, die, cu);
/* dwarf2_full_name might have already finished building the DIE's
type. If so, there is no need to continue. */
@@ -7717,7 +11273,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
{
/* The name is already allocated along with this objfile, so
we don't need to duplicate it for the type. */
- TYPE_TAG_NAME (type) = (char *) name;
+ TYPE_TAG_NAME (type) = name;
if (die->tag == DW_TAG_class_type)
TYPE_NAME (type) = TYPE_TAG_NAME (type);
}
@@ -7749,7 +11305,14 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
TYPE_LENGTH (type) = 0;
}
- TYPE_STUB_SUPPORTED (type) = 1;
+ if (producer_is_icc (cu))
+ {
+ /* ICC does not output the required DW_AT_declaration
+ on incomplete types, but gives them a size of zero. */
+ }
+ else
+ TYPE_STUB_SUPPORTED (type) = 1;
+
if (die_is_declaration (die, cu))
TYPE_STUB (type) = 1;
else if (attr == NULL && die->child == NULL
@@ -7873,7 +11436,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
i >= TYPE_N_BASECLASSES (t);
--i)
{
- char *fieldname = TYPE_FIELD_NAME (t, i);
+ const char *fieldname = TYPE_FIELD_NAME (t, i);
if (is_vtable_name (fieldname, cu))
{
@@ -7948,7 +11511,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
TYPE_CPLUS_REALLY_JAVA (type) = cu->language == language_java;
}
- quirk_gcc_member_function_pointer (type, cu->objfile);
+ quirk_gcc_member_function_pointer (type, objfile);
/* NOTE: carlton/2004-03-16: GCC 3.4 (or at least one of its
snapshots) has been known to create a die giving a declaration
@@ -7995,7 +11558,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
/* If the definition of this type lives in .debug_types, read that type.
Don't follow DW_AT_specification though, that will take us back up
the chain and we want to go down. */
- attr = dwarf2_attr_no_follow (die, DW_AT_signature, cu);
+ attr = dwarf2_attr_no_follow (die, DW_AT_signature);
if (attr)
{
struct dwarf2_cu *type_cu = cu;
@@ -8013,7 +11576,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
TYPE_CODE (type) = TYPE_CODE_ENUM;
name = dwarf2_full_name (NULL, die, cu);
if (name != NULL)
- TYPE_TAG_NAME (type) = (char *) name;
+ TYPE_TAG_NAME (type) = name;
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
@@ -8058,7 +11621,9 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
struct field *fields = NULL;
int num_fields = 0;
int unsigned_enum = 1;
- char *name;
+ const char *name;
+ int flag_enum = 1;
+ ULONGEST mask = 0;
child_die = die->child;
while (child_die && child_die->tag)
@@ -8074,7 +11639,14 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
{
sym = new_symbol (child_die, this_type, cu);
if (SYMBOL_VALUE (sym) < 0)
- unsigned_enum = 0;
+ {
+ unsigned_enum = 0;
+ flag_enum = 0;
+ }
+ else if ((mask & SYMBOL_VALUE (sym)) != 0)
+ flag_enum = 0;
+ else
+ mask |= SYMBOL_VALUE (sym);
if ((num_fields % DW_FIELD_ALLOC_CHUNK) == 0)
{
@@ -8086,7 +11658,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
FIELD_NAME (fields[num_fields]) = SYMBOL_LINKAGE_NAME (sym);
FIELD_TYPE (fields[num_fields]) = NULL;
- SET_FIELD_BITPOS (fields[num_fields], SYMBOL_VALUE (sym));
+ SET_FIELD_ENUMVAL (fields[num_fields], SYMBOL_VALUE (sym));
FIELD_BITSIZE (fields[num_fields]) = 0;
num_fields++;
@@ -8107,6 +11679,8 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
}
if (unsigned_enum)
TYPE_UNSIGNED (this_type) = 1;
+ if (flag_enum)
+ TYPE_FLAG_ENUM (this_type) = 1;
}
/* If we are reading an enum from a .debug_types unit, and the enum
@@ -8117,16 +11691,17 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
actually available. Note that we do not want to do this for all
enums which are just declarations, because C++0x allows forward
enum declarations. */
- if (cu->per_cu->debug_types_section
+ if (cu->per_cu->is_debug_types
&& die_is_declaration (die, cu))
{
- struct signatured_type *type_sig;
+ struct signatured_type *sig_type;
- type_sig
+ sig_type
= lookup_signatured_type_at_offset (dwarf2_per_objfile->objfile,
- cu->per_cu->debug_types_section,
+ cu->per_cu->info_or_types_section,
cu->per_cu->offset);
- if (type_sig->type_offset != die->offset)
+ gdb_assert (sig_type->type_offset_in_section.sect_off != 0);
+ if (sig_type->type_offset_in_section.sect_off != die->offset.sect_off)
return;
}
@@ -8148,7 +11723,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
struct attribute *attr;
int ndim = 0;
struct cleanup *back_to;
- char *name;
+ const char *name;
element_type = die_type (die, cu);
@@ -8307,15 +11882,89 @@ read_set_type (struct die_info *die, struct dwarf2_cu *cu)
return set_die_type (die, set_type, cu);
}
-/* First cut: install each common block member as a global variable. */
+/* A helper for read_common_block that creates a locexpr baton.
+ SYM is the symbol which we are marking as computed.
+ COMMON_DIE is the DIE for the common block.
+ COMMON_LOC is the location expression attribute for the common
+ block itself.
+ MEMBER_LOC is the location expression attribute for the particular
+ member of the common block that we are processing.
+ CU is the CU from which the above come. */
+
+static void
+mark_common_block_symbol_computed (struct symbol *sym,
+ struct die_info *common_die,
+ struct attribute *common_loc,
+ struct attribute *member_loc,
+ struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_locexpr_baton *baton;
+ gdb_byte *ptr;
+ unsigned int cu_off;
+ enum bfd_endian byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+ LONGEST offset = 0;
+
+ gdb_assert (common_loc && member_loc);
+ gdb_assert (attr_form_is_block (common_loc));
+ gdb_assert (attr_form_is_block (member_loc)
+ || attr_form_is_constant (member_loc));
+
+ baton = obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct dwarf2_locexpr_baton));
+ baton->per_cu = cu->per_cu;
+ gdb_assert (baton->per_cu);
+
+ baton->size = 5 /* DW_OP_call4 */ + 1 /* DW_OP_plus */;
+
+ if (attr_form_is_constant (member_loc))
+ {
+ offset = dwarf2_get_attr_constant_value (member_loc, 0);
+ baton->size += 1 /* DW_OP_addr */ + cu->header.addr_size;
+ }
+ else
+ baton->size += DW_BLOCK (member_loc)->size;
+
+ ptr = obstack_alloc (&objfile->objfile_obstack, baton->size);
+ baton->data = ptr;
+
+ *ptr++ = DW_OP_call4;
+ cu_off = common_die->offset.sect_off - cu->per_cu->offset.sect_off;
+ store_unsigned_integer (ptr, 4, byte_order, cu_off);
+ ptr += 4;
+
+ if (attr_form_is_constant (member_loc))
+ {
+ *ptr++ = DW_OP_addr;
+ store_unsigned_integer (ptr, cu->header.addr_size, byte_order, offset);
+ ptr += cu->header.addr_size;
+ }
+ else
+ {
+ /* We have to copy the data here, because DW_OP_call4 will only
+ use a DW_AT_location attribute. */
+ memcpy (ptr, DW_BLOCK (member_loc)->data, DW_BLOCK (member_loc)->size);
+ ptr += DW_BLOCK (member_loc)->size;
+ }
+
+ *ptr++ = DW_OP_plus;
+ gdb_assert (ptr - baton->data == baton->size);
+
+ SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
+ SYMBOL_LOCATION_BATON (sym) = baton;
+ SYMBOL_CLASS (sym) = LOC_COMPUTED;
+}
+
+/* Create appropriate locally-scoped variables for all the
+ DW_TAG_common_block entries. Also create a struct common_block
+ listing all such variables for `info common'. COMMON_BLOCK_DOMAIN
+ is used to sepate the common blocks name namespace from regular
+ variable names. */
static void
read_common_block (struct die_info *die, struct dwarf2_cu *cu)
{
- struct die_info *child_die;
struct attribute *attr;
- struct symbol *sym;
- CORE_ADDR base = (CORE_ADDR) 0;
attr = dwarf2_attr (die, DW_AT_location, cu);
if (attr)
@@ -8323,34 +11972,84 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
/* Support the .debug_loc offsets. */
if (attr_form_is_block (attr))
{
- base = decode_locdesc (DW_BLOCK (attr), cu);
+ /* Ok. */
}
else if (attr_form_is_section_offset (attr))
{
dwarf2_complex_location_expr_complaint ();
+ attr = NULL;
}
else
{
dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
"common block member");
+ attr = NULL;
}
}
+
if (die->child != NULL)
{
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- LONGEST offset;
+ struct objfile *objfile = cu->objfile;
+ struct die_info *child_die;
+ size_t n_entries = 0, size;
+ struct common_block *common_block;
+ struct symbol *sym;
+
+ for (child_die = die->child;
+ child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ ++n_entries;
+ size = (sizeof (struct common_block)
+ + (n_entries - 1) * sizeof (struct symbol *));
+ common_block = obstack_alloc (&objfile->objfile_obstack, size);
+ memset (common_block->contents, 0, n_entries * sizeof (struct symbol *));
+ common_block->n_entries = 0;
+
+ for (child_die = die->child;
+ child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ {
+ /* Create the symbol in the DW_TAG_common_block block in the current
+ symbol scope. */
sym = new_symbol (child_die, NULL, cu);
- if (sym != NULL
- && handle_data_member_location (child_die, cu, &offset))
+ if (sym != NULL)
{
- SYMBOL_VALUE_ADDRESS (sym) = base + offset;
- add_symbol_to_list (sym, &global_symbols);
+ struct attribute *member_loc;
+
+ common_block->contents[common_block->n_entries++] = sym;
+
+ member_loc = dwarf2_attr (child_die, DW_AT_data_member_location,
+ cu);
+ if (member_loc)
+ {
+ /* GDB has handled this for a long time, but it is
+ not specified by DWARF. It seems to have been
+ emitted by gfortran at least as recently as:
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23057. */
+ complaint (&symfile_complaints,
+ _("Variable in common block has "
+ "DW_AT_data_member_location "
+ "- DIE at 0x%x [in module %s]"),
+ child_die->offset.sect_off, cu->objfile->name);
+
+ if (attr_form_is_section_offset (member_loc))
+ dwarf2_complex_location_expr_complaint ();
+ else if (attr_form_is_constant (member_loc)
+ || attr_form_is_block (member_loc))
+ {
+ if (attr)
+ mark_common_block_symbol_computed (sym, die, attr,
+ member_loc, cu);
+ }
+ else
+ dwarf2_complex_location_expr_complaint ();
+ }
}
- child_die = sibling_die (child_die);
}
+
+ sym = new_symbol (die, objfile_type (objfile)->builtin_void, cu);
+ SYMBOL_VALUE_COMMON_BLOCK (sym) = common_block;
}
}
@@ -8390,7 +12089,7 @@ read_namespace_type (struct die_info *die, struct dwarf2_cu *cu)
/* Create the type. */
type = init_type (TYPE_CODE_NAMESPACE, 0, 0, NULL,
objfile);
- TYPE_NAME (type) = (char *) name;
+ TYPE_NAME (type) = name;
TYPE_TAG_NAME (type) = TYPE_NAME (type);
return set_die_type (die, type, cu);
@@ -8421,7 +12120,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
const char *previous_prefix = determine_prefix (die, cu);
cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
- NULL, NULL, &objfile->objfile_obstack);
+ NULL, NULL, 0, &objfile->objfile_obstack);
}
}
@@ -8445,14 +12144,14 @@ static struct type *
read_module_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- char *module_name;
+ const char *module_name;
struct type *type;
module_name = dwarf2_name (die, cu);
if (!module_name)
complaint (&symfile_complaints,
_("DW_TAG_module has no name, offset 0x%x"),
- die->offset);
+ die->offset.sect_off);
type = init_type (TYPE_CODE_MODULE, 0, 0, module_name, objfile);
/* determine_prefix uses TYPE_TAG_NAME. */
@@ -8590,6 +12289,15 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_METHOD)
type = lookup_methodptr_type (to_type);
+ else if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_FUNC)
+ {
+ struct type *new_type = alloc_type (cu->objfile);
+
+ smash_to_method_type (new_type, domain, TYPE_TARGET_TYPE (to_type),
+ TYPE_FIELDS (to_type), TYPE_NFIELDS (to_type),
+ TYPE_VARARGS (to_type));
+ type = lookup_methodptr_type (new_type);
+ }
else
type = lookup_memberptr_type (to_type, domain);
@@ -8681,6 +12389,24 @@ read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
return set_die_type (die, cv_type, cu);
}
+/* Handle DW_TAG_restrict_type. */
+
+static struct type *
+read_tag_restrict_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct type *base_type, *cv_type;
+
+ base_type = die_type (die, cu);
+
+ /* The die_type call above may have already set the type for this DIE. */
+ cv_type = get_die_type (die, cu);
+ if (cv_type)
+ return cv_type;
+
+ cv_type = make_restrict_type (base_type);
+ return set_die_type (die, cv_type, cu);
+}
+
/* Extract all information from a DW_TAG_string_type DIE and add to
the user defined type vector. It isn't really a user defined type,
but it behaves like one, with other DIE's using an AT_user_def_type
@@ -8735,6 +12461,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
static struct type *
read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
{
+ struct objfile *objfile = cu->objfile;
struct type *type; /* Type that this function returns. */
struct type *ftype; /* Function that returns above type. */
struct attribute *attr;
@@ -8780,7 +12507,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
if (die->child != NULL)
{
- struct type *void_type = objfile_type (cu->objfile)->builtin_void;
+ struct type *void_type = objfile_type (objfile)->builtin_void;
struct die_info *child_die;
int nparams, iparams;
@@ -8890,14 +12617,26 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
const char *name = NULL;
- struct type *this_type;
+ struct type *this_type, *target_type;
name = dwarf2_full_name (NULL, die, cu);
this_type = init_type (TYPE_CODE_TYPEDEF, 0,
TYPE_FLAG_TARGET_STUB, NULL, objfile);
- TYPE_NAME (this_type) = (char *) name;
+ TYPE_NAME (this_type) = name;
set_die_type (die, this_type, cu);
- TYPE_TARGET_TYPE (this_type) = die_type (die, cu);
+ target_type = die_type (die, cu);
+ if (target_type != this_type)
+ TYPE_TARGET_TYPE (this_type) = target_type;
+ else
+ {
+ /* Self-referential typedefs are, it seems, not allowed by the DWARF
+ spec and cause infinite loops in GDB. */
+ complaint (&symfile_complaints,
+ _("Self-referential DW_TAG_typedef "
+ "- DIE at 0x%x [in module %s]"),
+ die->offset.sect_off, objfile->name);
+ TYPE_TARGET_TYPE (this_type) = NULL;
+ }
return this_type;
}
@@ -8911,7 +12650,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
struct type *type;
struct attribute *attr;
int encoding = 0, size = 0;
- char *name;
+ const char *name;
enum type_code code = TYPE_CODE_INT;
int type_flags = 0;
struct type *target_type = NULL;
@@ -9003,27 +12742,55 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
static struct type *
read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct type *base_type;
+ struct type *base_type, *orig_base_type;
struct type *range_type;
struct attribute *attr;
- LONGEST low = 0;
- LONGEST high = -1;
- char *name;
+ LONGEST low, high;
+ int low_default_is_valid;
+ const char *name;
LONGEST negative_mask;
- base_type = die_type (die, cu);
- /* Preserve BASE_TYPE's original type, just set its LENGTH. */
- check_typedef (base_type);
+ orig_base_type = die_type (die, cu);
+ /* If ORIG_BASE_TYPE is a typedef, it will not be TYPE_UNSIGNED,
+ whereas the real type might be. So, we use ORIG_BASE_TYPE when
+ creating the range type, but we use the result of check_typedef
+ when examining properties of the type. */
+ base_type = check_typedef (orig_base_type);
/* The die_type call above may have already set the type for this DIE. */
range_type = get_die_type (die, cu);
if (range_type)
return range_type;
- if (cu->language == language_fortran)
+ /* Set LOW_DEFAULT_IS_VALID if current language and DWARF version allow
+ omitting DW_AT_lower_bound. */
+ switch (cu->language)
{
- /* FORTRAN implies a lower bound of 1, if not given. */
+ case language_c:
+ case language_cplus:
+ low = 0;
+ low_default_is_valid = 1;
+ break;
+ case language_fortran:
+ low = 1;
+ low_default_is_valid = 1;
+ break;
+ case language_d:
+ case language_java:
+ case language_objc:
+ low = 0;
+ low_default_is_valid = (cu->header.version >= 4);
+ break;
+ case language_ada:
+ case language_m2:
+ case language_pascal:
low = 1;
+ low_default_is_valid = (cu->header.version >= 4);
+ break;
+ default:
+ low = 0;
+ low_default_is_valid = 0;
+ break;
}
/* FIXME: For variable sized arrays either of these could be
@@ -9031,7 +12798,11 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
but we don't know how to handle it. */
attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
if (attr)
- low = dwarf2_get_attr_constant_value (attr, 0);
+ low = dwarf2_get_attr_constant_value (attr, low);
+ else if (!low_default_is_valid)
+ complaint (&symfile_complaints, _("Missing DW_AT_lower_bound "
+ "- DIE at 0x%x [in module %s]"),
+ die->offset.sect_off, cu->objfile->name);
attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
if (attr)
@@ -9114,131 +12885,45 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
if (!TYPE_UNSIGNED (base_type) && (high & negative_mask))
high |= negative_mask;
- range_type = create_range_type (NULL, base_type, low, high);
+ range_type = create_range_type (NULL, orig_base_type, low, high);
/* Mark arrays with dynamic length at least as an array of unspecified
length. GDB could check the boundary but before it gets implemented at
least allow accessing the array elements. */
if (attr && attr_form_is_block (attr))
- TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
-
- /* Ada expects an empty array on no boundary attributes. */
- if (attr == NULL && cu->language != language_ada)
- TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
-
- name = dwarf2_name (die, cu);
- if (name)
- TYPE_NAME (range_type) = name;
-
- attr = dwarf2_attr (die, DW_AT_byte_size, cu);
- if (attr)
- TYPE_LENGTH (range_type) = DW_UNSND (attr);
-
- set_die_type (die, range_type, cu);
-
- /* set_die_type should be already done. */
- set_descriptive_type (range_type, die, cu);
-
- return range_type;
-}
-
-static struct type *
-read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
-{
- struct type *type;
-
- /* For now, we only support the C meaning of an unspecified type: void. */
-
- type = init_type (TYPE_CODE_VOID, 0, 0, NULL, cu->objfile);
- TYPE_NAME (type) = dwarf2_name (die, cu);
-
- return set_die_type (die, type, cu);
-}
-
-/* Trivial hash function for die_info: the hash value of a DIE
- is its offset in .debug_info for this objfile. */
-
-static hashval_t
-die_hash (const void *item)
-{
- const struct die_info *die = item;
-
- return die->offset;
-}
-
-/* Trivial comparison function for die_info structures: two DIEs
- are equal if they have the same offset. */
-
-static int
-die_eq (const void *item_lhs, const void *item_rhs)
-{
- const struct die_info *die_lhs = item_lhs;
- const struct die_info *die_rhs = item_rhs;
-
- return die_lhs->offset == die_rhs->offset;
-}
-
-/* Read a whole compilation unit into a linked list of dies. */
-
-static struct die_info *
-read_comp_unit (gdb_byte *info_ptr, struct dwarf2_cu *cu)
-{
- struct die_reader_specs reader_specs;
- int read_abbrevs = 0;
- struct cleanup *back_to = NULL;
- struct die_info *die;
+ TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
- if (cu->dwarf2_abbrevs == NULL)
- {
- dwarf2_read_abbrevs (cu->objfile->obfd, cu);
- back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
- read_abbrevs = 1;
- }
+ /* Ada expects an empty array on no boundary attributes. */
+ if (attr == NULL && cu->language != language_ada)
+ TYPE_HIGH_BOUND_UNDEFINED (range_type) = 1;
- gdb_assert (cu->die_hash == NULL);
- cu->die_hash
- = htab_create_alloc_ex (cu->header.length / 12,
- die_hash,
- die_eq,
- NULL,
- &cu->comp_unit_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
+ name = dwarf2_name (die, cu);
+ if (name)
+ TYPE_NAME (range_type) = name;
- init_cu_die_reader (&reader_specs, cu);
+ attr = dwarf2_attr (die, DW_AT_byte_size, cu);
+ if (attr)
+ TYPE_LENGTH (range_type) = DW_UNSND (attr);
- die = read_die_and_children (&reader_specs, info_ptr, &info_ptr, NULL);
+ set_die_type (die, range_type, cu);
- if (read_abbrevs)
- do_cleanups (back_to);
+ /* set_die_type should be already done. */
+ set_descriptive_type (range_type, die, cu);
- return die;
+ return range_type;
}
-/* Main entry point for reading a DIE and all children.
- Read the DIE and dump it if requested. */
-
-static struct die_info *
-read_die_and_children (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- gdb_byte **new_info_ptr,
- struct die_info *parent)
+static struct type *
+read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct die_info *result = read_die_and_children_1 (reader, info_ptr,
- new_info_ptr, parent);
+ struct type *type;
- if (dwarf2_die_debug)
- {
- fprintf_unfiltered (gdb_stdlog,
- "\nRead die from %s of %s:\n",
- (reader->cu->per_cu->debug_types_section
- ? ".debug_types"
- : ".debug_info"),
- reader->abfd->filename);
- dump_die (result, dwarf2_die_debug);
- }
+ /* For now, we only support the C meaning of an unspecified type: void. */
- return result;
+ type = init_type (TYPE_CODE_VOID, 0, 0, NULL, cu->objfile);
+ TYPE_NAME (type) = dwarf2_name (die, cu);
+
+ return set_die_type (die, type, cu);
}
/* Read a single die and all its descendents. Set the die's sibling
@@ -9248,10 +12933,10 @@ read_die_and_children (const struct die_reader_specs *reader,
is the parent of the die in question. */
static struct die_info *
-read_die_and_children_1 (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- gdb_byte **new_info_ptr,
- struct die_info *parent)
+read_die_and_children (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ gdb_byte **new_info_ptr,
+ struct die_info *parent)
{
struct die_info *die;
gdb_byte *cur_ptr;
@@ -9297,7 +12982,7 @@ read_die_and_siblings (const struct die_reader_specs *reader,
while (1)
{
struct die_info *die
- = read_die_and_children_1 (reader, cur_ptr, &cur_ptr, parent);
+ = read_die_and_children (reader, cur_ptr, &cur_ptr, parent);
if (die == NULL)
{
@@ -9314,23 +12999,27 @@ read_die_and_siblings (const struct die_reader_specs *reader,
}
}
-/* Read the die from the .debug_info section buffer. Set DIEP to
- point to a newly allocated die with its information, except for its
- child, sibling, and parent fields. Set HAS_CHILDREN to tell
- whether the die has children or not. */
+/* Read a die and all its attributes, leave space for NUM_EXTRA_ATTRS
+ attributes.
+ The caller is responsible for filling in the extra attributes
+ and updating (*DIEP)->num_attrs.
+ Set DIEP to point to a newly allocated die with its information,
+ except for its child, sibling, and parent fields.
+ Set HAS_CHILDREN to tell whether the die has children or not. */
static gdb_byte *
-read_full_die (const struct die_reader_specs *reader,
- struct die_info **diep, gdb_byte *info_ptr,
- int *has_children)
+read_full_die_1 (const struct die_reader_specs *reader,
+ struct die_info **diep, gdb_byte *info_ptr,
+ int *has_children, int num_extra_attrs)
{
- unsigned int abbrev_number, bytes_read, i, offset;
+ unsigned int abbrev_number, bytes_read, i;
+ sect_offset offset;
struct abbrev_info *abbrev;
struct die_info *die;
struct dwarf2_cu *cu = reader->cu;
bfd *abfd = reader->abfd;
- offset = info_ptr - reader->buffer;
+ offset.sect_off = info_ptr - reader->buffer;
abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
if (!abbrev_number)
@@ -9340,56 +13029,127 @@ read_full_die (const struct die_reader_specs *reader,
return info_ptr;
}
- abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
+ abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number);
if (!abbrev)
error (_("Dwarf Error: could not find abbrev number %d [in module %s]"),
abbrev_number,
bfd_get_filename (abfd));
- die = dwarf_alloc_die (cu, abbrev->num_attrs);
+ die = dwarf_alloc_die (cu, abbrev->num_attrs + num_extra_attrs);
die->offset = offset;
die->tag = abbrev->tag;
die->abbrev = abbrev_number;
+ /* Make the result usable.
+ The caller needs to update num_attrs after adding the extra
+ attributes. */
die->num_attrs = abbrev->num_attrs;
for (i = 0; i < abbrev->num_attrs; ++i)
- info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
- abfd, info_ptr, cu);
+ info_ptr = read_attribute (reader, &die->attrs[i], &abbrev->attrs[i],
+ info_ptr);
*diep = die;
*has_children = abbrev->has_children;
return info_ptr;
}
-/* In DWARF version 2, the description of the debugging information is
+/* Read a die and all its attributes.
+ Set DIEP to point to a newly allocated die with its information,
+ except for its child, sibling, and parent fields.
+ Set HAS_CHILDREN to tell whether the die has children or not. */
+
+static gdb_byte *
+read_full_die (const struct die_reader_specs *reader,
+ struct die_info **diep, gdb_byte *info_ptr,
+ int *has_children)
+{
+ return read_full_die_1 (reader, diep, info_ptr, has_children, 0);
+}
+
+/* Abbreviation tables.
+
+ In DWARF version 2, the description of the debugging information is
stored in a separate .debug_abbrev section. Before we read any
dies from a section we read in all abbreviations and install them
- in a hash table. This function also sets flags in CU describing
- the data found in the abbrev table. */
+ in a hash table. */
+
+/* Allocate space for a struct abbrev_info object in ABBREV_TABLE. */
+
+static struct abbrev_info *
+abbrev_table_alloc_abbrev (struct abbrev_table *abbrev_table)
+{
+ struct abbrev_info *abbrev;
+
+ abbrev = (struct abbrev_info *)
+ obstack_alloc (&abbrev_table->abbrev_obstack, sizeof (struct abbrev_info));
+ memset (abbrev, 0, sizeof (struct abbrev_info));
+ return abbrev;
+}
+
+/* Add an abbreviation to the table. */
static void
-dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
+abbrev_table_add_abbrev (struct abbrev_table *abbrev_table,
+ unsigned int abbrev_number,
+ struct abbrev_info *abbrev)
{
- struct comp_unit_head *cu_header = &cu->header;
+ unsigned int hash_number;
+
+ hash_number = abbrev_number % ABBREV_HASH_SIZE;
+ abbrev->next = abbrev_table->abbrevs[hash_number];
+ abbrev_table->abbrevs[hash_number] = abbrev;
+}
+
+/* Look up an abbrev in the table.
+ Returns NULL if the abbrev is not found. */
+
+static struct abbrev_info *
+abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table,
+ unsigned int abbrev_number)
+{
+ unsigned int hash_number;
+ struct abbrev_info *abbrev;
+
+ hash_number = abbrev_number % ABBREV_HASH_SIZE;
+ abbrev = abbrev_table->abbrevs[hash_number];
+
+ while (abbrev)
+ {
+ if (abbrev->number == abbrev_number)
+ return abbrev;
+ abbrev = abbrev->next;
+ }
+ return NULL;
+}
+
+/* Read in an abbrev table. */
+
+static struct abbrev_table *
+abbrev_table_read_table (struct dwarf2_section_info *section,
+ sect_offset offset)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *abfd = section->asection->owner;
+ struct abbrev_table *abbrev_table;
gdb_byte *abbrev_ptr;
struct abbrev_info *cur_abbrev;
unsigned int abbrev_number, bytes_read, abbrev_name;
- unsigned int abbrev_form, hash_number;
+ unsigned int abbrev_form;
struct attr_abbrev *cur_attrs;
unsigned int allocated_attrs;
- /* Initialize dwarf2 abbrevs. */
- obstack_init (&cu->abbrev_obstack);
- cu->dwarf2_abbrevs = obstack_alloc (&cu->abbrev_obstack,
- (ABBREV_HASH_SIZE
- * sizeof (struct abbrev_info *)));
- memset (cu->dwarf2_abbrevs, 0,
- ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
-
- dwarf2_read_section (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->abbrev);
- abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset;
+ abbrev_table = XMALLOC (struct abbrev_table);
+ abbrev_table->offset = offset;
+ obstack_init (&abbrev_table->abbrev_obstack);
+ abbrev_table->abbrevs = obstack_alloc (&abbrev_table->abbrev_obstack,
+ (ABBREV_HASH_SIZE
+ * sizeof (struct abbrev_info *)));
+ memset (abbrev_table->abbrevs, 0,
+ ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
+
+ dwarf2_read_section (objfile, section);
+ abbrev_ptr = section->buffer + offset.sect_off;
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
@@ -9399,7 +13159,7 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
/* Loop until we reach an abbrev number of 0. */
while (abbrev_number)
{
- cur_abbrev = dwarf_alloc_abbrev (cu);
+ cur_abbrev = abbrev_table_alloc_abbrev (abbrev_table);
/* read in abbrev header */
cur_abbrev->number = abbrev_number;
@@ -9408,9 +13168,6 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr);
abbrev_ptr += 1;
- if (cur_abbrev->tag == DW_TAG_namespace)
- cu->has_namespace_info = 1;
-
/* now read in declarations */
abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
@@ -9426,16 +13183,6 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
* sizeof (struct attr_abbrev)));
}
- /* Record whether this compilation unit might have
- inter-compilation-unit references. If we don't know what form
- this attribute will have, then it might potentially be a
- DW_FORM_ref_addr, so we conservatively expect inter-CU
- references. */
-
- if (abbrev_form == DW_FORM_ref_addr
- || abbrev_form == DW_FORM_indirect)
- cu->has_form_ref_addr = 1;
-
cur_attrs[cur_abbrev->num_attrs].name = abbrev_name;
cur_attrs[cur_abbrev->num_attrs++].form = abbrev_form;
abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
@@ -9444,15 +13191,13 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
abbrev_ptr += bytes_read;
}
- cur_abbrev->attrs = obstack_alloc (&cu->abbrev_obstack,
+ cur_abbrev->attrs = obstack_alloc (&abbrev_table->abbrev_obstack,
(cur_abbrev->num_attrs
* sizeof (struct attr_abbrev)));
memcpy (cur_abbrev->attrs, cur_attrs,
cur_abbrev->num_attrs * sizeof (struct attr_abbrev));
- hash_number = abbrev_number % ABBREV_HASH_SIZE;
- cur_abbrev->next = cu->dwarf2_abbrevs[hash_number];
- cu->dwarf2_abbrevs[hash_number] = cur_abbrev;
+ abbrev_table_add_abbrev (abbrev_table, abbrev_number, cur_abbrev);
/* Get next abbreviation.
Under Irix6 the abbreviations for a compilation unit are not
@@ -9461,50 +13206,65 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
already read (which means we are about to read the abbreviations
for the next compile unit) or if the end of the abbreviation
table is reached. */
- if ((unsigned int) (abbrev_ptr - dwarf2_per_objfile->abbrev.buffer)
- >= dwarf2_per_objfile->abbrev.size)
+ if ((unsigned int) (abbrev_ptr - section->buffer) >= section->size)
break;
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
- if (dwarf2_lookup_abbrev (abbrev_number, cu) != NULL)
+ if (abbrev_table_lookup_abbrev (abbrev_table, abbrev_number) != NULL)
break;
}
xfree (cur_attrs);
+ return abbrev_table;
}
-/* Release the memory used by the abbrev table for a compilation unit. */
+/* Free the resources held by ABBREV_TABLE. */
static void
-dwarf2_free_abbrev_table (void *ptr_to_cu)
+abbrev_table_free (struct abbrev_table *abbrev_table)
{
- struct dwarf2_cu *cu = ptr_to_cu;
-
- obstack_free (&cu->abbrev_obstack, NULL);
- cu->dwarf2_abbrevs = NULL;
+ obstack_free (&abbrev_table->abbrev_obstack, NULL);
+ xfree (abbrev_table);
}
-/* Lookup an abbrev_info structure in the abbrev hash table. */
+/* Same as abbrev_table_free but as a cleanup.
+ We pass in a pointer to the pointer to the table so that we can
+ set the pointer to NULL when we're done. It also simplifies
+ build_type_unit_groups. */
-static struct abbrev_info *
-dwarf2_lookup_abbrev (unsigned int number, struct dwarf2_cu *cu)
+static void
+abbrev_table_free_cleanup (void *table_ptr)
{
- unsigned int hash_number;
- struct abbrev_info *abbrev;
+ struct abbrev_table **abbrev_table_ptr = table_ptr;
+
+ if (*abbrev_table_ptr != NULL)
+ abbrev_table_free (*abbrev_table_ptr);
+ *abbrev_table_ptr = NULL;
+}
- hash_number = number % ABBREV_HASH_SIZE;
- abbrev = cu->dwarf2_abbrevs[hash_number];
+/* Read the abbrev table for CU from ABBREV_SECTION. */
- while (abbrev)
- {
- if (abbrev->number == number)
- return abbrev;
- else
- abbrev = abbrev->next;
- }
- return NULL;
+static void
+dwarf2_read_abbrevs (struct dwarf2_cu *cu,
+ struct dwarf2_section_info *abbrev_section)
+{
+ cu->abbrev_table =
+ abbrev_table_read_table (abbrev_section, cu->header.abbrev_offset);
}
+/* Release the memory used by the abbrev table for a compilation unit. */
+
+static void
+dwarf2_free_abbrev_table (void *ptr_to_cu)
+{
+ struct dwarf2_cu *cu = ptr_to_cu;
+
+ abbrev_table_free (cu->abbrev_table);
+ /* Set this to NULL so that we SEGV if we try to read it later,
+ and also because free_comp_unit verifies this is NULL. */
+ cu->abbrev_table = NULL;
+}
+
/* Returns nonzero if TAG represents a type that we might generate a partial
symbol for. */
@@ -9540,21 +13300,23 @@ is_type_tag_for_partial (int tag)
/* Load all DIEs that are interesting for partial symbols into memory. */
static struct partial_die_info *
-load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
- int building_psymtab, struct dwarf2_cu *cu)
+load_partial_dies (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr, int building_psymtab)
{
+ struct dwarf2_cu *cu = reader->cu;
+ struct objfile *objfile = cu->objfile;
struct partial_die_info *part_die;
struct partial_die_info *parent_die, *last_die, *first_die = NULL;
struct abbrev_info *abbrev;
unsigned int bytes_read;
unsigned int load_all = 0;
-
int nesting_level = 1;
parent_die = NULL;
last_die = NULL;
- if (cu->per_cu && cu->per_cu->load_all_dies)
+ gdb_assert (cu->per_cu != NULL);
+ if (cu->per_cu->load_all_dies)
load_all = 1;
cu->partial_dies
@@ -9604,20 +13366,19 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
if (!load_all)
{
/* We don't need a partial DIE for the template argument. */
- info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev,
- cu);
+ info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
continue;
}
}
- /* We only recurse into subprograms looking for template arguments.
+ /* We only recurse into c++ subprograms looking for template arguments.
Skip their other children. */
if (!load_all
&& cu->language == language_cplus
&& parent_die != NULL
&& parent_die->tag == DW_TAG_subprogram)
{
- info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu);
+ info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
continue;
}
@@ -9634,15 +13395,16 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
&& abbrev->tag != DW_TAG_variable
&& abbrev->tag != DW_TAG_namespace
&& abbrev->tag != DW_TAG_module
- && abbrev->tag != DW_TAG_member)
+ && abbrev->tag != DW_TAG_member
+ && abbrev->tag != DW_TAG_imported_unit)
{
/* Otherwise we skip to the next sibling, if any. */
- info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu);
+ info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
continue;
}
- info_ptr = read_partial_die (part_die, abbrev, bytes_read, abfd,
- buffer, info_ptr, cu);
+ info_ptr = read_partial_die (reader, part_die, abbrev, bytes_read,
+ info_ptr);
/* This two-pass algorithm for processing partial symbols has a
high cost in cache pressure. Thus, handle some simple cases
@@ -9670,9 +13432,9 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
if (building_psymtab && part_die->name != NULL)
add_psymbol_to_list (part_die->name, strlen (part_die->name), 0,
VAR_DOMAIN, LOC_TYPEDEF,
- &cu->objfile->static_psymbols,
- 0, (CORE_ADDR) 0, cu->language, cu->objfile);
- info_ptr = locate_pdi_sibling (part_die, buffer, info_ptr, abfd, cu);
+ &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu->language, objfile);
+ info_ptr = locate_pdi_sibling (reader, part_die, info_ptr);
continue;
}
@@ -9688,7 +13450,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
complaint (&symfile_complaints,
_("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
"- DIE at 0x%x [in module %s]"),
- part_die->offset, cu->objfile->name);
+ part_die->offset.sect_off, objfile->name);
/* If we're at the second level, and we're an enumerator, and
our parent has no specification (meaning possibly lives in a
@@ -9708,11 +13470,11 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
VAR_DOMAIN, LOC_CONST,
(cu->language == language_cplus
|| cu->language == language_java)
- ? &cu->objfile->global_psymbols
- : &cu->objfile->static_psymbols,
- 0, (CORE_ADDR) 0, cu->language, cu->objfile);
+ ? &objfile->global_psymbols
+ : &objfile->static_psymbols,
+ 0, (CORE_ADDR) 0, cu->language, objfile);
- info_ptr = locate_pdi_sibling (part_die, buffer, info_ptr, abfd, cu);
+ info_ptr = locate_pdi_sibling (reader, part_die, info_ptr);
continue;
}
@@ -9762,7 +13524,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
void **slot;
slot = htab_find_slot_with_hash (cu->partial_dies, part_die,
- part_die->offset, INSERT);
+ part_die->offset.sect_off, INSERT);
*slot = part_die;
}
@@ -9805,7 +13567,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
}
/* Otherwise we skip to the next sibling, if any. */
- info_ptr = locate_pdi_sibling (last_die, buffer, info_ptr, abfd, cu);
+ info_ptr = locate_pdi_sibling (reader, last_die, info_ptr);
/* Back to the top, do it again. */
}
@@ -9814,20 +13576,23 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
/* Read a minimal amount of information into the minimal die structure. */
static gdb_byte *
-read_partial_die (struct partial_die_info *part_die,
- struct abbrev_info *abbrev,
- unsigned int abbrev_len, bfd *abfd,
- gdb_byte *buffer, gdb_byte *info_ptr,
- struct dwarf2_cu *cu)
+read_partial_die (const struct die_reader_specs *reader,
+ struct partial_die_info *part_die,
+ struct abbrev_info *abbrev, unsigned int abbrev_len,
+ gdb_byte *info_ptr)
{
+ struct dwarf2_cu *cu = reader->cu;
+ struct objfile *objfile = cu->objfile;
+ gdb_byte *buffer = reader->buffer;
unsigned int i;
struct attribute attr;
int has_low_pc_attr = 0;
int has_high_pc_attr = 0;
+ int high_pc_relative = 0;
memset (part_die, 0, sizeof (struct partial_die_info));
- part_die->offset = info_ptr - buffer;
+ part_die->offset.sect_off = info_ptr - buffer;
info_ptr += abbrev_len;
@@ -9839,7 +13604,7 @@ read_partial_die (struct partial_die_info *part_die,
for (i = 0; i < abbrev->num_attrs; ++i)
{
- info_ptr = read_attribute (&attr, &abbrev->attrs[i], abfd, info_ptr, cu);
+ info_ptr = read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
/* Store the data if it is of an attribute we want to keep in a
partial symbol table. */
@@ -9849,6 +13614,7 @@ read_partial_die (struct partial_die_info *part_die,
switch (part_die->tag)
{
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
case DW_TAG_type_unit:
/* Compilation units have a DW_AT_name that is a filename, not
a source language identifier. */
@@ -9861,7 +13627,7 @@ read_partial_die (struct partial_die_info *part_die,
default:
part_die->name
= dwarf2_canonicalize_name (DW_STRING (&attr), cu,
- &cu->objfile->objfile_obstack);
+ &objfile->objfile_obstack);
break;
}
break;
@@ -9880,13 +13646,20 @@ read_partial_die (struct partial_die_info *part_die,
break;
case DW_AT_high_pc:
has_high_pc_attr = 1;
- part_die->highpc = DW_ADDR (&attr);
+ if (attr.form == DW_FORM_addr
+ || attr.form == DW_FORM_GNU_addr_index)
+ part_die->highpc = DW_ADDR (&attr);
+ else
+ {
+ high_pc_relative = 1;
+ part_die->highpc = DW_UNSND (&attr);
+ }
break;
case DW_AT_location:
/* Support the .debug_loc offsets. */
if (attr_form_is_block (&attr))
{
- part_die->locdesc = DW_BLOCK (&attr);
+ part_die->d.locdesc = DW_BLOCK (&attr);
}
else if (attr_form_is_section_offset (&attr))
{
@@ -9912,6 +13685,8 @@ read_partial_die (struct partial_die_info *part_die,
case DW_AT_extension:
part_die->has_specification = 1;
part_die->spec_offset = dwarf2_get_ref_die_offset (&attr);
+ part_die->spec_is_dwz = (attr.form == DW_FORM_GNU_ref_alt
+ || cu->per_cu->is_dwz);
break;
case DW_AT_sibling:
/* Ignore absolute siblings, they might point outside of
@@ -9920,7 +13695,7 @@ read_partial_die (struct partial_die_info *part_die,
complaint (&symfile_complaints,
_("ignoring absolute DW_AT_sibling"));
else
- part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr);
+ part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
break;
case DW_AT_byte_size:
part_die->has_byte_size = 1;
@@ -9950,11 +13725,29 @@ read_partial_die (struct partial_die_info *part_die,
language_of_main = language_fortran;
}
break;
+ case DW_AT_inline:
+ if (DW_UNSND (&attr) == DW_INL_inlined
+ || DW_UNSND (&attr) == DW_INL_declared_inlined)
+ part_die->may_be_inlined = 1;
+ break;
+
+ case DW_AT_import:
+ if (part_die->tag == DW_TAG_imported_unit)
+ {
+ part_die->d.offset = dwarf2_get_ref_die_offset (&attr);
+ part_die->is_dwz = (attr.form == DW_FORM_GNU_ref_alt
+ || cu->per_cu->is_dwz);
+ }
+ break;
+
default:
break;
}
}
+ if (high_pc_relative)
+ part_die->highpc += part_die->lowpc;
+
if (has_low_pc_attr && has_high_pc_attr)
{
/* When using the GNU linker, .gnu.linkonce. sections are used to
@@ -9967,25 +13760,25 @@ read_partial_die (struct partial_die_info *part_die,
so that GDB will ignore it. */
if (part_die->lowpc == 0 && !dwarf2_per_objfile->has_section_at_zero)
{
- struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
complaint (&symfile_complaints,
_("DW_AT_low_pc %s is zero "
"for DIE at 0x%x [in module %s]"),
paddress (gdbarch, part_die->lowpc),
- part_die->offset, cu->objfile->name);
+ part_die->offset.sect_off, objfile->name);
}
/* dwarf2_get_pc_bounds has also the strict low < high requirement. */
else if (part_die->lowpc >= part_die->highpc)
{
- struct gdbarch *gdbarch = get_objfile_arch (cu->objfile);
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
complaint (&symfile_complaints,
_("DW_AT_low_pc %s is not < DW_AT_high_pc %s "
"for DIE at 0x%x [in module %s]"),
paddress (gdbarch, part_die->lowpc),
paddress (gdbarch, part_die->highpc),
- part_die->offset, cu->objfile->name);
+ part_die->offset.sect_off, objfile->name);
}
else
part_die->has_pc_info = 1;
@@ -9997,13 +13790,14 @@ read_partial_die (struct partial_die_info *part_die,
/* Find a cached partial DIE at OFFSET in CU. */
static struct partial_die_info *
-find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu)
+find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu)
{
struct partial_die_info *lookup_die = NULL;
struct partial_die_info part_die;
part_die.offset = offset;
- lookup_die = htab_find_with_hash (cu->partial_dies, &part_die, offset);
+ lookup_die = htab_find_with_hash (cu->partial_dies, &part_die,
+ offset.sect_off);
return lookup_die;
}
@@ -10014,75 +13808,65 @@ find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu)
DW_FORM_ref_sig8). */
static struct partial_die_info *
-find_partial_die (unsigned int offset, struct dwarf2_cu *cu)
+find_partial_die (sect_offset offset, int offset_in_dwz, struct dwarf2_cu *cu)
{
+ struct objfile *objfile = cu->objfile;
struct dwarf2_per_cu_data *per_cu = NULL;
struct partial_die_info *pd = NULL;
- if (cu->per_cu->debug_types_section)
+ if (offset_in_dwz == cu->per_cu->is_dwz
+ && offset_in_cu_p (&cu->header, offset))
{
pd = find_partial_die_in_comp_unit (offset, cu);
if (pd != NULL)
return pd;
- goto not_found;
+ /* We missed recording what we needed.
+ Load all dies and try again. */
+ per_cu = cu->per_cu;
}
-
- if (offset_in_cu_p (&cu->header, offset))
+ else
{
- pd = find_partial_die_in_comp_unit (offset, cu);
- if (pd != NULL)
- return pd;
- }
+ /* TUs don't reference other CUs/TUs (except via type signatures). */
+ if (cu->per_cu->is_debug_types)
+ {
+ error (_("Dwarf Error: Type Unit at offset 0x%lx contains"
+ " external reference to offset 0x%lx [in module %s].\n"),
+ (long) cu->header.offset.sect_off, (long) offset.sect_off,
+ bfd_get_filename (objfile->obfd));
+ }
+ per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz,
+ objfile);
- per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+ if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
+ load_partial_comp_unit (per_cu);
- if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
- load_partial_comp_unit (per_cu, cu->objfile);
+ per_cu->cu->last_used = 0;
+ pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+ }
- per_cu->cu->last_used = 0;
- pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+ /* If we didn't find it, and not all dies have been loaded,
+ load them all and try again. */
if (pd == NULL && per_cu->load_all_dies == 0)
{
- struct cleanup *back_to;
- struct partial_die_info comp_unit_die;
- struct abbrev_info *abbrev;
- unsigned int bytes_read;
- char *info_ptr;
-
per_cu->load_all_dies = 1;
- /* Re-read the DIEs. */
- back_to = make_cleanup (null_cleanup, 0);
- if (per_cu->cu->dwarf2_abbrevs == NULL)
- {
- dwarf2_read_abbrevs (per_cu->cu->objfile->obfd, per_cu->cu);
- make_cleanup (dwarf2_free_abbrev_table, per_cu->cu);
- }
- info_ptr = (dwarf2_per_objfile->info.buffer
- + per_cu->cu->header.offset
- + per_cu->cu->header.first_die_offset);
- abbrev = peek_die_abbrev (info_ptr, &bytes_read, per_cu->cu);
- info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
- per_cu->cu->objfile->obfd,
- dwarf2_per_objfile->info.buffer, info_ptr,
- per_cu->cu);
- if (comp_unit_die.has_children)
- load_partial_dies (per_cu->cu->objfile->obfd,
- dwarf2_per_objfile->info.buffer, info_ptr,
- 0, per_cu->cu);
- do_cleanups (back_to);
+ /* This is nasty. When we reread the DIEs, somewhere up the call chain
+ THIS_CU->cu may already be in use. So we can't just free it and
+ replace its DIEs with the ones we read in. Instead, we leave those
+ DIEs alone (which can still be in use, e.g. in scan_partial_symbols),
+ and clobber THIS_CU->cu->partial_dies with the hash table for the new
+ set. */
+ load_partial_comp_unit (per_cu);
pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
}
- not_found:
-
if (pd == NULL)
internal_error (__FILE__, __LINE__,
_("could not find partial DIE 0x%x "
"in cache [from module %s]\n"),
- offset, bfd_get_filename (cu->objfile->obfd));
+ offset.sect_off, bfd_get_filename (objfile->obfd));
return pd;
}
@@ -10109,7 +13893,8 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi,
real_pdi = struct_pdi;
while (real_pdi->has_specification)
- real_pdi = find_partial_die (real_pdi->spec_offset, cu);
+ real_pdi = find_partial_die (real_pdi->spec_offset,
+ real_pdi->spec_is_dwz, cu);
if (real_pdi->die_parent != NULL)
return;
@@ -10127,9 +13912,9 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi,
if (actual_class_name != NULL)
{
struct_pdi->name
- = obsavestring (actual_class_name,
- strlen (actual_class_name),
- &cu->objfile->objfile_obstack);
+ = obstack_copy0 (&cu->objfile->objfile_obstack,
+ actual_class_name,
+ strlen (actual_class_name));
xfree (actual_class_name);
}
break;
@@ -10157,7 +13942,8 @@ fixup_partial_die (struct partial_die_info *part_die,
{
struct partial_die_info *spec_die;
- spec_die = find_partial_die (part_die->spec_offset, cu);
+ spec_die = find_partial_die (part_die->spec_offset,
+ part_die->spec_is_dwz, cu);
fixup_partial_die (spec_die, cu);
@@ -10178,9 +13964,7 @@ fixup_partial_die (struct partial_die_info *part_die,
/* If there is no parent die to provide a namespace, and there are
children, see if we can determine the namespace from their linkage
- name.
- NOTE: We need to do this even if cu->has_namespace_info != 0.
- gcc-4.5 -gdwarf-4 can drop the enclosing namespace. */
+ name. */
if (cu->language == language_cplus
&& !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)
&& part_die->die_parent == NULL
@@ -10214,8 +13998,8 @@ fixup_partial_die (struct partial_die_info *part_die,
else
base = demangled;
- part_die->name = obsavestring (base, strlen (base),
- &cu->objfile->objfile_obstack);
+ part_die->name = obstack_copy0 (&cu->objfile->objfile_obstack,
+ base, strlen (base));
xfree (demangled);
}
}
@@ -10226,10 +14010,12 @@ fixup_partial_die (struct partial_die_info *part_die,
/* Read an attribute value described by an attribute form. */
static gdb_byte *
-read_attribute_value (struct attribute *attr, unsigned form,
- bfd *abfd, gdb_byte *info_ptr,
- struct dwarf2_cu *cu)
+read_attribute_value (const struct die_reader_specs *reader,
+ struct attribute *attr, unsigned form,
+ gdb_byte *info_ptr)
{
+ struct dwarf2_cu *cu = reader->cu;
+ bfd *abfd = reader->abfd;
struct comp_unit_head *cu_header = &cu->header;
unsigned int bytes_read;
struct dwarf_block *blk;
@@ -10239,10 +14025,14 @@ read_attribute_value (struct attribute *attr, unsigned form,
{
case DW_FORM_ref_addr:
if (cu->header.version == 2)
- DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read);
+ DW_UNSND (attr) = read_address (abfd, info_ptr, cu, &bytes_read);
else
- DW_ADDR (attr) = read_offset (abfd, info_ptr,
- &cu->header, &bytes_read);
+ DW_UNSND (attr) = read_offset (abfd, info_ptr,
+ &cu->header, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_GNU_ref_alt:
+ DW_UNSND (attr) = read_offset (abfd, info_ptr, &cu->header, &bytes_read);
info_ptr += bytes_read;
break;
case DW_FORM_addr:
@@ -10287,10 +14077,25 @@ read_attribute_value (struct attribute *attr, unsigned form,
info_ptr += bytes_read;
break;
case DW_FORM_strp:
- DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
- &bytes_read);
- DW_STRING_IS_CANONICAL (attr) = 0;
- info_ptr += bytes_read;
+ if (!cu->per_cu->is_dwz)
+ {
+ DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
+ &bytes_read);
+ DW_STRING_IS_CANONICAL (attr) = 0;
+ info_ptr += bytes_read;
+ break;
+ }
+ /* FALLTHROUGH */
+ case DW_FORM_GNU_strp_alt:
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+ LONGEST str_offset = read_offset (abfd, info_ptr, cu_header,
+ &bytes_read);
+
+ DW_STRING (attr) = read_indirect_string_from_dwz (dwz, str_offset);
+ DW_STRING_IS_CANONICAL (attr) = 0;
+ info_ptr += bytes_read;
+ }
break;
case DW_FORM_exprloc:
case DW_FORM_block:
@@ -10329,19 +14134,23 @@ read_attribute_value (struct attribute *attr, unsigned form,
info_ptr += bytes_read;
break;
case DW_FORM_ref1:
- DW_ADDR (attr) = cu->header.offset + read_1_byte (abfd, info_ptr);
+ DW_UNSND (attr) = (cu->header.offset.sect_off
+ + read_1_byte (abfd, info_ptr));
info_ptr += 1;
break;
case DW_FORM_ref2:
- DW_ADDR (attr) = cu->header.offset + read_2_bytes (abfd, info_ptr);
+ DW_UNSND (attr) = (cu->header.offset.sect_off
+ + read_2_bytes (abfd, info_ptr));
info_ptr += 2;
break;
case DW_FORM_ref4:
- DW_ADDR (attr) = cu->header.offset + read_4_bytes (abfd, info_ptr);
+ DW_UNSND (attr) = (cu->header.offset.sect_off
+ + read_4_bytes (abfd, info_ptr));
info_ptr += 4;
break;
case DW_FORM_ref8:
- DW_ADDR (attr) = cu->header.offset + read_8_bytes (abfd, info_ptr);
+ DW_UNSND (attr) = (cu->header.offset.sect_off
+ + read_8_bytes (abfd, info_ptr));
info_ptr += 8;
break;
case DW_FORM_ref_sig8:
@@ -10349,18 +14158,48 @@ read_attribute_value (struct attribute *attr, unsigned form,
for later lookup.
NOTE: This is NULL if the type wasn't found. */
DW_SIGNATURED_TYPE (attr) =
- lookup_signatured_type (cu->objfile, read_8_bytes (abfd, info_ptr));
+ lookup_signatured_type (read_8_bytes (abfd, info_ptr));
info_ptr += 8;
break;
case DW_FORM_ref_udata:
- DW_ADDR (attr) = (cu->header.offset
- + read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
+ DW_UNSND (attr) = (cu->header.offset.sect_off
+ + read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
info_ptr += bytes_read;
break;
case DW_FORM_indirect:
form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
- info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu);
+ info_ptr = read_attribute_value (reader, attr, form, info_ptr);
+ break;
+ case DW_FORM_GNU_addr_index:
+ if (reader->dwo_file == NULL)
+ {
+ /* For now flag a hard error.
+ Later we can turn this into a complaint. */
+ error (_("Dwarf Error: %s found in non-DWO CU [in module %s]"),
+ dwarf_form_name (form),
+ bfd_get_filename (abfd));
+ }
+ DW_ADDR (attr) = read_addr_index_from_leb128 (cu, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
+ case DW_FORM_GNU_str_index:
+ if (reader->dwo_file == NULL)
+ {
+ /* For now flag a hard error.
+ Later we can turn this into a complaint if warranted. */
+ error (_("Dwarf Error: %s found in non-DWO CU [in module %s]"),
+ dwarf_form_name (form),
+ bfd_get_filename (abfd));
+ }
+ {
+ ULONGEST str_index =
+ read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+
+ DW_STRING (attr) = read_str_index (reader, cu, str_index);
+ DW_STRING_IS_CANONICAL (attr) = 0;
+ info_ptr += bytes_read;
+ }
break;
default:
error (_("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]"),
@@ -10368,6 +14207,10 @@ read_attribute_value (struct attribute *attr, unsigned form,
bfd_get_filename (abfd));
}
+ /* Super hack. */
+ if (cu->per_cu->is_dwz && is_ref_attr (attr))
+ attr->form = DW_FORM_GNU_ref_alt;
+
/* We have seen instances where the compiler tried to emit a byte
size attribute of -1 which ended up being encoded as an unsigned
0xffffffff. Although 0xffffffff is technically a valid size value,
@@ -10391,53 +14234,54 @@ read_attribute_value (struct attribute *attr, unsigned form,
/* Read an attribute described by an abbreviated attribute. */
static gdb_byte *
-read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
- bfd *abfd, gdb_byte *info_ptr, struct dwarf2_cu *cu)
+read_attribute (const struct die_reader_specs *reader,
+ struct attribute *attr, struct attr_abbrev *abbrev,
+ gdb_byte *info_ptr)
{
attr->name = abbrev->name;
- return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu);
+ return read_attribute_value (reader, attr, abbrev->form, info_ptr);
}
/* Read dwarf information from a buffer. */
static unsigned int
-read_1_byte (bfd *abfd, gdb_byte *buf)
+read_1_byte (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_8 (abfd, buf);
}
static int
-read_1_signed_byte (bfd *abfd, gdb_byte *buf)
+read_1_signed_byte (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_signed_8 (abfd, buf);
}
static unsigned int
-read_2_bytes (bfd *abfd, gdb_byte *buf)
+read_2_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_16 (abfd, buf);
}
static int
-read_2_signed_bytes (bfd *abfd, gdb_byte *buf)
+read_2_signed_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_signed_16 (abfd, buf);
}
static unsigned int
-read_4_bytes (bfd *abfd, gdb_byte *buf)
+read_4_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_32 (abfd, buf);
}
static int
-read_4_signed_bytes (bfd *abfd, gdb_byte *buf)
+read_4_signed_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_signed_32 (abfd, buf);
}
static ULONGEST
-read_8_bytes (bfd *abfd, gdb_byte *buf)
+read_8_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_64 (abfd, buf);
}
@@ -10663,6 +14507,30 @@ read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
return (char *) (dwarf2_per_objfile->str.buffer + str_offset);
}
+/* Read a string at offset STR_OFFSET in the .debug_str section from
+ the .dwz file DWZ. Throw an error if the offset is too large. If
+ the string consists of a single NUL byte, return NULL; otherwise
+ return a pointer to the string. */
+
+static char *
+read_indirect_string_from_dwz (struct dwz_file *dwz, LONGEST str_offset)
+{
+ dwarf2_read_section (dwarf2_per_objfile->objfile, &dwz->str);
+
+ if (dwz->str.buffer == NULL)
+ error (_("DW_FORM_GNU_strp_alt used without .debug_str "
+ "section [in module %s]"),
+ bfd_get_filename (dwz->dwz_bfd));
+ if (str_offset >= dwz->str.size)
+ error (_("DW_FORM_GNU_strp_alt pointing outside of "
+ ".debug_str section [in module %s]"),
+ bfd_get_filename (dwz->dwz_bfd));
+ gdb_assert (HOST_CHAR_BIT == 8);
+ if (dwz->str.buffer[str_offset] == '\0')
+ return NULL;
+ return (char *) (dwz->str.buffer + str_offset);
+}
+
static char *
read_indirect_string (bfd *abfd, gdb_byte *buf,
const struct comp_unit_head *cu_header,
@@ -10673,10 +14541,10 @@ read_indirect_string (bfd *abfd, gdb_byte *buf,
return read_indirect_string_at_offset (abfd, str_offset);
}
-static unsigned long
+static ULONGEST
read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
{
- unsigned long result;
+ ULONGEST result;
unsigned int num_read;
int i, shift;
unsigned char byte;
@@ -10690,7 +14558,7 @@ read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
byte = bfd_get_8 (abfd, buf);
buf++;
num_read++;
- result |= ((unsigned long)(byte & 127) << shift);
+ result |= ((ULONGEST) (byte & 127) << shift);
if ((byte & 128) == 0)
{
break;
@@ -10701,10 +14569,10 @@ read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
return result;
}
-static long
+static LONGEST
read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
{
- long result;
+ LONGEST result;
int i, shift, num_read;
unsigned char byte;
@@ -10717,7 +14585,7 @@ read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
byte = bfd_get_8 (abfd, buf);
buf++;
num_read++;
- result |= ((long)(byte & 127) << shift);
+ result |= ((LONGEST) (byte & 127) << shift);
shift += 7;
if ((byte & 128) == 0)
{
@@ -10725,24 +14593,190 @@ read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
}
}
if ((shift < 8 * sizeof (result)) && (byte & 0x40))
- result |= -(((long)1) << shift);
+ result |= -(((LONGEST) 1) << shift);
*bytes_read_ptr = num_read;
return result;
}
-/* Return a pointer to just past the end of an LEB128 number in BUF. */
+/* Given index ADDR_INDEX in .debug_addr, fetch the value.
+ ADDR_BASE is the DW_AT_GNU_addr_base attribute or zero.
+ ADDR_SIZE is the size of addresses from the CU header. */
+
+static CORE_ADDR
+read_addr_index_1 (unsigned int addr_index, ULONGEST addr_base, int addr_size)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *abfd = objfile->obfd;
+ const gdb_byte *info_ptr;
+
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->addr);
+ if (dwarf2_per_objfile->addr.buffer == NULL)
+ error (_("DW_FORM_addr_index used without .debug_addr section [in module %s]"),
+ objfile->name);
+ if (addr_base + addr_index * addr_size >= dwarf2_per_objfile->addr.size)
+ error (_("DW_FORM_addr_index pointing outside of "
+ ".debug_addr section [in module %s]"),
+ objfile->name);
+ info_ptr = (dwarf2_per_objfile->addr.buffer
+ + addr_base + addr_index * addr_size);
+ if (addr_size == 4)
+ return bfd_get_32 (abfd, info_ptr);
+ else
+ return bfd_get_64 (abfd, info_ptr);
+}
+
+/* Given index ADDR_INDEX in .debug_addr, fetch the value. */
+
+static CORE_ADDR
+read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index)
+{
+ return read_addr_index_1 (addr_index, cu->addr_base, cu->header.addr_size);
+}
+
+/* Given a pointer to an leb128 value, fetch the value from .debug_addr. */
+
+static CORE_ADDR
+read_addr_index_from_leb128 (struct dwarf2_cu *cu, gdb_byte *info_ptr,
+ unsigned int *bytes_read)
+{
+ bfd *abfd = cu->objfile->obfd;
+ unsigned int addr_index = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
+
+ return read_addr_index (cu, addr_index);
+}
+
+/* Data structure to pass results from dwarf2_read_addr_index_reader
+ back to dwarf2_read_addr_index. */
+
+struct dwarf2_read_addr_index_data
+{
+ ULONGEST addr_base;
+ int addr_size;
+};
+
+/* die_reader_func for dwarf2_read_addr_index. */
+
+static void
+dwarf2_read_addr_index_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
+{
+ struct dwarf2_cu *cu = reader->cu;
+ struct dwarf2_read_addr_index_data *aidata =
+ (struct dwarf2_read_addr_index_data *) data;
+
+ aidata->addr_base = cu->addr_base;
+ aidata->addr_size = cu->header.addr_size;
+}
+
+/* Given an index in .debug_addr, fetch the value.
+ NOTE: This can be called during dwarf expression evaluation,
+ long after the debug information has been read, and thus per_cu->cu
+ may no longer exist. */
+
+CORE_ADDR
+dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
+ unsigned int addr_index)
+{
+ struct objfile *objfile = per_cu->objfile;
+ struct dwarf2_cu *cu = per_cu->cu;
+ ULONGEST addr_base;
+ int addr_size;
+
+ /* This is intended to be called from outside this file. */
+ dw2_setup (objfile);
+
+ /* We need addr_base and addr_size.
+ If we don't have PER_CU->cu, we have to get it.
+ Nasty, but the alternative is storing the needed info in PER_CU,
+ which at this point doesn't seem justified: it's not clear how frequently
+ it would get used and it would increase the size of every PER_CU.
+ Entry points like dwarf2_per_cu_addr_size do a similar thing
+ so we're not in uncharted territory here.
+ Alas we need to be a bit more complicated as addr_base is contained
+ in the DIE.
+
+ We don't need to read the entire CU(/TU).
+ We just need the header and top level die.
+
+ IWBN to use the aging mechanism to let us lazily later discard the CU.
+ For now we skip this optimization. */
+
+ if (cu != NULL)
+ {
+ addr_base = cu->addr_base;
+ addr_size = cu->header.addr_size;
+ }
+ else
+ {
+ struct dwarf2_read_addr_index_data aidata;
+
+ /* Note: We can't use init_cutu_and_read_dies_simple here,
+ we need addr_base. */
+ init_cutu_and_read_dies (per_cu, NULL, 0, 0,
+ dwarf2_read_addr_index_reader, &aidata);
+ addr_base = aidata.addr_base;
+ addr_size = aidata.addr_size;
+ }
+
+ return read_addr_index_1 (addr_index, addr_base, addr_size);
+}
+
+/* Given a DW_AT_str_index, fetch the string. */
+
+static char *
+read_str_index (const struct die_reader_specs *reader,
+ struct dwarf2_cu *cu, ULONGEST str_index)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ const char *dwo_name = objfile->name;
+ bfd *abfd = objfile->obfd;
+ struct dwo_sections *sections = &reader->dwo_file->sections;
+ gdb_byte *info_ptr;
+ ULONGEST str_offset;
+
+ dwarf2_read_section (objfile, §ions->str);
+ dwarf2_read_section (objfile, §ions->str_offsets);
+ if (sections->str.buffer == NULL)
+ error (_("DW_FORM_str_index used without .debug_str.dwo section"
+ " in CU at offset 0x%lx [in module %s]"),
+ (long) cu->header.offset.sect_off, dwo_name);
+ if (sections->str_offsets.buffer == NULL)
+ error (_("DW_FORM_str_index used without .debug_str_offsets.dwo section"
+ " in CU at offset 0x%lx [in module %s]"),
+ (long) cu->header.offset.sect_off, dwo_name);
+ if (str_index * cu->header.offset_size >= sections->str_offsets.size)
+ error (_("DW_FORM_str_index pointing outside of .debug_str_offsets.dwo"
+ " section in CU at offset 0x%lx [in module %s]"),
+ (long) cu->header.offset.sect_off, dwo_name);
+ info_ptr = (sections->str_offsets.buffer
+ + str_index * cu->header.offset_size);
+ if (cu->header.offset_size == 4)
+ str_offset = bfd_get_32 (abfd, info_ptr);
+ else
+ str_offset = bfd_get_64 (abfd, info_ptr);
+ if (str_offset >= sections->str.size)
+ error (_("Offset from DW_FORM_str_index pointing outside of"
+ " .debug_str.dwo section in CU at offset 0x%lx [in module %s]"),
+ (long) cu->header.offset.sect_off, dwo_name);
+ return (char *) (sections->str.buffer + str_offset);
+}
+
+/* Return the length of an LEB128 number in BUF. */
-static gdb_byte *
-skip_leb128 (bfd *abfd, gdb_byte *buf)
+static int
+leb128_size (const gdb_byte *buf)
{
- int byte;
+ const gdb_byte *begin = buf;
+ gdb_byte byte;
while (1)
{
- byte = bfd_get_8 (abfd, buf);
- buf++;
+ byte = *buf++;
if ((byte & 128) == 0)
- return buf;
+ return buf - begin;
}
}
@@ -10767,6 +14801,9 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
case DW_LANG_Fortran95:
cu->language = language_fortran;
break;
+ case DW_LANG_Go:
+ cu->language = language_go;
+ break;
case DW_LANG_Mips_Assembler:
cu->language = language_asm;
break;
@@ -10800,22 +14837,24 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
static struct attribute *
dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
{
- unsigned int i;
- struct attribute *spec = NULL;
-
- for (i = 0; i < die->num_attrs; ++i)
+ for (;;)
{
- if (die->attrs[i].name == name)
- return &die->attrs[i];
- if (die->attrs[i].name == DW_AT_specification
- || die->attrs[i].name == DW_AT_abstract_origin)
- spec = &die->attrs[i];
- }
+ unsigned int i;
+ struct attribute *spec = NULL;
+
+ for (i = 0; i < die->num_attrs; ++i)
+ {
+ if (die->attrs[i].name == name)
+ return &die->attrs[i];
+ if (die->attrs[i].name == DW_AT_specification
+ || die->attrs[i].name == DW_AT_abstract_origin)
+ spec = &die->attrs[i];
+ }
+
+ if (!spec)
+ break;
- if (spec)
- {
die = follow_die_ref (die, spec, &cu);
- return dwarf2_attr (die, name, cu);
}
return NULL;
@@ -10828,8 +14867,7 @@ dwarf2_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *cu)
back up the chain, and we want to go down. */
static struct attribute *
-dwarf2_attr_no_follow (struct die_info *die, unsigned int name,
- struct dwarf2_cu *cu)
+dwarf2_attr_no_follow (struct die_info *die, unsigned int name)
{
unsigned int i;
@@ -10967,17 +15005,40 @@ add_file_name (struct line_header *lh,
fe->symtab = NULL;
}
+/* A convenience function to find the proper .debug_line section for a
+ CU. */
+
+static struct dwarf2_section_info *
+get_debug_line_section (struct dwarf2_cu *cu)
+{
+ struct dwarf2_section_info *section;
+
+ /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
+ DWO file. */
+ if (cu->dwo_unit && cu->per_cu->is_debug_types)
+ section = &cu->dwo_unit->dwo_file->sections.line;
+ else if (cu->per_cu->is_dwz)
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+
+ section = &dwz->line;
+ }
+ else
+ section = &dwarf2_per_objfile->line;
+
+ return section;
+}
+
/* Read the statement program header starting at OFFSET in
- .debug_line, according to the endianness of ABFD. Return a pointer
+ .debug_line, or .debug_line.dwo. Return a pointer
to a struct line_header, allocated using xmalloc.
NOTE: the strings in the include directory and file name tables of
- the returned object point into debug_line_buffer, and must not be
- freed. */
+ the returned object point into the dwarf line section buffer,
+ and must not be freed. */
static struct line_header *
-dwarf_decode_line_header (unsigned int offset, bfd *abfd,
- struct dwarf2_cu *cu)
+dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
{
struct cleanup *back_to;
struct line_header *lh;
@@ -10985,17 +15046,27 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
unsigned int bytes_read, offset_size;
int i;
char *cur_dir, *cur_file;
+ struct dwarf2_section_info *section;
+ bfd *abfd;
- dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->line);
- if (dwarf2_per_objfile->line.buffer == NULL)
+ section = get_debug_line_section (cu);
+ dwarf2_read_section (dwarf2_per_objfile->objfile, section);
+ if (section->buffer == NULL)
{
- complaint (&symfile_complaints, _("missing .debug_line section"));
+ if (cu->dwo_unit && cu->per_cu->is_debug_types)
+ complaint (&symfile_complaints, _("missing .debug_line.dwo section"));
+ else
+ complaint (&symfile_complaints, _("missing .debug_line section"));
return 0;
}
+ /* We can't do this until we know the section is non-empty.
+ Only then do we know we have such a section. */
+ abfd = section->asection->owner;
+
/* Make sure that at least there's room for the total_length field.
That could be 12 bytes long, but we're just going to fudge that. */
- if (offset + 4 >= dwarf2_per_objfile->line.size)
+ if (offset + 4 >= section->size)
{
dwarf2_statement_list_fits_in_line_number_section_complaint ();
return 0;
@@ -11006,15 +15077,14 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
(void *) lh);
- line_ptr = dwarf2_per_objfile->line.buffer + offset;
+ line_ptr = section->buffer + offset;
/* Read in the header. */
lh->total_length =
read_checked_initial_length_and_offset (abfd, line_ptr, &cu->header,
&bytes_read, &offset_size);
line_ptr += bytes_read;
- if (line_ptr + lh->total_length > (dwarf2_per_objfile->line.buffer
- + dwarf2_per_objfile->line.size))
+ if (line_ptr + lh->total_length > (section->buffer + section->size))
{
dwarf2_statement_list_fits_in_line_number_section_complaint ();
return 0;
@@ -11086,8 +15156,7 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
line_ptr += bytes_read;
lh->statement_program_start = line_ptr;
- if (line_ptr > (dwarf2_per_objfile->line.buffer
- + dwarf2_per_objfile->line.size))
+ if (line_ptr > (section->buffer + section->size))
complaint (&symfile_complaints,
_("line number info header doesn't "
"fit in `.debug_line' section"));
@@ -11096,58 +15165,14 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
return lh;
}
-/* This function exists to work around a bug in certain compilers
- (particularly GCC 2.95), in which the first line number marker of a
- function does not show up until after the prologue, right before
- the second line number marker. This function shifts ADDRESS down
- to the beginning of the function if necessary, and is called on
- addresses passed to record_line. */
-
-static CORE_ADDR
-check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu)
-{
- struct function_range *fn;
-
- /* Find the function_range containing address. */
- if (!cu->first_fn)
- return address;
-
- if (!cu->cached_fn)
- cu->cached_fn = cu->first_fn;
-
- fn = cu->cached_fn;
- while (fn)
- if (fn->lowpc <= address && fn->highpc > address)
- goto found;
- else
- fn = fn->next;
-
- fn = cu->first_fn;
- while (fn && fn != cu->cached_fn)
- if (fn->lowpc <= address && fn->highpc > address)
- goto found;
- else
- fn = fn->next;
-
- return address;
-
- found:
- if (fn->seen_line)
- return address;
- if (address != fn->lowpc)
- complaint (&symfile_complaints,
- _("misplaced first line number at 0x%lx for '%s'"),
- (unsigned long) address, fn->name);
- fn->seen_line = 1;
- return fn->lowpc;
-}
-
/* Subroutine of dwarf_decode_lines to simplify it.
Return the file name of the psymtab for included file FILE_INDEX
in line header LH of PST.
COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown.
If space for the result is malloc'd, it will be freed by a cleanup.
- Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename. */
+ Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename.
+
+ The function creates dangling cleanup registration. */
static char *
psymtab_include_file_name (const struct line_header *lh, int file_index,
@@ -11321,8 +15346,7 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
last_subfile = current_subfile;
}
/* Append row to matrix using current values. */
- addr = check_cu_functions (address, cu);
- addr = gdbarch_addr_bits_remove (gdbarch, addr);
+ addr = gdbarch_addr_bits_remove (gdbarch, address);
(*p_record_line) (current_subfile, line, addr);
}
}
@@ -11352,12 +15376,12 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
GCd by the linker. Ignore it. PR gdb/12528 */
long line_offset
- = line_ptr - dwarf2_per_objfile->line.buffer;
+ = line_ptr - get_debug_line_section (cu)->buffer;
complaint (&symfile_complaints,
_(".debug_line address at offset 0x%lx is 0 "
"[in module %s]"),
- line_offset, cu->objfile->name);
+ line_offset, objfile->name);
p_record_line = noop_record_line;
}
@@ -11420,8 +15444,7 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
(*p_record_line) (last_subfile, 0, addr);
last_subfile = current_subfile;
}
- addr = check_cu_functions (address, cu);
- addr = gdbarch_addr_bits_remove (gdbarch, addr);
+ addr = gdbarch_addr_bits_remove (gdbarch, address);
(*p_record_line) (current_subfile, line, addr);
}
}
@@ -11601,7 +15624,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
if (current_subfile->symtab == NULL)
current_subfile->symtab = allocate_symtab (current_subfile->name,
- cu->objfile);
+ objfile);
fe->symtab = current_subfile->symtab;
}
}
@@ -11658,6 +15681,23 @@ dwarf2_start_subfile (char *filename, const char *dirname,
xfree (fullname);
}
+/* Start a symtab for DWARF.
+ NAME, COMP_DIR, LOW_PC are passed to start_symtab. */
+
+static void
+dwarf2_start_symtab (struct dwarf2_cu *cu,
+ const char *name, const char *comp_dir, CORE_ADDR low_pc)
+{
+ start_symtab (name, comp_dir, low_pc);
+ record_debugformat ("DWARF 2");
+ record_producer (cu->producer);
+
+ /* We assume that we're processing GCC output. */
+ processing_gcc_compilation = 2;
+
+ cu->processing_has_namespace_info = 0;
+}
+
static void
var_decode_location (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
@@ -11685,17 +15725,24 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
/* Handle one degenerate form of location expression specially, to
preserve GDB's previous behavior when section offsets are
- specified. If this is just a DW_OP_addr then mark this symbol
- as LOC_STATIC. */
+ specified. If this is just a DW_OP_addr or DW_OP_GNU_addr_index
+ then mark this symbol as LOC_STATIC. */
if (attr_form_is_block (attr)
- && DW_BLOCK (attr)->size == 1 + cu_header->addr_size
- && DW_BLOCK (attr)->data[0] == DW_OP_addr)
+ && ((DW_BLOCK (attr)->data[0] == DW_OP_addr
+ && DW_BLOCK (attr)->size == 1 + cu_header->addr_size)
+ || (DW_BLOCK (attr)->data[0] == DW_OP_GNU_addr_index
+ && (DW_BLOCK (attr)->size
+ == 1 + leb128_size (&DW_BLOCK (attr)->data[1])))))
{
unsigned int dummy;
- SYMBOL_VALUE_ADDRESS (sym) =
- read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy);
+ if (DW_BLOCK (attr)->data[0] == DW_OP_addr)
+ SYMBOL_VALUE_ADDRESS (sym) =
+ read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu, &dummy);
+ else
+ SYMBOL_VALUE_ADDRESS (sym) =
+ read_addr_index_from_leb128 (cu, DW_BLOCK (attr)->data + 1, &dummy);
SYMBOL_CLASS (sym) = LOC_STATIC;
fixup_symbol_section (sym, objfile);
SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
@@ -11731,7 +15778,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
{
struct objfile *objfile = cu->objfile;
struct symbol *sym = NULL;
- char *name;
+ const char *name;
struct attribute *attr = NULL;
struct attribute *attr2 = NULL;
CORE_ADDR baseaddr;
@@ -11763,7 +15810,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
if (cu->language == language_fortran
&& symbol_get_demangled_name (&(sym->ginfo)) == NULL)
symbol_set_demangled_name (&(sym->ginfo),
- (char *) dwarf2_full_name (name, die, cu),
+ dwarf2_full_name (name, die, cu),
NULL);
/* Default assumptions.
@@ -11841,8 +15888,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
finish_block. */
SYMBOL_CLASS (sym) = LOC_BLOCK;
SYMBOL_INLINED (sym) = 1;
- /* Do not add the symbol to any lists. It will be found via
- BLOCK_FUNCTION from the blockvector. */
+ list_to_add = cu->list_in_scope;
break;
case DW_TAG_template_value_param:
suppress_add = 1;
@@ -11885,6 +15931,13 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
{
var_decode_location (attr, sym, cu);
attr2 = dwarf2_attr (die, DW_AT_external, cu);
+
+ /* Fortran explicitly imports any global symbols to the local
+ scope by DW_TAG_common_block. */
+ if (cu->language == language_fortran && die->parent
+ && die->parent->tag == DW_TAG_common_block)
+ attr2 = NULL;
+
if (SYMBOL_CLASS (sym) == LOC_STATIC
&& SYMBOL_VALUE_ADDRESS (sym) == 0
&& !dwarf2_per_objfile->has_section_at_zero)
@@ -11927,8 +15980,19 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
the minimal symbol table whenever the variable is
referenced. */
attr2 = dwarf2_attr (die, DW_AT_external, cu);
- if (attr2 && (DW_UNSND (attr2) != 0)
- && dwarf2_attr (die, DW_AT_type, cu) != NULL)
+
+ /* Fortran explicitly imports any global symbols to the local
+ scope by DW_TAG_common_block. */
+ if (cu->language == language_fortran && die->parent
+ && die->parent->tag == DW_TAG_common_block)
+ {
+ /* SYMBOL_CLASS doesn't matter here because
+ read_common_block is going to reset it. */
+ if (!suppress_add)
+ list_to_add = cu->list_in_scope;
+ }
+ else if (attr2 && (DW_UNSND (attr2) != 0)
+ && dwarf2_attr (die, DW_AT_type, cu) != NULL)
{
/* A variable with DW_AT_external is never static, but it
may be block-scoped. */
@@ -12049,6 +16113,11 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
list_to_add = &global_symbols;
break;
+ case DW_TAG_common_block:
+ SYMBOL_CLASS (sym) = LOC_COMMON_BLOCK;
+ SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN;
+ add_symbol_to_list (sym, cu->list_in_scope);
+ break;
default:
/* Not a tag we recognize. Hopefully we aren't processing
trash data, but since we must specifically ignore things
@@ -12071,7 +16140,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
/* For the benefit of old versions of GCC, check for anonymous
namespaces based on the demangled name. */
- if (!processing_has_namespace_info
+ if (!cu->processing_has_namespace_info
&& cu->language == language_cplus)
cp_scan_for_anonymous_namespaces (sym, objfile);
}
@@ -12097,7 +16166,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
static gdb_byte *
dwarf2_const_value_data (struct attribute *attr, struct type *type,
const char *name, struct obstack *obstack,
- struct dwarf2_cu *cu, long *value, int bits)
+ struct dwarf2_cu *cu, LONGEST *value, int bits)
{
struct objfile *objfile = cu->objfile;
enum bfd_endian byte_order = bfd_big_endian (objfile->obfd) ?
@@ -12131,7 +16200,7 @@ static void
dwarf2_const_value_attr (struct attribute *attr, struct type *type,
const char *name, struct obstack *obstack,
struct dwarf2_cu *cu,
- long *value, gdb_byte **bytes,
+ LONGEST *value, gdb_byte **bytes,
struct dwarf2_locexpr_baton **baton)
{
struct objfile *objfile = cu->objfile;
@@ -12147,6 +16216,7 @@ dwarf2_const_value_attr (struct attribute *attr, struct type *type,
switch (attr->form)
{
case DW_FORM_addr:
+ case DW_FORM_GNU_addr_index:
{
gdb_byte *data;
@@ -12174,6 +16244,8 @@ dwarf2_const_value_attr (struct attribute *attr, struct type *type,
break;
case DW_FORM_string:
case DW_FORM_strp:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_strp_alt:
/* DW_STRING is already allocated on the objfile obstack, point
directly to it. */
*bytes = (gdb_byte *) DW_STRING (attr);
@@ -12238,7 +16310,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
{
struct objfile *objfile = cu->objfile;
struct comp_unit_head *cu_header = &cu->header;
- long value;
+ LONGEST value;
gdb_byte *bytes;
struct dwarf2_locexpr_baton *baton;
@@ -12355,38 +16427,52 @@ static struct type *
lookup_die_type (struct die_info *die, struct attribute *attr,
struct dwarf2_cu *cu)
{
+ struct objfile *objfile = cu->objfile;
struct type *this_type;
/* First see if we have it cached. */
- if (is_ref_attr (attr))
+ if (attr->form == DW_FORM_GNU_ref_alt)
+ {
+ struct dwarf2_per_cu_data *per_cu;
+ sect_offset offset = dwarf2_get_ref_die_offset (attr);
+
+ per_cu = dwarf2_find_containing_comp_unit (offset, 1, cu->objfile);
+ this_type = get_die_type_at_offset (offset, per_cu);
+ }
+ else if (is_ref_attr (attr))
{
- unsigned int offset = dwarf2_get_ref_die_offset (attr);
+ sect_offset offset = dwarf2_get_ref_die_offset (attr);
this_type = get_die_type_at_offset (offset, cu->per_cu);
}
else if (attr->form == DW_FORM_ref_sig8)
{
struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr);
- struct dwarf2_cu *sig_cu;
- unsigned int offset;
/* sig_type will be NULL if the signatured type is missing from
the debug info. */
if (sig_type == NULL)
error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
"at 0x%x [in module %s]"),
- die->offset, cu->objfile->name);
+ die->offset.sect_off, objfile->name);
- gdb_assert (sig_type->per_cu.debug_types_section);
- offset = sig_type->per_cu.offset + sig_type->type_offset;
- this_type = get_die_type_at_offset (offset, &sig_type->per_cu);
+ gdb_assert (sig_type->per_cu.is_debug_types);
+ /* If we haven't filled in type_offset_in_section yet, then we
+ haven't read the type in yet. */
+ this_type = NULL;
+ if (sig_type->type_offset_in_section.sect_off != 0)
+ {
+ this_type =
+ get_die_type_at_offset (sig_type->type_offset_in_section,
+ &sig_type->per_cu);
+ }
}
else
{
dump_die_for_error (die);
error (_("Dwarf Error: Bad type attribute %s [in module %s]"),
- dwarf_attr_name (attr->name), cu->objfile->name);
+ dwarf_attr_name (attr->name), objfile->name);
}
/* If not cached we need to read it in. */
@@ -12397,9 +16483,12 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
struct dwarf2_cu *type_cu = cu;
type_die = follow_die_ref_or_sig (die, attr, &type_cu);
- /* If the type is cached, we should have found it above. */
- gdb_assert (get_die_type (type_die, type_cu) == NULL);
- this_type = read_type_die_1 (type_die, type_cu);
+ /* If we found the type now, it's probably because the type came
+ from an inter-CU reference and the type's CU got expanded before
+ ours. */
+ this_type = get_die_type (type_die, type_cu);
+ if (this_type == NULL)
+ this_type = read_type_die_1 (type_die, type_cu);
}
/* If we still don't have a type use an error marker. */
@@ -12410,14 +16499,14 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
/* read_type_die already issued a complaint. */
message = xstrprintf (_(""),
- cu->objfile->name,
- cu->header.offset,
- die->offset);
- saved = obstack_copy0 (&cu->objfile->objfile_obstack,
+ objfile->name,
+ cu->header.offset.sect_off,
+ die->offset.sect_off);
+ saved = obstack_copy0 (&objfile->objfile_obstack,
message, strlen (message));
xfree (message);
- this_type = init_type (TYPE_CODE_ERROR, 0, 0, saved, cu->objfile);
+ this_type = init_type (TYPE_CODE_ERROR, 0, 0, saved, objfile);
}
return this_type;
@@ -12488,6 +16577,9 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
case DW_TAG_volatile_type:
this_type = read_tag_volatile_type (die, cu);
break;
+ case DW_TAG_restrict_type:
+ this_type = read_tag_restrict_type (die, cu);
+ break;
case DW_TAG_string_type:
this_type = read_tag_string_type (die, cu);
break;
@@ -12562,7 +16654,7 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
if (actual_name != NULL)
{
- char *die_name = dwarf2_name (die, cu);
+ const char *die_name = dwarf2_name (die, cu);
if (die_name != NULL
&& strcmp (die_name, actual_name) != 0)
@@ -12577,9 +16669,9 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
&& actual_name[actual_name_len
- die_name_len - 1] == ':')
name =
- obsavestring (actual_name,
- actual_name_len - die_name_len - 2,
- &cu->objfile->objfile_obstack);
+ obstack_copy0 (&cu->objfile->objfile_obstack,
+ actual_name,
+ actual_name_len - die_name_len - 2);
}
}
xfree (actual_name);
@@ -12623,8 +16715,8 @@ anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
if (base == NULL || base == DW_STRING (attr) || base[-1] != ':')
return "";
- return obsavestring (DW_STRING (attr), &base[-1] - DW_STRING (attr),
- &cu->objfile->objfile_obstack);
+ return obstack_copy0 (&cu->objfile->objfile_obstack,
+ DW_STRING (attr), &base[-1] - DW_STRING (attr));
}
/* Return the name of the namespace/class that DIE is defined within,
@@ -12642,7 +16734,7 @@ anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
then determine_prefix on foo's die will return "N::C". */
-static char *
+static const char *
determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
{
struct die_info *parent, *spec_die;
@@ -12759,6 +16851,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
So it does not need a prefix. */
return "";
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
/* gcc-4.5 -gdwarf-4 can drop the enclosing namespace. Cope. */
if (cu->language == language_cplus
&& !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)
@@ -12841,8 +16934,8 @@ sibling_die (struct die_info *die)
/* Get name of a die, return NULL if not found. */
-static char *
-dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu,
+static const char *
+dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
struct obstack *obstack)
{
if (name && cu->language == language_cplus)
@@ -12852,8 +16945,7 @@ dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu,
if (canon_name != NULL)
{
if (strcmp (canon_name, name) != 0)
- name = obsavestring (canon_name, strlen (canon_name),
- obstack);
+ name = obstack_copy0 (obstack, canon_name, strlen (canon_name));
xfree (canon_name);
}
}
@@ -12863,7 +16955,7 @@ dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu,
/* Get name of a die, return NULL if not found. */
-static char *
+static const char *
dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
@@ -12879,6 +16971,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
switch (die->tag)
{
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
/* Compilation units have a DW_AT_name that is a filename, not
a source language identifier. */
case DW_TAG_enumeration_type:
@@ -12912,7 +17005,8 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
if (die->tag == DW_TAG_class_type)
return dwarf2_name (die, cu);
}
- while (die->tag != DW_TAG_compile_unit);
+ while (die->tag != DW_TAG_compile_unit
+ && die->tag != DW_TAG_partial_unit);
}
break;
@@ -12952,8 +17046,8 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
char *base;
/* FIXME: we already did this for the partial symbol... */
- DW_STRING (attr) = obsavestring (demangled, strlen (demangled),
- &cu->objfile->objfile_obstack);
+ DW_STRING (attr) = obstack_copy0 (&cu->objfile->objfile_obstack,
+ demangled, strlen (demangled));
DW_STRING_IS_CANONICAL (attr) = 1;
xfree (demangled);
@@ -13000,843 +17094,51 @@ dwarf2_extension (struct die_info *die, struct dwarf2_cu **ext_cu)
/* Convert a DIE tag into its string name. */
-static char *
+static const char *
dwarf_tag_name (unsigned tag)
{
- switch (tag)
- {
- case DW_TAG_padding:
- return "DW_TAG_padding";
- case DW_TAG_array_type:
- return "DW_TAG_array_type";
- case DW_TAG_class_type:
- return "DW_TAG_class_type";
- case DW_TAG_entry_point:
- return "DW_TAG_entry_point";
- case DW_TAG_enumeration_type:
- return "DW_TAG_enumeration_type";
- case DW_TAG_formal_parameter:
- return "DW_TAG_formal_parameter";
- case DW_TAG_imported_declaration:
- return "DW_TAG_imported_declaration";
- case DW_TAG_label:
- return "DW_TAG_label";
- case DW_TAG_lexical_block:
- return "DW_TAG_lexical_block";
- case DW_TAG_member:
- return "DW_TAG_member";
- case DW_TAG_pointer_type:
- return "DW_TAG_pointer_type";
- case DW_TAG_reference_type:
- return "DW_TAG_reference_type";
- case DW_TAG_compile_unit:
- return "DW_TAG_compile_unit";
- case DW_TAG_string_type:
- return "DW_TAG_string_type";
- case DW_TAG_structure_type:
- return "DW_TAG_structure_type";
- case DW_TAG_subroutine_type:
- return "DW_TAG_subroutine_type";
- case DW_TAG_typedef:
- return "DW_TAG_typedef";
- case DW_TAG_union_type:
- return "DW_TAG_union_type";
- case DW_TAG_unspecified_parameters:
- return "DW_TAG_unspecified_parameters";
- case DW_TAG_variant:
- return "DW_TAG_variant";
- case DW_TAG_common_block:
- return "DW_TAG_common_block";
- case DW_TAG_common_inclusion:
- return "DW_TAG_common_inclusion";
- case DW_TAG_inheritance:
- return "DW_TAG_inheritance";
- case DW_TAG_inlined_subroutine:
- return "DW_TAG_inlined_subroutine";
- case DW_TAG_module:
- return "DW_TAG_module";
- case DW_TAG_ptr_to_member_type:
- return "DW_TAG_ptr_to_member_type";
- case DW_TAG_set_type:
- return "DW_TAG_set_type";
- case DW_TAG_subrange_type:
- return "DW_TAG_subrange_type";
- case DW_TAG_with_stmt:
- return "DW_TAG_with_stmt";
- case DW_TAG_access_declaration:
- return "DW_TAG_access_declaration";
- case DW_TAG_base_type:
- return "DW_TAG_base_type";
- case DW_TAG_catch_block:
- return "DW_TAG_catch_block";
- case DW_TAG_const_type:
- return "DW_TAG_const_type";
- case DW_TAG_constant:
- return "DW_TAG_constant";
- case DW_TAG_enumerator:
- return "DW_TAG_enumerator";
- case DW_TAG_file_type:
- return "DW_TAG_file_type";
- case DW_TAG_friend:
- return "DW_TAG_friend";
- case DW_TAG_namelist:
- return "DW_TAG_namelist";
- case DW_TAG_namelist_item:
- return "DW_TAG_namelist_item";
- case DW_TAG_packed_type:
- return "DW_TAG_packed_type";
- case DW_TAG_subprogram:
- return "DW_TAG_subprogram";
- case DW_TAG_template_type_param:
- return "DW_TAG_template_type_param";
- case DW_TAG_template_value_param:
- return "DW_TAG_template_value_param";
- case DW_TAG_thrown_type:
- return "DW_TAG_thrown_type";
- case DW_TAG_try_block:
- return "DW_TAG_try_block";
- case DW_TAG_variant_part:
- return "DW_TAG_variant_part";
- case DW_TAG_variable:
- return "DW_TAG_variable";
- case DW_TAG_volatile_type:
- return "DW_TAG_volatile_type";
- case DW_TAG_dwarf_procedure:
- return "DW_TAG_dwarf_procedure";
- case DW_TAG_restrict_type:
- return "DW_TAG_restrict_type";
- case DW_TAG_interface_type:
- return "DW_TAG_interface_type";
- case DW_TAG_namespace:
- return "DW_TAG_namespace";
- case DW_TAG_imported_module:
- return "DW_TAG_imported_module";
- case DW_TAG_unspecified_type:
- return "DW_TAG_unspecified_type";
- case DW_TAG_partial_unit:
- return "DW_TAG_partial_unit";
- case DW_TAG_imported_unit:
- return "DW_TAG_imported_unit";
- case DW_TAG_condition:
- return "DW_TAG_condition";
- case DW_TAG_shared_type:
- return "DW_TAG_shared_type";
- case DW_TAG_type_unit:
- return "DW_TAG_type_unit";
- case DW_TAG_MIPS_loop:
- return "DW_TAG_MIPS_loop";
- case DW_TAG_HP_array_descriptor:
- return "DW_TAG_HP_array_descriptor";
- case DW_TAG_format_label:
- return "DW_TAG_format_label";
- case DW_TAG_function_template:
- return "DW_TAG_function_template";
- case DW_TAG_class_template:
- return "DW_TAG_class_template";
- case DW_TAG_GNU_BINCL:
- return "DW_TAG_GNU_BINCL";
- case DW_TAG_GNU_EINCL:
- return "DW_TAG_GNU_EINCL";
- case DW_TAG_upc_shared_type:
- return "DW_TAG_upc_shared_type";
- case DW_TAG_upc_strict_type:
- return "DW_TAG_upc_strict_type";
- case DW_TAG_upc_relaxed_type:
- return "DW_TAG_upc_relaxed_type";
- case DW_TAG_PGI_kanji_type:
- return "DW_TAG_PGI_kanji_type";
- case DW_TAG_PGI_interface_block:
- return "DW_TAG_PGI_interface_block";
- case DW_TAG_GNU_call_site:
- return "DW_TAG_GNU_call_site";
- default:
- return "DW_TAG_";
- }
+ const char *name = get_DW_TAG_name (tag);
+
+ if (name == NULL)
+ return "DW_TAG_";
+
+ return name;
}
/* Convert a DWARF attribute code into its string name. */
-static char *
+static const char *
dwarf_attr_name (unsigned attr)
{
- switch (attr)
- {
- case DW_AT_sibling:
- return "DW_AT_sibling";
- case DW_AT_location:
- return "DW_AT_location";
- case DW_AT_name:
- return "DW_AT_name";
- case DW_AT_ordering:
- return "DW_AT_ordering";
- case DW_AT_subscr_data:
- return "DW_AT_subscr_data";
- case DW_AT_byte_size:
- return "DW_AT_byte_size";
- case DW_AT_bit_offset:
- return "DW_AT_bit_offset";
- case DW_AT_bit_size:
- return "DW_AT_bit_size";
- case DW_AT_element_list:
- return "DW_AT_element_list";
- case DW_AT_stmt_list:
- return "DW_AT_stmt_list";
- case DW_AT_low_pc:
- return "DW_AT_low_pc";
- case DW_AT_high_pc:
- return "DW_AT_high_pc";
- case DW_AT_language:
- return "DW_AT_language";
- case DW_AT_member:
- return "DW_AT_member";
- case DW_AT_discr:
- return "DW_AT_discr";
- case DW_AT_discr_value:
- return "DW_AT_discr_value";
- case DW_AT_visibility:
- return "DW_AT_visibility";
- case DW_AT_import:
- return "DW_AT_import";
- case DW_AT_string_length:
- return "DW_AT_string_length";
- case DW_AT_common_reference:
- return "DW_AT_common_reference";
- case DW_AT_comp_dir:
- return "DW_AT_comp_dir";
- case DW_AT_const_value:
- return "DW_AT_const_value";
- case DW_AT_containing_type:
- return "DW_AT_containing_type";
- case DW_AT_default_value:
- return "DW_AT_default_value";
- case DW_AT_inline:
- return "DW_AT_inline";
- case DW_AT_is_optional:
- return "DW_AT_is_optional";
- case DW_AT_lower_bound:
- return "DW_AT_lower_bound";
- case DW_AT_producer:
- return "DW_AT_producer";
- case DW_AT_prototyped:
- return "DW_AT_prototyped";
- case DW_AT_return_addr:
- return "DW_AT_return_addr";
- case DW_AT_start_scope:
- return "DW_AT_start_scope";
- case DW_AT_bit_stride:
- return "DW_AT_bit_stride";
- case DW_AT_upper_bound:
- return "DW_AT_upper_bound";
- case DW_AT_abstract_origin:
- return "DW_AT_abstract_origin";
- case DW_AT_accessibility:
- return "DW_AT_accessibility";
- case DW_AT_address_class:
- return "DW_AT_address_class";
- case DW_AT_artificial:
- return "DW_AT_artificial";
- case DW_AT_base_types:
- return "DW_AT_base_types";
- case DW_AT_calling_convention:
- return "DW_AT_calling_convention";
- case DW_AT_count:
- return "DW_AT_count";
- case DW_AT_data_member_location:
- return "DW_AT_data_member_location";
- case DW_AT_decl_column:
- return "DW_AT_decl_column";
- case DW_AT_decl_file:
- return "DW_AT_decl_file";
- case DW_AT_decl_line:
- return "DW_AT_decl_line";
- case DW_AT_declaration:
- return "DW_AT_declaration";
- case DW_AT_discr_list:
- return "DW_AT_discr_list";
- case DW_AT_encoding:
- return "DW_AT_encoding";
- case DW_AT_external:
- return "DW_AT_external";
- case DW_AT_frame_base:
- return "DW_AT_frame_base";
- case DW_AT_friend:
- return "DW_AT_friend";
- case DW_AT_identifier_case:
- return "DW_AT_identifier_case";
- case DW_AT_macro_info:
- return "DW_AT_macro_info";
- case DW_AT_namelist_items:
- return "DW_AT_namelist_items";
- case DW_AT_priority:
- return "DW_AT_priority";
- case DW_AT_segment:
- return "DW_AT_segment";
- case DW_AT_specification:
- return "DW_AT_specification";
- case DW_AT_static_link:
- return "DW_AT_static_link";
- case DW_AT_type:
- return "DW_AT_type";
- case DW_AT_use_location:
- return "DW_AT_use_location";
- case DW_AT_variable_parameter:
- return "DW_AT_variable_parameter";
- case DW_AT_virtuality:
- return "DW_AT_virtuality";
- case DW_AT_vtable_elem_location:
- return "DW_AT_vtable_elem_location";
- /* DWARF 3 values. */
- case DW_AT_allocated:
- return "DW_AT_allocated";
- case DW_AT_associated:
- return "DW_AT_associated";
- case DW_AT_data_location:
- return "DW_AT_data_location";
- case DW_AT_byte_stride:
- return "DW_AT_byte_stride";
- case DW_AT_entry_pc:
- return "DW_AT_entry_pc";
- case DW_AT_use_UTF8:
- return "DW_AT_use_UTF8";
- case DW_AT_extension:
- return "DW_AT_extension";
- case DW_AT_ranges:
- return "DW_AT_ranges";
- case DW_AT_trampoline:
- return "DW_AT_trampoline";
- case DW_AT_call_column:
- return "DW_AT_call_column";
- case DW_AT_call_file:
- return "DW_AT_call_file";
- case DW_AT_call_line:
- return "DW_AT_call_line";
- case DW_AT_description:
- return "DW_AT_description";
- case DW_AT_binary_scale:
- return "DW_AT_binary_scale";
- case DW_AT_decimal_scale:
- return "DW_AT_decimal_scale";
- case DW_AT_small:
- return "DW_AT_small";
- case DW_AT_decimal_sign:
- return "DW_AT_decimal_sign";
- case DW_AT_digit_count:
- return "DW_AT_digit_count";
- case DW_AT_picture_string:
- return "DW_AT_picture_string";
- case DW_AT_mutable:
- return "DW_AT_mutable";
- case DW_AT_threads_scaled:
- return "DW_AT_threads_scaled";
- case DW_AT_explicit:
- return "DW_AT_explicit";
- case DW_AT_object_pointer:
- return "DW_AT_object_pointer";
- case DW_AT_endianity:
- return "DW_AT_endianity";
- case DW_AT_elemental:
- return "DW_AT_elemental";
- case DW_AT_pure:
- return "DW_AT_pure";
- case DW_AT_recursive:
- return "DW_AT_recursive";
- /* DWARF 4 values. */
- case DW_AT_signature:
- return "DW_AT_signature";
- case DW_AT_linkage_name:
- return "DW_AT_linkage_name";
- /* SGI/MIPS extensions. */
+ const char *name;
+
#ifdef MIPS /* collides with DW_AT_HP_block_index */
- case DW_AT_MIPS_fde:
- return "DW_AT_MIPS_fde";
-#endif
- case DW_AT_MIPS_loop_begin:
- return "DW_AT_MIPS_loop_begin";
- case DW_AT_MIPS_tail_loop_begin:
- return "DW_AT_MIPS_tail_loop_begin";
- case DW_AT_MIPS_epilog_begin:
- return "DW_AT_MIPS_epilog_begin";
- case DW_AT_MIPS_loop_unroll_factor:
- return "DW_AT_MIPS_loop_unroll_factor";
- case DW_AT_MIPS_software_pipeline_depth:
- return "DW_AT_MIPS_software_pipeline_depth";
- case DW_AT_MIPS_linkage_name:
- return "DW_AT_MIPS_linkage_name";
- case DW_AT_MIPS_stride:
- return "DW_AT_MIPS_stride";
- case DW_AT_MIPS_abstract_name:
- return "DW_AT_MIPS_abstract_name";
- case DW_AT_MIPS_clone_origin:
- return "DW_AT_MIPS_clone_origin";
- case DW_AT_MIPS_has_inlines:
- return "DW_AT_MIPS_has_inlines";
- /* HP extensions. */
-#ifndef MIPS /* collides with DW_AT_MIPS_fde */
- case DW_AT_HP_block_index:
- return "DW_AT_HP_block_index";
+ if (attr == DW_AT_MIPS_fde)
+ return "DW_AT_MIPS_fde";
+#else
+ if (attr == DW_AT_HP_block_index)
+ return "DW_AT_HP_block_index";
#endif
- case DW_AT_HP_unmodifiable:
- return "DW_AT_HP_unmodifiable";
- case DW_AT_HP_actuals_stmt_list:
- return "DW_AT_HP_actuals_stmt_list";
- case DW_AT_HP_proc_per_section:
- return "DW_AT_HP_proc_per_section";
- case DW_AT_HP_raw_data_ptr:
- return "DW_AT_HP_raw_data_ptr";
- case DW_AT_HP_pass_by_reference:
- return "DW_AT_HP_pass_by_reference";
- case DW_AT_HP_opt_level:
- return "DW_AT_HP_opt_level";
- case DW_AT_HP_prof_version_id:
- return "DW_AT_HP_prof_version_id";
- case DW_AT_HP_opt_flags:
- return "DW_AT_HP_opt_flags";
- case DW_AT_HP_cold_region_low_pc:
- return "DW_AT_HP_cold_region_low_pc";
- case DW_AT_HP_cold_region_high_pc:
- return "DW_AT_HP_cold_region_high_pc";
- case DW_AT_HP_all_variables_modifiable:
- return "DW_AT_HP_all_variables_modifiable";
- case DW_AT_HP_linkage_name:
- return "DW_AT_HP_linkage_name";
- case DW_AT_HP_prof_flags:
- return "DW_AT_HP_prof_flags";
- /* GNU extensions. */
- case DW_AT_sf_names:
- return "DW_AT_sf_names";
- case DW_AT_src_info:
- return "DW_AT_src_info";
- case DW_AT_mac_info:
- return "DW_AT_mac_info";
- case DW_AT_src_coords:
- return "DW_AT_src_coords";
- case DW_AT_body_begin:
- return "DW_AT_body_begin";
- case DW_AT_body_end:
- return "DW_AT_body_end";
- case DW_AT_GNU_vector:
- return "DW_AT_GNU_vector";
- case DW_AT_GNU_odr_signature:
- return "DW_AT_GNU_odr_signature";
- /* VMS extensions. */
- case DW_AT_VMS_rtnbeg_pd_address:
- return "DW_AT_VMS_rtnbeg_pd_address";
- /* UPC extension. */
- case DW_AT_upc_threads_scaled:
- return "DW_AT_upc_threads_scaled";
- /* PGI (STMicroelectronics) extensions. */
- case DW_AT_PGI_lbase:
- return "DW_AT_PGI_lbase";
- case DW_AT_PGI_soffset:
- return "DW_AT_PGI_soffset";
- case DW_AT_PGI_lstride:
- return "DW_AT_PGI_lstride";
- default:
- return "DW_AT_";
- }
+
+ name = get_DW_AT_name (attr);
+
+ if (name == NULL)
+ return "DW_AT_";
+
+ return name;
}
/* Convert a DWARF value form code into its string name. */
-static char *
+static const char *
dwarf_form_name (unsigned form)
{
- switch (form)
- {
- case DW_FORM_addr:
- return "DW_FORM_addr";
- case DW_FORM_block2:
- return "DW_FORM_block2";
- case DW_FORM_block4:
- return "DW_FORM_block4";
- case DW_FORM_data2:
- return "DW_FORM_data2";
- case DW_FORM_data4:
- return "DW_FORM_data4";
- case DW_FORM_data8:
- return "DW_FORM_data8";
- case DW_FORM_string:
- return "DW_FORM_string";
- case DW_FORM_block:
- return "DW_FORM_block";
- case DW_FORM_block1:
- return "DW_FORM_block1";
- case DW_FORM_data1:
- return "DW_FORM_data1";
- case DW_FORM_flag:
- return "DW_FORM_flag";
- case DW_FORM_sdata:
- return "DW_FORM_sdata";
- case DW_FORM_strp:
- return "DW_FORM_strp";
- case DW_FORM_udata:
- return "DW_FORM_udata";
- case DW_FORM_ref_addr:
- return "DW_FORM_ref_addr";
- case DW_FORM_ref1:
- return "DW_FORM_ref1";
- case DW_FORM_ref2:
- return "DW_FORM_ref2";
- case DW_FORM_ref4:
- return "DW_FORM_ref4";
- case DW_FORM_ref8:
- return "DW_FORM_ref8";
- case DW_FORM_ref_udata:
- return "DW_FORM_ref_udata";
- case DW_FORM_indirect:
- return "DW_FORM_indirect";
- case DW_FORM_sec_offset:
- return "DW_FORM_sec_offset";
- case DW_FORM_exprloc:
- return "DW_FORM_exprloc";
- case DW_FORM_flag_present:
- return "DW_FORM_flag_present";
- case DW_FORM_ref_sig8:
- return "DW_FORM_ref_sig8";
- default:
- return "DW_FORM_";
- }
-}
-
-/* Convert a DWARF stack opcode into its string name. */
-
-const char *
-dwarf_stack_op_name (unsigned op)
-{
- switch (op)
- {
- case DW_OP_addr:
- return "DW_OP_addr";
- case DW_OP_deref:
- return "DW_OP_deref";
- case DW_OP_const1u:
- return "DW_OP_const1u";
- case DW_OP_const1s:
- return "DW_OP_const1s";
- case DW_OP_const2u:
- return "DW_OP_const2u";
- case DW_OP_const2s:
- return "DW_OP_const2s";
- case DW_OP_const4u:
- return "DW_OP_const4u";
- case DW_OP_const4s:
- return "DW_OP_const4s";
- case DW_OP_const8u:
- return "DW_OP_const8u";
- case DW_OP_const8s:
- return "DW_OP_const8s";
- case DW_OP_constu:
- return "DW_OP_constu";
- case DW_OP_consts:
- return "DW_OP_consts";
- case DW_OP_dup:
- return "DW_OP_dup";
- case DW_OP_drop:
- return "DW_OP_drop";
- case DW_OP_over:
- return "DW_OP_over";
- case DW_OP_pick:
- return "DW_OP_pick";
- case DW_OP_swap:
- return "DW_OP_swap";
- case DW_OP_rot:
- return "DW_OP_rot";
- case DW_OP_xderef:
- return "DW_OP_xderef";
- case DW_OP_abs:
- return "DW_OP_abs";
- case DW_OP_and:
- return "DW_OP_and";
- case DW_OP_div:
- return "DW_OP_div";
- case DW_OP_minus:
- return "DW_OP_minus";
- case DW_OP_mod:
- return "DW_OP_mod";
- case DW_OP_mul:
- return "DW_OP_mul";
- case DW_OP_neg:
- return "DW_OP_neg";
- case DW_OP_not:
- return "DW_OP_not";
- case DW_OP_or:
- return "DW_OP_or";
- case DW_OP_plus:
- return "DW_OP_plus";
- case DW_OP_plus_uconst:
- return "DW_OP_plus_uconst";
- case DW_OP_shl:
- return "DW_OP_shl";
- case DW_OP_shr:
- return "DW_OP_shr";
- case DW_OP_shra:
- return "DW_OP_shra";
- case DW_OP_xor:
- return "DW_OP_xor";
- case DW_OP_bra:
- return "DW_OP_bra";
- case DW_OP_eq:
- return "DW_OP_eq";
- case DW_OP_ge:
- return "DW_OP_ge";
- case DW_OP_gt:
- return "DW_OP_gt";
- case DW_OP_le:
- return "DW_OP_le";
- case DW_OP_lt:
- return "DW_OP_lt";
- case DW_OP_ne:
- return "DW_OP_ne";
- case DW_OP_skip:
- return "DW_OP_skip";
- case DW_OP_lit0:
- return "DW_OP_lit0";
- case DW_OP_lit1:
- return "DW_OP_lit1";
- case DW_OP_lit2:
- return "DW_OP_lit2";
- case DW_OP_lit3:
- return "DW_OP_lit3";
- case DW_OP_lit4:
- return "DW_OP_lit4";
- case DW_OP_lit5:
- return "DW_OP_lit5";
- case DW_OP_lit6:
- return "DW_OP_lit6";
- case DW_OP_lit7:
- return "DW_OP_lit7";
- case DW_OP_lit8:
- return "DW_OP_lit8";
- case DW_OP_lit9:
- return "DW_OP_lit9";
- case DW_OP_lit10:
- return "DW_OP_lit10";
- case DW_OP_lit11:
- return "DW_OP_lit11";
- case DW_OP_lit12:
- return "DW_OP_lit12";
- case DW_OP_lit13:
- return "DW_OP_lit13";
- case DW_OP_lit14:
- return "DW_OP_lit14";
- case DW_OP_lit15:
- return "DW_OP_lit15";
- case DW_OP_lit16:
- return "DW_OP_lit16";
- case DW_OP_lit17:
- return "DW_OP_lit17";
- case DW_OP_lit18:
- return "DW_OP_lit18";
- case DW_OP_lit19:
- return "DW_OP_lit19";
- case DW_OP_lit20:
- return "DW_OP_lit20";
- case DW_OP_lit21:
- return "DW_OP_lit21";
- case DW_OP_lit22:
- return "DW_OP_lit22";
- case DW_OP_lit23:
- return "DW_OP_lit23";
- case DW_OP_lit24:
- return "DW_OP_lit24";
- case DW_OP_lit25:
- return "DW_OP_lit25";
- case DW_OP_lit26:
- return "DW_OP_lit26";
- case DW_OP_lit27:
- return "DW_OP_lit27";
- case DW_OP_lit28:
- return "DW_OP_lit28";
- case DW_OP_lit29:
- return "DW_OP_lit29";
- case DW_OP_lit30:
- return "DW_OP_lit30";
- case DW_OP_lit31:
- return "DW_OP_lit31";
- case DW_OP_reg0:
- return "DW_OP_reg0";
- case DW_OP_reg1:
- return "DW_OP_reg1";
- case DW_OP_reg2:
- return "DW_OP_reg2";
- case DW_OP_reg3:
- return "DW_OP_reg3";
- case DW_OP_reg4:
- return "DW_OP_reg4";
- case DW_OP_reg5:
- return "DW_OP_reg5";
- case DW_OP_reg6:
- return "DW_OP_reg6";
- case DW_OP_reg7:
- return "DW_OP_reg7";
- case DW_OP_reg8:
- return "DW_OP_reg8";
- case DW_OP_reg9:
- return "DW_OP_reg9";
- case DW_OP_reg10:
- return "DW_OP_reg10";
- case DW_OP_reg11:
- return "DW_OP_reg11";
- case DW_OP_reg12:
- return "DW_OP_reg12";
- case DW_OP_reg13:
- return "DW_OP_reg13";
- case DW_OP_reg14:
- return "DW_OP_reg14";
- case DW_OP_reg15:
- return "DW_OP_reg15";
- case DW_OP_reg16:
- return "DW_OP_reg16";
- case DW_OP_reg17:
- return "DW_OP_reg17";
- case DW_OP_reg18:
- return "DW_OP_reg18";
- case DW_OP_reg19:
- return "DW_OP_reg19";
- case DW_OP_reg20:
- return "DW_OP_reg20";
- case DW_OP_reg21:
- return "DW_OP_reg21";
- case DW_OP_reg22:
- return "DW_OP_reg22";
- case DW_OP_reg23:
- return "DW_OP_reg23";
- case DW_OP_reg24:
- return "DW_OP_reg24";
- case DW_OP_reg25:
- return "DW_OP_reg25";
- case DW_OP_reg26:
- return "DW_OP_reg26";
- case DW_OP_reg27:
- return "DW_OP_reg27";
- case DW_OP_reg28:
- return "DW_OP_reg28";
- case DW_OP_reg29:
- return "DW_OP_reg29";
- case DW_OP_reg30:
- return "DW_OP_reg30";
- case DW_OP_reg31:
- return "DW_OP_reg31";
- case DW_OP_breg0:
- return "DW_OP_breg0";
- case DW_OP_breg1:
- return "DW_OP_breg1";
- case DW_OP_breg2:
- return "DW_OP_breg2";
- case DW_OP_breg3:
- return "DW_OP_breg3";
- case DW_OP_breg4:
- return "DW_OP_breg4";
- case DW_OP_breg5:
- return "DW_OP_breg5";
- case DW_OP_breg6:
- return "DW_OP_breg6";
- case DW_OP_breg7:
- return "DW_OP_breg7";
- case DW_OP_breg8:
- return "DW_OP_breg8";
- case DW_OP_breg9:
- return "DW_OP_breg9";
- case DW_OP_breg10:
- return "DW_OP_breg10";
- case DW_OP_breg11:
- return "DW_OP_breg11";
- case DW_OP_breg12:
- return "DW_OP_breg12";
- case DW_OP_breg13:
- return "DW_OP_breg13";
- case DW_OP_breg14:
- return "DW_OP_breg14";
- case DW_OP_breg15:
- return "DW_OP_breg15";
- case DW_OP_breg16:
- return "DW_OP_breg16";
- case DW_OP_breg17:
- return "DW_OP_breg17";
- case DW_OP_breg18:
- return "DW_OP_breg18";
- case DW_OP_breg19:
- return "DW_OP_breg19";
- case DW_OP_breg20:
- return "DW_OP_breg20";
- case DW_OP_breg21:
- return "DW_OP_breg21";
- case DW_OP_breg22:
- return "DW_OP_breg22";
- case DW_OP_breg23:
- return "DW_OP_breg23";
- case DW_OP_breg24:
- return "DW_OP_breg24";
- case DW_OP_breg25:
- return "DW_OP_breg25";
- case DW_OP_breg26:
- return "DW_OP_breg26";
- case DW_OP_breg27:
- return "DW_OP_breg27";
- case DW_OP_breg28:
- return "DW_OP_breg28";
- case DW_OP_breg29:
- return "DW_OP_breg29";
- case DW_OP_breg30:
- return "DW_OP_breg30";
- case DW_OP_breg31:
- return "DW_OP_breg31";
- case DW_OP_regx:
- return "DW_OP_regx";
- case DW_OP_fbreg:
- return "DW_OP_fbreg";
- case DW_OP_bregx:
- return "DW_OP_bregx";
- case DW_OP_piece:
- return "DW_OP_piece";
- case DW_OP_deref_size:
- return "DW_OP_deref_size";
- case DW_OP_xderef_size:
- return "DW_OP_xderef_size";
- case DW_OP_nop:
- return "DW_OP_nop";
- /* DWARF 3 extensions. */
- case DW_OP_push_object_address:
- return "DW_OP_push_object_address";
- case DW_OP_call2:
- return "DW_OP_call2";
- case DW_OP_call4:
- return "DW_OP_call4";
- case DW_OP_call_ref:
- return "DW_OP_call_ref";
- case DW_OP_form_tls_address:
- return "DW_OP_form_tls_address";
- case DW_OP_call_frame_cfa:
- return "DW_OP_call_frame_cfa";
- case DW_OP_bit_piece:
- return "DW_OP_bit_piece";
- /* DWARF 4 extensions. */
- case DW_OP_implicit_value:
- return "DW_OP_implicit_value";
- case DW_OP_stack_value:
- return "DW_OP_stack_value";
- /* GNU extensions. */
- case DW_OP_GNU_push_tls_address:
- return "DW_OP_GNU_push_tls_address";
- case DW_OP_GNU_uninit:
- return "DW_OP_GNU_uninit";
- case DW_OP_GNU_implicit_pointer:
- return "DW_OP_GNU_implicit_pointer";
- case DW_OP_GNU_entry_value:
- return "DW_OP_GNU_entry_value";
- case DW_OP_GNU_const_type:
- return "DW_OP_GNU_const_type";
- case DW_OP_GNU_regval_type:
- return "DW_OP_GNU_regval_type";
- case DW_OP_GNU_deref_type:
- return "DW_OP_GNU_deref_type";
- case DW_OP_GNU_convert:
- return "DW_OP_GNU_convert";
- case DW_OP_GNU_reinterpret:
- return "DW_OP_GNU_reinterpret";
- default:
- return NULL;
- }
+ const char *name = get_DW_FORM_name (form);
+
+ if (name == NULL)
+ return "DW_FORM_";
+
+ return name;
}
static char *
@@ -13850,143 +17152,16 @@ dwarf_bool_name (unsigned mybool)
/* Convert a DWARF type code into its string name. */
-static char *
+static const char *
dwarf_type_encoding_name (unsigned enc)
{
- switch (enc)
- {
- case DW_ATE_void:
- return "DW_ATE_void";
- case DW_ATE_address:
- return "DW_ATE_address";
- case DW_ATE_boolean:
- return "DW_ATE_boolean";
- case DW_ATE_complex_float:
- return "DW_ATE_complex_float";
- case DW_ATE_float:
- return "DW_ATE_float";
- case DW_ATE_signed:
- return "DW_ATE_signed";
- case DW_ATE_signed_char:
- return "DW_ATE_signed_char";
- case DW_ATE_unsigned:
- return "DW_ATE_unsigned";
- case DW_ATE_unsigned_char:
- return "DW_ATE_unsigned_char";
- /* DWARF 3. */
- case DW_ATE_imaginary_float:
- return "DW_ATE_imaginary_float";
- case DW_ATE_packed_decimal:
- return "DW_ATE_packed_decimal";
- case DW_ATE_numeric_string:
- return "DW_ATE_numeric_string";
- case DW_ATE_edited:
- return "DW_ATE_edited";
- case DW_ATE_signed_fixed:
- return "DW_ATE_signed_fixed";
- case DW_ATE_unsigned_fixed:
- return "DW_ATE_unsigned_fixed";
- case DW_ATE_decimal_float:
- return "DW_ATE_decimal_float";
- /* DWARF 4. */
- case DW_ATE_UTF:
- return "DW_ATE_UTF";
- /* HP extensions. */
- case DW_ATE_HP_float80:
- return "DW_ATE_HP_float80";
- case DW_ATE_HP_complex_float80:
- return "DW_ATE_HP_complex_float80";
- case DW_ATE_HP_float128:
- return "DW_ATE_HP_float128";
- case DW_ATE_HP_complex_float128:
- return "DW_ATE_HP_complex_float128";
- case DW_ATE_HP_floathpintel:
- return "DW_ATE_HP_floathpintel";
- case DW_ATE_HP_imaginary_float80:
- return "DW_ATE_HP_imaginary_float80";
- case DW_ATE_HP_imaginary_float128:
- return "DW_ATE_HP_imaginary_float128";
- default:
- return "DW_ATE_";
- }
-}
+ const char *name = get_DW_ATE_name (enc);
-/* Convert a DWARF call frame info operation to its string name. */
+ if (name == NULL)
+ return "DW_ATE_";
-#if 0
-static char *
-dwarf_cfi_name (unsigned cfi_opc)
-{
- switch (cfi_opc)
- {
- case DW_CFA_advance_loc:
- return "DW_CFA_advance_loc";
- case DW_CFA_offset:
- return "DW_CFA_offset";
- case DW_CFA_restore:
- return "DW_CFA_restore";
- case DW_CFA_nop:
- return "DW_CFA_nop";
- case DW_CFA_set_loc:
- return "DW_CFA_set_loc";
- case DW_CFA_advance_loc1:
- return "DW_CFA_advance_loc1";
- case DW_CFA_advance_loc2:
- return "DW_CFA_advance_loc2";
- case DW_CFA_advance_loc4:
- return "DW_CFA_advance_loc4";
- case DW_CFA_offset_extended:
- return "DW_CFA_offset_extended";
- case DW_CFA_restore_extended:
- return "DW_CFA_restore_extended";
- case DW_CFA_undefined:
- return "DW_CFA_undefined";
- case DW_CFA_same_value:
- return "DW_CFA_same_value";
- case DW_CFA_register:
- return "DW_CFA_register";
- case DW_CFA_remember_state:
- return "DW_CFA_remember_state";
- case DW_CFA_restore_state:
- return "DW_CFA_restore_state";
- case DW_CFA_def_cfa:
- return "DW_CFA_def_cfa";
- case DW_CFA_def_cfa_register:
- return "DW_CFA_def_cfa_register";
- case DW_CFA_def_cfa_offset:
- return "DW_CFA_def_cfa_offset";
- /* DWARF 3. */
- case DW_CFA_def_cfa_expression:
- return "DW_CFA_def_cfa_expression";
- case DW_CFA_expression:
- return "DW_CFA_expression";
- case DW_CFA_offset_extended_sf:
- return "DW_CFA_offset_extended_sf";
- case DW_CFA_def_cfa_sf:
- return "DW_CFA_def_cfa_sf";
- case DW_CFA_def_cfa_offset_sf:
- return "DW_CFA_def_cfa_offset_sf";
- case DW_CFA_val_offset:
- return "DW_CFA_val_offset";
- case DW_CFA_val_offset_sf:
- return "DW_CFA_val_offset_sf";
- case DW_CFA_val_expression:
- return "DW_CFA_val_expression";
- /* SGI/MIPS specific. */
- case DW_CFA_MIPS_advance_loc8:
- return "DW_CFA_MIPS_advance_loc8";
- /* GNU extensions. */
- case DW_CFA_GNU_window_save:
- return "DW_CFA_GNU_window_save";
- case DW_CFA_GNU_args_size:
- return "DW_CFA_GNU_args_size";
- case DW_CFA_GNU_negative_offset_extended:
- return "DW_CFA_GNU_negative_offset_extended";
- default:
- return "DW_CFA_";
- }
+ return name;
}
-#endif
static void
dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
@@ -13995,13 +17170,13 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
print_spaces (indent, f);
fprintf_unfiltered (f, "Die: %s (abbrev %d, offset 0x%x)\n",
- dwarf_tag_name (die->tag), die->abbrev, die->offset);
+ dwarf_tag_name (die->tag), die->abbrev, die->offset.sect_off);
if (die->parent != NULL)
{
print_spaces (indent, f);
fprintf_unfiltered (f, " parent at offset: 0x%x\n",
- die->parent->offset);
+ die->parent->offset.sect_off);
}
print_spaces (indent, f);
@@ -14020,8 +17195,8 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
switch (die->attrs[i].form)
{
- case DW_FORM_ref_addr:
case DW_FORM_addr:
+ case DW_FORM_GNU_addr_index:
fprintf_unfiltered (f, "address: ");
fputs_filtered (hex_string (DW_ADDR (&die->attrs[i])), f);
break;
@@ -14029,18 +17204,28 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
case DW_FORM_block4:
case DW_FORM_block:
case DW_FORM_block1:
- fprintf_unfiltered (f, "block: size %d",
- DW_BLOCK (&die->attrs[i])->size);
+ fprintf_unfiltered (f, "block: size %s",
+ pulongest (DW_BLOCK (&die->attrs[i])->size));
break;
case DW_FORM_exprloc:
- fprintf_unfiltered (f, "expression: size %u",
- DW_BLOCK (&die->attrs[i])->size);
+ fprintf_unfiltered (f, "expression: size %s",
+ pulongest (DW_BLOCK (&die->attrs[i])->size));
+ break;
+ case DW_FORM_ref_addr:
+ fprintf_unfiltered (f, "ref address: ");
+ fputs_filtered (hex_string (DW_UNSND (&die->attrs[i])), f);
+ break;
+ case DW_FORM_GNU_ref_alt:
+ fprintf_unfiltered (f, "alt ref address: ");
+ fputs_filtered (hex_string (DW_UNSND (&die->attrs[i])), f);
break;
case DW_FORM_ref1:
case DW_FORM_ref2:
case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
fprintf_unfiltered (f, "constant ref: 0x%lx (adjusted)",
- (long) (DW_ADDR (&die->attrs[i])));
+ (long) (DW_UNSND (&die->attrs[i])));
break;
case DW_FORM_data1:
case DW_FORM_data2:
@@ -14058,12 +17243,14 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
case DW_FORM_ref_sig8:
if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL)
fprintf_unfiltered (f, "signatured type, offset: 0x%x",
- DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset);
+ DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset.sect_off);
else
fprintf_unfiltered (f, "signatured type, offset: unknown");
break;
case DW_FORM_string:
case DW_FORM_strp:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_strp_alt:
fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)",
DW_STRING (&die->attrs[i])
? DW_STRING (&die->attrs[i]) : "",
@@ -14147,11 +17334,15 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu)
{
void **slot;
- slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset, INSERT);
+ slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset.sect_off,
+ INSERT);
*slot = die;
}
+/* DW_ADDR is always stored already as sect_offset; despite for the forms
+ besides DW_FORM_ref_addr it is stored as cu_offset in the DWARF file. */
+
static int
is_ref_attr (struct attribute *attr)
{
@@ -14163,22 +17354,29 @@ is_ref_attr (struct attribute *attr)
case DW_FORM_ref4:
case DW_FORM_ref8:
case DW_FORM_ref_udata:
+ case DW_FORM_GNU_ref_alt:
return 1;
default:
return 0;
}
}
-static unsigned int
+/* Return DIE offset of ATTR. Return 0 with complaint if ATTR is not of the
+ required kind. */
+
+static sect_offset
dwarf2_get_ref_die_offset (struct attribute *attr)
{
+ sect_offset retval = { DW_UNSND (attr) };
+
if (is_ref_attr (attr))
- return DW_ADDR (attr);
+ return retval;
+ retval.sect_off = 0;
complaint (&symfile_complaints,
_("unsupported die ref attribute form: '%s'"),
dwarf_form_name (attr->form));
- return 0;
+ return retval;
}
/* Return the constant value held by ATTR. Return DEFAULT_VALUE if
@@ -14196,53 +17394,12 @@ dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
|| attr->form == DW_FORM_data8)
return DW_UNSND (attr);
else
- {
- complaint (&symfile_complaints,
- _("Attribute value is not a constant (%s)"),
- dwarf_form_name (attr->form));
- return default_value;
- }
-}
-
-/* THIS_CU has a reference to PER_CU. If necessary, load the new compilation
- unit and add it to our queue.
- The result is non-zero if PER_CU was queued, otherwise the result is zero
- meaning either PER_CU is already queued or it is already loaded. */
-
-static int
-maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
- struct dwarf2_per_cu_data *per_cu)
-{
- /* We may arrive here during partial symbol reading, if we need full
- DIEs to process an unusual case (e.g. template arguments). Do
- not queue PER_CU, just tell our caller to load its DIEs. */
- if (dwarf2_per_objfile->reading_partial_symbols)
- {
- if (per_cu->cu == NULL || per_cu->cu->dies == NULL)
- return 1;
- return 0;
- }
-
- /* Mark the dependence relation so that we don't flush PER_CU
- too early. */
- dwarf2_add_dependence (this_cu, per_cu);
-
- /* If it's already on the queue, we have nothing to do. */
- if (per_cu->queued)
- return 0;
-
- /* If the compilation unit is already loaded, just mark it as
- used. */
- if (per_cu->cu != NULL)
- {
- per_cu->cu->last_used = 0;
- return 0;
+ {
+ complaint (&symfile_complaints,
+ _("Attribute value is not a constant (%s)"),
+ dwarf_form_name (attr->form));
+ return default_value;
}
-
- /* Add it to the queue. */
- queue_comp_unit (per_cu, this_cu->objfile);
-
- return 1;
}
/* Follow reference or signature attribute ATTR of SRC_DIE.
@@ -14275,7 +17432,8 @@ follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr,
Returns NULL if OFFSET is invalid. */
static struct die_info *
-follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
+follow_die_offset (sect_offset offset, int offset_in_dwz,
+ struct dwarf2_cu **ref_cu)
{
struct die_info temp_die;
struct dwarf2_cu *target_cu, *cu = *ref_cu;
@@ -14284,7 +17442,7 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
target_cu = cu;
- if (cu->per_cu->debug_types_section)
+ if (cu->per_cu->is_debug_types)
{
/* .debug_types CUs cannot reference anything outside their CU.
If they need to, they have to reference a signatured type via
@@ -14292,15 +17450,17 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
if (! offset_in_cu_p (&cu->header, offset))
return NULL;
}
- else if (! offset_in_cu_p (&cu->header, offset))
+ else if (offset_in_dwz != cu->per_cu->is_dwz
+ || ! offset_in_cu_p (&cu->header, offset))
{
struct dwarf2_per_cu_data *per_cu;
- per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+ per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz,
+ cu->objfile);
/* If necessary, add it to the queue and load its DIEs. */
- if (maybe_queue_comp_unit (cu, per_cu))
- load_full_comp_unit (per_cu, cu->objfile);
+ if (maybe_queue_comp_unit (cu, per_cu, cu->language))
+ load_full_comp_unit (per_cu, cu->language);
target_cu = per_cu->cu;
}
@@ -14308,12 +17468,12 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
{
/* We're loading full DIEs during partial symbol reading. */
gdb_assert (dwarf2_per_objfile->reading_partial_symbols);
- load_full_comp_unit (cu->per_cu, cu->objfile);
+ load_full_comp_unit (cu->per_cu, language_minimal);
}
*ref_cu = target_cu;
temp_die.offset = offset;
- return htab_find_with_hash (target_cu->die_hash, &temp_die, offset);
+ return htab_find_with_hash (target_cu->die_hash, &temp_die, offset.sect_off);
}
/* Follow reference attribute ATTR of SRC_DIE.
@@ -14324,15 +17484,18 @@ static struct die_info *
follow_die_ref (struct die_info *src_die, struct attribute *attr,
struct dwarf2_cu **ref_cu)
{
- unsigned int offset = dwarf2_get_ref_die_offset (attr);
+ sect_offset offset = dwarf2_get_ref_die_offset (attr);
struct dwarf2_cu *cu = *ref_cu;
struct die_info *die;
- die = follow_die_offset (offset, ref_cu);
+ die = follow_die_offset (offset,
+ (attr->form == DW_FORM_GNU_ref_alt
+ || cu->per_cu->is_dwz),
+ ref_cu);
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
"at 0x%x [in module %s]"),
- offset, src_die->offset, cu->objfile->name);
+ offset.sect_off, src_die->offset.sect_off, cu->objfile->name);
return die;
}
@@ -14342,10 +17505,10 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr,
dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE. */
struct dwarf2_locexpr_baton
-dwarf2_fetch_die_location_block (unsigned int offset,
- struct dwarf2_per_cu_data *per_cu,
- CORE_ADDR (*get_frame_pc) (void *baton),
- void *baton)
+dwarf2_fetch_die_loc_sect_off (sect_offset offset,
+ struct dwarf2_per_cu_data *per_cu,
+ CORE_ADDR (*get_frame_pc) (void *baton),
+ void *baton)
{
struct dwarf2_cu *cu;
struct die_info *die;
@@ -14358,10 +17521,10 @@ dwarf2_fetch_die_location_block (unsigned int offset,
load_cu (per_cu);
cu = per_cu->cu;
- die = follow_die_offset (offset, &cu);
+ die = follow_die_offset (offset, per_cu->is_dwz, &cu);
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
- offset, per_cu->cu->objfile->name);
+ offset.sect_off, per_cu->objfile->name);
attr = dwarf2_attr (die, DW_AT_location, cu);
if (!attr)
@@ -14389,7 +17552,7 @@ dwarf2_fetch_die_location_block (unsigned int offset,
if (!attr_form_is_block (attr))
error (_("Dwarf Error: DIE at 0x%x referenced in module %s "
"is neither DW_FORM_block* nor DW_FORM_exprloc"),
- offset, per_cu->cu->objfile->name);
+ offset.sect_off, per_cu->objfile->name);
retval.data = DW_BLOCK (attr)->data;
retval.size = DW_BLOCK (attr)->size;
@@ -14401,15 +17564,33 @@ dwarf2_fetch_die_location_block (unsigned int offset,
return retval;
}
+/* Like dwarf2_fetch_die_loc_sect_off, but take a CU
+ offset. */
+
+struct dwarf2_locexpr_baton
+dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu,
+ struct dwarf2_per_cu_data *per_cu,
+ CORE_ADDR (*get_frame_pc) (void *baton),
+ void *baton)
+{
+ sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off };
+
+ return dwarf2_fetch_die_loc_sect_off (offset, per_cu, get_frame_pc, baton);
+}
+
/* Return the type of the DIE at DIE_OFFSET in the CU named by
PER_CU. */
struct type *
-dwarf2_get_die_type (unsigned int die_offset,
+dwarf2_get_die_type (cu_offset die_offset,
struct dwarf2_per_cu_data *per_cu)
{
+ sect_offset die_offset_sect;
+
dw2_setup (per_cu->objfile);
- return get_die_type_at_offset (die_offset, per_cu);
+
+ die_offset_sect.sect_off = per_cu->offset.sect_off + die_offset.cu_off;
+ return get_die_type_at_offset (die_offset_sect, per_cu);
}
/* Follow the signature attribute ATTR in SRC_DIE.
@@ -14431,27 +17612,39 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
if (sig_type == NULL)
error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
"at 0x%x [in module %s]"),
- src_die->offset, objfile->name);
+ src_die->offset.sect_off, objfile->name);
/* If necessary, add it to the queue and load its DIEs. */
- if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu))
- read_signatured_type (objfile, sig_type);
+ if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, language_minimal))
+ read_signatured_type (sig_type);
gdb_assert (sig_type->per_cu.cu != NULL);
sig_cu = sig_type->per_cu.cu;
- temp_die.offset = sig_cu->header.offset + sig_type->type_offset;
- die = htab_find_with_hash (sig_cu->die_hash, &temp_die, temp_die.offset);
+ gdb_assert (sig_type->type_offset_in_section.sect_off != 0);
+ temp_die.offset = sig_type->type_offset_in_section;
+ die = htab_find_with_hash (sig_cu->die_hash, &temp_die,
+ temp_die.offset.sect_off);
if (die)
{
+ /* For .gdb_index version 7 keep track of included TUs.
+ http://sourceware.org/bugzilla/show_bug.cgi?id=15021. */
+ if (dwarf2_per_objfile->index_table != NULL
+ && dwarf2_per_objfile->index_table->version <= 7)
+ {
+ VEC_safe_push (dwarf2_per_cu_ptr,
+ (*ref_cu)->per_cu->imported_symtabs,
+ sig_cu->per_cu);
+ }
+
*ref_cu = sig_cu;
return die;
}
error (_("Dwarf Error: Cannot find signatured DIE at 0x%x referenced "
"from DIE at 0x%x [in module %s]"),
- sig_type->type_offset, src_die->offset, objfile->name);
+ temp_die.offset.sect_off, src_die->offset.sect_off, objfile->name);
}
/* Given an offset of a signatured type, return its signatured_type. */
@@ -14459,12 +17652,12 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
static struct signatured_type *
lookup_signatured_type_at_offset (struct objfile *objfile,
struct dwarf2_section_info *section,
- unsigned int offset)
+ sect_offset offset)
{
- gdb_byte *info_ptr = section->buffer + offset;
+ gdb_byte *info_ptr = section->buffer + offset.sect_off;
unsigned int length, initial_length_size;
unsigned int sig_offset;
- struct signatured_type find_entry, *type_sig;
+ struct signatured_type find_entry, *sig_type;
length = read_initial_length (objfile->obfd, info_ptr, &initial_length_size);
sig_offset = (initial_length_size
@@ -14472,100 +17665,90 @@ lookup_signatured_type_at_offset (struct objfile *objfile,
+ (initial_length_size == 4 ? 4 : 8) /*debug_abbrev_offset*/
+ 1 /*address_size*/);
find_entry.signature = bfd_get_64 (objfile->obfd, info_ptr + sig_offset);
- type_sig = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
+ sig_type = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
/* This is only used to lookup previously recorded types.
If we didn't find it, it's our bug. */
- gdb_assert (type_sig != NULL);
- gdb_assert (offset == type_sig->per_cu.offset);
+ gdb_assert (sig_type != NULL);
+ gdb_assert (offset.sect_off == sig_type->per_cu.offset.sect_off);
- return type_sig;
+ return sig_type;
}
-/* Read in signatured type at OFFSET and build its CU and die(s). */
+/* Load the DIEs associated with type unit PER_CU into memory. */
static void
-read_signatured_type_at_offset (struct objfile *objfile,
- struct dwarf2_section_info *sect,
- unsigned int offset)
+load_full_type_unit (struct dwarf2_per_cu_data *per_cu)
{
- struct signatured_type *type_sig;
+ struct signatured_type *sig_type;
- dwarf2_read_section (objfile, sect);
+ /* Caller is responsible for ensuring type_unit_groups don't get here. */
+ gdb_assert (! IS_TYPE_UNIT_GROUP (per_cu));
- /* We have the section offset, but we need the signature to do the
- hash table lookup. */
- type_sig = lookup_signatured_type_at_offset (objfile, sect, offset);
+ /* We have the per_cu, but we need the signatured_type.
+ Fortunately this is an easy translation. */
+ gdb_assert (per_cu->is_debug_types);
+ sig_type = (struct signatured_type *) per_cu;
- gdb_assert (type_sig->per_cu.cu == NULL);
+ gdb_assert (per_cu->cu == NULL);
- read_signatured_type (objfile, type_sig);
+ read_signatured_type (sig_type);
- gdb_assert (type_sig->per_cu.cu != NULL);
+ gdb_assert (per_cu->cu != NULL);
}
-/* Read in a signatured type and build its CU and DIEs. */
+/* die_reader_func for read_signatured_type.
+ This is identical to load_full_comp_unit_reader,
+ but is kept separate for now. */
static void
-read_signatured_type (struct objfile *objfile,
- struct signatured_type *type_sig)
+read_signatured_type_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
{
- gdb_byte *types_ptr;
- struct die_reader_specs reader_specs;
- struct dwarf2_cu *cu;
- ULONGEST signature;
- struct cleanup *back_to, *free_cu_cleanup;
- struct dwarf2_section_info *section = type_sig->per_cu.debug_types_section;
-
- dwarf2_read_section (objfile, section);
- types_ptr = section->buffer + type_sig->per_cu.offset;
-
- gdb_assert (type_sig->per_cu.cu == NULL);
-
- cu = xmalloc (sizeof (*cu));
- init_one_comp_unit (cu, objfile);
-
- type_sig->per_cu.cu = cu;
- cu->per_cu = &type_sig->per_cu;
-
- /* If an error occurs while loading, release our storage. */
- free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
-
- types_ptr = read_type_comp_unit_head (&cu->header, section, &signature,
- types_ptr, objfile->obfd);
- gdb_assert (signature == type_sig->signature);
-
- cu->die_hash
- = htab_create_alloc_ex (cu->header.length / 12,
- die_hash,
- die_eq,
- NULL,
- &cu->comp_unit_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
-
- dwarf2_read_abbrevs (cu->objfile->obfd, cu);
- back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
+ struct dwarf2_cu *cu = reader->cu;
- init_cu_die_reader (&reader_specs, cu);
+ gdb_assert (cu->die_hash == NULL);
+ cu->die_hash =
+ htab_create_alloc_ex (cu->header.length / 12,
+ die_hash,
+ die_eq,
+ NULL,
+ &cu->comp_unit_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
- cu->dies = read_die_and_children (&reader_specs, types_ptr, &types_ptr,
- NULL /*parent*/);
+ if (has_children)
+ comp_unit_die->child = read_die_and_siblings (reader, info_ptr,
+ &info_ptr, comp_unit_die);
+ cu->dies = comp_unit_die;
+ /* comp_unit_die is not stored in die_hash, no need. */
/* We try not to read any attributes in this function, because not
- all objfiles needed for references have been loaded yet, and symbol
+ all CUs needed for references have been loaded yet, and symbol
table processing isn't initialized. But we have to set the CU language,
- or we won't be able to build types correctly. */
- prepare_one_comp_unit (cu, cu->dies);
+ or we won't be able to build types correctly.
+ Similarly, if we do not read the producer, we can not apply
+ producer-specific interpretation. */
+ prepare_one_comp_unit (cu, cu->dies, language_minimal);
+}
- do_cleanups (back_to);
+/* Read in a signatured type and build its CU and DIEs.
+ If the type is a stub for the real type in a DWO file,
+ read in the real type from the DWO file as well. */
+
+static void
+read_signatured_type (struct signatured_type *sig_type)
+{
+ struct dwarf2_per_cu_data *per_cu = &sig_type->per_cu;
- /* We've successfully allocated this compilation unit. Let our caller
- clean it up when finished with it. */
- discard_cleanups (free_cu_cleanup);
+ gdb_assert (per_cu->is_debug_types);
+ gdb_assert (per_cu->cu == NULL);
- type_sig->per_cu.cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
- dwarf2_per_objfile->read_in_chain = &type_sig->per_cu;
+ init_cutu_and_read_dies (per_cu, NULL, 0, 1,
+ read_signatured_type_reader, NULL);
}
/* Decode simple location descriptions.
@@ -14593,8 +17776,8 @@ static CORE_ADDR
decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- int i;
- int size = blk->size;
+ size_t i;
+ size_t size = blk->size;
gdb_byte *data = blk->data;
CORE_ADDR stack[64];
int stacki;
@@ -14790,9 +17973,16 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
case DW_OP_GNU_uninit:
break;
+ case DW_OP_GNU_addr_index:
+ case DW_OP_GNU_const_index:
+ stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i],
+ &bytes_read);
+ i += bytes_read;
+ break;
+
default:
{
- const char *name = dwarf_stack_op_name (op);
+ const char *name = get_DW_OP_name (op);
if (name)
complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
@@ -14836,17 +18026,6 @@ dwarf_alloc_block (struct dwarf2_cu *cu)
return (blk);
}
-static struct abbrev_info *
-dwarf_alloc_abbrev (struct dwarf2_cu *cu)
-{
- struct abbrev_info *abbrev;
-
- abbrev = (struct abbrev_info *)
- obstack_alloc (&cu->abbrev_obstack, sizeof (struct abbrev_info));
- memset (abbrev, 0, sizeof (struct abbrev_info));
- return (abbrev);
-}
-
static struct die_info *
dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs)
{
@@ -14864,12 +18043,12 @@ dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs)
/* Macro support. */
-/* Return the full name of file number I in *LH's file name table.
- Use COMP_DIR as the name of the current directory of the
- compilation. The result is allocated using xmalloc; the caller is
+/* Return file name relative to the compilation directory of file number I in
+ *LH's file name table. The result is allocated using xmalloc; the caller is
responsible for freeing it. */
+
static char *
-file_full_name (int file, struct line_header *lh, const char *comp_dir)
+file_file_name (int file, struct line_header *lh)
{
/* Is the file number a valid index into the line header's file name
table? Remember that file numbers start with one, not zero. */
@@ -14877,31 +18056,10 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir)
{
struct file_entry *fe = &lh->file_names[file - 1];
- if (IS_ABSOLUTE_PATH (fe->name))
+ if (IS_ABSOLUTE_PATH (fe->name) || fe->dir_index == 0)
return xstrdup (fe->name);
- else
- {
- const char *dir;
- int dir_len;
- char *full_name;
-
- if (fe->dir_index)
- dir = lh->include_dirs[fe->dir_index - 1];
- else
- dir = comp_dir;
-
- if (dir)
- {
- dir_len = strlen (dir);
- full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1);
- strcpy (full_name, dir);
- full_name[dir_len] = '/';
- strcpy (full_name + dir_len + 1, fe->name);
- return full_name;
- }
- else
- return xstrdup (fe->name);
- }
+ return concat (lh->include_dirs[fe->dir_index - 1], SLASH_STRING,
+ fe->name, NULL);
}
else
{
@@ -14910,7 +18068,8 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir)
won't be able to find the file by name. */
char fake_name[80];
- sprintf (fake_name, "", file);
+ xsnprintf (fake_name, sizeof (fake_name),
+ "", file);
complaint (&symfile_complaints,
_("bad file number in macro information (%d)"),
@@ -14920,6 +18079,27 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir)
}
}
+/* Return the full name of file number I in *LH's file name table.
+ Use COMP_DIR as the name of the current directory of the
+ compilation. The result is allocated using xmalloc; the caller is
+ responsible for freeing it. */
+static char *
+file_full_name (int file, struct line_header *lh, const char *comp_dir)
+{
+ /* Is the file number a valid index into the line header's file name
+ table? Remember that file numbers start with one, not zero. */
+ if (1 <= file && file <= lh->num_file_names)
+ {
+ char *relative = file_file_name (file, lh);
+
+ if (IS_ABSOLUTE_PATH (relative) || comp_dir == NULL)
+ return relative;
+ return reconcat (relative, comp_dir, SLASH_STRING, relative, NULL);
+ }
+ else
+ return file_file_name (file, lh);
+}
+
static struct macro_source_file *
macro_start_file (int file, int line,
@@ -14927,23 +18107,27 @@ macro_start_file (int file, int line,
const char *comp_dir,
struct line_header *lh, struct objfile *objfile)
{
- /* The full name of this source file. */
- char *full_name = file_full_name (file, lh, comp_dir);
+ /* File name relative to the compilation directory of this source file. */
+ char *file_name = file_file_name (file, lh);
/* We don't create a macro table for this compilation unit
at all until we actually get a filename. */
if (! pending_macros)
- pending_macros = new_macro_table (&objfile->objfile_obstack,
- objfile->macro_cache);
+ pending_macros = new_macro_table (&objfile->per_bfd->storage_obstack,
+ objfile->per_bfd->macro_cache,
+ comp_dir);
if (! current_file)
- /* If we have no current file, then this must be the start_file
- directive for the compilation unit's main source file. */
- current_file = macro_set_main (pending_macros, full_name);
+ {
+ /* If we have no current file, then this must be the start_file
+ directive for the compilation unit's main source file. */
+ current_file = macro_set_main (pending_macros, file_name);
+ macro_define_special (pending_macros);
+ }
else
- current_file = macro_include (current_file, line, full_name);
+ current_file = macro_include (current_file, line, file_name);
- xfree (full_name);
+ xfree (file_name);
return current_file;
}
@@ -15124,7 +18308,7 @@ parse_macro_definition (struct macro_source_file *file, int line,
Returns the new pointer. */
static gdb_byte *
-skip_form_bytes (bfd *abfd, gdb_byte *bytes,
+skip_form_bytes (bfd *abfd, gdb_byte *bytes, gdb_byte *buffer_end,
enum dwarf_form form,
unsigned int offset_size,
struct dwarf2_section_info *section)
@@ -15157,6 +18341,7 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes,
case DW_FORM_sec_offset:
case DW_FORM_strp:
+ case DW_FORM_GNU_strp_alt:
bytes += offset_size;
break;
@@ -15177,7 +18362,14 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes,
case DW_FORM_sdata:
case DW_FORM_udata:
- bytes = skip_leb128 (abfd, bytes);
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ bytes = (gdb_byte *) gdb_skip_leb128 (bytes, buffer_end);
+ if (bytes == NULL)
+ {
+ dwarf2_section_buffer_overflow_complaint (section);
+ return NULL;
+ }
break;
default:
@@ -15201,7 +18393,7 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes,
static gdb_byte *
skip_unknown_opcode (unsigned int opcode,
gdb_byte **opcode_definitions,
- gdb_byte *mac_ptr,
+ gdb_byte *mac_ptr, gdb_byte *mac_end,
bfd *abfd,
unsigned int offset_size,
struct dwarf2_section_info *section)
@@ -15224,7 +18416,8 @@ skip_unknown_opcode (unsigned int opcode,
for (i = 0; i < arg; ++i)
{
- mac_ptr = skip_form_bytes (abfd, mac_ptr, defn[i], offset_size, section);
+ mac_ptr = skip_form_bytes (abfd, mac_ptr, mac_end, defn[i], offset_size,
+ section);
if (mac_ptr == NULL)
{
/* skip_form_bytes already issued the complaint. */
@@ -15297,16 +18490,17 @@ dwarf_parse_macro_header (gdb_byte **opcode_definitions,
}
/* A helper for dwarf_decode_macros that handles the GNU extensions,
- including DW_GNU_MACINFO_transparent_include. */
+ including DW_MACRO_GNU_transparent_include. */
static void
dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
struct macro_source_file *current_file,
- struct line_header *lh, char *comp_dir,
+ struct line_header *lh, const char *comp_dir,
struct dwarf2_section_info *section,
- int section_is_gnu,
+ int section_is_gnu, int section_is_dwz,
unsigned int offset_size,
- struct objfile *objfile)
+ struct objfile *objfile,
+ htab_t include_hash)
{
enum dwarf_macro_record_type macinfo_type;
int at_commandline;
@@ -15334,7 +18528,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
/* Do we at least have room for a macinfo type byte? */
if (mac_ptr >= mac_end)
{
- dwarf2_macros_too_long_complaint (section);
+ dwarf2_section_buffer_overflow_complaint (section);
break;
}
@@ -15354,6 +18548,8 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
case DW_MACRO_GNU_undef:
case DW_MACRO_GNU_define_indirect:
case DW_MACRO_GNU_undef_indirect:
+ case DW_MACRO_GNU_define_indirect_alt:
+ case DW_MACRO_GNU_undef_indirect_alt:
{
unsigned int bytes_read;
int line;
@@ -15376,11 +18572,21 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
str_offset = read_offset_1 (abfd, mac_ptr, offset_size);
mac_ptr += offset_size;
- body = read_indirect_string_at_offset (abfd, str_offset);
+ if (macinfo_type == DW_MACRO_GNU_define_indirect_alt
+ || macinfo_type == DW_MACRO_GNU_undef_indirect_alt
+ || section_is_dwz)
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+
+ body = read_indirect_string_from_dwz (dwz, str_offset);
+ }
+ else
+ body = read_indirect_string_at_offset (abfd, str_offset);
}
is_define = (macinfo_type == DW_MACRO_GNU_define
- || macinfo_type == DW_MACRO_GNU_define_indirect);
+ || macinfo_type == DW_MACRO_GNU_define_indirect
+ || macinfo_type == DW_MACRO_GNU_define_indirect_alt);
if (! current_file)
{
/* DWARF violation as no main source is present. */
@@ -15404,7 +18610,8 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
else
{
gdb_assert (macinfo_type == DW_MACRO_GNU_undef
- || macinfo_type == DW_MACRO_GNU_undef_indirect);
+ || macinfo_type == DW_MACRO_GNU_undef_indirect
+ || macinfo_type == DW_MACRO_GNU_undef_indirect_alt);
macro_undef (current_file, line, body);
}
}
@@ -15461,7 +18668,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
/* Do we at least have room for a macinfo type byte? */
if (mac_ptr >= mac_end)
{
- dwarf2_macros_too_long_complaint (section);
+ dwarf2_section_buffer_overflow_complaint (section);
return;
}
@@ -15479,18 +18686,56 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
break;
case DW_MACRO_GNU_transparent_include:
+ case DW_MACRO_GNU_transparent_include_alt:
{
LONGEST offset;
+ void **slot;
+ bfd *include_bfd = abfd;
+ struct dwarf2_section_info *include_section = section;
+ struct dwarf2_section_info alt_section;
+ gdb_byte *include_mac_end = mac_end;
+ int is_dwz = section_is_dwz;
+ gdb_byte *new_mac_ptr;
offset = read_offset_1 (abfd, mac_ptr, offset_size);
mac_ptr += offset_size;
- dwarf_decode_macro_bytes (abfd,
- section->buffer + offset,
- mac_end, current_file,
- lh, comp_dir,
- section, section_is_gnu,
- offset_size, objfile);
+ if (macinfo_type == DW_MACRO_GNU_transparent_include_alt)
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+
+ dwarf2_read_section (dwarf2_per_objfile->objfile,
+ &dwz->macro);
+
+ include_bfd = dwz->macro.asection->owner;
+ include_section = &dwz->macro;
+ include_mac_end = dwz->macro.buffer + dwz->macro.size;
+ is_dwz = 1;
+ }
+
+ new_mac_ptr = include_section->buffer + offset;
+ slot = htab_find_slot (include_hash, new_mac_ptr, INSERT);
+
+ if (*slot != NULL)
+ {
+ /* This has actually happened; see
+ http://sourceware.org/bugzilla/show_bug.cgi?id=13568. */
+ complaint (&symfile_complaints,
+ _("recursive DW_MACRO_GNU_transparent_include in "
+ ".debug_macro section"));
+ }
+ else
+ {
+ *slot = new_mac_ptr;
+
+ dwarf_decode_macro_bytes (include_bfd, new_mac_ptr,
+ include_mac_end, current_file,
+ lh, comp_dir,
+ section, section_is_gnu, is_dwz,
+ offset_size, objfile, include_hash);
+
+ htab_remove_elt (include_hash, new_mac_ptr);
+ }
}
break;
@@ -15512,7 +18757,7 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
default:
mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
- mac_ptr, abfd, offset_size,
+ mac_ptr, mac_end, abfd, offset_size,
section);
if (mac_ptr == NULL)
return;
@@ -15522,25 +18767,57 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
}
static void
-dwarf_decode_macros (struct line_header *lh, unsigned int offset,
- char *comp_dir, bfd *abfd,
- struct dwarf2_cu *cu,
- struct dwarf2_section_info *section,
- int section_is_gnu)
+dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
+ const char *comp_dir, int section_is_gnu)
{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct line_header *lh = cu->line_header;
+ bfd *abfd;
gdb_byte *mac_ptr, *mac_end;
struct macro_source_file *current_file = 0;
enum dwarf_macro_record_type macinfo_type;
unsigned int offset_size = cu->header.offset_size;
gdb_byte *opcode_definitions[256];
+ struct cleanup *cleanup;
+ htab_t include_hash;
+ void **slot;
+ struct dwarf2_section_info *section;
+ const char *section_name;
- dwarf2_read_section (dwarf2_per_objfile->objfile, section);
+ if (cu->dwo_unit != NULL)
+ {
+ if (section_is_gnu)
+ {
+ section = &cu->dwo_unit->dwo_file->sections.macro;
+ section_name = ".debug_macro.dwo";
+ }
+ else
+ {
+ section = &cu->dwo_unit->dwo_file->sections.macinfo;
+ section_name = ".debug_macinfo.dwo";
+ }
+ }
+ else
+ {
+ if (section_is_gnu)
+ {
+ section = &dwarf2_per_objfile->macro;
+ section_name = ".debug_macro";
+ }
+ else
+ {
+ section = &dwarf2_per_objfile->macinfo;
+ section_name = ".debug_macinfo";
+ }
+ }
+
+ dwarf2_read_section (objfile, section);
if (section->buffer == NULL)
{
- complaint (&symfile_complaints, _("missing %s section"),
- section->asection->name);
+ complaint (&symfile_complaints, _("missing %s section"), section_name);
return;
}
+ abfd = section->asection->owner;
/* First pass: Find the name of the base filename.
This filename is needed in order to process all macros whose definition
@@ -15611,7 +18888,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
mac_ptr += bytes_read;
current_file = macro_start_file (file, line, current_file,
- comp_dir, lh, cu->objfile);
+ comp_dir, lh, objfile);
}
break;
@@ -15621,6 +18898,8 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
case DW_MACRO_GNU_define_indirect:
case DW_MACRO_GNU_undef_indirect:
+ case DW_MACRO_GNU_define_indirect_alt:
+ case DW_MACRO_GNU_undef_indirect_alt:
{
unsigned int bytes_read;
@@ -15631,6 +18910,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
break;
case DW_MACRO_GNU_transparent_include:
+ case DW_MACRO_GNU_transparent_include_alt:
/* Note that, according to the spec, a transparent include
chain cannot call DW_MACRO_GNU_start_file. So, we can just
skip this opcode. */
@@ -15652,7 +18932,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
default:
mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
- mac_ptr, abfd, offset_size,
+ mac_ptr, mac_end, abfd, offset_size,
section);
if (mac_ptr == NULL)
return;
@@ -15666,13 +18946,22 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
command-line macro definitions/undefinitions. This flag is unset when we
reach the first DW_MACINFO_start_file entry. */
- dwarf_decode_macro_bytes (abfd, section->buffer + offset, mac_end,
- current_file, lh, comp_dir, section, section_is_gnu,
- offset_size, cu->objfile);
+ include_hash = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (include_hash);
+ mac_ptr = section->buffer + offset;
+ slot = htab_find_slot (include_hash, mac_ptr, INSERT);
+ *slot = mac_ptr;
+ dwarf_decode_macro_bytes (abfd, mac_ptr, mac_end,
+ current_file, lh, comp_dir, section,
+ section_is_gnu, 0,
+ offset_size, objfile, include_hash);
+ do_cleanups (cleanup);
}
/* Check if the attribute's form is a DW_FORM_block*
if so return true else false. */
+
static int
attr_form_is_block (struct attribute *attr)
{
@@ -15692,6 +18981,7 @@ attr_form_is_block (struct attribute *attr)
may have a value that belongs to more than one of these classes; it
would be ambiguous if we did, because we use the same forms for all
of them. */
+
static int
attr_form_is_section_offset (struct attribute *attr)
{
@@ -15700,7 +18990,6 @@ attr_form_is_section_offset (struct attribute *attr)
|| attr->form == DW_FORM_sec_offset);
}
-
/* Return non-zero if ATTR's value falls in the 'constant' class, or
zero otherwise. When this function returns true, you can apply
dwarf2_get_attr_constant_value to it.
@@ -15713,6 +19002,7 @@ attr_form_is_section_offset (struct attribute *attr)
that, if an attribute's can be either a constant or one of the
section offset classes, DW_FORM_data4 and DW_FORM_data8 should be
taken as section offsets, not constants. */
+
static int
attr_form_is_constant (struct attribute *attr)
{
@@ -15730,6 +19020,17 @@ attr_form_is_constant (struct attribute *attr)
}
}
+/* Return the .debug_loc section to use for CU.
+ For DWO files use .debug_loc.dwo. */
+
+static struct dwarf2_section_info *
+cu_debug_loc_section (struct dwarf2_cu *cu)
+{
+ if (cu->dwo_unit)
+ return &cu->dwo_unit->dwo_file->sections.loc;
+ return &dwarf2_per_objfile->loc;
+}
+
/* A helper function that fills in a dwarf2_loclist_baton. */
static void
@@ -15737,32 +19038,36 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
struct dwarf2_loclist_baton *baton,
struct attribute *attr)
{
- dwarf2_read_section (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->loc);
+ struct dwarf2_section_info *section = cu_debug_loc_section (cu);
+
+ dwarf2_read_section (dwarf2_per_objfile->objfile, section);
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
/* We don't know how long the location list is, but make sure we
don't run off the edge of the section. */
- baton->size = dwarf2_per_objfile->loc.size - DW_UNSND (attr);
- baton->data = dwarf2_per_objfile->loc.buffer + DW_UNSND (attr);
+ baton->size = section->size - DW_UNSND (attr);
+ baton->data = section->buffer + DW_UNSND (attr);
baton->base_address = cu->base_address;
+ baton->from_dwo = cu->dwo_unit != NULL;
}
static void
dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_section_info *section = cu_debug_loc_section (cu);
+
if (attr_form_is_section_offset (attr)
- /* ".debug_loc" may not exist at all, or the offset may be outside
+ /* .debug_loc{,.dwo} may not exist at all, or the offset may be outside
the section. If so, fall through to the complaint in the
other branch. */
- && DW_UNSND (attr) < dwarf2_section_size (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->loc))
+ && DW_UNSND (attr) < dwarf2_section_size (objfile, section))
{
struct dwarf2_loclist_baton *baton;
- baton = obstack_alloc (&cu->objfile->objfile_obstack,
+ baton = obstack_alloc (&objfile->objfile_obstack,
sizeof (struct dwarf2_loclist_baton));
fill_in_loclist_baton (cu, baton, attr);
@@ -15779,7 +19084,7 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
{
struct dwarf2_locexpr_baton *baton;
- baton = obstack_alloc (&cu->objfile->objfile_obstack,
+ baton = obstack_alloc (&objfile->objfile_obstack,
sizeof (struct dwarf2_locexpr_baton));
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
@@ -15831,26 +19136,22 @@ static const struct comp_unit_head *
per_cu_header_read_in (struct comp_unit_head *cu_headerp,
struct dwarf2_per_cu_data *per_cu)
{
- struct objfile *objfile;
- struct dwarf2_per_objfile *per_objfile;
gdb_byte *info_ptr;
if (per_cu->cu)
return &per_cu->cu->header;
- objfile = per_cu->objfile;
- per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
- info_ptr = per_objfile->info.buffer + per_cu->offset;
+ info_ptr = per_cu->info_or_types_section->buffer + per_cu->offset.sect_off;
memset (cu_headerp, 0, sizeof (*cu_headerp));
- read_comp_unit_head (cu_headerp, info_ptr, objfile->obfd);
+ read_comp_unit_head (cu_headerp, info_ptr, per_cu->objfile->obfd);
return cu_headerp;
}
/* Return the address size given in the compilation unit header for CU. */
-CORE_ADDR
+int
dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
{
struct comp_unit_head cu_header_local;
@@ -15907,73 +19208,72 @@ dwarf2_per_cu_text_offset (struct dwarf2_per_cu_data *per_cu)
the DIE at OFFSET. Raises an error on failure. */
static struct dwarf2_per_cu_data *
-dwarf2_find_containing_comp_unit (unsigned int offset,
+dwarf2_find_containing_comp_unit (sect_offset offset,
+ unsigned int offset_in_dwz,
struct objfile *objfile)
{
struct dwarf2_per_cu_data *this_cu;
int low, high;
+ const sect_offset *cu_off;
low = 0;
high = dwarf2_per_objfile->n_comp_units - 1;
while (high > low)
{
+ struct dwarf2_per_cu_data *mid_cu;
int mid = low + (high - low) / 2;
- if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset)
+ mid_cu = dwarf2_per_objfile->all_comp_units[mid];
+ cu_off = &mid_cu->offset;
+ if (mid_cu->is_dwz > offset_in_dwz
+ || (mid_cu->is_dwz == offset_in_dwz
+ && cu_off->sect_off >= offset.sect_off))
high = mid;
else
low = mid + 1;
}
gdb_assert (low == high);
- if (dwarf2_per_objfile->all_comp_units[low]->offset > offset)
+ this_cu = dwarf2_per_objfile->all_comp_units[low];
+ cu_off = &this_cu->offset;
+ if (this_cu->is_dwz != offset_in_dwz || cu_off->sect_off > offset.sect_off)
{
- if (low == 0)
+ if (low == 0 || this_cu->is_dwz != offset_in_dwz)
error (_("Dwarf Error: could not find partial DIE containing "
"offset 0x%lx [in module %s]"),
- (long) offset, bfd_get_filename (objfile->obfd));
+ (long) offset.sect_off, bfd_get_filename (objfile->obfd));
- gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset <= offset);
+ gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset.sect_off
+ <= offset.sect_off);
return dwarf2_per_objfile->all_comp_units[low-1];
}
else
{
this_cu = dwarf2_per_objfile->all_comp_units[low];
if (low == dwarf2_per_objfile->n_comp_units - 1
- && offset >= this_cu->offset + this_cu->length)
- error (_("invalid dwarf2 offset %u"), offset);
- gdb_assert (offset < this_cu->offset + this_cu->length);
+ && offset.sect_off >= this_cu->offset.sect_off + this_cu->length)
+ error (_("invalid dwarf2 offset %u"), offset.sect_off);
+ gdb_assert (offset.sect_off < this_cu->offset.sect_off + this_cu->length);
return this_cu;
}
}
-/* Locate the compilation unit from OBJFILE which is located at exactly
- OFFSET. Raises an error on failure. */
-
-static struct dwarf2_per_cu_data *
-dwarf2_find_comp_unit (unsigned int offset, struct objfile *objfile)
-{
- struct dwarf2_per_cu_data *this_cu;
-
- this_cu = dwarf2_find_containing_comp_unit (offset, objfile);
- if (this_cu->offset != offset)
- error (_("no compilation unit with offset %u."), offset);
- return this_cu;
-}
-
-/* Initialize dwarf2_cu CU for OBJFILE in a pre-allocated space. */
+/* Initialize dwarf2_cu CU, owned by PER_CU. */
static void
-init_one_comp_unit (struct dwarf2_cu *cu, struct objfile *objfile)
+init_one_comp_unit (struct dwarf2_cu *cu, struct dwarf2_per_cu_data *per_cu)
{
memset (cu, 0, sizeof (*cu));
- cu->objfile = objfile;
+ per_cu->cu = cu;
+ cu->per_cu = per_cu;
+ cu->objfile = per_cu->objfile;
obstack_init (&cu->comp_unit_obstack);
}
/* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE. */
static void
-prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die)
+prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
+ enum language pretend_language)
{
struct attribute *attr;
@@ -15983,9 +19283,13 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die)
set_cu_language (DW_UNSND (attr), cu);
else
{
- cu->language = language_minimal;
+ cu->language = pretend_language;
cu->language_defn = language_def (cu->language);
}
+
+ attr = dwarf2_attr (comp_unit_die, DW_AT_producer, cu);
+ if (attr)
+ cu->producer = DW_STRING (attr);
}
/* Release one cached compilation unit, CU. We unlink it from the tree
@@ -15995,12 +19299,12 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die)
cleanup routine. */
static void
-free_one_comp_unit (void *data)
+free_heap_comp_unit (void *data)
{
struct dwarf2_cu *cu = data;
- if (cu->per_cu != NULL)
- cu->per_cu->cu = NULL;
+ gdb_assert (cu->per_cu != NULL);
+ cu->per_cu->cu = NULL;
cu->per_cu = NULL;
obstack_free (&cu->comp_unit_obstack, NULL);
@@ -16010,30 +19314,19 @@ free_one_comp_unit (void *data)
/* This cleanup function is passed the address of a dwarf2_cu on the stack
when we're finished with it. We can't free the pointer itself, but be
- sure to unlink it from the cache. Also release any associated storage
- and perform cache maintenance.
-
- Only used during partial symbol parsing. */
+ sure to unlink it from the cache. Also release any associated storage. */
static void
free_stack_comp_unit (void *data)
{
struct dwarf2_cu *cu = data;
+ gdb_assert (cu->per_cu != NULL);
+ cu->per_cu->cu = NULL;
+ cu->per_cu = NULL;
+
obstack_free (&cu->comp_unit_obstack, NULL);
cu->partial_dies = NULL;
-
- if (cu->per_cu != NULL)
- {
- /* This compilation unit is on the stack in our caller, so we
- should not xfree it. Just unlink it. */
- cu->per_cu->cu = NULL;
- cu->per_cu = NULL;
-
- /* If we had a per-cu pointer, then we may have other compilation
- units loaded, so age them now. */
- age_cached_comp_units ();
- }
}
/* Free all cached compilation units. */
@@ -16051,7 +19344,7 @@ free_cached_comp_units (void *data)
next_cu = per_cu->cu->read_in_chain;
- free_one_comp_unit (per_cu->cu);
+ free_heap_comp_unit (per_cu->cu);
*last_chain = next_cu;
per_cu = next_cu;
@@ -16086,7 +19379,7 @@ age_cached_comp_units (void)
if (!per_cu->cu->mark)
{
- free_one_comp_unit (per_cu->cu);
+ free_heap_comp_unit (per_cu->cu);
*last_chain = next_cu;
}
else
@@ -16099,7 +19392,7 @@ age_cached_comp_units (void)
/* Remove a single compilation unit from the cache. */
static void
-free_one_cached_comp_unit (void *target_cu)
+free_one_cached_comp_unit (struct dwarf2_per_cu_data *target_per_cu)
{
struct dwarf2_per_cu_data *per_cu, **last_chain;
@@ -16111,9 +19404,10 @@ free_one_cached_comp_unit (void *target_cu)
next_cu = per_cu->cu->read_in_chain;
- if (per_cu->cu == target_cu)
+ if (per_cu == target_per_cu)
{
- free_one_comp_unit (per_cu->cu);
+ free_heap_comp_unit (per_cu->cu);
+ per_cu->cu = NULL;
*last_chain = next_cu;
break;
}
@@ -16143,35 +19437,45 @@ dwarf2_free_objfile (struct objfile *objfile)
/* Everything else should be on the objfile obstack. */
}
-/* A pair of DIE offset and GDB type pointer. We store these
- in a hash table separate from the DIEs, and preserve them
- when the DIEs are flushed out of cache. */
+/* A set of CU "per_cu" pointer, DIE offset, and GDB type pointer.
+ We store these in a hash table separate from the DIEs, and preserve them
+ when the DIEs are flushed out of cache.
+
+ The CU "per_cu" pointer is needed because offset alone is not enough to
+ uniquely identify the type. A file may have multiple .debug_types sections,
+ or the type may come from a DWO file. We have to use something in
+ dwarf2_per_cu_data (or the pointer to it) because we can enter the lookup
+ routine, get_die_type_at_offset, from outside this file, and thus won't
+ necessarily have PER_CU->cu. Fortunately, PER_CU is stable for the life
+ of the objfile. */
-struct dwarf2_offset_and_type
+struct dwarf2_per_cu_offset_and_type
{
- unsigned int offset;
+ const struct dwarf2_per_cu_data *per_cu;
+ sect_offset offset;
struct type *type;
};
-/* Hash function for a dwarf2_offset_and_type. */
+/* Hash function for a dwarf2_per_cu_offset_and_type. */
static hashval_t
-offset_and_type_hash (const void *item)
+per_cu_offset_and_type_hash (const void *item)
{
- const struct dwarf2_offset_and_type *ofs = item;
+ const struct dwarf2_per_cu_offset_and_type *ofs = item;
- return ofs->offset;
+ return (uintptr_t) ofs->per_cu + ofs->offset.sect_off;
}
-/* Equality function for a dwarf2_offset_and_type. */
+/* Equality function for a dwarf2_per_cu_offset_and_type. */
static int
-offset_and_type_eq (const void *item_lhs, const void *item_rhs)
+per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs)
{
- const struct dwarf2_offset_and_type *ofs_lhs = item_lhs;
- const struct dwarf2_offset_and_type *ofs_rhs = item_rhs;
+ const struct dwarf2_per_cu_offset_and_type *ofs_lhs = item_lhs;
+ const struct dwarf2_per_cu_offset_and_type *ofs_rhs = item_rhs;
- return ofs_lhs->offset == ofs_rhs->offset;
+ return (ofs_lhs->per_cu == ofs_rhs->per_cu
+ && ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off);
}
/* Set the type associated with DIE to TYPE. Save it in CU's hash
@@ -16195,9 +19499,8 @@ offset_and_type_eq (const void *item_lhs, const void *item_rhs)
static struct type *
set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
{
- struct dwarf2_offset_and_type **slot, ofs;
+ struct dwarf2_per_cu_offset_and_type **slot, ofs;
struct objfile *objfile = cu->objfile;
- htab_t *type_hash_ptr;
/* For Ada types, make sure that the gnat-specific data is always
initialized (if not already set). There are a few types where
@@ -16212,55 +19515,47 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
&& !HAVE_GNAT_AUX_INFO (type))
INIT_GNAT_SPECIFIC (type);
- if (cu->per_cu->debug_types_section)
- type_hash_ptr = &dwarf2_per_objfile->debug_types_type_hash;
- else
- type_hash_ptr = &dwarf2_per_objfile->debug_info_type_hash;
-
- if (*type_hash_ptr == NULL)
+ if (dwarf2_per_objfile->die_type_hash == NULL)
{
- *type_hash_ptr
- = htab_create_alloc_ex (127,
- offset_and_type_hash,
- offset_and_type_eq,
- NULL,
- &objfile->objfile_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
+ dwarf2_per_objfile->die_type_hash =
+ htab_create_alloc_ex (127,
+ per_cu_offset_and_type_hash,
+ per_cu_offset_and_type_eq,
+ NULL,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
}
+ ofs.per_cu = cu->per_cu;
ofs.offset = die->offset;
ofs.type = type;
- slot = (struct dwarf2_offset_and_type **)
- htab_find_slot_with_hash (*type_hash_ptr, &ofs, ofs.offset, INSERT);
+ slot = (struct dwarf2_per_cu_offset_and_type **)
+ htab_find_slot (dwarf2_per_objfile->die_type_hash, &ofs, INSERT);
if (*slot)
complaint (&symfile_complaints,
_("A problem internal to GDB: DIE 0x%x has type already set"),
- die->offset);
+ die->offset.sect_off);
*slot = obstack_alloc (&objfile->objfile_obstack, sizeof (**slot));
**slot = ofs;
return type;
}
-/* Look up the type for the die at DIE_OFFSET in the appropriate type_hash
+/* Look up the type for the die at OFFSET in the appropriate type_hash
table, or return NULL if the die does not have a saved type. */
static struct type *
-get_die_type_at_offset (unsigned int offset,
+get_die_type_at_offset (sect_offset offset,
struct dwarf2_per_cu_data *per_cu)
{
- struct dwarf2_offset_and_type *slot, ofs;
- htab_t type_hash;
+ struct dwarf2_per_cu_offset_and_type *slot, ofs;
- if (per_cu->debug_types_section)
- type_hash = dwarf2_per_objfile->debug_types_type_hash;
- else
- type_hash = dwarf2_per_objfile->debug_info_type_hash;
- if (type_hash == NULL)
+ if (dwarf2_per_objfile->die_type_hash == NULL)
return NULL;
+ ofs.per_cu = per_cu;
ofs.offset = offset;
- slot = htab_find_with_hash (type_hash, &ofs, ofs.offset);
+ slot = htab_find (dwarf2_per_objfile->die_type_hash, &ofs);
if (slot)
return slot->type;
else
@@ -16354,7 +19649,7 @@ partial_die_hash (const void *item)
{
const struct partial_die_info *part_die = item;
- return part_die->offset;
+ return part_die->offset.sect_off;
}
/* Trivial comparison function for partial_die_info structures: two DIEs
@@ -16366,7 +19661,7 @@ partial_die_eq (const void *item_lhs, const void *item_rhs)
const struct partial_die_info *part_die_lhs = item_lhs;
const struct partial_die_info *part_die_rhs = item_rhs;
- return part_die_lhs->offset == part_die_rhs->offset;
+ return part_die_lhs->offset.sect_off == part_die_rhs->offset.sect_off;
}
static struct cmd_list_element *set_dwarf2_cmdlist;
@@ -16384,54 +19679,31 @@ show_dwarf2_cmd (char *args, int from_tty)
cmd_show_list (show_dwarf2_cmdlist, from_tty, "");
}
-/* If section described by INFO was mmapped, munmap it now. */
-
-static void
-munmap_section_buffer (struct dwarf2_section_info *info)
-{
- if (info->map_addr != NULL)
- {
-#ifdef HAVE_MMAP
- int res;
-
- res = munmap (info->map_addr, info->map_len);
- gdb_assert (res == 0);
-#else
- /* Without HAVE_MMAP, we should never be here to begin with. */
- gdb_assert_not_reached ("no mmap support");
-#endif
- }
-}
-
-/* munmap debug sections for OBJFILE, if necessary. */
+/* Free data associated with OBJFILE, if necessary. */
static void
dwarf2_per_objfile_free (struct objfile *objfile, void *d)
{
struct dwarf2_per_objfile *data = d;
int ix;
- struct dwarf2_section_info *section;
- /* This is sorted according to the order they're defined in to make it easier
- to keep in sync. */
- munmap_section_buffer (&data->info);
- munmap_section_buffer (&data->abbrev);
- munmap_section_buffer (&data->line);
- munmap_section_buffer (&data->loc);
- munmap_section_buffer (&data->macinfo);
- munmap_section_buffer (&data->macro);
- munmap_section_buffer (&data->str);
- munmap_section_buffer (&data->ranges);
- munmap_section_buffer (&data->frame);
- munmap_section_buffer (&data->eh_frame);
- munmap_section_buffer (&data->gdb_index);
+ for (ix = 0; ix < dwarf2_per_objfile->n_comp_units; ++ix)
+ VEC_free (dwarf2_per_cu_ptr,
+ dwarf2_per_objfile->all_comp_units[ix]->imported_symtabs);
- for (ix = 0;
- VEC_iterate (dwarf2_section_info_def, data->types, ix, section);
- ++ix)
- munmap_section_buffer (section);
+ for (ix = 0; ix < dwarf2_per_objfile->n_type_units; ++ix)
+ VEC_free (dwarf2_per_cu_ptr,
+ dwarf2_per_objfile->all_type_units[ix]->per_cu.imported_symtabs);
VEC_free (dwarf2_section_info_def, data->types);
+
+ if (data->dwo_files)
+ free_dwo_files (data->dwo_files, objfile);
+ if (data->dwp_file)
+ gdb_bfd_unref (data->dwp_file->dbfd);
+
+ if (data->dwz_file && data->dwz_file->dwz_bfd)
+ gdb_bfd_unref (data->dwz_file->dwz_bfd);
}
@@ -16638,14 +19910,17 @@ hash_expand (struct mapped_symtab *symtab)
xfree (old_entries);
}
-/* Add an entry to SYMTAB. NAME is the name of the symbol. CU_INDEX
- is the index of the CU in which the symbol appears. */
+/* Add an entry to SYMTAB. NAME is the name of the symbol.
+ CU_INDEX is the index of the CU in which the symbol appears.
+ IS_STATIC is one if the symbol is static, otherwise zero (global). */
static void
add_index_entry (struct mapped_symtab *symtab, const char *name,
+ int is_static, gdb_index_symbol_kind kind,
offset_type cu_index)
{
struct symtab_index_entry **slot;
+ offset_type cu_index_and_attrs;
++symtab->n_elements;
if (4 * symtab->n_elements / 3 >= symtab->size)
@@ -16656,13 +19931,76 @@ add_index_entry (struct mapped_symtab *symtab, const char *name,
{
*slot = XNEW (struct symtab_index_entry);
(*slot)->name = name;
+ /* index_offset is set later. */
(*slot)->cu_indices = NULL;
}
- /* Don't push an index twice. Due to how we add entries we only
- have to check the last one. */
- if (VEC_empty (offset_type, (*slot)->cu_indices)
- || VEC_last (offset_type, (*slot)->cu_indices) != cu_index)
- VEC_safe_push (offset_type, (*slot)->cu_indices, cu_index);
+
+ cu_index_and_attrs = 0;
+ DW2_GDB_INDEX_CU_SET_VALUE (cu_index_and_attrs, cu_index);
+ DW2_GDB_INDEX_SYMBOL_STATIC_SET_VALUE (cu_index_and_attrs, is_static);
+ DW2_GDB_INDEX_SYMBOL_KIND_SET_VALUE (cu_index_and_attrs, kind);
+
+ /* We don't want to record an index value twice as we want to avoid the
+ duplication.
+ We process all global symbols and then all static symbols
+ (which would allow us to avoid the duplication by only having to check
+ the last entry pushed), but a symbol could have multiple kinds in one CU.
+ To keep things simple we don't worry about the duplication here and
+ sort and uniqufy the list after we've processed all symbols. */
+ VEC_safe_push (offset_type, (*slot)->cu_indices, cu_index_and_attrs);
+}
+
+/* qsort helper routine for uniquify_cu_indices. */
+
+static int
+offset_type_compare (const void *ap, const void *bp)
+{
+ offset_type a = *(offset_type *) ap;
+ offset_type b = *(offset_type *) bp;
+
+ return (a > b) - (b > a);
+}
+
+/* Sort and remove duplicates of all symbols' cu_indices lists. */
+
+static void
+uniquify_cu_indices (struct mapped_symtab *symtab)
+{
+ int i;
+
+ for (i = 0; i < symtab->size; ++i)
+ {
+ struct symtab_index_entry *entry = symtab->data[i];
+
+ if (entry
+ && entry->cu_indices != NULL)
+ {
+ unsigned int next_to_insert, next_to_check;
+ offset_type last_value;
+
+ qsort (VEC_address (offset_type, entry->cu_indices),
+ VEC_length (offset_type, entry->cu_indices),
+ sizeof (offset_type), offset_type_compare);
+
+ last_value = VEC_index (offset_type, entry->cu_indices, 0);
+ next_to_insert = 1;
+ for (next_to_check = 1;
+ next_to_check < VEC_length (offset_type, entry->cu_indices);
+ ++next_to_check)
+ {
+ if (VEC_index (offset_type, entry->cu_indices, next_to_check)
+ != last_value)
+ {
+ last_value = VEC_index (offset_type, entry->cu_indices,
+ next_to_check);
+ VEC_replace (offset_type, entry->cu_indices, next_to_insert,
+ last_value);
+ ++next_to_insert;
+ }
+ }
+ VEC_truncate (offset_type, entry->cu_indices, next_to_insert);
+ }
+ }
}
/* Add a vector of indices to the constant pool. */
@@ -16821,8 +20159,6 @@ add_address_entry_worker (void *datap, CORE_ADDR start_addr, void *obj)
{
struct addrmap_index_data *data = datap;
struct partial_symtab *pst = obj;
- offset_type cu_index;
- void **slot;
if (data->previous_valid)
add_address_entry (data->objfile, data->addr_obstack,
@@ -16878,6 +20214,44 @@ write_address_map (struct objfile *objfile, struct obstack *obstack,
addrmap_index_data.previous_cu_index);
}
+/* Return the symbol kind of PSYM. */
+
+static gdb_index_symbol_kind
+symbol_kind (struct partial_symbol *psym)
+{
+ domain_enum domain = PSYMBOL_DOMAIN (psym);
+ enum address_class aclass = PSYMBOL_CLASS (psym);
+
+ switch (domain)
+ {
+ case VAR_DOMAIN:
+ switch (aclass)
+ {
+ case LOC_BLOCK:
+ return GDB_INDEX_SYMBOL_KIND_FUNCTION;
+ case LOC_TYPEDEF:
+ return GDB_INDEX_SYMBOL_KIND_TYPE;
+ case LOC_COMPUTED:
+ case LOC_CONST_BYTES:
+ case LOC_OPTIMIZED_OUT:
+ case LOC_STATIC:
+ return GDB_INDEX_SYMBOL_KIND_VARIABLE;
+ case LOC_CONST:
+ /* Note: It's currently impossible to recognize psyms as enum values
+ short of reading the type info. For now punt. */
+ return GDB_INDEX_SYMBOL_KIND_VARIABLE;
+ default:
+ /* There are other LOC_FOO values that one might want to classify
+ as variables, but dwarf2read.c doesn't currently use them. */
+ return GDB_INDEX_SYMBOL_KIND_OTHER;
+ }
+ case STRUCT_DOMAIN:
+ return GDB_INDEX_SYMBOL_KIND_TYPE;
+ default:
+ return GDB_INDEX_SYMBOL_KIND_OTHER;
+ }
+}
+
/* Add a list of partial symbols to SYMTAB. */
static void
@@ -16890,29 +20264,21 @@ write_psymbols (struct mapped_symtab *symtab,
{
for (; count-- > 0; ++psymp)
{
- void **slot, *lookup;
+ struct partial_symbol *psym = *psymp;
+ void **slot;
- if (SYMBOL_LANGUAGE (*psymp) == language_ada)
+ if (SYMBOL_LANGUAGE (psym) == language_ada)
error (_("Ada is not currently supported by the index"));
- /* We only want to add a given psymbol once. However, we also
- want to account for whether it is global or static. So, we
- may add it twice, using slightly different values. */
- if (is_static)
- {
- uintptr_t val = 1 | (uintptr_t) *psymp;
-
- lookup = (void *) val;
- }
- else
- lookup = *psymp;
-
/* Only add a given psymbol once. */
- slot = htab_find_slot (psyms_seen, lookup, INSERT);
+ slot = htab_find_slot (psyms_seen, psym, INSERT);
if (!*slot)
{
- *slot = lookup;
- add_index_entry (symtab, SYMBOL_NATURAL_NAME (*psymp), cu_index);
+ gdb_index_symbol_kind kind = symbol_kind (psym);
+
+ *slot = psym;
+ add_index_entry (symtab, SYMBOL_SEARCH_NAME (psym),
+ is_static, kind, cu_index);
}
}
}
@@ -16974,9 +20340,11 @@ write_one_signatured_type (void **slot, void *d)
psymtab->n_static_syms, info->cu_index,
1);
- store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->per_cu.offset);
+ store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
+ entry->per_cu.offset.sect_off);
obstack_grow (info->types_list, val, 8);
- store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset);
+ store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
+ entry->type_offset_in_tu.cu_off);
obstack_grow (info->types_list, val, 8);
store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->signature);
obstack_grow (info->types_list, val, 8);
@@ -16986,6 +20354,35 @@ write_one_signatured_type (void **slot, void *d)
return 1;
}
+/* Recurse into all "included" dependencies and write their symbols as
+ if they appeared in this psymtab. */
+
+static void
+recursively_write_psymbols (struct objfile *objfile,
+ struct partial_symtab *psymtab,
+ struct mapped_symtab *symtab,
+ htab_t psyms_seen,
+ offset_type cu_index)
+{
+ int i;
+
+ for (i = 0; i < psymtab->number_of_dependencies; ++i)
+ if (psymtab->dependencies[i]->user != NULL)
+ recursively_write_psymbols (objfile, psymtab->dependencies[i],
+ symtab, psyms_seen, cu_index);
+
+ write_psymbols (symtab,
+ psyms_seen,
+ objfile->global_psymbols.list + psymtab->globals_offset,
+ psymtab->n_global_syms, cu_index,
+ 0);
+ write_psymbols (symtab,
+ psyms_seen,
+ objfile->static_psymbols.list + psymtab->statics_offset,
+ psymtab->n_static_syms, cu_index,
+ 1);
+}
+
/* Create an index file for OBJFILE in the directory DIR. */
static void
@@ -17000,7 +20397,6 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
struct mapped_symtab *symtab;
offset_type val, size_of_contents, total_len;
struct stat st;
- char buf[8];
htab_t psyms_seen;
htab_t cu_index_htab;
struct psymtab_cu_index_map *psymtab_cu_index_map;
@@ -17070,16 +20466,8 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
struct psymtab_cu_index_map *map;
void **slot;
- write_psymbols (symtab,
- psyms_seen,
- objfile->global_psymbols.list + psymtab->globals_offset,
- psymtab->n_global_syms, i,
- 0);
- write_psymbols (symtab,
- psyms_seen,
- objfile->static_psymbols.list + psymtab->statics_offset,
- psymtab->n_static_syms, i,
- 1);
+ if (psymtab->user == NULL)
+ recursively_write_psymbols (objfile, psymtab, symtab, psyms_seen, i);
map = &psymtab_cu_index_map[i];
map->psymtab = psymtab;
@@ -17089,7 +20477,8 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
gdb_assert (*slot == NULL);
*slot = map;
- store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->offset);
+ store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
+ per_cu->offset.sect_off);
obstack_grow (&cu_list, val, 8);
store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->length);
obstack_grow (&cu_list, val, 8);
@@ -17112,6 +20501,10 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
write_one_signatured_type, &sig_data);
}
+ /* Now that we've processed all symbols we can shrink their cu_indices
+ lists. */
+ uniquify_cu_indices (symtab);
+
obstack_init (&constant_pool);
make_cleanup_obstack_free (&constant_pool);
obstack_init (&symtab_obstack);
@@ -17124,7 +20517,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
total_len = size_of_contents;
/* The version number. */
- val = MAYBE_SWAP (5);
+ val = MAYBE_SWAP (8);
obstack_grow (&contents, &val, sizeof (val));
/* The offset of the CU list from the start of the file. */
@@ -17277,14 +20670,23 @@ conversational style, when possible."),
&set_dwarf2_cmdlist,
&show_dwarf2_cmdlist);
- add_setshow_zinteger_cmd ("dwarf2-die", no_class, &dwarf2_die_debug, _("\
+ add_setshow_boolean_cmd ("dwarf2-read", no_class, &dwarf2_read_debug, _("\
+Set debugging of the dwarf2 reader."), _("\
+Show debugging of the dwarf2 reader."), _("\
+When enabled, debugging messages are printed during dwarf2 reading\n\
+and symtab expansion."),
+ NULL,
+ NULL,
+ &setdebuglist, &showdebuglist);
+
+ add_setshow_zuinteger_cmd ("dwarf2-die", no_class, &dwarf2_die_debug, _("\
Set debugging of the dwarf2 DIE reader."), _("\
Show debugging of the dwarf2 DIE reader."), _("\
When enabled (non-zero), DIEs are dumped after they are read in.\n\
The value is the maximum depth to print."),
- NULL,
- NULL,
- &setdebuglist, &showdebuglist);
+ NULL,
+ NULL,
+ &setdebuglist, &showdebuglist);
add_setshow_boolean_cmd ("check-physname", no_class, &check_physname, _("\
Set cross-checking of \"physname\" code against demangler."), _("\
@@ -17294,6 +20696,18 @@ the demangler."),
NULL, show_check_physname,
&setdebuglist, &showdebuglist);
+ add_setshow_boolean_cmd ("use-deprecated-index-sections",
+ no_class, &use_deprecated_index_sections, _("\
+Set whether to use deprecated gdb_index sections."), _("\
+Show whether to use deprecated gdb_index sections."), _("\
+When enabled, deprecated .gdb_index sections are used anyway.\n\
+Normally they are ignored either because of a missing feature or\n\
+performance issue.\n\
+Warning: This option must be enabled before gdb reads the file."),
+ NULL,
+ NULL,
+ &setlist, &showlist);
+
c = add_cmd ("gdb-index", class_files, save_gdb_index_command,
_("\
Save a gdb-index file.\n\