X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=9060a840effd1ee051798d19378f9e0bfe15a85b;hb=3019eac3a2ebb5509f71db9fb21f131a7e759a5d;hp=c009aac7ff98e2b2b2cbd804eaa109c389987406;hpb=24d3216fd914347928f66a31c5b3be7c98e90be8;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index c009aac7ff..9060a840ef 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -1,8 +1,6 @@
/* DWARF 2 debugging format support for GDB.
- Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1994-2012 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
@@ -26,6 +24,10 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
+/* FIXME: Various die-reading functions need to be more careful with
+ reading off the end of the section.
+ E.g., load_partial_dies, read_partial_die. */
+
#include "defs.h"
#include "bfd.h"
#include "symtab.h"
@@ -34,6 +36,7 @@
#include "dwarf2.h"
#include "buildsym.h"
#include "demangle.h"
+#include "gdb-demangle.h"
#include "expression.h"
#include "filenames.h" /* for DOSish file names */
#include "macrotab.h"
@@ -56,7 +59,9 @@
#include "completer.h"
#include "vec.h"
#include "c-lang.h"
+#include "go-lang.h"
#include "valprint.h"
+#include "gdbcore.h" /* for gnutarget */
#include
#include
@@ -76,52 +81,15 @@
typedef struct symbol *symbolp;
DEF_VEC_P (symbolp);
-#if 0
-/* .debug_info header for a compilation unit
- Because of alignment constraints, this structure has padding and cannot
- be mapped directly onto the beginning of the .debug_info section. */
-typedef struct comp_unit_header
- {
- unsigned int length; /* length of the .debug_info
- contribution */
- unsigned short version; /* version number -- 2 for DWARF
- version 2 */
- unsigned int abbrev_offset; /* offset into .debug_abbrev section */
- unsigned char addr_size; /* byte size of an address -- 4 */
- }
-_COMP_UNIT_HEADER;
-#define _ACTUAL_COMP_UNIT_HEADER_SIZE 11
-#endif
-
-/* .debug_line statement program prologue
- Because of alignment constraints, this structure has padding and cannot
- be mapped directly onto the beginning of the .debug_info section. */
-typedef struct statement_prologue
- {
- unsigned int total_length; /* byte length of the statement
- information */
- unsigned short version; /* version number -- 2 for DWARF
- version 2 */
- unsigned int prologue_length; /* # bytes between prologue &
- stmt program */
- unsigned char minimum_instruction_length; /* byte size of
- smallest instr */
- unsigned char default_is_stmt; /* initial value of is_stmt
- register */
- char line_base;
- unsigned char line_range;
- unsigned char opcode_base; /* number assigned to first special
- opcode */
- unsigned char *standard_opcode_lengths;
- }
-_STATEMENT_PROLOGUE;
-
/* When non-zero, dump DIEs after they are read in. */
static int dwarf2_die_debug = 0;
/* When non-zero, cross-check physname against demangler. */
static int check_physname = 0;
+/* When non-zero, do not reject deprecated .gdb_index sections. */
+int use_deprecated_index_sections = 0;
+
static int pagesize;
/* When set, the file that we're processing is known to have debugging
@@ -180,6 +148,9 @@ struct mapped_index
const char *constant_pool;
};
+/* Collection of data recorded per objfile.
+ This hangs off of dwarf2_objfile_data_key. */
+
struct dwarf2_per_objfile
{
struct dwarf2_section_info info;
@@ -190,6 +161,7 @@ struct dwarf2_per_objfile
struct dwarf2_section_info macro;
struct dwarf2_section_info str;
struct dwarf2_section_info ranges;
+ struct dwarf2_section_info addr;
struct dwarf2_section_info frame;
struct dwarf2_section_info eh_frame;
struct dwarf2_section_info gdb_index;
@@ -199,7 +171,7 @@ struct dwarf2_per_objfile
/* Back link. */
struct objfile *objfile;
- /* A list of all the compilation units. This is used to locate
+ /* Table of all the compilation units. This is used to locate
the target compilation unit of a particular reference. */
struct dwarf2_per_cu_data **all_comp_units;
@@ -207,10 +179,10 @@ struct dwarf2_per_objfile
int n_comp_units;
/* The number of .debug_types-related CUs. */
- int n_type_comp_units;
+ int n_type_units;
- /* The .debug_types-related CUs. */
- struct dwarf2_per_cu_data **type_comp_units;
+ /* The .debug_types-related CUs (TUs). */
+ struct dwarf2_per_cu_data **all_type_units;
/* A chain of compilation units that are currently read in, so that
they can be freed later. */
@@ -220,6 +192,10 @@ struct dwarf2_per_objfile
This is NULL if the .debug_types section hasn't been read in yet. */
htab_t signatured_types;
+ /* A table mapping DW_AT_dwo_name values to struct dwo_file objects.
+ This is NULL if the table hasn't been allocated yet. */
+ htab_t dwo_files;
+
/* A flag indicating wether this objfile has a section loaded at a
VMA of 0. */
int has_section_at_zero;
@@ -241,15 +217,10 @@ struct dwarf2_per_objfile
symbols. */
int reading_partial_symbols;
- /* Table mapping type .debug_info DIE offsets to types.
+ /* Table mapping type DIEs to their struct type *.
This is NULL if not allocated yet.
- It (currently) makes sense to allocate debug_types_type_hash lazily.
- To keep things simple we allocate both lazily. */
- htab_t debug_info_type_hash;
-
- /* Table mapping type .debug_types DIE offsets to types.
- This is NULL if not allocated yet. */
- htab_t debug_types_type_hash;
+ The mapping is done via (CU/TU signature + DIE offset) -> type. */
+ htab_t die_type_hash;
};
static struct dwarf2_per_objfile *dwarf2_per_objfile;
@@ -259,7 +230,8 @@ static struct dwarf2_per_objfile *dwarf2_per_objfile;
/* Note that if the debugging section has been compressed, it might
have a name like .zdebug_info. */
-static const struct dwarf2_debug_sections dwarf2_elf_names = {
+static const struct dwarf2_debug_sections dwarf2_elf_names =
+{
{ ".debug_info", ".zdebug_info" },
{ ".debug_abbrev", ".zdebug_abbrev" },
{ ".debug_line", ".zdebug_line" },
@@ -269,12 +241,36 @@ static const struct dwarf2_debug_sections dwarf2_elf_names = {
{ ".debug_str", ".zdebug_str" },
{ ".debug_ranges", ".zdebug_ranges" },
{ ".debug_types", ".zdebug_types" },
+ { ".debug_addr", ".zdebug_addr" },
{ ".debug_frame", ".zdebug_frame" },
{ ".eh_frame", NULL },
{ ".gdb_index", ".zgdb_index" },
23
};
+/* List of DWO sections. */
+
+static const struct dwo_section_names
+{
+ struct dwarf2_section_names abbrev_dwo;
+ struct dwarf2_section_names info_dwo;
+ struct dwarf2_section_names line_dwo;
+ struct dwarf2_section_names loc_dwo;
+ struct dwarf2_section_names str_dwo;
+ struct dwarf2_section_names str_offsets_dwo;
+ struct dwarf2_section_names types_dwo;
+}
+dwo_section_names =
+{
+ { ".debug_abbrev.dwo", ".zdebug_abbrev.dwo" },
+ { ".debug_info.dwo", ".zdebug_info.dwo" },
+ { ".debug_line.dwo", ".zdebug_line.dwo" },
+ { ".debug_loc.dwo", ".zdebug_loc.dwo" },
+ { ".debug_str.dwo", ".zdebug_str.dwo" },
+ { ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo" },
+ { ".debug_types.dwo", ".zdebug_types.dwo" },
+};
+
/* local data types */
/* We hold several abbreviation tables in memory at the same time. */
@@ -290,7 +286,7 @@ struct comp_unit_head
short version;
unsigned char addr_size;
unsigned char signed_addr_p;
- unsigned int abbrev_offset;
+ sect_offset abbrev_offset;
/* Size of file offsets; either 4 or 8. */
unsigned int offset_size;
@@ -300,11 +296,11 @@ struct comp_unit_head
/* Offset to the first byte of this compilation unit header in the
.debug_info section, for resolving relative reference dies. */
- unsigned int offset;
+ sect_offset offset;
/* Offset to first die in this cu from the start of the cu.
This will be the first byte following the compilation unit header. */
- unsigned int first_die_offset;
+ cu_offset first_die_offset;
};
/* Type used for delaying computation of method physnames.
@@ -345,8 +341,6 @@ struct dwarf2_cu
/* Non-zero if base_address has been set. */
int base_known;
- struct function_range *first_fn, *last_fn, *cached_fn;
-
/* The language we are debugging. */
enum language language;
const struct language_defn *language_defn;
@@ -370,7 +364,8 @@ struct dwarf2_cu
/* Storage for the abbrev table. */
struct obstack abbrev_obstack;
- /* Hash table holding all the loaded partial DIEs. */
+ /* Hash table holding all the loaded partial DIEs
+ with partial_die->offset.SECT_OFF as hash. */
htab_t partial_dies;
/* Storage for things with the same lifetime as this read-in compilation
@@ -389,7 +384,8 @@ struct dwarf2_cu
/* How many compilation units ago was this CU last referenced? */
int last_used;
- /* A hash table of die offsets for following references. */
+ /* A hash table of DIE cu_offset for following references with
+ die_info->offset.sect_off as hash. */
htab_t die_hash;
/* Full DIEs if read in. */
@@ -407,32 +403,41 @@ struct dwarf2_cu
after all type information has been read. */
VEC (delayed_method_info) *method_list;
- /* Mark used when releasing cached dies. */
- unsigned int mark : 1;
+ /* To be copied to symtab->call_site_htab. */
+ htab_t call_site_htab;
- /* This flag will be set if this compilation unit might include
- inter-compilation-unit references. */
- unsigned int has_form_ref_addr : 1;
+ /* Non-NULL if this CU came from a DWO file. */
+ struct dwo_unit *dwo_unit;
- /* This flag will be set if this compilation unit includes any
- DW_TAG_namespace DIEs. If we know that there are explicit
- DIEs for namespaces, we don't need to try to infer them
- from mangled names. */
- unsigned int has_namespace_info : 1;
+ /* The DW_AT_addr_base attribute if present, zero otherwise
+ (zero is a valid value though).
+ Note this value comes from the stub CU/TU's DIE. */
+ ULONGEST addr_base;
+
+ /* Mark used when releasing cached dies. */
+ unsigned int mark : 1;
/* This CU references .debug_loc. See the symtab->locations_valid field.
This test is imperfect as there may exist optimized debug code not using
any location list and still facing inlining issues if handled as
unoptimized code. For a future better test see GCC PR other/32998. */
-
unsigned int has_loclist : 1;
+
+ /* These cache the results of producer_is_gxx_lt_4_6.
+ CHECKED_PRODUCER is set if PRODUCER_IS_GXX_LT_4_6 is valid. This
+ information is cached because profiling CU expansion showed
+ excessive time spent in producer_is_gxx_lt_4_6. */
+ unsigned int checked_producer : 1;
+ unsigned int producer_is_gxx_lt_4_6 : 1;
+
+ /* Non-zero if DW_AT_addr_base was found.
+ Used when processing DWO files. */
+ unsigned int have_addr_base : 1;
};
/* Persistent data held for a compilation unit, even when not
processing it. We put a pointer to this structure in the
- read_symtab_private field of the psymtab. If we encounter
- inter-compilation-unit references, we also maintain a sorted
- list of all compilation units. */
+ read_symtab_private field of the psymtab. */
struct dwarf2_per_cu_data
{
@@ -440,29 +445,37 @@ struct dwarf2_per_cu_data
bytes should suffice to store the length of any compilation unit
- if it doesn't, GDB will fall over anyway.
NOTE: Unlike comp_unit_head.length, this length includes
- initial_length_size. */
- unsigned int offset;
+ initial_length_size.
+ If the DIE refers to a DWO file, this is always of the original die,
+ not the DWO file. */
+ sect_offset offset;
unsigned int length : 29;
/* Flag indicating this compilation unit will be read in before
any of the current compilation units are processed. */
unsigned int queued : 1;
- /* This flag will be set if we need to load absolutely all DIEs
- for this compilation unit, instead of just the ones we think
- are interesting. It gets set if we look for a DIE in the
+ /* This flag will be set when reading partial DIEs if we need to load
+ absolutely all DIEs for this compilation unit, instead of just the ones
+ we think are interesting. It gets set if we look for a DIE in the
hash table and don't find it. */
unsigned int load_all_dies : 1;
- /* Non-null if this CU is from .debug_types; in which case it points
- to the section. Otherwise it's from .debug_info. */
- struct dwarf2_section_info *debug_type_section;
+ /* Non-zero if this CU is from .debug_types. */
+ unsigned int is_debug_types : 1;
+
+ /* The section this CU/TU lives in.
+ If the DIE refers to a DWO file, this is always the original die,
+ not the DWO file. */
+ struct dwarf2_section_info *info_or_types_section;
/* Set to non-NULL iff this CU is currently loaded. When it gets freed out
of the CU cache it gets reset to NULL again. */
struct dwarf2_cu *cu;
- /* The corresponding objfile. */
+ /* The corresponding objfile.
+ Normally we can get the objfile from dwarf2_per_objfile.
+ However we can enter this file with just a "per_cu" handle. */
struct objfile *objfile;
/* When using partial symbol tables, the 'psymtab' field is active.
@@ -483,34 +496,114 @@ struct dwarf2_per_cu_data
struct signatured_type
{
+ /* The type's signature. */
ULONGEST signature;
- /* Offset in .debug_types of the type defined by this TU. */
- unsigned int type_offset;
+ /* Offset in the TU of the type's DIE, as read from the TU header.
+ If the definition lives in a DWO file, this value is unusable. */
+ cu_offset type_offset_in_tu;
+
+ /* Offset in the section of the type's DIE.
+ If the definition lives in a DWO file, this is the offset in the
+ .debug_types.dwo section.
+ The value is zero until the actual value is known.
+ Zero is otherwise not a valid section offset. */
+ sect_offset type_offset_in_section;
/* The CU(/TU) of this type. */
struct dwarf2_per_cu_data per_cu;
};
+/* These sections are what may appear in a "dwo" file. */
+
+struct dwo_sections
+{
+ struct dwarf2_section_info abbrev;
+ struct dwarf2_section_info info;
+ struct dwarf2_section_info line;
+ struct dwarf2_section_info loc;
+ struct dwarf2_section_info str;
+ struct dwarf2_section_info str_offsets;
+ VEC (dwarf2_section_info_def) *types;
+};
+
+/* Common bits of DWO CUs/TUs. */
+
+struct dwo_unit
+{
+ /* Backlink to the containing struct dwo_file. */
+ struct dwo_file *dwo_file;
+
+ /* The "id" that distinguishes this CU/TU.
+ .debug_info calls this "dwo_id", .debug_types calls this "signature".
+ Since signatures came first, we stick with it for consistency. */
+ ULONGEST signature;
+
+ /* The section this CU/TU lives in, in the DWO file. */
+ struct dwarf2_section_info *info_or_types_section;
+
+ /* Same as dwarf2_per_cu_data:{offset,length} but for the DWO section. */
+ sect_offset offset;
+ unsigned int length;
+
+ /* For types, offset in the type's DIE of the type defined by this TU. */
+ cu_offset type_offset_in_tu;
+};
+
+/* Data for one DWO file. */
+
+struct dwo_file
+{
+ /* The DW_AT_GNU_dwo_name attribute.
+ We don't manage space for this, it's an attribute. */
+ const char *dwo_name;
+
+ /* The bfd, when the file is open. Otherwise this is NULL. */
+ bfd *dwo_bfd;
+
+ /* Section info for this file. */
+ struct dwo_sections sections;
+
+ /* Table of CUs in the file.
+ Each element is a struct dwo_unit. */
+ htab_t cus;
+
+ /* Table of TUs in the file.
+ Each element is a struct dwo_unit. */
+ htab_t tus;
+};
+
/* Struct used to pass misc. parameters to read_die_and_children, et
al. which are used for both .debug_info and .debug_types dies.
All parameters here are unchanging for the life of the call. This
- struct exists to abstract away the constant parameters of die
- reading. */
+ struct exists to abstract away the constant parameters of die reading. */
struct die_reader_specs
{
- /* The bfd of this objfile. */
+ /* die_section->asection->owner. */
bfd* abfd;
/* The CU of the DIE we are parsing. */
struct dwarf2_cu *cu;
- /* Pointer to start of section buffer.
- This is either the start of .debug_info or .debug_types. */
- const gdb_byte *buffer;
+ /* Non-NULL if reading a DWO file. */
+ struct dwo_file *dwo_file;
+
+ /* The section the die comes from.
+ This is either .debug_info or .debug_types, or the .dwo variants. */
+ struct dwarf2_section_info *die_section;
+
+ /* die_section->buffer. */
+ gdb_byte *buffer;
};
+/* Type of function passed to init_cu_and_read_dies, et.al. */
+typedef void (die_reader_func_ftype) (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data);
+
/* The line number information for a compilation unit (found in the
.debug_line section) begins with a "statement program header",
which contains the following information. */
@@ -563,7 +656,7 @@ struct line_header
struct partial_die_info
{
/* Offset of this DIE. */
- unsigned int offset;
+ sect_offset offset;
/* DWARF-2 tag for this DIE. */
ENUM_BITFIELD(dwarf_tag) tag : 16;
@@ -575,6 +668,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. */
@@ -617,7 +711,7 @@ struct partial_die_info
/* If HAS_SPECIFICATION, the offset of the DIE referred to by
DW_AT_specification (or DW_AT_abstract_origin or
DW_AT_extension). */
- unsigned int spec_offset;
+ sect_offset spec_offset;
/* Pointers to this DIE's parent, first child, and next sibling,
if any. */
@@ -681,7 +775,7 @@ struct die_info
unsigned int abbrev;
/* Offset in .debug_info or .debug_types section. */
- unsigned int offset;
+ sect_offset offset;
/* The dies in a compilation unit form an n-ary tree. PARENT
points to this die's parent; CHILD points to the first child of
@@ -697,14 +791,6 @@ struct die_info
struct attribute attrs[1];
};
-struct function_range
-{
- const char *name;
- CORE_ADDR lowpc, highpc;
- int seen_line;
- struct function_range *next;
-};
-
/* Get at parts of an attribute structure. */
#define DW_STRING(attr) ((attr)->u.str)
@@ -719,6 +805,8 @@ struct function_range
struct dwarf_block
{
unsigned int size;
+
+ /* Valid only if SIZE is not zero. */
gdb_byte *data;
};
@@ -919,45 +1007,41 @@ static void add_partial_subprogram (struct partial_die_info *pdi,
CORE_ADDR *lowpc, CORE_ADDR *highpc,
int need_pc, struct dwarf2_cu *cu);
-static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi,
- gdb_byte *buffer, gdb_byte *info_ptr,
- bfd *abfd, struct dwarf2_cu *cu);
-
static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
static void psymtab_to_symtab_1 (struct partial_symtab *);
-static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
+static void dwarf2_read_abbrevs (struct dwarf2_cu *,
+ struct dwarf2_section_info *);
static void dwarf2_free_abbrev_table (void *);
+static unsigned int peek_abbrev_code (bfd *, gdb_byte *);
+
static struct abbrev_info *peek_die_abbrev (gdb_byte *, unsigned int *,
struct dwarf2_cu *);
static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
struct dwarf2_cu *);
-static struct partial_die_info *load_partial_dies (bfd *,
- gdb_byte *, gdb_byte *,
- int, struct dwarf2_cu *);
+static struct partial_die_info *load_partial_dies
+ (const struct die_reader_specs *, gdb_byte *, int);
-static gdb_byte *read_partial_die (struct partial_die_info *,
- struct abbrev_info *abbrev,
- unsigned int, bfd *,
- gdb_byte *, gdb_byte *,
- struct dwarf2_cu *);
+static gdb_byte *read_partial_die (const struct die_reader_specs *,
+ struct partial_die_info *,
+ struct abbrev_info *,
+ unsigned int,
+ gdb_byte *);
-static struct partial_die_info *find_partial_die (unsigned int,
+static struct partial_die_info *find_partial_die (sect_offset,
struct dwarf2_cu *);
static void fixup_partial_die (struct partial_die_info *,
struct dwarf2_cu *);
-static gdb_byte *read_attribute (struct attribute *, struct attr_abbrev *,
- bfd *, gdb_byte *, struct dwarf2_cu *);
-
-static gdb_byte *read_attribute_value (struct attribute *, unsigned,
- bfd *, gdb_byte *, struct dwarf2_cu *);
+static gdb_byte *read_attribute (const struct die_reader_specs *,
+ struct attribute *, struct attr_abbrev *,
+ gdb_byte *);
static unsigned int read_1_byte (bfd *, gdb_byte *);
@@ -991,9 +1075,15 @@ static char *read_indirect_string (bfd *, gdb_byte *,
const struct comp_unit_head *,
unsigned int *);
-static unsigned long read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *);
+static ULONGEST read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *);
+
+static LONGEST read_signed_leb128 (bfd *, gdb_byte *, unsigned int *);
+
+static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *, gdb_byte *,
+ unsigned int *);
-static long read_signed_leb128 (bfd *, gdb_byte *, unsigned int *);
+static char *read_str_index (const struct die_reader_specs *reader,
+ struct dwarf2_cu *cu, ULONGEST str_index);
static gdb_byte *skip_leb128 (bfd *, gdb_byte *);
@@ -1019,12 +1109,12 @@ static void free_line_header (struct line_header *lh);
static void add_file_name (struct line_header *, char *, unsigned int,
unsigned int, unsigned int);
-static struct line_header *(dwarf_decode_line_header
- (unsigned int offset,
- bfd *abfd, struct dwarf2_cu *cu));
+static struct line_header *dwarf_decode_line_header (unsigned int offset,
+ struct dwarf2_cu *cu);
-static void dwarf_decode_lines (struct line_header *, const char *, bfd *,
- struct dwarf2_cu *, struct partial_symtab *);
+static void dwarf_decode_lines (struct line_header *, const char *,
+ struct dwarf2_cu *, struct partial_symtab *,
+ int);
static void dwarf2_start_subfile (char *, const char *, const char *);
@@ -1041,7 +1131,7 @@ static void dwarf2_const_value_attr (struct attribute *attr,
struct type *type,
const char *name,
struct obstack *obstack,
- struct dwarf2_cu *cu, long *value,
+ struct dwarf2_cu *cu, LONGEST *value,
gdb_byte **bytes,
struct dwarf2_locexpr_baton **baton);
@@ -1065,7 +1155,7 @@ static struct type *read_type_die (struct die_info *, struct dwarf2_cu *);
static struct type *read_type_die_1 (struct die_info *, struct dwarf2_cu *);
-static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
+static const char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
static char *typename_concat (struct obstack *obs, const char *prefix,
const char *suffix, int physname,
@@ -1079,6 +1169,8 @@ static void read_func_scope (struct die_info *, struct dwarf2_cu *);
static void read_lexical_block_scope (struct die_info *, struct dwarf2_cu *);
+static void read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu);
+
static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
struct dwarf2_cu *, struct partial_symtab *);
@@ -1130,26 +1222,21 @@ static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
struct dwarf2_cu *);
-static struct die_info *read_comp_unit (gdb_byte *, struct dwarf2_cu *);
-
-static struct die_info *read_die_and_children_1 (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- gdb_byte **new_info_ptr,
- struct die_info *parent);
-
-static struct die_info *read_die_and_children (const struct die_reader_specs *reader,
+static struct die_info *read_die_and_children (const struct die_reader_specs *,
gdb_byte *info_ptr,
gdb_byte **new_info_ptr,
struct die_info *parent);
-static struct die_info *read_die_and_siblings (const struct die_reader_specs *reader,
+static struct die_info *read_die_and_siblings (const struct die_reader_specs *,
gdb_byte *info_ptr,
gdb_byte **new_info_ptr,
struct die_info *parent);
-static gdb_byte *read_full_die (const struct die_reader_specs *reader,
- struct die_info **, gdb_byte *,
- int *);
+static gdb_byte *read_full_die_1 (const struct die_reader_specs *,
+ struct die_info **, gdb_byte *, int *, int);
+
+static gdb_byte *read_full_die (const struct die_reader_specs *,
+ struct die_info **, gdb_byte *, int *);
static void process_die (struct die_info *, struct dwarf2_cu *);
@@ -1195,7 +1282,7 @@ static void store_in_ref_table (struct die_info *,
static int is_ref_attr (struct attribute *);
-static unsigned int dwarf2_get_ref_die_offset (struct attribute *);
+static sect_offset dwarf2_get_ref_die_offset (struct attribute *);
static LONGEST dwarf2_get_attr_constant_value (struct attribute *, int);
@@ -1213,15 +1300,11 @@ static struct die_info *follow_die_sig (struct die_info *,
static struct signatured_type *lookup_signatured_type_at_offset
(struct objfile *objfile,
- struct dwarf2_section_info *section,
- unsigned int offset);
+ struct dwarf2_section_info *section, sect_offset offset);
-static void read_signatured_type_at_offset (struct objfile *objfile,
- struct dwarf2_section_info *sect,
- unsigned int offset);
+static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu);
-static void read_signatured_type (struct objfile *,
- struct signatured_type *type_sig);
+static void read_signatured_type (struct signatured_type *);
/* memory allocation interface */
@@ -1231,11 +1314,6 @@ 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 *,
@@ -1255,9 +1333,9 @@ static void dwarf2_symbol_mark_computed (struct attribute *attr,
struct symbol *sym,
struct dwarf2_cu *cu);
-static gdb_byte *skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
- struct abbrev_info *abbrev,
- struct dwarf2_cu *cu);
+static gdb_byte *skip_one_die (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct abbrev_info *abbrev);
static void free_stack_comp_unit (void *);
@@ -1266,34 +1344,30 @@ static hashval_t partial_die_hash (const void *item);
static int partial_die_eq (const void *item_lhs, const void *item_rhs);
static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
- (unsigned int offset, struct objfile *objfile);
-
-static struct dwarf2_per_cu_data *dwarf2_find_comp_unit
- (unsigned int offset, struct objfile *objfile);
+ (sect_offset offset, struct objfile *objfile);
static void init_one_comp_unit (struct dwarf2_cu *cu,
- struct objfile *objfile);
+ struct dwarf2_per_cu_data *per_cu);
static void prepare_one_comp_unit (struct dwarf2_cu *cu,
struct die_info *comp_unit_die);
-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 *);
+static void load_full_comp_unit (struct dwarf2_per_cu_data *);
static void process_full_comp_unit (struct dwarf2_per_cu_data *);
@@ -1304,17 +1378,16 @@ 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);
static void dwarf2_release_queue (void *dummy);
-static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
- struct objfile *objfile);
+static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu);
-static void process_queue (struct objfile *objfile);
+static void process_queue (void);
static void find_file_and_directory (struct die_info *die,
struct dwarf2_cu *cu,
@@ -1323,17 +1396,35 @@ static void find_file_and_directory (struct die_info *die,
static char *file_full_name (int file, struct line_header *lh,
const char *comp_dir);
-static gdb_byte *partial_read_comp_unit_head (struct comp_unit_head *header,
- gdb_byte *info_ptr,
- gdb_byte *buffer,
- unsigned int buffer_size,
- bfd *abfd);
+static gdb_byte *read_and_check_comp_unit_head
+ (struct comp_unit_head *header,
+ struct dwarf2_section_info *section, gdb_byte *info_ptr,
+ int is_debug_types_section);
-static void init_cu_die_reader (struct die_reader_specs *reader,
- struct dwarf2_cu *cu);
+static void init_tu_and_read_dies
+ (struct dwarf2_per_cu_data *this_cu, int keep,
+ die_reader_func_ftype *die_reader_func, void *data);
+
+static void init_cutu_and_read_dies_simple
+ (struct dwarf2_per_cu_data *this_cu,
+ die_reader_func_ftype *die_reader_func, void *data);
static htab_t allocate_signatured_type_table (struct objfile *objfile);
+static void process_psymtab_comp_unit (struct dwarf2_per_cu_data *);
+
+static htab_t allocate_dwo_unit_table (struct objfile *objfile);
+
+static struct dwo_unit *lookup_dwo_comp_unit
+ (struct dwarf2_per_cu_data *, char *, const char *, ULONGEST);
+
+static struct dwo_unit *lookup_dwo_type_unit
+ (struct signatured_type *, char *, const char *);
+
+static void free_dwo_file_cleanup (void *);
+
+static void munmap_section_buffer (struct dwarf2_section_info *);
+
#if WORDS_BIGENDIAN
/* Convert VALUE between big- and little-endian. */
@@ -1454,6 +1545,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;
@@ -1503,7 +1599,7 @@ static void
zlib_decompress_section (struct objfile *objfile, asection *sectp,
gdb_byte **outbuf, bfd_size_type *outsize)
{
- bfd *abfd = objfile->obfd;
+ bfd *abfd = sectp->owner;
#ifndef HAVE_ZLIB_H
error (_("Support for zlib-compressed DWARF data (from '%s') "
"is disabled in this copy of GDB"),
@@ -1583,15 +1679,17 @@ dwarf2_section_empty_p (struct dwarf2_section_info *info)
return info->asection == NULL || info->size == 0;
}
-/* Read the contents of the section SECTP from object file specified by
- OBJFILE, store info about the section into INFO.
+/* Read the contents of the section INFO.
+ OBJFILE is the main object file, but not necessarily the file where
+ the section comes from. E.g., for DWO files INFO->asection->owner
+ is the bfd of the DWO file.
If the section is compressed, uncompress it before returning. */
static void
dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
{
- bfd *abfd = objfile->obfd;
asection *sectp = info->asection;
+ bfd *abfd;
gdb_byte *buf, *retbuf;
unsigned char header[4];
@@ -1604,6 +1702,9 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
if (dwarf2_section_empty_p (info))
return;
+ /* Note that ABFD may not be from OBJFILE, e.g. a DWO section. */
+ abfd = sectp->owner;
+
/* Check if the file has a 4-byte header indicating compression. */
if (info->size > sizeof (header)
&& bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
@@ -1825,34 +1926,30 @@ create_quick_file_names_table (unsigned int nr_initial_entries)
static void
load_cu (struct dwarf2_per_cu_data *per_cu)
{
- if (per_cu->debug_type_section)
- read_signatured_type_at_offset (per_cu->objfile,
- per_cu->debug_type_section,
- per_cu->offset);
+ if (per_cu->is_debug_types)
+ load_full_type_unit (per_cu);
else
- load_full_comp_unit (per_cu, per_cu->objfile);
-
- dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
+ load_full_comp_unit (per_cu);
gdb_assert (per_cu->cu != NULL);
+
+ dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
}
-/* Read in the symbols for PER_CU. OBJFILE is the objfile from which
- this CU came. */
+/* Read in the symbols for PER_CU. */
static void
-dw2_do_instantiate_symtab (struct objfile *objfile,
- struct dwarf2_per_cu_data *per_cu)
+dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
{
struct cleanup *back_to;
back_to = make_cleanup (dwarf2_release_queue, NULL);
- queue_comp_unit (per_cu, objfile);
+ queue_comp_unit (per_cu);
load_cu (per_cu);
- process_queue (objfile);
+ process_queue ();
/* Age the cache, releasing compilation units that have not
been used recently. */
@@ -1866,14 +1963,13 @@ 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)
{
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);
do_cleanups (back_to);
}
return per_cu->v.quick->symtab;
@@ -1887,7 +1983,7 @@ dw2_get_cu (int index)
if (index >= dwarf2_per_objfile->n_comp_units)
{
index -= dwarf2_per_objfile->n_comp_units;
- return dwarf2_per_objfile->type_comp_units[index];
+ return dwarf2_per_objfile->all_type_units[index];
}
return dwarf2_per_objfile->all_comp_units[index];
}
@@ -1943,9 +2039,10 @@ create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list,
the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_data);
- the_cu->offset = offset;
+ the_cu->offset.sect_off = offset;
the_cu->length = length;
the_cu->objfile = objfile;
+ the_cu->info_or_types_section = &dwarf2_per_objfile->info;
the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_quick_data);
dwarf2_per_objfile->all_comp_units[i / 2] = the_cu;
@@ -1965,41 +2062,42 @@ create_signatured_type_table_from_index (struct objfile *objfile,
offset_type i;
htab_t sig_types_hash;
- dwarf2_per_objfile->n_type_comp_units = elements / 3;
- dwarf2_per_objfile->type_comp_units
+ dwarf2_per_objfile->n_type_units = elements / 3;
+ dwarf2_per_objfile->all_type_units
= obstack_alloc (&objfile->objfile_obstack,
- dwarf2_per_objfile->n_type_comp_units
+ dwarf2_per_objfile->n_type_units
* sizeof (struct dwarf2_per_cu_data *));
sig_types_hash = allocate_signatured_type_table (objfile);
for (i = 0; i < elements; i += 3)
{
- struct signatured_type *type_sig;
- ULONGEST offset, type_offset, signature;
+ struct signatured_type *sig_type;
+ ULONGEST offset, type_offset_in_tu, signature;
void **slot;
if (!extract_cu_value (bytes, &offset)
- || !extract_cu_value (bytes + 8, &type_offset))
+ || !extract_cu_value (bytes + 8, &type_offset_in_tu))
return 0;
signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
bytes += 3 * 8;
- type_sig = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct signatured_type);
- type_sig->signature = signature;
- type_sig->type_offset = type_offset;
- type_sig->per_cu.debug_type_section = section;
- type_sig->per_cu.offset = offset;
- type_sig->per_cu.objfile = objfile;
- type_sig->per_cu.v.quick
+ sig_type->signature = signature;
+ sig_type->type_offset_in_tu.cu_off = type_offset_in_tu;
+ sig_type->per_cu.is_debug_types = 1;
+ sig_type->per_cu.info_or_types_section = section;
+ sig_type->per_cu.offset.sect_off = offset;
+ sig_type->per_cu.objfile = objfile;
+ sig_type->per_cu.v.quick
= OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_quick_data);
- slot = htab_find_slot (sig_types_hash, type_sig, INSERT);
- *slot = type_sig;
+ slot = htab_find_slot (sig_types_hash, sig_type, INSERT);
+ *slot = sig_type;
- dwarf2_per_objfile->type_comp_units[i / 3] = &type_sig->per_cu;
+ dwarf2_per_objfile->all_type_units[i / 3] = &sig_type->per_cu;
}
dwarf2_per_objfile->signatured_types = sig_types_hash;
@@ -2107,7 +2205,7 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
}
/* Index version 4 did not support case insensitive searches. But the
- indexes for case insensitive languages are built in lowercase, therefore
+ indices for case insensitive languages are built in lowercase, therefore
simulate our NAME being searched is also lowercased. */
hash = mapped_index_string_hash ((index->version == 4
&& case_sensitivity == case_sensitive_off
@@ -2174,13 +2272,41 @@ dwarf2_read_index (struct objfile *objfile)
/* Versions earlier than 3 emitted every copy of a psymbol. This
causes the index to behave very poorly for certain requests. Version 3
contained incomplete addrmap. So, it seems better to just ignore such
- indices. Index version 4 uses a different hash function than index
- version 5 and later. */
+ indices. */
if (version < 4)
- return 0;
+ {
+ static int warning_printed = 0;
+ if (!warning_printed)
+ {
+ warning (_("Skipping obsolete .gdb_index section in %s."),
+ objfile->name);
+ warning_printed = 1;
+ }
+ return 0;
+ }
+ /* Index version 4 uses a different hash function than index version
+ 5 and later.
+
+ Versions earlier than 6 did not emit psymbols for inlined
+ functions. Using these files will cause GDB not to be able to
+ set breakpoints on inlined functions by name, so we ignore these
+ indices unless the --use-deprecated-index-sections command line
+ option was supplied. */
+ if (version < 6 && !use_deprecated_index_sections)
+ {
+ static int warning_printed = 0;
+ if (!warning_printed)
+ {
+ warning (_("Skipping deprecated .gdb_index section in %s, pass "
+ "--use-deprecated-index-sections to use them anyway"),
+ objfile->name);
+ warning_printed = 1;
+ }
+ return 0;
+ }
/* Indexes with higher version than the one supported by GDB may be no
longer backward compatible. */
- if (version > 5)
+ if (version > 6)
return 0;
map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
@@ -2214,6 +2340,10 @@ dwarf2_read_index (struct objfile *objfile)
map->constant_pool = addr + MAYBE_SWAP (metadata[i]);
+ /* Don't use the index if it's empty. */
+ if (map->symbol_table_slots == 0)
+ return 0;
+
if (!create_cus_from_index (objfile, cu_list, cu_list_elements))
return 0;
@@ -2255,72 +2385,32 @@ dw2_setup (struct objfile *objfile)
gdb_assert (dwarf2_per_objfile);
}
-/* A helper for the "quick" functions which attempts to read the line
- table for THIS_CU. */
+/* die_reader_func for dw2_get_file_names. */
-static struct quick_file_names *
-dw2_get_file_names (struct objfile *objfile,
- struct dwarf2_per_cu_data *this_cu)
+static void
+dw2_get_file_names_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
{
- bfd *abfd = objfile->obfd;
+ struct dwarf2_cu *cu = reader->cu;
+ struct dwarf2_per_cu_data *this_cu = cu->per_cu;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
struct line_header *lh;
struct attribute *attr;
- struct cleanup *cleanups;
- struct die_info *comp_unit_die;
- struct dwarf2_section_info* sec;
- gdb_byte *beg_of_comp_unit, *info_ptr, *buffer;
- int has_children, i;
- struct dwarf2_cu cu;
- unsigned int bytes_read, buffer_size;
- struct die_reader_specs reader_specs;
+ int i;
+ unsigned int bytes_read;
char *name, *comp_dir;
void **slot;
struct quick_file_names *qfn;
unsigned int line_offset;
- if (this_cu->v.quick->file_names != NULL)
- return this_cu->v.quick->file_names;
- /* If we know there is no line data, no point in looking again. */
- if (this_cu->v.quick->no_file_data)
- return NULL;
-
- init_one_comp_unit (&cu, objfile);
- cleanups = make_cleanup (free_stack_comp_unit, &cu);
-
- if (this_cu->debug_type_section)
- sec = this_cu->debug_type_section;
- else
- sec = &dwarf2_per_objfile->info;
- dwarf2_read_section (objfile, sec);
- buffer_size = sec->size;
- buffer = sec->buffer;
- info_ptr = buffer + this_cu->offset;
- beg_of_comp_unit = info_ptr;
-
- info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr,
- buffer, buffer_size,
- abfd);
-
- /* Complete the cu_header. */
- cu.header.offset = beg_of_comp_unit - buffer;
- cu.header.first_die_offset = info_ptr - beg_of_comp_unit;
-
- this_cu->cu = &cu;
- cu.per_cu = this_cu;
-
- dwarf2_read_abbrevs (abfd, &cu);
- make_cleanup (dwarf2_free_abbrev_table, &cu);
-
- if (this_cu->debug_type_section)
- info_ptr += 8 /*signature*/ + cu.header.offset_size;
- init_cu_die_reader (&reader_specs, &cu);
- read_full_die (&reader_specs, &comp_unit_die, info_ptr,
- &has_children);
-
lh = NULL;
slot = NULL;
line_offset = 0;
- attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, &cu);
+
+ attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
if (attr)
{
struct quick_file_names find_entry;
@@ -2334,18 +2424,16 @@ dw2_get_file_names (struct objfile *objfile,
&find_entry, INSERT);
if (*slot != NULL)
{
- do_cleanups (cleanups);
this_cu->v.quick->file_names = *slot;
- return *slot;
+ return;
}
- lh = dwarf_decode_line_header (line_offset, abfd, &cu);
+ lh = dwarf_decode_line_header (line_offset, cu);
}
if (lh == NULL)
{
- do_cleanups (cleanups);
this_cu->v.quick->no_file_data = 1;
- return NULL;
+ return;
}
qfn = obstack_alloc (&objfile->objfile_obstack, sizeof (*qfn));
@@ -2353,7 +2441,7 @@ dw2_get_file_names (struct objfile *objfile,
gdb_assert (slot != NULL);
*slot = qfn;
- find_file_and_directory (comp_unit_die, &cu, &name, &comp_dir);
+ find_file_and_directory (comp_unit_die, cu, &name, &comp_dir);
qfn->num_file_names = lh->num_file_names;
qfn->file_names = obstack_alloc (&objfile->objfile_obstack,
@@ -2363,10 +2451,35 @@ dw2_get_file_names (struct objfile *objfile,
qfn->real_names = NULL;
free_line_header (lh);
- do_cleanups (cleanups);
this_cu->v.quick->file_names = qfn;
- return qfn;
+}
+
+/* A helper for the "quick" functions which attempts to read the line
+ table for THIS_CU. */
+
+static struct quick_file_names *
+dw2_get_file_names (struct objfile *objfile,
+ struct dwarf2_per_cu_data *this_cu)
+{
+ if (this_cu->v.quick->file_names != NULL)
+ return this_cu->v.quick->file_names;
+ /* If we know there is no line data, no point in looking again. */
+ if (this_cu->v.quick->no_file_data)
+ return NULL;
+
+ /* If DWO files are in use, we can still find the DW_AT_stmt_list attribute
+ in the stub for CUs, there's is no need to lookup the DWO file.
+ However, that's not the case for TUs where DW_AT_stmt_list lives in the
+ DWO file. */
+ if (this_cu->is_debug_types)
+ init_tu_and_read_dies (this_cu, 0, dw2_get_file_names_reader, NULL);
+ else
+ init_cutu_and_read_dies_simple (this_cu, dw2_get_file_names_reader, NULL);
+
+ if (this_cu->v.quick->no_file_data)
+ return NULL;
+ return this_cu->v.quick->file_names;
}
/* A helper for the "quick" functions which computes and caches the
@@ -2393,7 +2506,7 @@ dw2_find_last_source_symtab (struct objfile *objfile)
dw2_setup (objfile);
index = dwarf2_per_objfile->n_comp_units - 1;
- return dw2_instantiate_symtab (objfile, dw2_get_cu (index));
+ return dw2_instantiate_symtab (dw2_get_cu (index));
}
/* Traversal function for dw2_forget_cached_source_info. */
@@ -2426,24 +2539,54 @@ dw2_forget_cached_source_info (struct objfile *objfile)
dw2_free_cached_file_names, NULL);
}
+/* Helper function for dw2_map_symtabs_matching_filename that expands
+ the symtabs and calls the iterator. */
+
+static int
+dw2_map_expand_apply (struct objfile *objfile,
+ struct dwarf2_per_cu_data *per_cu,
+ const char *name,
+ const char *full_path, const char *real_path,
+ int (*callback) (struct symtab *, void *),
+ void *data)
+{
+ struct symtab *last_made = objfile->symtabs;
+
+ /* Don't visit already-expanded CUs. */
+ if (per_cu->v.quick->symtab)
+ return 0;
+
+ /* This may expand more than one symtab, and we want to iterate over
+ all of them. */
+ dw2_instantiate_symtab (per_cu);
+
+ return iterate_over_some_symtabs (name, full_path, real_path, callback, data,
+ objfile->symtabs, last_made);
+}
+
+/* Implementation of the map_symtabs_matching_filename method. */
+
static int
-dw2_lookup_symtab (struct objfile *objfile, const char *name,
- const char *full_path, const char *real_path,
- struct symtab **result)
+dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
+ const char *full_path, const char *real_path,
+ int (*callback) (struct symtab *, void *),
+ void *data)
{
int i;
- int check_basename = lbasename (name) == name;
- struct dwarf2_per_cu_data *base_cu = NULL;
+ const char *name_basename = lbasename (name);
+ int name_len = strlen (name);
+ int is_abs = IS_ABSOLUTE_PATH (name);
dw2_setup (objfile);
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
struct quick_file_names *file_data;
+ /* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->symtab)
continue;
@@ -2455,15 +2598,21 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name,
{
const char *this_name = file_data->file_names[j];
- if (FILENAME_CMP (name, this_name) == 0)
+ if (FILENAME_CMP (name, this_name) == 0
+ || (!is_abs && compare_filenames_for_search (this_name,
+ name, name_len)))
{
- *result = dw2_instantiate_symtab (objfile, per_cu);
- return 1;
+ if (dw2_map_expand_apply (objfile, per_cu,
+ name, full_path, real_path,
+ callback, data))
+ return 1;
}
- if (check_basename && ! base_cu
- && FILENAME_CMP (lbasename (this_name), name) == 0)
- base_cu = per_cu;
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (! basenames_may_differ
+ && FILENAME_CMP (lbasename (this_name), name_basename) != 0)
+ continue;
if (full_path != NULL)
{
@@ -2471,10 +2620,15 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name,
file_data, j);
if (this_real_name != NULL
- && FILENAME_CMP (full_path, this_real_name) == 0)
+ && (FILENAME_CMP (full_path, this_real_name) == 0
+ || (!is_abs
+ && compare_filenames_for_search (this_real_name,
+ name, name_len))))
{
- *result = dw2_instantiate_symtab (objfile, per_cu);
- return 1;
+ if (dw2_map_expand_apply (objfile, per_cu,
+ name, full_path, real_path,
+ callback, data))
+ return 1;
}
}
@@ -2484,21 +2638,20 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name,
file_data, j);
if (this_real_name != NULL
- && FILENAME_CMP (real_path, this_real_name) == 0)
+ && (FILENAME_CMP (real_path, this_real_name) == 0
+ || (!is_abs
+ && compare_filenames_for_search (this_real_name,
+ name, name_len))))
{
- *result = dw2_instantiate_symtab (objfile, per_cu);
- return 1;
+ if (dw2_map_expand_apply (objfile, per_cu,
+ name, full_path, real_path,
+ callback, data))
+ return 1;
}
}
}
}
- if (base_cu)
- {
- *result = dw2_instantiate_symtab (objfile, base_cu);
- return 1;
- }
-
return 0;
}
@@ -2533,7 +2686,7 @@ dw2_do_expand_symtabs_matching (struct objfile *objfile, const char *name)
offset_type cu_index = MAYBE_SWAP (vec[i + 1]);
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (cu_index);
- dw2_instantiate_symtab (objfile, per_cu);
+ dw2_instantiate_symtab (per_cu);
}
}
}
@@ -2555,7 +2708,7 @@ dw2_print_stats (struct objfile *objfile)
dw2_setup (objfile);
count = 0;
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
@@ -2593,11 +2746,11 @@ dw2_expand_all_symtabs (struct objfile *objfile)
dw2_setup (objfile);
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
- dw2_instantiate_symtab (objfile, per_cu);
+ dw2_instantiate_symtab (per_cu);
}
}
@@ -2620,6 +2773,7 @@ dw2_expand_symtabs_with_filename (struct objfile *objfile,
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
struct quick_file_names *file_data;
+ /* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->symtab)
continue;
@@ -2632,7 +2786,7 @@ dw2_expand_symtabs_with_filename (struct objfile *objfile,
const char *this_name = file_data->file_names[j];
if (FILENAME_CMP (this_name, filename) == 0)
{
- dw2_instantiate_symtab (objfile, per_cu);
+ dw2_instantiate_symtab (per_cu);
break;
}
}
@@ -2650,7 +2804,21 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name)
/* index_table is NULL if OBJF_READNOW. */
if (!dwarf2_per_objfile->index_table)
- return NULL;
+ {
+ struct symtab *s;
+
+ ALL_OBJFILE_SYMTABS (objfile, s)
+ if (s->primary)
+ {
+ struct blockvector *bv = BLOCKVECTOR (s);
+ const struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ struct symbol *sym = lookup_block_symbol (block, name, VAR_DOMAIN);
+
+ if (sym)
+ return sym->symtab->filename;
+ }
+ return NULL;
+ }
if (!find_slot_in_mapped_hash (dwarf2_per_objfile->index_table,
name, &vec))
@@ -2684,11 +2852,12 @@ dw2_map_matching_symbols (const char * name, domain_enum namespace,
}
static void
-dw2_expand_symtabs_matching (struct objfile *objfile,
- int (*file_matcher) (const char *, void *),
- int (*name_matcher) (const char *, void *),
- enum search_domain kind,
- void *data)
+dw2_expand_symtabs_matching
+ (struct objfile *objfile,
+ int (*file_matcher) (const char *, void *),
+ int (*name_matcher) (const char *, void *),
+ enum search_domain kind,
+ void *data)
{
int i;
offset_type iter;
@@ -2702,30 +2871,63 @@ dw2_expand_symtabs_matching (struct objfile *objfile,
index = dwarf2_per_objfile->index_table;
if (file_matcher != NULL)
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
- {
- int j;
- struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
- struct quick_file_names *file_data;
+ {
+ struct cleanup *cleanup;
+ htab_t visited_found, visited_not_found;
- per_cu->v.quick->mark = 0;
- if (per_cu->v.quick->symtab)
- continue;
+ visited_found = htab_create_alloc (10,
+ htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (visited_found);
+ visited_not_found = htab_create_alloc (10,
+ htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ make_cleanup_htab_delete (visited_not_found);
- file_data = dw2_get_file_names (objfile, per_cu);
- if (file_data == NULL)
- continue;
+ for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_type_units); ++i)
+ {
+ int j;
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+ struct quick_file_names *file_data;
+ void **slot;
- for (j = 0; j < file_data->num_file_names; ++j)
- {
- if (file_matcher (file_data->file_names[j], data))
- {
- per_cu->v.quick->mark = 1;
- break;
- }
- }
- }
+ per_cu->v.quick->mark = 0;
+
+ /* We only need to look at symtabs not already expanded. */
+ if (per_cu->v.quick->symtab)
+ continue;
+
+ file_data = dw2_get_file_names (objfile, per_cu);
+ if (file_data == NULL)
+ continue;
+
+ if (htab_find (visited_not_found, file_data) != NULL)
+ continue;
+ else if (htab_find (visited_found, file_data) != NULL)
+ {
+ per_cu->v.quick->mark = 1;
+ continue;
+ }
+
+ for (j = 0; j < file_data->num_file_names; ++j)
+ {
+ if (file_matcher (file_data->file_names[j], data))
+ {
+ per_cu->v.quick->mark = 1;
+ break;
+ }
+ }
+
+ slot = htab_find_slot (per_cu->v.quick->mark
+ ? visited_found
+ : visited_not_found,
+ file_data, INSERT);
+ *slot = file_data;
+ }
+
+ do_cleanups (cleanup);
+ }
for (iter = 0; iter < index->symbol_table_slots; ++iter)
{
@@ -2752,7 +2954,7 @@ dw2_expand_symtabs_matching (struct objfile *objfile,
per_cu = dw2_get_cu (MAYBE_SWAP (vec[vec_idx + 1]));
if (file_matcher == NULL || per_cu->v.quick->mark)
- dw2_instantiate_symtab (objfile, per_cu);
+ dw2_instantiate_symtab (per_cu);
}
}
}
@@ -2779,24 +2981,45 @@ 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);
+ return dw2_instantiate_symtab (data);
}
static void
dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
- void *data)
+ void *data, int need_fullname)
{
int i;
+ struct cleanup *cleanup;
+ htab_t visited = htab_create_alloc (10, htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (visited);
dw2_setup (objfile);
+ /* We can ignore file names coming from already-expanded CUs. */
+ for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_type_units); ++i)
+ {
+ 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
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
struct quick_file_names *file_data;
+ void **slot;
+ /* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->symtab)
continue;
@@ -2804,13 +3027,27 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
if (file_data == NULL)
continue;
+ slot = htab_find_slot (visited, file_data, INSERT);
+ if (*slot)
+ {
+ /* Already visited. */
+ continue;
+ }
+ *slot = file_data;
+
for (j = 0; j < file_data->num_file_names; ++j)
{
- const char *this_real_name = dw2_get_real_path (objfile, file_data,
- j);
+ const char *this_real_name;
+
+ if (need_fullname)
+ this_real_name = dw2_get_real_path (objfile, file_data, j);
+ else
+ this_real_name = NULL;
(*fun) (file_data->file_names[j], this_real_name, data);
}
}
+
+ do_cleanups (cleanup);
}
static int
@@ -2824,7 +3061,7 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions =
dw2_has_symbols,
dw2_find_last_source_symtab,
dw2_forget_cached_source_info,
- dw2_lookup_symtab,
+ dw2_map_symtabs_matching_filename,
dw2_lookup_symbol,
dw2_pre_expand_symtabs_matching,
dw2_print_stats,
@@ -2856,12 +3093,12 @@ dwarf2_initialize_objfile (struct objfile *objfile)
dwarf2_per_objfile->using_index = 1;
create_all_comp_units (objfile);
- create_debug_types_hash_table (objfile);
+ create_all_type_units (objfile);
dwarf2_per_objfile->quick_file_names_table =
create_quick_file_names_table (dwarf2_per_objfile->n_comp_units);
for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_comp_units); ++i)
+ + dwarf2_per_objfile->n_type_units); ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
@@ -2899,14 +3136,13 @@ dwarf2_build_psymtabs (struct objfile *objfile)
/* Return TRUE if OFFSET is within CU_HEADER. */
static inline int
-offset_in_cu_p (const struct comp_unit_head *cu_header, unsigned int offset)
+offset_in_cu_p (const struct comp_unit_head *cu_header, sect_offset offset)
{
- unsigned int bottom = cu_header->offset;
- unsigned int top = (cu_header->offset
- + cu_header->length
- + cu_header->initial_length_size);
+ sect_offset bottom = { cu_header->offset.sect_off };
+ sect_offset top = { (cu_header->offset.sect_off + cu_header->length
+ + cu_header->initial_length_size) };
- return (offset >= bottom && offset < top);
+ return (offset.sect_off >= bottom.sect_off && offset.sect_off < top.sect_off);
}
/* Read in the comp unit header information from the debug_info at info_ptr.
@@ -2926,8 +3162,8 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
info_ptr += bytes_read;
cu_header->version = read_2_bytes (abfd, info_ptr);
info_ptr += 2;
- cu_header->abbrev_offset = read_offset (abfd, info_ptr, cu_header,
- &bytes_read);
+ cu_header->abbrev_offset.sect_off = read_offset (abfd, info_ptr, cu_header,
+ &bytes_read);
info_ptr += bytes_read;
cu_header->addr_size = read_1_byte (abfd, info_ptr);
info_ptr += 1;
@@ -2940,36 +3176,66 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
return info_ptr;
}
-static gdb_byte *
-partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr,
- gdb_byte *buffer, unsigned int buffer_size,
- bfd *abfd)
-{
- gdb_byte *beg_of_comp_unit = info_ptr;
+/* Subroutine of read_and_check_comp_unit_head and
+ read_and_check_type_unit_head to simplify them.
+ Perform various error checking on the header. */
- info_ptr = read_comp_unit_head (header, info_ptr, abfd);
+static void
+error_check_comp_unit_head (struct comp_unit_head *header,
+ struct dwarf2_section_info *section)
+{
+ bfd *abfd = section->asection->owner;
+ const char *filename = bfd_get_filename (abfd);
if (header->version != 2 && header->version != 3 && header->version != 4)
error (_("Dwarf Error: wrong version in compilation unit header "
"(is %d, should be 2, 3, or 4) [in module %s]"), header->version,
- bfd_get_filename (abfd));
+ filename);
- if (header->abbrev_offset
+ if (header->abbrev_offset.sect_off
>= dwarf2_section_size (dwarf2_per_objfile->objfile,
&dwarf2_per_objfile->abbrev))
error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
"(offset 0x%lx + 6) [in module %s]"),
- (long) header->abbrev_offset,
- (long) (beg_of_comp_unit - buffer),
- bfd_get_filename (abfd));
-
- if (beg_of_comp_unit + header->length + header->initial_length_size
- > buffer + buffer_size)
+ (long) header->abbrev_offset.sect_off, (long) header->offset.sect_off,
+ filename);
+
+ /* Cast to unsigned long to use 64-bit arithmetic when possible to
+ avoid potential 32-bit overflow. */
+ if (((unsigned long) header->offset.sect_off
+ + header->length + header->initial_length_size)
+ > section->size)
error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
"(offset 0x%lx + 0) [in module %s]"),
- (long) header->length,
- (long) (beg_of_comp_unit - buffer),
- bfd_get_filename (abfd));
+ (long) header->length, (long) header->offset.sect_off,
+ filename);
+}
+
+/* Read in a CU/TU header and perform some basic error checking.
+ The contents of the header are stored in HEADER.
+ The result is a pointer to the start of the first DIE. */
+
+static gdb_byte *
+read_and_check_comp_unit_head (struct comp_unit_head *header,
+ struct dwarf2_section_info *section,
+ gdb_byte *info_ptr,
+ int is_debug_types_section)
+{
+ gdb_byte *beg_of_comp_unit = info_ptr;
+ bfd *abfd = section->asection->owner;
+
+ header->offset.sect_off = beg_of_comp_unit - section->buffer;
+
+ info_ptr = read_comp_unit_head (header, info_ptr, abfd);
+
+ /* If we're reading a type unit, skip over the signature and
+ type_offset fields. */
+ if (is_debug_types_section)
+ info_ptr += 8 /*signature*/ + header->offset_size;
+
+ header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
+
+ error_check_comp_unit_head (header, section);
return info_ptr;
}
@@ -2978,24 +3244,34 @@ partial_read_comp_unit_head (struct comp_unit_head *header, gdb_byte *info_ptr,
types_ptr. The result is a pointer to one past the end of the header. */
static gdb_byte *
-read_type_comp_unit_head (struct comp_unit_head *cu_header,
- struct dwarf2_section_info *section,
- ULONGEST *signature,
- gdb_byte *types_ptr, bfd *abfd)
+read_and_check_type_unit_head (struct comp_unit_head *header,
+ struct dwarf2_section_info *section,
+ gdb_byte *info_ptr,
+ ULONGEST *signature,
+ cu_offset *type_offset_in_tu)
{
- gdb_byte *initial_types_ptr = types_ptr;
+ gdb_byte *beg_of_comp_unit = info_ptr;
+ bfd *abfd = section->asection->owner;
- dwarf2_read_section (dwarf2_per_objfile->objfile, section);
- cu_header->offset = types_ptr - section->buffer;
+ header->offset.sect_off = beg_of_comp_unit - section->buffer;
+
+ info_ptr = read_comp_unit_head (header, info_ptr, abfd);
+
+ /* 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);
- return types_ptr;
+ return info_ptr;
}
/* Allocate a new partial symtab for file named NAME and mark this new
@@ -3037,41 +3313,35 @@ dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst,
static void
dwarf2_build_include_psymtabs (struct dwarf2_cu *cu,
- struct die_info *die,
- struct partial_symtab *pst)
+ struct die_info *die,
+ struct partial_symtab *pst)
{
- struct objfile *objfile = cu->objfile;
- bfd *abfd = objfile->obfd;
struct line_header *lh = NULL;
struct attribute *attr;
attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
if (attr)
- {
- unsigned int line_offset = DW_UNSND (attr);
-
- lh = dwarf_decode_line_header (line_offset, abfd, cu);
- }
+ lh = dwarf_decode_line_header (DW_UNSND (attr), cu);
if (lh == NULL)
return; /* No linetable, so no includes. */
/* NOTE: pst->dirname is DW_AT_comp_dir (if present). */
- dwarf_decode_lines (lh, pst->dirname, abfd, cu, pst);
+ dwarf_decode_lines (lh, pst->dirname, cu, pst, 1);
free_line_header (lh);
}
static hashval_t
-hash_type_signature (const void *item)
+hash_signatured_type (const void *item)
{
- const struct signatured_type *type_sig = item;
+ const struct signatured_type *sig_type = item;
/* This drops the top 32 bits of the signature, but is ok for a hash. */
- return type_sig->signature;
+ return sig_type->signature;
}
static int
-eq_type_signature (const void *item_lhs, const void *item_rhs)
+eq_signatured_type (const void *item_lhs, const void *item_rhs)
{
const struct signatured_type *lhs = item_lhs;
const struct signatured_type *rhs = item_rhs;
@@ -3085,18 +3355,18 @@ static htab_t
allocate_signatured_type_table (struct objfile *objfile)
{
return htab_create_alloc_ex (41,
- hash_type_signature,
- eq_type_signature,
+ hash_signatured_type,
+ eq_signatured_type,
NULL,
&objfile->objfile_obstack,
hashtab_obstack_allocate,
dummy_obstack_deallocate);
}
-/* A helper function to add a signatured type CU to a list. */
+/* A helper function to add a signatured type CU to a table. */
static int
-add_signatured_type_cu_to_list (void **slot, void *datum)
+add_signatured_type_cu_to_table (void **slot, void *datum)
{
struct signatured_type *sigt = *slot;
struct dwarf2_per_cu_data ***datap = datum;
@@ -3108,28 +3378,27 @@ add_signatured_type_cu_to_list (void **slot, void *datum)
}
/* Create the hash table of all entries in the .debug_types section.
- The result is zero if there is an error (e.g. missing .debug_types section),
- otherwise non-zero. */
+ DWO_FILE is a pointer to the DWO file for .debug_types.dwo, NULL otherwise.
+ The result is a pointer to the hash table or NULL if there are
+ no types. */
-static int
-create_debug_types_hash_table (struct objfile *objfile)
+static htab_t
+create_debug_types_hash_table (struct dwo_file *dwo_file,
+ VEC (dwarf2_section_info_def) *types)
{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
htab_t types_htab = NULL;
- struct dwarf2_per_cu_data **iter;
int ix;
struct dwarf2_section_info *section;
- if (VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types))
- {
- dwarf2_per_objfile->signatured_types = NULL;
- return 0;
- }
+ if (VEC_empty (dwarf2_section_info_def, types))
+ return NULL;
for (ix = 0;
- VEC_iterate (dwarf2_section_info_def, dwarf2_per_objfile->types,
- ix, section);
+ VEC_iterate (dwarf2_section_info_def, types, ix, section);
++ix)
{
+ bfd *abfd;
gdb_byte *info_ptr, *end_ptr;
dwarf2_read_section (objfile, section);
@@ -3138,102 +3407,164 @@ create_debug_types_hash_table (struct objfile *objfile)
if (info_ptr == NULL)
continue;
+ /* We can't set abfd until now because the section may be empty or
+ not present, in which case section->asection will be NULL. */
+ abfd = section->asection->owner;
+
if (types_htab == NULL)
- types_htab = allocate_signatured_type_table (objfile);
+ {
+ if (dwo_file)
+ types_htab = allocate_dwo_unit_table (objfile);
+ else
+ types_htab = allocate_signatured_type_table (objfile);
+ }
if (dwarf2_die_debug)
- fprintf_unfiltered (gdb_stdlog, "Signatured types:\n");
+ fprintf_unfiltered (gdb_stdlog, "Reading signatured types for %s:\n",
+ bfd_get_filename (abfd));
+
+ /* We don't use init_cutu_and_read_dies_simple, or some such, here
+ because we don't need to read any dies: the signature is in the
+ header. */
end_ptr = info_ptr + section->size;
while (info_ptr < end_ptr)
{
- unsigned int offset;
- unsigned int offset_size;
- unsigned int type_offset;
- unsigned int length, initial_length_size;
- unsigned short version;
+ sect_offset offset;
+ cu_offset type_offset_in_tu;
ULONGEST signature;
- struct signatured_type *type_sig;
+ struct signatured_type *sig_type;
+ struct dwo_unit *dwo_tu;
void **slot;
gdb_byte *ptr = info_ptr;
+ struct comp_unit_head header;
+ unsigned int length;
- offset = ptr - section->buffer;
+ offset.sect_off = ptr - section->buffer;
/* We need to read the type's signature in order to build the hash
- table, but we don't need to read anything else just yet. */
+ table, but we don't need anything else just yet. */
+
+ ptr = read_and_check_type_unit_head (&header, section, ptr,
+ &signature, &type_offset_in_tu);
- /* 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)
+ length = header.initial_length_size + header.length;
+
+ /* Skip dummy type units. */
+ if (ptr >= info_ptr + length
+ || peek_abbrev_code (abfd, ptr) == 0)
{
- complaint (&symfile_complaints,
- _("debug type entry runs off end "
- "of `.debug_types' section, ignored"));
- break;
+ info_ptr += header.initial_length_size + header.length;
+ continue;
}
- offset_size = initial_length_size == 4 ? 4 : 8;
- ptr += initial_length_size;
- version = bfd_get_16 (objfile->obfd, ptr);
- ptr += 2;
- ptr += offset_size; /* abbrev offset */
- ptr += 1; /* address size */
- signature = bfd_get_64 (objfile->obfd, ptr);
- ptr += 8;
- type_offset = read_offset_1 (objfile->obfd, ptr, offset_size);
-
- type_sig = obstack_alloc (&objfile->objfile_obstack, sizeof (*type_sig));
- memset (type_sig, 0, sizeof (*type_sig));
- type_sig->signature = signature;
- type_sig->type_offset = type_offset;
- type_sig->per_cu.objfile = objfile;
- type_sig->per_cu.debug_type_section = section;
- type_sig->per_cu.offset = offset;
-
- slot = htab_find_slot (types_htab, type_sig, INSERT);
+ 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,
+ dwo_file ? (void*) dwo_tu : (void *) sig_type,
+ INSERT);
gdb_assert (slot != NULL);
if (*slot != NULL)
{
- const struct signatured_type *dup_sig = *slot;
+ sect_offset dup_offset;
+
+ if (dwo_file)
+ {
+ const struct dwo_unit *dup_tu = *slot;
+
+ dup_offset = dup_tu->offset;
+ }
+ else
+ {
+ const struct signatured_type *dup_tu = *slot;
+
+ dup_offset = dup_tu->per_cu.offset;
+ }
complaint (&symfile_complaints,
_("debug type entry at offset 0x%x is duplicate to the "
"entry at offset 0x%x, signature 0x%s"),
- offset, dup_sig->per_cu.offset,
+ offset.sect_off, dup_offset.sect_off,
phex (signature, sizeof (signature)));
- gdb_assert (signature == dup_sig->signature);
}
- *slot = type_sig;
+ *slot = dwo_file ? (void *) dwo_tu : (void *) sig_type;
if (dwarf2_die_debug)
fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n",
- offset, phex (signature, sizeof (signature)));
+ offset.sect_off,
+ phex (signature, sizeof (signature)));
- info_ptr = info_ptr + initial_length_size + length;
+ info_ptr += length;
}
}
+ return types_htab;
+}
+
+/* Create the hash table of all entries in the .debug_types section,
+ and initialize all_type_units.
+ The result is zero if there is an error (e.g. missing .debug_types section),
+ otherwise non-zero. */
+
+static int
+create_all_type_units (struct objfile *objfile)
+{
+ htab_t types_htab;
+ struct dwarf2_per_cu_data **iter;
+
+ types_htab = create_debug_types_hash_table (NULL, dwarf2_per_objfile->types);
+ if (types_htab == NULL)
+ {
+ dwarf2_per_objfile->signatured_types = NULL;
+ return 0;
+ }
+
dwarf2_per_objfile->signatured_types = types_htab;
- dwarf2_per_objfile->n_type_comp_units = htab_elements (types_htab);
- dwarf2_per_objfile->type_comp_units
+ dwarf2_per_objfile->n_type_units = htab_elements (types_htab);
+ dwarf2_per_objfile->all_type_units
= obstack_alloc (&objfile->objfile_obstack,
- dwarf2_per_objfile->n_type_comp_units
+ dwarf2_per_objfile->n_type_units
* sizeof (struct dwarf2_per_cu_data *));
- iter = &dwarf2_per_objfile->type_comp_units[0];
- htab_traverse_noresize (types_htab, add_signatured_type_cu_to_list, &iter);
- gdb_assert (iter - &dwarf2_per_objfile->type_comp_units[0]
- == dwarf2_per_objfile->n_type_comp_units);
+ iter = &dwarf2_per_objfile->all_type_units[0];
+ htab_traverse_noresize (types_htab, add_signatured_type_cu_to_table, &iter);
+ gdb_assert (iter - &dwarf2_per_objfile->all_type_units[0]
+ == dwarf2_per_objfile->n_type_units);
return 1;
}
-/* Lookup a signature based type.
- Returns NULL if SIG is not present in the table. */
+/* Lookup a signature based type for DW_FORM_ref_sig8.
+ Returns NULL if signature SIG is not present in the table. */
static struct signatured_type *
-lookup_signatured_type (struct objfile *objfile, ULONGEST sig)
+lookup_signatured_type (ULONGEST sig)
{
struct signatured_type find_entry, *entry;
@@ -3241,7 +3572,7 @@ lookup_signatured_type (struct objfile *objfile, ULONGEST sig)
{
complaint (&symfile_complaints,
_("missing `.debug_types' section for DW_FORM_ref_sig8 die"));
- return 0;
+ return NULL;
}
find_entry.signature = sig;
@@ -3253,20 +3584,16 @@ lookup_signatured_type (struct objfile *objfile, ULONGEST sig)
static void
init_cu_die_reader (struct die_reader_specs *reader,
- struct dwarf2_cu *cu)
+ struct dwarf2_cu *cu,
+ struct dwarf2_section_info *section,
+ struct dwo_file *dwo_file)
{
- reader->abfd = cu->objfile->obfd;
+ gdb_assert (section->readin);
+ reader->abfd = section->asection->owner;
reader->cu = cu;
- if (cu->per_cu->debug_type_section)
- {
- gdb_assert (cu->per_cu->debug_type_section->readin);
- reader->buffer = cu->per_cu->debug_type_section->buffer;
- }
- else
- {
- gdb_assert (dwarf2_per_objfile->info.readin);
- reader->buffer = dwarf2_per_objfile->info.buffer;
- }
+ reader->dwo_file = dwo_file;
+ reader->die_section = section;
+ reader->buffer = section->buffer;
}
/* Find the base address of the compilation unit for range lists and
@@ -3300,91 +3627,450 @@ dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
}
}
-/* Subroutine of process_type_comp_unit and dwarf2_build_psymtabs_hard
- to combine the common parts.
- Process a compilation unit for a psymtab.
- BUFFER is a pointer to the beginning of the dwarf section buffer,
- either .debug_info or debug_types.
- INFO_PTR is a pointer to the start of the CU.
- Returns a pointer to the next CU. */
+/* Subroutine of init_{cu,tu}_and_read_dies.
+ Do all the work necessary to initialize THIS_CU->cu and read in its DIE(s).
+ If the CU defers to a DWO file, read the DWO file as well.
-static gdb_byte *
-process_psymtab_comp_unit (struct objfile *objfile,
- struct dwarf2_per_cu_data *this_cu,
- gdb_byte *buffer, gdb_byte *info_ptr,
- unsigned int buffer_size)
-{
- bfd *abfd = objfile->obfd;
- gdb_byte *beg_of_comp_unit = info_ptr;
+ If USE_EXISTING_CU is non-zero, and THIS_CU->cu is non-NULL, then use it.
+ Otherwise, a new CU is allocated with xmalloc.
+
+ If KEEP is non-zero, then if we allocated a dwarf2_cu we add it to
+ read_in_chain. Otherwise the dwarf2_cu data is freed at the end.
+
+ WARNING: If THIS_CU is a "dummy CU" (used as filler by the incremental
+ linker) then DIE_READER_FUNC will not get called.
+
+ FIXME: As an implementation detail between our callers and us,
+ USE_EXISTING_CU and KEEP are OK. But bubbling them up into their callers
+ isn't as clean as I'd like. Having more callers with good names
+ may be the way to go. */
+
+static void
+init_and_read_dies_worker (struct dwarf2_per_cu_data *this_cu,
+ int use_existing_cu, int keep,
+ die_reader_func_ftype *die_reader_func,
+ void *data)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_section_info *section = this_cu->info_or_types_section;
+ bfd *abfd = section->asection->owner;
+ struct dwarf2_cu *cu;
+ gdb_byte *begin_info_ptr, *info_ptr;
+ struct die_reader_specs reader;
struct die_info *comp_unit_die;
- struct partial_symtab *pst;
- CORE_ADDR baseaddr;
- struct cleanup *back_to_inner;
- struct dwarf2_cu cu;
- int has_children, has_pc_info;
+ int has_children;
struct attribute *attr;
- CORE_ADDR best_lowpc = 0, best_highpc = 0;
- struct die_reader_specs reader_specs;
- const char *filename;
+ struct cleanup *cleanups, *free_cu_cleanup = NULL;
+ struct signatured_type *sig_type = NULL;
- init_one_comp_unit (&cu, objfile);
- back_to_inner = make_cleanup (free_stack_comp_unit, &cu);
+ if (use_existing_cu)
+ gdb_assert (keep);
+ if (this_cu->is_debug_types)
+ gdb_assert (! use_existing_cu);
- info_ptr = partial_read_comp_unit_head (&cu.header, info_ptr,
- buffer, buffer_size,
- abfd);
+ cleanups = make_cleanup (null_cleanup, NULL);
- /* Complete the cu_header. */
- cu.header.offset = beg_of_comp_unit - buffer;
- cu.header.first_die_offset = info_ptr - beg_of_comp_unit;
+ /* This is cheap if the section is already read in. */
+ dwarf2_read_section (objfile, section);
- cu.list_in_scope = &file_symbols;
+ begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
- /* If this compilation unit was already read in, free the
- cached copy in order to read it in again. This is
- necessary because we skipped some symbols when we first
- read in the compilation unit (see load_partial_dies).
- This problem could be avoided, but the benefit is
- unclear. */
- if (this_cu->cu != NULL)
- free_one_cached_comp_unit (this_cu->cu);
+ if (use_existing_cu && this_cu->cu != NULL)
+ {
+ cu = this_cu->cu;
+ info_ptr += cu->header.first_die_offset.cu_off;
+ }
+ else
+ {
+ /* If !use_existing_cu, this_cu->cu must be NULL. */
+ gdb_assert (this_cu->cu == NULL);
+
+ cu = xmalloc (sizeof (*cu));
+ init_one_comp_unit (cu, this_cu);
+
+ /* If an error occurs while loading, release our storage. */
+ free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu);
+
+ if (this_cu->is_debug_types)
+ {
+ ULONGEST signature;
+
+ info_ptr = read_and_check_type_unit_head (&cu->header,
+ section, info_ptr,
+ &signature, NULL);
+
+ /* There's no way to get from PER_CU to its containing
+ struct signatured_type.
+ But we have the signature so we can use that. */
+ sig_type = lookup_signatured_type (signature);
+ /* We've already scanned all the signatured types,
+ this must succeed. */
+ gdb_assert (sig_type != NULL);
+ gdb_assert (&sig_type->per_cu == this_cu);
+ gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
+
+ /* LENGTH has not been set yet for type units. */
+ this_cu->length = cu->header.length + cu->header.initial_length_size;
+
+ /* Establish the type offset that can be used to lookup the type. */
+ sig_type->type_offset_in_section.sect_off =
+ this_cu->offset.sect_off + sig_type->type_offset_in_tu.cu_off;
+ }
+ else
+ {
+ info_ptr = read_and_check_comp_unit_head (&cu->header,
+ section, info_ptr, 0);
+
+ gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
+ gdb_assert (this_cu->length
+ == cu->header.length + cu->header.initial_length_size);
+ }
+ }
- /* Note that this is a pointer to our stack frame, being
- added to a global data structure. It will be cleaned up
- in free_stack_comp_unit when we finish with this
- compilation unit. */
- this_cu->cu = &cu;
- cu.per_cu = this_cu;
+ /* Skip dummy compilation units. */
+ if (info_ptr >= begin_info_ptr + this_cu->length
+ || peek_abbrev_code (abfd, info_ptr) == 0)
+ {
+ do_cleanups (cleanups);
+ return;
+ }
/* Read the abbrevs for this compilation unit into a table. */
- dwarf2_read_abbrevs (abfd, &cu);
- make_cleanup (dwarf2_free_abbrev_table, &cu);
+ if (cu->dwarf2_abbrevs == NULL)
+ {
+ dwarf2_read_abbrevs (cu, &dwarf2_per_objfile->abbrev);
+ make_cleanup (dwarf2_free_abbrev_table, cu);
+ }
- /* Read the compilation unit die. */
- if (this_cu->debug_type_section)
- info_ptr += 8 /*signature*/ + cu.header.offset_size;
- init_cu_die_reader (&reader_specs, &cu);
- info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr,
- &has_children);
+ /* Read the top level CU/TU die. */
+ init_cu_die_reader (&reader, cu, section, NULL);
+ info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
- if (this_cu->debug_type_section)
+ /* 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)
{
- /* 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;
+ char *dwo_name = DW_STRING (attr);
+ const char *comp_dir;
+ struct dwo_unit *dwo_unit;
+ ULONGEST signature; /* Or dwo_id. */
+ struct attribute *stmt_list, *low_pc, *high_pc, *ranges;
+ int i,num_extra_attrs;
+
+ if (has_children)
+ error (_("Dwarf Error: compilation unit with DW_AT_GNU_dwo_name"
+ " has children (offset 0x%x) [in module %s]"),
+ this_cu->offset.sect_off, bfd_get_filename (abfd));
+
+ /* These attributes aren't processed until later:
+ DW_AT_stmt_list, DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges.
+ However, the attribute is found in the stub which we won't have later.
+ In order to not impose this complication on the rest of the code,
+ we read them here and copy them to the DWO CU/TU die. */
+ stmt_list = low_pc = high_pc = ranges = NULL;
+
+ /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
+ DWO file. */
+ if (! this_cu->is_debug_types)
+ stmt_list = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
+ low_pc = dwarf2_attr (comp_unit_die, DW_AT_low_pc, cu);
+ high_pc = dwarf2_attr (comp_unit_die, DW_AT_high_pc, cu);
+ ranges = dwarf2_attr (comp_unit_die, DW_AT_ranges, cu);
+
+ /* There should be a DW_AT_addr_base attribute here (if needed).
+ We need the value before we can process DW_FORM_GNU_addr_index. */
+ cu->addr_base = 0;
+ cu->have_addr_base = 0;
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_addr_base, cu);
+ if (attr)
+ {
+ cu->addr_base = DW_UNSND (attr);
+ cu->have_addr_base = 1;
+ }
+
+ if (this_cu->is_debug_types)
+ {
+ gdb_assert (sig_type != NULL);
+ signature = sig_type->signature;
+ }
+ else
+ {
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu);
+ if (! attr)
+ error (_("Dwarf Error: missing dwo_id [in module %s]"),
+ dwo_name);
+ signature = DW_UNSND (attr);
+ }
+
+ /* We may need the comp_dir in order to find the DWO file. */
+ comp_dir = NULL;
+ attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
+ if (attr)
+ comp_dir = DW_STRING (attr);
+
+ if (this_cu->is_debug_types)
+ dwo_unit = lookup_dwo_type_unit (sig_type, dwo_name, comp_dir);
+ else
+ dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir,
+ signature);
+
+ if (dwo_unit == NULL)
+ {
+ error (_("Dwarf Error: CU at offset 0x%x references unknown DWO"
+ " with ID %s [in module %s]"),
+ this_cu->offset.sect_off,
+ phex (signature, sizeof (signature)),
+ objfile->name);
+ }
+
+ /* Set up for reading the DWO CU/TU. */
+ cu->dwo_unit = dwo_unit;
+ section = dwo_unit->info_or_types_section;
+ begin_info_ptr = info_ptr = section->buffer + dwo_unit->offset.sect_off;
+ init_cu_die_reader (&reader, cu, section, dwo_unit->dwo_file);
+
+ if (this_cu->is_debug_types)
+ {
+ ULONGEST signature;
+
+ info_ptr = read_and_check_type_unit_head (&cu->header,
+ section, info_ptr,
+ &signature, NULL);
+ gdb_assert (sig_type->signature == signature);
+ gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+ gdb_assert (dwo_unit->length
+ == cu->header.length + cu->header.initial_length_size);
+
+ /* Establish the type offset that can be used to lookup the type.
+ For DWO files, we don't know it until now. */
+ sig_type->type_offset_in_section.sect_off =
+ dwo_unit->offset.sect_off + dwo_unit->type_offset_in_tu.cu_off;
+ }
+ else
+ {
+ info_ptr = read_and_check_comp_unit_head (&cu->header,
+ section, info_ptr, 0);
+ gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+ gdb_assert (dwo_unit->length
+ == cu->header.length + cu->header.initial_length_size);
+ }
+
+ /* Discard the original CU's abbrev table, and read the DWO's. */
+ dwarf2_free_abbrev_table (cu);
+ dwarf2_read_abbrevs (cu, &dwo_unit->dwo_file->sections.abbrev);
+
+ /* Read in the die, but leave space to copy over the attributes
+ from the stub. This has the benefit of simplifying the rest of
+ the code - all the real work is done here. */
+ num_extra_attrs = ((stmt_list != NULL)
+ + (low_pc != NULL)
+ + (high_pc != NULL)
+ + (ranges != NULL));
+ info_ptr = read_full_die_1 (&reader, &comp_unit_die, info_ptr,
+ &has_children, num_extra_attrs);
+
+ /* Copy over the attributes from the stub to the DWO die. */
+ i = comp_unit_die->num_attrs;
+ if (stmt_list != NULL)
+ comp_unit_die->attrs[i++] = *stmt_list;
+ if (low_pc != NULL)
+ comp_unit_die->attrs[i++] = *low_pc;
+ if (high_pc != NULL)
+ comp_unit_die->attrs[i++] = *high_pc;
+ if (ranges != NULL)
+ comp_unit_die->attrs[i++] = *ranges;
+ comp_unit_die->num_attrs += num_extra_attrs;
+
+ /* Skip dummy compilation units. */
+ if (info_ptr >= begin_info_ptr + dwo_unit->length
+ || peek_abbrev_code (abfd, info_ptr) == 0)
+ {
+ do_cleanups (cleanups);
+ return;
+ }
}
- else if (comp_unit_die->tag == DW_TAG_partial_unit)
+
+ die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
+
+ if (free_cu_cleanup != NULL)
{
- info_ptr = (beg_of_comp_unit + cu.header.length
- + cu.header.initial_length_size);
- do_cleanups (back_to_inner);
- return info_ptr;
+ if (keep)
+ {
+ /* We've successfully allocated this compilation unit. Let our
+ caller clean it up when finished with it. */
+ discard_cleanups (free_cu_cleanup);
+
+ /* We can only discard free_cu_cleanup and all subsequent cleanups.
+ So we have to manually free the abbrev table. */
+ dwarf2_free_abbrev_table (cu);
+
+ /* Link this CU into read_in_chain. */
+ this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
+ dwarf2_per_objfile->read_in_chain = this_cu;
+ }
+ else
+ do_cleanups (free_cu_cleanup);
+ }
+
+ do_cleanups (cleanups);
+}
+
+/* Main entry point for reading a CU.
+ Do all the work necessary to initialize THIS_CU->cu and read in its DIE(s).
+ If the CU defers to a DWO file, read the DWO file as well.
+
+ 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. */
+
+static void
+init_cu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
+ int use_existing_cu, int keep,
+ die_reader_func_ftype *die_reader_func,
+ void *data)
+{
+ init_and_read_dies_worker (this_cu, use_existing_cu, keep,
+ die_reader_func, data);
+}
+
+/* Main entry point for reading a TU.
+ Do all the work necessary to initialize THIS_CU->cu and read in its DIE(s).
+ If the TU defers to a DWO file, read the DWO file as well.
+
+ 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. */
+
+static void
+init_tu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
+ int keep,
+ die_reader_func_ftype *die_reader_func,
+ void *data)
+{
+ gdb_assert (this_cu->is_debug_types);
+ init_and_read_dies_worker (this_cu, 0, keep, die_reader_func, data);
+}
+
+/* Read CU/TU THIS_CU in section SECTION,
+ but do not follow DW_AT_GNU_dwo_name if present.
+ DWO_FILE, if non-NULL, is the DWO file to read (the caller is assumed to
+ have already done the lookup to find the DWO file).
+
+ The caller is required to fill in THIS_CU->section, THIS_CU->offset, and
+ THIS_CU->is_debug_types, but nothing else.
+
+ We fill in THIS_CU->length.
+
+ WARNING: If THIS_CU is a "dummy CU" (used as filler by the incremental
+ linker) then DIE_READER_FUNC will not get called.
+
+ THIS_CU->cu is always freed when done.
+ This is done in order to not leave THIS_CU->cu in a state where we have
+ to care whether it refers to the "main" CU or the DWO CU. */
+
+static void
+init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
+ struct dwarf2_section_info *abbrev_section,
+ struct dwo_file *dwo_file,
+ die_reader_func_ftype *die_reader_func,
+ void *data)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_section_info *section = this_cu->info_or_types_section;
+ bfd *abfd = section->asection->owner;
+ struct dwarf2_cu cu;
+ gdb_byte *begin_info_ptr, *info_ptr;
+ struct die_reader_specs reader;
+ struct cleanup *cleanups;
+ struct die_info *comp_unit_die;
+ int has_children;
+
+ gdb_assert (this_cu->cu == NULL);
+
+ /* This is cheap if the section is already read in. */
+ dwarf2_read_section (objfile, section);
+
+ init_one_comp_unit (&cu, this_cu);
+
+ cleanups = make_cleanup (free_stack_comp_unit, &cu);
+
+ begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
+ info_ptr = read_and_check_comp_unit_head (&cu.header, section, info_ptr,
+ this_cu->is_debug_types);
+
+ this_cu->length = cu.header.length + cu.header.initial_length_size;
+
+ /* Skip dummy compilation units. */
+ if (info_ptr >= begin_info_ptr + this_cu->length
+ || peek_abbrev_code (abfd, info_ptr) == 0)
+ {
+ do_cleanups (cleanups);
+ return;
}
- prepare_one_comp_unit (&cu, comp_unit_die);
+ dwarf2_read_abbrevs (&cu, abbrev_section);
+ make_cleanup (dwarf2_free_abbrev_table, &cu);
+
+ init_cu_die_reader (&reader, &cu, section, dwo_file);
+ info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
+
+ die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
+
+ do_cleanups (cleanups);
+}
+
+/* Read a CU/TU, except that this does not look for DW_AT_GNU_dwo_name and
+ does not lookup the specified DWO file.
+ This cannot be used to read DWO files.
+
+ THIS_CU->cu is always freed when done.
+ This is done in order to not leave THIS_CU->cu in a state where we have
+ to care whether it refers to the "main" CU or the DWO CU.
+ We can revisit this if the data shows there's a performance issue. */
+
+static void
+init_cutu_and_read_dies_simple (struct dwarf2_per_cu_data *this_cu,
+ die_reader_func_ftype *die_reader_func,
+ void *data)
+{
+ init_cutu_and_read_dies_no_follow (this_cu,
+ &dwarf2_per_objfile->abbrev,
+ NULL,
+ die_reader_func, data);
+}
+
+/* die_reader_func for process_psymtab_comp_unit. */
+
+static void
+process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
+{
+ struct dwarf2_cu *cu = reader->cu;
+ struct objfile *objfile = cu->objfile;
+ struct dwarf2_per_cu_data *per_cu = cu->per_cu;
+ bfd *abfd = objfile->obfd;
+ struct attribute *attr;
+ CORE_ADDR baseaddr;
+ CORE_ADDR best_lowpc = 0, best_highpc = 0;
+ struct partial_symtab *pst;
+ int has_pc_info;
+ const char *filename;
+
+ if (comp_unit_die->tag == DW_TAG_partial_unit)
+ return;
+
+ prepare_one_comp_unit (cu, comp_unit_die);
+
+ cu->list_in_scope = &file_symbols;
/* Allocate a new partial symbol table structure. */
- attr = dwarf2_attr (comp_unit_die, DW_AT_name, &cu);
+ attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
if (attr == NULL || !DW_STRING (attr))
filename = "";
else
@@ -3395,26 +4081,27 @@ process_psymtab_comp_unit (struct objfile *objfile,
0,
objfile->global_psymbols.next,
objfile->static_psymbols.next);
+ pst->psymtabs_addrmap_supported = 1;
- attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, &cu);
+ attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
if (attr != NULL)
pst->dirname = DW_STRING (attr);
- pst->read_symtab_private = this_cu;
+ pst->read_symtab_private = per_cu;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
/* Store the function that reads in the rest of the symbol table. */
pst->read_symtab = dwarf2_psymtab_to_symtab;
- this_cu->v.psymtab = pst;
+ per_cu->v.psymtab = pst;
- dwarf2_find_base_address (comp_unit_die, &cu);
+ dwarf2_find_base_address (comp_unit_die, cu);
/* Possibly set the default values of LOWPC and HIGHPC from
`DW_AT_ranges'. */
has_pc_info = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc,
- &best_highpc, &cu, pst);
+ &best_highpc, cu, pst);
if (has_pc_info == 1 && best_lowpc < best_highpc)
/* Store the contiguous range if it is not empty; it can be empty for
CUs with no code. */
@@ -3433,10 +4120,10 @@ process_psymtab_comp_unit (struct objfile *objfile,
lowpc = ((CORE_ADDR) -1);
highpc = ((CORE_ADDR) 0);
- first_die = load_partial_dies (abfd, buffer, info_ptr, 1, &cu);
+ first_die = load_partial_dies (reader, info_ptr, 1);
scan_partial_symbols (first_die, &lowpc, &highpc,
- ! has_pc_info, &cu);
+ ! has_pc_info, cu);
/* If we didn't find a lowpc, set it to highpc to avoid
complaints from `maint check'. */
@@ -3460,10 +4147,7 @@ process_psymtab_comp_unit (struct objfile *objfile,
(objfile->static_psymbols.list + pst->statics_offset);
sort_pst_symbols (pst);
- info_ptr = (beg_of_comp_unit + cu.header.length
- + cu.header.initial_length_size);
-
- if (this_cu->debug_type_section)
+ if (per_cu->is_debug_types)
{
/* It's not clear we want to do anything with stmt lists here.
Waiting to see what gcc ultimately does. */
@@ -3472,32 +4156,56 @@ process_psymtab_comp_unit (struct objfile *objfile,
{
/* Get the list of files included in the current compilation unit,
and build a psymtab for each of them. */
- dwarf2_build_include_psymtabs (&cu, comp_unit_die, pst);
+ dwarf2_build_include_psymtabs (cu, comp_unit_die, pst);
}
+}
- do_cleanups (back_to_inner);
+/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
+ Process compilation unit THIS_CU for a psymtab. */
- return info_ptr;
+static void
+process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu)
+{
+ /* If this compilation unit was already read in, free the
+ cached copy in order to read it in again. This is
+ necessary because we skipped some symbols when we first
+ read in the compilation unit (see load_partial_dies).
+ This problem could be avoided, but the benefit is unclear. */
+ if (this_cu->cu != NULL)
+ free_one_cached_comp_unit (this_cu);
+
+ gdb_assert (! this_cu->is_debug_types);
+ init_cu_and_read_dies (this_cu, 0, 0, process_psymtab_comp_unit_reader,
+ NULL);
+
+ /* Age out any secondary CUs. */
+ age_cached_comp_units ();
}
/* Traversal function for htab_traverse_noresize.
Process one .debug_types comp-unit. */
static int
-process_type_comp_unit (void **slot, void *info)
+process_psymtab_type_unit (void **slot, void *info)
{
- struct signatured_type *entry = (struct signatured_type *) *slot;
- struct objfile *objfile = (struct objfile *) info;
- struct dwarf2_per_cu_data *this_cu;
+ struct signatured_type *sig_type = (struct signatured_type *) *slot;
+ struct dwarf2_per_cu_data *per_cu = &sig_type->per_cu;
+
+ gdb_assert (info == NULL);
+
+ /* If this compilation unit was already read in, free the
+ cached copy in order to read it in again. This is
+ necessary because we skipped some symbols when we first
+ read in the compilation unit (see load_partial_dies).
+ This problem could be avoided, but the benefit is unclear. */
+ if (per_cu->cu != NULL)
+ free_one_cached_comp_unit (per_cu);
- this_cu = &entry->per_cu;
+ gdb_assert (per_cu->is_debug_types);
+ init_tu_and_read_dies (per_cu, 0, process_psymtab_comp_unit_reader, NULL);
- gdb_assert (this_cu->debug_type_section->readin);
- process_psymtab_comp_unit (objfile, this_cu,
- this_cu->debug_type_section->buffer,
- (this_cu->debug_type_section->buffer
- + this_cu->offset),
- this_cu->debug_type_section->size);
+ /* Age out any secondary CUs. */
+ age_cached_comp_units ();
return 1;
}
@@ -3508,11 +4216,11 @@ process_type_comp_unit (void **slot, void *info)
static void
build_type_psymtabs (struct objfile *objfile)
{
- if (! create_debug_types_hash_table (objfile))
+ if (! create_all_type_units (objfile))
return;
htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
- process_type_comp_unit, objfile);
+ process_psymtab_type_unit, NULL);
}
/* A cleanup function that clears objfile's psymtabs_addrmap field. */
@@ -3531,14 +4239,13 @@ psymtabs_addrmap_cleanup (void *o)
static void
dwarf2_build_psymtabs_hard (struct objfile *objfile)
{
- gdb_byte *info_ptr;
struct cleanup *back_to, *addrmap_cleanup;
struct obstack temp_obstack;
+ int i;
dwarf2_per_objfile->reading_partial_symbols = 1;
dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
- info_ptr = dwarf2_per_objfile->info.buffer;
/* Any cached compilation units will be linked by the per-objfile
read_in_chain. Make sure to free them when we're done. */
@@ -3555,33 +4262,11 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
objfile->psymtabs_addrmap = addrmap_create_mutable (&temp_obstack);
addrmap_cleanup = make_cleanup (psymtabs_addrmap_cleanup, objfile);
- /* Since the objects we're extracting from .debug_info vary in
- length, only the individual functions to extract them (like
- read_comp_unit_head and load_partial_die) can really know whether
- the buffer is large enough to hold another complete object.
-
- At the moment, they don't actually check that. If .debug_info
- holds just one extra byte after the last compilation unit's dies,
- then read_comp_unit_head will happily read off the end of the
- buffer. read_partial_die is similarly casual. Those functions
- should be fixed.
-
- For this loop condition, simply checking whether there's any data
- left at all should be sufficient. */
-
- while (info_ptr < (dwarf2_per_objfile->info.buffer
- + dwarf2_per_objfile->info.size))
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
- struct dwarf2_per_cu_data *this_cu;
-
- this_cu = dwarf2_find_comp_unit (info_ptr
- - dwarf2_per_objfile->info.buffer,
- objfile);
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
- info_ptr = process_psymtab_comp_unit (objfile, this_cu,
- dwarf2_per_objfile->info.buffer,
- info_ptr,
- dwarf2_per_objfile->info.size);
+ process_psymtab_comp_unit (per_cu);
}
objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
@@ -3591,69 +4276,16 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
do_cleanups (back_to);
}
-/* Load the partial DIEs for a secondary CU into memory. */
+/* die_reader_func for load_partial_comp_unit. */
static void
-load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu,
- struct objfile *objfile)
+load_partial_comp_unit_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
{
- bfd *abfd = objfile->obfd;
- gdb_byte *info_ptr, *beg_of_comp_unit;
- struct die_info *comp_unit_die;
- struct dwarf2_cu *cu;
- struct cleanup *free_abbrevs_cleanup, *free_cu_cleanup = NULL;
- int has_children;
- struct die_reader_specs reader_specs;
- int read_cu = 0;
-
- gdb_assert (! this_cu->debug_type_section);
-
- gdb_assert (dwarf2_per_objfile->info.readin);
- info_ptr = dwarf2_per_objfile->info.buffer + this_cu->offset;
- beg_of_comp_unit = info_ptr;
-
- if (this_cu->cu == NULL)
- {
- cu = xmalloc (sizeof (*cu));
- init_one_comp_unit (cu, objfile);
-
- read_cu = 1;
-
- /* If an error occurs while loading, release our storage. */
- free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
-
- info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr,
- dwarf2_per_objfile->info.buffer,
- dwarf2_per_objfile->info.size,
- abfd);
-
- /* Complete the cu_header. */
- cu->header.offset = this_cu->offset;
- cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
-
- /* Link this compilation unit into the compilation unit tree. */
- this_cu->cu = cu;
- cu->per_cu = this_cu;
-
- /* Link this CU into read_in_chain. */
- this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
- dwarf2_per_objfile->read_in_chain = this_cu;
- }
- else
- {
- cu = this_cu->cu;
- info_ptr += cu->header.first_die_offset;
- }
-
- /* Read the abbrevs for this compilation unit into a table. */
- gdb_assert (cu->dwarf2_abbrevs == NULL);
- dwarf2_read_abbrevs (abfd, cu);
- free_abbrevs_cleanup = make_cleanup (dwarf2_free_abbrev_table, cu);
-
- /* Read the compilation unit die. */
- init_cu_die_reader (&reader_specs, cu);
- info_ptr = read_full_die (&reader_specs, &comp_unit_die, info_ptr,
- &has_children);
+ struct dwarf2_cu *cu = reader->cu;
prepare_one_comp_unit (cu, comp_unit_die);
@@ -3661,22 +4293,23 @@ load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu,
If so, read the rest of the partial symbols from this comp unit.
If not, there's no more debug_info for this comp unit. */
if (has_children)
- load_partial_dies (abfd, dwarf2_per_objfile->info.buffer, info_ptr, 0, cu);
+ load_partial_dies (reader, info_ptr, 0);
+}
- do_cleanups (free_abbrevs_cleanup);
+/* Load the partial DIEs for a secondary CU into memory.
+ This is also used when rereading a primary CU with load_all_dies. */
- if (read_cu)
- {
- /* We've successfully allocated this compilation unit. Let our
- caller clean it up when finished with it. */
- discard_cleanups (free_cu_cleanup);
- }
+static void
+load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
+{
+ if (this_cu->is_debug_types)
+ init_tu_and_read_dies (this_cu, 1, load_partial_comp_unit_reader, NULL);
+ else
+ init_cu_and_read_dies (this_cu, 0, 1, load_partial_comp_unit_reader, NULL);
}
-/* Create a list of all compilation units in OBJFILE. We do this only
- if an inter-comp-unit reference is found; presumably if there is one,
- there will be many, and one will occur early in the .debug_info section.
- So there's no point in building this list incrementally. */
+/* Create a list of all compilation units in OBJFILE.
+ This is only done for -readnow and building partial symtabs. */
static void
create_all_comp_units (struct objfile *objfile)
@@ -3699,9 +4332,9 @@ create_all_comp_units (struct objfile *objfile)
{
unsigned int length, initial_length_size;
struct dwarf2_per_cu_data *this_cu;
- unsigned int offset;
+ sect_offset offset;
- offset = info_ptr - dwarf2_per_objfile->info.buffer;
+ offset.sect_off = info_ptr - dwarf2_per_objfile->info.buffer;
/* Read just enough information to find out where the next
compilation unit is. */
@@ -3715,6 +4348,7 @@ create_all_comp_units (struct objfile *objfile)
this_cu->offset = offset;
this_cu->length = length + initial_length_size;
this_cu->objfile = objfile;
+ this_cu->info_or_types_section = &dwarf2_per_objfile->info;
if (n_comp_units == n_allocated)
{
@@ -3878,7 +4512,10 @@ partial_die_parent_scope (struct partial_die_info *pdi,
return NULL;
}
- if (parent->tag == DW_TAG_namespace
+ if (pdi->tag == DW_TAG_enumerator)
+ /* Enumerators should not get the name of the enumeration as a prefix. */
+ parent->scope = grandparent_scope;
+ else if (parent->tag == DW_TAG_namespace
|| parent->tag == DW_TAG_module
|| parent->tag == DW_TAG_structure_type
|| parent->tag == DW_TAG_class_type
@@ -3893,9 +4530,6 @@ partial_die_parent_scope (struct partial_die_info *pdi,
grandparent_scope,
parent->name, 0, cu);
}
- else if (parent->tag == DW_TAG_enumerator)
- /* Enumerators should not get the name of the enumeration as a prefix. */
- parent->scope = grandparent_scope;
else
{
/* FIXME drow/2004-04-01: What should we be doing with
@@ -3903,7 +4537,7 @@ partial_die_parent_scope (struct partial_die_info *pdi,
ignoring them. */
complaint (&symfile_complaints,
_("unhandled containing DIE tag %d for DIE at %d"),
- parent->tag, pdi->offset);
+ parent->tag, pdi->offset.sect_off);
parent->scope = grandparent_scope;
}
@@ -3913,6 +4547,7 @@ partial_die_parent_scope (struct partial_die_info *pdi,
/* Return the fully scoped name associated with PDI, from compilation unit
CU. The result will be allocated with malloc. */
+
static char *
partial_die_full_name (struct partial_die_info *pdi,
struct dwarf2_cu *cu)
@@ -3933,9 +4568,10 @@ partial_die_full_name (struct partial_die_info *pdi,
struct attribute attr;
struct dwarf2_cu *ref_cu = cu;
+ /* DW_FORM_ref_addr is using section offset. */
attr.name = 0;
attr.form = DW_FORM_ref_addr;
- attr.u.addr = pdi->offset;
+ attr.u.unsnd = pdi->offset.sect_off;
die = follow_die_ref (NULL, &attr, &ref_cu);
return xstrdup (dwarf2_full_name (NULL, die, ref_cu));
@@ -3955,7 +4591,6 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
struct objfile *objfile = cu->objfile;
CORE_ADDR addr = 0;
char *actual_name = NULL;
- const struct partial_symbol *psym = NULL;
CORE_ADDR baseaddr;
int built_actual_name = 0;
@@ -4195,6 +4830,10 @@ add_partial_subprogram (struct partial_die_info *pdi,
pdi->highpc - 1 + baseaddr,
cu->per_cu->v.psymtab);
}
+ }
+
+ if (pdi->has_pc_info || (!pdi->is_external && pdi->may_be_inlined))
+ {
if (!pdi->is_declaration)
/* Ignore subprogram DIEs that do not have a name, they are
illegal. Do not emit a complaint at this point, we will
@@ -4243,6 +4882,16 @@ add_partial_enumeration (struct partial_die_info *enum_pdi,
}
}
+/* Return the initial uleb128 in the die at INFO_PTR. */
+
+static unsigned int
+peek_abbrev_code (bfd *abfd, gdb_byte *info_ptr)
+{
+ unsigned int bytes_read;
+
+ return read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+}
+
/* Read the initial uleb128 in the die at INFO_PTR in compilation unit CU.
Return the corresponding abbrev, or NULL if the number is zero (indicating
an empty DIE). In either case *BYTES_READ will be set to the length of
@@ -4276,8 +4925,9 @@ peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read,
DIE. Any children of the skipped DIEs will also be skipped. */
static gdb_byte *
-skip_children (gdb_byte *buffer, gdb_byte *info_ptr, struct dwarf2_cu *cu)
+skip_children (const struct die_reader_specs *reader, gdb_byte *info_ptr)
{
+ struct dwarf2_cu *cu = reader->cu;
struct abbrev_info *abbrev;
unsigned int bytes_read;
@@ -4287,7 +4937,7 @@ skip_children (gdb_byte *buffer, gdb_byte *info_ptr, struct dwarf2_cu *cu)
if (abbrev == NULL)
return info_ptr + bytes_read;
else
- info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu);
+ info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
}
}
@@ -4298,12 +4948,14 @@ skip_children (gdb_byte *buffer, gdb_byte *info_ptr, struct dwarf2_cu *cu)
children. */
static gdb_byte *
-skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
- struct abbrev_info *abbrev, struct dwarf2_cu *cu)
+skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr,
+ struct abbrev_info *abbrev)
{
unsigned int bytes_read;
struct attribute attr;
- bfd *abfd = cu->objfile->obfd;
+ bfd *abfd = reader->abfd;
+ struct dwarf2_cu *cu = reader->cu;
+ gdb_byte *buffer = reader->buffer;
unsigned int form, i;
for (i = 0; i < abbrev->num_attrs; i++)
@@ -4311,13 +4963,12 @@ skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
/* The only abbrev we care about is DW_AT_sibling. */
if (abbrev->attrs[i].name == DW_AT_sibling)
{
- read_attribute (&attr, &abbrev->attrs[i],
- abfd, info_ptr, cu);
+ read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
if (attr.form == DW_FORM_ref_addr)
complaint (&symfile_complaints,
_("ignoring absolute DW_AT_sibling"));
else
- return buffer + dwarf2_get_ref_die_offset (&attr);
+ return buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
}
/* If it isn't DW_AT_sibling, skip this attribute. */
@@ -4381,6 +5032,8 @@ skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_ref_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
info_ptr = skip_leb128 (abfd, info_ptr);
break;
case DW_FORM_indirect:
@@ -4399,19 +5052,18 @@ skip_one_die (gdb_byte *buffer, gdb_byte *info_ptr,
}
if (abbrev->has_children)
- return skip_children (buffer, info_ptr, cu);
+ return skip_children (reader, info_ptr);
else
return info_ptr;
}
/* Locate ORIG_PDI's sibling.
- INFO_PTR should point to the start of the next DIE after ORIG_PDI
- in BUFFER. */
+ INFO_PTR should point to the start of the next DIE after ORIG_PDI. */
static gdb_byte *
-locate_pdi_sibling (struct partial_die_info *orig_pdi,
- gdb_byte *buffer, gdb_byte *info_ptr,
- bfd *abfd, struct dwarf2_cu *cu)
+locate_pdi_sibling (const struct die_reader_specs *reader,
+ struct partial_die_info *orig_pdi,
+ gdb_byte *info_ptr)
{
/* Do we know the sibling already? */
@@ -4425,7 +5077,7 @@ locate_pdi_sibling (struct partial_die_info *orig_pdi,
/* Skip the children the long way. */
- return skip_children (buffer, info_ptr, cu);
+ return skip_children (reader, info_ptr);
}
/* Expand this partial symbol table into a full symbol table. */
@@ -4477,11 +5129,13 @@ dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
}
}
}
+
+/* Reading in full CUs. */
/* Add PER_CU to the queue. */
static void
-queue_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile)
+queue_comp_unit (struct dwarf2_per_cu_data *per_cu)
{
struct dwarf2_queue_item *item;
@@ -4501,7 +5155,7 @@ queue_comp_unit (struct dwarf2_per_cu_data *per_cu, struct objfile *objfile)
/* Process the queue. */
static void
-process_queue (struct objfile *objfile)
+process_queue (void)
{
struct dwarf2_queue_item *item, *next_item;
@@ -4539,7 +5193,7 @@ dwarf2_release_queue (void *dummy)
if (item->per_cu->queued)
{
if (item->per_cu->cu != NULL)
- free_one_cached_comp_unit (item->per_cu->cu);
+ free_one_cached_comp_unit (item->per_cu);
item->per_cu->queued = 0;
}
@@ -4588,89 +5242,79 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
return;
}
- dw2_do_instantiate_symtab (pst->objfile, per_cu);
+ dw2_do_instantiate_symtab (per_cu);
}
-/* Load the DIEs associated with PER_CU into memory. */
+/* Trivial hash function for die_info: the hash value of a DIE
+ is its offset in .debug_info for this objfile. */
-static void
-load_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
- struct objfile *objfile)
+static hashval_t
+die_hash (const void *item)
{
- bfd *abfd = objfile->obfd;
- struct dwarf2_cu *cu;
- unsigned int offset;
- gdb_byte *info_ptr, *beg_of_comp_unit;
- struct cleanup *free_abbrevs_cleanup = NULL, *free_cu_cleanup = NULL;
- struct attribute *attr;
- int read_cu = 0;
-
- gdb_assert (! per_cu->debug_type_section);
-
- /* Set local variables from the partial symbol table info. */
- offset = per_cu->offset;
-
- dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
- info_ptr = dwarf2_per_objfile->info.buffer + offset;
- beg_of_comp_unit = info_ptr;
-
- if (per_cu->cu == NULL)
- {
- cu = xmalloc (sizeof (*cu));
- init_one_comp_unit (cu, objfile);
+ const struct die_info *die = item;
- read_cu = 1;
+ return die->offset.sect_off;
+}
- /* If an error occurs while loading, release our storage. */
- free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
+/* Trivial comparison function for die_info structures: two DIEs
+ are equal if they have the same offset. */
- /* Read in the comp_unit header. */
- info_ptr = read_comp_unit_head (&cu->header, info_ptr, abfd);
+static int
+die_eq (const void *item_lhs, const void *item_rhs)
+{
+ const struct die_info *die_lhs = item_lhs;
+ const struct die_info *die_rhs = item_rhs;
- /* Complete the cu_header. */
- cu->header.offset = offset;
- cu->header.first_die_offset = info_ptr - beg_of_comp_unit;
+ return die_lhs->offset.sect_off == die_rhs->offset.sect_off;
+}
- /* Read the abbrevs for this compilation unit. */
- dwarf2_read_abbrevs (abfd, cu);
- free_abbrevs_cleanup = make_cleanup (dwarf2_free_abbrev_table, cu);
+/* die_reader_func for load_full_comp_unit.
+ This is identical to read_signatured_type_reader,
+ but is kept separate for now. */
- /* Link this compilation unit into the compilation unit tree. */
- per_cu->cu = cu;
- cu->per_cu = per_cu;
+static void
+load_full_comp_unit_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
+{
+ struct dwarf2_cu *cu = reader->cu;
+ struct attribute *attr;
- /* Link this CU into read_in_chain. */
- per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
- dwarf2_per_objfile->read_in_chain = per_cu;
- }
- else
- {
- cu = per_cu->cu;
- info_ptr += cu->header.first_die_offset;
- }
+ gdb_assert (cu->die_hash == NULL);
+ cu->die_hash =
+ htab_create_alloc_ex (cu->header.length / 12,
+ die_hash,
+ die_eq,
+ NULL,
+ &cu->comp_unit_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
- cu->dies = read_comp_unit (info_ptr, cu);
+ if (has_children)
+ comp_unit_die->child = read_die_and_siblings (reader, info_ptr,
+ &info_ptr, comp_unit_die);
+ cu->dies = comp_unit_die;
+ /* comp_unit_die is not stored in die_hash, no need. */
/* We try not to read any attributes in this function, because not
- all objfiles needed for references have been loaded yet, and symbol
+ all CUs needed for references have been loaded yet, and symbol
table processing isn't initialized. But we have to set the CU language,
- or we won't be able to build types correctly. */
+ 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);
+}
- /* 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);
+/* Load the DIEs associated with PER_CU into memory. */
- if (read_cu)
- {
- do_cleanups (free_abbrevs_cleanup);
+static void
+load_full_comp_unit (struct dwarf2_per_cu_data *this_cu)
+{
+ gdb_assert (! this_cu->is_debug_types);
- /* We've successfully allocated this compilation unit. Let our
- caller clean it up when finished with it. */
- discard_cleanups (free_cu_cleanup);
- }
+ init_cu_and_read_dies (this_cu, 1, 1, load_full_comp_unit_reader, NULL);
}
/* Add a DIE to the delayed physname list. */
@@ -4723,51 +5367,79 @@ compute_delayed_physnames (struct dwarf2_cu *cu)
}
}
-/* Check for GCC >= 4.x. Return minor version (x) of 4.x in such case. If it
- is not GCC or it is GCC older than 4.x return -1. If it is GCC 5.x or
- higher return INT_MAX. */
+/* Go objects should be embedded in a DW_TAG_module DIE,
+ and it's not clear if/how imported objects will appear.
+ To keep Go support simple until that's worked out,
+ go back through what we've read and create something usable.
+ We could do this while processing each DIE, and feels kinda cleaner,
+ but that way is more invasive.
+ This is to, for example, allow the user to type "p var" or "b main"
+ without having to specify the package name, and allow lookups
+ of module.object to work in contexts that use the expression
+ parser. */
-static int
-producer_is_gcc_ge_4 (struct dwarf2_cu *cu)
+static void
+fixup_go_packaging (struct dwarf2_cu *cu)
{
- const char *cs;
- int major, minor;
+ char *package_name = NULL;
+ struct pending *list;
+ int i;
- if (cu->producer == NULL)
+ for (list = global_symbols; list != NULL; list = list->next)
{
- /* For unknown compilers expect their behavior is not compliant. For GCC
- this case can also happen for -gdwarf-4 type units supported since
- gcc-4.5. */
+ for (i = 0; i < list->nsyms; ++i)
+ {
+ struct symbol *sym = list->symbol[i];
- return -1;
- }
+ if (SYMBOL_LANGUAGE (sym) == language_go
+ && SYMBOL_CLASS (sym) == LOC_BLOCK)
+ {
+ char *this_package_name = go_symbol_package_name (sym);
- /* Skip any identifier after "GNU " - such as "C++" or "Java". */
+ if (this_package_name == NULL)
+ continue;
+ if (package_name == NULL)
+ package_name = this_package_name;
+ else
+ {
+ if (strcmp (package_name, this_package_name) != 0)
+ complaint (&symfile_complaints,
+ _("Symtab %s has objects from two different Go packages: %s and %s"),
+ (sym->symtab && sym->symtab->filename
+ ? sym->symtab->filename
+ : cu->objfile->name),
+ this_package_name, package_name);
+ xfree (this_package_name);
+ }
+ }
+ }
+ }
- if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0)
+ if (package_name != NULL)
{
- /* For non-GCC compilers expect their behavior is not compliant. */
+ struct objfile *objfile = cu->objfile;
+ struct type *type = init_type (TYPE_CODE_MODULE, 0, 0,
+ package_name, objfile);
+ struct symbol *sym;
- return -1;
- }
- cs = &cu->producer[strlen ("GNU ")];
- while (*cs && !isdigit (*cs))
- cs++;
- if (sscanf (cs, "%d.%d", &major, &minor) != 2)
- {
- /* Not recognized as GCC. */
+ TYPE_TAG_NAME (type) = TYPE_NAME (type);
- return -1;
- }
+ sym = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
+ SYMBOL_SET_LANGUAGE (sym, language_go);
+ SYMBOL_SET_NAMES (sym, package_name, strlen (package_name), 1, objfile);
+ /* This is not VAR_DOMAIN because we want a way to ensure a lookup of,
+ e.g., "main" finds the "main" module and not C's main(). */
+ SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
+ SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_TYPE (sym) = type;
- if (major < 4)
- return -1;
- if (major > 4)
- return INT_MAX;
- return minor;
+ add_symbol_to_list (sym, &global_symbols);
+
+ xfree (package_name);
+ }
}
-/* Generate full symbol information for PST and CU, whose DIEs have
+/* Generate full symbol information for PER_CU, whose DIEs have
already been loaded into memory. */
static void
@@ -4791,6 +5463,10 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
/* Do line number decoding in read_file_scope () */
process_die (cu->dies, cu);
+ /* For now fudge the Go package. */
+ if (cu->language == language_go)
+ fixup_go_packaging (cu);
+
/* Now that we have processed all the DIEs in the CU, all the types
should be complete, and it should now be safe to compute all of the
physnames. */
@@ -4806,7 +5482,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
if (symtab != NULL)
{
- int gcc_4_minor = producer_is_gcc_ge_4 (cu);
+ int gcc_4_minor = producer_is_gcc_ge_4 (cu->producer);
/* Set symtab language to language from DW_AT_language. If the
compilation is from a C file generated by language preprocessors, do
@@ -4816,7 +5492,9 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
/* GCC-4.0 has started to support -fvar-tracking. GCC-3.x still can
produce DW_AT_location with location lists but it can be possibly
- invalid without -fvar-tracking.
+ invalid without -fvar-tracking. Still up to GCC-4.4.x incl. 4.4.0
+ there were bugs in prologue debug info, fixed later in GCC-4.5
+ by "unwind info for epilogues" patch (which is not directly related).
For -gdwarf-4 type units LOCATIONS_VALID indication is fortunately not
needed, it would be wrong due to missing DW_AT_producer there.
@@ -4824,11 +5502,13 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
Still one can confuse GDB by using non-standard GCC compilation
options - this waits on GCC PR other/32998 (-frecord-gcc-switches).
*/
- if (cu->has_loclist && gcc_4_minor >= 0)
+ if (cu->has_loclist && gcc_4_minor >= 5)
symtab->locations_valid = 1;
if (gcc_4_minor >= 5)
symtab->epilogue_unwind_valid = 1;
+
+ symtab->call_site_htab = cu->call_site_htab;
}
if (dwarf2_per_objfile->using_index)
@@ -4867,6 +5547,9 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
case DW_TAG_catch_block:
read_lexical_block_scope (die, cu);
break;
+ case DW_TAG_GNU_call_site:
+ read_call_site_scope (die, cu);
+ break;
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_TAG_structure_type:
@@ -4993,8 +5676,14 @@ do_ui_file_peek_last (void *object, const char *buffer, long length)
}
/* Compute the fully qualified name of DIE in CU. If PHYSNAME is nonzero,
- compute the physname for the object, which include a method's
- formal parameters (C++/Java) and return type (Java).
+ compute the physname for the object, which include a method's:
+ - formal parameters (C++/Java),
+ - receiver type (Go),
+ - return type (Java).
+
+ The term "physname" is a bit confusing.
+ For C++, for example, it is the demangled name.
+ For Go, for example, it's the mangled name.
For Ada, return the DIE's linkage name rather than the fully qualified
name. PHYSNAME is ignored..
@@ -5005,6 +5694,8 @@ static const char *
dwarf2_compute_name (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);
@@ -5035,7 +5726,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
if (die_needs_namespace (die, cu))
{
long length;
- char *prefix;
+ const char *prefix;
struct ui_file *buf;
prefix = determine_prefix (die, cu);
@@ -5083,7 +5774,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
for (child = die->child; child != NULL; child = child->sibling)
{
struct type *type;
- long value;
+ LONGEST value;
gdb_byte *bytes;
struct dwarf2_locexpr_baton *baton;
struct value *v;
@@ -5212,7 +5903,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
}
}
- name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+ name = ui_file_obsavestring (buf, &objfile->objfile_obstack,
&length);
ui_file_delete (buf);
@@ -5220,7 +5911,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
{
char *cname
= dwarf2_canonicalize_name (name, cu,
- &cu->objfile->objfile_obstack);
+ &objfile->objfile_obstack);
if (cname != NULL)
name = cname;
@@ -5255,6 +5946,7 @@ dwarf2_full_name (char *name, struct die_info *die, struct dwarf2_cu *cu)
static const char *
dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
{
+ struct objfile *objfile = cu->objfile;
struct attribute *attr;
const char *retval, *mangled = NULL, *canon = NULL;
struct cleanup *back_to;
@@ -5288,10 +5980,21 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
variant `long name(params)' does not have the proper inferior type.
*/
- demangled = cplus_demangle (mangled, (DMGL_PARAMS | DMGL_ANSI
- | (cu->language == language_java
- ? DMGL_JAVA | DMGL_RET_POSTFIX
- : DMGL_RET_DROP)));
+ if (cu->language == language_go)
+ {
+ /* This is a lie, but we already lie to the caller new_symbol_full.
+ new_symbol_full assumes we return the mangled name.
+ This just undoes that lie until things are cleaned up. */
+ demangled = NULL;
+ }
+ else
+ {
+ demangled = cplus_demangle (mangled,
+ (DMGL_PARAMS | DMGL_ANSI
+ | (cu->language == language_java
+ ? DMGL_JAVA | DMGL_RET_POSTFIX
+ : DMGL_RET_DROP)));
+ }
if (demangled)
{
make_cleanup (xfree, demangled);
@@ -5317,7 +6020,7 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("Computed physname <%s> does not match demangled <%s> "
"(from linkage <%s>) - DIE at 0x%x [in module %s]"),
- physname, canon, mangled, die->offset, cu->objfile->name);
+ physname, canon, mangled, die->offset.sect_off, objfile->name);
/* Prefer DW_AT_linkage_name (in the CANON form) - when it
is available here - over computed PHYSNAME. It is safer
@@ -5336,7 +6039,7 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
if (need_copy)
retval = obsavestring (retval, strlen (retval),
- &cu->objfile->objfile_obstack);
+ &objfile->objfile_obstack);
do_cleanups (back_to);
return retval;
@@ -5347,6 +6050,7 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
static void
read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
{
+ struct objfile *objfile = cu->objfile;
struct attribute *import_attr;
struct die_info *imported_die, *child_die;
struct dwarf2_cu *imported_cu;
@@ -5453,7 +6157,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("child DW_TAG_imported_declaration expected "
"- DIE at 0x%x [in module %s]"),
- child_die->offset, cu->objfile->name);
+ child_die->offset.sect_off, objfile->name);
continue;
}
@@ -5474,7 +6178,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("child DW_TAG_imported_declaration has unknown "
"imported name - DIE at 0x%x [in module %s]"),
- child_die->offset, cu->objfile->name);
+ child_die->offset.sect_off, objfile->name);
continue;
}
@@ -5488,17 +6192,11 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
import_alias,
imported_declaration,
excludes,
- &cu->objfile->objfile_obstack);
+ &objfile->objfile_obstack);
do_cleanups (cleanups);
}
-static void
-initialize_cu_func_list (struct dwarf2_cu *cu)
-{
- cu->first_fn = cu->last_fn = cu->cached_fn = NULL;
-}
-
/* Cleanup function for read_file_scope. */
static void
@@ -5550,32 +6248,30 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
*name = "";
}
-/* Handle DW_AT_stmt_list for a compilation unit. */
+/* Handle DW_AT_stmt_list for a compilation unit or type unit.
+ DIE is the DW_TAG_compile_unit or DW_TAG_type_unit die for CU.
+ COMP_DIR is the compilation directory.
+ WANT_LINE_INFO is non-zero if the pc/line-number mapping is needed. */
static void
handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
- const char *comp_dir)
+ const char *comp_dir, int want_line_info)
{
struct attribute *attr;
- struct objfile *objfile = cu->objfile;
- bfd *abfd = objfile->obfd;
- /* Decode line number information if present. We do this before
- processing child DIEs, so that the line header table is available
- for DW_AT_decl_file. */
attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
if (attr)
{
unsigned int line_offset = DW_UNSND (attr);
struct line_header *line_header
- = dwarf_decode_line_header (line_offset, abfd, cu);
+ = dwarf_decode_line_header (line_offset, cu);
if (line_header)
- {
- cu->line_header = line_header;
- make_cleanup (free_cu_line_header, cu);
- dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL);
- }
+ {
+ cu->line_header = line_header;
+ make_cleanup (free_cu_line_header, cu);
+ dwarf_decode_lines (line_header, comp_dir, cu, NULL, want_line_info);
+ }
}
}
@@ -5584,7 +6280,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
static void
read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
struct cleanup *back_to = make_cleanup (null_cleanup, 0);
CORE_ADDR lowpc = ((CORE_ADDR) -1);
CORE_ADDR highpc = ((CORE_ADDR) 0);
@@ -5597,189 +6293,691 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- get_scope_pc_bounds (die, &lowpc, &highpc, cu);
+ get_scope_pc_bounds (die, &lowpc, &highpc, cu);
+
+ /* 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;
+
+ find_file_and_directory (die, cu, &name, &comp_dir);
+
+ prepare_one_comp_unit (cu, die);
+
+ /* 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;
+
+ /* Similar hack for Go. */
+ if (cu->producer && strstr (cu->producer, "GNU Go ") != NULL)
+ set_cu_language (DW_LANG_Go, cu);
+
+ /* We assume that we're processing GCC output. */
+ processing_gcc_compilation = 2;
+
+ processing_has_namespace_info = 0;
+
+ start_symtab (name, comp_dir, lowpc);
+ record_debugformat ("DWARF 2");
+ record_producer (cu->producer);
+
+ /* Decode line number information if present. We do this before
+ processing child DIEs, so that the line header table is available
+ for DW_AT_decl_file. */
+ handle_DW_AT_stmt_list (die, cu, comp_dir, 1);
+
+ /* Process all dies in compilation unit. */
+ if (die->child != NULL)
+ {
+ child_die = die->child;
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, cu);
+ child_die = sibling_die (child_die);
+ }
+ }
+
+ /* 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"));
+
+ dwarf_decode_macros (cu->line_header, DW_UNSND (attr),
+ comp_dir, abfd, cu,
+ &dwarf2_per_objfile->macro, 1);
+ }
+ else
+ {
+ 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->line_header, macro_offset,
+ comp_dir, abfd, cu,
+ &dwarf2_per_objfile->macinfo, 0);
+ }
+ }
+
+ 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);
+
+ attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
+ if (attr)
+ comp_dir = DW_STRING (attr);
+ else if (name != NULL && IS_ABSOLUTE_PATH (name))
+ {
+ comp_dir = ldirname (name);
+ if (comp_dir != NULL)
+ make_cleanup (xfree, comp_dir);
+ }
+
+ if (name == NULL)
+ name = "";
+
+ prepare_one_comp_unit (cu, die);
+
+ /* We assume that we're processing GCC output. */
+ processing_gcc_compilation = 2;
+
+ processing_has_namespace_info = 0;
+
+ start_symtab (name, comp_dir, lowpc);
+ record_debugformat ("DWARF 2");
+ record_producer (cu->producer);
+
+ /* Decode line number information if present. We do this before
+ processing child DIEs, so that the line header table is available
+ for DW_AT_decl_file.
+ We don't need the pc/line-number mapping for type units. */
+ handle_DW_AT_stmt_list (die, cu, comp_dir, 0);
+
+ /* Process the dies in the type unit. */
+ if (die->child == NULL)
+ {
+ dump_die_for_error (die);
+ error (_("Dwarf Error: Missing children for type unit [in module %s]"),
+ bfd_get_filename (abfd));
+ }
+
+ child_die = die->child;
+
+ while (child_die && child_die->tag)
+ {
+ process_die (child_die, cu);
+
+ child_die = sibling_die (child_die);
+ }
+
+ do_cleanups (back_to);
+}
+
+/* DWO files. */
+
+static hashval_t
+hash_dwo_file (const void *item)
+{
+ const struct dwo_file *dwo_file = item;
+
+ return htab_hash_string (dwo_file->dwo_name);
+}
+
+static int
+eq_dwo_file (const void *item_lhs, const void *item_rhs)
+{
+ const struct dwo_file *lhs = item_lhs;
+ const struct dwo_file *rhs = item_rhs;
+
+ return strcmp (lhs->dwo_name, rhs->dwo_name) == 0;
+}
+
+/* Allocate a hash table for DWO files. */
+
+static htab_t
+allocate_dwo_file_hash_table (void)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+
+ return htab_create_alloc_ex (41,
+ hash_dwo_file,
+ eq_dwo_file,
+ NULL,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+}
+
+static hashval_t
+hash_dwo_unit (const void *item)
+{
+ const struct dwo_unit *dwo_unit = item;
+
+ /* This drops the top 32 bits of the id, but is ok for a hash. */
+ return dwo_unit->signature;
+}
+
+static int
+eq_dwo_unit (const void *item_lhs, const void *item_rhs)
+{
+ const struct dwo_unit *lhs = item_lhs;
+ const struct dwo_unit *rhs = item_rhs;
+
+ /* The signature is assumed to be unique within the DWO file.
+ So while object file CU dwo_id's always have the value zero,
+ that's OK, assuming each object file DWO file has only one CU,
+ and that's the rule for now. */
+ return lhs->signature == rhs->signature;
+}
+
+/* Allocate a hash table for DWO CUs,TUs.
+ There is one of these tables for each of CUs,TUs for each DWO file. */
+
+static htab_t
+allocate_dwo_unit_table (struct objfile *objfile)
+{
+ /* Start out with a pretty small number.
+ Generally DWO files contain only one CU and maybe some TUs. */
+ return htab_create_alloc_ex (3,
+ hash_dwo_unit,
+ eq_dwo_unit,
+ NULL,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+}
+
+/* This function is mapped across the sections and remembers the offset and
+ size of each of the DWO debugging sections we are interested in. */
+
+static void
+dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp, void *dwo_file_ptr)
+{
+ struct dwo_file *dwo_file = dwo_file_ptr;
+ const struct dwo_section_names *names = &dwo_section_names;
+
+ if (section_is_p (sectp->name, &names->abbrev_dwo))
+ {
+ dwo_file->sections.abbrev.asection = sectp;
+ dwo_file->sections.abbrev.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->info_dwo))
+ {
+ dwo_file->sections.info.asection = sectp;
+ dwo_file->sections.info.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->line_dwo))
+ {
+ dwo_file->sections.line.asection = sectp;
+ dwo_file->sections.line.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->loc_dwo))
+ {
+ dwo_file->sections.loc.asection = sectp;
+ dwo_file->sections.loc.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_dwo))
+ {
+ dwo_file->sections.str.asection = sectp;
+ dwo_file->sections.str.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+ {
+ dwo_file->sections.str_offsets.asection = sectp;
+ dwo_file->sections.str_offsets.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->types_dwo))
+ {
+ struct dwarf2_section_info type_section;
+
+ memset (&type_section, 0, sizeof (type_section));
+ type_section.asection = sectp;
+ type_section.size = bfd_get_section_size (sectp);
+ VEC_safe_push (dwarf2_section_info_def, dwo_file->sections.types,
+ &type_section);
+ }
+}
+
+/* Structure used to pass data to create_debug_info_hash_table_reader. */
+
+struct create_dwo_info_table_data
+{
+ struct dwo_file *dwo_file;
+ htab_t cu_htab;
+};
+
+/* die_reader_func for create_debug_info_hash_table. */
+
+static void
+create_debug_info_hash_table_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *datap)
+{
+ struct 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->dwo_name);
+ return;
+ }
+
+ dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ dwo_unit->dwo_file = dwo_file;
+ dwo_unit->signature = DW_UNSND (attr);
+ dwo_unit->info_or_types_section = section;
+ dwo_unit->offset = offset;
+ dwo_unit->length = cu->per_cu->length;
+
+ slot = htab_find_slot (cu_htab, dwo_unit, INSERT);
+ gdb_assert (slot != NULL);
+ if (*slot != NULL)
+ {
+ const struct dwo_unit *dup_dwo_unit = *slot;
+
+ complaint (&symfile_complaints,
+ _("debug entry at offset 0x%x is duplicate to the entry at"
+ " offset 0x%x, dwo_id 0x%s [in module %s]"),
+ offset.sect_off, dup_dwo_unit->offset.sect_off,
+ phex (dwo_unit->signature, sizeof (dwo_unit->signature)),
+ dwo_file->dwo_name);
+ }
+ else
+ *slot = dwo_unit;
+
+ if (dwarf2_die_debug)
+ fprintf_unfiltered (gdb_stdlog, " offset 0x%x, dwo_id 0x%s\n",
+ offset.sect_off,
+ phex (dwo_unit->signature,
+ sizeof (dwo_unit->signature)));
+}
+
+/* Create a hash table to map DWO IDs to their CU entry in .debug_info.dwo. */
+
+static htab_t
+create_debug_info_hash_table (struct dwo_file *dwo_file)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_section_info *section = &dwo_file->sections.info;
+ bfd *abfd;
+ htab_t cu_htab;
+ gdb_byte *info_ptr, *end_ptr;
+ struct create_dwo_info_table_data create_dwo_info_table_data;
+
+ dwarf2_read_section (objfile, section);
+ info_ptr = section->buffer;
+
+ if (info_ptr == NULL)
+ return NULL;
+
+ /* We can't set abfd until now because the section may be empty or
+ not present, in which case section->asection will be NULL. */
+ abfd = section->asection->owner;
+
+ if (dwarf2_die_debug)
+ fprintf_unfiltered (gdb_stdlog, "Reading .debug_info.dwo for %s:\n",
+ bfd_get_filename (abfd));
+
+ cu_htab = allocate_dwo_unit_table (objfile);
+
+ create_dwo_info_table_data.dwo_file = dwo_file;
+ create_dwo_info_table_data.cu_htab = cu_htab;
+
+ end_ptr = info_ptr + section->size;
+ while (info_ptr < end_ptr)
+ {
+ struct dwarf2_per_cu_data per_cu;
+
+ memset (&per_cu, 0, sizeof (per_cu));
+ per_cu.objfile = objfile;
+ per_cu.is_debug_types = 0;
+ per_cu.offset.sect_off = info_ptr - section->buffer;
+ per_cu.info_or_types_section = section;
+
+ init_cutu_and_read_dies_no_follow (&per_cu,
+ &dwo_file->sections.abbrev,
+ dwo_file,
+ create_debug_info_hash_table_reader,
+ &create_dwo_info_table_data);
+
+ info_ptr += per_cu.length;
+ }
+
+ return cu_htab;
+}
+
+/* Subroutine of open_dwo_file to simplify it.
+ Open the file specified by FILE_NAME and hand it off to BFD for
+ preliminary analysis. Return a newly initialized bfd *, which
+ includes a canonicalized copy of FILE_NAME.
+ In case of trouble, return NULL.
+ NOTE: This function is derived from symfile_bfd_open. */
+
+static bfd *
+try_open_dwo_file (const char *file_name)
+{
+ bfd *sym_bfd;
+ int desc;
+ char *absolute_name;
+ char *name;
+
+ desc = openp (debug_file_directory, OPF_TRY_CWD_FIRST, file_name,
+ O_RDONLY | O_BINARY, &absolute_name);
+ if (desc < 0)
+ return NULL;
+
+ sym_bfd = bfd_fopen (absolute_name, gnutarget, FOPEN_RB, desc);
+ if (!sym_bfd)
+ {
+ close (desc);
+ xfree (absolute_name);
+ return NULL;
+ }
+ bfd_set_cacheable (sym_bfd, 1);
+
+ if (!bfd_check_format (sym_bfd, bfd_object))
+ {
+ bfd_close (sym_bfd); /* This also closes desc. */
+ xfree (absolute_name);
+ return NULL;
+ }
+
+ /* bfd_usrdata exists for applications and libbfd must not touch it. */
+ gdb_assert (bfd_usrdata (sym_bfd) == NULL);
+
+ return sym_bfd;
+}
+
+/* Try to open DWO file DWO_NAME.
+ COMP_DIR is the DW_AT_comp_dir attribute.
+ The result is the bfd handle of the file.
+ If there is a problem finding or opening the file, return NULL.
+ Upon success, the canonicalized path of the file is stored in the bfd,
+ same as symfile_bfd_open. */
+
+static bfd *
+open_dwo_file (const char *dwo_name, const char *comp_dir)
+{
+ bfd *abfd;
+ char *path_to_try, *debug_dir;
+
+ if (IS_ABSOLUTE_PATH (dwo_name))
+ return try_open_dwo_file (dwo_name);
+
+ /* Before trying the search path, try DWO_NAME in COMP_DIR. */
+
+ if (comp_dir != NULL)
+ {
+ char *path_to_try = concat (comp_dir, SLASH_STRING, dwo_name, NULL);
+
+ /* NOTE: If comp_dir is a relative path, this will also try the
+ search path, which seems useful. */
+ abfd = try_open_dwo_file (path_to_try);
+ xfree (path_to_try);
+ if (abfd != NULL)
+ return abfd;
+ }
+
+ /* That didn't work, try debug-file-directory, which, despite its name,
+ is a list of paths. */
+
+ if (*debug_file_directory == '\0')
+ return NULL;
+
+ return try_open_dwo_file (dwo_name);
+}
+
+/* Initialize the use of the DWO file specified by DWO_NAME. */
+
+static struct dwo_file *
+init_dwo_file (const char *dwo_name, const char *comp_dir)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwo_file *dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwo_file);
+ bfd *abfd;
+ struct cleanup *cleanups;
+
+ if (dwarf2_die_debug)
+ fprintf_unfiltered (gdb_stdlog, "Reading DWO file %s:\n", dwo_name);
+
+ abfd = open_dwo_file (dwo_name, comp_dir);
+ if (abfd == NULL)
+ return NULL;
+ dwo_file->dwo_name = dwo_name;
+ dwo_file->dwo_bfd = abfd;
+
+ cleanups = make_cleanup (free_dwo_file_cleanup, dwo_file);
+
+ bfd_map_over_sections (abfd, dwarf2_locate_dwo_sections, dwo_file);
+
+ dwo_file->cus = create_debug_info_hash_table (dwo_file);
+
+ dwo_file->tus = create_debug_types_hash_table (dwo_file,
+ dwo_file->sections.types);
+
+ discard_cleanups (cleanups);
+
+ return dwo_file;
+}
+
+/* Lookup DWO file DWO_NAME. */
- /* 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;
+static struct dwo_file *
+lookup_dwo_file (char *dwo_name, const char *comp_dir)
+{
+ struct dwo_file *dwo_file;
+ struct dwo_file find_entry;
+ void **slot;
- find_file_and_directory (die, cu, &name, &comp_dir);
+ if (dwarf2_per_objfile->dwo_files == NULL)
+ dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table ();
- attr = dwarf2_attr (die, DW_AT_language, cu);
- if (attr)
- {
- set_cu_language (DW_UNSND (attr), cu);
- }
+ /* Have we already seen this DWO file? */
+ find_entry.dwo_name = dwo_name;
+ slot = htab_find_slot (dwarf2_per_objfile->dwo_files, &find_entry, INSERT);
- attr = dwarf2_attr (die, DW_AT_producer, cu);
- if (attr)
- cu->producer = DW_STRING (attr);
+ /* If not, read it in and build a table of the DWOs it contains. */
+ if (*slot == NULL)
+ *slot = init_dwo_file (dwo_name, comp_dir);
- /* 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;
+ /* NOTE: This will be NULL if unable to open the file. */
+ dwo_file = *slot;
- /* We assume that we're processing GCC output. */
- processing_gcc_compilation = 2;
+ return dwo_file;
+}
- processing_has_namespace_info = 0;
+/* Lookup the DWO CU referenced from THIS_CU in DWO file DWO_NAME.
+ If non-NULL, comp_dir is the DW_AT_comp_dir attribute.
+ SIGNATURE is the "dwo_id" of the CU (for consistency we use the same
+ nomenclature as TUs).
+ The result is the DWO CU or NULL if we didn't find it
+ (dwo_id mismatch or couldn't find the DWO file). */
- start_symtab (name, comp_dir, lowpc);
- record_debugformat ("DWARF 2");
- record_producer (cu->producer);
+static struct dwo_unit *
+lookup_dwo_comp_unit (struct dwarf2_per_cu_data *this_cu,
+ char *dwo_name, const char *comp_dir,
+ ULONGEST signature)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwo_file *dwo_file;
- initialize_cu_func_list (cu);
+ dwo_file = lookup_dwo_file (dwo_name, comp_dir);
+ if (dwo_file == NULL)
+ return NULL;
- handle_DW_AT_stmt_list (die, cu, comp_dir);
+ /* Look up the DWO using its signature(dwo_id). */
- /* Process all dies in compilation unit. */
- if (die->child != NULL)
+ if (dwo_file->cus != NULL)
{
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- process_die (child_die, cu);
- child_die = sibling_die (child_die);
- }
- }
+ struct dwo_unit find_dwo_cu, *dwo_cu;
- /* 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"));
+ find_dwo_cu.signature = signature;
+ dwo_cu = htab_find (dwo_file->cus, &find_dwo_cu);
- dwarf_decode_macros (cu->line_header, DW_UNSND (attr),
- comp_dir, abfd, cu,
- &dwarf2_per_objfile->macro, 1);
+ if (dwo_cu != NULL)
+ return dwo_cu;
}
- else
- {
- 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->line_header, macro_offset,
- comp_dir, abfd, cu,
- &dwarf2_per_objfile->macinfo, 0);
- }
- }
- do_cleanups (back_to);
+ /* We didn't find it. This must mean a dwo_id mismatch. */
+
+ complaint (&symfile_complaints,
+ _("Could not find DWO CU referenced by CU at offset 0x%x"
+ " [in module %s]"),
+ this_cu->offset.sect_off, objfile->name);
+ return NULL;
}
-/* 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. */
+/* Lookup the DWO TU referenced from THIS_TU in DWO file DWO_NAME.
+ If non-NULL, comp_dir is the DW_AT_comp_dir attribute.
+ The result is the DWO CU or NULL if we didn't find it
+ (dwo_id mismatch or couldn't find the DWO file). */
-static void
-read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
+static struct dwo_unit *
+lookup_dwo_type_unit (struct signatured_type *this_tu,
+ char *dwo_name, const char *comp_dir)
{
- struct objfile *objfile = cu->objfile;
- struct cleanup *back_to = make_cleanup (null_cleanup, 0);
- CORE_ADDR lowpc;
- struct attribute *attr;
- char *name = NULL;
- char *comp_dir = NULL;
- struct die_info *child_die;
- bfd *abfd = objfile->obfd;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwo_file *dwo_file;
+ struct dwo_unit find_dwo_tu, *dwo_tu;
- /* 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));
+ dwo_file = lookup_dwo_file (dwo_name, comp_dir);
+ if (dwo_file == NULL)
+ return NULL;
- /* 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);
+ /* Look up the DWO using its signature(dwo_id). */
- 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 (dwo_file->tus != NULL)
{
- comp_dir = ldirname (name);
- if (comp_dir != NULL)
- make_cleanup (xfree, comp_dir);
- }
+ struct dwo_unit find_dwo_tu, *dwo_tu;
- if (name == NULL)
- name = "";
+ find_dwo_tu.signature = this_tu->signature;
+ dwo_tu = htab_find (dwo_file->tus, &find_dwo_tu);
- attr = dwarf2_attr (die, DW_AT_language, cu);
- if (attr)
- set_cu_language (DW_UNSND (attr), cu);
+ if (dwo_tu != NULL)
+ return dwo_tu;
+ }
- /* This isn't technically needed today. It is done for symmetry
- with read_file_scope. */
- attr = dwarf2_attr (die, DW_AT_producer, cu);
- if (attr)
- cu->producer = DW_STRING (attr);
+ /* We didn't find it. This must mean a dwo_id mismatch. */
- /* We assume that we're processing GCC output. */
- processing_gcc_compilation = 2;
+ complaint (&symfile_complaints,
+ _("Could not find DWO TU referenced by TU at offset 0x%x"
+ " [in module %s]"),
+ this_tu->per_cu.offset.sect_off, objfile->name);
+ return NULL;
+}
- processing_has_namespace_info = 0;
+/* Free all resources associated with DWO_FILE.
+ Close the DWO file and munmap the sections.
+ All memory should be on the objfile obstack. */
- start_symtab (name, comp_dir, lowpc);
- record_debugformat ("DWARF 2");
- record_producer (cu->producer);
+static void
+free_dwo_file (struct dwo_file *dwo_file, struct objfile *objfile)
+{
+ int ix;
+ struct dwarf2_section_info *section;
- handle_DW_AT_stmt_list (die, cu, comp_dir);
+ gdb_assert (dwo_file->dwo_bfd != objfile->obfd);
+ bfd_close (dwo_file->dwo_bfd);
- /* 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));
- }
+ munmap_section_buffer (&dwo_file->sections.abbrev);
+ munmap_section_buffer (&dwo_file->sections.info);
+ munmap_section_buffer (&dwo_file->sections.line);
+ munmap_section_buffer (&dwo_file->sections.loc);
+ munmap_section_buffer (&dwo_file->sections.str);
+ munmap_section_buffer (&dwo_file->sections.str_offsets);
- child_die = die->child;
+ for (ix = 0;
+ VEC_iterate (dwarf2_section_info_def, dwo_file->sections.types,
+ ix, section);
+ ++ix)
+ munmap_section_buffer (section);
- while (child_die && child_die->tag)
- {
- process_die (child_die, cu);
+ VEC_free (dwarf2_section_info_def, dwo_file->sections.types);
+}
- child_die = sibling_die (child_die);
- }
+/* Wrapper for free_dwo_file for use in cleanups. */
- do_cleanups (back_to);
+static void
+free_dwo_file_cleanup (void *arg)
+{
+ struct dwo_file *dwo_file = (struct dwo_file *) arg;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+
+ free_dwo_file (dwo_file, objfile);
}
-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;
- 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;
+ free_dwo_file (dwo_file, objfile);
- if (cu->last_fn == NULL)
- cu->first_fn = thisfn;
- else
- cu->last_fn->next = thisfn;
+ return 1;
+}
- cu->last_fn = thisfn;
+/* Free all resources associated with DWO_FILES. */
+
+static void
+free_dwo_files (htab_t dwo_files, struct objfile *objfile)
+{
+ htab_traverse_noresize (dwo_files, free_dwo_file_from_slot, objfile);
}
+
+/* Read in various DIEs. */
/* qsort helper for inherit_abstract_dies. */
@@ -5803,8 +7001,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. */
@@ -5834,7 +7032,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;
@@ -5877,13 +7075,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;
}
@@ -5892,20 +7090,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);
@@ -5956,7 +7156,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;
}
@@ -5968,16 +7169,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))
@@ -6150,15 +7348,266 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
walking across all its children's ranges as they appear in
the address map, which is quadratic behavior.
- It would be nicer to record the parent's ranges before
- traversing its children, simply overriding whatever you find
- there. But since we don't even decide whether to create a
- block until after we've traversed its children, that's hard
- to do. */
- dwarf2_record_block_ranges (die, block, baseaddr, cu);
+ It would be nicer to record the parent's ranges before
+ traversing its children, simply overriding whatever you find
+ there. But since we don't even decide whether to create a
+ block until after we've traversed its children, that's hard
+ to do. */
+ dwarf2_record_block_ranges (die, block, baseaddr, cu);
+ }
+ local_symbols = new->locals;
+ using_directives = new->using_directives;
+}
+
+/* Read in DW_TAG_GNU_call_site and insert it to CU->call_site_htab. */
+
+static void
+read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = cu->objfile;
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ CORE_ADDR pc, baseaddr;
+ struct attribute *attr;
+ struct call_site *call_site, call_site_local;
+ void **slot;
+ int nparams;
+ struct die_info *child_die;
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ attr = dwarf2_attr (die, DW_AT_low_pc, cu);
+ if (!attr)
+ {
+ complaint (&symfile_complaints,
+ _("missing DW_AT_low_pc for DW_TAG_GNU_call_site "
+ "DIE 0x%x [in module %s]"),
+ die->offset.sect_off, objfile->name);
+ return;
+ }
+ pc = DW_ADDR (attr) + baseaddr;
+
+ if (cu->call_site_htab == NULL)
+ cu->call_site_htab = htab_create_alloc_ex (16, core_addr_hash, core_addr_eq,
+ NULL, &objfile->objfile_obstack,
+ hashtab_obstack_allocate, NULL);
+ call_site_local.pc = pc;
+ slot = htab_find_slot (cu->call_site_htab, &call_site_local, INSERT);
+ if (*slot != NULL)
+ {
+ complaint (&symfile_complaints,
+ _("Duplicate PC %s for DW_TAG_GNU_call_site "
+ "DIE 0x%x [in module %s]"),
+ paddress (gdbarch, pc), die->offset.sect_off, objfile->name);
+ return;
+ }
+
+ /* Count parameters at the caller. */
+
+ nparams = 0;
+ for (child_die = die->child; child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ {
+ if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+ {
+ complaint (&symfile_complaints,
+ _("Tag %d is not DW_TAG_GNU_call_site_parameter in "
+ "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
+ child_die->tag, child_die->offset.sect_off, objfile->name);
+ continue;
+ }
+
+ nparams++;
+ }
+
+ call_site = obstack_alloc (&objfile->objfile_obstack,
+ (sizeof (*call_site)
+ + (sizeof (*call_site->parameter)
+ * (nparams - 1))));
+ *slot = call_site;
+ memset (call_site, 0, sizeof (*call_site) - sizeof (*call_site->parameter));
+ call_site->pc = pc;
+
+ if (dwarf2_flag_true_p (die, DW_AT_GNU_tail_call, cu))
+ {
+ struct die_info *func_die;
+
+ /* Skip also over DW_TAG_inlined_subroutine. */
+ for (func_die = die->parent;
+ func_die && func_die->tag != DW_TAG_subprogram
+ && func_die->tag != DW_TAG_subroutine_type;
+ func_die = func_die->parent);
+
+ /* DW_AT_GNU_all_call_sites is a superset
+ of DW_AT_GNU_all_tail_call_sites. */
+ if (func_die
+ && !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_call_sites, cu)
+ && !dwarf2_flag_true_p (func_die, DW_AT_GNU_all_tail_call_sites, cu))
+ {
+ /* TYPE_TAIL_CALL_LIST is not interesting in functions where it is
+ not complete. But keep CALL_SITE for look ups via call_site_htab,
+ both the initial caller containing the real return address PC and
+ the final callee containing the current PC of a chain of tail
+ calls do not need to have the tail call list complete. But any
+ function candidate for a virtual tail call frame searched via
+ TYPE_TAIL_CALL_LIST must have the tail call list complete to be
+ determined unambiguously. */
+ }
+ else
+ {
+ struct type *func_type = NULL;
+
+ if (func_die)
+ func_type = get_die_type (func_die, cu);
+ if (func_type != NULL)
+ {
+ gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC);
+
+ /* Enlist this call site to the function. */
+ call_site->tail_call_next = TYPE_TAIL_CALL_LIST (func_type);
+ TYPE_TAIL_CALL_LIST (func_type) = call_site;
+ }
+ else
+ complaint (&symfile_complaints,
+ _("Cannot find function owning DW_TAG_GNU_call_site "
+ "DIE 0x%x [in module %s]"),
+ die->offset.sect_off, objfile->name);
+ }
+ }
+
+ attr = dwarf2_attr (die, DW_AT_GNU_call_site_target, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
+ SET_FIELD_DWARF_BLOCK (call_site->target, NULL);
+ if (!attr || (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0))
+ /* Keep NULL DWARF_BLOCK. */;
+ else if (attr_form_is_block (attr))
+ {
+ struct dwarf2_locexpr_baton *dlbaton;
+
+ dlbaton = obstack_alloc (&objfile->objfile_obstack, sizeof (*dlbaton));
+ dlbaton->data = DW_BLOCK (attr)->data;
+ dlbaton->size = DW_BLOCK (attr)->size;
+ dlbaton->per_cu = cu->per_cu;
+
+ SET_FIELD_DWARF_BLOCK (call_site->target, dlbaton);
+ }
+ else if (is_ref_attr (attr))
+ {
+ struct dwarf2_cu *target_cu = cu;
+ struct die_info *target_die;
+
+ target_die = follow_die_ref_or_sig (die, attr, &target_cu);
+ gdb_assert (target_cu->objfile == objfile);
+ if (die_is_declaration (target_die, target_cu))
+ {
+ const char *target_physname;
+
+ target_physname = dwarf2_physname (NULL, target_die, target_cu);
+ if (target_physname == NULL)
+ complaint (&symfile_complaints,
+ _("DW_AT_GNU_call_site_target target DIE has invalid "
+ "physname, for referencing DIE 0x%x [in module %s]"),
+ die->offset.sect_off, objfile->name);
+ else
+ SET_FIELD_PHYSNAME (call_site->target, (char *) target_physname);
+ }
+ else
+ {
+ CORE_ADDR lowpc;
+
+ /* DW_AT_entry_pc should be preferred. */
+ if (!dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu, NULL))
+ complaint (&symfile_complaints,
+ _("DW_AT_GNU_call_site_target target DIE has invalid "
+ "low pc, for referencing DIE 0x%x [in module %s]"),
+ die->offset.sect_off, objfile->name);
+ else
+ SET_FIELD_PHYSADDR (call_site->target, lowpc + baseaddr);
+ }
+ }
+ else
+ complaint (&symfile_complaints,
+ _("DW_TAG_GNU_call_site DW_AT_GNU_call_site_target is neither "
+ "block nor reference, for DIE 0x%x [in module %s]"),
+ die->offset.sect_off, objfile->name);
+
+ call_site->per_cu = cu->per_cu;
+
+ for (child_die = die->child;
+ child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ {
+ struct dwarf2_locexpr_baton *dlbaton;
+ struct call_site_parameter *parameter;
+
+ if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+ {
+ /* Already printed the complaint above. */
+ continue;
+ }
+
+ gdb_assert (call_site->parameter_count < nparams);
+ parameter = &call_site->parameter[call_site->parameter_count];
+
+ /* DW_AT_location specifies the register number. Value of the data
+ assumed for the register is contained in DW_AT_GNU_call_site_value. */
+
+ attr = dwarf2_attr (child_die, DW_AT_location, cu);
+ if (!attr || !attr_form_is_block (attr))
+ {
+ complaint (&symfile_complaints,
+ _("No DW_FORM_block* DW_AT_location for "
+ "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
+ child_die->offset.sect_off, objfile->name);
+ continue;
+ }
+ parameter->dwarf_reg = dwarf_block_to_dwarf_reg (DW_BLOCK (attr)->data,
+ &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size]);
+ if (parameter->dwarf_reg == -1
+ && !dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (attr)->data,
+ &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size],
+ ¶meter->fb_offset))
+ {
+ complaint (&symfile_complaints,
+ _("Only single DW_OP_reg or DW_OP_fbreg is supported "
+ "for DW_FORM_block* DW_AT_location for "
+ "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
+ child_die->offset.sect_off, objfile->name);
+ continue;
+ }
+
+ attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
+ if (!attr_form_is_block (attr))
+ {
+ complaint (&symfile_complaints,
+ _("No DW_FORM_block* DW_AT_GNU_call_site_value for "
+ "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
+ child_die->offset.sect_off, objfile->name);
+ continue;
+ }
+ parameter->value = DW_BLOCK (attr)->data;
+ parameter->value_size = DW_BLOCK (attr)->size;
+
+ /* Parameters are not pre-cleared by memset above. */
+ parameter->data_value = NULL;
+ parameter->data_value_size = 0;
+ call_site->parameter_count++;
+
+ attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_data_value, cu);
+ if (attr)
+ {
+ if (!attr_form_is_block (attr))
+ complaint (&symfile_complaints,
+ _("No DW_FORM_block* DW_AT_GNU_call_site_data_value for "
+ "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
+ child_die->offset.sect_off, objfile->name);
+ else
+ {
+ parameter->data_value = DW_BLOCK (attr)->data;
+ parameter->data_value_size = DW_BLOCK (attr)->size;
+ }
+ }
}
- local_symbols = new->locals;
- using_directives = new->using_directives;
}
/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
@@ -6306,23 +7755,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;
@@ -6360,7 +7817,8 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
return 0;
*lowpc = low;
- *highpc = high;
+ if (highpc)
+ *highpc = high;
return ret;
}
@@ -6462,21 +7920,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);
}
@@ -6485,7 +7950,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
attr = dwarf2_attr (die, DW_AT_ranges, cu);
if (attr)
{
- bfd *obfd = cu->objfile->obfd;
+ bfd *obfd = objfile->obfd;
/* The value of the DW_AT_ranges attribute is the offset of the
address range list in the .debug_ranges section. */
@@ -6580,6 +8045,7 @@ producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu)
{
const char *cs;
int major, minor, release;
+ int result = 0;
if (cu->producer == NULL)
{
@@ -6595,26 +8061,33 @@ producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu)
return 0;
}
+ if (cu->checked_producer)
+ return cu->producer_is_gxx_lt_4_6;
+
/* Skip any identifier after "GNU " - such as "C++" or "Java". */
if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0)
{
/* For non-GCC compilers expect their behavior is DWARF version
compliant. */
-
- return 0;
}
- cs = &cu->producer[strlen ("GNU ")];
- while (*cs && !isdigit (*cs))
- cs++;
- if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3)
+ else
{
- /* Not recognized as GCC. */
-
- return 0;
+ cs = &cu->producer[strlen ("GNU ")];
+ while (*cs && !isdigit (*cs))
+ cs++;
+ if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3)
+ {
+ /* Not recognized as GCC. */
+ }
+ else
+ result = major < 4 || (major == 4 && minor < 6);
}
- return major < 4 || (major == 4 && minor < 6);
+ cu->checked_producer = 1;
+ cu->producer_is_gxx_lt_4_6 = result;
+
+ return result;
}
/* Return the default accessibility type if it is not overriden by
@@ -6762,7 +8235,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
{
@@ -6791,8 +8264,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)));
}
}
@@ -7192,7 +8667,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;
}
@@ -7206,7 +8681,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)
@@ -7228,12 +8702,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
@@ -7525,7 +8996,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))
{
@@ -7600,7 +9071,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
@@ -7711,6 +9182,8 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
int num_fields = 0;
int unsigned_enum = 1;
char *name;
+ int flag_enum = 1;
+ ULONGEST mask = 0;
child_die = die->child;
while (child_die && child_die->tag)
@@ -7726,7 +9199,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)
{
@@ -7738,7 +9218,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++;
@@ -7759,6 +9239,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
@@ -7769,16 +9251,17 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
actually available. Note that we do not want to do this for all
enums which are just declarations, because C++0x allows forward
enum declarations. */
- if (cu->per_cu->debug_type_section
+ if (cu->per_cu->is_debug_types
&& die_is_declaration (die, cu))
{
- struct signatured_type *type_sig;
+ struct signatured_type *sig_type;
- type_sig
+ sig_type
= lookup_signatured_type_at_offset (dwarf2_per_objfile->objfile,
- cu->per_cu->debug_type_section,
+ cu->per_cu->info_or_types_section,
cu->per_cu->offset);
- if (type_sig->type_offset != die->offset)
+ gdb_assert (sig_type->type_offset_in_section.sect_off != 0);
+ if (sig_type->type_offset_in_section.sect_off != die->offset.sect_off)
return;
}
@@ -8104,7 +9587,7 @@ read_module_type (struct die_info *die, struct dwarf2_cu *cu)
if (!module_name)
complaint (&symfile_complaints,
_("DW_TAG_module has no name, offset 0x%x"),
- die->offset);
+ die->offset.sect_off);
type = init_type (TYPE_CODE_MODULE, 0, 0, module_name, objfile);
/* determine_prefix uses TYPE_TAG_NAME. */
@@ -8387,6 +9870,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;
@@ -8432,7 +9916,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;
@@ -8542,14 +10026,26 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
const char *name = NULL;
- struct type *this_type;
+ struct type *this_type, *target_type;
name = dwarf2_full_name (NULL, die, cu);
this_type = init_type (TYPE_CODE_TYPEDEF, 0,
TYPE_FLAG_TARGET_STUB, NULL, objfile);
TYPE_NAME (this_type) = (char *) name;
set_die_type (die, this_type, cu);
- TYPE_TARGET_TYPE (this_type) = die_type (die, cu);
+ target_type = die_type (die, cu);
+ if (target_type != this_type)
+ TYPE_TARGET_TYPE (this_type) = target_type;
+ else
+ {
+ /* Self-referential typedefs are, it seems, not allowed by the DWARF
+ spec and cause infinite loops in GDB. */
+ complaint (&symfile_complaints,
+ _("Self-referential DW_TAG_typedef "
+ "- DIE at 0x%x [in module %s]"),
+ die->offset.sect_off, objfile->name);
+ TYPE_TARGET_TYPE (this_type) = NULL;
+ }
return this_type;
}
@@ -8658,8 +10154,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
struct type *base_type;
struct type *range_type;
struct attribute *attr;
- LONGEST low = 0;
- LONGEST high = -1;
+ LONGEST low, high;
+ int low_default_is_valid;
char *name;
LONGEST negative_mask;
@@ -8672,10 +10168,35 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
if (range_type)
return range_type;
- if (cu->language == language_fortran)
+ /* Set LOW_DEFAULT_IS_VALID if current language and DWARF version allow
+ omitting DW_AT_lower_bound. */
+ switch (cu->language)
{
- /* FORTRAN implies a lower bound of 1, if not given. */
+ case language_c:
+ case language_cplus:
+ low = 0;
+ low_default_is_valid = 1;
+ break;
+ case language_fortran:
+ low = 1;
+ low_default_is_valid = 1;
+ break;
+ case language_d:
+ case language_java:
+ case language_objc:
+ low = 0;
+ low_default_is_valid = (cu->header.version >= 4);
+ break;
+ case language_ada:
+ case language_m2:
+ case language_pascal:
low = 1;
+ low_default_is_valid = (cu->header.version >= 4);
+ break;
+ default:
+ low = 0;
+ low_default_is_valid = 0;
+ break;
}
/* FIXME: For variable sized arrays either of these could be
@@ -8683,7 +10204,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)
@@ -8807,92 +10332,6 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
return set_die_type (die, type, cu);
}
-/* Trivial hash function for die_info: the hash value of a DIE
- is its offset in .debug_info for this objfile. */
-
-static hashval_t
-die_hash (const void *item)
-{
- const struct die_info *die = item;
-
- return die->offset;
-}
-
-/* Trivial comparison function for die_info structures: two DIEs
- are equal if they have the same offset. */
-
-static int
-die_eq (const void *item_lhs, const void *item_rhs)
-{
- const struct die_info *die_lhs = item_lhs;
- const struct die_info *die_rhs = item_rhs;
-
- return die_lhs->offset == die_rhs->offset;
-}
-
-/* Read a whole compilation unit into a linked list of dies. */
-
-static struct die_info *
-read_comp_unit (gdb_byte *info_ptr, struct dwarf2_cu *cu)
-{
- struct die_reader_specs reader_specs;
- int read_abbrevs = 0;
- struct cleanup *back_to = NULL;
- struct die_info *die;
-
- if (cu->dwarf2_abbrevs == NULL)
- {
- dwarf2_read_abbrevs (cu->objfile->obfd, cu);
- back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
- read_abbrevs = 1;
- }
-
- gdb_assert (cu->die_hash == NULL);
- cu->die_hash
- = htab_create_alloc_ex (cu->header.length / 12,
- die_hash,
- die_eq,
- NULL,
- &cu->comp_unit_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
-
- init_cu_die_reader (&reader_specs, cu);
-
- die = read_die_and_children (&reader_specs, info_ptr, &info_ptr, NULL);
-
- if (read_abbrevs)
- do_cleanups (back_to);
-
- return die;
-}
-
-/* Main entry point for reading a DIE and all children.
- Read the DIE and dump it if requested. */
-
-static struct die_info *
-read_die_and_children (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- gdb_byte **new_info_ptr,
- struct die_info *parent)
-{
- struct die_info *result = read_die_and_children_1 (reader, info_ptr,
- new_info_ptr, parent);
-
- if (dwarf2_die_debug)
- {
- fprintf_unfiltered (gdb_stdlog,
- "\nRead die from %s of %s:\n",
- (reader->cu->per_cu->debug_type_section
- ? ".debug_types"
- : ".debug_info"),
- reader->abfd->filename);
- dump_die (result, dwarf2_die_debug);
- }
-
- return result;
-}
-
/* Read a single die and all its descendents. Set the die's sibling
field to NULL; set other fields in the die correctly, and set all
of the descendents' fields correctly. Set *NEW_INFO_PTR to the
@@ -8900,10 +10339,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;
@@ -8949,7 +10388,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)
{
@@ -8966,23 +10405,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)
@@ -8998,22 +10441,38 @@ read_full_die (const struct die_reader_specs *reader,
abbrev_number,
bfd_get_filename (abfd));
- die = dwarf_alloc_die (cu, abbrev->num_attrs);
+ die = dwarf_alloc_die (cu, abbrev->num_attrs + num_extra_attrs);
die->offset = offset;
die->tag = abbrev->tag;
die->abbrev = abbrev_number;
+ /* Make the result usable.
+ The caller needs to update num_attrs after adding the extra
+ attributes. */
die->num_attrs = abbrev->num_attrs;
for (i = 0; i < abbrev->num_attrs; ++i)
- info_ptr = read_attribute (&die->attrs[i], &abbrev->attrs[i],
- abfd, info_ptr, cu);
+ info_ptr = read_attribute (reader, &die->attrs[i], &abbrev->attrs[i],
+ info_ptr);
*diep = die;
*has_children = abbrev->has_children;
return info_ptr;
}
+/* Read a die and all its attributes.
+ Set DIEP to point to a newly allocated die with its information,
+ except for its child, sibling, and parent fields.
+ Set HAS_CHILDREN to tell whether the die has children or not. */
+
+static gdb_byte *
+read_full_die (const struct die_reader_specs *reader,
+ struct die_info **diep, gdb_byte *info_ptr,
+ int *has_children)
+{
+ return read_full_die_1 (reader, diep, info_ptr, has_children, 0);
+}
+
/* In DWARF version 2, the description of the debugging information is
stored in a separate .debug_abbrev section. Before we read any
dies from a section we read in all abbreviations and install them
@@ -9021,8 +10480,11 @@ read_full_die (const struct die_reader_specs *reader,
the data found in the abbrev table. */
static void
-dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
+dwarf2_read_abbrevs (struct dwarf2_cu *cu,
+ struct dwarf2_section_info *abbrev_section)
+
{
+ bfd *abfd = abbrev_section->asection->owner;
struct comp_unit_head *cu_header = &cu->header;
gdb_byte *abbrev_ptr;
struct abbrev_info *cur_abbrev;
@@ -9039,9 +10501,8 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
memset (cu->dwarf2_abbrevs, 0,
ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
- dwarf2_read_section (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->abbrev);
- abbrev_ptr = dwarf2_per_objfile->abbrev.buffer + cu_header->abbrev_offset;
+ dwarf2_read_section (cu->objfile, abbrev_section);
+ abbrev_ptr = abbrev_section->buffer + cu_header->abbrev_offset.sect_off;
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
@@ -9060,9 +10521,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;
@@ -9078,16 +10536,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);
@@ -9113,8 +10561,8 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
already read (which means we are about to read the abbreviations
for the next compile unit) or if the end of the abbreviation
table is reached. */
- if ((unsigned int) (abbrev_ptr - dwarf2_per_objfile->abbrev.buffer)
- >= dwarf2_per_objfile->abbrev.size)
+ if ((unsigned int) (abbrev_ptr - abbrev_section->buffer)
+ >= abbrev_section->size)
break;
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
@@ -9192,21 +10640,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
@@ -9256,20 +10706,19 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
if (!load_all)
{
/* We don't need a partial DIE for the template argument. */
- info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev,
- cu);
+ info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
continue;
}
}
- /* We only recurse into subprograms looking for template arguments.
+ /* We only recurse into c++ subprograms looking for template arguments.
Skip their other children. */
if (!load_all
&& cu->language == language_cplus
&& parent_die != NULL
&& parent_die->tag == DW_TAG_subprogram)
{
- info_ptr = skip_one_die (buffer, info_ptr + bytes_read, abbrev, cu);
+ info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
continue;
}
@@ -9289,12 +10738,12 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr,
&& abbrev->tag != DW_TAG_member)
{
/* 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
@@ -9322,9 +10771,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;
}
@@ -9340,7 +10789,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
@@ -9360,11 +10809,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;
}
@@ -9414,7 +10863,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;
}
@@ -9457,7 +10906,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. */
}
@@ -9466,20 +10915,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;
@@ -9491,7 +10943,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. */
@@ -9513,7 +10965,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;
@@ -9532,7 +10984,14 @@ 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. */
@@ -9572,7 +11031,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;
@@ -9602,11 +11061,19 @@ 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;
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
@@ -9619,25 +11086,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;
@@ -9649,13 +11116,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;
}
@@ -9666,75 +11134,60 @@ find_partial_die_in_comp_unit (unsigned int offset, struct dwarf2_cu *cu)
DW_FORM_ref_sig8). */
static struct partial_die_info *
-find_partial_die (unsigned int offset, struct dwarf2_cu *cu)
+find_partial_die (sect_offset offset, struct dwarf2_cu *cu)
{
+ struct objfile *objfile = cu->objfile;
struct dwarf2_per_cu_data *per_cu = NULL;
struct partial_die_info *pd = NULL;
- if (cu->per_cu->debug_type_section)
- {
- pd = find_partial_die_in_comp_unit (offset, cu);
- if (pd != NULL)
- return pd;
- goto not_found;
- }
-
if (offset_in_cu_p (&cu->header, offset))
{
pd = find_partial_die_in_comp_unit (offset, cu);
if (pd != NULL)
return pd;
+ /* We missed recording what we needed.
+ Load all dies and try again. */
+ per_cu = cu->per_cu;
}
+ else
+ {
+ /* TUs don't reference other CUs/TUs (except via type signatures). */
+ if (cu->per_cu->is_debug_types)
+ {
+ error (_("Dwarf Error: Type Unit at offset 0x%lx contains"
+ " external reference to offset 0x%lx [in module %s].\n"),
+ (long) cu->header.offset.sect_off, (long) offset.sect_off,
+ bfd_get_filename (objfile->obfd));
+ }
+ per_cu = dwarf2_find_containing_comp_unit (offset, objfile);
- per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+ if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
+ load_partial_comp_unit (per_cu);
- if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
- load_partial_comp_unit (per_cu, cu->objfile);
+ per_cu->cu->last_used = 0;
+ pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+ }
- per_cu->cu->last_used = 0;
- pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+ /* If we didn't find it, and not all dies have been loaded,
+ load them all and try again. */
if (pd == NULL && per_cu->load_all_dies == 0)
{
- struct cleanup *back_to;
- struct partial_die_info comp_unit_die;
- struct abbrev_info *abbrev;
- unsigned int bytes_read;
- char *info_ptr;
+ /* FIXME: The testsuite doesn't trigger this code path.
+ http://sourceware.org/bugzilla/show_bug.cgi?id=13961 */
+ free_one_cached_comp_unit (per_cu);
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);
+ 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;
}
@@ -9830,9 +11283,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
@@ -9845,9 +11296,10 @@ fixup_partial_die (struct partial_die_info *part_die,
/* GCC might emit a nameless struct or union that has a linkage
name. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */
if (part_die->name == NULL
- && (part_die->tag == DW_TAG_structure_type
- || part_die->tag == DW_TAG_union_type
- || part_die->tag == DW_TAG_class_type)
+ && (part_die->tag == DW_TAG_class_type
+ || part_die->tag == DW_TAG_interface_type
+ || part_die->tag == DW_TAG_structure_type
+ || part_die->tag == DW_TAG_union_type)
&& part_die->linkage_name != NULL)
{
char *demangled;
@@ -9855,7 +11307,17 @@ fixup_partial_die (struct partial_die_info *part_die,
demangled = cplus_demangle (part_die->linkage_name, DMGL_TYPES);
if (demangled)
{
- part_die->name = obsavestring (demangled, strlen (demangled),
+ const char *base;
+
+ /* Strip any leading namespaces/classes, keep only the base name.
+ DW_AT_name for named DIEs does not contain the prefixes. */
+ base = strrchr (demangled, ':');
+ if (base && base > demangled && base[-1] == ':')
+ base++;
+ else
+ base = demangled;
+
+ part_die->name = obsavestring (base, strlen (base),
&cu->objfile->objfile_obstack);
xfree (demangled);
}
@@ -9867,10 +11329,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;
@@ -9880,10 +11344,10 @@ read_attribute_value (struct attribute *attr, unsigned form,
{
case DW_FORM_ref_addr:
if (cu->header.version == 2)
- DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read);
+ DW_UNSND (attr) = read_address (abfd, info_ptr, cu, &bytes_read);
else
- DW_ADDR (attr) = read_offset (abfd, info_ptr,
- &cu->header, &bytes_read);
+ DW_UNSND (attr) = read_offset (abfd, info_ptr,
+ &cu->header, &bytes_read);
info_ptr += bytes_read;
break;
case DW_FORM_addr:
@@ -9970,19 +11434,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:
@@ -9990,18 +11458,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]"),
@@ -10032,11 +11530,12 @@ read_attribute_value (struct attribute *attr, unsigned form,
/* Read an attribute described by an abbreviated attribute. */
static gdb_byte *
-read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
- bfd *abfd, gdb_byte *info_ptr, struct dwarf2_cu *cu)
+read_attribute (const struct die_reader_specs *reader,
+ struct attribute *attr, struct attr_abbrev *abbrev,
+ gdb_byte *info_ptr)
{
attr->name = abbrev->name;
- return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu);
+ return read_attribute_value (reader, attr, abbrev->form, info_ptr);
}
/* Read dwarf information from a buffer. */
@@ -10314,10 +11813,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;
@@ -10331,7 +11830,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;
@@ -10342,10 +11841,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;
@@ -10358,7 +11857,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)
{
@@ -10366,11 +11865,174 @@ 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;
}
+/* Given index ADDR_INDEX in .debug_addr, fetch the value.
+ ADDR_BASE is the DW_AT_GNU_addr_base attribute or zero.
+ ADDR_SIZE is the size of addresses from the CU header. */
+
+static CORE_ADDR
+read_addr_index_1 (unsigned int addr_index, ULONGEST addr_base, int addr_size)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *abfd = objfile->obfd;
+ const gdb_byte *info_ptr;
+
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->addr);
+ if (dwarf2_per_objfile->addr.buffer == NULL)
+ error (_("DW_FORM_addr_index used without .debug_addr section [in module %s]"),
+ objfile->name);
+ if (addr_base + addr_index * addr_size >= dwarf2_per_objfile->addr.size)
+ error (_("DW_FORM_addr_index pointing outside of "
+ ".debug_addr section [in module %s]"),
+ objfile->name);
+ info_ptr = (dwarf2_per_objfile->addr.buffer
+ + addr_base + addr_index * addr_size);
+ if (addr_size == 4)
+ return bfd_get_32 (abfd, info_ptr);
+ else
+ return bfd_get_64 (abfd, info_ptr);
+}
+
+/* Given index ADDR_INDEX in .debug_addr, fetch the value. */
+
+static CORE_ADDR
+read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index)
+{
+ return read_addr_index_1 (addr_index, cu->addr_base, cu->header.addr_size);
+}
+
+/* Given a pointer to an leb128 value, fetch the value from .debug_addr. */
+
+static CORE_ADDR
+read_addr_index_from_leb128 (struct dwarf2_cu *cu, gdb_byte *info_ptr,
+ unsigned int *bytes_read)
+{
+ bfd *abfd = cu->objfile->obfd;
+ unsigned int addr_index = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
+
+ return read_addr_index (cu, addr_index);
+}
+
+/* Data structure to pass results from dwarf2_read_addr_index_reader
+ back to dwarf2_read_addr_index. */
+
+struct dwarf2_read_addr_index_data
+{
+ ULONGEST addr_base;
+ int addr_size;
+};
+
+/* die_reader_func for dwarf2_read_addr_index. */
+
+static void
+dwarf2_read_addr_index_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
+{
+ struct dwarf2_cu *cu = reader->cu;
+ struct dwarf2_read_addr_index_data *aidata =
+ (struct dwarf2_read_addr_index_data *) data;
+
+ aidata->addr_base = cu->addr_base;
+ aidata->addr_size = cu->header.addr_size;
+}
+
+/* Given an index in .debug_addr, fetch the value.
+ NOTE: This can be called during dwarf expression evaluation,
+ long after the debug information has been read, and thus per_cu->cu
+ may no longer exist. */
+
+CORE_ADDR
+dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
+ unsigned int addr_index)
+{
+ struct objfile *objfile = per_cu->objfile;
+ struct dwarf2_cu *cu = per_cu->cu;
+ ULONGEST addr_base;
+ int addr_size;
+
+ /* This is intended to be called from outside this file. */
+ dw2_setup (objfile);
+
+ /* We need addr_base and addr_size.
+ If we don't have PER_CU->cu, we have to get it.
+ Nasty, but the alternative is storing the needed info in PER_CU,
+ which at this point doesn't seem justified: it's not clear how frequently
+ it would get used and it would increase the size of every PER_CU.
+ Entry points like dwarf2_per_cu_addr_size do a similar thing
+ so we're not in uncharted territory here.
+ Alas we need to be a bit more complicated as addr_base is contained
+ in the DIE.
+
+ We don't need to read the entire CU(/TU).
+ We just need the header and top level die.
+ IWBN to use the aging mechanism to let us lazily later discard the CU.
+ See however init_cutu_and_read_dies_simple. */
+
+ if (cu != NULL)
+ {
+ addr_base = cu->addr_base;
+ addr_size = cu->header.addr_size;
+ }
+ else
+ {
+ struct dwarf2_read_addr_index_data aidata;
+
+ init_cutu_and_read_dies_simple (per_cu, dwarf2_read_addr_index_reader,
+ &aidata);
+ addr_base = aidata.addr_base;
+ addr_size = aidata.addr_size;
+ }
+
+ return read_addr_index_1 (addr_index, addr_base, addr_size);
+}
+
+/* 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 a pointer to just past the end of an LEB128 number in BUF. */
static gdb_byte *
@@ -10387,6 +12049,22 @@ skip_leb128 (bfd *abfd, gdb_byte *buf)
}
}
+/* Return the length of an LEB128 number in BUF. */
+
+static int
+leb128_size (const gdb_byte *buf)
+{
+ const gdb_byte *begin = buf;
+ gdb_byte byte;
+
+ while (1)
+ {
+ byte = *buf++;
+ if ((byte & 128) == 0)
+ return buf - begin;
+ }
+}
+
static void
set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
{
@@ -10408,6 +12086,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;
@@ -10441,22 +12122,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;
@@ -10609,16 +12292,15 @@ add_file_name (struct line_header *lh,
}
/* Read the statement program header starting at OFFSET in
- .debug_line, according to the endianness of ABFD. Return a pointer
+ .debug_line, or .debug_line.dwo. Return a pointer
to a struct line_header, allocated using xmalloc.
NOTE: the strings in the include directory and file name tables of
- the returned object point into debug_line_buffer, and must not be
- freed. */
+ the returned object point into the dwarf line section buffer,
+ and must not be freed. */
static struct line_header *
-dwarf_decode_line_header (unsigned int offset, bfd *abfd,
- struct dwarf2_cu *cu)
+dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
{
struct cleanup *back_to;
struct line_header *lh;
@@ -10626,17 +12308,30 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
unsigned int bytes_read, offset_size;
int i;
char *cur_dir, *cur_file;
+ struct dwarf2_section_info *section;
+ bfd *abfd;
+
+ /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
+ DWO file. */
+ if (cu->dwo_unit && cu->per_cu->is_debug_types)
+ section = &cu->dwo_unit->dwo_file->sections.line;
+ else
+ section = &dwarf2_per_objfile->line;
+ abfd = section->asection->owner;
- dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->line);
- if (dwarf2_per_objfile->line.buffer == NULL)
+ dwarf2_read_section (dwarf2_per_objfile->objfile, section);
+ if (section->buffer == NULL)
{
- complaint (&symfile_complaints, _("missing .debug_line section"));
+ if (cu->dwo_unit && cu->per_cu->is_debug_types)
+ complaint (&symfile_complaints, _("missing .debug_line.dwo section"));
+ else
+ complaint (&symfile_complaints, _("missing .debug_line section"));
return 0;
}
/* 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;
@@ -10647,15 +12342,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;
@@ -10727,8 +12421,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"));
@@ -10737,52 +12430,6 @@ dwarf_decode_line_header (unsigned int offset, bfd *abfd,
return lh;
}
-/* This function exists to work around a bug in certain compilers
- (particularly GCC 2.95), in which the first line number marker of a
- function does not show up until after the prologue, right before
- the second line number marker. This function shifts ADDRESS down
- to the beginning of the function if necessary, and is called on
- addresses passed to record_line. */
-
-static CORE_ADDR
-check_cu_functions (CORE_ADDR address, struct dwarf2_cu *cu)
-{
- struct function_range *fn;
-
- /* Find the function_range containing address. */
- if (!cu->first_fn)
- return address;
-
- if (!cu->cached_fn)
- cu->cached_fn = cu->first_fn;
-
- fn = cu->cached_fn;
- while (fn)
- if (fn->lowpc <= address && fn->highpc > address)
- goto found;
- else
- fn = fn->next;
-
- fn = cu->first_fn;
- while (fn && fn != cu->cached_fn)
- if (fn->lowpc <= address && fn->highpc > address)
- goto found;
- else
- fn = fn->next;
-
- return address;
-
- found:
- if (fn->seen_line)
- return address;
- if (address != fn->lowpc)
- complaint (&symfile_complaints,
- _("misplaced first line number at 0x%lx for '%s'"),
- (unsigned long) address, fn->name);
- fn->seen_line = 1;
- return fn->lowpc;
-}
-
/* Subroutine of dwarf_decode_lines to simplify it.
Return the file name of the psymtab for included file FILE_INDEX
in line header LH of PST.
@@ -10870,31 +12517,12 @@ noop_record_line (struct subfile *subfile, int line, CORE_ADDR pc)
return;
}
-/* Decode the Line Number Program (LNP) for the given line_header
- structure and CU. The actual information extracted and the type
- of structures created from the LNP depends on the value of PST.
-
- 1. If PST is NULL, then this procedure uses the data from the program
- to create all necessary symbol tables, and their linetables.
-
- 2. If PST is not NULL, this procedure reads the program to determine
- the list of files included by the unit represented by PST, and
- builds all the associated partial symbol tables.
-
- COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown.
- It is used for relative paths in the line table.
- NOTE: When processing partial symtabs (pst != NULL),
- comp_dir == pst->dirname.
-
- NOTE: It is important that psymtabs have the same file name (via strcmp)
- as the corresponding symtab. Since COMP_DIR is not used in the name of the
- symtab we don't use it in the name of the psymtabs we create.
- E.g. expand_line_sal requires this when finding psymtabs to expand.
- A good testcase for this is mb-inline.exp. */
+/* Subroutine of dwarf_decode_lines to simplify it.
+ Process the line number information in LH. */
static void
-dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd,
- struct dwarf2_cu *cu, struct partial_symtab *pst)
+dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
+ struct dwarf2_cu *cu, struct partial_symtab *pst)
{
gdb_byte *line_ptr, *extended_end;
gdb_byte *line_end;
@@ -10902,9 +12530,10 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd,
unsigned char op_code, extended_op, adj_opcode;
CORE_ADDR baseaddr;
struct objfile *objfile = cu->objfile;
+ bfd *abfd = objfile->obfd;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
const int decode_for_pst_p = (pst != NULL);
- struct subfile *last_subfile = NULL, *first_subfile = current_subfile;
+ struct subfile *last_subfile = NULL;
void (*p_record_line) (struct subfile *subfile, int line, CORE_ADDR pc)
= record_line;
@@ -10980,8 +12609,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd,
last_subfile = current_subfile;
}
/* Append row to matrix using current values. */
- addr = check_cu_functions (address, cu);
- addr = gdbarch_addr_bits_remove (gdbarch, addr);
+ addr = gdbarch_addr_bits_remove (gdbarch, address);
(*p_record_line) (current_subfile, line, addr);
}
}
@@ -11016,7 +12644,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd,
complaint (&symfile_complaints,
_(".debug_line address at offset 0x%lx is 0 "
"[in module %s]"),
- line_offset, cu->objfile->name);
+ line_offset, objfile->name);
p_record_line = noop_record_line;
}
@@ -11079,8 +12707,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd,
(*p_record_line) (last_subfile, 0, addr);
last_subfile = current_subfile;
}
- addr = check_cu_functions (address, cu);
- addr = gdbarch_addr_bits_remove (gdbarch, addr);
+ addr = gdbarch_addr_bits_remove (gdbarch, address);
(*p_record_line) (current_subfile, line, addr);
}
}
@@ -11184,6 +12811,41 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd,
}
}
}
+}
+
+/* Decode the Line Number Program (LNP) for the given line_header
+ structure and CU. The actual information extracted and the type
+ of structures created from the LNP depends on the value of PST.
+
+ 1. If PST is NULL, then this procedure uses the data from the program
+ to create all necessary symbol tables, and their linetables.
+
+ 2. If PST is not NULL, this procedure reads the program to determine
+ the list of files included by the unit represented by PST, and
+ builds all the associated partial symbol tables.
+
+ COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown.
+ It is used for relative paths in the line table.
+ NOTE: When processing partial symtabs (pst != NULL),
+ comp_dir == pst->dirname.
+
+ NOTE: It is important that psymtabs have the same file name (via strcmp)
+ as the corresponding symtab. Since COMP_DIR is not used in the name of the
+ symtab we don't use it in the name of the psymtabs we create.
+ E.g. expand_line_sal requires this when finding psymtabs to expand.
+ A good testcase for this is mb-inline.exp. */
+
+static void
+dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
+ struct dwarf2_cu *cu, struct partial_symtab *pst,
+ int want_line_info)
+{
+ struct objfile *objfile = cu->objfile;
+ const int decode_for_pst_p = (pst != NULL);
+ struct subfile *first_subfile = current_subfile;
+
+ if (want_line_info)
+ dwarf_decode_lines_1 (lh, comp_dir, cu, pst);
if (decode_for_pst_p)
{
@@ -11205,13 +12867,12 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd,
/* Make sure a symtab is created for every file, even files
which contain only variables (i.e. no code with associated
line numbers). */
-
int i;
- struct file_entry *fe;
for (i = 0; i < lh->num_file_names; i++)
{
char *dir = NULL;
+ struct file_entry *fe;
fe = &lh->file_names[i];
if (fe->dir_index)
@@ -11226,7 +12887,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir, bfd *abfd,
if (current_subfile->symtab == NULL)
current_subfile->symtab = allocate_symtab (current_subfile->name,
- cu->objfile);
+ objfile);
fe->symtab = current_subfile->symtab;
}
}
@@ -11310,17 +12971,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,
@@ -11466,8 +13134,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;
@@ -11590,14 +13257,6 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
{
dwarf2_const_value (attr, sym, cu);
}
- attr = dwarf2_attr (die, DW_AT_variable_parameter, cu);
- if (attr && DW_UNSND (attr))
- {
- struct type *ref_type;
-
- ref_type = lookup_reference_type (SYMBOL_TYPE (sym));
- SYMBOL_TYPE (sym) = ref_type;
- }
list_to_add = cu->list_in_scope;
break;
@@ -11706,7 +13365,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
namespaces based on the demangled name. */
if (!processing_has_namespace_info
&& cu->language == language_cplus)
- cp_scan_for_anonymous_namespaces (sym);
+ cp_scan_for_anonymous_namespaces (sym, objfile);
}
return (sym);
}
@@ -11730,7 +13389,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) ?
@@ -11764,7 +13423,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;
@@ -11780,6 +13439,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;
@@ -11807,6 +13467,7 @@ dwarf2_const_value_attr (struct attribute *attr, struct type *type,
break;
case DW_FORM_string:
case DW_FORM_strp:
+ case DW_FORM_GNU_str_index:
/* DW_STRING is already allocated on the objfile obstack, point
directly to it. */
*bytes = (gdb_byte *) DW_STRING (attr);
@@ -11871,7 +13532,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;
@@ -11988,38 +13649,44 @@ static struct type *
lookup_die_type (struct die_info *die, struct attribute *attr,
struct dwarf2_cu *cu)
{
+ struct objfile *objfile = cu->objfile;
struct type *this_type;
/* First see if we have it cached. */
if (is_ref_attr (attr))
{
- unsigned int offset = dwarf2_get_ref_die_offset (attr);
+ sect_offset offset = dwarf2_get_ref_die_offset (attr);
this_type = get_die_type_at_offset (offset, cu->per_cu);
}
else if (attr->form == DW_FORM_ref_sig8)
{
struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr);
- struct dwarf2_cu *sig_cu;
- unsigned int offset;
/* sig_type will be NULL if the signatured type is missing from
the debug info. */
if (sig_type == NULL)
error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
"at 0x%x [in module %s]"),
- die->offset, cu->objfile->name);
+ die->offset.sect_off, objfile->name);
- gdb_assert (sig_type->per_cu.debug_type_section);
- offset = sig_type->per_cu.offset + sig_type->type_offset;
- this_type = get_die_type_at_offset (offset, &sig_type->per_cu);
+ gdb_assert (sig_type->per_cu.is_debug_types);
+ /* If we haven't filled in type_offset_in_section yet, then we
+ haven't read the type in yet. */
+ this_type = NULL;
+ if (sig_type->type_offset_in_section.sect_off != 0)
+ {
+ this_type =
+ get_die_type_at_offset (sig_type->type_offset_in_section,
+ &sig_type->per_cu);
+ }
}
else
{
dump_die_for_error (die);
error (_("Dwarf Error: Bad type attribute %s [in module %s]"),
- dwarf_attr_name (attr->name), cu->objfile->name);
+ dwarf_attr_name (attr->name), objfile->name);
}
/* If not cached we need to read it in. */
@@ -12030,9 +13697,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. */
@@ -12043,14 +13713,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;
@@ -12224,6 +13894,42 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
return NULL;
}
+/* GCC might emit a nameless typedef that has a linkage name. Determine the
+ prefix part in such case. See
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */
+
+static char *
+anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *attr;
+ char *base;
+
+ if (die->tag != DW_TAG_class_type && die->tag != DW_TAG_interface_type
+ && die->tag != DW_TAG_structure_type && die->tag != DW_TAG_union_type)
+ return NULL;
+
+ attr = dwarf2_attr (die, DW_AT_name, cu);
+ if (attr != NULL && DW_STRING (attr) != NULL)
+ return NULL;
+
+ attr = dwarf2_attr (die, DW_AT_linkage_name, cu);
+ if (attr == NULL)
+ attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
+ if (attr == NULL || DW_STRING (attr) == NULL)
+ return NULL;
+
+ /* dwarf2_name had to be already called. */
+ gdb_assert (DW_STRING_IS_CANONICAL (attr));
+
+ /* Strip the base name, keep any leading namespaces/classes. */
+ base = strrchr (DW_STRING (attr), ':');
+ if (base == NULL || base == DW_STRING (attr) || base[-1] != ':')
+ return "";
+
+ return obsavestring (DW_STRING (attr), &base[-1] - DW_STRING (attr),
+ &cu->objfile->objfile_obstack);
+}
+
/* Return the name of the namespace/class that DIE is defined within,
or "" if we can't tell. The caller should not xfree the result.
@@ -12239,17 +13945,22 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
then determine_prefix on foo's die will return "N::C". */
-static char *
+static const char *
determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
{
struct die_info *parent, *spec_die;
struct dwarf2_cu *spec_cu;
struct type *parent_type;
+ char *retval;
if (cu->language != language_cplus && cu->language != language_java
&& cu->language != language_fortran)
return "";
+ retval = anonymous_struct_prefix (die, cu);
+ if (retval)
+ return retval;
+
/* We have to be careful in the presence of DW_AT_specification.
For example, with GCC 3.4, given the code
@@ -12541,12 +14252,21 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
if (demangled)
{
+ char *base;
+
/* FIXME: we already did this for the partial symbol... */
- DW_STRING (attr)
- = obsavestring (demangled, strlen (demangled),
- &cu->objfile->objfile_obstack);
+ DW_STRING (attr) = obsavestring (demangled, strlen (demangled),
+ &cu->objfile->objfile_obstack);
DW_STRING_IS_CANONICAL (attr) = 1;
xfree (demangled);
+
+ /* Strip any leading namespaces/classes, keep only the base name.
+ DW_AT_name for named DIEs does not contain the prefixes. */
+ base = strrchr (DW_STRING (attr), ':');
+ if (base && base > DW_STRING (attr) && base[-1] == ':')
+ return &base[1];
+ else
+ return DW_STRING (attr);
}
}
break;
@@ -12730,6 +14450,8 @@ dwarf_tag_name (unsigned tag)
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_";
}
@@ -12926,6 +14648,17 @@ dwarf_attr_name (unsigned attr)
return "DW_AT_signature";
case DW_AT_linkage_name:
return "DW_AT_linkage_name";
+ /* Tentative Fission values. */
+ case DW_AT_GNU_dwo_name:
+ return "DW_AT_GNU_dwo_name";
+ case DW_AT_GNU_dwo_id:
+ return "DW_AT_GNU_dwo_id";
+ case DW_AT_GNU_addr_base:
+ return "DW_AT_GNU_addr_base";
+ case DW_AT_GNU_pubnames:
+ return "DW_AT_GNU_pubnames";
+ case DW_AT_GNU_pubtypes:
+ return "DW_AT_GNU_pubtypes";
/* SGI/MIPS extensions. */
#ifdef MIPS /* collides with DW_AT_HP_block_index */
case DW_AT_MIPS_fde:
@@ -13074,6 +14807,10 @@ dwarf_form_name (unsigned form)
return "DW_FORM_flag_present";
case DW_FORM_ref_sig8:
return "DW_FORM_ref_sig8";
+ case DW_FORM_GNU_addr_index:
+ return "DW_FORM_GNU_addr_index";
+ case DW_FORM_GNU_str_index:
+ return "DW_FORM_GNU_str_index";
default:
return "DW_FORM_";
}
@@ -13401,6 +15138,8 @@ dwarf_stack_op_name (unsigned op)
return "DW_OP_GNU_push_tls_address";
case DW_OP_GNU_uninit:
return "DW_OP_GNU_uninit";
+ case DW_OP_GNU_encoded_addr:
+ return "DW_OP_GNU_encoded_addr";
case DW_OP_GNU_implicit_pointer:
return "DW_OP_GNU_implicit_pointer";
case DW_OP_GNU_entry_value:
@@ -13415,6 +15154,8 @@ dwarf_stack_op_name (unsigned op)
return "DW_OP_GNU_convert";
case DW_OP_GNU_reinterpret:
return "DW_OP_GNU_reinterpret";
+ case DW_OP_GNU_parameter_ref:
+ return "DW_OP_GNU_parameter_ref";
default:
return NULL;
}
@@ -13576,13 +15317,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);
@@ -13601,8 +15342,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;
@@ -13617,11 +15358,17 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
fprintf_unfiltered (f, "expression: size %u",
DW_BLOCK (&die->attrs[i])->size);
break;
+ case DW_FORM_ref_addr:
+ fprintf_unfiltered (f, "ref address: ");
+ fputs_filtered (hex_string (DW_UNSND (&die->attrs[i])), f);
+ break;
case DW_FORM_ref1:
case DW_FORM_ref2:
case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
fprintf_unfiltered (f, "constant ref: 0x%lx (adjusted)",
- (long) (DW_ADDR (&die->attrs[i])));
+ (long) (DW_UNSND (&die->attrs[i])));
break;
case DW_FORM_data1:
case DW_FORM_data2:
@@ -13639,12 +15386,13 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
case DW_FORM_ref_sig8:
if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL)
fprintf_unfiltered (f, "signatured type, offset: 0x%x",
- DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset);
+ DW_SIGNATURED_TYPE (&die->attrs[i])->per_cu.offset.sect_off);
else
fprintf_unfiltered (f, "signatured type, offset: unknown");
break;
case DW_FORM_string:
case DW_FORM_strp:
+ case DW_FORM_GNU_str_index:
fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)",
DW_STRING (&die->attrs[i])
? DW_STRING (&die->attrs[i]) : "",
@@ -13728,11 +15476,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)
{
@@ -13750,16 +15502,22 @@ is_ref_attr (struct attribute *attr)
}
}
-static unsigned int
+/* Return DIE offset of ATTR. Return 0 with complaint if ATTR is not of the
+ required kind. */
+
+static sect_offset
dwarf2_get_ref_die_offset (struct attribute *attr)
{
+ sect_offset retval = { DW_UNSND (attr) };
+
if (is_ref_attr (attr))
- return DW_ADDR (attr);
+ return retval;
+ retval.sect_off = 0;
complaint (&symfile_complaints,
_("unsupported die ref attribute form: '%s'"),
dwarf_form_name (attr->form));
- return 0;
+ return retval;
}
/* Return the constant value held by ATTR. Return DEFAULT_VALUE if
@@ -13821,7 +15579,7 @@ maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
}
/* Add it to the queue. */
- queue_comp_unit (per_cu, this_cu->objfile);
+ queue_comp_unit (per_cu);
return 1;
}
@@ -13856,7 +15614,7 @@ follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr,
Returns NULL if OFFSET is invalid. */
static struct die_info *
-follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
+follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
{
struct die_info temp_die;
struct dwarf2_cu *target_cu, *cu = *ref_cu;
@@ -13865,7 +15623,7 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
target_cu = cu;
- if (cu->per_cu->debug_type_section)
+ if (cu->per_cu->is_debug_types)
{
/* .debug_types CUs cannot reference anything outside their CU.
If they need to, they have to reference a signatured type via
@@ -13881,7 +15639,7 @@ follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu)
/* 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);
+ load_full_comp_unit (per_cu);
target_cu = per_cu->cu;
}
@@ -13889,12 +15647,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);
}
*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.
@@ -13905,7 +15663,7 @@ static struct die_info *
follow_die_ref (struct die_info *src_die, struct attribute *attr,
struct dwarf2_cu **ref_cu)
{
- unsigned int offset = dwarf2_get_ref_die_offset (attr);
+ sect_offset offset = dwarf2_get_ref_die_offset (attr);
struct dwarf2_cu *cu = *ref_cu;
struct die_info *die;
@@ -13913,21 +15671,22 @@ follow_die_ref (struct die_info *src_die, struct attribute *attr,
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
"at 0x%x [in module %s]"),
- offset, src_die->offset, cu->objfile->name);
+ offset.sect_off, src_die->offset.sect_off, cu->objfile->name);
return die;
}
-/* Return DWARF block and its CU referenced by OFFSET at PER_CU. Returned
- value is intended for DW_OP_call*. You must call xfree on returned
- dwarf2_locexpr_baton->data. */
+/* Return DWARF block referenced by DW_AT_location of DIE at OFFSET at PER_CU.
+ Returned value is intended for DW_OP_call*. Returned
+ dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE. */
struct dwarf2_locexpr_baton
-dwarf2_fetch_die_location_block (unsigned int offset,
+dwarf2_fetch_die_location_block (cu_offset offset_in_cu,
struct dwarf2_per_cu_data *per_cu,
CORE_ADDR (*get_frame_pc) (void *baton),
void *baton)
{
+ sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off };
struct dwarf2_cu *cu;
struct die_info *die;
struct attribute *attr;
@@ -13942,12 +15701,13 @@ dwarf2_fetch_die_location_block (unsigned int offset,
die = follow_die_offset (offset, &cu);
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
- offset, per_cu->cu->objfile->name);
+ offset.sect_off, per_cu->objfile->name);
attr = dwarf2_attr (die, DW_AT_location, cu);
if (!attr)
{
- /* DWARF: "If there is no such attribute, then there is no effect.". */
+ /* DWARF: "If there is no such attribute, then there is no effect.".
+ DATA is ignored if SIZE is 0. */
retval.data = NULL;
retval.size = 0;
@@ -13969,16 +15729,13 @@ dwarf2_fetch_die_location_block (unsigned int offset,
if (!attr_form_is_block (attr))
error (_("Dwarf Error: DIE at 0x%x referenced in module %s "
"is neither DW_FORM_block* nor DW_FORM_exprloc"),
- offset, per_cu->cu->objfile->name);
+ offset.sect_off, per_cu->objfile->name);
retval.data = DW_BLOCK (attr)->data;
retval.size = DW_BLOCK (attr)->size;
}
retval.per_cu = cu->per_cu;
- if (retval.data)
- retval.data = xmemdup (retval.data, retval.size, retval.size);
-
age_cached_comp_units ();
return retval;
@@ -13988,11 +15745,15 @@ dwarf2_fetch_die_location_block (unsigned int offset,
PER_CU. */
struct type *
-dwarf2_get_die_type (unsigned int die_offset,
+dwarf2_get_die_type (cu_offset die_offset,
struct dwarf2_per_cu_data *per_cu)
{
+ sect_offset die_offset_sect;
+
dw2_setup (per_cu->objfile);
- return get_die_type_at_offset (die_offset, per_cu);
+
+ die_offset_sect.sect_off = per_cu->offset.sect_off + die_offset.cu_off;
+ return get_die_type_at_offset (die_offset_sect, per_cu);
}
/* Follow the signature attribute ATTR in SRC_DIE.
@@ -14014,18 +15775,20 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
if (sig_type == NULL)
error (_("Dwarf Error: Cannot find signatured DIE referenced from DIE "
"at 0x%x [in module %s]"),
- src_die->offset, objfile->name);
+ src_die->offset.sect_off, objfile->name);
/* If necessary, add it to the queue and load its DIEs. */
if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu))
- read_signatured_type (objfile, sig_type);
+ read_signatured_type (sig_type);
gdb_assert (sig_type->per_cu.cu != NULL);
sig_cu = sig_type->per_cu.cu;
- temp_die.offset = sig_cu->header.offset + sig_type->type_offset;
- die = htab_find_with_hash (sig_cu->die_hash, &temp_die, temp_die.offset);
+ gdb_assert (sig_type->type_offset_in_section.sect_off != 0);
+ temp_die.offset = sig_type->type_offset_in_section;
+ die = htab_find_with_hash (sig_cu->die_hash, &temp_die,
+ temp_die.offset.sect_off);
if (die)
{
*ref_cu = sig_cu;
@@ -14034,7 +15797,7 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
error (_("Dwarf Error: Cannot find signatured DIE at 0x%x referenced "
"from DIE at 0x%x [in module %s]"),
- sig_type->type_offset, src_die->offset, objfile->name);
+ temp_die.offset.sect_off, src_die->offset.sect_off, objfile->name);
}
/* Given an offset of a signatured type, return its signatured_type. */
@@ -14042,12 +15805,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
@@ -14055,100 +15818,96 @@ lookup_signatured_type_at_offset (struct objfile *objfile,
+ (initial_length_size == 4 ? 4 : 8) /*debug_abbrev_offset*/
+ 1 /*address_size*/);
find_entry.signature = bfd_get_64 (objfile->obfd, info_ptr + sig_offset);
- type_sig = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
+ sig_type = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
/* This is only used to lookup previously recorded types.
If we didn't find it, it's our bug. */
- gdb_assert (type_sig != NULL);
- gdb_assert (offset == type_sig->per_cu.offset);
+ gdb_assert (sig_type != NULL);
+ gdb_assert (offset.sect_off == sig_type->per_cu.offset.sect_off);
- return type_sig;
+ return sig_type;
}
-/* Read in signatured type at OFFSET and build its CU and die(s). */
+/* Load the DIEs associated with type unit PER_CU into memory. */
static void
-read_signatured_type_at_offset (struct objfile *objfile,
- struct dwarf2_section_info *sect,
- unsigned int offset)
+load_full_type_unit (struct dwarf2_per_cu_data *per_cu)
{
- struct signatured_type *type_sig;
+ struct objfile *objfile = per_cu->objfile;
+ struct dwarf2_section_info *sect = per_cu->info_or_types_section;
+ sect_offset offset = per_cu->offset;
+ struct signatured_type *sig_type;
dwarf2_read_section (objfile, sect);
/* We have the section offset, but we need the signature to do the
- hash table lookup. */
- type_sig = lookup_signatured_type_at_offset (objfile, sect, offset);
+ hash table lookup. */
+ /* FIXME: This is sorta unnecessary, read_signatured_type only uses
+ the signature to assert we found the right one.
+ Ok, but it's a lot of work. We should simplify things so any needed
+ assert doesn't require all this clumsiness. */
+ sig_type = lookup_signatured_type_at_offset (objfile, sect, offset);
- gdb_assert (type_sig->per_cu.cu == NULL);
+ gdb_assert (&sig_type->per_cu == per_cu);
+ gdb_assert (sig_type->per_cu.cu == NULL);
- read_signatured_type (objfile, type_sig);
+ read_signatured_type (sig_type);
- gdb_assert (type_sig->per_cu.cu != NULL);
+ gdb_assert (sig_type->per_cu.cu != NULL);
}
-/* Read in a signatured type and build its CU and DIEs. */
+/* die_reader_func for read_signatured_type.
+ This is identical to load_full_comp_unit_reader,
+ but is kept separate for now. */
static void
-read_signatured_type (struct objfile *objfile,
- struct signatured_type *type_sig)
+read_signatured_type_reader (const struct die_reader_specs *reader,
+ gdb_byte *info_ptr,
+ struct die_info *comp_unit_die,
+ int has_children,
+ void *data)
{
- gdb_byte *types_ptr;
- struct die_reader_specs reader_specs;
- struct dwarf2_cu *cu;
- ULONGEST signature;
- struct cleanup *back_to, *free_cu_cleanup;
- struct dwarf2_section_info *section = type_sig->per_cu.debug_type_section;
-
- dwarf2_read_section (objfile, section);
- types_ptr = section->buffer + type_sig->per_cu.offset;
-
- gdb_assert (type_sig->per_cu.cu == NULL);
-
- cu = xmalloc (sizeof (*cu));
- init_one_comp_unit (cu, objfile);
-
- type_sig->per_cu.cu = cu;
- cu->per_cu = &type_sig->per_cu;
-
- /* If an error occurs while loading, release our storage. */
- free_cu_cleanup = make_cleanup (free_one_comp_unit, cu);
-
- types_ptr = read_type_comp_unit_head (&cu->header, section, &signature,
- types_ptr, objfile->obfd);
- gdb_assert (signature == type_sig->signature);
-
- cu->die_hash
- = htab_create_alloc_ex (cu->header.length / 12,
- die_hash,
- die_eq,
- NULL,
- &cu->comp_unit_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
-
- dwarf2_read_abbrevs (cu->objfile->obfd, cu);
- back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
+ struct dwarf2_cu *cu = reader->cu;
+ struct attribute *attr;
- init_cu_die_reader (&reader_specs, cu);
+ gdb_assert (cu->die_hash == NULL);
+ cu->die_hash =
+ htab_create_alloc_ex (cu->header.length / 12,
+ die_hash,
+ die_eq,
+ NULL,
+ &cu->comp_unit_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
- cu->dies = read_die_and_children (&reader_specs, types_ptr, &types_ptr,
- NULL /*parent*/);
+ if (has_children)
+ comp_unit_die->child = read_die_and_siblings (reader, info_ptr,
+ &info_ptr, comp_unit_die);
+ cu->dies = comp_unit_die;
+ /* comp_unit_die is not stored in die_hash, no need. */
/* We try not to read any attributes in this function, because not
- all objfiles needed for references have been loaded yet, and symbol
+ all CUs needed for references have been loaded yet, and symbol
table processing isn't initialized. But we have to set the CU language,
- or we won't be able to build types correctly. */
+ 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);
+}
- 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_tu_and_read_dies (per_cu, 1, read_signatured_type_reader, NULL);
}
/* Decode simple location descriptions.
@@ -14310,6 +16069,11 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
i += 4;
break;
+ case DW_OP_const8u:
+ stack[++stacki] = read_8_bytes (objfile->obfd, &data[i]);
+ i += 8;
+ break;
+
case DW_OP_constu:
stack[++stacki] = read_unsigned_leb128 (NULL, (data + i),
&bytes_read);
@@ -14357,14 +16121,23 @@ decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
/* Nothing should follow this operator, so the top of stack would
be returned. */
/* This is valid for partial global symbols, but the variable's
- address will be bogus in the psymtab. */
+ address will be bogus in the psymtab. Make it always at least
+ non-zero to not look as a variable garbage collected by linker
+ which have DW_OP_addr 0. */
if (i < size)
dwarf2_complex_location_expr_complaint ();
+ stack[stacki]++;
break;
case DW_OP_GNU_uninit:
break;
+ case DW_OP_GNU_addr_index:
+ stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i],
+ &bytes_read);
+ i += bytes_read;
+ break;
+
default:
{
const char *name = dwarf_stack_op_name (op);
@@ -14752,6 +16525,8 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes,
case DW_FORM_sdata:
case DW_FORM_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
bytes = skip_leb128 (abfd, bytes);
break;
@@ -14872,7 +16647,7 @@ dwarf_parse_macro_header (gdb_byte **opcode_definitions,
}
/* A helper for dwarf_decode_macros that handles the GNU extensions,
- including DW_GNU_MACINFO_transparent_include. */
+ including DW_MACRO_GNU_transparent_include. */
static void
dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
@@ -14881,7 +16656,8 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
struct dwarf2_section_info *section,
int section_is_gnu,
unsigned int offset_size,
- struct objfile *objfile)
+ struct objfile *objfile,
+ htab_t include_hash)
{
enum dwarf_macro_record_type macinfo_type;
int at_commandline;
@@ -15056,16 +16832,33 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
case DW_MACRO_GNU_transparent_include:
{
LONGEST offset;
+ void **slot;
offset = read_offset_1 (abfd, mac_ptr, offset_size);
mac_ptr += offset_size;
- dwarf_decode_macro_bytes (abfd,
- section->buffer + offset,
- mac_end, current_file,
- lh, comp_dir,
- section, section_is_gnu,
- offset_size, objfile);
+ slot = htab_find_slot (include_hash, mac_ptr, INSERT);
+ if (*slot != NULL)
+ {
+ /* This has actually happened; see
+ http://sourceware.org/bugzilla/show_bug.cgi?id=13568. */
+ complaint (&symfile_complaints,
+ _("recursive DW_MACRO_GNU_transparent_include in "
+ ".debug_macro section"));
+ }
+ else
+ {
+ *slot = mac_ptr;
+
+ dwarf_decode_macro_bytes (abfd,
+ section->buffer + offset,
+ mac_end, current_file,
+ lh, comp_dir,
+ section, section_is_gnu,
+ offset_size, objfile, include_hash);
+
+ htab_remove_elt (include_hash, mac_ptr);
+ }
}
break;
@@ -15103,13 +16896,17 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
struct dwarf2_section_info *section,
int section_is_gnu)
{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
gdb_byte *mac_ptr, *mac_end;
struct macro_source_file *current_file = 0;
enum dwarf_macro_record_type macinfo_type;
unsigned int offset_size = cu->header.offset_size;
gdb_byte *opcode_definitions[256];
+ struct cleanup *cleanup;
+ htab_t include_hash;
+ void **slot;
- dwarf2_read_section (dwarf2_per_objfile->objfile, section);
+ dwarf2_read_section (objfile, section);
if (section->buffer == NULL)
{
complaint (&symfile_complaints, _("missing %s section"),
@@ -15186,7 +16983,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;
@@ -15241,13 +17038,21 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
command-line macro definitions/undefinitions. This flag is unset when we
reach the first DW_MACINFO_start_file entry. */
- dwarf_decode_macro_bytes (abfd, section->buffer + offset, mac_end,
+ include_hash = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+ cleanup = make_cleanup_htab_delete (include_hash);
+ mac_ptr = section->buffer + offset;
+ slot = htab_find_slot (include_hash, mac_ptr, INSERT);
+ *slot = mac_ptr;
+ dwarf_decode_macro_bytes (abfd, mac_ptr, mac_end,
current_file, lh, comp_dir, section, section_is_gnu,
- offset_size, cu->objfile);
+ offset_size, objfile, include_hash);
+ do_cleanups (cleanup);
}
/* Check if the attribute's form is a DW_FORM_block*
if so return true else false. */
+
static int
attr_form_is_block (struct attribute *attr)
{
@@ -15267,6 +17072,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)
{
@@ -15275,7 +17081,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.
@@ -15288,6 +17093,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)
{
@@ -15305,6 +17111,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
@@ -15312,15 +17129,16 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
struct dwarf2_loclist_baton *baton,
struct attribute *attr)
{
- dwarf2_read_section (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->loc);
+ struct dwarf2_section_info *section = cu_debug_loc_section (cu);
+
+ dwarf2_read_section (dwarf2_per_objfile->objfile, section);
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
/* We don't know how long the location list is, but make sure we
don't run off the edge of the section. */
- baton->size = dwarf2_per_objfile->loc.size - DW_UNSND (attr);
- baton->data = dwarf2_per_objfile->loc.buffer + DW_UNSND (attr);
+ baton->size = section->size - DW_UNSND (attr);
+ baton->data = section->buffer + DW_UNSND (attr);
baton->base_address = cu->base_address;
}
@@ -15328,16 +17146,18 @@ static void
dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_section_info *section = cu_debug_loc_section (cu);
+
if (attr_form_is_section_offset (attr)
- /* ".debug_loc" may not exist at all, or the offset may be outside
+ /* .debug_loc{,.dwo} may not exist at all, or the offset may be outside
the section. If so, fall through to the complaint in the
other branch. */
- && DW_UNSND (attr) < dwarf2_section_size (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->loc))
+ && DW_UNSND (attr) < dwarf2_section_size (objfile, section))
{
struct dwarf2_loclist_baton *baton;
- baton = obstack_alloc (&cu->objfile->objfile_obstack,
+ baton = obstack_alloc (&objfile->objfile_obstack,
sizeof (struct dwarf2_loclist_baton));
fill_in_loclist_baton (cu, baton, attr);
@@ -15354,7 +17174,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);
@@ -15374,7 +17194,6 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
dwarf2_invalid_attrib_class_complaint ("location description",
SYMBOL_NATURAL_NAME (sym));
baton->size = 0;
- baton->data = NULL;
}
SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
@@ -15399,26 +17218,42 @@ dwarf2_per_cu_objfile (struct dwarf2_per_cu_data *per_cu)
return objfile;
}
+/* Return comp_unit_head for PER_CU, either already available in PER_CU->CU
+ (CU_HEADERP is unused in such case) or prepare a temporary copy at
+ CU_HEADERP first. */
+
+static const struct comp_unit_head *
+per_cu_header_read_in (struct comp_unit_head *cu_headerp,
+ struct dwarf2_per_cu_data *per_cu)
+{
+ struct objfile *objfile;
+ struct dwarf2_per_objfile *per_objfile;
+ gdb_byte *info_ptr;
+
+ if (per_cu->cu)
+ return &per_cu->cu->header;
+
+ objfile = per_cu->objfile;
+ per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+ info_ptr = per_objfile->info.buffer + per_cu->offset.sect_off;
+
+ memset (cu_headerp, 0, sizeof (*cu_headerp));
+ read_comp_unit_head (cu_headerp, info_ptr, objfile->obfd);
+
+ return cu_headerp;
+}
+
/* Return the address size given in the compilation unit header for CU. */
-CORE_ADDR
+int
dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
{
- if (per_cu->cu)
- return per_cu->cu->header.addr_size;
- else
- {
- /* If the CU is not currently read in, we re-read its header. */
- struct objfile *objfile = per_cu->objfile;
- struct dwarf2_per_objfile *per_objfile
- = objfile_data (objfile, dwarf2_objfile_data_key);
- gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset;
- struct comp_unit_head cu_header;
+ struct comp_unit_head cu_header_local;
+ const struct comp_unit_head *cu_headerp;
- memset (&cu_header, 0, sizeof cu_header);
- read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
- return cu_header.addr_size;
- }
+ cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu);
+
+ return cu_headerp->addr_size;
}
/* Return the offset size given in the compilation unit header for CU. */
@@ -15426,21 +17261,28 @@ dwarf2_per_cu_addr_size (struct dwarf2_per_cu_data *per_cu)
int
dwarf2_per_cu_offset_size (struct dwarf2_per_cu_data *per_cu)
{
- if (per_cu->cu)
- return per_cu->cu->header.offset_size;
- else
- {
- /* If the CU is not currently read in, we re-read its header. */
- struct objfile *objfile = per_cu->objfile;
- struct dwarf2_per_objfile *per_objfile
- = objfile_data (objfile, dwarf2_objfile_data_key);
- gdb_byte *info_ptr = per_objfile->info.buffer + per_cu->offset;
- struct comp_unit_head cu_header;
+ struct comp_unit_head cu_header_local;
+ const struct comp_unit_head *cu_headerp;
- memset (&cu_header, 0, sizeof cu_header);
- read_comp_unit_head (&cu_header, info_ptr, objfile->obfd);
- return cu_header.offset_size;
- }
+ cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu);
+
+ return cu_headerp->offset_size;
+}
+
+/* See its dwarf2loc.h declaration. */
+
+int
+dwarf2_per_cu_ref_addr_size (struct dwarf2_per_cu_data *per_cu)
+{
+ struct comp_unit_head cu_header_local;
+ const struct comp_unit_head *cu_headerp;
+
+ cu_headerp = per_cu_header_read_in (&cu_header_local, per_cu);
+
+ if (cu_headerp->version == 2)
+ return cu_headerp->addr_size;
+ else
+ return cu_headerp->offset_size;
}
/* Return the text offset of the CU. The returned offset comes from
@@ -15460,7 +17302,7 @@ dwarf2_per_cu_text_offset (struct dwarf2_per_cu_data *per_cu)
the DIE at OFFSET. Raises an error on failure. */
static struct dwarf2_per_cu_data *
-dwarf2_find_containing_comp_unit (unsigned int offset,
+dwarf2_find_containing_comp_unit (sect_offset offset,
struct objfile *objfile)
{
struct dwarf2_per_cu_data *this_cu;
@@ -15472,54 +17314,45 @@ dwarf2_find_containing_comp_unit (unsigned int offset,
{
int mid = low + (high - low) / 2;
- if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset)
+ if (dwarf2_per_objfile->all_comp_units[mid]->offset.sect_off
+ >= offset.sect_off)
high = mid;
else
low = mid + 1;
}
gdb_assert (low == high);
- if (dwarf2_per_objfile->all_comp_units[low]->offset > offset)
+ if (dwarf2_per_objfile->all_comp_units[low]->offset.sect_off
+ > offset.sect_off)
{
if (low == 0)
error (_("Dwarf Error: could not find partial DIE containing "
"offset 0x%lx [in module %s]"),
- (long) offset, bfd_get_filename (objfile->obfd));
+ (long) offset.sect_off, bfd_get_filename (objfile->obfd));
- gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset <= offset);
+ gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset.sect_off
+ <= offset.sect_off);
return dwarf2_per_objfile->all_comp_units[low-1];
}
else
{
this_cu = dwarf2_per_objfile->all_comp_units[low];
if (low == dwarf2_per_objfile->n_comp_units - 1
- && offset >= this_cu->offset + this_cu->length)
- error (_("invalid dwarf2 offset %u"), offset);
- gdb_assert (offset < this_cu->offset + this_cu->length);
+ && offset.sect_off >= this_cu->offset.sect_off + this_cu->length)
+ error (_("invalid dwarf2 offset %u"), offset.sect_off);
+ gdb_assert (offset.sect_off < this_cu->offset.sect_off + this_cu->length);
return this_cu;
}
}
-/* Locate the compilation unit from OBJFILE which is located at exactly
- OFFSET. Raises an error on failure. */
-
-static struct dwarf2_per_cu_data *
-dwarf2_find_comp_unit (unsigned int offset, struct objfile *objfile)
-{
- struct dwarf2_per_cu_data *this_cu;
-
- this_cu = dwarf2_find_containing_comp_unit (offset, objfile);
- if (this_cu->offset != offset)
- error (_("no compilation unit with offset %u."), offset);
- return this_cu;
-}
-
-/* Initialize dwarf2_cu CU for OBJFILE in a pre-allocated space. */
+/* Initialize dwarf2_cu CU, owned by PER_CU. */
static void
-init_one_comp_unit (struct dwarf2_cu *cu, struct objfile *objfile)
+init_one_comp_unit (struct dwarf2_cu *cu, struct dwarf2_per_cu_data *per_cu)
{
memset (cu, 0, sizeof (*cu));
- cu->objfile = objfile;
+ per_cu->cu = cu;
+ cu->per_cu = per_cu;
+ cu->objfile = per_cu->objfile;
obstack_init (&cu->comp_unit_obstack);
}
@@ -15539,6 +17372,10 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die)
cu->language = language_minimal;
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
@@ -15548,12 +17385,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);
@@ -15563,30 +17400,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. */
@@ -15604,7 +17430,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;
@@ -15639,7 +17465,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
@@ -15652,7 +17478,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;
@@ -15664,9 +17490,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;
}
@@ -15696,35 +17523,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
@@ -15748,9 +17585,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
@@ -15765,55 +17601,47 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
&& !HAVE_GNAT_AUX_INFO (type))
INIT_GNAT_SPECIFIC (type);
- if (cu->per_cu->debug_type_section)
- type_hash_ptr = &dwarf2_per_objfile->debug_types_type_hash;
- else
- type_hash_ptr = &dwarf2_per_objfile->debug_info_type_hash;
-
- if (*type_hash_ptr == NULL)
+ if (dwarf2_per_objfile->die_type_hash == NULL)
{
- *type_hash_ptr
- = htab_create_alloc_ex (127,
- offset_and_type_hash,
- offset_and_type_eq,
- NULL,
- &objfile->objfile_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
+ dwarf2_per_objfile->die_type_hash =
+ htab_create_alloc_ex (127,
+ per_cu_offset_and_type_hash,
+ per_cu_offset_and_type_eq,
+ NULL,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
}
+ ofs.per_cu = cu->per_cu;
ofs.offset = die->offset;
ofs.type = type;
- slot = (struct dwarf2_offset_and_type **)
- htab_find_slot_with_hash (*type_hash_ptr, &ofs, ofs.offset, INSERT);
+ slot = (struct dwarf2_per_cu_offset_and_type **)
+ htab_find_slot (dwarf2_per_objfile->die_type_hash, &ofs, INSERT);
if (*slot)
complaint (&symfile_complaints,
_("A problem internal to GDB: DIE 0x%x has type already set"),
- die->offset);
+ die->offset.sect_off);
*slot = obstack_alloc (&objfile->objfile_obstack, sizeof (**slot));
**slot = ofs;
return type;
}
-/* Look up the type for the die at DIE_OFFSET in the appropriate type_hash
+/* Look up the type for the die at OFFSET in the appropriate type_hash
table, or return NULL if the die does not have a saved type. */
static struct type *
-get_die_type_at_offset (unsigned int offset,
+get_die_type_at_offset (sect_offset offset,
struct dwarf2_per_cu_data *per_cu)
{
- struct dwarf2_offset_and_type *slot, ofs;
- htab_t type_hash;
+ struct dwarf2_per_cu_offset_and_type *slot, ofs;
- if (per_cu->debug_type_section)
- type_hash = dwarf2_per_objfile->debug_types_type_hash;
- else
- type_hash = dwarf2_per_objfile->debug_info_type_hash;
- if (type_hash == NULL)
+ if (dwarf2_per_objfile->die_type_hash == NULL)
return NULL;
+ ofs.per_cu = per_cu;
ofs.offset = offset;
- slot = htab_find_with_hash (type_hash, &ofs, ofs.offset);
+ slot = htab_find (dwarf2_per_objfile->die_type_hash, &ofs);
if (slot)
return slot->type;
else
@@ -15907,7 +17735,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
@@ -15919,7 +17747,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;
@@ -15975,6 +17803,7 @@ dwarf2_per_objfile_free (struct objfile *objfile, void *d)
munmap_section_buffer (&data->macro);
munmap_section_buffer (&data->str);
munmap_section_buffer (&data->ranges);
+ munmap_section_buffer (&data->addr);
munmap_section_buffer (&data->frame);
munmap_section_buffer (&data->eh_frame);
munmap_section_buffer (&data->gdb_index);
@@ -15985,6 +17814,9 @@ dwarf2_per_objfile_free (struct objfile *objfile, void *d)
munmap_section_buffer (section);
VEC_free (dwarf2_section_info_def, data->types);
+
+ if (data->dwo_files)
+ free_dwo_files (data->dwo_files, objfile);
}
@@ -16465,7 +18297,7 @@ write_psymbols (struct mapped_symtab *symtab,
if (!*slot)
{
*slot = lookup;
- add_index_entry (symtab, SYMBOL_NATURAL_NAME (*psymp), cu_index);
+ add_index_entry (symtab, SYMBOL_SEARCH_NAME (*psymp), cu_index);
}
}
}
@@ -16527,9 +18359,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);
@@ -16539,14 +18373,6 @@ write_one_signatured_type (void **slot, void *d)
return 1;
}
-/* A cleanup function for an htab_t. */
-
-static void
-cleanup_htab (void *arg)
-{
- htab_delete (arg);
-}
-
/* Create an index file for OBJFILE in the directory DIR. */
static void
@@ -16603,7 +18429,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
psyms_seen = htab_create_alloc (100, htab_hash_pointer, htab_eq_pointer,
NULL, xcalloc, xfree);
- make_cleanup (cleanup_htab, psyms_seen);
+ make_cleanup_htab_delete (psyms_seen);
/* While we're scanning CU's create a table that maps a psymtab pointer
(which is what addrmap records) to its index (which is what is recorded
@@ -16613,7 +18439,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
hash_psymtab_cu_index,
eq_psymtab_cu_index,
NULL, xcalloc, xfree);
- make_cleanup (cleanup_htab, cu_index_htab);
+ make_cleanup_htab_delete (cu_index_htab);
psymtab_cu_index_map = (struct psymtab_cu_index_map *)
xmalloc (sizeof (struct psymtab_cu_index_map)
* dwarf2_per_objfile->n_comp_units);
@@ -16650,7 +18476,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);
@@ -16685,7 +18512,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
total_len = size_of_contents;
/* The version number. */
- val = MAYBE_SWAP (5);
+ val = MAYBE_SWAP (6);
obstack_grow (&contents, &val, sizeof (val));
/* The offset of the CU list from the start of the file. */