Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1062)

Unified Diff: gdb/dwarf2read.c

Issue 124383005: GDB 7.6.50 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@upstream
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gdb/dwarf2loc.c ('k') | gdb/elfread.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gdb/dwarf2read.c
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 48b8c08ae63204384fbe563ec2b5626a715945c2..1c7dfc54fbcf122d7bc584ebc68e6d442d3962e1 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -1,6 +1,6 @@
/* DWARF 2 debugging format support for GDB.
- Copyright (C) 1994-2012 Free Software Foundation, Inc.
+ Copyright (C) 1994-2013 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
@@ -30,6 +30,7 @@
#include "defs.h"
#include "bfd.h"
+#include "elf-bfd.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "objfiles.h"
@@ -55,7 +56,7 @@
#include "jv-lang.h"
#include "psympriv.h"
#include "exceptions.h"
-#include "gdb_stat.h"
+#include <sys/stat.h>
#include "completer.h"
#include "vec.h"
#include "c-lang.h"
@@ -64,30 +65,27 @@
#include "gdbcore.h" /* for gnutarget */
#include "gdb/gdb-index.h"
#include <ctype.h>
+#include "gdb_bfd.h"
+#include "f-lang.h"
+#include "source.h"
+#include "filestuff.h"
+#include "build-id.h"
#include <fcntl.h>
-#include "gdb_string.h"
+#include <string.h>
#include "gdb_assert.h"
#include <sys/types.h>
-#ifdef HAVE_ZLIB_H
-#include <zlib.h>
-#endif
-#ifdef HAVE_MMAP
-#include <sys/mman.h>
-#ifndef MAP_FAILED
-#define MAP_FAILED ((void *) -1)
-#endif
-#endif
typedef struct symbol *symbolp;
DEF_VEC_P (symbolp);
-/* When non-zero, print basic high level tracing messages.
+/* When == 1, print basic high level tracing messages.
+ When > 1, be more verbose.
This is in contrast to the low level DIE reading of dwarf2_die_debug. */
-static int dwarf2_read_debug = 0;
+static unsigned int dwarf2_read_debug = 0;
/* When non-zero, dump DIEs after they are read in. */
-static int dwarf2_die_debug = 0;
+static unsigned int dwarf2_die_debug = 0;
/* When non-zero, cross-check physname against demangler. */
static int check_physname = 0;
@@ -95,27 +93,53 @@ static int check_physname = 0;
/* When non-zero, do not reject deprecated .gdb_index sections. */
static int use_deprecated_index_sections = 0;
-static int pagesize;
+static const struct objfile_data *dwarf2_objfile_data_key;
+
+/* The "aclass" indices for various kinds of computed DWARF symbols. */
-/* When set, the file that we're processing is known to have debugging
- info for C++ namespaces. GCC 3.3.x did not produce this information,
- but later versions do. */
+static int dwarf2_locexpr_index;
+static int dwarf2_loclist_index;
+static int dwarf2_locexpr_block_index;
+static int dwarf2_loclist_block_index;
-static int processing_has_namespace_info;
+/* A descriptor for dwarf sections.
-static const struct objfile_data *dwarf2_objfile_data_key;
+ S.ASECTION, SIZE are typically initialized when the objfile is first
+ scanned. BUFFER, READIN are filled in later when the section is read.
+ If the section contained compressed data then SIZE is updated to record
+ the uncompressed size of the section.
+
+ DWP file format V2 introduces a wrinkle that is easiest to handle by
+ creating the concept of virtual sections contained within a real section.
+ In DWP V2 the sections of the input DWO files are concatenated together
+ into one section, but section offsets are kept relative to the original
+ input section.
+ If this is a virtual dwp-v2 section, S.CONTAINING_SECTION is a backlink to
+ the real section this "virtual" section is contained in, and BUFFER,SIZE
+ describe the virtual section. */
struct dwarf2_section_info
{
- asection *asection;
- gdb_byte *buffer;
+ union
+ {
+ /* If this is a real section, the bfd section. */
+ asection *asection;
+ /* If this is a virtual section, pointer to the containing ("real")
+ section. */
+ struct dwarf2_section_info *containing_section;
+ } s;
+ /* Pointer to section data, only valid if readin. */
+ const gdb_byte *buffer;
+ /* The size of the section, real or virtual. */
bfd_size_type size;
- /* Not NULL if the section was actually mmapped. */
- void *map_addr;
- /* Page aligned size of mmapped area. */
- bfd_size_type map_len;
+ /* If this is a virtual section, the offset in the real section.
+ Only valid if is_virtual. */
+ bfd_size_type virtual_offset;
/* True if we have tried to read this section. */
- int readin;
+ char readin;
+ /* True if this is a virtual section, False otherwise.
+ This specifies which of s.asection and s.containing_section to use. */
+ char is_virtual;
};
typedef struct dwarf2_section_info dwarf2_section_info_def;
@@ -211,7 +235,8 @@ struct dwarf2_per_objfile
/* The number of .debug_types-related CUs. */
int n_type_units;
- /* The .debug_types-related CUs (TUs). */
+ /* The .debug_types-related CUs (TUs).
+ This is stored in malloc space because we may realloc it. */
struct signatured_type **all_type_units;
/* The number of entries in all_type_unit_groups. */
@@ -247,6 +272,16 @@ struct dwarf2_per_objfile
This is NULL if the table hasn't been allocated yet. */
htab_t dwo_files;
+ /* Non-zero if we've check for whether there is a DWP file. */
+ int dwp_checked;
+
+ /* The DWP file if there is one, or NULL. */
+ struct dwp_file *dwp_file;
+
+ /* The shared '.dwz' file, if one exists. This is used when the
+ original data was compressed using 'dwz -m'. */
+ struct dwz_file *dwz_file;
+
/* A flag indicating wether this objfile has a section loaded at a
VMA of 0. */
int has_section_at_zero;
@@ -259,9 +294,12 @@ struct dwarf2_per_objfile
struct mapped_index *index_table;
/* When using index_table, this keeps track of all quick_file_names entries.
- TUs can share line table entries with CUs or other TUs, and there can be
- a lot more TUs than unique line tables, so we maintain a separate table
- of all line table entries to support the sharing. */
+ TUs typically share line table entries with a CU, so we maintain a
+ separate table of all line table entries to support the sharing.
+ Note that while there can be way more TUs than CUs, we've already
+ sorted all the TUs into "type unit groups", grouped by their
+ DW_AT_stmt_list value. Therefore the only sharing done here is with a
+ CU and its associated TU group if there is one. */
htab_t quick_file_names_table;
/* Set during partial symbol reading, to prevent queueing of full
@@ -270,7 +308,7 @@ struct dwarf2_per_objfile
/* Table mapping type DIEs to their struct type *.
This is NULL if not allocated yet.
- The mapping is done via (CU/TU signature + DIE offset) -> type. */
+ The mapping is done via (CU/TU + DIE offset) -> type. */
htab_t die_type_hash;
/* The CUs we recently read. */
@@ -302,9 +340,9 @@ static const struct dwarf2_debug_sections dwarf2_elf_names =
23
};
-/* List of DWO sections. */
+/* List of DWO/DWP sections. */
-static const struct dwo_section_names
+static const struct dwop_section_names
{
struct dwarf2_section_names abbrev_dwo;
struct dwarf2_section_names info_dwo;
@@ -315,8 +353,10 @@ static const struct dwo_section_names
struct dwarf2_section_names str_dwo;
struct dwarf2_section_names str_offsets_dwo;
struct dwarf2_section_names types_dwo;
+ struct dwarf2_section_names cu_index;
+ struct dwarf2_section_names tu_index;
}
-dwo_section_names =
+dwop_section_names =
{
{ ".debug_abbrev.dwo", ".zdebug_abbrev.dwo" },
{ ".debug_info.dwo", ".zdebug_info.dwo" },
@@ -327,6 +367,8 @@ dwo_section_names =
{ ".debug_str.dwo", ".zdebug_str.dwo" },
{ ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo" },
{ ".debug_types.dwo", ".zdebug_types.dwo" },
+ { ".debug_cu_index", ".zdebug_cu_index" },
+ { ".debug_tu_index", ".zdebug_tu_index" },
};
/* local data types */
@@ -430,7 +472,7 @@ struct dwarf2_cu
compilation units are cached... */
struct dwarf2_per_cu_data *read_in_chain;
- /* Backchain to our per_cu entry if the tree has been built. */
+ /* Backlink to our per_cu entry. */
struct dwarf2_per_cu_data *per_cu;
/* How many compilation units ago was this CU last referenced? */
@@ -478,7 +520,12 @@ struct dwarf2_cu
(zero is a valid value though).
Note this value comes from the stub CU/TU's DIE.
Also note that the value is zero in the non-DWO case so this value can
- be used without needing to know whether DWO files are in use or not. */
+ be used without needing to know whether DWO files are in use or not.
+ N.B. This does not apply to DW_AT_ranges appearing in
+ DW_TAG_compile_unit dies. This is a bit of a wart, consider if ever
+ DW_AT_ranges appeared in the DW_TAG_compile_unit of DWO DIEs: then
+ DW_AT_ranges_base *would* have to be applied, and we'd have to care
+ whether the DW_AT_ranges attribute came from the skeleton or DWO. */
ULONGEST ranges_base;
/* Mark used when releasing cached dies. */
@@ -490,13 +537,20 @@ struct dwarf2_cu
unoptimized code. For a future better test see GCC PR other/32998. */
unsigned int has_loclist : 1;
- /* These cache the results for producer_is_gxx_lt_4_6 and producer_is_icc.
- CHECKED_PRODUCER is set if both PRODUCER_IS_GXX_LT_4_6 and PRODUCER_IS_ICC
- are valid. This information is cached because profiling CU expansion
- showed excessive time spent in producer_is_gxx_lt_4_6. */
+ /* These cache the results for producer_is_* fields. CHECKED_PRODUCER is set
+ if all the producer_is_* fields are valid. This information is cached
+ because profiling CU expansion showed excessive time spent in
+ producer_is_gxx_lt_4_6. */
unsigned int checked_producer : 1;
unsigned int producer_is_gxx_lt_4_6 : 1;
+ unsigned int producer_is_gcc_lt_4_3 : 1;
unsigned int producer_is_icc : 1;
+
+ /* When set, the file that we're processing is known to have
+ debugging info for C++ namespaces. GCC 3.3.x did not produce
+ this information, but later versions do. */
+
+ unsigned int processing_has_namespace_info : 1;
};
/* Persistent data held for a compilation unit, even when not
@@ -505,15 +559,13 @@ struct dwarf2_cu
struct dwarf2_per_cu_data
{
- /* The start offset and length of this compilation unit. 2**29-1
- bytes should suffice to store the length of any compilation unit
- - if it doesn't, GDB will fall over anyway.
+ /* The start offset and length of this compilation unit.
NOTE: Unlike comp_unit_head.length, this length includes
initial_length_size.
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;
+ unsigned int length;
/* Flag indicating this compilation unit will be read in before
any of the current compilation units are processed. */
@@ -525,13 +577,34 @@ struct dwarf2_per_cu_data
hash table and don't find it. */
unsigned int load_all_dies : 1;
- /* Non-zero if this CU is from .debug_types. */
+ /* Non-zero if this CU is from .debug_types.
+ Struct dwarf2_per_cu_data is contained in struct signatured_type iff
+ this is non-zero. */
unsigned int is_debug_types : 1;
+ /* Non-zero if this CU is from the .dwz file. */
+ unsigned int is_dwz : 1;
+
+ /* Non-zero if reading a TU directly from a DWO file, bypassing the stub.
+ This flag is only valid if is_debug_types is true.
+ We can't read a CU directly from a DWO file: There are required
+ attributes in the stub. */
+ unsigned int reading_dwo_directly : 1;
+
+ /* Non-zero if the TU has been read.
+ This is used to assist the "Stay in DWO Optimization" for Fission:
+ When reading a DWO, it's faster to read TUs from the DWO instead of
+ fetching them from random other DWOs (due to comdat folding).
+ If the TU has already been read, the optimization is unnecessary
+ (and unwise - we don't want to change where gdb thinks the TU lives
+ "midflight").
+ This flag is only valid if is_debug_types is true. */
+ unsigned int tu_read : 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;
+ struct dwarf2_section_info *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. */
@@ -554,19 +627,25 @@ struct dwarf2_per_cu_data
struct dwarf2_per_cu_quick_data *quick;
} v;
- union
- {
- /* The CUs we import using DW_TAG_imported_unit. This is filled in
- while reading psymtabs, used to compute the psymtab dependencies,
- and then cleared. Then it is filled in again while reading full
- symbols, and only deleted when the objfile is destroyed. */
- VEC (dwarf2_per_cu_ptr) *imported_symtabs;
-
- /* Type units are grouped by their DW_AT_stmt_list entry so that they
- can share them. If this is a TU, this points to the containing
- symtab. */
- struct type_unit_group *type_unit_group;
- } s;
+ /* The CUs we import using DW_TAG_imported_unit. This is filled in
+ while reading psymtabs, used to compute the psymtab dependencies,
+ and then cleared. Then it is filled in again while reading full
+ symbols, and only deleted when the objfile is destroyed.
+
+ This is also used to work around a difference between the way gold
+ generates .gdb_index version <=7 and the way gdb does. Arguably this
+ is a gold bug. For symbols coming from TUs, gold records in the index
+ the CU that includes the TU instead of the TU itself. This breaks
+ dw2_lookup_symbol: It assumes that if the index says symbol X lives
+ in CU/TU Y, then one need only expand Y and a subsequent lookup in Y
+ will find X. Alas TUs live in their own symtab, so after expanding CU Y
+ we need to look in TU Z to find X. Fortunately, this is akin to
+ DW_TAG_imported_unit, so we just use the same mechanism: For
+ .gdb_index version <=7 this also records the TUs that the CU referred
+ to. Concurrently with this change gdb was modified to emit version 8
+ indices so we only pay a price for gold generated indices.
+ http://sourceware.org/bugzilla/show_bug.cgi?id=15021. */
+ VEC (dwarf2_per_cu_ptr) *imported_symtabs;
};
/* Entry in the signatured_types hash table. */
@@ -574,6 +653,7 @@ struct dwarf2_per_cu_data
struct signatured_type
{
/* The "per_cu" object of this type.
+ This struct is used iff per_cu.is_debug_types.
N.B.: This is the first member so that it's easy to convert pointers
between them. */
struct dwarf2_per_cu_data per_cu;
@@ -582,7 +662,8 @@ struct signatured_type
ULONGEST signature;
/* Offset in the TU of the type's DIE, as read from the TU header.
- If the definition lives in a DWO file, this value is unusable. */
+ If this TU is a DWO stub and the definition lives in a DWO file
+ (specified by DW_AT_GNU_dwo_name), this value is unusable. */
cu_offset type_offset_in_tu;
/* Offset in the section of the type's DIE.
@@ -591,8 +672,24 @@ struct signatured_type
The value is zero until the actual value is known.
Zero is otherwise not a valid section offset. */
sect_offset type_offset_in_section;
+
+ /* Type units are grouped by their DW_AT_stmt_list entry so that they
+ can share them. This points to the containing symtab. */
+ struct type_unit_group *type_unit_group;
+
+ /* The type.
+ The first time we encounter this type we fully read it in and install it
+ in the symbol tables. Subsequent times we only need the type. */
+ struct type *type;
+
+ /* Containing DWO unit.
+ This field is valid iff per_cu.reading_dwo_directly. */
+ struct dwo_unit *dwo_unit;
};
+typedef struct signatured_type *sig_type_ptr;
+DEF_VEC_P (sig_type_ptr);
+
/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list.
This includes type_unit_group and quick_file_names. */
@@ -610,26 +707,18 @@ struct stmt_list_hash
struct type_unit_group
{
- /* dwarf2read.c's main "handle" on the symtab.
+ /* dwarf2read.c's main "handle" on a TU symtab.
To simplify things we create an artificial CU that "includes" all the
type units using this stmt_list so that the rest of the code still has
a "per_cu" handle on the symtab.
This PER_CU is recognized by having no section. */
-#define IS_TYPE_UNIT_GROUP(per_cu) ((per_cu)->info_or_types_section == NULL)
+#define IS_TYPE_UNIT_GROUP(per_cu) ((per_cu)->section == NULL)
struct dwarf2_per_cu_data per_cu;
- union
- {
- /* The TUs that share this DW_AT_stmt_list entry.
- This is added to while parsing type units to build partial symtabs,
- and is deleted afterwards and not used again. */
- VEC (dwarf2_per_cu_ptr) *tus;
-
- /* When reading the line table in "quick" functions, we need a real TU.
- Any will do, we know they all share the same DW_AT_stmt_list entry.
- For simplicity's sake, we pick the first one. */
- struct dwarf2_per_cu_data *first_tu;
- } t;
+ /* The TUs that share this DW_AT_stmt_list entry.
+ This is added to while parsing type units to build partial symtabs,
+ and is deleted afterwards and not used again. */
+ VEC (sig_type_ptr) *tus;
/* The primary symtab.
Type units in a group needn't all be defined in the same source file,
@@ -654,22 +743,23 @@ struct type_unit_group
struct symtab **symtabs;
};
-/* These sections are what may appear in a "dwo" file. */
+/* These sections are what may appear in a (real or virtual) DWO file. */
struct dwo_sections
{
struct dwarf2_section_info abbrev;
- struct dwarf2_section_info info;
struct dwarf2_section_info line;
struct dwarf2_section_info loc;
struct dwarf2_section_info macinfo;
struct dwarf2_section_info macro;
struct dwarf2_section_info str;
struct dwarf2_section_info str_offsets;
+ /* In the case of a virtual DWO file, these two are unused. */
+ struct dwarf2_section_info info;
VEC (dwarf2_section_info_def) *types;
};
-/* Common bits of DWO CUs/TUs. */
+/* CUs/TUs in DWP/DWO files. */
struct dwo_unit
{
@@ -682,9 +772,9 @@ struct dwo_unit
ULONGEST signature;
/* The section this CU/TU lives in, in the DWO file. */
- struct dwarf2_section_info *info_or_types_section;
+ struct dwarf2_section_info *section;
- /* Same as dwarf2_per_cu_data:{offset,length} but for the DWO section. */
+ /* Same as dwarf2_per_cu_data:{offset,length} but in the DWO section. */
sect_offset offset;
unsigned int length;
@@ -692,29 +782,211 @@ struct dwo_unit
cu_offset type_offset_in_tu;
};
-/* Data for one DWO file. */
+/* include/dwarf2.h defines the DWP section codes.
+ It defines a max value but it doesn't define a min value, which we
+ use for error checking, so provide one. */
+
+enum dwp_v2_section_ids
+{
+ DW_SECT_MIN = 1
+};
+
+/* Data for one DWO file.
+
+ This includes virtual DWO files (a virtual DWO file is a DWO file as it
+ appears in a DWP file). DWP files don't really have DWO files per se -
+ comdat folding of types "loses" the DWO file they came from, and from
+ a high level view DWP files appear to contain a mass of random types.
+ However, to maintain consistency with the non-DWP case we pretend DWP
+ files contain virtual DWO files, and we assign each TU with one virtual
+ DWO file (generally based on the line and abbrev section offsets -
+ a heuristic that seems to work in practice). */
struct dwo_file
{
/* The DW_AT_GNU_dwo_name attribute.
- We don't manage space for this, it's an attribute. */
+ For virtual DWO files the name is constructed from the section offsets
+ of abbrev,line,loc,str_offsets so that we combine virtual DWO files
+ from related CU+TUs. */
const char *dwo_name;
- /* The bfd, when the file is open. Otherwise this is NULL. */
- bfd *dwo_bfd;
+ /* The DW_AT_comp_dir attribute. */
+ const char *comp_dir;
- /* Section info for this file. */
+ /* The bfd, when the file is open. Otherwise this is NULL.
+ This is unused(NULL) for virtual DWO files where we use dwp_file.dbfd. */
+ bfd *dbfd;
+
+ /* The sections that make up this DWO file.
+ Remember that for virtual DWO files in DWP V2, these are virtual
+ sections (for lack of a better name). */
struct dwo_sections sections;
- /* Table of CUs in the file.
- Each element is a struct dwo_unit. */
- htab_t cus;
+ /* The CU in the file.
+ We only support one because having more than one requires hacking the
+ dwo_name of each to match, which is highly unlikely to happen.
+ Doing this means all TUs can share comp_dir: We also assume that
+ DW_AT_comp_dir across all TUs in a DWO file will be identical. */
+ struct dwo_unit *cu;
/* Table of TUs in the file.
Each element is a struct dwo_unit. */
htab_t tus;
};
+/* These sections are what may appear in a DWP file. */
+
+struct dwp_sections
+{
+ /* These are used by both DWP version 1 and 2. */
+ struct dwarf2_section_info str;
+ struct dwarf2_section_info cu_index;
+ struct dwarf2_section_info tu_index;
+
+ /* These are only used by DWP version 2 files.
+ In DWP version 1 the .debug_info.dwo, .debug_types.dwo, and other
+ sections are referenced by section number, and are not recorded here.
+ In DWP version 2 there is at most one copy of all these sections, each
+ section being (effectively) comprised of the concatenation of all of the
+ individual sections that exist in the version 1 format.
+ To keep the code simple we treat each of these concatenated pieces as a
+ section itself (a virtual section?). */
+ struct dwarf2_section_info abbrev;
+ struct dwarf2_section_info info;
+ struct dwarf2_section_info line;
+ struct dwarf2_section_info loc;
+ struct dwarf2_section_info macinfo;
+ struct dwarf2_section_info macro;
+ struct dwarf2_section_info str_offsets;
+ struct dwarf2_section_info types;
+};
+
+/* These sections are what may appear in a virtual DWO file in DWP version 1.
+ A virtual DWO file is a DWO file as it appears in a DWP file. */
+
+struct virtual_v1_dwo_sections
+{
+ struct dwarf2_section_info abbrev;
+ struct dwarf2_section_info line;
+ struct dwarf2_section_info loc;
+ struct dwarf2_section_info macinfo;
+ struct dwarf2_section_info macro;
+ struct dwarf2_section_info str_offsets;
+ /* Each DWP hash table entry records one CU or one TU.
+ That is recorded here, and copied to dwo_unit.section. */
+ struct dwarf2_section_info info_or_types;
+};
+
+/* Similar to virtual_v1_dwo_sections, but for DWP version 2.
+ In version 2, the sections of the DWO files are concatenated together
+ and stored in one section of that name. Thus each ELF section contains
+ several "virtual" sections. */
+
+struct virtual_v2_dwo_sections
+{
+ bfd_size_type abbrev_offset;
+ bfd_size_type abbrev_size;
+
+ bfd_size_type line_offset;
+ bfd_size_type line_size;
+
+ bfd_size_type loc_offset;
+ bfd_size_type loc_size;
+
+ bfd_size_type macinfo_offset;
+ bfd_size_type macinfo_size;
+
+ bfd_size_type macro_offset;
+ bfd_size_type macro_size;
+
+ bfd_size_type str_offsets_offset;
+ bfd_size_type str_offsets_size;
+
+ /* Each DWP hash table entry records one CU or one TU.
+ That is recorded here, and copied to dwo_unit.section. */
+ bfd_size_type info_or_types_offset;
+ bfd_size_type info_or_types_size;
+};
+
+/* Contents of DWP hash tables. */
+
+struct dwp_hash_table
+{
+ uint32_t version, nr_columns;
+ uint32_t nr_units, nr_slots;
+ const gdb_byte *hash_table, *unit_table;
+ union
+ {
+ struct
+ {
+ const gdb_byte *indices;
+ } v1;
+ struct
+ {
+ /* This is indexed by column number and gives the id of the section
+ in that column. */
+#define MAX_NR_V2_DWO_SECTIONS \
+ (1 /* .debug_info or .debug_types */ \
+ + 1 /* .debug_abbrev */ \
+ + 1 /* .debug_line */ \
+ + 1 /* .debug_loc */ \
+ + 1 /* .debug_str_offsets */ \
+ + 1 /* .debug_macro or .debug_macinfo */)
+ int section_ids[MAX_NR_V2_DWO_SECTIONS];
+ const gdb_byte *offsets;
+ const gdb_byte *sizes;
+ } v2;
+ } section_pool;
+};
+
+/* Data for one DWP file. */
+
+struct dwp_file
+{
+ /* Name of the file. */
+ const char *name;
+
+ /* File format version. */
+ int version;
+
+ /* The bfd. */
+ bfd *dbfd;
+
+ /* Section info for this file. */
+ struct dwp_sections sections;
+
+ /* Table of CUs in the file. */
+ const struct dwp_hash_table *cus;
+
+ /* Table of TUs in the file. */
+ const struct dwp_hash_table *tus;
+
+ /* Tables of loaded CUs/TUs. Each entry is a struct dwo_unit *. */
+ htab_t loaded_cus;
+ htab_t loaded_tus;
+
+ /* Table to map ELF section numbers to their sections.
+ This is only needed for the DWP V1 file format. */
+ unsigned int num_sections;
+ asection **elf_sections;
+};
+
+/* This represents a '.dwz' file. */
+
+struct dwz_file
+{
+ /* A dwz file can only contain a few sections. */
+ struct dwarf2_section_info abbrev;
+ struct dwarf2_section_info info;
+ struct dwarf2_section_info str;
+ struct dwarf2_section_info line;
+ struct dwarf2_section_info macro;
+ struct dwarf2_section_info gdb_index;
+
+ /* The dwz's BFD. */
+ bfd *dwz_bfd;
+};
+
/* Struct used to pass misc. parameters to read_die_and_children, et
al. which are used for both .debug_info and .debug_types dies.
All parameters here are unchanging for the life of the call. This
@@ -722,13 +994,13 @@ struct dwo_file
struct die_reader_specs
{
- /* die_section->asection->owner. */
+ /* The bfd of die_section. */
bfd* abfd;
/* The CU of the DIE we are parsing. */
struct dwarf2_cu *cu;
- /* Non-NULL if reading a DWO file. */
+ /* Non-NULL if reading a DWO file (including one packaged into a DWP). */
struct dwo_file *dwo_file;
/* The section the die comes from.
@@ -736,15 +1008,18 @@ struct die_reader_specs
struct dwarf2_section_info *die_section;
/* die_section->buffer. */
- gdb_byte *buffer;
+ const gdb_byte *buffer;
/* The end of the buffer. */
const gdb_byte *buffer_end;
+
+ /* The value of the DW_AT_comp_dir attribute. */
+ const char *comp_dir;
};
/* Type of function passed to init_cutu_and_read_dies, et.al. */
typedef void (die_reader_func_ftype) (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
+ const gdb_byte *info_ptr,
struct die_info *comp_unit_die,
int has_children,
void *data);
@@ -775,7 +1050,7 @@ struct line_header
debug_line_buffer. If you try to free them, `free' will get
indigestion. */
unsigned int num_include_dirs, include_dirs_size;
- char **include_dirs;
+ const char **include_dirs;
/* The file_names table. NOTE! These strings are not allocated
with xmalloc; instead, they are pointers into debug_line_buffer.
@@ -783,7 +1058,7 @@ struct line_header
unsigned int num_file_names, file_names_size;
struct file_entry
{
- char *name;
+ const char *name;
unsigned int dir_index;
unsigned int mod_time;
unsigned int length;
@@ -793,7 +1068,7 @@ struct line_header
/* The start and end of the statement program following this
header. These point into dwarf2_per_objfile->line_buffer. */
- gdb_byte *statement_program_start, *statement_program_end;
+ const gdb_byte *statement_program_start, *statement_program_end;
};
/* When we construct a partial symbol table entry we only
@@ -828,9 +1103,15 @@ struct partial_die_info
/* Flag set if fixup_partial_die has been called on this die. */
unsigned int fixup_called : 1;
+ /* Flag set if DW_TAG_imported_unit uses DW_FORM_GNU_ref_alt. */
+ unsigned int is_dwz : 1;
+
+ /* Flag set if spec_offset uses DW_FORM_GNU_ref_alt. */
+ unsigned int spec_is_dwz : 1;
+
/* The name of this DIE. Normally the value of DW_AT_name, but
sometimes a default name for unnamed DIEs. */
- char *name;
+ const char *name;
/* The linkage name, if present. */
const char *linkage_name;
@@ -838,7 +1119,7 @@ struct partial_die_info
/* The scope to prepend to our children. This is generally
allocated on the comp_unit_obstack, so will disappear
when this compilation unit leaves the cache. */
- char *scope;
+ const char *scope;
/* Some data associated with the partial DIE. The tag determines
which field is live. */
@@ -858,7 +1139,7 @@ struct partial_die_info
DW_AT_sibling, if any. */
/* NOTE: This member isn't strictly necessary, read_partial_die could
return DW_AT_sibling values to its caller load_partial_dies. */
- gdb_byte *sibling;
+ const gdb_byte *sibling;
/* If HAS_SPECIFICATION, the offset of the DIE referred to by
DW_AT_specification (or DW_AT_abstract_origin or
@@ -921,12 +1202,12 @@ struct attribute
union
{
- char *str;
+ const char *str;
struct dwarf_block *blk;
ULONGEST unsnd;
LONGEST snd;
CORE_ADDR addr;
- struct signatured_type *signatured_type;
+ ULONGEST signature;
}
u;
};
@@ -972,15 +1253,15 @@ struct die_info
#define DW_BLOCK(attr) ((attr)->u.blk)
#define DW_SND(attr) ((attr)->u.snd)
#define DW_ADDR(attr) ((attr)->u.addr)
-#define DW_SIGNATURED_TYPE(attr) ((attr)->u.signatured_type)
+#define DW_SIGNATURE(attr) ((attr)->u.signature)
/* Blocks are a bunch of untyped bytes. */
struct dwarf_block
{
- unsigned int size;
+ size_t size;
/* Valid only if SIZE is not zero. */
- gdb_byte *data;
+ const gdb_byte *data;
};
#ifndef ATTR_ALLOC_CHUNK
@@ -1035,7 +1316,7 @@ struct field_info
to the head of the member function field chain. */
struct fnfieldlist
{
- char *name;
+ const char *name;
int length;
struct nextfnfield *head;
}
@@ -1081,84 +1362,21 @@ show_dwarf2_max_cache_age (struct ui_file *file, int from_tty,
"dwarf2 compilation units is %s.\n"),
value);
}
+
+/* local function prototypes */
+static const char *get_section_name (const struct dwarf2_section_info *);
-/* Various complaints about symbol reading that don't abort the process. */
-
-static void
-dwarf2_statement_list_fits_in_line_number_section_complaint (void)
-{
- complaint (&symfile_complaints,
- _("statement list doesn't fit in .debug_line section"));
-}
-
-static void
-dwarf2_debug_line_missing_file_complaint (void)
-{
- complaint (&symfile_complaints,
- _(".debug_line section has line data without a file"));
-}
-
-static void
-dwarf2_debug_line_missing_end_sequence_complaint (void)
-{
- complaint (&symfile_complaints,
- _(".debug_line section has line "
- "program sequence without an end"));
-}
-
-static void
-dwarf2_complex_location_expr_complaint (void)
-{
- complaint (&symfile_complaints, _("location expression too complex"));
-}
-
-static void
-dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
- int arg3)
-{
- complaint (&symfile_complaints,
- _("const value length mismatch for '%s', got %d, expected %d"),
- arg1, arg2, arg3);
-}
-
-static void
-dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section)
-{
- complaint (&symfile_complaints,
- _("debug info runs off end of %s section"
- " [in module %s]"),
- section->asection->name,
- bfd_get_filename (section->asection->owner));
-}
-
-static void
-dwarf2_macro_malformed_definition_complaint (const char *arg1)
-{
- complaint (&symfile_complaints,
- _("macro debug info contains a "
- "malformed macro definition:\n`%s'"),
- arg1);
-}
-
-static void
-dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
-{
- complaint (&symfile_complaints,
- _("invalid attribute class or form for '%s' in '%s'"),
- arg1, arg2);
-}
-
-/* local function prototypes */
+static const char *get_section_file_name (const struct dwarf2_section_info *);
static void dwarf2_locate_sections (bfd *, asection *, void *);
-static void dwarf2_create_include_psymtab (char *, struct partial_symtab *,
- struct objfile *);
-
static void dwarf2_find_base_address (struct die_info *die,
struct dwarf2_cu *cu);
+static struct partial_symtab *create_partial_symtab
+ (struct dwarf2_per_cu_data *per_cu, const char *name);
+
static void dwarf2_build_psymtabs_hard (struct objfile *);
static void scan_partial_symbols (struct partial_die_info *,
@@ -1183,7 +1401,8 @@ static void add_partial_subprogram (struct partial_die_info *pdi,
CORE_ADDR *lowpc, CORE_ADDR *highpc,
int need_pc, struct dwarf2_cu *cu);
-static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
+static void dwarf2_read_symtab (struct partial_symtab *,
+ struct objfile *);
static void psymtab_to_symtab_1 (struct partial_symtab *);
@@ -1202,71 +1421,75 @@ static void dwarf2_read_abbrevs (struct dwarf2_cu *,
static void dwarf2_free_abbrev_table (void *);
-static unsigned int peek_abbrev_code (bfd *, gdb_byte *);
+static unsigned int peek_abbrev_code (bfd *, const gdb_byte *);
static struct partial_die_info *load_partial_dies
- (const struct die_reader_specs *, gdb_byte *, int);
+ (const struct die_reader_specs *, const gdb_byte *, int);
-static gdb_byte *read_partial_die (const struct die_reader_specs *,
- struct partial_die_info *,
- struct abbrev_info *,
- unsigned int,
- gdb_byte *);
+static const gdb_byte *read_partial_die (const struct die_reader_specs *,
+ struct partial_die_info *,
+ struct abbrev_info *,
+ unsigned int,
+ const gdb_byte *);
-static struct partial_die_info *find_partial_die (sect_offset,
+static struct partial_die_info *find_partial_die (sect_offset, int,
struct dwarf2_cu *);
static void fixup_partial_die (struct partial_die_info *,
struct dwarf2_cu *);
-static gdb_byte *read_attribute (const struct die_reader_specs *,
- struct attribute *, struct attr_abbrev *,
- gdb_byte *);
+static const gdb_byte *read_attribute (const struct die_reader_specs *,
+ struct attribute *, struct attr_abbrev *,
+ const gdb_byte *);
-static unsigned int read_1_byte (bfd *, gdb_byte *);
+static unsigned int read_1_byte (bfd *, const gdb_byte *);
-static int read_1_signed_byte (bfd *, gdb_byte *);
+static int read_1_signed_byte (bfd *, const gdb_byte *);
-static unsigned int read_2_bytes (bfd *, gdb_byte *);
+static unsigned int read_2_bytes (bfd *, const gdb_byte *);
-static unsigned int read_4_bytes (bfd *, gdb_byte *);
+static unsigned int read_4_bytes (bfd *, const gdb_byte *);
-static ULONGEST read_8_bytes (bfd *, gdb_byte *);
+static ULONGEST read_8_bytes (bfd *, const gdb_byte *);
-static CORE_ADDR read_address (bfd *, gdb_byte *ptr, struct dwarf2_cu *,
+static CORE_ADDR read_address (bfd *, const gdb_byte *ptr, struct dwarf2_cu *,
unsigned int *);
-static LONGEST read_initial_length (bfd *, gdb_byte *, unsigned int *);
+static LONGEST read_initial_length (bfd *, const gdb_byte *, unsigned int *);
static LONGEST read_checked_initial_length_and_offset
- (bfd *, gdb_byte *, const struct comp_unit_head *,
+ (bfd *, const gdb_byte *, const struct comp_unit_head *,
unsigned int *, unsigned int *);
-static LONGEST read_offset (bfd *, gdb_byte *, const struct comp_unit_head *,
+static LONGEST read_offset (bfd *, const gdb_byte *,
+ const struct comp_unit_head *,
unsigned int *);
-static LONGEST read_offset_1 (bfd *, gdb_byte *, unsigned int);
+static LONGEST read_offset_1 (bfd *, const gdb_byte *, unsigned int);
static sect_offset read_abbrev_offset (struct dwarf2_section_info *,
sect_offset);
-static gdb_byte *read_n_bytes (bfd *, gdb_byte *, unsigned int);
+static const gdb_byte *read_n_bytes (bfd *, const gdb_byte *, unsigned int);
-static char *read_direct_string (bfd *, gdb_byte *, unsigned int *);
+static const char *read_direct_string (bfd *, const gdb_byte *, unsigned int *);
-static char *read_indirect_string (bfd *, gdb_byte *,
- const struct comp_unit_head *,
- unsigned int *);
+static const char *read_indirect_string (bfd *, const gdb_byte *,
+ const struct comp_unit_head *,
+ unsigned int *);
-static ULONGEST read_unsigned_leb128 (bfd *, gdb_byte *, unsigned int *);
+static const char *read_indirect_string_from_dwz (struct dwz_file *, LONGEST);
-static LONGEST read_signed_leb128 (bfd *, gdb_byte *, unsigned int *);
+static ULONGEST read_unsigned_leb128 (bfd *, const gdb_byte *, unsigned int *);
-static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *, gdb_byte *,
+static LONGEST read_signed_leb128 (bfd *, const gdb_byte *, unsigned int *);
+
+static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *,
+ const gdb_byte *,
unsigned int *);
-static char *read_str_index (const struct die_reader_specs *reader,
- struct dwarf2_cu *cu, ULONGEST str_index);
+static const char *read_str_index (const struct die_reader_specs *reader,
+ struct dwarf2_cu *cu, ULONGEST str_index);
static void set_cu_language (unsigned int, struct dwarf2_cu *);
@@ -1286,9 +1509,6 @@ static struct die_info *die_specification (struct die_info *die,
static void free_line_header (struct line_header *lh);
-static void add_file_name (struct line_header *, char *, unsigned int,
- unsigned int, unsigned int);
-
static struct line_header *dwarf_decode_line_header (unsigned int offset,
struct dwarf2_cu *cu);
@@ -1296,10 +1516,10 @@ static void dwarf_decode_lines (struct line_header *, const char *,
struct dwarf2_cu *, struct partial_symtab *,
int);
-static void dwarf2_start_subfile (char *, const char *, const char *);
+static void dwarf2_start_subfile (const char *, const char *, const char *);
static void dwarf2_start_symtab (struct dwarf2_cu *,
- char *, char *, CORE_ADDR);
+ const char *, const char *, CORE_ADDR);
static struct symbol *new_symbol (struct die_info *, struct type *,
struct dwarf2_cu *);
@@ -1307,15 +1527,15 @@ static struct symbol *new_symbol (struct die_info *, struct type *,
static struct symbol *new_symbol_full (struct die_info *, struct type *,
struct dwarf2_cu *, struct symbol *);
-static void dwarf2_const_value (struct attribute *, struct symbol *,
+static void dwarf2_const_value (const struct attribute *, struct symbol *,
struct dwarf2_cu *);
-static void dwarf2_const_value_attr (struct attribute *attr,
+static void dwarf2_const_value_attr (const struct attribute *attr,
struct type *type,
const char *name,
struct obstack *obstack,
struct dwarf2_cu *cu, LONGEST *value,
- gdb_byte **bytes,
+ const gdb_byte **bytes,
struct dwarf2_locexpr_baton **baton);
static struct type *die_type (struct die_info *, struct dwarf2_cu *);
@@ -1331,7 +1551,7 @@ static void set_descriptive_type (struct type *, struct die_info *,
static struct type *die_containing_type (struct die_info *,
struct dwarf2_cu *);
-static struct type *lookup_die_type (struct die_info *, struct attribute *,
+static struct type *lookup_die_type (struct die_info *, const struct attribute *,
struct dwarf2_cu *);
static struct type *read_type_die (struct die_info *, struct dwarf2_cu *);
@@ -1392,6 +1612,8 @@ static void read_module (struct die_info *die, struct dwarf2_cu *cu);
static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
+static int read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu);
+
static struct type *read_module_type (struct die_info *die,
struct dwarf2_cu *cu);
@@ -1405,33 +1627,37 @@ static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
struct dwarf2_cu *);
-static struct die_info *read_die_and_children (const struct die_reader_specs *,
- gdb_byte *info_ptr,
- gdb_byte **new_info_ptr,
- struct die_info *parent);
+static struct die_info *read_die_and_siblings_1
+ (const struct die_reader_specs *, const gdb_byte *, const gdb_byte **,
+ struct die_info *);
static struct die_info *read_die_and_siblings (const struct die_reader_specs *,
- gdb_byte *info_ptr,
- gdb_byte **new_info_ptr,
+ const gdb_byte *info_ptr,
+ const gdb_byte **new_info_ptr,
struct die_info *parent);
-static gdb_byte *read_full_die_1 (const struct die_reader_specs *,
- struct die_info **, gdb_byte *, int *, int);
+static const gdb_byte *read_full_die_1 (const struct die_reader_specs *,
+ struct die_info **, const gdb_byte *,
+ int *, int);
-static gdb_byte *read_full_die (const struct die_reader_specs *,
- struct die_info **, gdb_byte *, int *);
+static const gdb_byte *read_full_die (const struct die_reader_specs *,
+ struct die_info **, const gdb_byte *,
+ int *);
static void process_die (struct die_info *, struct dwarf2_cu *);
-static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *,
- struct obstack *);
+static const char *dwarf2_canonicalize_name (const char *, struct dwarf2_cu *,
+ struct obstack *);
-static char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
+static const char *dwarf2_name (struct die_info *die, struct dwarf2_cu *);
-static const char *dwarf2_full_name (char *name,
+static const char *dwarf2_full_name (const char *name,
struct die_info *die,
struct dwarf2_cu *cu);
+static const char *dwarf2_physname (const char *name, struct die_info *die,
+ struct dwarf2_cu *cu);
+
static struct die_info *dwarf2_extension (struct die_info *die,
struct dwarf2_cu **);
@@ -1459,34 +1685,35 @@ static void dump_die_1 (struct ui_file *, int level, int max_level,
static void store_in_ref_table (struct die_info *,
struct dwarf2_cu *);
-static int is_ref_attr (struct attribute *);
+static sect_offset dwarf2_get_ref_die_offset (const struct attribute *);
-static sect_offset dwarf2_get_ref_die_offset (struct attribute *);
-
-static LONGEST dwarf2_get_attr_constant_value (struct attribute *, int);
+static LONGEST dwarf2_get_attr_constant_value (const struct attribute *, int);
static struct die_info *follow_die_ref_or_sig (struct die_info *,
- struct attribute *,
+ const struct attribute *,
struct dwarf2_cu **);
static struct die_info *follow_die_ref (struct die_info *,
- struct attribute *,
+ const struct attribute *,
struct dwarf2_cu **);
static struct die_info *follow_die_sig (struct die_info *,
- struct attribute *,
+ const struct attribute *,
struct dwarf2_cu **);
-static struct signatured_type *lookup_signatured_type_at_offset
- (struct objfile *objfile,
- struct dwarf2_section_info *section, sect_offset offset);
+static struct type *get_signatured_type (struct die_info *, ULONGEST,
+ struct dwarf2_cu *);
+
+static struct type *get_DW_AT_signature_type (struct die_info *,
+ const struct attribute *,
+ struct dwarf2_cu *);
static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu);
static void read_signatured_type (struct signatured_type *);
static struct type_unit_group *get_type_unit_group
- (struct dwarf2_cu *, struct attribute *);
+ (struct dwarf2_cu *, const struct attribute *);
static void build_type_unit_groups (die_reader_func_ftype *, void *);
@@ -1497,25 +1724,28 @@ static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
static struct die_info *dwarf_alloc_die (struct dwarf2_cu *, int);
static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int,
- char *, int);
+ const char *, int);
+
+static int attr_form_is_block (const struct attribute *);
-static int attr_form_is_block (struct attribute *);
+static int attr_form_is_section_offset (const struct attribute *);
-static int attr_form_is_section_offset (struct attribute *);
+static int attr_form_is_constant (const struct attribute *);
-static int attr_form_is_constant (struct attribute *);
+static int attr_form_is_ref (const struct attribute *);
static void fill_in_loclist_baton (struct dwarf2_cu *cu,
struct dwarf2_loclist_baton *baton,
- struct attribute *attr);
+ const struct attribute *attr);
-static void dwarf2_symbol_mark_computed (struct attribute *attr,
+static void dwarf2_symbol_mark_computed (const struct attribute *attr,
struct symbol *sym,
- struct dwarf2_cu *cu);
+ struct dwarf2_cu *cu,
+ int is_block);
-static gdb_byte *skip_one_die (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- struct abbrev_info *abbrev);
+static const gdb_byte *skip_one_die (const struct die_reader_specs *reader,
+ const gdb_byte *info_ptr,
+ struct abbrev_info *abbrev);
static void free_stack_comp_unit (void *);
@@ -1524,7 +1754,7 @@ static hashval_t partial_die_hash (const void *item);
static int partial_die_eq (const void *item_lhs, const void *item_rhs);
static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
- (sect_offset offset, struct objfile *objfile);
+ (sect_offset offset, unsigned int offset_in_dwz, struct objfile *objfile);
static void init_one_comp_unit (struct dwarf2_cu *cu,
struct dwarf2_per_cu_data *per_cu);
@@ -1565,7 +1795,7 @@ static void dwarf2_mark (struct dwarf2_cu *);
static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
static struct type *get_die_type_at_offset (sect_offset,
- struct dwarf2_per_cu_data *per_cu);
+ struct dwarf2_per_cu_data *);
static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
@@ -1574,19 +1804,21 @@ static void dwarf2_release_queue (void *dummy);
static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
enum language pretend_language);
-static int maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
- struct dwarf2_per_cu_data *per_cu,
- enum language pretend_language);
-
static void process_queue (void);
static void find_file_and_directory (struct die_info *die,
struct dwarf2_cu *cu,
- char **name, char **comp_dir);
+ const char **name, const char **comp_dir);
static char *file_full_name (int file, struct line_header *lh,
const char *comp_dir);
+static const gdb_byte *read_and_check_comp_unit_head
+ (struct comp_unit_head *header,
+ struct dwarf2_section_info *section,
+ struct dwarf2_section_info *abbrev_section, const gdb_byte *info_ptr,
+ int is_debug_types_section);
+
static void init_cutu_and_read_dies
(struct dwarf2_per_cu_data *this_cu, struct abbrev_table *abbrev_table,
int use_existing_cu, int keep,
@@ -1600,60 +1832,131 @@ static htab_t allocate_signatured_type_table (struct objfile *objfile);
static htab_t allocate_dwo_unit_table (struct objfile *objfile);
+static struct dwo_unit *lookup_dwo_unit_in_dwp
+ (struct dwp_file *dwp_file, const char *comp_dir,
+ ULONGEST signature, int is_debug_types);
+
+static struct dwp_file *get_dwp_file (void);
+
static struct dwo_unit *lookup_dwo_comp_unit
- (struct dwarf2_per_cu_data *, char *, const char *, ULONGEST);
+ (struct dwarf2_per_cu_data *, const char *, const char *, ULONGEST);
static struct dwo_unit *lookup_dwo_type_unit
- (struct signatured_type *, char *, const char *);
+ (struct signatured_type *, const char *, const char *);
-static void free_dwo_file_cleanup (void *);
+static void queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *);
-static void munmap_section_buffer (struct dwarf2_section_info *);
+static void free_dwo_file_cleanup (void *);
static void process_cu_includes (void);
-#if WORDS_BIGENDIAN
+static void check_producer (struct dwarf2_cu *cu);
+
+/* Various complaints about symbol reading that don't abort the process. */
-/* Convert VALUE between big- and little-endian. */
-static offset_type
-byte_swap (offset_type value)
+static void
+dwarf2_statement_list_fits_in_line_number_section_complaint (void)
{
- offset_type result;
-
- result = (value & 0xff) << 24;
- result |= (value & 0xff00) << 8;
- result |= (value & 0xff0000) >> 8;
- result |= (value & 0xff000000) >> 24;
- return result;
+ complaint (&symfile_complaints,
+ _("statement list doesn't fit in .debug_line section"));
}
-#define MAYBE_SWAP(V) byte_swap (V)
-
-#else
-#define MAYBE_SWAP(V) (V)
-#endif /* WORDS_BIGENDIAN */
-
-/* The suffix for an index file. */
-#define INDEX_SUFFIX ".gdb-index"
+static void
+dwarf2_debug_line_missing_file_complaint (void)
+{
+ complaint (&symfile_complaints,
+ _(".debug_line section has line data without a file"));
+}
-static const char *dwarf2_physname (char *name, struct die_info *die,
- struct dwarf2_cu *cu);
+static void
+dwarf2_debug_line_missing_end_sequence_complaint (void)
+{
+ complaint (&symfile_complaints,
+ _(".debug_line section has line "
+ "program sequence without an end"));
+}
-/* Try to locate the sections we need for DWARF 2 debugging
- information and return true if we have enough to do something.
- NAMES points to the dwarf2 section names, or is NULL if the standard
- ELF names are used. */
+static void
+dwarf2_complex_location_expr_complaint (void)
+{
+ complaint (&symfile_complaints, _("location expression too complex"));
+}
-int
-dwarf2_has_info (struct objfile *objfile,
- const struct dwarf2_debug_sections *names)
+static void
+dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
+ int arg3)
{
- dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
- if (!dwarf2_per_objfile)
- {
- /* Initialize per-objfile state. */
- struct dwarf2_per_objfile *data
- = obstack_alloc (&objfile->objfile_obstack, sizeof (*data));
+ complaint (&symfile_complaints,
+ _("const value length mismatch for '%s', got %d, expected %d"),
+ arg1, arg2, arg3);
+}
+
+static void
+dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section)
+{
+ complaint (&symfile_complaints,
+ _("debug info runs off end of %s section"
+ " [in module %s]"),
+ get_section_name (section),
+ get_section_file_name (section));
+}
+
+static void
+dwarf2_macro_malformed_definition_complaint (const char *arg1)
+{
+ complaint (&symfile_complaints,
+ _("macro debug info contains a "
+ "malformed macro definition:\n`%s'"),
+ arg1);
+}
+
+static void
+dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
+{
+ complaint (&symfile_complaints,
+ _("invalid attribute class or form for '%s' in '%s'"),
+ arg1, arg2);
+}
+
+#if WORDS_BIGENDIAN
+
+/* Convert VALUE between big- and little-endian. */
+static offset_type
+byte_swap (offset_type value)
+{
+ offset_type result;
+
+ result = (value & 0xff) << 24;
+ result |= (value & 0xff00) << 8;
+ result |= (value & 0xff0000) >> 8;
+ result |= (value & 0xff000000) >> 24;
+ return result;
+}
+
+#define MAYBE_SWAP(V) byte_swap (V)
+
+#else
+#define MAYBE_SWAP(V) (V)
+#endif /* WORDS_BIGENDIAN */
+
+/* The suffix for an index file. */
+#define INDEX_SUFFIX ".gdb-index"
+
+/* Try to locate the sections we need for DWARF 2 debugging
+ information and return true if we have enough to do something.
+ NAMES points to the dwarf2 section names, or is NULL if the standard
+ ELF names are used. */
+
+int
+dwarf2_has_info (struct objfile *objfile,
+ const struct dwarf2_debug_sections *names)
+{
+ dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+ if (!dwarf2_per_objfile)
+ {
+ /* Initialize per-objfile state. */
+ struct dwarf2_per_objfile *data
+ = obstack_alloc (&objfile->objfile_obstack, sizeof (*data));
memset (data, 0, sizeof (*data));
set_objfile_data (objfile, dwarf2_objfile_data_key, data);
@@ -1663,8 +1966,92 @@ dwarf2_has_info (struct objfile *objfile,
(void *) names);
dwarf2_per_objfile->objfile = objfile;
}
- return (dwarf2_per_objfile->info.asection != NULL
- && dwarf2_per_objfile->abbrev.asection != NULL);
+ return (!dwarf2_per_objfile->info.is_virtual
+ && dwarf2_per_objfile->info.s.asection != NULL
+ && !dwarf2_per_objfile->abbrev.is_virtual
+ && dwarf2_per_objfile->abbrev.s.asection != NULL);
+}
+
+/* Return the containing section of virtual section SECTION. */
+
+static struct dwarf2_section_info *
+get_containing_section (const struct dwarf2_section_info *section)
+{
+ gdb_assert (section->is_virtual);
+ return section->s.containing_section;
+}
+
+/* Return the bfd owner of SECTION. */
+
+static struct bfd *
+get_section_bfd_owner (const struct dwarf2_section_info *section)
+{
+ if (section->is_virtual)
+ {
+ section = get_containing_section (section);
+ gdb_assert (!section->is_virtual);
+ }
+ return section->s.asection->owner;
+}
+
+/* Return the bfd section of SECTION.
+ Returns NULL if the section is not present. */
+
+static asection *
+get_section_bfd_section (const struct dwarf2_section_info *section)
+{
+ if (section->is_virtual)
+ {
+ section = get_containing_section (section);
+ gdb_assert (!section->is_virtual);
+ }
+ return section->s.asection;
+}
+
+/* Return the name of SECTION. */
+
+static const char *
+get_section_name (const struct dwarf2_section_info *section)
+{
+ asection *sectp = get_section_bfd_section (section);
+
+ gdb_assert (sectp != NULL);
+ return bfd_section_name (get_section_bfd_owner (section), sectp);
+}
+
+/* Return the name of the file SECTION is in. */
+
+static const char *
+get_section_file_name (const struct dwarf2_section_info *section)
+{
+ bfd *abfd = get_section_bfd_owner (section);
+
+ return bfd_get_filename (abfd);
+}
+
+/* Return the id of SECTION.
+ Returns 0 if SECTION doesn't exist. */
+
+static int
+get_section_id (const struct dwarf2_section_info *section)
+{
+ asection *sectp = get_section_bfd_section (section);
+
+ if (sectp == NULL)
+ return 0;
+ return sectp->id;
+}
+
+/* Return the flags of SECTION.
+ SECTION (or containing section if this is a virtual section) must exist. */
+
+static int
+get_section_flags (const struct dwarf2_section_info *section)
+{
+ asection *sectp = get_section_bfd_section (section);
+
+ gdb_assert (sectp != NULL);
+ return bfd_get_section_flags (sectp->owner, sectp);
}
/* When loading sections, we look either for uncompressed section or for
@@ -1703,57 +2090,57 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
}
else if (section_is_p (sectp->name, &names->info))
{
- dwarf2_per_objfile->info.asection = sectp;
+ dwarf2_per_objfile->info.s.asection = sectp;
dwarf2_per_objfile->info.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->abbrev))
{
- dwarf2_per_objfile->abbrev.asection = sectp;
+ dwarf2_per_objfile->abbrev.s.asection = sectp;
dwarf2_per_objfile->abbrev.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->line))
{
- dwarf2_per_objfile->line.asection = sectp;
+ dwarf2_per_objfile->line.s.asection = sectp;
dwarf2_per_objfile->line.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->loc))
{
- dwarf2_per_objfile->loc.asection = sectp;
+ dwarf2_per_objfile->loc.s.asection = sectp;
dwarf2_per_objfile->loc.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->macinfo))
{
- dwarf2_per_objfile->macinfo.asection = sectp;
+ dwarf2_per_objfile->macinfo.s.asection = sectp;
dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->macro))
{
- dwarf2_per_objfile->macro.asection = sectp;
+ dwarf2_per_objfile->macro.s.asection = sectp;
dwarf2_per_objfile->macro.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->str))
{
- dwarf2_per_objfile->str.asection = sectp;
+ dwarf2_per_objfile->str.s.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.s.asection = sectp;
dwarf2_per_objfile->addr.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->frame))
{
- dwarf2_per_objfile->frame.asection = sectp;
+ dwarf2_per_objfile->frame.s.asection = sectp;
dwarf2_per_objfile->frame.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->eh_frame))
{
- dwarf2_per_objfile->eh_frame.asection = sectp;
+ dwarf2_per_objfile->eh_frame.s.asection = sectp;
dwarf2_per_objfile->eh_frame.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->ranges))
{
- dwarf2_per_objfile->ranges.asection = sectp;
+ dwarf2_per_objfile->ranges.s.asection = sectp;
dwarf2_per_objfile->ranges.size = bfd_get_section_size (sectp);
}
else if (section_is_p (sectp->name, &names->types))
@@ -1761,7 +2148,7 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
struct dwarf2_section_info type_section;
memset (&type_section, 0, sizeof (type_section));
- type_section.asection = sectp;
+ type_section.s.asection = sectp;
type_section.size = bfd_get_section_size (sectp);
VEC_safe_push (dwarf2_section_info_def, dwarf2_per_objfile->types,
@@ -1769,7 +2156,7 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
}
else if (section_is_p (sectp->name, &names->gdb_index))
{
- dwarf2_per_objfile->gdb_index.asection = sectp;
+ dwarf2_per_objfile->gdb_index.s.asection = sectp;
dwarf2_per_objfile->gdb_index.size = bfd_get_section_size (sectp);
}
@@ -1778,161 +2165,75 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
dwarf2_per_objfile->has_section_at_zero = 1;
}
-/* Decompress a section that was compressed using zlib. Store the
- decompressed buffer, and its size, in OUTBUF and OUTSIZE. */
-
-static void
-zlib_decompress_section (struct objfile *objfile, asection *sectp,
- gdb_byte **outbuf, bfd_size_type *outsize)
-{
- bfd *abfd = sectp->owner;
-#ifndef HAVE_ZLIB_H
- error (_("Support for zlib-compressed DWARF data (from '%s') "
- "is disabled in this copy of GDB"),
- bfd_get_filename (abfd));
-#else
- bfd_size_type compressed_size = bfd_get_section_size (sectp);
- gdb_byte *compressed_buffer = xmalloc (compressed_size);
- struct cleanup *cleanup = make_cleanup (xfree, compressed_buffer);
- bfd_size_type uncompressed_size;
- gdb_byte *uncompressed_buffer;
- z_stream strm;
- int rc;
- int header_size = 12;
-
- if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
- || bfd_bread (compressed_buffer,
- compressed_size, abfd) != compressed_size)
- error (_("Dwarf Error: Can't read DWARF data from '%s'"),
- bfd_get_filename (abfd));
-
- /* Read the zlib header. In this case, it should be "ZLIB" followed
- by the uncompressed section size, 8 bytes in big-endian order. */
- if (compressed_size < header_size
- || strncmp (compressed_buffer, "ZLIB", 4) != 0)
- error (_("Dwarf Error: Corrupt DWARF ZLIB header from '%s'"),
- bfd_get_filename (abfd));
- uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
- uncompressed_size += compressed_buffer[11];
-
- /* It is possible the section consists of several compressed
- buffers concatenated together, so we uncompress in a loop. */
- strm.zalloc = NULL;
- strm.zfree = NULL;
- strm.opaque = NULL;
- strm.avail_in = compressed_size - header_size;
- strm.next_in = (Bytef*) compressed_buffer + header_size;
- strm.avail_out = uncompressed_size;
- uncompressed_buffer = obstack_alloc (&objfile->objfile_obstack,
- uncompressed_size);
- rc = inflateInit (&strm);
- while (strm.avail_in > 0)
- {
- if (rc != Z_OK)
- error (_("Dwarf Error: setting up DWARF uncompression in '%s': %d"),
- bfd_get_filename (abfd), rc);
- strm.next_out = ((Bytef*) uncompressed_buffer
- + (uncompressed_size - strm.avail_out));
- rc = inflate (&strm, Z_FINISH);
- if (rc != Z_STREAM_END)
- error (_("Dwarf Error: zlib error uncompressing from '%s': %d"),
- bfd_get_filename (abfd), rc);
- rc = inflateReset (&strm);
- }
- rc = inflateEnd (&strm);
- if (rc != Z_OK
- || strm.avail_out != 0)
- error (_("Dwarf Error: concluding DWARF uncompression in '%s': %d"),
- bfd_get_filename (abfd), rc);
-
- do_cleanups (cleanup);
- *outbuf = uncompressed_buffer;
- *outsize = uncompressed_size;
-#endif
-}
-
/* A helper function that decides whether a section is empty,
or not present. */
static int
-dwarf2_section_empty_p (struct dwarf2_section_info *info)
+dwarf2_section_empty_p (const struct dwarf2_section_info *section)
{
- return info->asection == NULL || info->size == 0;
+ if (section->is_virtual)
+ return section->size == 0;
+ return section->s.asection == NULL || section->size == 0;
}
/* Read the contents of the section INFO.
OBJFILE is the main object file, but not necessarily the file where
- the section comes from. E.g., for DWO files INFO->asection->owner
- is the bfd of the DWO file.
+ the section comes from. E.g., for DWO files the bfd of INFO is the bfd
+ of the DWO file.
If the section is compressed, uncompress it before returning. */
static void
dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
{
- asection *sectp = info->asection;
+ asection *sectp;
bfd *abfd;
gdb_byte *buf, *retbuf;
- unsigned char header[4];
if (info->readin)
return;
info->buffer = NULL;
- info->map_addr = NULL;
info->readin = 1;
if (dwarf2_section_empty_p (info))
return;
- /* Note that ABFD may not be from OBJFILE, e.g. a DWO section. */
- abfd = sectp->owner;
-
- /* Check if the file has a 4-byte header indicating compression. */
- if (info->size > sizeof (header)
- && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0
- && bfd_bread (header, sizeof (header), abfd) == sizeof (header))
- {
- /* Upon decompression, update the buffer and its size. */
- if (strncmp (header, "ZLIB", sizeof (header)) == 0)
- {
- zlib_decompress_section (objfile, sectp, &info->buffer,
- &info->size);
- return;
- }
- }
-
-#ifdef HAVE_MMAP
- if (pagesize == 0)
- pagesize = getpagesize ();
+ sectp = get_section_bfd_section (info);
- /* Only try to mmap sections which are large enough: we don't want to
- waste space due to fragmentation. Also, only try mmap for sections
- without relocations. */
-
- if (info->size > 4 * pagesize && (sectp->flags & SEC_RELOC) == 0)
+ /* If this is a virtual section we need to read in the real one first. */
+ if (info->is_virtual)
{
- info->buffer = bfd_mmap (abfd, 0, info->size, PROT_READ,
- MAP_PRIVATE, sectp->filepos,
- &info->map_addr, &info->map_len);
+ struct dwarf2_section_info *containing_section =
+ get_containing_section (info);
- if ((caddr_t)info->buffer != MAP_FAILED)
+ gdb_assert (sectp != NULL);
+ if ((sectp->flags & SEC_RELOC) != 0)
{
-#if HAVE_POSIX_MADVISE
- posix_madvise (info->map_addr, info->map_len, POSIX_MADV_WILLNEED);
-#endif
- return;
+ error (_("Dwarf Error: DWP format V2 with relocations is not"
+ " supported in section %s [in module %s]"),
+ get_section_name (info), get_section_file_name (info));
}
+ dwarf2_read_section (objfile, containing_section);
+ /* Other code should have already caught virtual sections that don't
+ fit. */
+ gdb_assert (info->virtual_offset + info->size
+ <= containing_section->size);
+ /* If the real section is empty or there was a problem reading the
+ section we shouldn't get here. */
+ gdb_assert (containing_section->buffer != NULL);
+ info->buffer = containing_section->buffer + info->virtual_offset;
+ return;
+ }
+
+ /* If the section has relocations, we must read it ourselves.
+ Otherwise we attach it to the BFD. */
+ if ((sectp->flags & SEC_RELOC) == 0)
+ {
+ info->buffer = gdb_bfd_map_section (sectp, &info->size);
+ return;
}
-#endif
- /* If we get here, we are a normal, not-compressed section. */
- info->buffer = buf
- = obstack_alloc (&objfile->objfile_obstack, info->size);
+ buf = obstack_alloc (&objfile->objfile_obstack, info->size);
+ info->buffer = buf;
/* When debugging .o files, we may need to apply relocations; see
http://sourceware.org/ml/gdb-patches/2002-04/msg00136.html .
@@ -1945,10 +2246,16 @@ dwarf2_read_section (struct objfile *objfile, struct dwarf2_section_info *info)
return;
}
+ abfd = get_section_bfd_owner (info);
+ gdb_assert (abfd != NULL);
+
if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
|| bfd_bread (buf, info->size, abfd) != info->size)
- error (_("Dwarf Error: Can't read DWARF data from '%s'"),
- bfd_get_filename (abfd));
+ {
+ error (_("Dwarf Error: Can't read DWARF data"
+ " in section %s [in module %s]"),
+ bfd_section_name (abfd, sectp), bfd_get_filename (abfd));
+ }
}
/* A helper function that returns the size of a section in a safe way.
@@ -1973,7 +2280,7 @@ dwarf2_section_size (struct objfile *objfile,
void
dwarf2_get_section_info (struct objfile *objfile,
enum dwarf2_section_enum sect,
- asection **sectp, gdb_byte **bufp,
+ asection **sectp, const gdb_byte **bufp,
bfd_size_type *sizep)
{
struct dwarf2_per_objfile *data
@@ -2003,11 +2310,131 @@ dwarf2_get_section_info (struct objfile *objfile,
dwarf2_read_section (objfile, info);
- *sectp = info->asection;
+ *sectp = get_section_bfd_section (info);
*bufp = info->buffer;
*sizep = info->size;
}
+/* A helper function to find the sections for a .dwz file. */
+
+static void
+locate_dwz_sections (bfd *abfd, asection *sectp, void *arg)
+{
+ struct dwz_file *dwz_file = arg;
+
+ /* Note that we only support the standard ELF names, because .dwz
+ is ELF-only (at the time of writing). */
+ if (section_is_p (sectp->name, &dwarf2_elf_names.abbrev))
+ {
+ dwz_file->abbrev.s.asection = sectp;
+ dwz_file->abbrev.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &dwarf2_elf_names.info))
+ {
+ dwz_file->info.s.asection = sectp;
+ dwz_file->info.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &dwarf2_elf_names.str))
+ {
+ dwz_file->str.s.asection = sectp;
+ dwz_file->str.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &dwarf2_elf_names.line))
+ {
+ dwz_file->line.s.asection = sectp;
+ dwz_file->line.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &dwarf2_elf_names.macro))
+ {
+ dwz_file->macro.s.asection = sectp;
+ dwz_file->macro.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &dwarf2_elf_names.gdb_index))
+ {
+ dwz_file->gdb_index.s.asection = sectp;
+ dwz_file->gdb_index.size = bfd_get_section_size (sectp);
+ }
+}
+
+/* Open the separate '.dwz' debug file, if needed. Return NULL if
+ there is no .gnu_debugaltlink section in the file. Error if there
+ is such a section but the file cannot be found. */
+
+static struct dwz_file *
+dwarf2_get_dwz_file (void)
+{
+ bfd *dwz_bfd;
+ char *data;
+ struct cleanup *cleanup;
+ const char *filename;
+ struct dwz_file *result;
+ bfd_size_type buildid_len_arg;
+ size_t buildid_len;
+ bfd_byte *buildid;
+
+ if (dwarf2_per_objfile->dwz_file != NULL)
+ return dwarf2_per_objfile->dwz_file;
+
+ bfd_set_error (bfd_error_no_error);
+ data = bfd_get_alt_debug_link_info (dwarf2_per_objfile->objfile->obfd,
+ &buildid_len_arg, &buildid);
+ if (data == NULL)
+ {
+ if (bfd_get_error () == bfd_error_no_error)
+ return NULL;
+ error (_("could not read '.gnu_debugaltlink' section: %s"),
+ bfd_errmsg (bfd_get_error ()));
+ }
+ cleanup = make_cleanup (xfree, data);
+ make_cleanup (xfree, buildid);
+
+ buildid_len = (size_t) buildid_len_arg;
+
+ filename = (const char *) data;
+ if (!IS_ABSOLUTE_PATH (filename))
+ {
+ char *abs = gdb_realpath (objfile_name (dwarf2_per_objfile->objfile));
+ char *rel;
+
+ make_cleanup (xfree, abs);
+ abs = ldirname (abs);
+ make_cleanup (xfree, abs);
+
+ rel = concat (abs, SLASH_STRING, filename, (char *) NULL);
+ make_cleanup (xfree, rel);
+ filename = rel;
+ }
+
+ /* First try the file name given in the section. If that doesn't
+ work, try to use the build-id instead. */
+ dwz_bfd = gdb_bfd_open (filename, gnutarget, -1);
+ if (dwz_bfd != NULL)
+ {
+ if (!build_id_verify (dwz_bfd, buildid_len, buildid))
+ {
+ gdb_bfd_unref (dwz_bfd);
+ dwz_bfd = NULL;
+ }
+ }
+
+ if (dwz_bfd == NULL)
+ dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid);
+
+ if (dwz_bfd == NULL)
+ error (_("could not find '.gnu_debugaltlink' file for %s"),
+ objfile_name (dwarf2_per_objfile->objfile));
+
+ result = OBSTACK_ZALLOC (&dwarf2_per_objfile->objfile->objfile_obstack,
+ struct dwz_file);
+ result->dwz_bfd = dwz_bfd;
+
+ bfd_map_over_sections (dwz_bfd, locate_dwz_sections, result);
+
+ do_cleanups (cleanup);
+
+ dwarf2_per_objfile->dwz_file = result;
+ return result;
+}
/* DWARF quick_symbols_functions support. */
@@ -2171,6 +2598,17 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
{
queue_comp_unit (per_cu, language_minimal);
load_cu (per_cu);
+
+ /* If we just loaded a CU from a DWO, and we're working with an index
+ that may badly handle TUs, load all the TUs in that DWO as well.
+ http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */
+ if (!per_cu->is_debug_types
+ && per_cu->cu->dwo_unit != NULL
+ && dwarf2_per_objfile->index_table != NULL
+ && dwarf2_per_objfile->index_table->version <= 7
+ /* DWP files aren't supported yet. */
+ && get_dwp_file () == NULL)
+ queue_and_load_all_dwo_tus (per_cu);
}
process_queue ();
@@ -2255,53 +2693,26 @@ dw2_get_primary_cu (int index)
return dwarf2_per_objfile->all_comp_units[index];
}
-/* A helper function that knows how to read a 64-bit value in a way
- that doesn't make gdb die. Returns 1 if the conversion went ok, 0
- otherwise. */
-
-static int
-extract_cu_value (const char *bytes, ULONGEST *result)
-{
- if (sizeof (ULONGEST) < 8)
- {
- int i;
-
- /* Ignore the upper 4 bytes if they are all zero. */
- for (i = 0; i < 4; ++i)
- if (bytes[i + 4] != 0)
- return 0;
-
- *result = extract_unsigned_integer (bytes, 4, BFD_ENDIAN_LITTLE);
- }
- else
- *result = extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE);
- return 1;
-}
-
-/* Read the CU list from the mapped index, and use it to create all
- the CU objects for this objfile. Return 0 if something went wrong,
- 1 if everything went ok. */
+/* A helper for create_cus_from_index that handles a given list of
+ CUs. */
-static int
-create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list,
- offset_type cu_list_elements)
+static void
+create_cus_from_index_list (struct objfile *objfile,
+ const gdb_byte *cu_list, offset_type n_elements,
+ struct dwarf2_section_info *section,
+ int is_dwz,
+ int base_offset)
{
offset_type i;
- dwarf2_per_objfile->n_comp_units = cu_list_elements / 2;
- dwarf2_per_objfile->all_comp_units
- = obstack_alloc (&objfile->objfile_obstack,
- dwarf2_per_objfile->n_comp_units
- * sizeof (struct dwarf2_per_cu_data *));
-
- for (i = 0; i < cu_list_elements; i += 2)
+ for (i = 0; i < n_elements; i += 2)
{
struct dwarf2_per_cu_data *the_cu;
ULONGEST offset, length;
- if (!extract_cu_value (cu_list, &offset)
- || !extract_cu_value (cu_list + 8, &length))
- return 0;
+ gdb_static_assert (sizeof (ULONGEST) >= 8);
+ offset = extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE);
+ length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
cu_list += 2 * 8;
the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
@@ -2309,18 +2720,44 @@ create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list,
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->section = section;
the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_quick_data);
- dwarf2_per_objfile->all_comp_units[i / 2] = the_cu;
+ the_cu->is_dwz = is_dwz;
+ dwarf2_per_objfile->all_comp_units[base_offset + i / 2] = the_cu;
}
+}
- return 1;
+/* Read the CU list from the mapped index, and use it to create all
+ the CU objects for this objfile. */
+
+static void
+create_cus_from_index (struct objfile *objfile,
+ const gdb_byte *cu_list, offset_type cu_list_elements,
+ const gdb_byte *dwz_list, offset_type dwz_elements)
+{
+ struct dwz_file *dwz;
+
+ dwarf2_per_objfile->n_comp_units = (cu_list_elements + dwz_elements) / 2;
+ dwarf2_per_objfile->all_comp_units
+ = obstack_alloc (&objfile->objfile_obstack,
+ dwarf2_per_objfile->n_comp_units
+ * sizeof (struct dwarf2_per_cu_data *));
+
+ create_cus_from_index_list (objfile, cu_list, cu_list_elements,
+ &dwarf2_per_objfile->info, 0, 0);
+
+ if (dwz_elements == 0)
+ return;
+
+ dwz = dwarf2_get_dwz_file ();
+ create_cus_from_index_list (objfile, dwz_list, dwz_elements, &dwz->info, 1,
+ cu_list_elements / 2);
}
/* Create the signatured type hash table from the index. */
-static int
+static void
create_signatured_type_table_from_index (struct objfile *objfile,
struct dwarf2_section_info *section,
const gdb_byte *bytes,
@@ -2331,9 +2768,8 @@ create_signatured_type_table_from_index (struct objfile *objfile,
dwarf2_per_objfile->n_type_units = elements / 3;
dwarf2_per_objfile->all_type_units
- = obstack_alloc (&objfile->objfile_obstack,
- dwarf2_per_objfile->n_type_units
- * sizeof (struct signatured_type *));
+ = xmalloc (dwarf2_per_objfile->n_type_units
+ * sizeof (struct signatured_type *));
sig_types_hash = allocate_signatured_type_table (objfile);
@@ -2343,9 +2779,10 @@ create_signatured_type_table_from_index (struct objfile *objfile,
ULONGEST offset, type_offset_in_tu, signature;
void **slot;
- if (!extract_cu_value (bytes, &offset)
- || !extract_cu_value (bytes + 8, &type_offset_in_tu))
- return 0;
+ gdb_static_assert (sizeof (ULONGEST) >= 8);
+ offset = extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE);
+ type_offset_in_tu = extract_unsigned_integer (bytes + 8, 8,
+ BFD_ENDIAN_LITTLE);
signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
bytes += 3 * 8;
@@ -2354,7 +2791,7 @@ create_signatured_type_table_from_index (struct objfile *objfile,
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.section = section;
sig_type->per_cu.offset.sect_off = offset;
sig_type->per_cu.objfile = objfile;
sig_type->per_cu.v.quick
@@ -2368,8 +2805,6 @@ create_signatured_type_table_from_index (struct objfile *objfile,
}
dwarf2_per_objfile->signatured_types = sig_types_hash;
-
- return 1;
}
/* Read the address map data from the mapped index, and use it to
@@ -2402,7 +2837,23 @@ create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index)
iter += 8;
cu_index = extract_unsigned_integer (iter, 4, BFD_ENDIAN_LITTLE);
iter += 4;
-
+
+ if (lo > hi)
+ {
+ complaint (&symfile_complaints,
+ _(".gdb_index address table has invalid range (%s - %s)"),
+ hex_string (lo), hex_string (hi));
+ continue;
+ }
+
+ if (cu_index >= dwarf2_per_objfile->n_comp_units)
+ {
+ complaint (&symfile_complaints,
+ _(".gdb_index address table has invalid CU number %u"),
+ (unsigned) cu_index);
+ continue;
+ }
+
addrmap_set_empty (mutable_map, lo + baseaddr, hi + baseaddr - 1,
dw2_get_cu (cu_index));
}
@@ -2507,33 +2958,44 @@ find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
}
}
-/* Read the index file. If everything went ok, initialize the "quick"
- elements of all the CUs and return 1. Otherwise, return 0. */
+/* A helper function that reads the .gdb_index from SECTION and fills
+ in MAP. FILENAME is the name of the file containing the section;
+ it is used for error reporting. DEPRECATED_OK is nonzero if it is
+ ok to use deprecated sections.
+
+ CU_LIST, CU_LIST_ELEMENTS, TYPES_LIST, and TYPES_LIST_ELEMENTS are
+ out parameters that are filled in with information about the CU and
+ TU lists in the section.
+
+ Returns 1 if all went well, 0 otherwise. */
static int
-dwarf2_read_index (struct objfile *objfile)
-{
- char *addr;
- struct mapped_index *map;
+read_index_from_section (struct objfile *objfile,
+ const char *filename,
+ int deprecated_ok,
+ struct dwarf2_section_info *section,
+ struct mapped_index *map,
+ const gdb_byte **cu_list,
+ offset_type *cu_list_elements,
+ const gdb_byte **types_list,
+ offset_type *types_list_elements)
+{
+ const gdb_byte *addr;
+ offset_type version;
offset_type *metadata;
- const gdb_byte *cu_list;
- const gdb_byte *types_list = NULL;
- offset_type version, cu_list_elements;
- offset_type types_list_elements = 0;
int i;
- if (dwarf2_section_empty_p (&dwarf2_per_objfile->gdb_index))
+ if (dwarf2_section_empty_p (section))
return 0;
/* Older elfutils strip versions could keep the section in the main
executable while splitting it for the separate debug info file. */
- if ((bfd_get_file_flags (dwarf2_per_objfile->gdb_index.asection)
- & SEC_HAS_CONTENTS) == 0)
+ if ((get_section_flags (section) & SEC_HAS_CONTENTS) == 0)
return 0;
- dwarf2_read_section (objfile, &dwarf2_per_objfile->gdb_index);
+ dwarf2_read_section (objfile, section);
- addr = dwarf2_per_objfile->gdb_index.buffer;
+ addr = section->buffer;
/* Version check. */
version = MAYBE_SWAP (*(offset_type *) addr);
/* Versions earlier than 3 emitted every copy of a psymbol. This
@@ -2546,7 +3008,7 @@ dwarf2_read_index (struct objfile *objfile)
if (!warning_printed)
{
warning (_("Skipping obsolete .gdb_index section in %s."),
- objfile->name);
+ filename);
warning_printed = 1;
}
return 0;
@@ -2559,7 +3021,7 @@ dwarf2_read_index (struct objfile *objfile)
set breakpoints on inlined functions by name, so we ignore these
indices unless the user has done
"set use-deprecated-index-sections on". */
- if (version < 6 && !use_deprecated_index_sections)
+ if (version < 6 && !deprecated_ok)
{
static int warning_printed = 0;
if (!warning_printed)
@@ -2568,32 +3030,39 @@ dwarf2_read_index (struct objfile *objfile)
Skipping deprecated .gdb_index section in %s.\n\
Do \"set use-deprecated-index-sections on\" before the file is read\n\
to use the section anyway."),
- objfile->name);
+ filename);
warning_printed = 1;
}
return 0;
}
+ /* Version 7 indices generated by gold refer to the CU for a symbol instead
+ of the TU (for symbols coming from TUs),
+ http://sourceware.org/bugzilla/show_bug.cgi?id=15021.
+ Plus gold-generated indices can have duplicate entries for global symbols,
+ http://sourceware.org/bugzilla/show_bug.cgi?id=15646.
+ These are just performance bugs, and we can't distinguish gdb-generated
+ indices from gold-generated ones, so issue no warning here. */
+
/* Indexes with higher version than the one supported by GDB may be no
longer backward compatible. */
- if (version > 7)
+ if (version > 8)
return 0;
- map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
map->version = version;
- map->total_size = dwarf2_per_objfile->gdb_index.size;
+ map->total_size = section->size;
metadata = (offset_type *) (addr + sizeof (offset_type));
i = 0;
- cu_list = addr + MAYBE_SWAP (metadata[i]);
- cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
- / 8);
+ *cu_list = addr + MAYBE_SWAP (metadata[i]);
+ *cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
+ / 8);
++i;
- types_list = addr + MAYBE_SWAP (metadata[i]);
- types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
- - MAYBE_SWAP (metadata[i]))
- / 8);
+ *types_list = addr + MAYBE_SWAP (metadata[i]);
+ *types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
+ - MAYBE_SWAP (metadata[i]))
+ / 8);
++i;
map->address_table = addr + MAYBE_SWAP (metadata[i]);
@@ -2607,16 +3076,60 @@ to use the section anyway."),
/ (2 * sizeof (offset_type)));
++i;
- map->constant_pool = addr + MAYBE_SWAP (metadata[i]);
+ map->constant_pool = (char *) (addr + MAYBE_SWAP (metadata[i]));
- /* Don't use the index if it's empty. */
- if (map->symbol_table_slots == 0)
- return 0;
+ return 1;
+}
- if (!create_cus_from_index (objfile, cu_list, cu_list_elements))
- return 0;
- if (types_list_elements)
+/* Read the index file. If everything went ok, initialize the "quick"
+ elements of all the CUs and return 1. Otherwise, return 0. */
+
+static int
+dwarf2_read_index (struct objfile *objfile)
+{
+ struct mapped_index local_map, *map;
+ const gdb_byte *cu_list, *types_list, *dwz_list = NULL;
+ offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0;
+ struct dwz_file *dwz;
+
+ if (!read_index_from_section (objfile, objfile_name (objfile),
+ use_deprecated_index_sections,
+ &dwarf2_per_objfile->gdb_index, &local_map,
+ &cu_list, &cu_list_elements,
+ &types_list, &types_list_elements))
+ return 0;
+
+ /* Don't use the index if it's empty. */
+ if (local_map.symbol_table_slots == 0)
+ return 0;
+
+ /* If there is a .dwz file, read it so we can get its CU list as
+ well. */
+ dwz = dwarf2_get_dwz_file ();
+ if (dwz != NULL)
+ {
+ struct mapped_index dwz_map;
+ const gdb_byte *dwz_types_ignore;
+ offset_type dwz_types_elements_ignore;
+
+ if (!read_index_from_section (objfile, bfd_get_filename (dwz->dwz_bfd),
+ 1,
+ &dwz->gdb_index, &dwz_map,
+ &dwz_list, &dwz_list_elements,
+ &dwz_types_ignore,
+ &dwz_types_elements_ignore))
+ {
+ warning (_("could not read '.gdb_index' section from %s; skipping"),
+ bfd_get_filename (dwz->dwz_bfd));
+ return 0;
+ }
+ }
+
+ create_cus_from_index (objfile, cu_list, cu_list_elements, dwz_list,
+ dwz_list_elements);
+
+ if (types_list_elements)
{
struct dwarf2_section_info *section;
@@ -2628,13 +3141,14 @@ to use the section anyway."),
section = VEC_index (dwarf2_section_info_def,
dwarf2_per_objfile->types, 0);
- if (!create_signatured_type_table_from_index (objfile, section,
- types_list,
- types_list_elements))
- return 0;
+ create_signatured_type_table_from_index (objfile, section, types_list,
+ types_list_elements);
}
- create_addrmap_from_index (objfile, map);
+ create_addrmap_from_index (objfile, &local_map);
+
+ map = obstack_alloc (&objfile->objfile_obstack, sizeof (struct mapped_index));
+ *map = local_map;
dwarf2_per_objfile->index_table = map;
dwarf2_per_objfile->using_index = 1;
@@ -2654,45 +3168,11 @@ dw2_setup (struct objfile *objfile)
gdb_assert (dwarf2_per_objfile);
}
-/* Reader function for dw2_build_type_unit_groups. */
-
-static void
-dw2_build_type_unit_groups_reader (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- struct die_info *type_unit_die,
- int has_children,
- void *data)
-{
- struct dwarf2_cu *cu = reader->cu;
- struct attribute *attr;
- struct type_unit_group *tu_group;
-
- gdb_assert (data == NULL);
-
- if (! has_children)
- return;
-
- attr = dwarf2_attr_no_follow (type_unit_die, DW_AT_stmt_list);
- /* Call this for its side-effect of creating the associated
- struct type_unit_group if it doesn't already exist. */
- tu_group = get_type_unit_group (cu, attr);
-}
-
-/* Build dwarf2_per_objfile->type_unit_groups.
- This function may be called multiple times. */
-
-static void
-dw2_build_type_unit_groups (void)
-{
- if (dwarf2_per_objfile->type_unit_groups == NULL)
- build_type_unit_groups (dw2_build_type_unit_groups_reader, NULL);
-}
-
/* die_reader_func for dw2_get_file_names. */
static void
dw2_get_file_names_reader (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
+ const gdb_byte *info_ptr,
struct die_info *comp_unit_die,
int has_children,
void *data)
@@ -2704,11 +3184,13 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
struct line_header *lh;
struct attribute *attr;
int i;
- char *name, *comp_dir;
+ const char *name, *comp_dir;
void **slot;
struct quick_file_names *qfn;
unsigned int line_offset;
+ gdb_assert (! this_cu->is_debug_types);
+
/* Our callers never want to match partial units -- instead they
will match the enclosing full CU. */
if (comp_unit_die->tag == DW_TAG_partial_unit)
@@ -2717,18 +3199,7 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
return;
}
- /* If we're reading the line header for TUs, store it in the "per_cu"
- for tu_group. */
- if (this_cu->is_debug_types)
- {
- struct type_unit_group *tu_group = data;
-
- gdb_assert (tu_group != NULL);
- lh_cu = &tu_group->per_cu;
- }
- else
- lh_cu = this_cu;
-
+ lh_cu = this_cu;
lh = NULL;
slot = NULL;
line_offset = 0;
@@ -2784,12 +3255,12 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
table for THIS_CU. */
static struct quick_file_names *
-dw2_get_file_names (struct objfile *objfile,
- struct dwarf2_per_cu_data *this_cu)
+dw2_get_file_names (struct dwarf2_per_cu_data *this_cu)
{
- /* For TUs this should only be called on the parent group. */
- if (this_cu->is_debug_types)
- gdb_assert (IS_TYPE_UNIT_GROUP (this_cu));
+ /* This should never be called for TUs. */
+ gdb_assert (! this_cu->is_debug_types);
+ /* Nor type unit groups. */
+ gdb_assert (! IS_TYPE_UNIT_GROUP (this_cu));
if (this_cu->v.quick->file_names != NULL)
return this_cu->v.quick->file_names;
@@ -2797,19 +3268,7 @@ dw2_get_file_names (struct objfile *objfile,
if (this_cu->v.quick->no_file_data)
return NULL;
- /* If DWO files are in use, we can still find the DW_AT_stmt_list attribute
- in the stub for CUs, there's is no need to lookup the DWO file.
- However, that's not the case for TUs where DW_AT_stmt_list lives in the
- DWO file. */
- if (this_cu->is_debug_types)
- {
- struct type_unit_group *tu_group = this_cu->s.type_unit_group;
-
- init_cutu_and_read_dies (tu_group->t.first_tu, NULL, 0, 0,
- dw2_get_file_names_reader, tu_group);
- }
- else
- init_cutu_and_read_dies_simple (this_cu, dw2_get_file_names_reader, NULL);
+ init_cutu_and_read_dies_simple (this_cu, dw2_get_file_names_reader, NULL);
if (this_cu->v.quick->no_file_data)
return NULL;
@@ -2825,7 +3284,7 @@ dw2_get_real_path (struct objfile *objfile,
{
if (qfn->real_names == NULL)
qfn->real_names = OBSTACK_CALLOC (&objfile->objfile_obstack,
- qfn->num_file_names, sizeof (char *));
+ qfn->num_file_names, char *);
if (qfn->real_names[index] == NULL)
qfn->real_names[index] = gdb_realpath (qfn->file_names[index]);
@@ -2879,8 +3338,7 @@ dw2_forget_cached_source_info (struct objfile *objfile)
static int
dw2_map_expand_apply (struct objfile *objfile,
struct dwarf2_per_cu_data *per_cu,
- const char *name,
- const char *full_path, const char *real_path,
+ const char *name, const char *real_path,
int (*callback) (struct symtab *, void *),
void *data)
{
@@ -2894,7 +3352,7 @@ dw2_map_expand_apply (struct objfile *objfile,
all of them. */
dw2_instantiate_symtab (per_cu);
- return iterate_over_some_symtabs (name, full_path, real_path, callback, data,
+ return iterate_over_some_symtabs (name, real_path, callback, data,
objfile->symtabs, last_made);
}
@@ -2902,21 +3360,19 @@ dw2_map_expand_apply (struct objfile *objfile,
static int
dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
- const char *full_path, const char *real_path,
+ const char *real_path,
int (*callback) (struct symtab *, void *),
void *data)
{
int i;
const char *name_basename = lbasename (name);
- int name_len = strlen (name);
- int is_abs = IS_ABSOLUTE_PATH (name);
dw2_setup (objfile);
- dw2_build_type_unit_groups ();
+ /* The rule is CUs specify all the files, including those used by
+ any TU, so there's no need to scan TUs here. */
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_unit_groups); ++i)
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i);
@@ -2926,22 +3382,21 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
if (per_cu->v.quick->symtab)
continue;
- file_data = dw2_get_file_names (objfile, per_cu);
+ file_data = dw2_get_file_names (per_cu);
if (file_data == NULL)
continue;
for (j = 0; j < file_data->num_file_names; ++j)
{
const char *this_name = file_data->file_names[j];
+ const char *this_real_name;
- if (FILENAME_CMP (name, this_name) == 0
- || (!is_abs && compare_filenames_for_search (this_name,
- name, name_len)))
+ if (compare_filenames_for_search (this_name, name))
{
- if (dw2_map_expand_apply (objfile, per_cu,
- name, full_path, real_path,
+ if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
callback, data))
return 1;
+ continue;
}
/* Before we invoke realpath, which can get expensive when many
@@ -2950,39 +3405,26 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
&& FILENAME_CMP (lbasename (this_name), name_basename) != 0)
continue;
- if (full_path != NULL)
+ this_real_name = dw2_get_real_path (objfile, file_data, j);
+ if (compare_filenames_for_search (this_real_name, name))
{
- const char *this_real_name = dw2_get_real_path (objfile,
- file_data, j);
-
- if (this_real_name != NULL
- && (FILENAME_CMP (full_path, this_real_name) == 0
- || (!is_abs
- && compare_filenames_for_search (this_real_name,
- name, name_len))))
- {
- if (dw2_map_expand_apply (objfile, per_cu,
- name, full_path, real_path,
- callback, data))
- return 1;
- }
+ if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
+ callback, data))
+ return 1;
+ continue;
}
if (real_path != NULL)
{
- const char *this_real_name = dw2_get_real_path (objfile,
- file_data, j);
-
+ gdb_assert (IS_ABSOLUTE_PATH (real_path));
+ gdb_assert (IS_ABSOLUTE_PATH (name));
if (this_real_name != NULL
- && (FILENAME_CMP (real_path, this_real_name) == 0
- || (!is_abs
- && compare_filenames_for_search (this_real_name,
- name, name_len))))
+ && FILENAME_CMP (real_path, this_real_name) == 0)
{
- if (dw2_map_expand_apply (objfile, per_cu,
- name, full_path, real_path,
+ if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
callback, data))
return 1;
+ continue;
}
}
}
@@ -2991,122 +3433,241 @@ dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
return 0;
}
-static struct symtab *
-dw2_lookup_symbol (struct objfile *objfile, int block_index,
- const char *name, domain_enum domain)
+/* Struct used to manage iterating over all CUs looking for a symbol. */
+
+struct dw2_symtab_iterator
{
- /* We do all the work in the pre_expand_symtabs_matching hook
- instead. */
- return NULL;
-}
+ /* The internalized form of .gdb_index. */
+ struct mapped_index *index;
+ /* If non-zero, only look for symbols that match BLOCK_INDEX. */
+ int want_specific_block;
+ /* One of GLOBAL_BLOCK or STATIC_BLOCK.
+ Unused if !WANT_SPECIFIC_BLOCK. */
+ int block_index;
+ /* The kind of symbol we're looking for. */
+ domain_enum domain;
+ /* The list of CUs from the index entry of the symbol,
+ or NULL if not found. */
+ offset_type *vec;
+ /* The next element in VEC to look at. */
+ int next;
+ /* The number of elements in VEC, or zero if there is no match. */
+ int length;
+ /* Have we seen a global version of the symbol?
+ If so we can ignore all further global instances.
+ This is to work around gold/15646, inefficient gold-generated
+ indices. */
+ int global_seen;
+};
-/* A helper function that expands all symtabs that hold an object
- named NAME. If WANT_SPECIFIC_BLOCK is non-zero, only look for
- symbols in block BLOCK_KIND. */
+/* Initialize the index symtab iterator ITER.
+ If WANT_SPECIFIC_BLOCK is non-zero, only look for symbols
+ in block BLOCK_INDEX. Otherwise BLOCK_INDEX is ignored. */
static void
-dw2_do_expand_symtabs_matching (struct objfile *objfile,
- int want_specific_block,
- enum block_enum block_kind,
- const char *name, domain_enum domain)
+dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
+ struct mapped_index *index,
+ int want_specific_block,
+ int block_index,
+ domain_enum domain,
+ const char *name)
+{
+ iter->index = index;
+ iter->want_specific_block = want_specific_block;
+ iter->block_index = block_index;
+ iter->domain = domain;
+ iter->next = 0;
+ iter->global_seen = 0;
+
+ if (find_slot_in_mapped_hash (index, name, &iter->vec))
+ iter->length = MAYBE_SWAP (*iter->vec);
+ else
+ {
+ iter->vec = NULL;
+ iter->length = 0;
+ }
+}
+
+/* Return the next matching CU or NULL if there are no more. */
+
+static struct dwarf2_per_cu_data *
+dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
+{
+ for ( ; iter->next < iter->length; ++iter->next)
+ {
+ offset_type cu_index_and_attrs =
+ MAYBE_SWAP (iter->vec[iter->next + 1]);
+ offset_type cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
+ struct dwarf2_per_cu_data *per_cu;
+ int want_static = iter->block_index != GLOBAL_BLOCK;
+ /* This value is only valid for index versions >= 7. */
+ int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
+ gdb_index_symbol_kind symbol_kind =
+ GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
+ /* Only check the symbol attributes if they're present.
+ Indices prior to version 7 don't record them,
+ and indices >= 7 may elide them for certain symbols
+ (gold does this). */
+ int attrs_valid =
+ (iter->index->version >= 7
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
+
+ /* Don't crash on bad data. */
+ if (cu_index >= (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_type_units))
+ {
+ complaint (&symfile_complaints,
+ _(".gdb_index entry has bad CU index"
+ " [in module %s]"),
+ objfile_name (dwarf2_per_objfile->objfile));
+ continue;
+ }
+
+ per_cu = dw2_get_cu (cu_index);
+
+ /* Skip if already read in. */
+ if (per_cu->v.quick->symtab)
+ continue;
+
+ /* Check static vs global. */
+ if (attrs_valid)
+ {
+ if (iter->want_specific_block
+ && want_static != is_static)
+ continue;
+ /* Work around gold/15646. */
+ if (!is_static && iter->global_seen)
+ continue;
+ if (!is_static)
+ iter->global_seen = 1;
+ }
+
+ /* Only check the symbol's kind if it has one. */
+ if (attrs_valid)
+ {
+ switch (iter->domain)
+ {
+ case VAR_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION
+ /* Some types are also in VAR_DOMAIN. */
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+ continue;
+ break;
+ case STRUCT_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+ continue;
+ break;
+ case LABEL_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER)
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
+
+ ++iter->next;
+ return per_cu;
+ }
+
+ return NULL;
+}
+
+static struct symtab *
+dw2_lookup_symbol (struct objfile *objfile, int block_index,
+ const char *name, domain_enum domain)
{
+ struct symtab *stab_best = NULL;
struct mapped_index *index;
dw2_setup (objfile);
index = dwarf2_per_objfile->index_table;
- /* index_table is NULL if OBJF_READNOW. */
+ /* index is NULL if OBJF_READNOW. */
if (index)
{
- offset_type *vec;
+ struct dw2_symtab_iterator iter;
+ struct dwarf2_per_cu_data *per_cu;
- if (find_slot_in_mapped_hash (index, name, &vec))
+ dw2_symtab_iter_init (&iter, index, 1, block_index, domain, name);
+
+ while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
{
- offset_type i, len = MAYBE_SWAP (*vec);
- for (i = 0; i < len; ++i)
+ struct symbol *sym = NULL;
+ struct symtab *stab = dw2_instantiate_symtab (per_cu);
+
+ /* Some caution must be observed with overloaded functions
+ and methods, since the index will not contain any overload
+ information (but NAME might contain it). */
+ if (stab->primary)
{
- offset_type cu_index_and_attrs = MAYBE_SWAP (vec[i + 1]);
- offset_type cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
- struct dwarf2_per_cu_data *per_cu = dw2_get_cu (cu_index);
- int want_static = block_kind != GLOBAL_BLOCK;
- /* This value is only valid for index versions >= 7. */
- int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
- gdb_index_symbol_kind symbol_kind =
- GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
-
- if (want_specific_block
- && index->version >= 7
- && want_static != is_static)
- continue;
+ struct blockvector *bv = BLOCKVECTOR (stab);
+ struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
- /* Only check the symbol's kind if it has one.
- Indices prior to version 7 don't record it. */
- if (index->version >= 7)
- {
- switch (domain)
- {
- case VAR_DOMAIN:
- if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE
- && symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION
- /* Some types are also in VAR_DOMAIN. */
- && symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
- continue;
- break;
- case STRUCT_DOMAIN:
- if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
- continue;
- break;
- case LABEL_DOMAIN:
- if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER)
- continue;
- break;
- default:
- break;
- }
- }
+ sym = lookup_block_symbol (block, name, domain);
+ }
- dw2_instantiate_symtab (per_cu);
+ if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
+ {
+ if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ return stab;
+
+ stab_best = stab;
}
+
+ /* Keep looking through other CUs. */
}
}
-}
-static void
-dw2_pre_expand_symtabs_matching (struct objfile *objfile,
- enum block_enum block_kind, const char *name,
- domain_enum domain)
-{
- dw2_do_expand_symtabs_matching (objfile, 1, block_kind, name, domain);
+ return stab_best;
}
static void
dw2_print_stats (struct objfile *objfile)
{
- int i, count;
+ int i, total, count;
dw2_setup (objfile);
+ total = dwarf2_per_objfile->n_comp_units + dwarf2_per_objfile->n_type_units;
count = 0;
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_units); ++i)
+ for (i = 0; i < total; ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
if (!per_cu->v.quick->symtab)
++count;
}
+ printf_filtered (_(" Number of read CUs: %d\n"), total - count);
printf_filtered (_(" Number of unread CUs: %d\n"), count);
}
+/* This dumps minimal information about the index.
+ It is called via "mt print objfiles".
+ One use is to verify .gdb_index has been loaded by the
+ gdb.dwarf2/gdb-index.exp testcase. */
+
static void
dw2_dump (struct objfile *objfile)
{
- /* Nothing worth printing. */
+ dw2_setup (objfile);
+ gdb_assert (dwarf2_per_objfile->using_index);
+ printf_filtered (".gdb_index:");
+ if (dwarf2_per_objfile->index_table != NULL)
+ {
+ printf_filtered (" version %d\n",
+ dwarf2_per_objfile->index_table->version);
+ }
+ else
+ printf_filtered (" faked for \"readnow\"\n");
+ printf_filtered ("\n");
}
static void
-dw2_relocate (struct objfile *objfile, struct section_offsets *new_offsets,
- struct section_offsets *delta)
+dw2_relocate (struct objfile *objfile,
+ const struct section_offsets *new_offsets,
+ const struct section_offsets *delta)
{
/* There's nothing to relocate here. */
}
@@ -3115,9 +3676,25 @@ static void
dw2_expand_symtabs_for_function (struct objfile *objfile,
const char *func_name)
{
- /* Note: It doesn't matter what we pass for block_kind here. */
- dw2_do_expand_symtabs_matching (objfile, 0, GLOBAL_BLOCK, func_name,
- VAR_DOMAIN);
+ struct mapped_index *index;
+
+ dw2_setup (objfile);
+
+ index = dwarf2_per_objfile->index_table;
+
+ /* index is NULL if OBJF_READNOW. */
+ if (index)
+ {
+ struct dw2_symtab_iterator iter;
+ struct dwarf2_per_cu_data *per_cu;
+
+ /* Note: It doesn't matter what we pass for block_index here. */
+ dw2_symtab_iter_init (&iter, index, 0, GLOBAL_BLOCK, VAR_DOMAIN,
+ func_name);
+
+ while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
+ dw2_instantiate_symtab (per_cu);
+ }
}
static void
@@ -3137,8 +3714,8 @@ dw2_expand_all_symtabs (struct objfile *objfile)
}
static void
-dw2_expand_symtabs_with_filename (struct objfile *objfile,
- const char *filename)
+dw2_expand_symtabs_with_fullname (struct objfile *objfile,
+ const char *fullname)
{
int i;
@@ -3159,14 +3736,15 @@ dw2_expand_symtabs_with_filename (struct objfile *objfile,
if (per_cu->v.quick->symtab)
continue;
- file_data = dw2_get_file_names (objfile, per_cu);
+ file_data = dw2_get_file_names (per_cu);
if (file_data == NULL)
continue;
for (j = 0; j < file_data->num_file_names; ++j)
{
- const char *this_name = file_data->file_names[j];
- if (FILENAME_CMP (this_name, filename) == 0)
+ const char *this_fullname = file_data->file_names[j];
+
+ if (filename_cmp (this_fullname, fullname) == 0)
{
dw2_instantiate_symtab (per_cu);
break;
@@ -3175,77 +3753,10 @@ dw2_expand_symtabs_with_filename (struct objfile *objfile,
}
}
-/* A helper function for dw2_find_symbol_file that finds the primary
- file name for a given CU. This is a die_reader_func. */
-
-static void
-dw2_get_primary_filename_reader (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- struct die_info *comp_unit_die,
- int has_children,
- void *data)
-{
- const char **result_ptr = data;
- struct dwarf2_cu *cu = reader->cu;
- struct attribute *attr;
-
- attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
- if (attr == NULL)
- *result_ptr = NULL;
- else
- *result_ptr = DW_STRING (attr);
-}
-
-static const char *
-dw2_find_symbol_file (struct objfile *objfile, const char *name)
-{
- struct dwarf2_per_cu_data *per_cu;
- offset_type *vec;
- struct quick_file_names *file_data;
- const char *filename;
-
- dw2_setup (objfile);
-
- /* index_table is NULL if OBJF_READNOW. */
- if (!dwarf2_per_objfile->index_table)
- {
- struct symtab *s;
-
- ALL_OBJFILE_PRIMARY_SYMTABS (objfile, s)
- {
- struct blockvector *bv = BLOCKVECTOR (s);
- const struct block *block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- struct symbol *sym = lookup_block_symbol (block, name, VAR_DOMAIN);
-
- if (sym)
- return sym->symtab->filename;
- }
- return NULL;
- }
-
- if (!find_slot_in_mapped_hash (dwarf2_per_objfile->index_table,
- name, &vec))
- return NULL;
-
- /* Note that this just looks at the very first one named NAME -- but
- actually we are looking for a function. find_main_filename
- should be rewritten so that it doesn't require a custom hook. It
- could just use the ordinary symbol tables. */
- /* vec[0] is the length, which must always be >0. */
- per_cu = dw2_get_cu (GDB_INDEX_CU_VALUE (MAYBE_SWAP (vec[1])));
-
- if (per_cu->v.quick->symtab != NULL)
- return per_cu->v.quick->symtab->filename;
-
- init_cutu_and_read_dies (per_cu, NULL, 0, 0,
- dw2_get_primary_filename_reader, &filename);
-
- return filename;
-}
-
static void
-dw2_map_matching_symbols (const char * name, domain_enum namespace,
- struct objfile *objfile, int global,
+dw2_map_matching_symbols (struct objfile *objfile,
+ const char * name, domain_enum namespace,
+ int global,
int (*callback) (struct block *,
struct symbol *, void *),
void *data, symbol_compare_ftype *match,
@@ -3259,7 +3770,7 @@ 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 (*file_matcher) (const char *, void *, int basenames),
int (*name_matcher) (const char *, void *),
enum search_domain kind,
void *data)
@@ -3280,8 +3791,6 @@ dw2_expand_symtabs_matching
struct cleanup *cleanup;
htab_t visited_found, visited_not_found;
- dw2_build_type_unit_groups ();
-
visited_found = htab_create_alloc (10,
htab_hash_pointer, htab_eq_pointer,
NULL, xcalloc, xfree);
@@ -3291,8 +3800,10 @@ dw2_expand_symtabs_matching
NULL, xcalloc, xfree);
make_cleanup_htab_delete (visited_not_found);
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_unit_groups); ++i)
+ /* The rule is CUs specify all the files, including those used by
+ any TU, so there's no need to scan TUs here. */
+
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i);
@@ -3305,7 +3816,7 @@ dw2_expand_symtabs_matching
if (per_cu->v.quick->symtab)
continue;
- file_data = dw2_get_file_names (objfile, per_cu);
+ file_data = dw2_get_file_names (per_cu);
if (file_data == NULL)
continue;
@@ -3319,7 +3830,23 @@ dw2_expand_symtabs_matching
for (j = 0; j < file_data->num_file_names; ++j)
{
- if (file_matcher (file_data->file_names[j], data))
+ const char *this_real_name;
+
+ if (file_matcher (file_data->file_names[j], data, 0))
+ {
+ per_cu->v.quick->mark = 1;
+ break;
+ }
+
+ /* Before we invoke realpath, which can get expensive when many
+ files are involved, do a quick comparison of the basenames. */
+ if (!basenames_may_differ
+ && !file_matcher (lbasename (file_data->file_names[j]),
+ data, 1))
+ continue;
+
+ this_real_name = dw2_get_real_path (objfile, file_data, j);
+ if (file_matcher (this_real_name, data, 0))
{
per_cu->v.quick->mark = 1;
break;
@@ -3341,6 +3868,7 @@ dw2_expand_symtabs_matching
offset_type idx = 2 * iter;
const char *name;
offset_type *vec, vec_len, vec_idx;
+ int global_seen = 0;
if (index->symbol_table[idx] == 0 && index->symbol_table[idx + 1] == 0)
continue;
@@ -3359,18 +3887,30 @@ dw2_expand_symtabs_matching
{
struct dwarf2_per_cu_data *per_cu;
offset_type cu_index_and_attrs = MAYBE_SWAP (vec[vec_idx + 1]);
+ /* This value is only valid for index versions >= 7. */
+ int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
gdb_index_symbol_kind symbol_kind =
GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
int cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
+ /* Only check the symbol attributes if they're present.
+ Indices prior to version 7 don't record them,
+ and indices >= 7 may elide them for certain symbols
+ (gold does this). */
+ int attrs_valid =
+ (index->version >= 7
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
+
+ /* Work around gold/15646. */
+ if (attrs_valid)
+ {
+ if (!is_static && global_seen)
+ continue;
+ if (!is_static)
+ global_seen = 1;
+ }
- /* Don't crash on bad data. */
- if (cu_index >= (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_units))
- continue;
-
- /* Only check the symbol's kind if it has one.
- Indices prior to version 7 don't record it. */
- if (index->version >= 7)
+ /* Only check the symbol's kind if it has one. */
+ if (attrs_valid)
{
switch (kind)
{
@@ -3391,6 +3931,16 @@ dw2_expand_symtabs_matching
}
}
+ /* Don't crash on bad data. */
+ if (cu_index >= (dwarf2_per_objfile->n_comp_units
+ + dwarf2_per_objfile->n_type_units))
+ {
+ complaint (&symfile_complaints,
+ _(".gdb_index entry has bad CU index"
+ " [in module %s]"), objfile_name (objfile));
+ continue;
+ }
+
per_cu = dw2_get_cu (cu_index);
if (file_matcher == NULL || per_cu->v.quick->mark)
dw2_instantiate_symtab (per_cu);
@@ -3465,11 +4015,11 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
cleanup = make_cleanup_htab_delete (visited);
dw2_setup (objfile);
- dw2_build_type_unit_groups ();
+ /* The rule is CUs specify all the files, including those used by
+ any TU, so there's no need to scan TUs here.
+ We can ignore file names coming from already-expanded CUs. */
- /* 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)
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
@@ -3482,8 +4032,7 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
}
}
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_unit_groups); ++i)
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i);
@@ -3494,7 +4043,7 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
if (per_cu->v.quick->symtab)
continue;
- file_data = dw2_get_file_names (objfile, per_cu);
+ file_data = dw2_get_file_names (per_cu);
if (file_data == NULL)
continue;
@@ -3534,14 +4083,12 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions =
dw2_forget_cached_source_info,
dw2_map_symtabs_matching_filename,
dw2_lookup_symbol,
- dw2_pre_expand_symtabs_matching,
dw2_print_stats,
dw2_dump,
dw2_relocate,
dw2_expand_symtabs_for_function,
dw2_expand_all_symtabs,
- dw2_expand_symtabs_with_filename,
- dw2_find_symbol_file,
+ dw2_expand_symtabs_with_fullname,
dw2_map_matching_symbols,
dw2_expand_symtabs_matching,
dw2_find_pc_sect_symtab,
@@ -3596,12 +4143,25 @@ dwarf2_initialize_objfile (struct objfile *objfile)
void
dwarf2_build_psymtabs (struct objfile *objfile)
{
+ volatile struct gdb_exception except;
+
if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)
{
init_psymbol_list (objfile, 1024);
}
- dwarf2_build_psymtabs_hard (objfile);
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ /* This isn't really ideal: all the data we allocate on the
+ objfile's obstack is still uselessly kept around. However,
+ freeing it seems unsafe. */
+ struct cleanup *cleanups = make_cleanup_discard_psymtabs (objfile);
+
+ dwarf2_build_psymtabs_hard (objfile);
+ discard_cleanups (cleanups);
+ }
+ if (except.reason < 0)
+ exception_print (gdb_stderr, except);
}
/* Return the total length of the CU described by HEADER. */
@@ -3658,9 +4218,9 @@ dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
NOTE: This leaves members offset, first_die_offset to be filled in
by the caller. */
-static gdb_byte *
+static const gdb_byte *
read_comp_unit_head (struct comp_unit_head *cu_header,
- gdb_byte *info_ptr, bfd *abfd)
+ const gdb_byte *info_ptr, bfd *abfd)
{
int signed_addr;
unsigned int bytes_read;
@@ -3685,6 +4245,22 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
return info_ptr;
}
+/* Helper function that returns the proper abbrev section for
+ THIS_CU. */
+
+static struct dwarf2_section_info *
+get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
+{
+ struct dwarf2_section_info *abbrev;
+
+ if (this_cu->is_dwz)
+ abbrev = &dwarf2_get_dwz_file ()->abbrev;
+ else
+ abbrev = &dwarf2_per_objfile->abbrev;
+
+ return abbrev;
+}
+
/* 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. */
@@ -3694,8 +4270,8 @@ error_check_comp_unit_head (struct comp_unit_head *header,
struct dwarf2_section_info *section,
struct dwarf2_section_info *abbrev_section)
{
- bfd *abfd = section->asection->owner;
- const char *filename = bfd_get_filename (abfd);
+ bfd *abfd = get_section_bfd_owner (section);
+ const char *filename = get_section_file_name (section);
if (header->version != 2 && header->version != 3 && header->version != 4)
error (_("Dwarf Error: wrong version in compilation unit header "
@@ -3703,8 +4279,7 @@ error_check_comp_unit_head (struct comp_unit_head *header,
filename);
if (header->abbrev_offset.sect_off
- >= dwarf2_section_size (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->abbrev))
+ >= dwarf2_section_size (dwarf2_per_objfile->objfile, abbrev_section))
error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
"(offset 0x%lx + 6) [in module %s]"),
(long) header->abbrev_offset.sect_off, (long) header->offset.sect_off,
@@ -3724,15 +4299,15 @@ error_check_comp_unit_head (struct comp_unit_head *header,
The contents of the header are stored in HEADER.
The result is a pointer to the start of the first DIE. */
-static gdb_byte *
+static const gdb_byte *
read_and_check_comp_unit_head (struct comp_unit_head *header,
struct dwarf2_section_info *section,
struct dwarf2_section_info *abbrev_section,
- gdb_byte *info_ptr,
+ const gdb_byte *info_ptr,
int is_debug_types_section)
{
- gdb_byte *beg_of_comp_unit = info_ptr;
- bfd *abfd = section->asection->owner;
+ const gdb_byte *beg_of_comp_unit = info_ptr;
+ bfd *abfd = get_section_bfd_owner (section);
header->offset.sect_off = beg_of_comp_unit - section->buffer;
@@ -3753,16 +4328,16 @@ read_and_check_comp_unit_head (struct comp_unit_head *header,
/* Read in the types comp unit header information from .debug_types entry at
types_ptr. The result is a pointer to one past the end of the header. */
-static gdb_byte *
+static const gdb_byte *
read_and_check_type_unit_head (struct comp_unit_head *header,
struct dwarf2_section_info *section,
struct dwarf2_section_info *abbrev_section,
- gdb_byte *info_ptr,
+ const gdb_byte *info_ptr,
ULONGEST *signature,
cu_offset *type_offset_in_tu)
{
- gdb_byte *beg_of_comp_unit = info_ptr;
- bfd *abfd = section->asection->owner;
+ const gdb_byte *beg_of_comp_unit = info_ptr;
+ bfd *abfd = get_section_bfd_owner (section);
header->offset.sect_off = beg_of_comp_unit - section->buffer;
@@ -3791,8 +4366,8 @@ static sect_offset
read_abbrev_offset (struct dwarf2_section_info *section,
sect_offset offset)
{
- bfd *abfd = section->asection->owner;
- gdb_byte *info_ptr;
+ bfd *abfd = get_section_bfd_owner (section);
+ const gdb_byte *info_ptr;
unsigned int length, initial_length_size, offset_size;
sect_offset abbrev_offset;
@@ -3809,11 +4384,17 @@ read_abbrev_offset (struct dwarf2_section_info *section,
partial symtab as being an include of PST. */
static void
-dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst,
+dwarf2_create_include_psymtab (const char *name, struct partial_symtab *pst,
struct objfile *objfile)
{
struct partial_symtab *subpst = allocate_psymtab (name, objfile);
+ if (!IS_ABSOLUTE_PATH (subpst->filename))
+ {
+ /* It shares objfile->objfile_obstack. */
+ subpst->dirname = pst->dirname;
+ }
+
subpst->section_offsets = pst->section_offsets;
subpst->textlow = 0;
subpst->texthigh = 0;
@@ -3908,10 +4489,14 @@ add_signatured_type_cu_to_table (void **slot, void *datum)
return 1;
}
-/* Create the hash table of all entries in the .debug_types section.
- 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. */
+/* Create the hash table of all entries in the .debug_types
+ (or .debug_types.dwo) section(s).
+ If reading a DWO file, then DWO_FILE is a pointer to the DWO file object,
+ otherwise it is NULL.
+
+ The result is a pointer to the hash table or NULL if there are no types.
+
+ Note: This function processes DWO files only, not DWP files. */
static htab_t
create_debug_types_hash_table (struct dwo_file *dwo_file,
@@ -3933,14 +4518,14 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
if (dwarf2_read_debug)
fprintf_unfiltered (gdb_stdlog, "Reading .debug_types%s for %s:\n",
dwo_file ? ".dwo" : "",
- bfd_get_filename (abbrev_section->asection->owner));
+ get_section_file_name (abbrev_section));
for (ix = 0;
VEC_iterate (dwarf2_section_info_def, types, ix, section);
++ix)
{
bfd *abfd;
- gdb_byte *info_ptr, *end_ptr;
+ const gdb_byte *info_ptr, *end_ptr;
dwarf2_read_section (objfile, section);
info_ptr = section->buffer;
@@ -3949,16 +4534,8 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
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)
- {
- if (dwo_file)
- types_htab = allocate_dwo_unit_table (objfile);
- else
- types_htab = allocate_signatured_type_table (objfile);
- }
+ not present, in which case the bfd is unknown. */
+ abfd = get_section_bfd_owner (section);
/* 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
@@ -3973,7 +4550,7 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
struct signatured_type *sig_type;
struct dwo_unit *dwo_tu;
void **slot;
- gdb_byte *ptr = info_ptr;
+ const gdb_byte *ptr = info_ptr;
struct comp_unit_head header;
unsigned int length;
@@ -3996,6 +4573,14 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
continue;
}
+ if (types_htab == NULL)
+ {
+ if (dwo_file)
+ types_htab = allocate_dwo_unit_table (objfile);
+ else
+ types_htab = allocate_signatured_type_table (objfile);
+ }
+
if (dwo_file)
{
sig_type = NULL;
@@ -4004,7 +4589,7 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
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->section = section;
dwo_tu->offset = offset;
dwo_tu->length = length;
}
@@ -4019,7 +4604,7 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
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.section = section;
sig_type->per_cu.offset = offset;
sig_type->per_cu.length = length;
}
@@ -4046,17 +4631,17 @@ create_debug_types_hash_table (struct dwo_file *dwo_file,
}
complaint (&symfile_complaints,
- _("debug type entry at offset 0x%x is duplicate to the "
- "entry at offset 0x%x, signature 0x%s"),
+ _("debug type entry at offset 0x%x is duplicate to"
+ " the entry at offset 0x%x, signature %s"),
offset.sect_off, dup_offset.sect_off,
- phex (signature, sizeof (signature)));
+ hex_string (signature));
}
*slot = dwo_file ? (void *) dwo_tu : (void *) sig_type;
- if (dwarf2_read_debug)
- fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature 0x%s\n",
+ if (dwarf2_read_debug > 1)
+ fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature %s\n",
offset.sect_off,
- phex (signature, sizeof (signature)));
+ hex_string (signature));
info_ptr += length;
}
@@ -4087,9 +4672,8 @@ create_all_type_units (struct objfile *objfile)
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_units
- * sizeof (struct signatured_type *));
+ = xmalloc (dwarf2_per_objfile->n_type_units
+ * sizeof (struct signatured_type *));
iter = &dwarf2_per_objfile->all_type_units[0];
htab_traverse_noresize (types_htab, add_signatured_type_cu_to_table, &iter);
gdb_assert (iter - &dwarf2_per_objfile->all_type_units[0]
@@ -4098,24 +4682,205 @@ create_all_type_units (struct objfile *objfile)
return 1;
}
-/* Lookup a signature based type for DW_FORM_ref_sig8.
- Returns NULL if signature SIG is not present in the table. */
+/* Subroutine of lookup_dwo_signatured_type and lookup_dwp_signatured_type.
+ Fill in SIG_ENTRY with DWO_ENTRY. */
+
+static void
+fill_in_sig_entry_from_dwo_entry (struct objfile *objfile,
+ struct signatured_type *sig_entry,
+ struct dwo_unit *dwo_entry)
+{
+ /* Make sure we're not clobbering something we don't expect to. */
+ gdb_assert (! sig_entry->per_cu.queued);
+ gdb_assert (sig_entry->per_cu.cu == NULL);
+ gdb_assert (sig_entry->per_cu.v.quick != NULL);
+ gdb_assert (sig_entry->per_cu.v.quick->symtab == NULL);
+ gdb_assert (sig_entry->signature == dwo_entry->signature);
+ gdb_assert (sig_entry->type_offset_in_section.sect_off == 0);
+ gdb_assert (sig_entry->type_unit_group == NULL);
+ gdb_assert (sig_entry->dwo_unit == NULL);
+
+ sig_entry->per_cu.section = dwo_entry->section;
+ sig_entry->per_cu.offset = dwo_entry->offset;
+ sig_entry->per_cu.length = dwo_entry->length;
+ sig_entry->per_cu.reading_dwo_directly = 1;
+ sig_entry->per_cu.objfile = objfile;
+ sig_entry->type_offset_in_tu = dwo_entry->type_offset_in_tu;
+ sig_entry->dwo_unit = dwo_entry;
+}
+
+/* Subroutine of lookup_signatured_type.
+ If we haven't read the TU yet, create the signatured_type data structure
+ for a TU to be read in directly from a DWO file, bypassing the stub.
+ This is the "Stay in DWO Optimization": When there is no DWP file and we're
+ using .gdb_index, then when reading a CU we want to stay in the DWO file
+ containing that CU. Otherwise we could end up reading several other DWO
+ files (due to comdat folding) to process the transitive closure of all the
+ mentioned TUs, and that can be slow. The current DWO file will have every
+ type signature that it needs.
+ We only do this for .gdb_index because in the psymtab case we already have
+ to read all the DWOs to build the type unit groups. */
static struct signatured_type *
-lookup_signatured_type (ULONGEST sig)
+lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
{
- struct signatured_type find_entry, *entry;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwo_file *dwo_file;
+ struct dwo_unit find_dwo_entry, *dwo_entry;
+ struct signatured_type find_sig_entry, *sig_entry;
+
+ gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index);
+
+ /* Note: cu->dwo_unit is the dwo_unit that references this TU, not the
+ dwo_unit of the TU itself. */
+ dwo_file = cu->dwo_unit->dwo_file;
+
+ /* We only ever need to read in one copy of a signatured type.
+ Just use the global signatured_types array. If this is the first time
+ we're reading this type, replace the recorded data from .gdb_index with
+ this TU. */
if (dwarf2_per_objfile->signatured_types == NULL)
+ return NULL;
+ find_sig_entry.signature = sig;
+ sig_entry = htab_find (dwarf2_per_objfile->signatured_types, &find_sig_entry);
+ if (sig_entry == NULL)
+ return NULL;
+
+ /* We can get here with the TU already read, *or* in the process of being
+ read. Don't reassign it if that's the case. Also note that if the TU is
+ already being read, it may not have come from a DWO, the program may be
+ a mix of Fission-compiled code and non-Fission-compiled code. */
+ /* Have we already tried to read this TU? */
+ if (sig_entry->per_cu.tu_read)
+ return sig_entry;
+
+ /* Ok, this is the first time we're reading this TU. */
+ if (dwo_file->tus == NULL)
+ return NULL;
+ find_dwo_entry.signature = sig;
+ dwo_entry = htab_find (dwo_file->tus, &find_dwo_entry);
+ if (dwo_entry == NULL)
+ return NULL;
+
+ fill_in_sig_entry_from_dwo_entry (objfile, sig_entry, dwo_entry);
+ sig_entry->per_cu.tu_read = 1;
+ return sig_entry;
+}
+
+/* Subroutine of lookup_dwp_signatured_type.
+ Add an entry for signature SIG to dwarf2_per_objfile->signatured_types. */
+
+static struct signatured_type *
+add_type_unit (ULONGEST sig)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ int n_type_units = dwarf2_per_objfile->n_type_units;
+ struct signatured_type *sig_type;
+ void **slot;
+
+ ++n_type_units;
+ dwarf2_per_objfile->all_type_units =
+ xrealloc (dwarf2_per_objfile->all_type_units,
+ n_type_units * sizeof (struct signatured_type *));
+ dwarf2_per_objfile->n_type_units = n_type_units;
+ sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct signatured_type);
+ dwarf2_per_objfile->all_type_units[n_type_units - 1] = sig_type;
+ sig_type->signature = sig;
+ sig_type->per_cu.is_debug_types = 1;
+ sig_type->per_cu.v.quick =
+ OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwarf2_per_cu_quick_data);
+ slot = htab_find_slot (dwarf2_per_objfile->signatured_types,
+ sig_type, INSERT);
+ gdb_assert (*slot == NULL);
+ *slot = sig_type;
+ /* The rest of sig_type must be filled in by the caller. */
+ return sig_type;
+}
+
+/* Subroutine of lookup_signatured_type.
+ Look up the type for signature SIG, and if we can't find SIG in .gdb_index
+ then try the DWP file.
+ Normally this "can't happen", but if there's a bug in signature
+ generation and/or the DWP file is built incorrectly, it can happen.
+ Using the type directly from the DWP file means we don't have the stub
+ which has some useful attributes (e.g., DW_AT_comp_dir), but they're
+ not critical. [Eventually the stub may go away for type units anyway.] */
+
+static struct signatured_type *
+lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwp_file *dwp_file = get_dwp_file ();
+ struct dwo_unit *dwo_entry;
+ struct signatured_type find_sig_entry, *sig_entry;
+
+ gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index);
+ gdb_assert (dwp_file != NULL);
+
+ if (dwarf2_per_objfile->signatured_types != NULL)
{
- complaint (&symfile_complaints,
- _("missing `.debug_types' section for DW_FORM_ref_sig8 die"));
- return NULL;
+ find_sig_entry.signature = sig;
+ sig_entry = htab_find (dwarf2_per_objfile->signatured_types,
+ &find_sig_entry);
+ if (sig_entry != NULL)
+ return sig_entry;
+ }
+
+ /* This is the "shouldn't happen" case.
+ Try the DWP file and hope for the best. */
+ if (dwp_file->tus == NULL)
+ return NULL;
+ dwo_entry = lookup_dwo_unit_in_dwp (dwp_file, NULL,
+ sig, 1 /* is_debug_types */);
+ if (dwo_entry == NULL)
+ return NULL;
+
+ sig_entry = add_type_unit (sig);
+ fill_in_sig_entry_from_dwo_entry (objfile, sig_entry, dwo_entry);
+
+ /* The caller will signal a complaint if we return NULL.
+ Here we don't return NULL but we still want to complain. */
+ complaint (&symfile_complaints,
+ _("Bad type signature %s referenced by %s at 0x%x,"
+ " coping by using copy in DWP [in module %s]"),
+ hex_string (sig),
+ cu->per_cu->is_debug_types ? "TU" : "CU",
+ cu->per_cu->offset.sect_off,
+ objfile_name (objfile));
+
+ return sig_entry;
+}
+
+/* Lookup a signature based type for DW_FORM_ref_sig8.
+ Returns NULL if signature SIG is not present in the table.
+ It is up to the caller to complain about this. */
+
+static struct signatured_type *
+lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
+{
+ if (cu->dwo_unit
+ && dwarf2_per_objfile->using_index)
+ {
+ /* We're in a DWO/DWP file, and we're using .gdb_index.
+ These cases require special processing. */
+ if (get_dwp_file () == NULL)
+ return lookup_dwo_signatured_type (cu, sig);
+ else
+ return lookup_dwp_signatured_type (cu, sig);
}
+ else
+ {
+ struct signatured_type find_entry, *entry;
- find_entry.signature = sig;
- entry = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
- return entry;
+ if (dwarf2_per_objfile->signatured_types == NULL)
+ return NULL;
+ find_entry.signature = sig;
+ entry = htab_find (dwarf2_per_objfile->signatured_types, &find_entry);
+ return entry;
+ }
}
/* Low level DIE reading support. */
@@ -4129,12 +4894,349 @@ init_cu_die_reader (struct die_reader_specs *reader,
struct dwo_file *dwo_file)
{
gdb_assert (section->readin && section->buffer != NULL);
- reader->abfd = section->asection->owner;
+ reader->abfd = get_section_bfd_owner (section);
reader->cu = cu;
reader->dwo_file = dwo_file;
reader->die_section = section;
reader->buffer = section->buffer;
reader->buffer_end = section->buffer + section->size;
+ reader->comp_dir = NULL;
+}
+
+/* Subroutine of init_cutu_and_read_dies to simplify it.
+ Read in the rest of a CU/TU top level DIE from DWO_UNIT.
+ There's just a lot of work to do, and init_cutu_and_read_dies is big enough
+ already.
+
+ STUB_COMP_UNIT_DIE is for the stub DIE, we copy over certain attributes
+ from it to the DIE in the DWO. If NULL we are skipping the stub.
+ STUB_COMP_DIR is similar to STUB_COMP_UNIT_DIE: When reading a TU directly
+ from the DWO file, bypassing the stub, it contains the DW_AT_comp_dir
+ attribute of the referencing CU. Exactly one of STUB_COMP_UNIT_DIE and
+ COMP_DIR must be non-NULL.
+ *RESULT_READER,*RESULT_INFO_PTR,*RESULT_COMP_UNIT_DIE,*RESULT_HAS_CHILDREN
+ are filled in with the info of the DIE from the DWO file.
+ ABBREV_TABLE_PROVIDED is non-zero if the caller of init_cutu_and_read_dies
+ provided an abbrev table to use.
+ The result is non-zero if a valid (non-dummy) DIE was found. */
+
+static int
+read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
+ struct dwo_unit *dwo_unit,
+ int abbrev_table_provided,
+ struct die_info *stub_comp_unit_die,
+ const char *stub_comp_dir,
+ struct die_reader_specs *result_reader,
+ const gdb_byte **result_info_ptr,
+ struct die_info **result_comp_unit_die,
+ int *result_has_children)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_cu *cu = this_cu->cu;
+ struct dwarf2_section_info *section;
+ bfd *abfd;
+ const gdb_byte *begin_info_ptr, *info_ptr;
+ const char *comp_dir_string;
+ ULONGEST signature; /* Or dwo_id. */
+ struct attribute *comp_dir, *stmt_list, *low_pc, *high_pc, *ranges;
+ int i,num_extra_attrs;
+ struct dwarf2_section_info *dwo_abbrev_section;
+ struct attribute *attr;
+ struct attribute comp_dir_attr;
+ struct die_info *comp_unit_die;
+
+ /* Both can't be provided. */
+ gdb_assert (! (stub_comp_unit_die && stub_comp_dir));
+
+ /* 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 = NULL;
+ low_pc = NULL;
+ high_pc = NULL;
+ ranges = NULL;
+ comp_dir = NULL;
+
+ if (stub_comp_unit_die != 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 (stub_comp_unit_die, DW_AT_stmt_list, cu);
+ low_pc = dwarf2_attr (stub_comp_unit_die, DW_AT_low_pc, cu);
+ high_pc = dwarf2_attr (stub_comp_unit_die, DW_AT_high_pc, cu);
+ ranges = dwarf2_attr (stub_comp_unit_die, DW_AT_ranges, cu);
+ comp_dir = dwarf2_attr (stub_comp_unit_die, DW_AT_comp_dir, cu);
+
+ /* There should be a DW_AT_addr_base attribute here (if needed).
+ We need the value before we can process DW_FORM_GNU_addr_index. */
+ cu->addr_base = 0;
+ attr = dwarf2_attr (stub_comp_unit_die, DW_AT_GNU_addr_base, cu);
+ if (attr)
+ cu->addr_base = DW_UNSND (attr);
+
+ /* There should be a DW_AT_ranges_base attribute here (if needed).
+ We need the value before we can process DW_AT_ranges. */
+ cu->ranges_base = 0;
+ attr = dwarf2_attr (stub_comp_unit_die, DW_AT_GNU_ranges_base, cu);
+ if (attr)
+ cu->ranges_base = DW_UNSND (attr);
+ }
+ else if (stub_comp_dir != NULL)
+ {
+ /* Reconstruct the comp_dir attribute to simplify the code below. */
+ comp_dir = (struct attribute *)
+ obstack_alloc (&cu->comp_unit_obstack, sizeof (*comp_dir));
+ comp_dir->name = DW_AT_comp_dir;
+ comp_dir->form = DW_FORM_string;
+ DW_STRING_IS_CANONICAL (comp_dir) = 0;
+ DW_STRING (comp_dir) = stub_comp_dir;
+ }
+
+ /* Set up for reading the DWO CU/TU. */
+ cu->dwo_unit = dwo_unit;
+ section = dwo_unit->section;
+ dwarf2_read_section (objfile, section);
+ abfd = get_section_bfd_owner (section);
+ begin_info_ptr = info_ptr = section->buffer + dwo_unit->offset.sect_off;
+ dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
+ init_cu_die_reader (result_reader, cu, section, dwo_unit->dwo_file);
+
+ if (this_cu->is_debug_types)
+ {
+ ULONGEST header_signature;
+ cu_offset type_offset_in_tu;
+ struct signatured_type *sig_type = (struct signatured_type *) this_cu;
+
+ info_ptr = read_and_check_type_unit_head (&cu->header, section,
+ dwo_abbrev_section,
+ info_ptr,
+ &header_signature,
+ &type_offset_in_tu);
+ /* This is not an assert because it can be caused by bad debug info. */
+ if (sig_type->signature != header_signature)
+ {
+ error (_("Dwarf Error: signature mismatch %s vs %s while reading"
+ " TU at offset 0x%x [in module %s]"),
+ hex_string (sig_type->signature),
+ hex_string (header_signature),
+ dwo_unit->offset.sect_off,
+ bfd_get_filename (abfd));
+ }
+ gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+ /* For DWOs coming from DWP files, we don't know the CU length
+ nor the type's offset in the TU until now. */
+ dwo_unit->length = get_cu_length (&cu->header);
+ dwo_unit->type_offset_in_tu = type_offset_in_tu;
+
+ /* Establish the type offset that can be used to lookup the type.
+ For DWO files, we don't know it until now. */
+ sig_type->type_offset_in_section.sect_off =
+ dwo_unit->offset.sect_off + dwo_unit->type_offset_in_tu.cu_off;
+ }
+ else
+ {
+ info_ptr = read_and_check_comp_unit_head (&cu->header, section,
+ dwo_abbrev_section,
+ info_ptr, 0);
+ gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+ /* For DWOs coming from DWP files, we don't know the CU length
+ until now. */
+ dwo_unit->length = get_cu_length (&cu->header);
+ }
+
+ /* Replace the CU's original abbrev table with the DWO's.
+ Reminder: We can't read the abbrev table until we've read the header. */
+ if (abbrev_table_provided)
+ {
+ /* Don't free the provided abbrev table, the caller of
+ init_cutu_and_read_dies owns it. */
+ dwarf2_read_abbrevs (cu, dwo_abbrev_section);
+ /* Ensure the DWO abbrev table gets freed. */
+ make_cleanup (dwarf2_free_abbrev_table, cu);
+ }
+ else
+ {
+ dwarf2_free_abbrev_table (cu);
+ dwarf2_read_abbrevs (cu, dwo_abbrev_section);
+ /* Leave any existing abbrev table cleanup as is. */
+ }
+
+ /* 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 work to maintain the illusion of a single
+ DW_TAG_{compile,type}_unit DIE is done here. */
+ num_extra_attrs = ((stmt_list != NULL)
+ + (low_pc != NULL)
+ + (high_pc != NULL)
+ + (ranges != NULL)
+ + (comp_dir != NULL));
+ info_ptr = read_full_die_1 (result_reader, result_comp_unit_die, info_ptr,
+ result_has_children, num_extra_attrs);
+
+ /* Copy over the attributes from the stub to the DIE we just read in. */
+ comp_unit_die = *result_comp_unit_die;
+ i = comp_unit_die->num_attrs;
+ if (stmt_list != NULL)
+ comp_unit_die->attrs[i++] = *stmt_list;
+ if (low_pc != NULL)
+ comp_unit_die->attrs[i++] = *low_pc;
+ if (high_pc != NULL)
+ comp_unit_die->attrs[i++] = *high_pc;
+ if (ranges != NULL)
+ comp_unit_die->attrs[i++] = *ranges;
+ if (comp_dir != NULL)
+ comp_unit_die->attrs[i++] = *comp_dir;
+ comp_unit_die->num_attrs += num_extra_attrs;
+
+ if (dwarf2_die_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Read die from %s@0x%x of %s:\n",
+ get_section_name (section),
+ (unsigned) (begin_info_ptr - section->buffer),
+ bfd_get_filename (abfd));
+ dump_die (comp_unit_die, dwarf2_die_debug);
+ }
+
+ /* Save the comp_dir attribute. If there is no DWP file then we'll read
+ TUs by skipping the stub and going directly to the entry in the DWO file.
+ However, skipping the stub means we won't get DW_AT_comp_dir, so we have
+ to get it via circuitous means. Blech. */
+ if (comp_dir != NULL)
+ result_reader->comp_dir = DW_STRING (comp_dir);
+
+ /* Skip dummy compilation units. */
+ if (info_ptr >= begin_info_ptr + dwo_unit->length
+ || peek_abbrev_code (abfd, info_ptr) == 0)
+ return 0;
+
+ *result_info_ptr = info_ptr;
+ return 1;
+}
+
+/* Subroutine of init_cutu_and_read_dies to simplify it.
+ Look up the DWO unit specified by COMP_UNIT_DIE of THIS_CU.
+ Returns NULL if the specified DWO unit cannot be found. */
+
+static struct dwo_unit *
+lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
+ struct die_info *comp_unit_die)
+{
+ struct dwarf2_cu *cu = this_cu->cu;
+ struct attribute *attr;
+ ULONGEST signature;
+ struct dwo_unit *dwo_unit;
+ const char *comp_dir, *dwo_name;
+
+ gdb_assert (cu != NULL);
+
+ /* Yeah, we look dwo_name up again, but it simplifies the code. */
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu);
+ gdb_assert (attr != NULL);
+ dwo_name = DW_STRING (attr);
+ 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)
+ {
+ struct signatured_type *sig_type;
+
+ /* Since this_cu is the first member of struct signatured_type,
+ we can go from a pointer to one to a pointer to the other. */
+ sig_type = (struct signatured_type *) this_cu;
+ signature = sig_type->signature;
+ dwo_unit = lookup_dwo_type_unit (sig_type, dwo_name, comp_dir);
+ }
+ else
+ {
+ struct attribute *attr;
+
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu);
+ if (! attr)
+ error (_("Dwarf Error: missing dwo_id for dwo_name %s"
+ " [in module %s]"),
+ dwo_name, objfile_name (this_cu->objfile));
+ signature = DW_UNSND (attr);
+ dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir,
+ signature);
+ }
+
+ return dwo_unit;
+}
+
+/* Subroutine of init_cutu_and_read_dies to simplify it.
+ Read a TU directly from a DWO file, bypassing the stub. */
+
+static void
+init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu, int keep,
+ die_reader_func_ftype *die_reader_func,
+ void *data)
+{
+ struct dwarf2_cu *cu;
+ struct signatured_type *sig_type;
+ struct cleanup *cleanups, *free_cu_cleanup;
+ struct die_reader_specs reader;
+ const gdb_byte *info_ptr;
+ struct die_info *comp_unit_die;
+ int has_children;
+
+ /* Verify we can do the following downcast, and that we have the
+ data we need. */
+ gdb_assert (this_cu->is_debug_types && this_cu->reading_dwo_directly);
+ sig_type = (struct signatured_type *) this_cu;
+ gdb_assert (sig_type->dwo_unit != NULL);
+
+ cleanups = make_cleanup (null_cleanup, 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 (read_cutu_die_from_dwo (this_cu, sig_type->dwo_unit,
+ 0 /* abbrev_table_provided */,
+ NULL /* stub_comp_unit_die */,
+ sig_type->dwo_unit->dwo_file->comp_dir,
+ &reader, &info_ptr,
+ &comp_unit_die, &has_children) == 0)
+ {
+ /* Dummy die. */
+ do_cleanups (cleanups);
+ return;
+ }
+
+ /* All the "real" work is done here. */
+ die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
+
+ /* This duplicates some code in init_cutu_and_read_dies,
+ but the alternative is making the latter more complex.
+ This function is only for the special case of using DWO files directly:
+ no point in overly complicating the general case just to handle this. */
+ 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);
}
/* Initialize a CU (or TU) and read its DIEs.
@@ -4161,10 +5263,10 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
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_section_info *section = this_cu->section;
+ bfd *abfd = get_section_bfd_owner (section);
struct dwarf2_cu *cu;
- gdb_byte *begin_info_ptr, *info_ptr;
+ const gdb_byte *begin_info_ptr, *info_ptr;
struct die_reader_specs reader;
struct die_info *comp_unit_die;
int has_children;
@@ -4174,7 +5276,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
struct dwarf2_section_info *abbrev_section;
/* Non-zero if CU currently points to a DWO file and we need to
reread it. When this happens we need to reread the skeleton die
- before we can reread the DWO file. */
+ before we can reread the DWO file (this only applies to CUs, not TUs). */
int rereading_dwo_cu = 0;
if (dwarf2_die_debug)
@@ -4185,13 +5287,26 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
if (use_existing_cu)
gdb_assert (keep);
+ /* If we're reading a TU directly from a DWO file, including a virtual DWO
+ file (instead of going through the stub), short-circuit all of this. */
+ if (this_cu->reading_dwo_directly)
+ {
+ /* Narrow down the scope of possibilities to have to understand. */
+ gdb_assert (this_cu->is_debug_types);
+ gdb_assert (abbrev_table == NULL);
+ gdb_assert (!use_existing_cu);
+ init_tu_and_read_dwo_dies (this_cu, keep, die_reader_func, data);
+ return;
+ }
+
cleanups = make_cleanup (null_cleanup, NULL);
/* This is cheap if the section is already read in. */
dwarf2_read_section (objfile, section);
begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
- abbrev_section = &dwarf2_per_objfile->abbrev;
+
+ abbrev_section = get_abbrev_section_for_cu (this_cu);
if (use_existing_cu && this_cu->cu != NULL)
{
@@ -4218,6 +5333,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu);
}
+ /* Get the header. */
if (cu->header.first_die_offset.cu_off != 0 && ! rereading_dwo_cu)
{
/* We already have the header, there's no need to read it in again. */
@@ -4297,170 +5413,52 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
init_cu_die_reader (&reader, cu, section, NULL);
info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
- /* If we have a DWO stub, process it and then read in the DWO file.
- Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains
- a DWO CU, that this test will fail. */
+ /* If we are in a DWO stub, process it and then read in the "real" CU/TU
+ from the DWO file.
+ Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains a
+ DWO CU, that this test will fail (the attribute will not be present). */
attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu);
if (attr)
{
- char *dwo_name = DW_STRING (attr);
- const char *comp_dir_string;
struct dwo_unit *dwo_unit;
- ULONGEST signature; /* Or dwo_id. */
- struct attribute *comp_dir, *stmt_list, *low_pc, *high_pc, *ranges;
- int i,num_extra_attrs;
- struct dwarf2_section_info *dwo_abbrev_section;
+ struct die_info *dwo_comp_unit_die;
if (has_children)
- error (_("Dwarf Error: compilation unit with DW_AT_GNU_dwo_name"
- " has children (offset 0x%x) [in module %s]"),
- this_cu->offset.sect_off, bfd_get_filename (abfd));
-
- /* These attributes aren't processed until later:
- DW_AT_stmt_list, DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges.
- However, the attribute is found in the stub which we won't have later.
- In order to not impose this complication on the rest of the code,
- we read them here and copy them to the DWO CU/TU die. */
-
- /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
- DWO file. */
- stmt_list = NULL;
- if (! this_cu->is_debug_types)
- stmt_list = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
- low_pc = dwarf2_attr (comp_unit_die, DW_AT_low_pc, cu);
- high_pc = dwarf2_attr (comp_unit_die, DW_AT_high_pc, cu);
- ranges = dwarf2_attr (comp_unit_die, DW_AT_ranges, cu);
- comp_dir = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
-
- /* There should be a DW_AT_addr_base attribute here (if needed).
- We need the value before we can process DW_FORM_GNU_addr_index. */
- cu->addr_base = 0;
- attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_addr_base, cu);
- if (attr)
- cu->addr_base = DW_UNSND (attr);
-
- /* There should be a DW_AT_ranges_base attribute here (if needed).
- We need the value before we can process DW_AT_ranges. */
- cu->ranges_base = 0;
- attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_ranges_base, cu);
- if (attr)
- cu->ranges_base = DW_UNSND (attr);
-
- 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_string = NULL;
- if (comp_dir)
- comp_dir_string = DW_STRING (comp_dir);
-
- if (this_cu->is_debug_types)
- dwo_unit = lookup_dwo_type_unit (sig_type, dwo_name, comp_dir_string);
- else
- dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir_string,
- signature);
-
- 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;
- dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
- 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,
- dwo_abbrev_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 == get_cu_length (&cu->header));
-
- /* Establish the type offset that can be used to lookup the type.
- For DWO files, we don't know it until now. */
- sig_type->type_offset_in_section.sect_off =
- dwo_unit->offset.sect_off + dwo_unit->type_offset_in_tu.cu_off;
- }
- else
{
- info_ptr = read_and_check_comp_unit_head (&cu->header, section,
- dwo_abbrev_section,
- info_ptr, 0);
- gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
- gdb_assert (dwo_unit->length == get_cu_length (&cu->header));
+ complaint (&symfile_complaints,
+ _("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));
}
-
- /* Discard the original CU's abbrev table, and read the DWO's. */
- if (abbrev_table == NULL)
+ dwo_unit = lookup_dwo_unit (this_cu, comp_unit_die);
+ if (dwo_unit != NULL)
{
- dwarf2_free_abbrev_table (cu);
- dwarf2_read_abbrevs (cu, dwo_abbrev_section);
+ if (read_cutu_die_from_dwo (this_cu, dwo_unit,
+ abbrev_table != NULL,
+ comp_unit_die, NULL,
+ &reader, &info_ptr,
+ &dwo_comp_unit_die, &has_children) == 0)
+ {
+ /* Dummy die. */
+ do_cleanups (cleanups);
+ return;
+ }
+ comp_unit_die = dwo_comp_unit_die;
}
else
{
- dwarf2_read_abbrevs (cu, dwo_abbrev_section);
- make_cleanup (dwarf2_free_abbrev_table, cu);
- }
-
- /* Read in the die, but leave space to copy over the attributes
- from the stub. This has the benefit of simplifying the rest of
- the code - all the real work is done here. */
- num_extra_attrs = ((stmt_list != NULL)
- + (low_pc != NULL)
- + (high_pc != NULL)
- + (ranges != NULL)
- + (comp_dir != NULL));
- info_ptr = read_full_die_1 (&reader, &comp_unit_die, info_ptr,
- &has_children, num_extra_attrs);
-
- /* Copy over the attributes from the stub to the DWO die. */
- i = comp_unit_die->num_attrs;
- if (stmt_list != NULL)
- comp_unit_die->attrs[i++] = *stmt_list;
- if (low_pc != NULL)
- comp_unit_die->attrs[i++] = *low_pc;
- if (high_pc != NULL)
- comp_unit_die->attrs[i++] = *high_pc;
- if (ranges != NULL)
- comp_unit_die->attrs[i++] = *ranges;
- if (comp_dir != NULL)
- comp_unit_die->attrs[i++] = *comp_dir;
- comp_unit_die->num_attrs += num_extra_attrs;
-
- /* Skip dummy compilation units. */
- if (info_ptr >= begin_info_ptr + dwo_unit->length
- || peek_abbrev_code (abfd, info_ptr) == 0)
- {
- do_cleanups (cleanups);
- return;
+ /* Yikes, we couldn't find the rest of the DIE, we only have
+ the stub. A complaint has already been logged. There's
+ not much more we can do except pass on the stub DIE to
+ die_reader_func. We don't want to throw an error on bad
+ debug info. */
}
}
+ /* All of the above is setup for this call. Yikes. */
die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
+ /* Done, clean up. */
if (free_cu_cleanup != NULL)
{
if (keep)
@@ -4486,8 +5484,8 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
/* 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).
+ DWOP_FILE, if non-NULL, is the DWO/DWP file to read (the caller is assumed
+ to have already done the lookup to find the DWO/DWP file).
The caller is required to fill in THIS_CU->section, THIS_CU->offset, and
THIS_CU->is_debug_types, but nothing else.
@@ -4509,10 +5507,10 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
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_section_info *section = this_cu->section;
+ bfd *abfd = get_section_bfd_owner (section);
struct dwarf2_cu cu;
- gdb_byte *begin_info_ptr, *info_ptr;
+ const gdb_byte *begin_info_ptr, *info_ptr;
struct die_reader_specs reader;
struct cleanup *cleanups;
struct die_info *comp_unit_die;
@@ -4573,197 +5571,18 @@ init_cutu_and_read_dies_simple (struct dwarf2_per_cu_data *this_cu,
void *data)
{
init_cutu_and_read_dies_no_follow (this_cu,
- &dwarf2_per_objfile->abbrev,
+ get_abbrev_section_for_cu (this_cu),
NULL,
die_reader_func, data);
}
+
+/* Type Unit Groups.
-/* Create a psymtab named NAME and assign it to PER_CU.
-
- The caller must fill in the following details:
- dirname, textlow, texthigh. */
-
-static struct partial_symtab *
-create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name)
-{
- struct objfile *objfile = per_cu->objfile;
- struct partial_symtab *pst;
-
- pst = start_psymtab_common (objfile, objfile->section_offsets,
- name, 0,
- objfile->global_psymbols.next,
- objfile->static_psymbols.next);
-
- pst->psymtabs_addrmap_supported = 1;
-
- /* This is the glue that links PST into GDB's symbol API. */
- pst->read_symtab_private = per_cu;
- pst->read_symtab = dwarf2_psymtab_to_symtab;
- per_cu->v.psymtab = pst;
-
- return pst;
-}
-
-/* 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;
- struct attribute *attr;
- CORE_ADDR baseaddr;
- CORE_ADDR best_lowpc = 0, best_highpc = 0;
- struct partial_symtab *pst;
- int has_pc_info;
- const char *filename;
- int *want_partial_unit_ptr = data;
-
- if (comp_unit_die->tag == DW_TAG_partial_unit
- && (want_partial_unit_ptr == NULL
- || !*want_partial_unit_ptr))
- return;
-
- gdb_assert (! per_cu->is_debug_types);
-
- prepare_one_comp_unit (cu, comp_unit_die, language_minimal);
-
- cu->list_in_scope = &file_symbols;
-
- /* Allocate a new partial symbol table structure. */
- attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
- if (attr == NULL || !DW_STRING (attr))
- filename = "";
- else
- filename = DW_STRING (attr);
-
- pst = create_partial_symtab (per_cu, filename);
-
- /* This must be done before calling dwarf2_build_include_psymtabs. */
- attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
- if (attr != NULL)
- pst->dirname = DW_STRING (attr);
-
- baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
-
- 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);
- if (has_pc_info == 1 && best_lowpc < best_highpc)
- /* Store the contiguous range if it is not empty; it can be empty for
- CUs with no code. */
- addrmap_set_empty (objfile->psymtabs_addrmap,
- best_lowpc + baseaddr,
- best_highpc + baseaddr - 1, pst);
-
- /* Check if comp unit has_children.
- If so, read the rest of the partial symbols from this comp unit.
- If not, there's no more debug_info for this comp unit. */
- if (has_children)
- {
- struct partial_die_info *first_die;
- CORE_ADDR lowpc, highpc;
-
- lowpc = ((CORE_ADDR) -1);
- highpc = ((CORE_ADDR) 0);
-
- first_die = load_partial_dies (reader, info_ptr, 1);
-
- scan_partial_symbols (first_die, &lowpc, &highpc,
- ! has_pc_info, cu);
-
- /* If we didn't find a lowpc, set it to highpc to avoid
- complaints from `maint check'. */
- if (lowpc == ((CORE_ADDR) -1))
- lowpc = highpc;
-
- /* If the compilation unit didn't have an explicit address range,
- then use the information extracted from its child dies. */
- if (! has_pc_info)
- {
- best_lowpc = lowpc;
- best_highpc = highpc;
- }
- }
- pst->textlow = best_lowpc + baseaddr;
- pst->texthigh = best_highpc + baseaddr;
-
- pst->n_global_syms = objfile->global_psymbols.next -
- (objfile->global_psymbols.list + pst->globals_offset);
- pst->n_static_syms = objfile->static_psymbols.next -
- (objfile->static_psymbols.list + pst->statics_offset);
- sort_pst_symbols (pst);
-
- if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->s.imported_symtabs))
- {
- int i;
- int len = VEC_length (dwarf2_per_cu_ptr, cu->per_cu->s.imported_symtabs);
- struct dwarf2_per_cu_data *iter;
-
- /* Fill in 'dependencies' here; we fill in 'users' in a
- post-pass. */
- pst->number_of_dependencies = len;
- pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
- len * sizeof (struct symtab *));
- for (i = 0;
- VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->s.imported_symtabs,
- i, iter);
- ++i)
- pst->dependencies[i] = iter->v.psymtab;
-
- VEC_free (dwarf2_per_cu_ptr, cu->per_cu->s.imported_symtabs);
- }
-
- /* Get the list of files included in the current compilation unit,
- and build a psymtab for each of them. */
- dwarf2_build_include_psymtabs (cu, comp_unit_die, pst);
-
- if (dwarf2_read_debug)
- {
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
-
- fprintf_unfiltered (gdb_stdlog,
- "Psymtab for %s unit @0x%x: 0x%s - 0x%s"
- ", %d global, %d static syms\n",
- per_cu->is_debug_types ? "type" : "comp",
- per_cu->offset.sect_off,
- paddress (gdbarch, pst->textlow),
- paddress (gdbarch, pst->texthigh),
- pst->n_global_syms, pst->n_static_syms);
- }
-}
-
-/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
- Process compilation unit THIS_CU for a psymtab. */
-
-static void
-process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
- int want_partial_unit)
-{
- /* If this compilation unit was already read in, free the
- cached copy in order to read it in again. This is
- necessary because we skipped some symbols when we first
- read in the compilation unit (see load_partial_dies).
- This problem could be avoided, but the benefit is unclear. */
- if (this_cu->cu != NULL)
- free_one_cached_comp_unit (this_cu);
-
- gdb_assert (! this_cu->is_debug_types);
- init_cutu_and_read_dies (this_cu, NULL, 0, 0,
- process_psymtab_comp_unit_reader,
- &want_partial_unit);
-
- /* Age out any secondary CUs. */
- age_cached_comp_units ();
-}
+ Type Unit Groups are a way to collapse the set of all TUs (type units) into
+ a more manageable set. The grouping is done by DW_AT_stmt_list entry
+ so that all types coming from the same compilation (.o file) are grouped
+ together. A future step could be to put the types in the same symtab as
+ the CU the types ultimately came from. */
static hashval_t
hash_type_unit_group (const void *item)
@@ -4816,14 +5635,11 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
struct type_unit_group);
per_cu = &tu_group->per_cu;
per_cu->objfile = objfile;
- per_cu->is_debug_types = 1;
- per_cu->s.type_unit_group = tu_group;
if (dwarf2_per_objfile->using_index)
{
per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_quick_data);
- tu_group->t.first_tu = cu->per_cu;
}
else
{
@@ -4854,7 +5670,7 @@ create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
STMT_LIST is a DW_AT_stmt_list attribute. */
static struct type_unit_group *
-get_type_unit_group (struct dwarf2_cu *cu, struct attribute *stmt_list)
+get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
{
struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
struct type_unit_group *tu_group;
@@ -5013,7 +5829,7 @@ build_type_unit_groups (die_reader_func_ftype *func, void *data)
sorted_by_abbrev[i].sig_type = sig_type;
sorted_by_abbrev[i].abbrev_offset =
- read_abbrev_offset (sig_type->per_cu.info_or_types_section,
+ read_abbrev_offset (sig_type->per_cu.section,
sig_type->per_cu.offset);
}
cleanups = make_cleanup (xfree, sorted_by_abbrev);
@@ -5053,6 +5869,16 @@ build_type_unit_groups (die_reader_func_ftype *func, void *data)
func, data);
}
+ /* type_unit_groups can be NULL if there is an error in the debug info.
+ Just create an empty table so the rest of gdb doesn't have to watch
+ for this error case. */
+ if (dwarf2_per_objfile->type_unit_groups == NULL)
+ {
+ dwarf2_per_objfile->type_unit_groups =
+ allocate_type_unit_groups_table ();
+ dwarf2_per_objfile->n_type_unit_groups = 0;
+ }
+
/* Create a vector of pointers to primary type units to make it easy to
iterate over them and CUs. See dw2_get_primary_cu. */
dwarf2_per_objfile->n_type_unit_groups =
@@ -5084,90 +5910,302 @@ build_type_unit_groups (die_reader_func_ftype *func, void *data)
tu_stats->nr_stmt_less_type_units);
}
}
+
+/* Partial symbol tables. */
-/* Reader function for build_type_psymtabs. */
+/* Create a psymtab named NAME and assign it to PER_CU.
-static void
-build_type_psymtabs_reader (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- struct die_info *type_unit_die,
- int has_children,
- void *data)
+ The caller must fill in the following details:
+ dirname, textlow, texthigh. */
+
+static struct partial_symtab *
+create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name)
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct dwarf2_cu *cu = reader->cu;
- struct dwarf2_per_cu_data *per_cu = cu->per_cu;
- struct type_unit_group *tu_group;
- struct attribute *attr;
- struct partial_die_info *first_die;
- CORE_ADDR lowpc, highpc;
+ struct objfile *objfile = per_cu->objfile;
struct partial_symtab *pst;
- gdb_assert (data == NULL);
-
- if (! has_children)
- return;
-
- attr = dwarf2_attr_no_follow (type_unit_die, DW_AT_stmt_list);
- tu_group = get_type_unit_group (cu, attr);
-
- VEC_safe_push (dwarf2_per_cu_ptr, tu_group->t.tus, per_cu);
-
- prepare_one_comp_unit (cu, type_unit_die, language_minimal);
- cu->list_in_scope = &file_symbols;
- pst = create_partial_symtab (per_cu, "");
- pst->anonymous = 1;
+ pst = start_psymtab_common (objfile, objfile->section_offsets,
+ name, 0,
+ objfile->global_psymbols.next,
+ objfile->static_psymbols.next);
- first_die = load_partial_dies (reader, info_ptr, 1);
+ pst->psymtabs_addrmap_supported = 1;
- lowpc = (CORE_ADDR) -1;
- highpc = (CORE_ADDR) 0;
- scan_partial_symbols (first_die, &lowpc, &highpc, 0, cu);
+ /* This is the glue that links PST into GDB's symbol API. */
+ pst->read_symtab_private = per_cu;
+ pst->read_symtab = dwarf2_read_symtab;
+ per_cu->v.psymtab = pst;
- pst->n_global_syms = objfile->global_psymbols.next -
- (objfile->global_psymbols.list + pst->globals_offset);
- pst->n_static_syms = objfile->static_psymbols.next -
- (objfile->static_psymbols.list + pst->statics_offset);
- sort_pst_symbols (pst);
+ return pst;
}
-/* Traversal function for build_type_psymtabs. */
+/* The DATA object passed to process_psymtab_comp_unit_reader has this
+ type. */
-static int
-build_type_psymtab_dependencies (void **slot, void *info)
+struct process_psymtab_comp_unit_data
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct type_unit_group *tu_group = (struct type_unit_group *) *slot;
- struct dwarf2_per_cu_data *per_cu = &tu_group->per_cu;
- struct partial_symtab *pst = per_cu->v.psymtab;
- int len = VEC_length (dwarf2_per_cu_ptr, tu_group->t.tus);
- struct dwarf2_per_cu_data *iter;
- int i;
-
- gdb_assert (len > 0);
+ /* True if we are reading a DW_TAG_partial_unit. */
- pst->number_of_dependencies = len;
- pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
- len * sizeof (struct psymtab *));
- for (i = 0;
- VEC_iterate (dwarf2_per_cu_ptr, tu_group->t.tus, i, iter);
- ++i)
- {
- pst->dependencies[i] = iter->v.psymtab;
- iter->s.type_unit_group = tu_group;
- }
+ int want_partial_unit;
- VEC_free (dwarf2_per_cu_ptr, tu_group->t.tus);
+ /* The "pretend" language that is used if the CU doesn't declare a
+ language. */
- return 1;
-}
+ enum language pretend_language;
+};
-/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
- Build partial symbol tables for the .debug_types comp-units. */
+/* die_reader_func for process_psymtab_comp_unit. */
static void
-build_type_psymtabs (struct objfile *objfile)
-{
+process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
+ const 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;
+ 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;
+ struct process_psymtab_comp_unit_data *info = data;
+
+ if (comp_unit_die->tag == DW_TAG_partial_unit && !info->want_partial_unit)
+ return;
+
+ gdb_assert (! per_cu->is_debug_types);
+
+ prepare_one_comp_unit (cu, comp_unit_die, info->pretend_language);
+
+ cu->list_in_scope = &file_symbols;
+
+ /* Allocate a new partial symbol table structure. */
+ attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
+ if (attr == NULL || !DW_STRING (attr))
+ filename = "";
+ else
+ filename = DW_STRING (attr);
+
+ pst = create_partial_symtab (per_cu, filename);
+
+ /* This must be done before calling dwarf2_build_include_psymtabs. */
+ attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
+ if (attr != NULL)
+ pst->dirname = DW_STRING (attr);
+
+ baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+ 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);
+ if (has_pc_info == 1 && best_lowpc < best_highpc)
+ /* Store the contiguous range if it is not empty; it can be empty for
+ CUs with no code. */
+ addrmap_set_empty (objfile->psymtabs_addrmap,
+ best_lowpc + baseaddr,
+ best_highpc + baseaddr - 1, pst);
+
+ /* Check if comp unit has_children.
+ If so, read the rest of the partial symbols from this comp unit.
+ If not, there's no more debug_info for this comp unit. */
+ if (has_children)
+ {
+ struct partial_die_info *first_die;
+ CORE_ADDR lowpc, highpc;
+
+ lowpc = ((CORE_ADDR) -1);
+ highpc = ((CORE_ADDR) 0);
+
+ first_die = load_partial_dies (reader, info_ptr, 1);
+
+ scan_partial_symbols (first_die, &lowpc, &highpc,
+ ! has_pc_info, cu);
+
+ /* If we didn't find a lowpc, set it to highpc to avoid
+ complaints from `maint check'. */
+ if (lowpc == ((CORE_ADDR) -1))
+ lowpc = highpc;
+
+ /* If the compilation unit didn't have an explicit address range,
+ then use the information extracted from its child dies. */
+ if (! has_pc_info)
+ {
+ best_lowpc = lowpc;
+ best_highpc = highpc;
+ }
+ }
+ pst->textlow = best_lowpc + baseaddr;
+ pst->texthigh = best_highpc + baseaddr;
+
+ pst->n_global_syms = objfile->global_psymbols.next -
+ (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms = objfile->static_psymbols.next -
+ (objfile->static_psymbols.list + pst->statics_offset);
+ sort_pst_symbols (objfile, pst);
+
+ if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs))
+ {
+ int i;
+ int len = VEC_length (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
+ struct dwarf2_per_cu_data *iter;
+
+ /* Fill in 'dependencies' here; we fill in 'users' in a
+ post-pass. */
+ pst->number_of_dependencies = len;
+ pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
+ len * sizeof (struct symtab *));
+ for (i = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
+ i, iter);
+ ++i)
+ pst->dependencies[i] = iter->v.psymtab;
+
+ VEC_free (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
+ }
+
+ /* Get the list of files included in the current compilation unit,
+ and build a psymtab for each of them. */
+ dwarf2_build_include_psymtabs (cu, comp_unit_die, pst);
+
+ if (dwarf2_read_debug)
+ {
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+ fprintf_unfiltered (gdb_stdlog,
+ "Psymtab for %s unit @0x%x: %s - %s"
+ ", %d global, %d static syms\n",
+ per_cu->is_debug_types ? "type" : "comp",
+ per_cu->offset.sect_off,
+ paddress (gdbarch, pst->textlow),
+ paddress (gdbarch, pst->texthigh),
+ pst->n_global_syms, pst->n_static_syms);
+ }
+}
+
+/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
+ Process compilation unit THIS_CU for a psymtab. */
+
+static void
+process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
+ int want_partial_unit,
+ enum language pretend_language)
+{
+ struct process_psymtab_comp_unit_data info;
+
+ /* 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);
+ info.want_partial_unit = want_partial_unit;
+ info.pretend_language = pretend_language;
+ init_cutu_and_read_dies (this_cu, NULL, 0, 0,
+ process_psymtab_comp_unit_reader,
+ &info);
+
+ /* Age out any secondary CUs. */
+ age_cached_comp_units ();
+}
+
+/* Reader function for build_type_psymtabs. */
+
+static void
+build_type_psymtabs_reader (const struct die_reader_specs *reader,
+ const gdb_byte *info_ptr,
+ struct die_info *type_unit_die,
+ int has_children,
+ void *data)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_cu *cu = reader->cu;
+ struct dwarf2_per_cu_data *per_cu = cu->per_cu;
+ struct signatured_type *sig_type;
+ struct type_unit_group *tu_group;
+ struct attribute *attr;
+ struct partial_die_info *first_die;
+ CORE_ADDR lowpc, highpc;
+ struct partial_symtab *pst;
+
+ gdb_assert (data == NULL);
+ gdb_assert (per_cu->is_debug_types);
+ sig_type = (struct signatured_type *) per_cu;
+
+ if (! has_children)
+ return;
+
+ attr = dwarf2_attr_no_follow (type_unit_die, DW_AT_stmt_list);
+ tu_group = get_type_unit_group (cu, attr);
+
+ VEC_safe_push (sig_type_ptr, tu_group->tus, sig_type);
+
+ prepare_one_comp_unit (cu, type_unit_die, language_minimal);
+ cu->list_in_scope = &file_symbols;
+ pst = create_partial_symtab (per_cu, "");
+ pst->anonymous = 1;
+
+ first_die = load_partial_dies (reader, info_ptr, 1);
+
+ lowpc = (CORE_ADDR) -1;
+ highpc = (CORE_ADDR) 0;
+ scan_partial_symbols (first_die, &lowpc, &highpc, 0, cu);
+
+ pst->n_global_syms = objfile->global_psymbols.next -
+ (objfile->global_psymbols.list + pst->globals_offset);
+ pst->n_static_syms = objfile->static_psymbols.next -
+ (objfile->static_psymbols.list + pst->statics_offset);
+ sort_pst_symbols (objfile, pst);
+}
+
+/* Traversal function for build_type_psymtabs. */
+
+static int
+build_type_psymtab_dependencies (void **slot, void *info)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct type_unit_group *tu_group = (struct type_unit_group *) *slot;
+ struct dwarf2_per_cu_data *per_cu = &tu_group->per_cu;
+ struct partial_symtab *pst = per_cu->v.psymtab;
+ int len = VEC_length (sig_type_ptr, tu_group->tus);
+ struct signatured_type *iter;
+ int i;
+
+ gdb_assert (len > 0);
+ gdb_assert (IS_TYPE_UNIT_GROUP (per_cu));
+
+ pst->number_of_dependencies = len;
+ pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
+ len * sizeof (struct psymtab *));
+ for (i = 0;
+ VEC_iterate (sig_type_ptr, tu_group->tus, i, iter);
+ ++i)
+ {
+ gdb_assert (iter->per_cu.is_debug_types);
+ pst->dependencies[i] = iter->per_cu.v.psymtab;
+ iter->type_unit_group = tu_group;
+ }
+
+ VEC_free (sig_type_ptr, tu_group->tus);
+
+ return 1;
+}
+
+/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
+ Build partial symbol tables for the .debug_types comp-units. */
+
+static void
+build_type_psymtabs (struct objfile *objfile)
+{
if (! create_all_type_units (objfile))
return;
@@ -5201,6 +6239,9 @@ set_partial_user (struct objfile *objfile)
struct partial_symtab *pst = per_cu->v.psymtab;
int j;
+ if (pst == NULL)
+ continue;
+
for (j = 0; j < pst->number_of_dependencies; ++j)
{
/* Set the 'user' field only if it is not already set. */
@@ -5223,7 +6264,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
if (dwarf2_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "Building psymtabs of objfile %s ...\n",
- objfile->name);
+ objfile_name (objfile));
}
dwarf2_per_objfile->reading_partial_symbols = 1;
@@ -5249,7 +6290,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
- process_psymtab_comp_unit (per_cu, 0);
+ process_psymtab_comp_unit (per_cu, 0, language_minimal);
}
set_partial_user (objfile);
@@ -5262,14 +6303,14 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
if (dwarf2_read_debug)
fprintf_unfiltered (gdb_stdlog, "Done building psymtabs of %s\n",
- objfile->name);
+ objfile_name (objfile));
}
/* die_reader_func for load_partial_comp_unit. */
static void
load_partial_comp_unit_reader (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
+ const gdb_byte *info_ptr,
struct die_info *comp_unit_die,
int has_children,
void *data)
@@ -5295,38 +6336,37 @@ load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
load_partial_comp_unit_reader, NULL);
}
-/* 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)
+read_comp_units_from_section (struct objfile *objfile,
+ struct dwarf2_section_info *section,
+ unsigned int is_dwz,
+ int *n_allocated,
+ int *n_comp_units,
+ struct dwarf2_per_cu_data ***all_comp_units)
{
- int n_allocated;
- int n_comp_units;
- struct dwarf2_per_cu_data **all_comp_units;
- gdb_byte *info_ptr;
+ const gdb_byte *info_ptr;
+ bfd *abfd = get_section_bfd_owner (section);
- dwarf2_read_section (objfile, &dwarf2_per_objfile->info);
- info_ptr = dwarf2_per_objfile->info.buffer;
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "Reading %s for %s\n",
+ get_section_name (section),
+ get_section_file_name (section));
- n_comp_units = 0;
- n_allocated = 10;
- all_comp_units = xmalloc (n_allocated
- * sizeof (struct dwarf2_per_cu_data *));
+ dwarf2_read_section (objfile, section);
+
+ info_ptr = section->buffer;
- while (info_ptr < dwarf2_per_objfile->info.buffer
- + dwarf2_per_objfile->info.size)
+ while (info_ptr < section->buffer + section->size)
{
unsigned int length, initial_length_size;
struct dwarf2_per_cu_data *this_cu;
sect_offset offset;
- offset.sect_off = info_ptr - dwarf2_per_objfile->info.buffer;
+ offset.sect_off = info_ptr - section->buffer;
/* Read just enough information to find out where the next
compilation unit is. */
- length = read_initial_length (objfile->obfd, info_ptr,
- &initial_length_size);
+ length = read_initial_length (abfd, info_ptr, &initial_length_size);
/* Save the compilation unit for later lookup. */
this_cu = obstack_alloc (&objfile->objfile_obstack,
@@ -5334,37 +6374,65 @@ create_all_comp_units (struct objfile *objfile)
memset (this_cu, 0, sizeof (*this_cu));
this_cu->offset = offset;
this_cu->length = length + initial_length_size;
+ this_cu->is_dwz = is_dwz;
this_cu->objfile = objfile;
- this_cu->info_or_types_section = &dwarf2_per_objfile->info;
+ this_cu->section = section;
- if (n_comp_units == n_allocated)
+ if (*n_comp_units == *n_allocated)
{
- n_allocated *= 2;
- all_comp_units = xrealloc (all_comp_units,
- n_allocated
- * sizeof (struct dwarf2_per_cu_data *));
+ *n_allocated *= 2;
+ *all_comp_units = xrealloc (*all_comp_units,
+ *n_allocated
+ * sizeof (struct dwarf2_per_cu_data *));
}
- all_comp_units[n_comp_units++] = this_cu;
+ (*all_comp_units)[*n_comp_units] = this_cu;
+ ++*n_comp_units;
info_ptr = info_ptr + this_cu->length;
}
-
- dwarf2_per_objfile->all_comp_units
- = obstack_alloc (&objfile->objfile_obstack,
- n_comp_units * sizeof (struct dwarf2_per_cu_data *));
- memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units,
- n_comp_units * sizeof (struct dwarf2_per_cu_data *));
- xfree (all_comp_units);
- dwarf2_per_objfile->n_comp_units = n_comp_units;
}
-/* Process all loaded DIEs for compilation unit CU, starting at
- FIRST_DIE. The caller should pass NEED_PC == 1 if the compilation
- unit DIE did not have PC info (DW_AT_low_pc and DW_AT_high_pc, or
- DW_AT_ranges). If NEED_PC is set, then this function will set
- *LOWPC and *HIGHPC to the lowest and highest PC values found in CU
- and record the covered ranges in the addrmap. */
-
+/* 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)
+{
+ int n_allocated;
+ int n_comp_units;
+ struct dwarf2_per_cu_data **all_comp_units;
+ struct dwz_file *dwz;
+
+ n_comp_units = 0;
+ n_allocated = 10;
+ all_comp_units = xmalloc (n_allocated
+ * sizeof (struct dwarf2_per_cu_data *));
+
+ read_comp_units_from_section (objfile, &dwarf2_per_objfile->info, 0,
+ &n_allocated, &n_comp_units, &all_comp_units);
+
+ dwz = dwarf2_get_dwz_file ();
+ if (dwz != NULL)
+ read_comp_units_from_section (objfile, &dwz->info, 1,
+ &n_allocated, &n_comp_units,
+ &all_comp_units);
+
+ dwarf2_per_objfile->all_comp_units
+ = obstack_alloc (&objfile->objfile_obstack,
+ n_comp_units * sizeof (struct dwarf2_per_cu_data *));
+ memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units,
+ n_comp_units * sizeof (struct dwarf2_per_cu_data *));
+ xfree (all_comp_units);
+ dwarf2_per_objfile->n_comp_units = n_comp_units;
+}
+
+/* Process all loaded DIEs for compilation unit CU, starting at
+ FIRST_DIE. The caller should pass NEED_PC == 1 if the compilation
+ unit DIE did not have PC info (DW_AT_low_pc and DW_AT_high_pc, or
+ DW_AT_ranges). If NEED_PC is set, then this function will set
+ *LOWPC and *HIGHPC to the lowest and highest PC values found in CU
+ and record the covered ranges in the addrmap. */
+
static void
scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
CORE_ADDR *highpc, int need_pc, struct dwarf2_cu *cu)
@@ -5436,20 +6504,24 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
{
error (_("Dwarf Error: DW_TAG_imported_unit is not"
" supported in type units [in module %s]"),
- cu->objfile->name);
+ objfile_name (cu->objfile));
}
per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset,
+ pdi->is_dwz,
cu->objfile);
/* Go read the partial unit, if needed. */
if (per_cu->v.psymtab == NULL)
- process_psymtab_comp_unit (per_cu, 1);
+ process_psymtab_comp_unit (per_cu, 1, cu->language);
VEC_safe_push (dwarf2_per_cu_ptr,
- cu->per_cu->s.imported_symtabs, per_cu);
+ cu->per_cu->imported_symtabs, per_cu);
}
break;
+ case DW_TAG_imported_declaration:
+ add_partial_symbol (pdi, cu);
+ break;
default:
break;
}
@@ -5485,11 +6557,11 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
compilation unit CU. The result will be allocated on CU's
comp_unit_obstack, or a copy of the already allocated PDI->NAME
field. NULL is returned if no prefix is necessary. */
-static char *
+static const char *
partial_die_parent_scope (struct partial_die_info *pdi,
struct dwarf2_cu *cu)
{
- char *grandparent_scope;
+ const char *grandparent_scope;
struct partial_die_info *parent, *real_pdi;
/* We need to look at our parent DIE; if we have a DW_AT_specification,
@@ -5497,7 +6569,8 @@ partial_die_parent_scope (struct partial_die_info *pdi,
real_pdi = pdi;
while (real_pdi->has_specification)
- real_pdi = find_partial_die (real_pdi->spec_offset, cu);
+ real_pdi = find_partial_die (real_pdi->spec_offset,
+ real_pdi->spec_is_dwz, cu);
parent = real_pdi->die_parent;
if (parent == NULL)
@@ -5563,7 +6636,7 @@ static char *
partial_die_full_name (struct partial_die_info *pdi,
struct dwarf2_cu *cu)
{
- char *parent_scope;
+ const char *parent_scope;
/* If this is a template instantiation, we can not work out the
template arguments from partial DIEs. So, unfortunately, we have
@@ -5601,15 +6674,15 @@ 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 char *actual_name = NULL;
CORE_ADDR baseaddr;
- int built_actual_name = 0;
+ char *built_actual_name;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- actual_name = partial_die_full_name (pdi, cu);
- if (actual_name)
- built_actual_name = 1;
+ built_actual_name = partial_die_full_name (pdi, cu);
+ if (built_actual_name != NULL)
+ actual_name = built_actual_name;
if (actual_name == NULL)
actual_name = pdi->name;
@@ -5626,7 +6699,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
/* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
mst_text, objfile); */
add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
+ built_actual_name != NULL,
VAR_DOMAIN, LOC_BLOCK,
&objfile->global_psymbols,
0, pdi->lowpc + baseaddr,
@@ -5637,7 +6710,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
/* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
mst_file_text, objfile); */
add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
+ built_actual_name != NULL,
VAR_DOMAIN, LOC_BLOCK,
&objfile->static_psymbols,
0, pdi->lowpc + baseaddr,
@@ -5653,7 +6726,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
else
list = &objfile->static_psymbols;
add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name, VAR_DOMAIN, LOC_STATIC,
+ built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC,
list, 0, 0, cu->language, objfile);
}
break;
@@ -5687,7 +6760,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
if (pdi->d.locdesc || pdi->has_type)
add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
+ built_actual_name != NULL,
VAR_DOMAIN, LOC_STATIC,
&objfile->global_psymbols,
0, addr + baseaddr,
@@ -5698,14 +6771,13 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
/* Static Variable. Skip symbols without location descriptors. */
if (pdi->d.locdesc == NULL)
{
- if (built_actual_name)
- xfree (actual_name);
+ xfree (built_actual_name);
return;
}
/* prim_record_minimal_symbol (actual_name, addr + baseaddr,
mst_file_data, objfile); */
add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
+ built_actual_name != NULL,
VAR_DOMAIN, LOC_STATIC,
&objfile->static_psymbols,
0, addr + baseaddr,
@@ -5716,14 +6788,15 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
case DW_TAG_base_type:
case DW_TAG_subrange_type:
add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
+ built_actual_name != NULL,
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, objfile);
break;
+ case DW_TAG_imported_declaration:
case DW_TAG_namespace:
add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
+ built_actual_name != NULL,
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->global_psymbols,
0, (CORE_ADDR) 0, cu->language, objfile);
@@ -5740,15 +6813,14 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
and that has a DW_AT_declaration attribute." */
if (!pdi->has_byte_size && pdi->is_declaration)
{
- if (built_actual_name)
- xfree (actual_name);
+ xfree (built_actual_name);
return;
}
/* NOTE: carlton/2003-10-07: See comment in new_symbol about
static vs. global. */
add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
+ built_actual_name != NULL,
STRUCT_DOMAIN, LOC_TYPEDEF,
(cu->language == language_cplus
|| cu->language == language_java)
@@ -5759,7 +6831,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
break;
case DW_TAG_enumerator:
add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name,
+ built_actual_name != NULL,
VAR_DOMAIN, LOC_CONST,
(cu->language == language_cplus
|| cu->language == language_java)
@@ -5771,8 +6843,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
break;
}
- if (built_actual_name)
- xfree (actual_name);
+ xfree (built_actual_name);
}
/* Read a partial die corresponding to a namespace; also, add a symbol
@@ -5896,7 +6967,7 @@ 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)
+peek_abbrev_code (bfd *abfd, const gdb_byte *info_ptr)
{
unsigned int bytes_read;
@@ -5909,7 +6980,7 @@ peek_abbrev_code (bfd *abfd, gdb_byte *info_ptr)
the initial number. */
static struct abbrev_info *
-peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read,
+peek_die_abbrev (const gdb_byte *info_ptr, unsigned int *bytes_read,
struct dwarf2_cu *cu)
{
bfd *abfd = cu->objfile->obfd;
@@ -5935,8 +7006,8 @@ peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read,
Returns a pointer to the end of a series of DIEs, terminated by an empty
DIE. Any children of the skipped DIEs will also be skipped. */
-static gdb_byte *
-skip_children (const struct die_reader_specs *reader, gdb_byte *info_ptr)
+static const gdb_byte *
+skip_children (const struct die_reader_specs *reader, const gdb_byte *info_ptr)
{
struct dwarf2_cu *cu = reader->cu;
struct abbrev_info *abbrev;
@@ -5958,17 +7029,17 @@ skip_children (const struct die_reader_specs *reader, gdb_byte *info_ptr)
ABBREV. Returns a pointer to this DIE's sibling, skipping any
children. */
-static gdb_byte *
-skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr,
+static const gdb_byte *
+skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
struct abbrev_info *abbrev)
{
unsigned int bytes_read;
struct attribute attr;
bfd *abfd = reader->abfd;
struct dwarf2_cu *cu = reader->cu;
- gdb_byte *buffer = reader->buffer;
+ const gdb_byte *buffer = reader->buffer;
const gdb_byte *buffer_end = reader->buffer_end;
- gdb_byte *start_info_ptr = info_ptr;
+ const gdb_byte *start_info_ptr = info_ptr;
unsigned int form, i;
for (i = 0; i < abbrev->num_attrs; i++)
@@ -5981,7 +7052,16 @@ skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr,
complaint (&symfile_complaints,
_("ignoring absolute DW_AT_sibling"));
else
- return buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
+ {
+ unsigned int off = dwarf2_get_ref_die_offset (&attr).sect_off;
+ const gdb_byte *sibling_ptr = buffer + off;
+
+ if (sibling_ptr < info_ptr)
+ complaint (&symfile_complaints,
+ _("DW_AT_sibling points backwards"));
+ else
+ return sibling_ptr;
+ }
}
/* If it isn't DW_AT_sibling, skip this attribute. */
@@ -5997,6 +7077,9 @@ skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr,
else
info_ptr += cu->header.offset_size;
break;
+ case DW_FORM_GNU_ref_alt:
+ info_ptr += cu->header.offset_size;
+ break;
case DW_FORM_addr:
info_ptr += cu->header.addr_size;
break;
@@ -6026,6 +7109,7 @@ skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr,
break;
case DW_FORM_sec_offset:
case DW_FORM_strp:
+ case DW_FORM_GNU_strp_alt:
info_ptr += cu->header.offset_size;
break;
case DW_FORM_exprloc:
@@ -6047,7 +7131,7 @@ skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr,
case DW_FORM_ref_udata:
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
- info_ptr = (gdb_byte *) safe_skip_leb128 (info_ptr, buffer_end);
+ info_ptr = safe_skip_leb128 (info_ptr, buffer_end);
break;
case DW_FORM_indirect:
form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
@@ -6073,10 +7157,10 @@ skip_one_die (const struct die_reader_specs *reader, gdb_byte *info_ptr,
/* Locate ORIG_PDI's sibling.
INFO_PTR should point to the start of the next DIE after ORIG_PDI. */
-static gdb_byte *
+static const gdb_byte *
locate_pdi_sibling (const struct die_reader_specs *reader,
struct partial_die_info *orig_pdi,
- gdb_byte *info_ptr)
+ const gdb_byte *info_ptr)
{
/* Do we know the sibling already? */
@@ -6093,53 +7177,51 @@ locate_pdi_sibling (const struct die_reader_specs *reader,
return skip_children (reader, info_ptr);
}
-/* Expand this partial symbol table into a full symbol table. */
+/* Expand this partial symbol table into a full symbol table. SELF is
+ not NULL. */
static void
-dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
+dwarf2_read_symtab (struct partial_symtab *self,
+ struct objfile *objfile)
{
- if (pst != NULL)
+ if (self->readin)
+ {
+ warning (_("bug: psymtab for %s is already read in."),
+ self->filename);
+ }
+ else
{
- if (pst->readin)
+ if (info_verbose)
{
- warning (_("bug: psymtab for %s is already read in."),
- pst->filename);
+ printf_filtered (_("Reading in symbols for %s..."),
+ self->filename);
+ gdb_flush (gdb_stdout);
}
- else
- {
- if (info_verbose)
- {
- printf_filtered (_("Reading in symbols for %s..."),
- pst->filename);
- gdb_flush (gdb_stdout);
- }
- /* Restore our global data. */
- dwarf2_per_objfile = objfile_data (pst->objfile,
- dwarf2_objfile_data_key);
+ /* Restore our global data. */
+ dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
- /* If this psymtab is constructed from a debug-only objfile, the
- has_section_at_zero flag will not necessarily be correct. We
- can get the correct value for this flag by looking at the data
- associated with the (presumably stripped) associated objfile. */
- if (pst->objfile->separate_debug_objfile_backlink)
- {
- struct dwarf2_per_objfile *dpo_backlink
- = objfile_data (pst->objfile->separate_debug_objfile_backlink,
- dwarf2_objfile_data_key);
+ /* If this psymtab is constructed from a debug-only objfile, the
+ has_section_at_zero flag will not necessarily be correct. We
+ can get the correct value for this flag by looking at the data
+ associated with the (presumably stripped) associated objfile. */
+ if (objfile->separate_debug_objfile_backlink)
+ {
+ struct dwarf2_per_objfile *dpo_backlink
+ = objfile_data (objfile->separate_debug_objfile_backlink,
+ dwarf2_objfile_data_key);
- dwarf2_per_objfile->has_section_at_zero
- = dpo_backlink->has_section_at_zero;
- }
+ dwarf2_per_objfile->has_section_at_zero
+ = dpo_backlink->has_section_at_zero;
+ }
- dwarf2_per_objfile->reading_partial_symbols = 0;
+ dwarf2_per_objfile->reading_partial_symbols = 0;
- psymtab_to_symtab_1 (pst);
+ psymtab_to_symtab_1 (self);
- /* Finish up the debug error message. */
- if (info_verbose)
- printf_filtered (_("done.\n"));
- }
+ /* Finish up the debug error message. */
+ if (info_verbose)
+ printf_filtered (_("done.\n"));
}
process_cu_includes ();
@@ -6169,13 +7251,17 @@ queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
dwarf2_queue_tail = item;
}
-/* THIS_CU has a reference to PER_CU. If necessary, load the new compilation
- unit and add it to our queue.
+/* If PER_CU is not yet queued, add it to the queue.
+ If DEPENDENT_CU is non-NULL, it has a reference to PER_CU so add a
+ dependency.
The result is non-zero if PER_CU was queued, otherwise the result is zero
- meaning either PER_CU is already queued or it is already loaded. */
+ meaning either PER_CU is already queued or it is already loaded.
+
+ N.B. There is an invariant here that if a CU is queued then it is loaded.
+ The caller is required to load PER_CU if we return non-zero. */
static int
-maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
+maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
struct dwarf2_per_cu_data *per_cu,
enum language pretend_language)
{
@@ -6191,7 +7277,8 @@ maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
/* Mark the dependence relation so that we don't flush PER_CU
too early. */
- dwarf2_add_dependence (this_cu, per_cu);
+ if (dependent_cu != NULL)
+ dwarf2_add_dependence (dependent_cu, per_cu);
/* If it's already on the queue, we have nothing to do. */
if (per_cu->queued)
@@ -6222,7 +7309,7 @@ process_queue (void)
{
fprintf_unfiltered (gdb_stdlog,
"Expanding one or more symtabs of objfile %s ...\n",
- dwarf2_per_objfile->objfile->name);
+ objfile_name (dwarf2_per_objfile->objfile));
}
/* The queue starts out with one item, but following a DIE reference
@@ -6234,27 +7321,37 @@ process_queue (void)
: (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin))
{
struct dwarf2_per_cu_data *per_cu = item->per_cu;
+ unsigned int debug_print_threshold;
+ char buf[100];
- if (dwarf2_read_debug)
+ if (per_cu->is_debug_types)
+ {
+ struct signatured_type *sig_type =
+ (struct signatured_type *) per_cu;
+
+ sprintf (buf, "TU %s at offset 0x%x",
+ hex_string (sig_type->signature),
+ per_cu->offset.sect_off);
+ /* There can be 100s of TUs.
+ Only print them in verbose mode. */
+ debug_print_threshold = 2;
+ }
+ else
{
- fprintf_unfiltered (gdb_stdlog,
- "Expanding symtab of %s at offset 0x%x\n",
- per_cu->is_debug_types ? "TU" : "CU",
- per_cu->offset.sect_off);
+ sprintf (buf, "CU at offset 0x%x", per_cu->offset.sect_off);
+ debug_print_threshold = 1;
}
+ if (dwarf2_read_debug >= debug_print_threshold)
+ fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
+
if (per_cu->is_debug_types)
process_full_type_unit (per_cu, item->pretend_language);
else
process_full_comp_unit (per_cu, item->pretend_language);
- if (dwarf2_read_debug)
- {
- fprintf_unfiltered (gdb_stdlog,
- "Done expanding %s at offset 0x%x\n",
- per_cu->is_debug_types ? "TU" : "CU",
- per_cu->offset.sect_off);
- }
+ if (dwarf2_read_debug >= debug_print_threshold)
+ fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
}
item->per_cu->queued = 0;
@@ -6267,7 +7364,7 @@ process_queue (void)
if (dwarf2_read_debug)
{
fprintf_unfiltered (gdb_stdlog, "Done expanding symtabs of %s.\n",
- dwarf2_per_objfile->objfile->name);
+ objfile_name (dwarf2_per_objfile->objfile));
}
}
@@ -6372,7 +7469,7 @@ die_eq (const void *item_lhs, const void *item_rhs)
static void
load_full_comp_unit_reader (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
+ const gdb_byte *info_ptr,
struct die_info *comp_unit_die,
int has_children,
void *data)
@@ -6462,7 +7559,7 @@ compute_delayed_physnames (struct dwarf2_cu *cu)
const char *physname;
struct fn_fieldlist *fn_flp
= &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
- physname = dwarf2_physname ((char *) mi->name, mi->die, cu);
+ physname = dwarf2_physname (mi->name, mi->die, cu);
fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
}
}
@@ -6505,9 +7602,9 @@ fixup_go_packaging (struct dwarf2_cu *cu)
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),
+ (SYMBOL_SYMTAB (sym)
+ ? symtab_to_filename_for_display (SYMBOL_SYMTAB (sym))
+ : objfile_name (cu->objfile)),
this_package_name, package_name);
xfree (this_package_name);
}
@@ -6518,19 +7615,23 @@ fixup_go_packaging (struct dwarf2_cu *cu)
if (package_name != NULL)
{
struct objfile *objfile = cu->objfile;
+ const char *saved_package_name = obstack_copy0 (&objfile->objfile_obstack,
+ package_name,
+ strlen (package_name));
struct type *type = init_type (TYPE_CODE_MODULE, 0, 0,
- package_name, objfile);
+ saved_package_name, objfile);
struct symbol *sym;
TYPE_TAG_NAME (type) = TYPE_NAME (type);
- sym = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
- SYMBOL_SET_LANGUAGE (sym, language_go);
- SYMBOL_SET_NAMES (sym, package_name, strlen (package_name), 1, objfile);
+ sym = allocate_symbol (objfile);
+ SYMBOL_SET_LANGUAGE (sym, language_go, &objfile->objfile_obstack);
+ SYMBOL_SET_NAMES (sym, saved_package_name,
+ strlen (saved_package_name), 0, objfile);
/* This is not VAR_DOMAIN because we want a way to ensure a lookup of,
e.g., "main" finds the "main" module and not C's main(). */
SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
- SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
SYMBOL_TYPE (sym) = type;
add_symbol_to_list (sym, &global_symbols);
@@ -6539,8 +7640,6 @@ fixup_go_packaging (struct dwarf2_cu *cu)
}
}
-static void compute_symtab_includes (struct dwarf2_per_cu_data *per_cu);
-
/* Return the symtab for PER_CU. This works properly regardless of
whether we're using the index or psymtabs. */
@@ -6556,12 +7655,14 @@ get_symtab (struct dwarf2_per_cu_data *per_cu)
included by PER_CU. */
static void
-recursively_compute_inclusions (VEC (dwarf2_per_cu_ptr) **result,
- htab_t all_children,
- struct dwarf2_per_cu_data *per_cu)
+recursively_compute_inclusions (VEC (symtab_ptr) **result,
+ htab_t all_children, htab_t all_type_symtabs,
+ struct dwarf2_per_cu_data *per_cu,
+ struct symtab *immediate_parent)
{
void **slot;
int ix;
+ struct symtab *symtab;
struct dwarf2_per_cu_data *iter;
slot = htab_find_slot (all_children, per_cu, INSERT);
@@ -6573,13 +7674,37 @@ recursively_compute_inclusions (VEC (dwarf2_per_cu_ptr) **result,
*slot = per_cu;
/* Only add a CU if it has a symbol table. */
- if (get_symtab (per_cu) != NULL)
- VEC_safe_push (dwarf2_per_cu_ptr, *result, per_cu);
+ symtab = get_symtab (per_cu);
+ if (symtab != NULL)
+ {
+ /* If this is a type unit only add its symbol table if we haven't
+ seen it yet (type unit per_cu's can share symtabs). */
+ if (per_cu->is_debug_types)
+ {
+ slot = htab_find_slot (all_type_symtabs, symtab, INSERT);
+ if (*slot == NULL)
+ {
+ *slot = symtab;
+ VEC_safe_push (symtab_ptr, *result, symtab);
+ if (symtab->user == NULL)
+ symtab->user = immediate_parent;
+ }
+ }
+ else
+ {
+ VEC_safe_push (symtab_ptr, *result, symtab);
+ if (symtab->user == NULL)
+ symtab->user = immediate_parent;
+ }
+ }
for (ix = 0;
- VEC_iterate (dwarf2_per_cu_ptr, per_cu->s.imported_symtabs, ix, iter);
+ VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs, ix, iter);
++ix)
- recursively_compute_inclusions (result, all_children, iter);
+ {
+ recursively_compute_inclusions (result, all_children,
+ all_type_symtabs, iter, symtab);
+ }
}
/* Compute the symtab 'includes' fields for the symtab related to
@@ -6590,12 +7715,13 @@ compute_symtab_includes (struct dwarf2_per_cu_data *per_cu)
{
gdb_assert (! per_cu->is_debug_types);
- if (!VEC_empty (dwarf2_per_cu_ptr, per_cu->s.imported_symtabs))
+ if (!VEC_empty (dwarf2_per_cu_ptr, per_cu->imported_symtabs))
{
int ix, len;
- struct dwarf2_per_cu_data *iter;
- VEC (dwarf2_per_cu_ptr) *result_children = NULL;
- htab_t all_children;
+ struct dwarf2_per_cu_data *per_cu_iter;
+ struct symtab *symtab_iter;
+ VEC (symtab_ptr) *result_symtabs = NULL;
+ htab_t all_children, all_type_symtabs;
struct symtab *symtab = get_symtab (per_cu);
/* If we don't have a symtab, we can just skip this case. */
@@ -6604,27 +7730,33 @@ compute_symtab_includes (struct dwarf2_per_cu_data *per_cu)
all_children = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer,
NULL, xcalloc, xfree);
+ all_type_symtabs = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
for (ix = 0;
- VEC_iterate (dwarf2_per_cu_ptr, per_cu->s.imported_symtabs,
- ix, iter);
+ VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs,
+ ix, per_cu_iter);
++ix)
- recursively_compute_inclusions (&result_children, all_children, iter);
+ {
+ recursively_compute_inclusions (&result_symtabs, all_children,
+ all_type_symtabs, per_cu_iter,
+ symtab);
+ }
- /* Now we have a transitive closure of all the included CUs, so
- we can convert it to a list of symtabs. */
- len = VEC_length (dwarf2_per_cu_ptr, result_children);
+ /* Now we have a transitive closure of all the included symtabs. */
+ len = VEC_length (symtab_ptr, result_symtabs);
symtab->includes
= obstack_alloc (&dwarf2_per_objfile->objfile->objfile_obstack,
(len + 1) * sizeof (struct symtab *));
for (ix = 0;
- VEC_iterate (dwarf2_per_cu_ptr, result_children, ix, iter);
+ VEC_iterate (symtab_ptr, result_symtabs, ix, symtab_iter);
++ix)
- symtab->includes[ix] = get_symtab (iter);
+ symtab->includes[ix] = symtab_iter;
symtab->includes[len] = NULL;
- VEC_free (dwarf2_per_cu_ptr, result_children);
+ VEC_free (symtab_ptr, result_symtabs);
htab_delete (all_children);
+ htab_delete (all_type_symtabs);
}
}
@@ -6693,7 +7825,8 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
it, by scanning the DIE's below the compilation unit. */
get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
- static_block = end_symtab_get_static_block (highpc + baseaddr, objfile, 0);
+ static_block
+ = end_symtab_get_static_block (highpc + baseaddr, objfile, 0, 1);
/* If the comp unit has DW_AT_ranges, it may have discontiguous ranges.
Also, DW_AT_ranges may record ranges not belonging to any child DIEs
@@ -6762,6 +7895,10 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
struct objfile *objfile = per_cu->objfile;
struct symtab *symtab;
struct cleanup *back_to, *delayed_list_cleanup;
+ struct signatured_type *sig_type;
+
+ gdb_assert (per_cu->is_debug_types);
+ sig_type = (struct signatured_type *) per_cu;
buildsym_init ();
back_to = make_cleanup (really_free_pendings, NULL);
@@ -6789,10 +7926,10 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
If this is the first TU to use this symtab, complete the construction
of it with end_expandable_symtab. Otherwise, complete the addition of
this TU's symbols to the existing symtab. */
- if (per_cu->s.type_unit_group->primary_symtab == NULL)
+ if (sig_type->type_unit_group->primary_symtab == NULL)
{
symtab = end_expandable_symtab (0, objfile, SECT_OFF_TEXT (objfile));
- per_cu->s.type_unit_group->primary_symtab = symtab;
+ sig_type->type_unit_group->primary_symtab = symtab;
if (symtab != NULL)
{
@@ -6807,8 +7944,8 @@ process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
else
{
augment_type_symtab (objfile,
- per_cu->s.type_unit_group->primary_symtab);
- symtab = per_cu->s.type_unit_group->primary_symtab;
+ sig_type->type_unit_group->primary_symtab);
+ symtab = sig_type->type_unit_group->primary_symtab;
}
if (dwarf2_per_objfile->using_index)
@@ -6835,7 +7972,7 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
{
error (_("Dwarf Error: DW_TAG_imported_unit is not"
" supported in type units [in module %s]"),
- cu->objfile->name);
+ objfile_name (cu->objfile));
}
attr = dwarf2_attr (die, DW_AT_import, cu);
@@ -6844,15 +7981,17 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
struct dwarf2_per_cu_data *per_cu;
struct symtab *imported_symtab;
sect_offset offset;
+ int is_dwz;
offset = dwarf2_get_ref_die_offset (attr);
- per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+ is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
+ per_cu = dwarf2_find_containing_comp_unit (offset, is_dwz, cu->objfile);
- /* Queue the unit, if needed. */
+ /* If necessary, add it to the queue and load its DIEs. */
if (maybe_queue_comp_unit (cu, per_cu, cu->language))
load_full_comp_unit (per_cu, cu->language);
- VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->s.imported_symtabs,
+ VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
per_cu);
}
}
@@ -6920,16 +8059,20 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
case DW_TAG_common_inclusion:
break;
case DW_TAG_namespace:
- processing_has_namespace_info = 1;
+ cu->processing_has_namespace_info = 1;
read_namespace (die, cu);
break;
case DW_TAG_module:
- processing_has_namespace_info = 1;
+ cu->processing_has_namespace_info = 1;
read_module (die, cu);
break;
case DW_TAG_imported_declaration:
+ cu->processing_has_namespace_info = 1;
+ if (read_namespace_alias (die, cu))
+ break;
+ /* The declaration is not a global namespace alias: fall through. */
case DW_TAG_imported_module:
- processing_has_namespace_info = 1;
+ cu->processing_has_namespace_info = 1;
if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
|| cu->language != language_fortran))
complaint (&symfile_complaints, _("Tag '%s' has unexpected children"),
@@ -6946,6 +8089,8 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
break;
}
}
+
+/* DWARF name computation. */
/* A helper function for dwarf2_compute_name which determines whether DIE
needs to have the name of the scope prepended to the name listed in the
@@ -6968,6 +8113,7 @@ die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
case DW_TAG_enumerator:
case DW_TAG_subprogram:
case DW_TAG_member:
+ case DW_TAG_imported_declaration:
return 1;
case DW_TAG_variable:
@@ -7031,7 +8177,8 @@ do_ui_file_peek_last (void *object, const char *buffer, long length)
The result is allocated on the objfile_obstack and canonicalized. */
static const char *
-dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
+dwarf2_compute_name (const char *name,
+ struct die_info *die, struct dwarf2_cu *cu,
int physname)
{
struct objfile *objfile = cu->objfile;
@@ -7115,7 +8262,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
{
struct type *type;
LONGEST value;
- gdb_byte *bytes;
+ const gdb_byte *bytes;
struct dwarf2_locexpr_baton *baton;
struct value *v;
@@ -7143,7 +8290,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
if (child->tag == DW_TAG_template_type_param)
{
- c_print_type (type, "", buf, -1, 0);
+ c_print_type (type, "", buf, -1, 0, &type_print_raw_options);
continue;
}
@@ -7217,7 +8364,8 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
{
struct type *type = read_type_die (die, cu);
- c_type_print_args (type, buf, 1, cu->language);
+ c_type_print_args (type, buf, 1, cu->language,
+ &type_print_raw_options);
if (cu->language == language_java)
{
@@ -7225,7 +8373,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
names. */
if (die->tag == DW_TAG_subprogram)
java_print_type (TYPE_TARGET_TYPE (type), "", buf,
- 0, 0);
+ 0, 0, &type_print_raw_options);
}
else if (cu->language == language_cplus)
{
@@ -7249,7 +8397,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
if (cu->language == language_cplus)
{
- char *cname
+ const char *cname
= dwarf2_canonicalize_name (name, cu,
&objfile->objfile_obstack);
@@ -7271,7 +8419,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
The output string will be canonicalized (if C++/Java). */
static const char *
-dwarf2_full_name (char *name, struct die_info *die, struct dwarf2_cu *cu)
+dwarf2_full_name (const char *name, struct die_info *die, struct dwarf2_cu *cu)
{
return dwarf2_compute_name (name, die, cu, 0);
}
@@ -7284,7 +8432,7 @@ dwarf2_full_name (char *name, struct die_info *die, struct dwarf2_cu *cu)
The output string will be canonicalized (if C++/Java). */
static const char *
-dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
+dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct attribute *attr;
@@ -7329,11 +8477,11 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
}
else
{
- demangled = cplus_demangle (mangled,
- (DMGL_PARAMS | DMGL_ANSI
- | (cu->language == language_java
- ? DMGL_JAVA | DMGL_RET_POSTFIX
- : DMGL_RET_DROP)));
+ demangled = gdb_demangle (mangled,
+ (DMGL_PARAMS | DMGL_ANSI
+ | (cu->language == language_java
+ ? DMGL_JAVA | DMGL_RET_POSTFIX
+ : DMGL_RET_DROP)));
}
if (demangled)
{
@@ -7360,7 +8508,8 @@ 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.sect_off, objfile->name);
+ physname, canon, mangled, die->offset.sect_off,
+ objfile_name (objfile));
/* Prefer DW_AT_linkage_name (in the CANON form) - when it
is available here - over computed PHYSNAME. It is safer
@@ -7378,13 +8527,72 @@ dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
retval = canon;
if (need_copy)
- retval = obsavestring (retval, strlen (retval),
- &objfile->objfile_obstack);
+ retval = obstack_copy0 (&objfile->objfile_obstack, retval, strlen (retval));
do_cleanups (back_to);
return retval;
}
+/* Inspect DIE in CU for a namespace alias. If one exists, record
+ a new symbol for it.
+
+ Returns 1 if a namespace alias was recorded, 0 otherwise. */
+
+static int
+read_namespace_alias (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *attr;
+
+ /* If the die does not have a name, this is not a namespace
+ alias. */
+ attr = dwarf2_attr (die, DW_AT_name, cu);
+ if (attr != NULL)
+ {
+ int num;
+ struct die_info *d = die;
+ struct dwarf2_cu *imported_cu = cu;
+
+ /* If the compiler has nested DW_AT_imported_declaration DIEs,
+ keep inspecting DIEs until we hit the underlying import. */
+#define MAX_NESTED_IMPORTED_DECLARATIONS 100
+ for (num = 0; num < MAX_NESTED_IMPORTED_DECLARATIONS; ++num)
+ {
+ attr = dwarf2_attr (d, DW_AT_import, cu);
+ if (attr == NULL)
+ break;
+
+ d = follow_die_ref (d, attr, &imported_cu);
+ if (d->tag != DW_TAG_imported_declaration)
+ break;
+ }
+
+ if (num == MAX_NESTED_IMPORTED_DECLARATIONS)
+ {
+ complaint (&symfile_complaints,
+ _("DIE at 0x%x has too many recursively imported "
+ "declarations"), d->offset.sect_off);
+ return 0;
+ }
+
+ if (attr != NULL)
+ {
+ struct type *type;
+ sect_offset offset = dwarf2_get_ref_die_offset (attr);
+
+ type = get_die_type_at_offset (offset, cu->per_cu);
+ if (type != NULL && TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
+ {
+ /* This declaration is a global namespace alias. Add
+ a symbol for it whose type is the aliased namespace. */
+ new_symbol (die, type, cu);
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
/* Read the import statement specified by the given die and record it. */
static void
@@ -7403,8 +8611,6 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
VEC (const_char_ptr) *excludes = NULL;
struct cleanup *cleanups;
- char *temp;
-
import_attr = dwarf2_attr (die, DW_AT_import, cu);
if (import_attr == NULL)
{
@@ -7470,14 +8676,9 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
canonical_name = imported_name_prefix;
}
else if (strlen (imported_name_prefix) > 0)
- {
- temp = alloca (strlen (imported_name_prefix)
- + 2 + strlen (imported_name) + 1);
- strcpy (temp, imported_name_prefix);
- strcat (temp, "::");
- strcat (temp, imported_name);
- canonical_name = temp;
- }
+ canonical_name = obconcat (&objfile->objfile_obstack,
+ imported_name_prefix, "::", imported_name,
+ (char *) NULL);
else
canonical_name = imported_name;
@@ -7497,7 +8698,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.sect_off, objfile->name);
+ child_die->offset.sect_off, objfile_name (objfile));
continue;
}
@@ -7518,7 +8719,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.sect_off, objfile->name);
+ child_die->offset.sect_off, objfile_name (objfile));
continue;
}
@@ -7532,6 +8733,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
import_alias,
imported_declaration,
excludes,
+ 0,
&objfile->objfile_obstack);
do_cleanups (cleanups);
@@ -7548,9 +8750,22 @@ free_cu_line_header (void *arg)
cu->line_header = NULL;
}
+/* Check for possibly missing DW_AT_comp_dir with relative .debug_line
+ directory paths. GCC SVN r127613 (new option -fdebug-prefix-map) fixed
+ this, it was first present in GCC release 4.3.0. */
+
+static int
+producer_is_gcc_lt_4_3 (struct dwarf2_cu *cu)
+{
+ if (!cu->checked_producer)
+ check_producer (cu);
+
+ return cu->producer_is_gcc_lt_4_3;
+}
+
static void
find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
- char **name, char **comp_dir)
+ const char **name, const char **comp_dir)
{
struct attribute *attr;
@@ -7568,11 +8783,14 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
attr = dwarf2_attr (die, DW_AT_comp_dir, cu);
if (attr)
*comp_dir = DW_STRING (attr);
- else if (*name != NULL && IS_ABSOLUTE_PATH (*name))
+ else if (producer_is_gcc_lt_4_3 (cu) && *name != NULL
+ && IS_ABSOLUTE_PATH (*name))
{
- *comp_dir = ldirname (*name);
- if (*comp_dir != NULL)
- make_cleanup (xfree, *comp_dir);
+ char *d = ldirname (*name);
+
+ *comp_dir = d;
+ if (d != NULL)
+ make_cleanup (xfree, d);
}
if (*comp_dir != NULL)
{
@@ -7595,7 +8813,7 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
static void
handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
- const char *comp_dir)
+ const char *comp_dir) /* ARI: editCase function */
{
struct attribute *attr;
@@ -7627,8 +8845,8 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
CORE_ADDR lowpc = ((CORE_ADDR) -1);
CORE_ADDR highpc = ((CORE_ADDR) 0);
struct attribute *attr;
- char *name = NULL;
- char *comp_dir = NULL;
+ const char *name = NULL;
+ const char *comp_dir = NULL;
struct die_info *child_die;
bfd *abfd = objfile->obfd;
CORE_ADDR baseaddr;
@@ -7719,16 +8937,18 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
struct line_header *lh;
struct attribute *attr;
unsigned int i, line_offset;
+ struct signatured_type *sig_type;
gdb_assert (per_cu->is_debug_types);
+ sig_type = (struct signatured_type *) per_cu;
attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
/* If we're using .gdb_index (includes -readnow) then
- per_cu->s.type_unit_group may not have been set up yet. */
- if (per_cu->s.type_unit_group == NULL)
- per_cu->s.type_unit_group = get_type_unit_group (cu, attr);
- tu_group = per_cu->s.type_unit_group;
+ per_cu->type_unit_group may not have been set up yet. */
+ if (sig_type->type_unit_group == NULL)
+ sig_type->type_unit_group = get_type_unit_group (cu, attr);
+ tu_group = sig_type->type_unit_group;
/* If we've already processed this stmt_list there's no real need to
do it again, we could fake it and just recreate the part we need
@@ -7769,7 +8989,7 @@ setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
for (i = 0; i < lh->num_file_names; ++i)
{
- char *dir = NULL;
+ const char *dir = NULL;
struct file_entry *fe = &lh->file_names[i];
if (fe->dir_index)
@@ -7840,14 +9060,25 @@ read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
}
}
-/* DWO files. */
+/* DWO/DWP files.
+
+ http://gcc.gnu.org/wiki/DebugFission
+ http://gcc.gnu.org/wiki/DebugFissionDWP
+
+ To simplify handling of both DWO files ("object" files with the DWARF info)
+ and DWP files (a file with the DWOs packaged up into one file), we treat
+ DWP files as having a collection of virtual DWO files. */
static hashval_t
hash_dwo_file (const void *item)
{
const struct dwo_file *dwo_file = item;
+ hashval_t hash;
- return htab_hash_string (dwo_file->dwo_name);
+ hash = htab_hash_string (dwo_file->dwo_name);
+ if (dwo_file->comp_dir != NULL)
+ hash += htab_hash_string (dwo_file->comp_dir);
+ return hash;
}
static int
@@ -7856,7 +9087,11 @@ 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;
+ if (strcmp (lhs->dwo_name, rhs->dwo_name) != 0)
+ return 0;
+ if (lhs->comp_dir == NULL || rhs->comp_dir == NULL)
+ return lhs->comp_dir == rhs->comp_dir;
+ return strcmp (lhs->comp_dir, rhs->comp_dir) == 0;
}
/* Allocate a hash table for DWO files. */
@@ -7875,6 +9110,25 @@ allocate_dwo_file_hash_table (void)
dummy_obstack_deallocate);
}
+/* Lookup DWO file DWO_NAME. */
+
+static void **
+lookup_dwo_file_slot (const char *dwo_name, const char *comp_dir)
+{
+ struct dwo_file find_entry;
+ void **slot;
+
+ if (dwarf2_per_objfile->dwo_files == NULL)
+ dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table ();
+
+ memset (&find_entry, 0, sizeof (find_entry));
+ find_entry.dwo_name = dwo_name;
+ find_entry.comp_dir = comp_dir;
+ slot = htab_find_slot (dwarf2_per_objfile->dwo_files, &find_entry, INSERT);
+
+ return slot;
+}
+
static hashval_t
hash_dwo_unit (const void *item)
{
@@ -7914,145 +9168,66 @@ allocate_dwo_unit_table (struct objfile *objfile)
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->macinfo_dwo))
- {
- dwo_file->sections.macinfo.asection = sectp;
- dwo_file->sections.macinfo.size = bfd_get_section_size (sectp);
- }
- else if (section_is_p (sectp->name, &names->macro_dwo))
- {
- dwo_file->sections.macro.asection = sectp;
- dwo_file->sections.macro.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. */
+/* Structure used to pass data to create_dwo_debug_info_hash_table_reader. */
-struct create_dwo_info_table_data
+struct create_dwo_cu_data
{
struct dwo_file *dwo_file;
- htab_t cu_htab;
+ struct dwo_unit dwo_unit;
};
-/* die_reader_func for create_debug_info_hash_table. */
+/* die_reader_func for create_dwo_cu. */
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)
+create_dwo_cu_reader (const struct die_reader_specs *reader,
+ const 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 dwarf2_section_info *section = cu->per_cu->section;
+ struct create_dwo_cu_data *data = datap;
struct dwo_file *dwo_file = data->dwo_file;
- htab_t cu_htab = data->cu_htab;
- void **slot;
+ struct dwo_unit *dwo_unit = &data->dwo_unit;
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);
+ complaint (&symfile_complaints,
+ _("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->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_read_debug)
- fprintf_unfiltered (gdb_stdlog, " offset 0x%x, dwo_id 0x%s\n",
- offset.sect_off,
- phex (dwo_unit->signature,
- sizeof (dwo_unit->signature)));
+ fprintf_unfiltered (gdb_stdlog, " offset 0x%x, dwo_id %s\n",
+ offset.sect_off, hex_string (dwo_unit->signature));
}
-/* Create a hash table to map DWO IDs to their CU entry in .debug_info.dwo. */
+/* Create the dwo_unit for the lone CU in DWO_FILE.
+ Note: This function processes DWO files only, not DWP files. */
-static htab_t
-create_debug_info_hash_table (struct dwo_file *dwo_file)
+static struct dwo_unit *
+create_dwo_cu (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;
+ const gdb_byte *info_ptr, *end_ptr;
+ struct create_dwo_cu_data create_dwo_cu_data;
+ struct dwo_unit *dwo_unit;
dwarf2_read_section (objfile, section);
info_ptr = section->buffer;
@@ -8062,255 +9237,1520 @@ create_debug_info_hash_table (struct dwo_file *dwo_file)
/* 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;
+ abfd = get_section_bfd_owner (section);
if (dwarf2_read_debug)
- fprintf_unfiltered (gdb_stdlog, "Reading .debug_info.dwo for %s:\n",
- bfd_get_filename (abfd));
-
- cu_htab = allocate_dwo_unit_table (objfile);
+ {
+ fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
+ get_section_name (section),
+ get_section_file_name (section));
+ }
- create_dwo_info_table_data.dwo_file = dwo_file;
- create_dwo_info_table_data.cu_htab = cu_htab;
+ create_dwo_cu_data.dwo_file = dwo_file;
+ dwo_unit = NULL;
end_ptr = info_ptr + section->size;
while (info_ptr < end_ptr)
{
struct dwarf2_per_cu_data per_cu;
+ memset (&create_dwo_cu_data.dwo_unit, 0,
+ sizeof (create_dwo_cu_data.dwo_unit));
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;
+ per_cu.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);
+ create_dwo_cu_reader,
+ &create_dwo_cu_data);
+
+ if (create_dwo_cu_data.dwo_unit.dwo_file != NULL)
+ {
+ /* If we've already found one, complain. We only support one
+ because having more than one requires hacking the dwo_name of
+ each to match, which is highly unlikely to happen. */
+ if (dwo_unit != NULL)
+ {
+ complaint (&symfile_complaints,
+ _("Multiple CUs in DWO file %s [in module %s]"),
+ dwo_file->dwo_name, objfile_name (objfile));
+ break;
+ }
+
+ dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ *dwo_unit = create_dwo_cu_data.dwo_unit;
+ }
info_ptr += per_cu.length;
}
- return cu_htab;
-}
+ return dwo_unit;
+}
+
+/* DWP file .debug_{cu,tu}_index section format:
+ [ref: http://gcc.gnu.org/wiki/DebugFissionDWP]
+
+ DWP Version 1:
+
+ Both index sections have the same format, and serve to map a 64-bit
+ signature to a set of section numbers. Each section begins with a header,
+ followed by a hash table of 64-bit signatures, a parallel table of 32-bit
+ indexes, and a pool of 32-bit section numbers. The index sections will be
+ aligned at 8-byte boundaries in the file.
+
+ The index section header consists of:
+
+ V, 32 bit version number
+ -, 32 bits unused
+ N, 32 bit number of compilation units or type units in the index
+ M, 32 bit number of slots in the hash table
-/* 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. */
+ Numbers are recorded using the byte order of the application binary.
+
+ The hash table begins at offset 16 in the section, and consists of an array
+ of M 64-bit slots. Each slot contains a 64-bit signature (using the byte
+ order of the application binary). Unused slots in the hash table are 0.
+ (We rely on the extreme unlikeliness of a signature being exactly 0.)
-static bfd *
-try_open_dwo_file (const char *file_name)
+ The parallel table begins immediately after the hash table
+ (at offset 16 + 8 * M from the beginning of the section), and consists of an
+ array of 32-bit indexes (using the byte order of the application binary),
+ corresponding 1-1 with slots in the hash table. Each entry in the parallel
+ table contains a 32-bit index into the pool of section numbers. For unused
+ hash table slots, the corresponding entry in the parallel table will be 0.
+
+ The pool of section numbers begins immediately following the hash table
+ (at offset 16 + 12 * M from the beginning of the section). The pool of
+ section numbers consists of an array of 32-bit words (using the byte order
+ of the application binary). Each item in the array is indexed starting
+ from 0. The hash table entry provides the index of the first section
+ number in the set. Additional section numbers in the set follow, and the
+ set is terminated by a 0 entry (section number 0 is not used in ELF).
+
+ In each set of section numbers, the .debug_info.dwo or .debug_types.dwo
+ section must be the first entry in the set, and the .debug_abbrev.dwo must
+ be the second entry. Other members of the set may follow in any order.
+
+ ---
+
+ DWP Version 2:
+
+ DWP Version 2 combines all the .debug_info, etc. sections into one,
+ and the entries in the index tables are now offsets into these sections.
+ CU offsets begin at 0. TU offsets begin at the size of the .debug_info
+ section.
+
+ Index Section Contents:
+ Header
+ Hash Table of Signatures dwp_hash_table.hash_table
+ Parallel Table of Indices dwp_hash_table.unit_table
+ Table of Section Offsets dwp_hash_table.v2.{section_ids,offsets}
+ Table of Section Sizes dwp_hash_table.v2.sizes
+
+ The index section header consists of:
+
+ V, 32 bit version number
+ L, 32 bit number of columns in the table of section offsets
+ N, 32 bit number of compilation units or type units in the index
+ M, 32 bit number of slots in the hash table
+
+ Numbers are recorded using the byte order of the application binary.
+
+ The hash table has the same format as version 1.
+ The parallel table of indices has the same format as version 1,
+ except that the entries are origin-1 indices into the table of sections
+ offsets and the table of section sizes.
+
+ The table of offsets begins immediately following the parallel table
+ (at offset 16 + 12 * M from the beginning of the section). The table is
+ a two-dimensional array of 32-bit words (using the byte order of the
+ application binary), with L columns and N+1 rows, in row-major order.
+ Each row in the array is indexed starting from 0. The first row provides
+ a key to the remaining rows: each column in this row provides an identifier
+ for a debug section, and the offsets in the same column of subsequent rows
+ refer to that section. The section identifiers are:
+
+ DW_SECT_INFO 1 .debug_info.dwo
+ DW_SECT_TYPES 2 .debug_types.dwo
+ DW_SECT_ABBREV 3 .debug_abbrev.dwo
+ DW_SECT_LINE 4 .debug_line.dwo
+ DW_SECT_LOC 5 .debug_loc.dwo
+ DW_SECT_STR_OFFSETS 6 .debug_str_offsets.dwo
+ DW_SECT_MACINFO 7 .debug_macinfo.dwo
+ DW_SECT_MACRO 8 .debug_macro.dwo
+
+ The offsets provided by the CU and TU index sections are the base offsets
+ for the contributions made by each CU or TU to the corresponding section
+ in the package file. Each CU and TU header contains an abbrev_offset
+ field, used to find the abbreviations table for that CU or TU within the
+ contribution to the .debug_abbrev.dwo section for that CU or TU, and should
+ be interpreted as relative to the base offset given in the index section.
+ Likewise, offsets into .debug_line.dwo from DW_AT_stmt_list attributes
+ should be interpreted as relative to the base offset for .debug_line.dwo,
+ and offsets into other debug sections obtained from DWARF attributes should
+ also be interpreted as relative to the corresponding base offset.
+
+ The table of sizes begins immediately following the table of offsets.
+ Like the table of offsets, it is a two-dimensional array of 32-bit words,
+ with L columns and N rows, in row-major order. Each row in the array is
+ indexed starting from 1 (row 0 is shared by the two tables).
+
+ ---
+
+ Hash table lookup is handled the same in version 1 and 2:
+
+ We assume that N and M will not exceed 2^32 - 1.
+ The size of the hash table, M, must be 2^k such that 2^k > 3*N/2.
+
+ Given a 64-bit compilation unit signature or a type signature S, an entry
+ in the hash table is located as follows:
+
+ 1) Calculate a primary hash H = S & MASK(k), where MASK(k) is a mask with
+ the low-order k bits all set to 1.
+
+ 2) Calculate a secondary hash H' = (((S >> 32) & MASK(k)) | 1).
+
+ 3) If the hash table entry at index H matches the signature, use that
+ entry. If the hash table entry at index H is unused (all zeroes),
+ terminate the search: the signature is not present in the table.
+
+ 4) Let H = (H + H') modulo M. Repeat at Step 3.
+
+ Because M > N and H' and M are relatively prime, the search is guaranteed
+ to stop at an unused slot or find the match. */
+
+/* Create a hash table to map DWO IDs to their CU/TU entry in
+ .debug_{info,types}.dwo in DWP_FILE.
+ Returns NULL if there isn't one.
+ Note: This function processes DWP files only, not DWO files. */
+
+static struct dwp_hash_table *
+create_dwp_hash_table (struct dwp_file *dwp_file, int is_debug_types)
{
- bfd *sym_bfd;
- int desc;
- char *absolute_name;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *dbfd = dwp_file->dbfd;
+ const gdb_byte *index_ptr, *index_end;
+ struct dwarf2_section_info *index;
+ uint32_t version, nr_columns, nr_units, nr_slots;
+ struct dwp_hash_table *htab;
+
+ if (is_debug_types)
+ index = &dwp_file->sections.tu_index;
+ else
+ index = &dwp_file->sections.cu_index;
- desc = openp (debug_file_directory, OPF_TRY_CWD_FIRST, file_name,
- O_RDONLY | O_BINARY, &absolute_name);
- if (desc < 0)
+ if (dwarf2_section_empty_p (index))
return NULL;
+ dwarf2_read_section (objfile, index);
+
+ index_ptr = index->buffer;
+ index_end = index_ptr + index->size;
- sym_bfd = bfd_fopen (absolute_name, gnutarget, FOPEN_RB, desc);
- if (!sym_bfd)
+ version = read_4_bytes (dbfd, index_ptr);
+ index_ptr += 4;
+ if (version == 2)
+ nr_columns = read_4_bytes (dbfd, index_ptr);
+ else
+ nr_columns = 0;
+ index_ptr += 4;
+ nr_units = read_4_bytes (dbfd, index_ptr);
+ index_ptr += 4;
+ nr_slots = read_4_bytes (dbfd, index_ptr);
+ index_ptr += 4;
+
+ if (version != 1 && version != 2)
{
- xfree (absolute_name);
- return NULL;
+ error (_("Dwarf Error: unsupported DWP file version (%s)"
+ " [in module %s]"),
+ pulongest (version), dwp_file->name);
}
+ if (nr_slots != (nr_slots & -nr_slots))
+ {
+ error (_("Dwarf Error: number of slots in DWP hash table (%s)"
+ " is not power of 2 [in module %s]"),
+ pulongest (nr_slots), dwp_file->name);
+ }
+
+ htab = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_hash_table);
+ htab->version = version;
+ htab->nr_columns = nr_columns;
+ htab->nr_units = nr_units;
+ htab->nr_slots = nr_slots;
+ htab->hash_table = index_ptr;
+ htab->unit_table = htab->hash_table + sizeof (uint64_t) * nr_slots;
+
+ /* Exit early if the table is empty. */
+ if (nr_slots == 0 || nr_units == 0
+ || (version == 2 && nr_columns == 0))
+ {
+ /* All must be zero. */
+ if (nr_slots != 0 || nr_units != 0
+ || (version == 2 && nr_columns != 0))
+ {
+ complaint (&symfile_complaints,
+ _("Empty DWP but nr_slots,nr_units,nr_columns not"
+ " all zero [in modules %s]"),
+ dwp_file->name);
+ }
+ return htab;
+ }
+
+ if (version == 1)
+ {
+ htab->section_pool.v1.indices =
+ htab->unit_table + sizeof (uint32_t) * nr_slots;
+ /* It's harder to decide whether the section is too small in v1.
+ V1 is deprecated anyway so we punt. */
+ }
+ else
+ {
+ const gdb_byte *ids_ptr = htab->unit_table + sizeof (uint32_t) * nr_slots;
+ int *ids = htab->section_pool.v2.section_ids;
+ /* Reverse map for error checking. */
+ int ids_seen[DW_SECT_MAX + 1];
+ int i;
+
+ if (nr_columns < 2)
+ {
+ error (_("Dwarf Error: bad DWP hash table, too few columns"
+ " in section table [in module %s]"),
+ dwp_file->name);
+ }
+ if (nr_columns > MAX_NR_V2_DWO_SECTIONS)
+ {
+ error (_("Dwarf Error: bad DWP hash table, too many columns"
+ " in section table [in module %s]"),
+ dwp_file->name);
+ }
+ memset (ids, 255, (DW_SECT_MAX + 1) * sizeof (int32_t));
+ memset (ids_seen, 255, (DW_SECT_MAX + 1) * sizeof (int32_t));
+ for (i = 0; i < nr_columns; ++i)
+ {
+ int id = read_4_bytes (dbfd, ids_ptr + i * sizeof (uint32_t));
+
+ if (id < DW_SECT_MIN || id > DW_SECT_MAX)
+ {
+ error (_("Dwarf Error: bad DWP hash table, bad section id %d"
+ " in section table [in module %s]"),
+ id, dwp_file->name);
+ }
+ if (ids_seen[id] != -1)
+ {
+ error (_("Dwarf Error: bad DWP hash table, duplicate section"
+ " id %d in section table [in module %s]"),
+ id, dwp_file->name);
+ }
+ ids_seen[id] = i;
+ ids[i] = id;
+ }
+ /* Must have exactly one info or types section. */
+ if (((ids_seen[DW_SECT_INFO] != -1)
+ + (ids_seen[DW_SECT_TYPES] != -1))
+ != 1)
+ {
+ error (_("Dwarf Error: bad DWP hash table, missing/duplicate"
+ " DWO info/types section [in module %s]"),
+ dwp_file->name);
+ }
+ /* Must have an abbrev section. */
+ if (ids_seen[DW_SECT_ABBREV] == -1)
+ {
+ error (_("Dwarf Error: bad DWP hash table, missing DWO abbrev"
+ " section [in module %s]"),
+ dwp_file->name);
+ }
+ htab->section_pool.v2.offsets = ids_ptr + sizeof (uint32_t) * nr_columns;
+ htab->section_pool.v2.sizes =
+ htab->section_pool.v2.offsets + (sizeof (uint32_t)
+ * nr_units * nr_columns);
+ if ((htab->section_pool.v2.sizes + (sizeof (uint32_t)
+ * nr_units * nr_columns))
+ > index_end)
+ {
+ error (_("Dwarf Error: DWP index section is corrupt (too small)"
+ " [in module %s]"),
+ dwp_file->name);
+ }
+ }
+
+ return htab;
+}
+
+/* Update SECTIONS with the data from SECTP.
+
+ This function is like the other "locate" section routines that are
+ passed to bfd_map_over_sections, but in this context the sections to
+ read comes from the DWP V1 hash table, not the full ELF section table.
+
+ The result is non-zero for success, or zero if an error was found. */
+
+static int
+locate_v1_virtual_dwo_sections (asection *sectp,
+ struct virtual_v1_dwo_sections *sections)
+{
+ const struct dwop_section_names *names = &dwop_section_names;
+
+ if (section_is_p (sectp->name, &names->abbrev_dwo))
+ {
+ /* There can be only one. */
+ if (sections->abbrev.s.asection != NULL)
+ return 0;
+ sections->abbrev.s.asection = sectp;
+ sections->abbrev.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->info_dwo)
+ || section_is_p (sectp->name, &names->types_dwo))
+ {
+ /* There can be only one. */
+ if (sections->info_or_types.s.asection != NULL)
+ return 0;
+ sections->info_or_types.s.asection = sectp;
+ sections->info_or_types.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->line_dwo))
+ {
+ /* There can be only one. */
+ if (sections->line.s.asection != NULL)
+ return 0;
+ sections->line.s.asection = sectp;
+ sections->line.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->loc_dwo))
+ {
+ /* There can be only one. */
+ if (sections->loc.s.asection != NULL)
+ return 0;
+ sections->loc.s.asection = sectp;
+ sections->loc.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macinfo_dwo))
+ {
+ /* There can be only one. */
+ if (sections->macinfo.s.asection != NULL)
+ return 0;
+ sections->macinfo.s.asection = sectp;
+ sections->macinfo.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macro_dwo))
+ {
+ /* There can be only one. */
+ if (sections->macro.s.asection != NULL)
+ return 0;
+ sections->macro.s.asection = sectp;
+ sections->macro.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+ {
+ /* There can be only one. */
+ if (sections->str_offsets.s.asection != NULL)
+ return 0;
+ sections->str_offsets.s.asection = sectp;
+ sections->str_offsets.size = bfd_get_section_size (sectp);
+ }
+ else
+ {
+ /* No other kind of section is valid. */
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Create a dwo_unit object for the DWO unit with signature SIGNATURE.
+ UNIT_INDEX is the index of the DWO unit in the DWP hash table.
+ COMP_DIR is the DW_AT_comp_dir attribute of the referencing CU.
+ This is for DWP version 1 files. */
+
+static struct dwo_unit *
+create_dwo_unit_in_dwp_v1 (struct dwp_file *dwp_file,
+ uint32_t unit_index,
+ const char *comp_dir,
+ ULONGEST signature, int is_debug_types)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ const struct dwp_hash_table *dwp_htab =
+ is_debug_types ? dwp_file->tus : dwp_file->cus;
+ bfd *dbfd = dwp_file->dbfd;
+ const char *kind = is_debug_types ? "TU" : "CU";
+ struct dwo_file *dwo_file;
+ struct dwo_unit *dwo_unit;
+ struct virtual_v1_dwo_sections sections;
+ void **dwo_file_slot;
+ char *virtual_dwo_name;
+ struct dwarf2_section_info *cutu;
+ struct cleanup *cleanups;
+ int i;
+
+ gdb_assert (dwp_file->version == 1);
+
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Reading %s %s/%s in DWP V1 file: %s\n",
+ kind,
+ pulongest (unit_index), hex_string (signature),
+ dwp_file->name);
+ }
+
+ /* Fetch the sections of this DWO unit.
+ Put a limit on the number of sections we look for so that bad data
+ doesn't cause us to loop forever. */
+
+#define MAX_NR_V1_DWO_SECTIONS \
+ (1 /* .debug_info or .debug_types */ \
+ + 1 /* .debug_abbrev */ \
+ + 1 /* .debug_line */ \
+ + 1 /* .debug_loc */ \
+ + 1 /* .debug_str_offsets */ \
+ + 1 /* .debug_macro or .debug_macinfo */ \
+ + 1 /* trailing zero */)
+
+ memset (&sections, 0, sizeof (sections));
+ cleanups = make_cleanup (null_cleanup, 0);
+
+ for (i = 0; i < MAX_NR_V1_DWO_SECTIONS; ++i)
+ {
+ asection *sectp;
+ uint32_t section_nr =
+ read_4_bytes (dbfd,
+ dwp_htab->section_pool.v1.indices
+ + (unit_index + i) * sizeof (uint32_t));
+
+ if (section_nr == 0)
+ break;
+ if (section_nr >= dwp_file->num_sections)
+ {
+ error (_("Dwarf Error: bad DWP hash table, section number too large"
+ " [in module %s]"),
+ dwp_file->name);
+ }
+
+ sectp = dwp_file->elf_sections[section_nr];
+ if (! locate_v1_virtual_dwo_sections (sectp, &sections))
+ {
+ error (_("Dwarf Error: bad DWP hash table, invalid section found"
+ " [in module %s]"),
+ dwp_file->name);
+ }
+ }
+
+ if (i < 2
+ || dwarf2_section_empty_p (&sections.info_or_types)
+ || dwarf2_section_empty_p (&sections.abbrev))
+ {
+ error (_("Dwarf Error: bad DWP hash table, missing DWO sections"
+ " [in module %s]"),
+ dwp_file->name);
+ }
+ if (i == MAX_NR_V1_DWO_SECTIONS)
+ {
+ error (_("Dwarf Error: bad DWP hash table, too many DWO sections"
+ " [in module %s]"),
+ dwp_file->name);
+ }
+
+ /* It's easier for the rest of the code if we fake a struct dwo_file and
+ have dwo_unit "live" in that. At least for now.
+
+ The DWP file can be made up of a random collection of CUs and TUs.
+ However, for each CU + set of TUs that came from the same original DWO
+ file, we can combine them back into a virtual DWO file to save space
+ (fewer struct dwo_file objects to allocate). Remember that for really
+ large apps there can be on the order of 8K CUs and 200K TUs, or more. */
+
+ virtual_dwo_name =
+ xstrprintf ("virtual-dwo/%d-%d-%d-%d",
+ get_section_id (&sections.abbrev),
+ get_section_id (&sections.line),
+ get_section_id (&sections.loc),
+ get_section_id (&sections.str_offsets));
+ make_cleanup (xfree, virtual_dwo_name);
+ /* Can we use an existing virtual DWO file? */
+ dwo_file_slot = lookup_dwo_file_slot (virtual_dwo_name, comp_dir);
+ /* Create one if necessary. */
+ if (*dwo_file_slot == NULL)
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
+ virtual_dwo_name);
+ }
+ dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
+ dwo_file->dwo_name = obstack_copy0 (&objfile->objfile_obstack,
+ virtual_dwo_name,
+ strlen (virtual_dwo_name));
+ dwo_file->comp_dir = comp_dir;
+ dwo_file->sections.abbrev = sections.abbrev;
+ dwo_file->sections.line = sections.line;
+ dwo_file->sections.loc = sections.loc;
+ dwo_file->sections.macinfo = sections.macinfo;
+ dwo_file->sections.macro = sections.macro;
+ dwo_file->sections.str_offsets = sections.str_offsets;
+ /* The "str" section is global to the entire DWP file. */
+ dwo_file->sections.str = dwp_file->sections.str;
+ /* The info or types section is assigned below to dwo_unit,
+ there's no need to record it in dwo_file.
+ Also, we can't simply record type sections in dwo_file because
+ we record a pointer into the vector in dwo_unit. As we collect more
+ types we'll grow the vector and eventually have to reallocate space
+ for it, invalidating all copies of pointers into the previous
+ contents. */
+ *dwo_file_slot = dwo_file;
+ }
+ else
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
+ virtual_dwo_name);
+ }
+ dwo_file = *dwo_file_slot;
+ }
+ do_cleanups (cleanups);
+
+ dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ dwo_unit->dwo_file = dwo_file;
+ dwo_unit->signature = signature;
+ dwo_unit->section = obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct dwarf2_section_info));
+ *dwo_unit->section = sections.info_or_types;
+ /* dwo_unit->{offset,length,type_offset_in_tu} are set later. */
+
+ return dwo_unit;
+}
+
+/* Subroutine of create_dwo_unit_in_dwp_v2 to simplify it.
+ Given a pointer to the containing section SECTION, and OFFSET,SIZE of the
+ piece within that section used by a TU/CU, return a virtual section
+ of just that piece. */
+
+static struct dwarf2_section_info
+create_dwp_v2_section (struct dwarf2_section_info *section,
+ bfd_size_type offset, bfd_size_type size)
+{
+ struct dwarf2_section_info result;
+ asection *sectp;
+
+ gdb_assert (section != NULL);
+ gdb_assert (!section->is_virtual);
+
+ memset (&result, 0, sizeof (result));
+ result.s.containing_section = section;
+ result.is_virtual = 1;
+
+ if (size == 0)
+ return result;
+
+ sectp = get_section_bfd_section (section);
+
+ /* Flag an error if the piece denoted by OFFSET,SIZE is outside the
+ bounds of the real section. This is a pretty-rare event, so just
+ flag an error (easier) instead of a warning and trying to cope. */
+ if (sectp == NULL
+ || offset + size > bfd_get_section_size (sectp))
+ {
+ bfd *abfd = sectp->owner;
+
+ error (_("Dwarf Error: Bad DWP V2 section info, doesn't fit"
+ " in section %s [in module %s]"),
+ sectp ? bfd_section_name (abfd, sectp) : "<unknown>",
+ objfile_name (dwarf2_per_objfile->objfile));
+ }
+
+ result.virtual_offset = offset;
+ result.size = size;
+ return result;
+}
+
+/* Create a dwo_unit object for the DWO unit with signature SIGNATURE.
+ UNIT_INDEX is the index of the DWO unit in the DWP hash table.
+ COMP_DIR is the DW_AT_comp_dir attribute of the referencing CU.
+ This is for DWP version 2 files. */
+
+static struct dwo_unit *
+create_dwo_unit_in_dwp_v2 (struct dwp_file *dwp_file,
+ uint32_t unit_index,
+ const char *comp_dir,
+ ULONGEST signature, int is_debug_types)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ const struct dwp_hash_table *dwp_htab =
+ is_debug_types ? dwp_file->tus : dwp_file->cus;
+ bfd *dbfd = dwp_file->dbfd;
+ const char *kind = is_debug_types ? "TU" : "CU";
+ struct dwo_file *dwo_file;
+ struct dwo_unit *dwo_unit;
+ struct virtual_v2_dwo_sections sections;
+ void **dwo_file_slot;
+ char *virtual_dwo_name;
+ struct dwarf2_section_info *cutu;
+ struct cleanup *cleanups;
+ int i;
+
+ gdb_assert (dwp_file->version == 2);
+
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Reading %s %s/%s in DWP V2 file: %s\n",
+ kind,
+ pulongest (unit_index), hex_string (signature),
+ dwp_file->name);
+ }
+
+ /* Fetch the section offsets of this DWO unit. */
+
+ memset (&sections, 0, sizeof (sections));
+ cleanups = make_cleanup (null_cleanup, 0);
+
+ for (i = 0; i < dwp_htab->nr_columns; ++i)
+ {
+ uint32_t offset = read_4_bytes (dbfd,
+ dwp_htab->section_pool.v2.offsets
+ + (((unit_index - 1) * dwp_htab->nr_columns
+ + i)
+ * sizeof (uint32_t)));
+ uint32_t size = read_4_bytes (dbfd,
+ dwp_htab->section_pool.v2.sizes
+ + (((unit_index - 1) * dwp_htab->nr_columns
+ + i)
+ * sizeof (uint32_t)));
+
+ switch (dwp_htab->section_pool.v2.section_ids[i])
+ {
+ case DW_SECT_INFO:
+ case DW_SECT_TYPES:
+ sections.info_or_types_offset = offset;
+ sections.info_or_types_size = size;
+ break;
+ case DW_SECT_ABBREV:
+ sections.abbrev_offset = offset;
+ sections.abbrev_size = size;
+ break;
+ case DW_SECT_LINE:
+ sections.line_offset = offset;
+ sections.line_size = size;
+ break;
+ case DW_SECT_LOC:
+ sections.loc_offset = offset;
+ sections.loc_size = size;
+ break;
+ case DW_SECT_STR_OFFSETS:
+ sections.str_offsets_offset = offset;
+ sections.str_offsets_size = size;
+ break;
+ case DW_SECT_MACINFO:
+ sections.macinfo_offset = offset;
+ sections.macinfo_size = size;
+ break;
+ case DW_SECT_MACRO:
+ sections.macro_offset = offset;
+ sections.macro_size = size;
+ break;
+ }
+ }
+
+ /* It's easier for the rest of the code if we fake a struct dwo_file and
+ have dwo_unit "live" in that. At least for now.
+
+ The DWP file can be made up of a random collection of CUs and TUs.
+ However, for each CU + set of TUs that came from the same original DWO
+ file, we can combine them back into a virtual DWO file to save space
+ (fewer struct dwo_file objects to allocate). Remember that for really
+ large apps there can be on the order of 8K CUs and 200K TUs, or more. */
+
+ virtual_dwo_name =
+ xstrprintf ("virtual-dwo/%ld-%ld-%ld-%ld",
+ (long) (sections.abbrev_size ? sections.abbrev_offset : 0),
+ (long) (sections.line_size ? sections.line_offset : 0),
+ (long) (sections.loc_size ? sections.loc_offset : 0),
+ (long) (sections.str_offsets_size
+ ? sections.str_offsets_offset : 0));
+ make_cleanup (xfree, virtual_dwo_name);
+ /* Can we use an existing virtual DWO file? */
+ dwo_file_slot = lookup_dwo_file_slot (virtual_dwo_name, comp_dir);
+ /* Create one if necessary. */
+ if (*dwo_file_slot == NULL)
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
+ virtual_dwo_name);
+ }
+ dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
+ dwo_file->dwo_name = obstack_copy0 (&objfile->objfile_obstack,
+ virtual_dwo_name,
+ strlen (virtual_dwo_name));
+ dwo_file->comp_dir = comp_dir;
+ dwo_file->sections.abbrev =
+ create_dwp_v2_section (&dwp_file->sections.abbrev,
+ sections.abbrev_offset, sections.abbrev_size);
+ dwo_file->sections.line =
+ create_dwp_v2_section (&dwp_file->sections.line,
+ sections.line_offset, sections.line_size);
+ dwo_file->sections.loc =
+ create_dwp_v2_section (&dwp_file->sections.loc,
+ sections.loc_offset, sections.loc_size);
+ dwo_file->sections.macinfo =
+ create_dwp_v2_section (&dwp_file->sections.macinfo,
+ sections.macinfo_offset, sections.macinfo_size);
+ dwo_file->sections.macro =
+ create_dwp_v2_section (&dwp_file->sections.macro,
+ sections.macro_offset, sections.macro_size);
+ dwo_file->sections.str_offsets =
+ create_dwp_v2_section (&dwp_file->sections.str_offsets,
+ sections.str_offsets_offset,
+ sections.str_offsets_size);
+ /* The "str" section is global to the entire DWP file. */
+ dwo_file->sections.str = dwp_file->sections.str;
+ /* The info or types section is assigned below to dwo_unit,
+ there's no need to record it in dwo_file.
+ Also, we can't simply record type sections in dwo_file because
+ we record a pointer into the vector in dwo_unit. As we collect more
+ types we'll grow the vector and eventually have to reallocate space
+ for it, invalidating all copies of pointers into the previous
+ contents. */
+ *dwo_file_slot = dwo_file;
+ }
+ else
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
+ virtual_dwo_name);
+ }
+ dwo_file = *dwo_file_slot;
+ }
+ do_cleanups (cleanups);
+
+ dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ dwo_unit->dwo_file = dwo_file;
+ dwo_unit->signature = signature;
+ dwo_unit->section = obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct dwarf2_section_info));
+ *dwo_unit->section = create_dwp_v2_section (is_debug_types
+ ? &dwp_file->sections.types
+ : &dwp_file->sections.info,
+ sections.info_or_types_offset,
+ sections.info_or_types_size);
+ /* dwo_unit->{offset,length,type_offset_in_tu} are set later. */
+
+ return dwo_unit;
+}
+
+/* Lookup the DWO unit with SIGNATURE in DWP_FILE.
+ Returns NULL if the signature isn't found. */
+
+static struct dwo_unit *
+lookup_dwo_unit_in_dwp (struct dwp_file *dwp_file, const char *comp_dir,
+ ULONGEST signature, int is_debug_types)
+{
+ const struct dwp_hash_table *dwp_htab =
+ is_debug_types ? dwp_file->tus : dwp_file->cus;
+ bfd *dbfd = dwp_file->dbfd;
+ uint32_t mask = dwp_htab->nr_slots - 1;
+ uint32_t hash = signature & mask;
+ uint32_t hash2 = ((signature >> 32) & mask) | 1;
+ unsigned int i;
+ void **slot;
+ struct dwo_unit find_dwo_cu, *dwo_cu;
+
+ memset (&find_dwo_cu, 0, sizeof (find_dwo_cu));
+ find_dwo_cu.signature = signature;
+ slot = htab_find_slot (is_debug_types
+ ? dwp_file->loaded_tus
+ : dwp_file->loaded_cus,
+ &find_dwo_cu, INSERT);
+
+ if (*slot != NULL)
+ return *slot;
+
+ /* Use a for loop so that we don't loop forever on bad debug info. */
+ for (i = 0; i < dwp_htab->nr_slots; ++i)
+ {
+ ULONGEST signature_in_table;
+
+ signature_in_table =
+ read_8_bytes (dbfd, dwp_htab->hash_table + hash * sizeof (uint64_t));
+ if (signature_in_table == signature)
+ {
+ uint32_t unit_index =
+ read_4_bytes (dbfd,
+ dwp_htab->unit_table + hash * sizeof (uint32_t));
+
+ if (dwp_file->version == 1)
+ {
+ *slot = create_dwo_unit_in_dwp_v1 (dwp_file, unit_index,
+ comp_dir, signature,
+ is_debug_types);
+ }
+ else
+ {
+ *slot = create_dwo_unit_in_dwp_v2 (dwp_file, unit_index,
+ comp_dir, signature,
+ is_debug_types);
+ }
+ return *slot;
+ }
+ if (signature_in_table == 0)
+ return NULL;
+ hash = (hash + hash2) & mask;
+ }
+
+ error (_("Dwarf Error: bad DWP hash table, lookup didn't terminate"
+ " [in module %s]"),
+ dwp_file->name);
+}
+
+/* Subroutine of open_dwo_file,open_dwp_file to simplify them.
+ Open the file specified by FILE_NAME and hand it off to BFD for
+ preliminary analysis. Return a newly initialized bfd *, which
+ includes a canonicalized copy of FILE_NAME.
+ If IS_DWP is TRUE, we're opening a DWP file, otherwise a DWO file.
+ SEARCH_CWD is true if the current directory is to be searched.
+ It will be searched before debug-file-directory.
+ If unable to find/open the file, return NULL.
+ NOTE: This function is derived from symfile_bfd_open. */
+
+static bfd *
+try_open_dwop_file (const char *file_name, int is_dwp, int search_cwd)
+{
+ bfd *sym_bfd;
+ int desc, flags;
+ char *absolute_name;
+ /* Blech. OPF_TRY_CWD_FIRST also disables searching the path list if
+ FILE_NAME contains a '/'. So we can't use it. Instead prepend "."
+ to debug_file_directory. */
+ char *search_path;
+ static const char dirname_separator_string[] = { DIRNAME_SEPARATOR, '\0' };
+
+ if (search_cwd)
+ {
+ if (*debug_file_directory != '\0')
+ search_path = concat (".", dirname_separator_string,
+ debug_file_directory, NULL);
+ else
+ search_path = xstrdup (".");
+ }
+ else
+ search_path = xstrdup (debug_file_directory);
+
+ flags = OPF_RETURN_REALPATH;
+ if (is_dwp)
+ flags |= OPF_SEARCH_IN_PATH;
+ desc = openp (search_path, flags, file_name,
+ O_RDONLY | O_BINARY, &absolute_name);
+ xfree (search_path);
+ if (desc < 0)
+ return NULL;
+
+ sym_bfd = gdb_bfd_open (absolute_name, gnutarget, desc);
+ xfree (absolute_name);
+ if (sym_bfd == NULL)
+ 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);
+ gdb_bfd_unref (sym_bfd); /* This also closes desc. */
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.
+/* Try to open DWO file FILE_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 *file_name, const char *comp_dir)
+{
+ bfd *abfd;
+
+ if (IS_ABSOLUTE_PATH (file_name))
+ return try_open_dwop_file (file_name, 0 /*is_dwp*/, 0 /*search_cwd*/);
+
+ /* Before trying the search path, try DWO_NAME in COMP_DIR. */
+
+ if (comp_dir != NULL)
+ {
+ char *path_to_try = concat (comp_dir, SLASH_STRING, file_name, NULL);
+
+ /* NOTE: If comp_dir is a relative path, this will also try the
+ search path, which seems useful. */
+ abfd = try_open_dwop_file (path_to_try, 0 /*is_dwp*/, 1 /*search_cwd*/);
+ 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_dwop_file (file_name, 0 /*is_dwp*/, 1 /*search_cwd*/);
+}
+
+/* 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_sections_ptr)
+{
+ struct dwo_sections *dwo_sections = dwo_sections_ptr;
+ const struct dwop_section_names *names = &dwop_section_names;
+
+ if (section_is_p (sectp->name, &names->abbrev_dwo))
+ {
+ dwo_sections->abbrev.s.asection = sectp;
+ dwo_sections->abbrev.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->info_dwo))
+ {
+ dwo_sections->info.s.asection = sectp;
+ dwo_sections->info.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->line_dwo))
+ {
+ dwo_sections->line.s.asection = sectp;
+ dwo_sections->line.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->loc_dwo))
+ {
+ dwo_sections->loc.s.asection = sectp;
+ dwo_sections->loc.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macinfo_dwo))
+ {
+ dwo_sections->macinfo.s.asection = sectp;
+ dwo_sections->macinfo.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macro_dwo))
+ {
+ dwo_sections->macro.s.asection = sectp;
+ dwo_sections->macro.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_dwo))
+ {
+ dwo_sections->str.s.asection = sectp;
+ dwo_sections->str.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+ {
+ dwo_sections->str_offsets.s.asection = sectp;
+ dwo_sections->str_offsets.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->types_dwo))
+ {
+ struct dwarf2_section_info type_section;
+
+ memset (&type_section, 0, sizeof (type_section));
+ type_section.s.asection = sectp;
+ type_section.size = bfd_get_section_size (sectp);
+ VEC_safe_push (dwarf2_section_info_def, dwo_sections->types,
+ &type_section);
+ }
+}
+
+/* Initialize the use of the DWO file specified by DWO_NAME and referenced
+ by PER_CU. This is for the non-DWP case.
+ The result is NULL if DWO_NAME can't be found. */
+
+static struct dwo_file *
+open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu,
+ const char *dwo_name, const char *comp_dir)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwo_file *dwo_file;
+ bfd *dbfd;
+ struct cleanup *cleanups;
+
+ dbfd = open_dwo_file (dwo_name, comp_dir);
+ if (dbfd == NULL)
+ {
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "DWO file not found: %s\n", dwo_name);
+ return NULL;
+ }
+ dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
+ dwo_file->dwo_name = dwo_name;
+ dwo_file->comp_dir = comp_dir;
+ dwo_file->dbfd = dbfd;
+
+ cleanups = make_cleanup (free_dwo_file_cleanup, dwo_file);
+
+ bfd_map_over_sections (dbfd, dwarf2_locate_dwo_sections, &dwo_file->sections);
+
+ dwo_file->cu = create_dwo_cu (dwo_file);
+
+ dwo_file->tus = create_debug_types_hash_table (dwo_file,
+ dwo_file->sections.types);
+
+ discard_cleanups (cleanups);
+
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "DWO file found: %s\n", dwo_name);
+
+ return dwo_file;
+}
+
+/* This function is mapped across the sections and remembers the offset and
+ size of each of the DWP debugging sections common to version 1 and 2 that
+ we are interested in. */
+
+static void
+dwarf2_locate_common_dwp_sections (bfd *abfd, asection *sectp,
+ void *dwp_file_ptr)
+{
+ struct dwp_file *dwp_file = dwp_file_ptr;
+ const struct dwop_section_names *names = &dwop_section_names;
+ unsigned int elf_section_nr = elf_section_data (sectp)->this_idx;
+
+ /* Record the ELF section number for later lookup: this is what the
+ .debug_cu_index,.debug_tu_index tables use in DWP V1. */
+ gdb_assert (elf_section_nr < dwp_file->num_sections);
+ dwp_file->elf_sections[elf_section_nr] = sectp;
+
+ /* Look for specific sections that we need. */
+ if (section_is_p (sectp->name, &names->str_dwo))
+ {
+ dwp_file->sections.str.s.asection = sectp;
+ dwp_file->sections.str.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->cu_index))
+ {
+ dwp_file->sections.cu_index.s.asection = sectp;
+ dwp_file->sections.cu_index.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->tu_index))
+ {
+ dwp_file->sections.tu_index.s.asection = sectp;
+ dwp_file->sections.tu_index.size = bfd_get_section_size (sectp);
+ }
+}
+
+/* This function is mapped across the sections and remembers the offset and
+ size of each of the DWP version 2 debugging sections that we are interested
+ in. This is split into a separate function because we don't know if we
+ have version 1 or 2 until we parse the cu_index/tu_index sections. */
+
+static void
+dwarf2_locate_v2_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
+{
+ struct dwp_file *dwp_file = dwp_file_ptr;
+ const struct dwop_section_names *names = &dwop_section_names;
+ unsigned int elf_section_nr = elf_section_data (sectp)->this_idx;
+
+ /* Record the ELF section number for later lookup: this is what the
+ .debug_cu_index,.debug_tu_index tables use in DWP V1. */
+ gdb_assert (elf_section_nr < dwp_file->num_sections);
+ dwp_file->elf_sections[elf_section_nr] = sectp;
+
+ /* Look for specific sections that we need. */
+ if (section_is_p (sectp->name, &names->abbrev_dwo))
+ {
+ dwp_file->sections.abbrev.s.asection = sectp;
+ dwp_file->sections.abbrev.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->info_dwo))
+ {
+ dwp_file->sections.info.s.asection = sectp;
+ dwp_file->sections.info.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->line_dwo))
+ {
+ dwp_file->sections.line.s.asection = sectp;
+ dwp_file->sections.line.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->loc_dwo))
+ {
+ dwp_file->sections.loc.s.asection = sectp;
+ dwp_file->sections.loc.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macinfo_dwo))
+ {
+ dwp_file->sections.macinfo.s.asection = sectp;
+ dwp_file->sections.macinfo.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macro_dwo))
+ {
+ dwp_file->sections.macro.s.asection = sectp;
+ dwp_file->sections.macro.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+ {
+ dwp_file->sections.str_offsets.s.asection = sectp;
+ dwp_file->sections.str_offsets.size = bfd_get_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->types_dwo))
+ {
+ dwp_file->sections.types.s.asection = sectp;
+ dwp_file->sections.types.size = bfd_get_section_size (sectp);
+ }
+}
+
+/* Hash function for dwp_file loaded CUs/TUs. */
+
+static hashval_t
+hash_dwp_loaded_cutus (const void *item)
+{
+ const struct dwo_unit *dwo_unit = item;
+
+ /* This drops the top 32 bits of the signature, but is ok for a hash. */
+ return dwo_unit->signature;
+}
+
+/* Equality function for dwp_file loaded CUs/TUs. */
+
+static int
+eq_dwp_loaded_cutus (const void *a, const void *b)
+{
+ const struct dwo_unit *dua = a;
+ const struct dwo_unit *dub = b;
+
+ return dua->signature == dub->signature;
+}
+
+/* Allocate a hash table for dwp_file loaded CUs/TUs. */
+
+static htab_t
+allocate_dwp_loaded_cutus_table (struct objfile *objfile)
+{
+ return htab_create_alloc_ex (3,
+ hash_dwp_loaded_cutus,
+ eq_dwp_loaded_cutus,
+ NULL,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+}
+
+/* Try to open DWP file FILE_NAME.
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)
+open_dwp_file (const char *file_name)
{
bfd *abfd;
- if (IS_ABSOLUTE_PATH (dwo_name))
- return try_open_dwo_file (dwo_name);
+ abfd = try_open_dwop_file (file_name, 1 /*is_dwp*/, 1 /*search_cwd*/);
+ if (abfd != NULL)
+ return abfd;
- /* Before trying the search path, try DWO_NAME in COMP_DIR. */
-
- if (comp_dir != NULL)
+ /* Work around upstream bug 15652.
+ http://sourceware.org/bugzilla/show_bug.cgi?id=15652
+ [Whether that's a "bug" is debatable, but it is getting in our way.]
+ We have no real idea where the dwp file is, because gdb's realpath-ing
+ of the executable's path may have discarded the needed info.
+ [IWBN if the dwp file name was recorded in the executable, akin to
+ .gnu_debuglink, but that doesn't exist yet.]
+ Strip the directory from FILE_NAME and search again. */
+ if (*debug_file_directory != '\0')
{
- 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;
+ /* Don't implicitly search the current directory here.
+ If the user wants to search "." to handle this case,
+ it must be added to debug-file-directory. */
+ return try_open_dwop_file (lbasename (file_name), 1 /*is_dwp*/,
+ 0 /*search_cwd*/);
}
- /* 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);
+ return NULL;
}
-/* Initialize the use of the DWO file specified by DWO_NAME. */
+/* Initialize the use of the DWP file for the current objfile.
+ By convention the name of the DWP file is ${objfile}.dwp.
+ The result is NULL if it can't be found. */
-static struct dwo_file *
-init_dwo_file (const char *dwo_name, const char *comp_dir)
+static struct dwp_file *
+open_and_init_dwp_file (void)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct dwo_file *dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwo_file);
- bfd *abfd;
+ struct dwp_file *dwp_file;
+ char *dwp_name;
+ bfd *dbfd;
struct cleanup *cleanups;
- if (dwarf2_read_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;
+ /* Try to find first .dwp for the binary file before any symbolic links
+ resolving. */
+ dwp_name = xstrprintf ("%s.dwp", objfile->original_name);
+ cleanups = make_cleanup (xfree, dwp_name);
- cleanups = make_cleanup (free_dwo_file_cleanup, dwo_file);
+ dbfd = open_dwp_file (dwp_name);
+ if (dbfd == NULL
+ && strcmp (objfile->original_name, objfile_name (objfile)) != 0)
+ {
+ /* Try to find .dwp for the binary file after gdb_realpath resolving. */
+ dwp_name = xstrprintf ("%s.dwp", objfile_name (objfile));
+ make_cleanup (xfree, dwp_name);
+ dbfd = open_dwp_file (dwp_name);
+ }
- bfd_map_over_sections (abfd, dwarf2_locate_dwo_sections, dwo_file);
+ if (dbfd == NULL)
+ {
+ if (dwarf2_read_debug)
+ fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name);
+ do_cleanups (cleanups);
+ return NULL;
+ }
+ dwp_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_file);
+ dwp_file->name = bfd_get_filename (dbfd);
+ dwp_file->dbfd = dbfd;
+ do_cleanups (cleanups);
- dwo_file->cus = create_debug_info_hash_table (dwo_file);
+ /* +1: section 0 is unused */
+ dwp_file->num_sections = bfd_count_sections (dbfd) + 1;
+ dwp_file->elf_sections =
+ OBSTACK_CALLOC (&objfile->objfile_obstack,
+ dwp_file->num_sections, asection *);
- dwo_file->tus = create_debug_types_hash_table (dwo_file,
- dwo_file->sections.types);
+ bfd_map_over_sections (dbfd, dwarf2_locate_common_dwp_sections, dwp_file);
- discard_cleanups (cleanups);
+ dwp_file->cus = create_dwp_hash_table (dwp_file, 0);
- return dwo_file;
-}
+ dwp_file->tus = create_dwp_hash_table (dwp_file, 1);
-/* Lookup DWO file DWO_NAME. */
+ /* The DWP file version is stored in the hash table. Oh well. */
+ if (dwp_file->cus->version != dwp_file->tus->version)
+ {
+ /* Technically speaking, we should try to limp along, but this is
+ pretty bizarre. */
+ error (_("Dwarf Error: DWP file CU version %d doesn't match"
+ " TU version %d [in DWP file %s]"),
+ dwp_file->cus->version, dwp_file->tus->version, dwp_name);
+ }
+ dwp_file->version = dwp_file->cus->version;
-static struct dwo_file *
-lookup_dwo_file (char *dwo_name, const char *comp_dir)
-{
- struct dwo_file *dwo_file;
- struct dwo_file find_entry;
- void **slot;
+ if (dwp_file->version == 2)
+ bfd_map_over_sections (dbfd, dwarf2_locate_v2_dwp_sections, dwp_file);
- if (dwarf2_per_objfile->dwo_files == NULL)
- dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table ();
+ dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table (objfile);
+ dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table (objfile);
- /* Have we already seen this DWO file? */
- find_entry.dwo_name = dwo_name;
- slot = htab_find_slot (dwarf2_per_objfile->dwo_files, &find_entry, INSERT);
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "DWP file found: %s\n", dwp_file->name);
+ fprintf_unfiltered (gdb_stdlog,
+ " %s CUs, %s TUs\n",
+ pulongest (dwp_file->cus ? dwp_file->cus->nr_units : 0),
+ pulongest (dwp_file->tus ? dwp_file->tus->nr_units : 0));
+ }
- /* 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);
+ return dwp_file;
+}
- /* NOTE: This will be NULL if unable to open the file. */
- dwo_file = *slot;
+/* Wrapper around open_and_init_dwp_file, only open it once. */
- return dwo_file;
+static struct dwp_file *
+get_dwp_file (void)
+{
+ if (! dwarf2_per_objfile->dwp_checked)
+ {
+ dwarf2_per_objfile->dwp_file = open_and_init_dwp_file ();
+ dwarf2_per_objfile->dwp_checked = 1;
+ }
+ return dwarf2_per_objfile->dwp_file;
}
-/* Lookup the DWO CU referenced from THIS_CU in DWO file DWO_NAME.
+/* Subroutine of lookup_dwo_comp_unit, lookup_dwo_type_unit.
+ Look up the CU/TU with signature SIGNATURE, either in DWO file DWO_NAME
+ or in the DWP file for the objfile, referenced by THIS_UNIT.
If non-NULL, comp_dir is the DW_AT_comp_dir attribute.
- SIGNATURE is the "dwo_id" of the CU (for consistency we use the same
- nomenclature as TUs).
+ IS_DEBUG_TYPES is non-zero if reading a TU, otherwise read a CU.
+
+ This is called, for example, when wanting to read a variable with a
+ complex location. Therefore we don't want to do file i/o for every call.
+ Therefore we don't want to look for a DWO file on every call.
+ Therefore we first see if we've already seen SIGNATURE in a DWP file,
+ then we check if we've already seen DWO_NAME, and only THEN do we check
+ for a DWO file.
+
The result is a pointer to the dwo_unit object or NULL if we didn't find it
- (dwo_id mismatch or couldn't find the DWO file). */
+ (dwo_id mismatch or couldn't find the DWO/DWP file). */
static struct dwo_unit *
-lookup_dwo_comp_unit (struct dwarf2_per_cu_data *this_cu,
- char *dwo_name, const char *comp_dir,
- ULONGEST signature)
+lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
+ const char *dwo_name, const char *comp_dir,
+ ULONGEST signature, int is_debug_types)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
+ const char *kind = is_debug_types ? "TU" : "CU";
+ void **dwo_file_slot;
struct dwo_file *dwo_file;
+ struct dwp_file *dwp_file;
- dwo_file = lookup_dwo_file (dwo_name, comp_dir);
- if (dwo_file == NULL)
- return NULL;
+ /* First see if there's a DWP file.
+ If we have a DWP file but didn't find the DWO inside it, don't
+ look for the original DWO file. It makes gdb behave differently
+ depending on whether one is debugging in the build tree. */
+
+ dwp_file = get_dwp_file ();
+ if (dwp_file != NULL)
+ {
+ const struct dwp_hash_table *dwp_htab =
+ is_debug_types ? dwp_file->tus : dwp_file->cus;
- /* Look up the DWO using its signature(dwo_id). */
+ if (dwp_htab != NULL)
+ {
+ struct dwo_unit *dwo_cutu =
+ lookup_dwo_unit_in_dwp (dwp_file, comp_dir,
+ signature, is_debug_types);
- if (dwo_file->cus != NULL)
+ if (dwo_cutu != NULL)
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Virtual DWO %s %s found: @%s\n",
+ kind, hex_string (signature),
+ host_address_to_string (dwo_cutu));
+ }
+ return dwo_cutu;
+ }
+ }
+ }
+ else
{
- struct dwo_unit find_dwo_cu, *dwo_cu;
+ /* No DWP file, look for the DWO file. */
- find_dwo_cu.signature = signature;
- dwo_cu = htab_find (dwo_file->cus, &find_dwo_cu);
+ dwo_file_slot = lookup_dwo_file_slot (dwo_name, comp_dir);
+ if (*dwo_file_slot == NULL)
+ {
+ /* Read in the file and build a table of the CUs/TUs it contains. */
+ *dwo_file_slot = open_and_init_dwo_file (this_unit, dwo_name, comp_dir);
+ }
+ /* NOTE: This will be NULL if unable to open the file. */
+ dwo_file = *dwo_file_slot;
+
+ if (dwo_file != NULL)
+ {
+ struct dwo_unit *dwo_cutu = NULL;
+
+ if (is_debug_types && dwo_file->tus)
+ {
+ struct dwo_unit find_dwo_cutu;
+
+ memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu));
+ find_dwo_cutu.signature = signature;
+ dwo_cutu = htab_find (dwo_file->tus, &find_dwo_cutu);
+ }
+ else if (!is_debug_types && dwo_file->cu)
+ {
+ if (signature == dwo_file->cu->signature)
+ dwo_cutu = dwo_file->cu;
+ }
- if (dwo_cu != NULL)
- return dwo_cu;
+ if (dwo_cutu != NULL)
+ {
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "DWO %s %s(%s) found: @%s\n",
+ kind, dwo_name, hex_string (signature),
+ host_address_to_string (dwo_cutu));
+ }
+ return dwo_cutu;
+ }
+ }
}
- /* We didn't find it. This must mean a dwo_id mismatch. */
+ /* We didn't find it. This could mean a dwo_id mismatch, or
+ someone deleted the DWO/DWP file, or the search path isn't set up
+ correctly to find the file. */
- 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);
+ if (dwarf2_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "DWO %s %s(%s) not found\n",
+ kind, dwo_name, hex_string (signature));
+ }
+
+ /* This is a warning and not a complaint because it can be caused by
+ pilot error (e.g., user accidentally deleting the DWO). */
+ warning (_("Could not find DWO %s %s(%s) referenced by %s at offset 0x%x"
+ " [in module %s]"),
+ kind, dwo_name, hex_string (signature),
+ this_unit->is_debug_types ? "TU" : "CU",
+ this_unit->offset.sect_off, objfile_name (objfile));
return NULL;
}
-/* Lookup the DWO TU referenced from THIS_TU in DWO file DWO_NAME.
- If non-NULL, comp_dir is the DW_AT_comp_dir attribute.
- The result is a pointer to the dwo_unit object or NULL if we didn't find it
- (dwo_id mismatch or couldn't find the DWO file). */
+/* Lookup the DWO CU DWO_NAME/SIGNATURE referenced from THIS_CU.
+ See lookup_dwo_cutu_unit for details. */
+
+static struct dwo_unit *
+lookup_dwo_comp_unit (struct dwarf2_per_cu_data *this_cu,
+ const char *dwo_name, const char *comp_dir,
+ ULONGEST signature)
+{
+ return lookup_dwo_cutu (this_cu, dwo_name, comp_dir, signature, 0);
+}
+
+/* Lookup the DWO TU DWO_NAME/SIGNATURE referenced from THIS_TU.
+ See lookup_dwo_cutu_unit for details. */
static struct dwo_unit *
lookup_dwo_type_unit (struct signatured_type *this_tu,
- char *dwo_name, const char *comp_dir)
+ const char *dwo_name, const char *comp_dir)
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct dwo_file *dwo_file;
+ return lookup_dwo_cutu (&this_tu->per_cu, dwo_name, comp_dir, this_tu->signature, 1);
+}
- dwo_file = lookup_dwo_file (dwo_name, comp_dir);
- if (dwo_file == NULL)
- return NULL;
+/* Traversal function for queue_and_load_all_dwo_tus. */
- /* Look up the DWO using its signature(dwo_id). */
+static int
+queue_and_load_dwo_tu (void **slot, void *info)
+{
+ struct dwo_unit *dwo_unit = (struct dwo_unit *) *slot;
+ struct dwarf2_per_cu_data *per_cu = (struct dwarf2_per_cu_data *) info;
+ ULONGEST signature = dwo_unit->signature;
+ struct signatured_type *sig_type =
+ lookup_dwo_signatured_type (per_cu->cu, signature);
- if (dwo_file->tus != NULL)
+ if (sig_type != NULL)
{
- struct dwo_unit find_dwo_tu, *dwo_tu;
-
- find_dwo_tu.signature = this_tu->signature;
- dwo_tu = htab_find (dwo_file->tus, &find_dwo_tu);
+ struct dwarf2_per_cu_data *sig_cu = &sig_type->per_cu;
- if (dwo_tu != NULL)
- return dwo_tu;
+ /* We pass NULL for DEPENDENT_CU because we don't yet know if there's
+ a real dependency of PER_CU on SIG_TYPE. That is detected later
+ while processing PER_CU. */
+ if (maybe_queue_comp_unit (NULL, sig_cu, per_cu->cu->language))
+ load_full_type_unit (sig_cu);
+ VEC_safe_push (dwarf2_per_cu_ptr, per_cu->imported_symtabs, sig_cu);
}
- /* We didn't find it. This must mean a dwo_id mismatch. */
+ return 1;
+}
+
+/* Queue all TUs contained in the DWO of PER_CU to be read in.
+ The DWO may have the only definition of the type, though it may not be
+ referenced anywhere in PER_CU. Thus we have to load *all* its TUs.
+ http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */
- 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;
+static void
+queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *per_cu)
+{
+ struct dwo_unit *dwo_unit;
+ struct dwo_file *dwo_file;
+
+ gdb_assert (!per_cu->is_debug_types);
+ gdb_assert (get_dwp_file () == NULL);
+ gdb_assert (per_cu->cu != NULL);
+
+ dwo_unit = per_cu->cu->dwo_unit;
+ gdb_assert (dwo_unit != NULL);
+
+ dwo_file = dwo_unit->dwo_file;
+ if (dwo_file->tus != NULL)
+ htab_traverse_noresize (dwo_file->tus, queue_and_load_dwo_tu, per_cu);
}
/* Free all resources associated with DWO_FILE.
@@ -8323,21 +10763,8 @@ free_dwo_file (struct dwo_file *dwo_file, struct objfile *objfile)
int ix;
struct dwarf2_section_info *section;
- gdb_assert (dwo_file->dwo_bfd != objfile->obfd);
- bfd_close (dwo_file->dwo_bfd);
-
- munmap_section_buffer (&dwo_file->sections.abbrev);
- munmap_section_buffer (&dwo_file->sections.info);
- munmap_section_buffer (&dwo_file->sections.line);
- munmap_section_buffer (&dwo_file->sections.loc);
- munmap_section_buffer (&dwo_file->sections.str);
- munmap_section_buffer (&dwo_file->sections.str_offsets);
-
- for (ix = 0;
- VEC_iterate (dwarf2_section_info_def, dwo_file->sections.types,
- ix, section);
- ++ix)
- munmap_section_buffer (section);
+ /* Note: dbfd is NULL for virtual DWO files. */
+ gdb_bfd_unref (dwo_file->dbfd);
VEC_free (dwarf2_section_info_def, dwo_file->sections.types);
}
@@ -8523,7 +10950,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
CORE_ADDR highpc;
struct die_info *child_die;
struct attribute *attr, *call_line, *call_file;
- char *name;
+ const char *name;
CORE_ADDR baseaddr;
struct block *block;
int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
@@ -8580,8 +11007,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
if (child_die->tag == DW_TAG_template_type_param
|| child_die->tag == DW_TAG_template_value_param)
{
- templ_func = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct template_symbol);
+ templ_func = allocate_template_symbol (objfile);
templ_func->base.is_cplus_template_function = 1;
break;
}
@@ -8595,16 +11021,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
it. */
attr = dwarf2_attr (die, DW_AT_frame_base, cu);
if (attr)
- /* FIXME: cagney/2004-01-26: The DW_AT_frame_base's location
- expression is being recorded directly in the function's symbol
- and not in a separate frame-base object. I guess this hack is
- to avoid adding some sort of frame-base adjunct/annex to the
- function's symbol :-(. The problem with doing this is that it
- results in a function symbol with a location expression that
- has nothing to do with the location of the function, ouch! The
- relationship should be: a function's symbol has-a frame base; a
- frame-base has-a location expression. */
- dwarf2_symbol_mark_computed (attr, new->name, cu);
+ dwarf2_symbol_mark_computed (attr, new->name, cu, 1);
cu->list_in_scope = &local_symbols;
@@ -8660,10 +11077,10 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
lowpc, highpc, objfile);
/* For C++, set the block's scope. */
- if (cu->language == language_cplus || cu->language == language_fortran)
- cp_set_block_scope (new->name, block, &objfile->objfile_obstack,
- determine_prefix (die, cu),
- processing_has_namespace_info);
+ if ((cu->language == language_cplus || cu->language == language_fortran)
+ && cu->processing_has_namespace_info)
+ block_set_scope (block, determine_prefix (die, cu),
+ &objfile->objfile_obstack);
/* If we have address ranges, record them. */
dwarf2_record_block_ranges (die, block, baseaddr, cu);
@@ -8689,7 +11106,6 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
when we finish processing a function scope, we may need to go
back to building a containing block's symbol lists. */
local_symbols = new->locals;
- param_symbols = new->params;
using_directives = new->using_directives;
/* If we've finished processing a top-level function, subsequent
@@ -8778,7 +11194,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("missing DW_AT_low_pc for DW_TAG_GNU_call_site "
"DIE 0x%x [in module %s]"),
- die->offset.sect_off, objfile->name);
+ die->offset.sect_off, objfile_name (objfile));
return;
}
pc = DW_ADDR (attr) + baseaddr;
@@ -8794,7 +11210,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("Duplicate PC %s for DW_TAG_GNU_call_site "
"DIE 0x%x [in module %s]"),
- paddress (gdbarch, pc), die->offset.sect_off, objfile->name);
+ paddress (gdbarch, pc), die->offset.sect_off,
+ objfile_name (objfile));
return;
}
@@ -8809,7 +11226,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("Tag %d is not DW_TAG_GNU_call_site_parameter in "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->tag, child_die->offset.sect_off, objfile->name);
+ child_die->tag, child_die->offset.sect_off,
+ objfile_name (objfile));
continue;
}
@@ -8867,7 +11285,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("Cannot find function owning DW_TAG_GNU_call_site "
"DIE 0x%x [in module %s]"),
- die->offset.sect_off, objfile->name);
+ die->offset.sect_off, objfile_name (objfile));
}
}
@@ -8888,25 +11306,34 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
SET_FIELD_DWARF_BLOCK (call_site->target, dlbaton);
}
- else if (is_ref_attr (attr))
+ else if (attr_form_is_ref (attr))
{
struct dwarf2_cu *target_cu = cu;
struct die_info *target_die;
- target_die = follow_die_ref_or_sig (die, attr, &target_cu);
+ target_die = follow_die_ref (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);
+ const char *target_physname = NULL;
+ struct attribute *target_attr;
+
+ /* Prefer the mangled name; otherwise compute the demangled one. */
+ target_attr = dwarf2_attr (target_die, DW_AT_linkage_name, target_cu);
+ if (target_attr == NULL)
+ target_attr = dwarf2_attr (target_die, DW_AT_MIPS_linkage_name,
+ target_cu);
+ if (target_attr != NULL && DW_STRING (target_attr) != NULL)
+ target_physname = DW_STRING (target_attr);
+ else
+ target_physname = dwarf2_physname (NULL, target_die, target_cu);
if (target_physname == NULL)
complaint (&symfile_complaints,
_("DW_AT_GNU_call_site_target target DIE has invalid "
"physname, for referencing DIE 0x%x [in module %s]"),
- die->offset.sect_off, objfile->name);
+ die->offset.sect_off, objfile_name (objfile));
else
- SET_FIELD_PHYSNAME (call_site->target, (char *) target_physname);
+ SET_FIELD_PHYSNAME (call_site->target, target_physname);
}
else
{
@@ -8917,7 +11344,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("DW_AT_GNU_call_site_target target DIE has invalid "
"low pc, for referencing DIE 0x%x [in module %s]"),
- die->offset.sect_off, objfile->name);
+ die->offset.sect_off, objfile_name (objfile));
else
SET_FIELD_PHYSADDR (call_site->target, lowpc + baseaddr);
}
@@ -8926,7 +11353,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("DW_TAG_GNU_call_site DW_AT_GNU_call_site_target is neither "
"block nor reference, for DIE 0x%x [in module %s]"),
- die->offset.sect_off, objfile->name);
+ die->offset.sect_off, objfile_name (objfile));
call_site->per_cu = cu->per_cu;
@@ -8952,7 +11379,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
loc = dwarf2_attr (child_die, DW_AT_location, cu);
origin = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
- if (loc == NULL && origin != NULL && is_ref_attr (origin))
+ if (loc == NULL && origin != NULL && attr_form_is_ref (origin))
{
sect_offset offset;
@@ -8967,7 +11394,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
_("DW_AT_abstract_origin offset is not in CU for "
"DW_TAG_GNU_call_site child DIE 0x%x "
"[in module %s]"),
- child_die->offset.sect_off, objfile->name);
+ child_die->offset.sect_off, objfile_name (objfile));
continue;
}
parameter->u.param_offset.cu_off = (offset.sect_off
@@ -8978,7 +11405,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
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);
+ child_die->offset.sect_off, objfile_name (objfile));
continue;
}
else
@@ -8998,7 +11425,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
"for DW_FORM_block* DW_AT_location is supported for "
"DW_TAG_GNU_call_site child DIE 0x%x "
"[in module %s]"),
- child_die->offset.sect_off, objfile->name);
+ child_die->offset.sect_off, objfile_name (objfile));
continue;
}
}
@@ -9009,7 +11436,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_GNU_call_site_value for "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile->name);
+ child_die->offset.sect_off, objfile_name (objfile));
continue;
}
parameter->value = DW_BLOCK (attr)->data;
@@ -9027,7 +11454,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_GNU_call_site_data_value for "
"DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile->name);
+ child_die->offset.sect_off, objfile_name (objfile));
else
{
parameter->data_value = DW_BLOCK (attr)->data;
@@ -9055,7 +11482,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
CORE_ADDR base;
int found_base;
unsigned int dummy;
- gdb_byte *buffer;
+ const gdb_byte *buffer;
CORE_ADDR marker;
int low_set;
CORE_ADDR low = 0;
@@ -9142,6 +11569,17 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
range_beginning += base;
range_end += base;
+ /* A not-uncommon case of bad debug info.
+ Don't pollute the addrmap with bad data. */
+ if (range_beginning + baseaddr == 0
+ && !dwarf2_per_objfile->has_section_at_zero)
+ {
+ complaint (&symfile_complaints,
+ _(".debug_ranges entry has start address of zero"
+ " [in module %s]"), objfile_name (objfile));
+ continue;
+ }
+
if (ranges_pst != NULL)
addrmap_set_empty (objfile->psymtabs_addrmap,
range_beginning + baseaddr,
@@ -9219,7 +11657,14 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
attr = dwarf2_attr (die, DW_AT_ranges, cu);
if (attr != NULL)
{
- unsigned int ranges_offset = DW_UNSND (attr) + cu->ranges_base;
+ /* DW_AT_ranges_base does not apply to DIEs from the DWO skeleton.
+ We take advantage of the fact that DW_AT_ranges does not appear
+ in DW_TAG_compile_unit of DWO files. */
+ int need_ranges_base = die->tag != DW_TAG_compile_unit;
+ unsigned int ranges_offset = (DW_UNSND (attr)
+ + (need_ranges_base
+ ? cu->ranges_base
+ : 0));
/* Value of the DW_AT_ranges attribute is the offset in the
.debug_ranges section. */
@@ -9380,11 +11825,16 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
if (attr)
{
bfd *obfd = objfile->obfd;
+ /* DW_AT_ranges_base does not apply to DIEs from the DWO skeleton.
+ We take advantage of the fact that DW_AT_ranges does not appear
+ in DW_TAG_compile_unit of DWO files. */
+ int need_ranges_base = die->tag != DW_TAG_compile_unit;
/* The value of the DW_AT_ranges attribute is the offset of the
address range list in the .debug_ranges section. */
- unsigned long offset = DW_UNSND (attr) + cu->ranges_base;
- gdb_byte *buffer = dwarf2_per_objfile->ranges.buffer + offset;
+ unsigned long offset = (DW_UNSND (attr)
+ + (need_ranges_base ? cu->ranges_base : 0));
+ const gdb_byte *buffer;
/* For some target architectures, but not others, the
read_address function sign-extends the addresses it returns.
@@ -9403,7 +11853,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
CORE_ADDR base = cu->base_address;
int base_known = cu->base_known;
- gdb_assert (dwarf2_per_objfile->ranges.readin);
+ dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
if (offset >= dwarf2_per_objfile->ranges.size)
{
complaint (&symfile_complaints,
@@ -9411,6 +11861,7 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
offset);
return;
}
+ buffer = dwarf2_per_objfile->ranges.buffer + offset;
for (;;)
{
@@ -9457,9 +11908,20 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
if (start == end)
continue;
- record_block_range (block,
- baseaddr + base + start,
- baseaddr + base + end - 1);
+ start += base + baseaddr;
+ end += base + baseaddr;
+
+ /* A not-uncommon case of bad debug info.
+ Don't pollute the addrmap with bad data. */
+ if (start == 0 && !dwarf2_per_objfile->has_section_at_zero)
+ {
+ complaint (&symfile_complaints,
+ _(".debug_ranges entry has start address of zero"
+ " [in module %s]"), objfile_name (objfile));
+ continue;
+ }
+
+ record_block_range (block, start, end - 1);
}
}
}
@@ -9497,7 +11959,10 @@ check_producer (struct dwarf2_cu *cu)
/* Not recognized as GCC. */
}
else
- cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
+ {
+ cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
+ cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
+ }
}
else if (strncmp (cu->producer, "Intel(R) C", strlen ("Intel(R) C")) == 0)
cu->producer_is_icc = 1;
@@ -9598,7 +12063,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
struct nextfield *new_field;
struct attribute *attr;
struct field *fp;
- char *fieldname = "";
+ const char *fieldname = "";
/* Allocate a new field list entry and link it in. */
new_field = (struct nextfield *) xmalloc (sizeof (struct nextfield));
@@ -9909,6 +12374,34 @@ dwarf2_attach_fields_to_type (struct field_info *fip, struct type *type,
}
}
+/* Return true if this member function is a constructor, false
+ otherwise. */
+
+static int
+dwarf2_is_constructor (struct die_info *die, struct dwarf2_cu *cu)
+{
+ const char *fieldname;
+ const char *typename;
+ int len;
+
+ if (die->parent == NULL)
+ return 0;
+
+ if (die->parent->tag != DW_TAG_structure_type
+ && die->parent->tag != DW_TAG_union_type
+ && die->parent->tag != DW_TAG_class_type)
+ return 0;
+
+ fieldname = dwarf2_name (die, cu);
+ typename = dwarf2_name (die->parent, cu);
+ if (fieldname == NULL || typename == NULL)
+ return 0;
+
+ len = strlen (fieldname);
+ return (strncmp (fieldname, typename, len) == 0
+ && (typename[len] == '\0' || typename[len] == '<'));
+}
+
/* Add a member function to the proper fieldlist. */
static void
@@ -9920,7 +12413,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
struct fnfieldlist *flp;
int i;
struct fn_field *fnp;
- char *fieldname;
+ const char *fieldname;
struct nextfnfield *new_fnfield;
struct type *this_type;
enum dwarf_access_attribute accessibility;
@@ -10040,6 +12533,8 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
if (attr && DW_UNSND (attr) != 0)
fnp->is_artificial = 1;
+ fnp->is_constructor = dwarf2_is_constructor (die, cu);
+
/* Get index in virtual function table if it is a virtual member
function. For older versions of GCC, this is an offset in the
appropriate virtual table, as specified by DW_AT_containing_type.
@@ -10218,7 +12713,7 @@ producer_is_icc (struct dwarf2_cu *cu)
/* Called when we find the DIE that starts a structure or union scope
(definition) to create a type for the structure or union. Fill in
the type's name and general properties; the members will not be
- processed until process_structure_type.
+ processed until process_structure_scope.
NOTE: we need to call these functions regardless of whether or not the
DIE has a DW_AT_name attribute, since it might be an anonymous
@@ -10238,7 +12733,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
struct objfile *objfile = cu->objfile;
struct type *type;
struct attribute *attr;
- char *name;
+ const char *name;
/* If the definition of this type lives in .debug_types, read that type.
Don't follow DW_AT_specification though, that will take us back up
@@ -10246,17 +12741,10 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr_no_follow (die, DW_AT_signature);
if (attr)
{
- struct dwarf2_cu *type_cu = cu;
- struct die_info *type_die = follow_die_ref_or_sig (die, attr, &type_cu);
-
- /* We could just recurse on read_structure_type, but we need to call
- get_die_type to ensure only one type for this DIE is created.
- This is important, for example, because for c++ classes we need
- TYPE_NAME set which is only done by new_symbol. Blech. */
- type = read_type_die (type_die, type_cu);
+ type = get_DW_AT_signature_type (die, attr, cu);
- /* TYPE_CU may not be the same as CU.
- Ensure TYPE is recorded in CU's type_hash table. */
+ /* The type's CU may not be the same as CU.
+ Ensure TYPE is recorded with CU in die_type_hash. */
return set_die_type (die, type, cu);
}
@@ -10269,7 +12757,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
if (cu->language == language_cplus
|| cu->language == language_java)
{
- char *full_name = (char *) dwarf2_full_name (name, die, cu);
+ const char *full_name = dwarf2_full_name (name, die, cu);
/* dwarf2_full_name might have already finished building the DIE's
type. If so, there is no need to continue. */
@@ -10285,7 +12773,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
{
/* The name is already allocated along with this objfile, so
we don't need to duplicate it for the type. */
- TYPE_TAG_NAME (type) = (char *) name;
+ TYPE_TAG_NAME (type) = name;
if (die->tag == DW_TAG_class_type)
TYPE_NAME (type) = TYPE_TAG_NAME (type);
}
@@ -10573,13 +13061,10 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr_no_follow (die, DW_AT_signature);
if (attr)
{
- struct dwarf2_cu *type_cu = cu;
- struct die_info *type_die = follow_die_ref_or_sig (die, attr, &type_cu);
-
- type = read_type_die (type_die, type_cu);
+ type = get_DW_AT_signature_type (die, attr, cu);
- /* TYPE_CU may not be the same as CU.
- Ensure TYPE is recorded in CU's type_hash table. */
+ /* The type's CU may not be the same as CU.
+ Ensure TYPE is recorded with CU in die_type_hash. */
return set_die_type (die, type, cu);
}
@@ -10588,7 +13073,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
TYPE_CODE (type) = TYPE_CODE_ENUM;
name = dwarf2_full_name (NULL, die, cu);
if (name != NULL)
- TYPE_TAG_NAME (type) = (char *) name;
+ TYPE_TAG_NAME (type) = name;
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
@@ -10633,7 +13118,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
struct field *fields = NULL;
int num_fields = 0;
int unsigned_enum = 1;
- char *name;
+ const char *name;
int flag_enum = 1;
ULONGEST mask = 0;
@@ -10708,10 +13193,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
{
struct signatured_type *sig_type;
- sig_type
- = lookup_signatured_type_at_offset (dwarf2_per_objfile->objfile,
- cu->per_cu->info_or_types_section,
- cu->per_cu->offset);
+ sig_type = (struct signatured_type *) cu->per_cu;
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;
@@ -10735,7 +13217,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
struct attribute *attr;
int ndim = 0;
struct cleanup *back_to;
- char *name;
+ const char *name;
element_type = die_type (die, cu);
@@ -10894,15 +13376,88 @@ read_set_type (struct die_info *die, struct dwarf2_cu *cu)
return set_die_type (die, set_type, cu);
}
-/* First cut: install each common block member as a global variable. */
+/* A helper for read_common_block that creates a locexpr baton.
+ SYM is the symbol which we are marking as computed.
+ COMMON_DIE is the DIE for the common block.
+ COMMON_LOC is the location expression attribute for the common
+ block itself.
+ MEMBER_LOC is the location expression attribute for the particular
+ member of the common block that we are processing.
+ CU is the CU from which the above come. */
+
+static void
+mark_common_block_symbol_computed (struct symbol *sym,
+ struct die_info *common_die,
+ struct attribute *common_loc,
+ struct attribute *member_loc,
+ struct dwarf2_cu *cu)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_locexpr_baton *baton;
+ gdb_byte *ptr;
+ unsigned int cu_off;
+ enum bfd_endian byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+ LONGEST offset = 0;
+
+ gdb_assert (common_loc && member_loc);
+ gdb_assert (attr_form_is_block (common_loc));
+ gdb_assert (attr_form_is_block (member_loc)
+ || attr_form_is_constant (member_loc));
+
+ baton = obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct dwarf2_locexpr_baton));
+ baton->per_cu = cu->per_cu;
+ gdb_assert (baton->per_cu);
+
+ baton->size = 5 /* DW_OP_call4 */ + 1 /* DW_OP_plus */;
+
+ if (attr_form_is_constant (member_loc))
+ {
+ offset = dwarf2_get_attr_constant_value (member_loc, 0);
+ baton->size += 1 /* DW_OP_addr */ + cu->header.addr_size;
+ }
+ else
+ baton->size += DW_BLOCK (member_loc)->size;
+
+ ptr = obstack_alloc (&objfile->objfile_obstack, baton->size);
+ baton->data = ptr;
+
+ *ptr++ = DW_OP_call4;
+ cu_off = common_die->offset.sect_off - cu->per_cu->offset.sect_off;
+ store_unsigned_integer (ptr, 4, byte_order, cu_off);
+ ptr += 4;
+
+ if (attr_form_is_constant (member_loc))
+ {
+ *ptr++ = DW_OP_addr;
+ store_unsigned_integer (ptr, cu->header.addr_size, byte_order, offset);
+ ptr += cu->header.addr_size;
+ }
+ else
+ {
+ /* We have to copy the data here, because DW_OP_call4 will only
+ use a DW_AT_location attribute. */
+ memcpy (ptr, DW_BLOCK (member_loc)->data, DW_BLOCK (member_loc)->size);
+ ptr += DW_BLOCK (member_loc)->size;
+ }
+
+ *ptr++ = DW_OP_plus;
+ gdb_assert (ptr - baton->data == baton->size);
+
+ SYMBOL_LOCATION_BATON (sym) = baton;
+ SYMBOL_ACLASS_INDEX (sym) = dwarf2_locexpr_index;
+}
+
+/* Create appropriate locally-scoped variables for all the
+ DW_TAG_common_block entries. Also create a struct common_block
+ listing all such variables for `info common'. COMMON_BLOCK_DOMAIN
+ is used to sepate the common blocks name namespace from regular
+ variable names. */
static void
read_common_block (struct die_info *die, struct dwarf2_cu *cu)
{
- struct die_info *child_die;
struct attribute *attr;
- struct symbol *sym;
- CORE_ADDR base = (CORE_ADDR) 0;
attr = dwarf2_attr (die, DW_AT_location, cu);
if (attr)
@@ -10910,34 +13465,85 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
/* Support the .debug_loc offsets. */
if (attr_form_is_block (attr))
{
- base = decode_locdesc (DW_BLOCK (attr), cu);
+ /* Ok. */
}
else if (attr_form_is_section_offset (attr))
{
dwarf2_complex_location_expr_complaint ();
+ attr = NULL;
}
else
{
dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
"common block member");
+ attr = NULL;
}
}
+
if (die->child != NULL)
{
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- LONGEST offset;
+ struct objfile *objfile = cu->objfile;
+ struct die_info *child_die;
+ size_t n_entries = 0, size;
+ struct common_block *common_block;
+ struct symbol *sym;
+
+ for (child_die = die->child;
+ child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ ++n_entries;
+ size = (sizeof (struct common_block)
+ + (n_entries - 1) * sizeof (struct symbol *));
+ common_block = obstack_alloc (&objfile->objfile_obstack, size);
+ memset (common_block->contents, 0, n_entries * sizeof (struct symbol *));
+ common_block->n_entries = 0;
+
+ for (child_die = die->child;
+ child_die && child_die->tag;
+ child_die = sibling_die (child_die))
+ {
+ /* Create the symbol in the DW_TAG_common_block block in the current
+ symbol scope. */
sym = new_symbol (child_die, NULL, cu);
- if (sym != NULL
- && handle_data_member_location (child_die, cu, &offset))
+ if (sym != NULL)
{
- SYMBOL_VALUE_ADDRESS (sym) = base + offset;
- add_symbol_to_list (sym, &global_symbols);
+ struct attribute *member_loc;
+
+ common_block->contents[common_block->n_entries++] = sym;
+
+ member_loc = dwarf2_attr (child_die, DW_AT_data_member_location,
+ cu);
+ if (member_loc)
+ {
+ /* GDB has handled this for a long time, but it is
+ not specified by DWARF. It seems to have been
+ emitted by gfortran at least as recently as:
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23057. */
+ complaint (&symfile_complaints,
+ _("Variable in common block has "
+ "DW_AT_data_member_location "
+ "- DIE at 0x%x [in module %s]"),
+ child_die->offset.sect_off,
+ objfile_name (cu->objfile));
+
+ if (attr_form_is_section_offset (member_loc))
+ dwarf2_complex_location_expr_complaint ();
+ else if (attr_form_is_constant (member_loc)
+ || attr_form_is_block (member_loc))
+ {
+ if (attr)
+ mark_common_block_symbol_computed (sym, die, attr,
+ member_loc, cu);
+ }
+ else
+ dwarf2_complex_location_expr_complaint ();
+ }
}
- child_die = sibling_die (child_die);
}
+
+ sym = new_symbol (die, objfile_type (objfile)->builtin_void, cu);
+ SYMBOL_VALUE_COMMON_BLOCK (sym) = common_block;
}
}
@@ -10961,7 +13567,7 @@ read_namespace_type (struct die_info *die, struct dwarf2_cu *cu)
type = read_type_die (ext_die, ext_cu);
/* EXT_CU may not be the same as CU.
- Ensure TYPE is recorded in CU's type_hash table. */
+ Ensure TYPE is recorded with CU in die_type_hash. */
return set_die_type (die, type, cu);
}
@@ -10977,7 +13583,7 @@ read_namespace_type (struct die_info *die, struct dwarf2_cu *cu)
/* Create the type. */
type = init_type (TYPE_CODE_NAMESPACE, 0, 0, NULL,
objfile);
- TYPE_NAME (type) = (char *) name;
+ TYPE_NAME (type) = name;
TYPE_TAG_NAME (type) = TYPE_NAME (type);
return set_die_type (die, type, cu);
@@ -11008,7 +13614,7 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
const char *previous_prefix = determine_prefix (die, cu);
cp_add_using_directive (previous_prefix, TYPE_NAME (type), NULL,
- NULL, NULL, &objfile->objfile_obstack);
+ NULL, NULL, 0, &objfile->objfile_obstack);
}
}
@@ -11032,7 +13638,7 @@ static struct type *
read_module_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- char *module_name;
+ const char *module_name;
struct type *type;
module_name = dwarf2_name (die, cu);
@@ -11177,6 +13783,15 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_METHOD)
type = lookup_methodptr_type (to_type);
+ else if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_FUNC)
+ {
+ struct type *new_type = alloc_type (cu->objfile);
+
+ smash_to_method_type (new_type, domain, TYPE_TARGET_TYPE (to_type),
+ TYPE_FIELDS (to_type), TYPE_NFIELDS (to_type),
+ TYPE_VARARGS (to_type));
+ type = lookup_methodptr_type (new_type);
+ }
else
type = lookup_memberptr_type (to_type, domain);
@@ -11268,6 +13883,24 @@ read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu)
return set_die_type (die, cv_type, cu);
}
+/* Handle DW_TAG_restrict_type. */
+
+static struct type *
+read_tag_restrict_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct type *base_type, *cv_type;
+
+ base_type = die_type (die, cu);
+
+ /* The die_type call above may have already set the type for this DIE. */
+ cv_type = get_die_type (die, cu);
+ if (cv_type)
+ return cv_type;
+
+ cv_type = make_restrict_type (base_type);
+ return set_die_type (die, cv_type, cu);
+}
+
/* Extract all information from a DW_TAG_string_type DIE and add to
the user defined type vector. It isn't really a user defined type,
but it behaves like one, with other DIE's using an AT_user_def_type
@@ -11301,12 +13934,44 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
}
}
- index_type = objfile_type (objfile)->builtin_int;
- range_type = create_range_type (NULL, index_type, 1, length);
- char_type = language_string_char_type (cu->language_defn, gdbarch);
- type = create_string_type (NULL, char_type, range_type);
+ index_type = objfile_type (objfile)->builtin_int;
+ range_type = create_range_type (NULL, index_type, 1, length);
+ char_type = language_string_char_type (cu->language_defn, gdbarch);
+ type = create_string_type (NULL, char_type, range_type);
+
+ return set_die_type (die, type, cu);
+}
+
+/* Assuming that DIE corresponds to a function, returns nonzero
+ if the function is prototyped. */
+
+static int
+prototyped_function_p (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *attr;
+
+ attr = dwarf2_attr (die, DW_AT_prototyped, cu);
+ if (attr && (DW_UNSND (attr) != 0))
+ return 1;
- return set_die_type (die, type, cu);
+ /* The DWARF standard implies that the DW_AT_prototyped attribute
+ is only meaninful for C, but the concept also extends to other
+ languages that allow unprototyped functions (Eg: Objective C).
+ For all other languages, assume that functions are always
+ prototyped. */
+ if (cu->language != language_c
+ && cu->language != language_objc
+ && cu->language != language_opencl)
+ return 1;
+
+ /* RealView does not emit DW_AT_prototyped. We can not distinguish
+ prototyped and unprototyped functions; default to prototyped,
+ since that is more common in modern code (and RealView warns
+ about unprototyped functions). */
+ if (producer_is_realview (cu->producer))
+ return 1;
+
+ return 0;
}
/* Handle DIES due to C code like:
@@ -11336,18 +14001,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
ftype = lookup_function_type (type);
- /* All functions in C++, Pascal and Java have prototypes. */
- attr = dwarf2_attr (die, DW_AT_prototyped, cu);
- if ((attr && (DW_UNSND (attr) != 0))
- || cu->language == language_cplus
- || cu->language == language_java
- || cu->language == language_pascal)
- TYPE_PROTOTYPED (ftype) = 1;
- else if (producer_is_realview (cu->producer))
- /* RealView does not emit DW_AT_prototyped. We can not
- distinguish prototyped and unprototyped functions; default to
- prototyped, since that is more common in modern code (and
- RealView warns about unprototyped functions). */
+ if (prototyped_function_p (die, cu))
TYPE_PROTOTYPED (ftype) = 1;
/* Store the calling convention in the type if it's available in
@@ -11483,7 +14137,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
name = dwarf2_full_name (NULL, die, cu);
this_type = init_type (TYPE_CODE_TYPEDEF, 0,
TYPE_FLAG_TARGET_STUB, NULL, objfile);
- TYPE_NAME (this_type) = (char *) name;
+ TYPE_NAME (this_type) = name;
set_die_type (die, this_type, cu);
target_type = die_type (die, cu);
if (target_type != this_type)
@@ -11495,7 +14149,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
complaint (&symfile_complaints,
_("Self-referential DW_TAG_typedef "
"- DIE at 0x%x [in module %s]"),
- die->offset.sect_off, objfile->name);
+ die->offset.sect_off, objfile_name (objfile));
TYPE_TARGET_TYPE (this_type) = NULL;
}
return this_type;
@@ -11511,7 +14165,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
struct type *type;
struct attribute *attr;
int encoding = 0, size = 0;
- char *name;
+ const char *name;
enum type_code code = TYPE_CODE_INT;
int type_flags = 0;
struct type *target_type = NULL;
@@ -11603,17 +14257,20 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
static struct type *
read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct type *base_type;
+ struct type *base_type, *orig_base_type;
struct type *range_type;
struct attribute *attr;
LONGEST low, high;
int low_default_is_valid;
- char *name;
+ const char *name;
LONGEST negative_mask;
- base_type = die_type (die, cu);
- /* Preserve BASE_TYPE's original type, just set its LENGTH. */
- check_typedef (base_type);
+ orig_base_type = die_type (die, cu);
+ /* If ORIG_BASE_TYPE is a typedef, it will not be TYPE_UNSIGNED,
+ whereas the real type might be. So, we use ORIG_BASE_TYPE when
+ creating the range type, but we use the result of check_typedef
+ when examining properties of the type. */
+ base_type = check_typedef (orig_base_type);
/* The die_type call above may have already set the type for this DIE. */
range_type = get_die_type (die, cu);
@@ -11660,12 +14317,12 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
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);
+ die->offset.sect_off, objfile_name (cu->objfile));
attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
if (attr)
{
- if (attr_form_is_block (attr) || is_ref_attr (attr))
+ if (attr_form_is_block (attr) || attr_form_is_ref (attr))
{
/* GCC encodes arrays with unspecified or dynamic length
with a DW_FORM_block1 attribute or a reference attribute.
@@ -11743,7 +14400,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
if (!TYPE_UNSIGNED (base_type) && (high & negative_mask))
high |= negative_mask;
- range_type = create_range_type (NULL, base_type, low, high);
+ range_type = create_range_type (NULL, orig_base_type, low, high);
/* Mark arrays with dynamic length at least as an array of unspecified
length. GDB could check the boundary but before it gets implemented at
@@ -11792,15 +14449,15 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
static struct die_info *
read_die_and_children (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- gdb_byte **new_info_ptr,
+ const gdb_byte *info_ptr,
+ const gdb_byte **new_info_ptr,
struct die_info *parent)
{
struct die_info *die;
- gdb_byte *cur_ptr;
+ const gdb_byte *cur_ptr;
int has_children;
- cur_ptr = read_full_die (reader, &die, info_ptr, &has_children);
+ cur_ptr = read_full_die_1 (reader, &die, info_ptr, &has_children, 0);
if (die == NULL)
{
*new_info_ptr = cur_ptr;
@@ -11809,7 +14466,7 @@ read_die_and_children (const struct die_reader_specs *reader,
store_in_ref_table (die, reader->cu);
if (has_children)
- die->child = read_die_and_siblings (reader, cur_ptr, new_info_ptr, die);
+ die->child = read_die_and_siblings_1 (reader, cur_ptr, new_info_ptr, die);
else
{
die->child = NULL;
@@ -11826,13 +14483,13 @@ read_die_and_children (const struct die_reader_specs *reader,
in read_die_and_children. */
static struct die_info *
-read_die_and_siblings (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- gdb_byte **new_info_ptr,
- struct die_info *parent)
+read_die_and_siblings_1 (const struct die_reader_specs *reader,
+ const gdb_byte *info_ptr,
+ const gdb_byte **new_info_ptr,
+ struct die_info *parent)
{
struct die_info *first_die, *last_sibling;
- gdb_byte *cur_ptr;
+ const gdb_byte *cur_ptr;
cur_ptr = info_ptr;
first_die = last_sibling = NULL;
@@ -11857,6 +14514,33 @@ read_die_and_siblings (const struct die_reader_specs *reader,
}
}
+/* Read a die, all of its descendents, and all of its siblings; set
+ all of the fields of all of the dies correctly. Arguments are as
+ in read_die_and_children.
+ This the main entry point for reading a DIE and all its children. */
+
+static struct die_info *
+read_die_and_siblings (const struct die_reader_specs *reader,
+ const gdb_byte *info_ptr,
+ const gdb_byte **new_info_ptr,
+ struct die_info *parent)
+{
+ struct die_info *die = read_die_and_siblings_1 (reader, info_ptr,
+ new_info_ptr, parent);
+
+ if (dwarf2_die_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Read die from %s@0x%x of %s:\n",
+ get_section_name (reader->die_section),
+ (unsigned) (info_ptr - reader->die_section->buffer),
+ bfd_get_filename (reader->abfd));
+ dump_die (die, dwarf2_die_debug);
+ }
+
+ return die;
+}
+
/* Read a die and all its attributes, leave space for NUM_EXTRA_ATTRS
attributes.
The caller is responsible for filling in the extra attributes
@@ -11865,9 +14549,9 @@ read_die_and_siblings (const struct die_reader_specs *reader,
except for its child, sibling, and parent fields.
Set HAS_CHILDREN to tell whether the die has children or not. */
-static gdb_byte *
+static const gdb_byte *
read_full_die_1 (const struct die_reader_specs *reader,
- struct die_info **diep, gdb_byte *info_ptr,
+ struct die_info **diep, const gdb_byte *info_ptr,
int *has_children, int num_extra_attrs)
{
unsigned int abbrev_number, bytes_read, i;
@@ -11917,12 +14601,26 @@ read_full_die_1 (const struct die_reader_specs *reader,
except for its child, sibling, and parent fields.
Set HAS_CHILDREN to tell whether the die has children or not. */
-static gdb_byte *
+static const gdb_byte *
read_full_die (const struct die_reader_specs *reader,
- struct die_info **diep, gdb_byte *info_ptr,
+ struct die_info **diep, const gdb_byte *info_ptr,
int *has_children)
{
- return read_full_die_1 (reader, diep, info_ptr, has_children, 0);
+ const gdb_byte *result;
+
+ result = read_full_die_1 (reader, diep, info_ptr, has_children, 0);
+
+ if (dwarf2_die_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "Read die from %s@0x%x of %s:\n",
+ get_section_name (reader->die_section),
+ (unsigned) (info_ptr - reader->die_section->buffer),
+ bfd_get_filename (reader->abfd));
+ dump_die (*diep, dwarf2_die_debug);
+ }
+
+ return result;
}
/* Abbreviation tables.
@@ -11988,9 +14686,9 @@ abbrev_table_read_table (struct dwarf2_section_info *section,
sect_offset offset)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- bfd *abfd = section->asection->owner;
+ bfd *abfd = get_section_bfd_owner (section);
struct abbrev_table *abbrev_table;
- gdb_byte *abbrev_ptr;
+ const gdb_byte *abbrev_ptr;
struct abbrev_info *cur_abbrev;
unsigned int abbrev_number, bytes_read, abbrev_name;
unsigned int abbrev_form;
@@ -12117,7 +14815,8 @@ dwarf2_free_abbrev_table (void *ptr_to_cu)
{
struct dwarf2_cu *cu = ptr_to_cu;
- abbrev_table_free (cu->abbrev_table);
+ if (cu->abbrev_table != NULL)
+ abbrev_table_free (cu->abbrev_table);
/* Set this to NULL so that we SEGV if we try to read it later,
and also because free_comp_unit verifies this is NULL. */
cu->abbrev_table = NULL;
@@ -12159,7 +14858,7 @@ is_type_tag_for_partial (int tag)
static struct partial_die_info *
load_partial_dies (const struct die_reader_specs *reader,
- gdb_byte *info_ptr, int building_psymtab)
+ const gdb_byte *info_ptr, int building_psymtab)
{
struct dwarf2_cu *cu = reader->cu;
struct objfile *objfile = cu->objfile;
@@ -12254,7 +14953,8 @@ load_partial_dies (const struct die_reader_specs *reader,
&& abbrev->tag != DW_TAG_namespace
&& abbrev->tag != DW_TAG_module
&& abbrev->tag != DW_TAG_member
- && abbrev->tag != DW_TAG_imported_unit)
+ && abbrev->tag != DW_TAG_imported_unit
+ && abbrev->tag != DW_TAG_imported_declaration)
{
/* Otherwise we skip to the next sibling, if any. */
info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
@@ -12308,7 +15008,7 @@ load_partial_dies (const struct die_reader_specs *reader,
complaint (&symfile_complaints,
_("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
"- DIE at 0x%x [in module %s]"),
- part_die->offset.sect_off, objfile->name);
+ part_die->offset.sect_off, objfile_name (objfile));
/* If we're at the second level, and we're an enumerator, and
our parent has no specification (meaning possibly lives in a
@@ -12433,15 +15133,15 @@ load_partial_dies (const struct die_reader_specs *reader,
/* Read a minimal amount of information into the minimal die structure. */
-static gdb_byte *
+static const gdb_byte *
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)
+ const gdb_byte *info_ptr)
{
struct dwarf2_cu *cu = reader->cu;
struct objfile *objfile = cu->objfile;
- gdb_byte *buffer = reader->buffer;
+ const gdb_byte *buffer = reader->buffer;
unsigned int i;
struct attribute attr;
int has_low_pc_attr = 0;
@@ -12543,6 +15243,8 @@ read_partial_die (const struct die_reader_specs *reader,
case DW_AT_extension:
part_die->has_specification = 1;
part_die->spec_offset = dwarf2_get_ref_die_offset (&attr);
+ part_die->spec_is_dwz = (attr.form == DW_FORM_GNU_ref_alt
+ || cu->per_cu->is_dwz);
break;
case DW_AT_sibling:
/* Ignore absolute siblings, they might point outside of
@@ -12551,7 +15253,16 @@ read_partial_die (const struct die_reader_specs *reader,
complaint (&symfile_complaints,
_("ignoring absolute DW_AT_sibling"));
else
- part_die->sibling = buffer + dwarf2_get_ref_die_offset (&attr).sect_off;
+ {
+ unsigned int off = dwarf2_get_ref_die_offset (&attr).sect_off;
+ const gdb_byte *sibling_ptr = buffer + off;
+
+ if (sibling_ptr < info_ptr)
+ complaint (&symfile_complaints,
+ _("DW_AT_sibling points backwards"));
+ else
+ part_die->sibling = sibling_ptr;
+ }
break;
case DW_AT_byte_size:
part_die->has_byte_size = 1;
@@ -12589,7 +15300,11 @@ read_partial_die (const struct die_reader_specs *reader,
case DW_AT_import:
if (part_die->tag == DW_TAG_imported_unit)
- part_die->d.offset = dwarf2_get_ref_die_offset (&attr);
+ {
+ part_die->d.offset = dwarf2_get_ref_die_offset (&attr);
+ part_die->is_dwz = (attr.form == DW_FORM_GNU_ref_alt
+ || cu->per_cu->is_dwz);
+ }
break;
default:
@@ -12618,7 +15333,7 @@ read_partial_die (const struct die_reader_specs *reader,
_("DW_AT_low_pc %s is zero "
"for DIE at 0x%x [in module %s]"),
paddress (gdbarch, part_die->lowpc),
- part_die->offset.sect_off, objfile->name);
+ part_die->offset.sect_off, objfile_name (objfile));
}
/* dwarf2_get_pc_bounds has also the strict low < high requirement. */
else if (part_die->lowpc >= part_die->highpc)
@@ -12630,7 +15345,7 @@ read_partial_die (const struct die_reader_specs *reader,
"for DIE at 0x%x [in module %s]"),
paddress (gdbarch, part_die->lowpc),
paddress (gdbarch, part_die->highpc),
- part_die->offset.sect_off, objfile->name);
+ part_die->offset.sect_off, objfile_name (objfile));
}
else
part_die->has_pc_info = 1;
@@ -12660,13 +15375,14 @@ find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu)
DW_FORM_ref_sig8). */
static struct partial_die_info *
-find_partial_die (sect_offset offset, struct dwarf2_cu *cu)
+find_partial_die (sect_offset offset, int offset_in_dwz, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct dwarf2_per_cu_data *per_cu = NULL;
struct partial_die_info *pd = NULL;
- if (offset_in_cu_p (&cu->header, offset))
+ if (offset_in_dwz == cu->per_cu->is_dwz
+ && offset_in_cu_p (&cu->header, offset))
{
pd = find_partial_die_in_comp_unit (offset, cu);
if (pd != NULL)
@@ -12685,7 +15401,8 @@ find_partial_die (sect_offset offset, struct dwarf2_cu *cu)
(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, offset_in_dwz,
+ objfile);
if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
load_partial_comp_unit (per_cu);
@@ -12743,7 +15460,8 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi,
real_pdi = struct_pdi;
while (real_pdi->has_specification)
- real_pdi = find_partial_die (real_pdi->spec_offset, cu);
+ real_pdi = find_partial_die (real_pdi->spec_offset,
+ real_pdi->spec_is_dwz, cu);
if (real_pdi->die_parent != NULL)
return;
@@ -12761,9 +15479,9 @@ guess_partial_die_structure_name (struct partial_die_info *struct_pdi,
if (actual_class_name != NULL)
{
struct_pdi->name
- = obsavestring (actual_class_name,
- strlen (actual_class_name),
- &cu->objfile->objfile_obstack);
+ = obstack_copy0 (&cu->objfile->objfile_obstack,
+ actual_class_name,
+ strlen (actual_class_name));
xfree (actual_class_name);
}
break;
@@ -12791,7 +15509,8 @@ fixup_partial_die (struct partial_die_info *part_die,
{
struct partial_die_info *spec_die;
- spec_die = find_partial_die (part_die->spec_offset, cu);
+ spec_die = find_partial_die (part_die->spec_offset,
+ part_die->spec_is_dwz, cu);
fixup_partial_die (spec_die, cu);
@@ -12833,7 +15552,7 @@ fixup_partial_die (struct partial_die_info *part_die,
{
char *demangled;
- demangled = cplus_demangle (part_die->linkage_name, DMGL_TYPES);
+ demangled = gdb_demangle (part_die->linkage_name, DMGL_TYPES);
if (demangled)
{
const char *base;
@@ -12846,8 +15565,8 @@ fixup_partial_die (struct partial_die_info *part_die,
else
base = demangled;
- part_die->name = obsavestring (base, strlen (base),
- &cu->objfile->objfile_obstack);
+ part_die->name = obstack_copy0 (&cu->objfile->objfile_obstack,
+ base, strlen (base));
xfree (demangled);
}
}
@@ -12857,10 +15576,10 @@ fixup_partial_die (struct partial_die_info *part_die,
/* Read an attribute value described by an attribute form. */
-static gdb_byte *
+static const gdb_byte *
read_attribute_value (const struct die_reader_specs *reader,
struct attribute *attr, unsigned form,
- gdb_byte *info_ptr)
+ const gdb_byte *info_ptr)
{
struct dwarf2_cu *cu = reader->cu;
bfd *abfd = reader->abfd;
@@ -12879,6 +15598,10 @@ read_attribute_value (const struct die_reader_specs *reader,
&cu->header, &bytes_read);
info_ptr += bytes_read;
break;
+ case DW_FORM_GNU_ref_alt:
+ DW_UNSND (attr) = read_offset (abfd, info_ptr, &cu->header, &bytes_read);
+ info_ptr += bytes_read;
+ break;
case DW_FORM_addr:
DW_ADDR (attr) = read_address (abfd, info_ptr, cu, &bytes_read);
info_ptr += bytes_read;
@@ -12921,10 +15644,25 @@ read_attribute_value (const struct die_reader_specs *reader,
info_ptr += bytes_read;
break;
case DW_FORM_strp:
- DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
- &bytes_read);
- DW_STRING_IS_CANONICAL (attr) = 0;
- info_ptr += bytes_read;
+ if (!cu->per_cu->is_dwz)
+ {
+ DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
+ &bytes_read);
+ DW_STRING_IS_CANONICAL (attr) = 0;
+ info_ptr += bytes_read;
+ break;
+ }
+ /* FALLTHROUGH */
+ case DW_FORM_GNU_strp_alt:
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+ LONGEST str_offset = read_offset (abfd, info_ptr, cu_header,
+ &bytes_read);
+
+ DW_STRING (attr) = read_indirect_string_from_dwz (dwz, str_offset);
+ DW_STRING_IS_CANONICAL (attr) = 0;
+ info_ptr += bytes_read;
+ }
break;
case DW_FORM_exprloc:
case DW_FORM_block:
@@ -12983,11 +15721,7 @@ read_attribute_value (const struct die_reader_specs *reader,
info_ptr += 8;
break;
case DW_FORM_ref_sig8:
- /* Convert the signature to something we can record in DW_UNSND
- for later lookup.
- NOTE: This is NULL if the type wasn't found. */
- DW_SIGNATURED_TYPE (attr) =
- lookup_signatured_type (read_8_bytes (abfd, info_ptr));
+ DW_SIGNATURE (attr) = read_8_bytes (abfd, info_ptr);
info_ptr += 8;
break;
case DW_FORM_ref_udata:
@@ -13036,6 +15770,10 @@ read_attribute_value (const struct die_reader_specs *reader,
bfd_get_filename (abfd));
}
+ /* Super hack. */
+ if (cu->per_cu->is_dwz && attr_form_is_ref (attr))
+ attr->form = DW_FORM_GNU_ref_alt;
+
/* We have seen instances where the compiler tried to emit a byte
size attribute of -1 which ended up being encoded as an unsigned
0xffffffff. Although 0xffffffff is technically a valid size value,
@@ -13058,10 +15796,10 @@ read_attribute_value (const struct die_reader_specs *reader,
/* Read an attribute described by an abbreviated attribute. */
-static gdb_byte *
+static const gdb_byte *
read_attribute (const struct die_reader_specs *reader,
struct attribute *attr, struct attr_abbrev *abbrev,
- gdb_byte *info_ptr)
+ const gdb_byte *info_ptr)
{
attr->name = abbrev->name;
return read_attribute_value (reader, attr, abbrev->form, info_ptr);
@@ -13070,49 +15808,49 @@ read_attribute (const struct die_reader_specs *reader,
/* Read dwarf information from a buffer. */
static unsigned int
-read_1_byte (bfd *abfd, gdb_byte *buf)
+read_1_byte (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_8 (abfd, buf);
}
static int
-read_1_signed_byte (bfd *abfd, gdb_byte *buf)
+read_1_signed_byte (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_signed_8 (abfd, buf);
}
static unsigned int
-read_2_bytes (bfd *abfd, gdb_byte *buf)
+read_2_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_16 (abfd, buf);
}
static int
-read_2_signed_bytes (bfd *abfd, gdb_byte *buf)
+read_2_signed_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_signed_16 (abfd, buf);
}
static unsigned int
-read_4_bytes (bfd *abfd, gdb_byte *buf)
+read_4_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_32 (abfd, buf);
}
static int
-read_4_signed_bytes (bfd *abfd, gdb_byte *buf)
+read_4_signed_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_signed_32 (abfd, buf);
}
static ULONGEST
-read_8_bytes (bfd *abfd, gdb_byte *buf)
+read_8_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_64 (abfd, buf);
}
static CORE_ADDR
-read_address (bfd *abfd, gdb_byte *buf, struct dwarf2_cu *cu,
+read_address (bfd *abfd, const gdb_byte *buf, struct dwarf2_cu *cu,
unsigned int *bytes_read)
{
struct comp_unit_head *cu_header = &cu->header;
@@ -13201,7 +15939,7 @@ read_address (bfd *abfd, gdb_byte *buf, struct dwarf2_cu *cu,
] */
static LONGEST
-read_initial_length (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read)
+read_initial_length (bfd *abfd, const gdb_byte *buf, unsigned int *bytes_read)
{
LONGEST length = bfd_get_32 (abfd, buf);
@@ -13233,7 +15971,7 @@ read_initial_length (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read)
This is useful when reading non-comp-unit headers. */
static LONGEST
-read_checked_initial_length_and_offset (bfd *abfd, gdb_byte *buf,
+read_checked_initial_length_and_offset (bfd *abfd, const gdb_byte *buf,
const struct comp_unit_head *cu_header,
unsigned int *bytes_read,
unsigned int *offset_size)
@@ -13256,7 +15994,8 @@ read_checked_initial_length_and_offset (bfd *abfd, gdb_byte *buf,
given by cu_header->offset_size. */
static LONGEST
-read_offset (bfd *abfd, gdb_byte *buf, const struct comp_unit_head *cu_header,
+read_offset (bfd *abfd, const gdb_byte *buf,
+ const struct comp_unit_head *cu_header,
unsigned int *bytes_read)
{
LONGEST offset = read_offset_1 (abfd, buf, cu_header->offset_size);
@@ -13268,7 +16007,7 @@ read_offset (bfd *abfd, gdb_byte *buf, const struct comp_unit_head *cu_header,
/* Read an offset from the data stream. */
static LONGEST
-read_offset_1 (bfd *abfd, gdb_byte *buf, unsigned int offset_size)
+read_offset_1 (bfd *abfd, const gdb_byte *buf, unsigned int offset_size)
{
LONGEST retval = 0;
@@ -13289,8 +16028,8 @@ read_offset_1 (bfd *abfd, gdb_byte *buf, unsigned int offset_size)
return retval;
}
-static gdb_byte *
-read_n_bytes (bfd *abfd, gdb_byte *buf, unsigned int size)
+static const gdb_byte *
+read_n_bytes (bfd *abfd, const gdb_byte *buf, unsigned int size)
{
/* If the size of a host char is 8 bits, we can return a pointer
to the buffer, otherwise we have to copy the data to a buffer
@@ -13299,8 +16038,9 @@ read_n_bytes (bfd *abfd, gdb_byte *buf, unsigned int size)
return buf;
}
-static char *
-read_direct_string (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
+static const char *
+read_direct_string (bfd *abfd, const gdb_byte *buf,
+ unsigned int *bytes_read_ptr)
{
/* If the size of a host char is 8 bits, we can return a pointer
to the string, otherwise we have to copy the string to a buffer
@@ -13311,11 +16051,11 @@ read_direct_string (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
*bytes_read_ptr = 1;
return NULL;
}
- *bytes_read_ptr = strlen ((char *) buf) + 1;
- return (char *) buf;
+ *bytes_read_ptr = strlen ((const char *) buf) + 1;
+ return (const char *) buf;
}
-static char *
+static const char *
read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
{
dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->str);
@@ -13329,11 +16069,35 @@ read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
gdb_assert (HOST_CHAR_BIT == 8);
if (dwarf2_per_objfile->str.buffer[str_offset] == '\0')
return NULL;
- return (char *) (dwarf2_per_objfile->str.buffer + str_offset);
+ return (const char *) (dwarf2_per_objfile->str.buffer + str_offset);
}
-static char *
-read_indirect_string (bfd *abfd, gdb_byte *buf,
+/* Read a string at offset STR_OFFSET in the .debug_str section from
+ the .dwz file DWZ. Throw an error if the offset is too large. If
+ the string consists of a single NUL byte, return NULL; otherwise
+ return a pointer to the string. */
+
+static const char *
+read_indirect_string_from_dwz (struct dwz_file *dwz, LONGEST str_offset)
+{
+ dwarf2_read_section (dwarf2_per_objfile->objfile, &dwz->str);
+
+ if (dwz->str.buffer == NULL)
+ error (_("DW_FORM_GNU_strp_alt used without .debug_str "
+ "section [in module %s]"),
+ bfd_get_filename (dwz->dwz_bfd));
+ if (str_offset >= dwz->str.size)
+ error (_("DW_FORM_GNU_strp_alt pointing outside of "
+ ".debug_str section [in module %s]"),
+ bfd_get_filename (dwz->dwz_bfd));
+ gdb_assert (HOST_CHAR_BIT == 8);
+ if (dwz->str.buffer[str_offset] == '\0')
+ return NULL;
+ return (const char *) (dwz->str.buffer + str_offset);
+}
+
+static const char *
+read_indirect_string (bfd *abfd, const gdb_byte *buf,
const struct comp_unit_head *cu_header,
unsigned int *bytes_read_ptr)
{
@@ -13343,7 +16107,8 @@ read_indirect_string (bfd *abfd, gdb_byte *buf,
}
static ULONGEST
-read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
+read_unsigned_leb128 (bfd *abfd, const gdb_byte *buf,
+ unsigned int *bytes_read_ptr)
{
ULONGEST result;
unsigned int num_read;
@@ -13371,7 +16136,8 @@ read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
}
static LONGEST
-read_signed_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
+read_signed_leb128 (bfd *abfd, const gdb_byte *buf,
+ unsigned int *bytes_read_ptr)
{
LONGEST result;
int i, shift, num_read;
@@ -13413,11 +16179,11 @@ read_addr_index_1 (unsigned int addr_index, ULONGEST addr_base, int addr_size)
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);
+ objfile_name (objfile));
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);
+ objfile_name (objfile));
info_ptr = (dwarf2_per_objfile->addr.buffer
+ addr_base + addr_index * addr_size);
if (addr_size == 4)
@@ -13437,7 +16203,7 @@ read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index)
/* 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,
+read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr,
unsigned int *bytes_read)
{
bfd *abfd = cu->objfile->obfd;
@@ -13459,7 +16225,7 @@ struct dwarf2_read_addr_index_data
static void
dwarf2_read_addr_index_reader (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
+ const gdb_byte *info_ptr,
struct die_info *comp_unit_die,
int has_children,
void *data)
@@ -13501,8 +16267,9 @@ dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
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. */
+ For now we skip this optimization. */
if (cu != NULL)
{
@@ -13513,8 +16280,10 @@ dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
{
struct dwarf2_read_addr_index_data aidata;
- init_cutu_and_read_dies_simple (per_cu, dwarf2_read_addr_index_reader,
- &aidata);
+ /* Note: We can't use init_cutu_and_read_dies_simple here,
+ we need addr_base. */
+ init_cutu_and_read_dies (per_cu, NULL, 0, 0,
+ dwarf2_read_addr_index_reader, &aidata);
addr_base = aidata.addr_base;
addr_size = aidata.addr_size;
}
@@ -13522,44 +16291,48 @@ dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
return read_addr_index_1 (addr_index, addr_base, addr_size);
}
-/* Given a DW_AT_str_index, fetch the string. */
+/* Given a DW_FORM_GNU_str_index, fetch the string.
+ This is only used by the Fission support. */
-static char *
+static const 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;
+ const char *dwo_name = objfile_name (objfile);
bfd *abfd = objfile->obfd;
- struct dwo_sections *sections = &reader->dwo_file->sections;
- gdb_byte *info_ptr;
+ struct dwarf2_section_info *str_section = &reader->dwo_file->sections.str;
+ struct dwarf2_section_info *str_offsets_section =
+ &reader->dwo_file->sections.str_offsets;
+ const gdb_byte *info_ptr;
ULONGEST str_offset;
+ static const char form_name[] = "DW_FORM_GNU_str_index";
- dwarf2_read_section (objfile, &sections->str);
- dwarf2_read_section (objfile, &sections->str_offsets);
- if (sections->str.buffer == NULL)
- error (_("DW_FORM_str_index used without .debug_str.dwo section"
+ dwarf2_read_section (objfile, str_section);
+ dwarf2_read_section (objfile, str_offsets_section);
+ if (str_section->buffer == NULL)
+ error (_("%s 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"
+ form_name, (long) cu->header.offset.sect_off, dwo_name);
+ if (str_offsets_section->buffer == NULL)
+ error (_("%s 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"
+ form_name, (long) cu->header.offset.sect_off, dwo_name);
+ if (str_index * cu->header.offset_size >= str_offsets_section->size)
+ error (_("%s 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
+ form_name, (long) cu->header.offset.sect_off, dwo_name);
+ info_ptr = (str_offsets_section->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"
+ if (str_offset >= str_section->size)
+ error (_("Offset from %s 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);
+ form_name, (long) cu->header.offset.sect_off, dwo_name);
+ return (const char *) (str_section->buffer + str_offset);
}
/* Return the length of an LEB128 number in BUF. */
@@ -13586,6 +16359,7 @@ set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
case DW_LANG_C89:
case DW_LANG_C99:
case DW_LANG_C:
+ case DW_LANG_UPC:
cu->language = language_c;
break;
case DW_LANG_C_plus_plus:
@@ -13748,7 +16522,7 @@ free_line_header (struct line_header *lh)
/* Add an entry to LH's include directory table. */
static void
-add_include_dir (struct line_header *lh, char *include_dir)
+add_include_dir (struct line_header *lh, const char *include_dir)
{
/* Grow the array if necessary. */
if (lh->include_dirs_size == 0)
@@ -13772,7 +16546,7 @@ add_include_dir (struct line_header *lh, char *include_dir)
static void
add_file_name (struct line_header *lh,
- char *name,
+ const char *name,
unsigned int dir_index,
unsigned int mod_time,
unsigned int length)
@@ -13803,6 +16577,30 @@ add_file_name (struct line_header *lh,
fe->symtab = NULL;
}
+/* A convenience function to find the proper .debug_line section for a
+ CU. */
+
+static struct dwarf2_section_info *
+get_debug_line_section (struct dwarf2_cu *cu)
+{
+ struct dwarf2_section_info *section;
+
+ /* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
+ DWO file. */
+ if (cu->dwo_unit && cu->per_cu->is_debug_types)
+ section = &cu->dwo_unit->dwo_file->sections.line;
+ else if (cu->per_cu->is_dwz)
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+
+ section = &dwz->line;
+ }
+ else
+ section = &dwarf2_per_objfile->line;
+
+ return section;
+}
+
/* Read the statement program header starting at OFFSET in
.debug_line, or .debug_line.dwo. Return a pointer
to a struct line_header, allocated using xmalloc.
@@ -13816,20 +16614,14 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
{
struct cleanup *back_to;
struct line_header *lh;
- gdb_byte *line_ptr;
+ const gdb_byte *line_ptr;
unsigned int bytes_read, offset_size;
int i;
- char *cur_dir, *cur_file;
+ const 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;
-
+ section = get_debug_line_section (cu);
dwarf2_read_section (dwarf2_per_objfile->objfile, section);
if (section->buffer == NULL)
{
@@ -13842,7 +16634,7 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
/* We can't do this until we know the section is non-empty.
Only then do we know we have such a section. */
- abfd = section->asection->owner;
+ abfd = get_section_bfd_owner (section);
/* 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. */
@@ -13867,6 +16659,7 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
if (line_ptr + lh->total_length > (section->buffer + section->size))
{
dwarf2_statement_list_fits_in_line_number_section_complaint ();
+ do_cleanups (back_to);
return 0;
}
lh->statement_program_end = line_ptr + lh->total_length;
@@ -13950,17 +16743,19 @@ dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
in line header LH of PST.
COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown.
If space for the result is malloc'd, it will be freed by a cleanup.
- Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename. */
+ Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename.
-static char *
+ The function creates dangling cleanup registration. */
+
+static const char *
psymtab_include_file_name (const struct line_header *lh, int file_index,
const struct partial_symtab *pst,
const char *comp_dir)
{
const struct file_entry fe = lh->file_names [file_index];
- char *include_name = fe.name;
- char *include_name_to_compare = include_name;
- char *dir_name = NULL;
+ const char *include_name = fe.name;
+ const char *include_name_to_compare = include_name;
+ const char *dir_name = NULL;
const char *pst_filename;
char *copied_name = NULL;
int file_is_pst;
@@ -13992,15 +16787,20 @@ psymtab_include_file_name (const struct line_header *lh, int file_index,
if (dir_name != NULL)
{
- include_name = concat (dir_name, SLASH_STRING,
- include_name, (char *)NULL);
+ char *tem = concat (dir_name, SLASH_STRING,
+ include_name, (char *)NULL);
+
+ make_cleanup (xfree, tem);
+ include_name = tem;
include_name_to_compare = include_name;
- make_cleanup (xfree, include_name);
}
if (!IS_ABSOLUTE_PATH (include_name) && comp_dir != NULL)
{
- include_name_to_compare = concat (comp_dir, SLASH_STRING,
- include_name, (char *)NULL);
+ char *tem = concat (comp_dir, SLASH_STRING,
+ include_name, (char *)NULL);
+
+ make_cleanup (xfree, tem);
+ include_name_to_compare = tem;
}
}
@@ -14014,8 +16814,6 @@ psymtab_include_file_name (const struct line_header *lh, int file_index,
file_is_pst = FILENAME_CMP (include_name_to_compare, pst_filename) == 0;
- if (include_name_to_compare != include_name)
- xfree (include_name_to_compare);
if (copied_name != NULL)
xfree (copied_name);
@@ -14039,8 +16837,8 @@ static void
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;
+ const gdb_byte *line_ptr, *extended_end;
+ const gdb_byte *line_end;
unsigned int bytes_read, extended_len;
unsigned char op_code, extended_op, adj_opcode;
CORE_ADDR baseaddr;
@@ -14078,7 +16876,7 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
directory and file name numbers in the statement program
are 1-based. */
struct file_entry *fe = &lh->file_names[file - 1];
- char *dir = NULL;
+ const char *dir = NULL;
if (fe->dir_index)
dir = lh->include_dirs[fe->dir_index - 1];
@@ -14154,12 +16952,12 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
GCd by the linker. Ignore it. PR gdb/12528 */
long line_offset
- = line_ptr - dwarf2_per_objfile->line.buffer;
+ = line_ptr - get_debug_line_section (cu)->buffer;
complaint (&symfile_complaints,
_(".debug_line address at offset 0x%lx is 0 "
"[in module %s]"),
- line_offset, objfile->name);
+ line_offset, objfile_name (objfile));
p_record_line = noop_record_line;
}
@@ -14169,7 +16967,7 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
break;
case DW_LNE_define_file:
{
- char *cur_file;
+ const char *cur_file;
unsigned int dir_index, mod_time, length;
cur_file = read_direct_string (abfd, line_ptr,
@@ -14251,7 +17049,7 @@ dwarf_decode_lines_1 (struct line_header *lh, const char *comp_dir,
0-based, but the directory and file name numbers in
the statement program are 1-based. */
struct file_entry *fe;
- char *dir = NULL;
+ const char *dir = NULL;
file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
@@ -14371,7 +17169,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
for (file_index = 0; file_index < lh->num_file_names; file_index++)
if (lh->file_names[file_index].included_p == 1)
{
- char *include_name =
+ const char *include_name =
psymtab_include_file_name (lh, file_index, pst, comp_dir);
if (include_name != NULL)
dwarf2_create_include_psymtab (include_name, pst, objfile);
@@ -14386,7 +17184,7 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
for (i = 0; i < lh->num_file_names; i++)
{
- char *dir = NULL;
+ const char *dir = NULL;
struct file_entry *fe;
fe = &lh->file_names[i];
@@ -14433,10 +17231,10 @@ dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
subfile's name. */
static void
-dwarf2_start_subfile (char *filename, const char *dirname,
+dwarf2_start_subfile (const char *filename, const char *dirname,
const char *comp_dir)
{
- char *fullname;
+ char *copy = NULL;
/* While reading the DIEs, we call start_symtab(DW_AT_name, DW_AT_comp_dir).
`start_symtab' will always pass the contents of DW_AT_comp_dir as
@@ -14449,14 +17247,15 @@ dwarf2_start_subfile (char *filename, const char *dirname,
`else' branch below isn't an issue. */
if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL)
- fullname = concat (dirname, SLASH_STRING, filename, (char *)NULL);
- else
- fullname = filename;
+ {
+ copy = concat (dirname, SLASH_STRING, filename, (char *)NULL);
+ filename = copy;
+ }
- start_subfile (fullname, comp_dir);
+ start_subfile (filename, comp_dir);
- if (fullname != filename)
- xfree (fullname);
+ if (copy != NULL)
+ xfree (copy);
}
/* Start a symtab for DWARF.
@@ -14464,7 +17263,7 @@ dwarf2_start_subfile (char *filename, const char *dirname,
static void
dwarf2_start_symtab (struct dwarf2_cu *cu,
- char *name, char *comp_dir, CORE_ADDR low_pc)
+ const char *name, const char *comp_dir, CORE_ADDR low_pc)
{
start_symtab (name, comp_dir, low_pc);
record_debugformat ("DWARF 2");
@@ -14473,7 +17272,7 @@ dwarf2_start_symtab (struct dwarf2_cu *cu,
/* We assume that we're processing GCC output. */
processing_gcc_compilation = 2;
- processing_has_namespace_info = 0;
+ cu->processing_has_namespace_info = 0;
}
static void
@@ -14497,7 +17296,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
variable has been optimized away. */
if (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0)
{
- SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;
return;
}
@@ -14521,7 +17320,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
else
SYMBOL_VALUE_ADDRESS (sym) =
read_addr_index_from_leb128 (cu, DW_BLOCK (attr)->data + 1, &dummy);
- SYMBOL_CLASS (sym) = LOC_STATIC;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_STATIC;
fixup_symbol_section (sym, objfile);
SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
SYMBOL_SECTION (sym));
@@ -14535,10 +17334,9 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
not be worthwhile. I'm assuming that it isn't unless performance
or memory numbers show me otherwise. */
- dwarf2_symbol_mark_computed (attr, sym, cu);
- SYMBOL_CLASS (sym) = LOC_COMPUTED;
+ dwarf2_symbol_mark_computed (attr, sym, cu, 0);
- if (SYMBOL_COMPUTED_OPS (sym) == &dwarf2_loclist_funcs)
+ if (SYMBOL_COMPUTED_OPS (sym)->location_has_loclist)
cu->has_loclist = 1;
}
@@ -14556,7 +17354,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
{
struct objfile *objfile = cu->objfile;
struct symbol *sym = NULL;
- char *name;
+ const char *name;
struct attribute *attr = NULL;
struct attribute *attr2 = NULL;
CORE_ADDR baseaddr;
@@ -14575,11 +17373,11 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
if (space)
sym = space;
else
- sym = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol);
+ sym = allocate_symbol (objfile);
OBJSTAT (objfile, n_syms++);
/* Cache this symbol's name and the name's demangled form (if any). */
- SYMBOL_SET_LANGUAGE (sym, cu->language);
+ SYMBOL_SET_LANGUAGE (sym, cu->language, &objfile->objfile_obstack);
linkagename = dwarf2_physname (name, die, cu);
SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile);
@@ -14588,13 +17386,13 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
if (cu->language == language_fortran
&& symbol_get_demangled_name (&(sym->ginfo)) == NULL)
symbol_set_demangled_name (&(sym->ginfo),
- (char *) dwarf2_full_name (name, die, cu),
+ dwarf2_full_name (name, die, cu),
NULL);
/* Default assumptions.
Use the passed type or decode it from the die. */
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
- SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_OPTIMIZED_OUT;
if (type != NULL)
SYMBOL_TYPE (sym) = type;
else
@@ -14637,13 +17435,13 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
}
SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_core_addr;
SYMBOL_DOMAIN (sym) = LABEL_DOMAIN;
- SYMBOL_CLASS (sym) = LOC_LABEL;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_LABEL;
add_symbol_to_list (sym, cu->list_in_scope);
break;
case DW_TAG_subprogram:
/* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
finish_block. */
- SYMBOL_CLASS (sym) = LOC_BLOCK;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
attr2 = dwarf2_attr (die, DW_AT_external, cu);
if ((attr2 && (DW_UNSND (attr2) != 0))
|| cu->language == language_ada)
@@ -14664,7 +17462,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
case DW_TAG_inlined_subroutine:
/* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
finish_block. */
- SYMBOL_CLASS (sym) = LOC_BLOCK;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
SYMBOL_INLINED (sym) = 1;
list_to_add = cu->list_in_scope;
break;
@@ -14709,6 +17507,13 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
{
var_decode_location (attr, sym, cu);
attr2 = dwarf2_attr (die, DW_AT_external, cu);
+
+ /* Fortran explicitly imports any global symbols to the local
+ scope by DW_TAG_common_block. */
+ if (cu->language == language_fortran && die->parent
+ && die->parent->tag == DW_TAG_common_block)
+ attr2 = NULL;
+
if (SYMBOL_CLASS (sym) == LOC_STATIC
&& SYMBOL_VALUE_ADDRESS (sym) == 0
&& !dwarf2_per_objfile->has_section_at_zero)
@@ -14732,7 +17537,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
&& die->parent->tag == DW_TAG_module
&& cu->producer
&& strncmp (cu->producer, "GNU Fortran ", 12) == 0)
- SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_UNRESOLVED;
/* A variable with DW_AT_external is never static,
but it may be block-scoped. */
@@ -14751,15 +17556,26 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
the minimal symbol table whenever the variable is
referenced. */
attr2 = dwarf2_attr (die, DW_AT_external, cu);
- if (attr2 && (DW_UNSND (attr2) != 0)
- && dwarf2_attr (die, DW_AT_type, cu) != NULL)
+
+ /* Fortran explicitly imports any global symbols to the local
+ scope by DW_TAG_common_block. */
+ if (cu->language == language_fortran && die->parent
+ && die->parent->tag == DW_TAG_common_block)
+ {
+ /* SYMBOL_CLASS doesn't matter here because
+ read_common_block is going to reset it. */
+ if (!suppress_add)
+ list_to_add = cu->list_in_scope;
+ }
+ else if (attr2 && (DW_UNSND (attr2) != 0)
+ && dwarf2_attr (die, DW_AT_type, cu) != NULL)
{
/* A variable with DW_AT_external is never static, but it
may be block-scoped. */
list_to_add = (cu->list_in_scope == &file_symbols
? &global_symbols : cu->list_in_scope);
- SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_UNRESOLVED;
}
else if (!die_is_declaration (die, cu))
{
@@ -14806,7 +17622,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
case DW_TAG_union_type:
case DW_TAG_set_type:
case DW_TAG_enumeration_type:
- SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
{
@@ -14843,13 +17659,13 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
}
break;
case DW_TAG_typedef:
- SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
list_to_add = cu->list_in_scope;
break;
case DW_TAG_base_type:
case DW_TAG_subrange_type:
- SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
list_to_add = cu->list_in_scope;
break;
@@ -14869,10 +17685,16 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
? &global_symbols : cu->list_in_scope);
}
break;
+ case DW_TAG_imported_declaration:
case DW_TAG_namespace:
- SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
list_to_add = &global_symbols;
break;
+ case DW_TAG_common_block:
+ SYMBOL_ACLASS_INDEX (sym) = LOC_COMMON_BLOCK;
+ SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN;
+ add_symbol_to_list (sym, cu->list_in_scope);
+ break;
default:
/* Not a tag we recognize. Hopefully we aren't processing
trash data, but since we must specifically ignore things
@@ -14895,7 +17717,7 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
/* For the benefit of old versions of GCC, check for anonymous
namespaces based on the demangled name. */
- if (!processing_has_namespace_info
+ if (!cu->processing_has_namespace_info
&& cu->language == language_cplus)
cp_scan_for_anonymous_namespaces (sym, objfile);
}
@@ -14919,8 +17741,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
because that is the interpretation long in use by GCC. */
static gdb_byte *
-dwarf2_const_value_data (struct attribute *attr, struct type *type,
- const char *name, struct obstack *obstack,
+dwarf2_const_value_data (const struct attribute *attr, struct obstack *obstack,
struct dwarf2_cu *cu, LONGEST *value, int bits)
{
struct objfile *objfile = cu->objfile;
@@ -14952,10 +17773,10 @@ dwarf2_const_value_data (struct attribute *attr, struct type *type,
expression. */
static void
-dwarf2_const_value_attr (struct attribute *attr, struct type *type,
+dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
const char *name, struct obstack *obstack,
struct dwarf2_cu *cu,
- LONGEST *value, gdb_byte **bytes,
+ LONGEST *value, const gdb_byte **bytes,
struct dwarf2_locexpr_baton **baton)
{
struct objfile *objfile = cu->objfile;
@@ -14982,13 +17803,12 @@ dwarf2_const_value_attr (struct attribute *attr, struct type *type,
/* Symbols of this form are reasonably rare, so we just
piggyback on the existing location code rather than writing
a new implementation of symbol_computed_ops. */
- *baton = obstack_alloc (&objfile->objfile_obstack,
- sizeof (struct dwarf2_locexpr_baton));
+ *baton = obstack_alloc (obstack, sizeof (struct dwarf2_locexpr_baton));
(*baton)->per_cu = cu->per_cu;
gdb_assert ((*baton)->per_cu);
(*baton)->size = 2 + cu_header->addr_size;
- data = obstack_alloc (&objfile->objfile_obstack, (*baton)->size);
+ data = obstack_alloc (obstack, (*baton)->size);
(*baton)->data = data;
data[0] = DW_OP_addr;
@@ -15000,9 +17820,10 @@ dwarf2_const_value_attr (struct attribute *attr, struct type *type,
case DW_FORM_string:
case DW_FORM_strp:
case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_strp_alt:
/* DW_STRING is already allocated on the objfile obstack, point
directly to it. */
- *bytes = (gdb_byte *) DW_STRING (attr);
+ *bytes = (const gdb_byte *) DW_STRING (attr);
break;
case DW_FORM_block1:
case DW_FORM_block2:
@@ -15022,20 +17843,16 @@ dwarf2_const_value_attr (struct attribute *attr, struct type *type,
converted to host endianness, so we just need to sign- or
zero-extend it as appropriate. */
case DW_FORM_data1:
- *bytes = dwarf2_const_value_data (attr, type, name,
- obstack, cu, value, 8);
+ *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 8);
break;
case DW_FORM_data2:
- *bytes = dwarf2_const_value_data (attr, type, name,
- obstack, cu, value, 16);
+ *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 16);
break;
case DW_FORM_data4:
- *bytes = dwarf2_const_value_data (attr, type, name,
- obstack, cu, value, 32);
+ *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 32);
break;
case DW_FORM_data8:
- *bytes = dwarf2_const_value_data (attr, type, name,
- obstack, cu, value, 64);
+ *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 64);
break;
case DW_FORM_sdata:
@@ -15059,13 +17876,13 @@ dwarf2_const_value_attr (struct attribute *attr, struct type *type,
/* Copy constant value from an attribute to a symbol. */
static void
-dwarf2_const_value (struct attribute *attr, struct symbol *sym,
+dwarf2_const_value (const struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct comp_unit_head *cu_header = &cu->header;
LONGEST value;
- gdb_byte *bytes;
+ const gdb_byte *bytes;
struct dwarf2_locexpr_baton *baton;
dwarf2_const_value_attr (attr, SYMBOL_TYPE (sym),
@@ -15075,19 +17892,18 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
if (baton != NULL)
{
- SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
SYMBOL_LOCATION_BATON (sym) = baton;
- SYMBOL_CLASS (sym) = LOC_COMPUTED;
+ SYMBOL_ACLASS_INDEX (sym) = dwarf2_locexpr_index;
}
else if (bytes != NULL)
{
SYMBOL_VALUE_BYTES (sym) = bytes;
- SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_CONST_BYTES;
}
else
{
SYMBOL_VALUE (sym) = value;
- SYMBOL_CLASS (sym) = LOC_CONST;
+ SYMBOL_ACLASS_INDEX (sym) = LOC_CONST;
}
}
@@ -15169,24 +17985,57 @@ die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
if (!type_attr)
error (_("Dwarf Error: Problem turning containing type into gdb type "
- "[in module %s]"), cu->objfile->name);
+ "[in module %s]"), objfile_name (cu->objfile));
return lookup_die_type (die, type_attr, cu);
}
+/* Return an error marker type to use for the ill formed type in DIE/CU. */
+
+static struct type *
+build_error_marker_type (struct dwarf2_cu *cu, struct die_info *die)
+{
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ char *message, *saved;
+
+ message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
+ objfile_name (objfile),
+ cu->header.offset.sect_off,
+ die->offset.sect_off);
+ saved = obstack_copy0 (&objfile->objfile_obstack,
+ message, strlen (message));
+ xfree (message);
+
+ return init_type (TYPE_CODE_ERROR, 0, 0, saved, objfile);
+}
+
/* Look up the type of DIE in CU using its type attribute ATTR.
+ ATTR must be one of: DW_AT_type, DW_AT_GNAT_descriptive_type,
+ DW_AT_containing_type.
If there is no type substitute an error marker. */
static struct type *
-lookup_die_type (struct die_info *die, struct attribute *attr,
+lookup_die_type (struct die_info *die, const struct attribute *attr,
struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct type *this_type;
+ gdb_assert (attr->name == DW_AT_type
+ || attr->name == DW_AT_GNAT_descriptive_type
+ || attr->name == DW_AT_containing_type);
+
/* First see if we have it cached. */
- if (is_ref_attr (attr))
+ if (attr->form == DW_FORM_GNU_ref_alt)
+ {
+ struct dwarf2_per_cu_data *per_cu;
+ sect_offset offset = dwarf2_get_ref_die_offset (attr);
+
+ per_cu = dwarf2_find_containing_comp_unit (offset, 1, cu->objfile);
+ this_type = get_die_type_at_offset (offset, per_cu);
+ }
+ else if (attr_form_is_ref (attr))
{
sect_offset offset = dwarf2_get_ref_die_offset (attr);
@@ -15194,66 +18043,41 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
}
else if (attr->form == DW_FORM_ref_sig8)
{
- struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr);
+ ULONGEST signature = DW_SIGNATURE (attr);
- /* 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.sect_off, objfile->name);
-
- 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);
- }
+ return get_signatured_type (die, signature, cu);
}
else
{
- dump_die_for_error (die);
- error (_("Dwarf Error: Bad type attribute %s [in module %s]"),
- dwarf_attr_name (attr->name), objfile->name);
+ complaint (&symfile_complaints,
+ _("Dwarf Error: Bad type attribute %s in DIE"
+ " at 0x%x [in module %s]"),
+ dwarf_attr_name (attr->name), die->offset.sect_off,
+ objfile_name (objfile));
+ return build_error_marker_type (cu, die);
}
/* If not cached we need to read it in. */
if (this_type == NULL)
{
- struct die_info *type_die;
+ struct die_info *type_die = NULL;
struct dwarf2_cu *type_cu = cu;
- type_die = follow_die_ref_or_sig (die, attr, &type_cu);
- /* If we found the type now, it's probably because the type came
+ if (attr_form_is_ref (attr))
+ type_die = follow_die_ref (die, attr, &type_cu);
+ if (type_die == NULL)
+ return build_error_marker_type (cu, die);
+ /* If we find 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);
+ this_type = read_type_die (type_die, type_cu);
}
/* If we still don't have a type use an error marker. */
if (this_type == NULL)
- {
- char *message, *saved;
-
- /* read_type_die already issued a complaint. */
- message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
- 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, objfile);
- }
+ return build_error_marker_type (cu, die);
return this_type;
}
@@ -15261,7 +18085,7 @@ lookup_die_type (struct die_info *die, struct attribute *attr,
/* Return the type in DIE, CU.
Returns NULL for invalid types.
- This first does a lookup in the appropriate type_hash table,
+ This first does a lookup in die_type_hash,
and only reads the die in if necessary.
NOTE: This can be called when reading in partial or full symbols. */
@@ -15323,6 +18147,9 @@ read_type_die_1 (struct die_info *die, struct dwarf2_cu *cu)
case DW_TAG_volatile_type:
this_type = read_tag_volatile_type (die, cu);
break;
+ case DW_TAG_restrict_type:
+ this_type = read_tag_restrict_type (die, cu);
+ break;
case DW_TAG_string_type:
this_type = read_tag_string_type (die, cu);
break;
@@ -15397,7 +18224,7 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
if (actual_name != NULL)
{
- char *die_name = dwarf2_name (die, cu);
+ const char *die_name = dwarf2_name (die, cu);
if (die_name != NULL
&& strcmp (die_name, actual_name) != 0)
@@ -15412,9 +18239,9 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
&& actual_name[actual_name_len
- die_name_len - 1] == ':')
name =
- obsavestring (actual_name,
- actual_name_len - die_name_len - 2,
- &cu->objfile->objfile_obstack);
+ obstack_copy0 (&cu->objfile->objfile_obstack,
+ actual_name,
+ actual_name_len - die_name_len - 2);
}
}
xfree (actual_name);
@@ -15458,8 +18285,8 @@ anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
if (base == NULL || base == DW_STRING (attr) || base[-1] != ':')
return "";
- return obsavestring (DW_STRING (attr), &base[-1] - DW_STRING (attr),
- &cu->objfile->objfile_obstack);
+ return obstack_copy0 (&cu->objfile->objfile_obstack,
+ DW_STRING (attr), &base[-1] - DW_STRING (attr));
}
/* Return the name of the namespace/class that DIE is defined within,
@@ -15677,8 +18504,8 @@ sibling_die (struct die_info *die)
/* Get name of a die, return NULL if not found. */
-static char *
-dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu,
+static const char *
+dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
struct obstack *obstack)
{
if (name && cu->language == language_cplus)
@@ -15688,8 +18515,7 @@ dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu,
if (canon_name != NULL)
{
if (strcmp (canon_name, name) != 0)
- name = obsavestring (canon_name, strlen (canon_name),
- obstack);
+ name = obstack_copy0 (obstack, canon_name, strlen (canon_name));
xfree (canon_name);
}
}
@@ -15699,7 +18525,7 @@ dwarf2_canonicalize_name (char *name, struct dwarf2_cu *cu,
/* Get name of a die, return NULL if not found. */
-static char *
+static const char *
dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
@@ -15783,15 +18609,15 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
/* Avoid demangling DW_STRING (attr) the second time on a second
call for the same DIE. */
if (!DW_STRING_IS_CANONICAL (attr))
- demangled = cplus_demangle (DW_STRING (attr), DMGL_TYPES);
+ demangled = gdb_demangle (DW_STRING (attr), DMGL_TYPES);
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) = obstack_copy0 (&cu->objfile->objfile_obstack,
+ demangled, strlen (demangled));
DW_STRING_IS_CANONICAL (attr) = 1;
xfree (demangled);
@@ -15948,17 +18774,21 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
case DW_FORM_block4:
case DW_FORM_block:
case DW_FORM_block1:
- fprintf_unfiltered (f, "block: size %d",
- DW_BLOCK (&die->attrs[i])->size);
+ fprintf_unfiltered (f, "block: size %s",
+ pulongest (DW_BLOCK (&die->attrs[i])->size));
break;
case DW_FORM_exprloc:
- fprintf_unfiltered (f, "expression: size %u",
- DW_BLOCK (&die->attrs[i])->size);
+ fprintf_unfiltered (f, "expression: size %s",
+ pulongest (DW_BLOCK (&die->attrs[i])->size));
break;
case DW_FORM_ref_addr:
fprintf_unfiltered (f, "ref address: ");
fputs_filtered (hex_string (DW_UNSND (&die->attrs[i])), f);
break;
+ case DW_FORM_GNU_ref_alt:
+ fprintf_unfiltered (f, "alt ref address: ");
+ fputs_filtered (hex_string (DW_UNSND (&die->attrs[i])), f);
+ break;
case DW_FORM_ref1:
case DW_FORM_ref2:
case DW_FORM_ref4:
@@ -15981,15 +18811,13 @@ dump_die_shallow (struct ui_file *f, int indent, struct die_info *die)
pulongest (DW_UNSND (&die->attrs[i])));
break;
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.sect_off);
- else
- fprintf_unfiltered (f, "signatured type, offset: unknown");
+ fprintf_unfiltered (f, "signature: %s",
+ hex_string (DW_SIGNATURE (&die->attrs[i])));
break;
case DW_FORM_string:
case DW_FORM_strp:
case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_strp_alt:
fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)",
DW_STRING (&die->attrs[i])
? DW_STRING (&die->attrs[i]) : "",
@@ -16079,35 +18907,15 @@ store_in_ref_table (struct die_info *die, struct dwarf2_cu *cu)
*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)
-{
- switch (attr->form)
- {
- case DW_FORM_ref_addr:
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_udata:
- return 1;
- default:
- return 0;
- }
-}
-
/* 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)
+dwarf2_get_ref_die_offset (const struct attribute *attr)
{
sect_offset retval = { DW_UNSND (attr) };
- if (is_ref_attr (attr))
+ if (attr_form_is_ref (attr))
return retval;
retval.sect_off = 0;
@@ -16121,7 +18929,7 @@ dwarf2_get_ref_die_offset (struct attribute *attr)
* the value held by the attribute is not constant. */
static LONGEST
-dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
+dwarf2_get_attr_constant_value (const struct attribute *attr, int default_value)
{
if (attr->form == DW_FORM_sdata)
return DW_SND (attr);
@@ -16145,12 +18953,12 @@ dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
On exit *REF_CU is the CU of the result. */
static struct die_info *
-follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr,
+follow_die_ref_or_sig (struct die_info *src_die, const struct attribute *attr,
struct dwarf2_cu **ref_cu)
{
struct die_info *die;
- if (is_ref_attr (attr))
+ if (attr_form_is_ref (attr))
die = follow_die_ref (src_die, attr, ref_cu);
else if (attr->form == DW_FORM_ref_sig8)
die = follow_die_sig (src_die, attr, ref_cu);
@@ -16158,7 +18966,7 @@ follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr,
{
dump_die_for_error (src_die);
error (_("Dwarf Error: Expected reference attribute [in module %s]"),
- (*ref_cu)->objfile->name);
+ objfile_name ((*ref_cu)->objfile));
}
return die;
@@ -16170,7 +18978,8 @@ follow_die_ref_or_sig (struct die_info *src_die, struct attribute *attr,
Returns NULL if OFFSET is invalid. */
static struct die_info *
-follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
+follow_die_offset (sect_offset offset, int offset_in_dwz,
+ struct dwarf2_cu **ref_cu)
{
struct die_info temp_die;
struct dwarf2_cu *target_cu, *cu = *ref_cu;
@@ -16187,11 +18996,13 @@ follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
if (! offset_in_cu_p (&cu->header, offset))
return NULL;
}
- else if (! offset_in_cu_p (&cu->header, offset))
+ else if (offset_in_dwz != cu->per_cu->is_dwz
+ || ! offset_in_cu_p (&cu->header, offset))
{
struct dwarf2_per_cu_data *per_cu;
- per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+ per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz,
+ cu->objfile);
/* If necessary, add it to the queue and load its DIEs. */
if (maybe_queue_comp_unit (cu, per_cu, cu->language))
@@ -16216,37 +19027,141 @@ follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
On exit *REF_CU is the CU of the result. */
static struct die_info *
-follow_die_ref (struct die_info *src_die, struct attribute *attr,
+follow_die_ref (struct die_info *src_die, const struct attribute *attr,
struct dwarf2_cu **ref_cu)
{
sect_offset offset = dwarf2_get_ref_die_offset (attr);
struct dwarf2_cu *cu = *ref_cu;
struct die_info *die;
- die = follow_die_offset (offset, ref_cu);
+ die = follow_die_offset (offset,
+ (attr->form == DW_FORM_GNU_ref_alt
+ || cu->per_cu->is_dwz),
+ ref_cu);
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
"at 0x%x [in module %s]"),
- offset.sect_off, src_die->offset.sect_off, cu->objfile->name);
+ offset.sect_off, src_die->offset.sect_off,
+ objfile_name (cu->objfile));
return die;
}
-/* 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. */
+/* 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_loc_sect_off (sect_offset offset,
+ struct dwarf2_per_cu_data *per_cu,
+ CORE_ADDR (*get_frame_pc) (void *baton),
+ void *baton)
+{
+ struct dwarf2_cu *cu;
+ struct die_info *die;
+ struct attribute *attr;
+ struct dwarf2_locexpr_baton retval;
+
+ dw2_setup (per_cu->objfile);
+
+ if (per_cu->cu == NULL)
+ load_cu (per_cu);
+ cu = per_cu->cu;
+
+ die = follow_die_offset (offset, per_cu->is_dwz, &cu);
+ if (!die)
+ error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
+ offset.sect_off, objfile_name (per_cu->objfile));
+
+ attr = dwarf2_attr (die, DW_AT_location, cu);
+ if (!attr)
+ {
+ /* 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;
+ }
+ else if (attr_form_is_section_offset (attr))
+ {
+ struct dwarf2_loclist_baton loclist_baton;
+ CORE_ADDR pc = (*get_frame_pc) (baton);
+ size_t size;
+
+ fill_in_loclist_baton (cu, &loclist_baton, attr);
+
+ retval.data = dwarf2_find_location_expression (&loclist_baton,
+ &size, pc);
+ retval.size = size;
+ }
+ else
+ {
+ 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.sect_off, objfile_name (per_cu->objfile));
+
+ retval.data = DW_BLOCK (attr)->data;
+ retval.size = DW_BLOCK (attr)->size;
+ }
+ retval.per_cu = cu->per_cu;
+
+ age_cached_comp_units ();
+
+ return retval;
+}
+
+/* Like dwarf2_fetch_die_loc_sect_off, but take a CU
+ offset. */
+
+struct dwarf2_locexpr_baton
+dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu,
+ struct dwarf2_per_cu_data *per_cu,
+ CORE_ADDR (*get_frame_pc) (void *baton),
+ void *baton)
+{
+ sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off };
+
+ return dwarf2_fetch_die_loc_sect_off (offset, per_cu, get_frame_pc, baton);
+}
+
+/* Write a constant of a given type as target-ordered bytes into
+ OBSTACK. */
+
+static const gdb_byte *
+write_constant_as_bytes (struct obstack *obstack,
+ enum bfd_endian byte_order,
+ struct type *type,
+ ULONGEST value,
+ LONGEST *len)
+{
+ gdb_byte *result;
+
+ *len = TYPE_LENGTH (type);
+ result = obstack_alloc (obstack, *len);
+ store_unsigned_integer (result, *len, byte_order, value);
+
+ return result;
+}
+
+/* If the DIE at OFFSET in PER_CU has a DW_AT_const_value, return a
+ pointer to the constant bytes and set LEN to the length of the
+ data. If memory is needed, allocate it on OBSTACK. If the DIE
+ does not have a DW_AT_const_value, return NULL. */
-struct dwarf2_locexpr_baton
-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)
+const gdb_byte *
+dwarf2_fetch_constant_bytes (sect_offset offset,
+ struct dwarf2_per_cu_data *per_cu,
+ struct obstack *obstack,
+ LONGEST *len)
{
- sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off };
struct dwarf2_cu *cu;
struct die_info *die;
struct attribute *attr;
- struct dwarf2_locexpr_baton retval;
+ const gdb_byte *result = NULL;
+ struct type *type;
+ LONGEST value;
+ enum bfd_endian byte_order;
dw2_setup (per_cu->objfile);
@@ -16254,47 +19169,104 @@ dwarf2_fetch_die_location_block (cu_offset offset_in_cu,
load_cu (per_cu);
cu = per_cu->cu;
- die = follow_die_offset (offset, &cu);
+ die = follow_die_offset (offset, per_cu->is_dwz, &cu);
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
- offset.sect_off, per_cu->objfile->name);
+ offset.sect_off, objfile_name (per_cu->objfile));
- attr = dwarf2_attr (die, DW_AT_location, cu);
- if (!attr)
- {
- /* 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;
- }
- else if (attr_form_is_section_offset (attr))
- {
- struct dwarf2_loclist_baton loclist_baton;
- CORE_ADDR pc = (*get_frame_pc) (baton);
- size_t size;
+ attr = dwarf2_attr (die, DW_AT_const_value, cu);
+ if (attr == NULL)
+ return NULL;
- fill_in_loclist_baton (cu, &loclist_baton, attr);
+ byte_order = (bfd_big_endian (per_cu->objfile->obfd)
+ ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE);
- retval.data = dwarf2_find_location_expression (&loclist_baton,
- &size, pc);
- retval.size = size;
- }
- else
+ switch (attr->form)
{
- 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.sect_off, per_cu->objfile->name);
+ case DW_FORM_addr:
+ case DW_FORM_GNU_addr_index:
+ {
+ gdb_byte *tem;
- retval.data = DW_BLOCK (attr)->data;
- retval.size = DW_BLOCK (attr)->size;
- }
- retval.per_cu = cu->per_cu;
+ *len = cu->header.addr_size;
+ tem = obstack_alloc (obstack, *len);
+ store_unsigned_integer (tem, *len, byte_order, DW_ADDR (attr));
+ result = tem;
+ }
+ break;
+ case DW_FORM_string:
+ case DW_FORM_strp:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_strp_alt:
+ /* DW_STRING is already allocated on the objfile obstack, point
+ directly to it. */
+ result = (const gdb_byte *) DW_STRING (attr);
+ *len = strlen (DW_STRING (attr));
+ break;
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ case DW_FORM_block:
+ case DW_FORM_exprloc:
+ result = DW_BLOCK (attr)->data;
+ *len = DW_BLOCK (attr)->size;
+ break;
- age_cached_comp_units ();
+ /* The DW_AT_const_value attributes are supposed to carry the
+ symbol's value "represented as it would be on the target
+ architecture." By the time we get here, it's already been
+ converted to host endianness, so we just need to sign- or
+ zero-extend it as appropriate. */
+ case DW_FORM_data1:
+ type = die_type (die, cu);
+ result = dwarf2_const_value_data (attr, obstack, cu, &value, 8);
+ if (result == NULL)
+ result = write_constant_as_bytes (obstack, byte_order,
+ type, value, len);
+ break;
+ case DW_FORM_data2:
+ type = die_type (die, cu);
+ result = dwarf2_const_value_data (attr, obstack, cu, &value, 16);
+ if (result == NULL)
+ result = write_constant_as_bytes (obstack, byte_order,
+ type, value, len);
+ break;
+ case DW_FORM_data4:
+ type = die_type (die, cu);
+ result = dwarf2_const_value_data (attr, obstack, cu, &value, 32);
+ if (result == NULL)
+ result = write_constant_as_bytes (obstack, byte_order,
+ type, value, len);
+ break;
+ case DW_FORM_data8:
+ type = die_type (die, cu);
+ result = dwarf2_const_value_data (attr, obstack, cu, &value, 64);
+ if (result == NULL)
+ result = write_constant_as_bytes (obstack, byte_order,
+ type, value, len);
+ break;
- return retval;
+ case DW_FORM_sdata:
+ type = die_type (die, cu);
+ result = write_constant_as_bytes (obstack, byte_order,
+ type, DW_SND (attr), len);
+ break;
+
+ case DW_FORM_udata:
+ type = die_type (die, cu);
+ result = write_constant_as_bytes (obstack, byte_order,
+ type, DW_UNSND (attr), len);
+ break;
+
+ default:
+ complaint (&symfile_complaints,
+ _("unsupported const value attribute form: '%s'"),
+ dwarf_form_name (attr->form));
+ break;
+ }
+
+ return result;
}
/* Return the type of the DIE at DIE_OFFSET in the CU named by
@@ -16312,76 +19284,183 @@ dwarf2_get_die_type (cu_offset die_offset,
return get_die_type_at_offset (die_offset_sect, per_cu);
}
-/* Follow the signature attribute ATTR in SRC_DIE.
+/* Follow type unit SIG_TYPE referenced by SRC_DIE.
On entry *REF_CU is the CU of SRC_DIE.
- On exit *REF_CU is the CU of the result. */
+ On exit *REF_CU is the CU of the result.
+ Returns NULL if the referenced DIE isn't found. */
static struct die_info *
-follow_die_sig (struct die_info *src_die, struct attribute *attr,
- struct dwarf2_cu **ref_cu)
+follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
+ struct dwarf2_cu **ref_cu)
{
struct objfile *objfile = (*ref_cu)->objfile;
struct die_info temp_die;
- struct signatured_type *sig_type = DW_SIGNATURED_TYPE (attr);
struct dwarf2_cu *sig_cu;
struct die_info *die;
- /* 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]"),
- src_die->offset.sect_off, objfile->name);
+ /* While it might be nice to assert sig_type->type == NULL here,
+ we can get here for DW_AT_imported_declaration where we need
+ the DIE not the type. */
/* If necessary, add it to the queue and load its DIEs. */
if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, language_minimal))
read_signatured_type (sig_type);
- gdb_assert (sig_type->per_cu.cu != NULL);
-
sig_cu = sig_type->per_cu.cu;
+ gdb_assert (sig_cu != NULL);
gdb_assert (sig_type->type_offset_in_section.sect_off != 0);
temp_die.offset = sig_type->type_offset_in_section;
die = htab_find_with_hash (sig_cu->die_hash, &temp_die,
temp_die.offset.sect_off);
if (die)
{
+ /* For .gdb_index version 7 keep track of included TUs.
+ http://sourceware.org/bugzilla/show_bug.cgi?id=15021. */
+ if (dwarf2_per_objfile->index_table != NULL
+ && dwarf2_per_objfile->index_table->version <= 7)
+ {
+ VEC_safe_push (dwarf2_per_cu_ptr,
+ (*ref_cu)->per_cu->imported_symtabs,
+ sig_cu->per_cu);
+ }
+
*ref_cu = sig_cu;
return die;
}
- error (_("Dwarf Error: Cannot find signatured DIE at 0x%x referenced "
- "from DIE at 0x%x [in module %s]"),
- temp_die.offset.sect_off, src_die->offset.sect_off, objfile->name);
+ return NULL;
+}
+
+/* Follow signatured type referenced by ATTR in SRC_DIE.
+ On entry *REF_CU is the CU of SRC_DIE.
+ On exit *REF_CU is the CU of the result.
+ The result is the DIE of the type.
+ If the referenced type cannot be found an error is thrown. */
+
+static struct die_info *
+follow_die_sig (struct die_info *src_die, const struct attribute *attr,
+ struct dwarf2_cu **ref_cu)
+{
+ ULONGEST signature = DW_SIGNATURE (attr);
+ struct signatured_type *sig_type;
+ struct die_info *die;
+
+ gdb_assert (attr->form == DW_FORM_ref_sig8);
+
+ sig_type = lookup_signatured_type (*ref_cu, signature);
+ /* 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 %s referenced"
+ " from DIE at 0x%x [in module %s]"),
+ hex_string (signature), src_die->offset.sect_off,
+ objfile_name ((*ref_cu)->objfile));
+ }
+
+ die = follow_die_sig_1 (src_die, sig_type, ref_cu);
+ if (die == NULL)
+ {
+ dump_die_for_error (src_die);
+ error (_("Dwarf Error: Problem reading signatured DIE %s referenced"
+ " from DIE at 0x%x [in module %s]"),
+ hex_string (signature), src_die->offset.sect_off,
+ objfile_name ((*ref_cu)->objfile));
+ }
+
+ return die;
}
-/* Given an offset of a signatured type, return its signatured_type. */
+/* Get the type specified by SIGNATURE referenced in DIE/CU,
+ reading in and processing the type unit if necessary. */
-static struct signatured_type *
-lookup_signatured_type_at_offset (struct objfile *objfile,
- struct dwarf2_section_info *section,
- sect_offset 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, *sig_type;
-
- length = read_initial_length (objfile->obfd, info_ptr, &initial_length_size);
- sig_offset = (initial_length_size
- + 2 /*version*/
- + (initial_length_size == 4 ? 4 : 8) /*debug_abbrev_offset*/
- + 1 /*address_size*/);
- find_entry.signature = bfd_get_64 (objfile->obfd, info_ptr + sig_offset);
- 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 (sig_type != NULL);
- gdb_assert (offset.sect_off == sig_type->per_cu.offset.sect_off);
+static struct type *
+get_signatured_type (struct die_info *die, ULONGEST signature,
+ struct dwarf2_cu *cu)
+{
+ struct signatured_type *sig_type;
+ struct dwarf2_cu *type_cu;
+ struct die_info *type_die;
+ struct type *type;
- return sig_type;
+ sig_type = lookup_signatured_type (cu, signature);
+ /* sig_type will be NULL if the signatured type is missing from
+ the debug info. */
+ if (sig_type == NULL)
+ {
+ complaint (&symfile_complaints,
+ _("Dwarf Error: Cannot find signatured DIE %s referenced"
+ " from DIE at 0x%x [in module %s]"),
+ hex_string (signature), die->offset.sect_off,
+ objfile_name (dwarf2_per_objfile->objfile));
+ return build_error_marker_type (cu, die);
+ }
+
+ /* If we already know the type we're done. */
+ if (sig_type->type != NULL)
+ return sig_type->type;
+
+ type_cu = cu;
+ type_die = follow_die_sig_1 (die, sig_type, &type_cu);
+ if (type_die != NULL)
+ {
+ /* N.B. We need to call get_die_type to ensure only one type for this DIE
+ is created. This is important, for example, because for c++ classes
+ we need TYPE_NAME set which is only done by new_symbol. Blech. */
+ type = read_type_die (type_die, type_cu);
+ if (type == NULL)
+ {
+ complaint (&symfile_complaints,
+ _("Dwarf Error: Cannot build signatured type %s"
+ " referenced from DIE at 0x%x [in module %s]"),
+ hex_string (signature), die->offset.sect_off,
+ objfile_name (dwarf2_per_objfile->objfile));
+ type = build_error_marker_type (cu, die);
+ }
+ }
+ else
+ {
+ complaint (&symfile_complaints,
+ _("Dwarf Error: Problem reading signatured DIE %s referenced"
+ " from DIE at 0x%x [in module %s]"),
+ hex_string (signature), die->offset.sect_off,
+ objfile_name (dwarf2_per_objfile->objfile));
+ type = build_error_marker_type (cu, die);
+ }
+ sig_type->type = type;
+
+ return type;
+}
+
+/* Get the type specified by the DW_AT_signature ATTR in DIE/CU,
+ reading in and processing the type unit if necessary. */
+
+static struct type *
+get_DW_AT_signature_type (struct die_info *die, const struct attribute *attr,
+ struct dwarf2_cu *cu) /* ARI: editCase function */
+{
+ /* Yes, DW_AT_signature can use a non-ref_sig8 reference. */
+ if (attr_form_is_ref (attr))
+ {
+ struct dwarf2_cu *type_cu = cu;
+ struct die_info *type_die = follow_die_ref (die, attr, &type_cu);
+
+ return read_type_die (type_die, type_cu);
+ }
+ else if (attr->form == DW_FORM_ref_sig8)
+ {
+ return get_signatured_type (die, DW_SIGNATURE (attr), cu);
+ }
+ else
+ {
+ complaint (&symfile_complaints,
+ _("Dwarf Error: DW_AT_signature has bad form %s in DIE"
+ " at 0x%x [in module %s]"),
+ dwarf_form_name (attr->form), die->offset.sect_off,
+ objfile_name (dwarf2_per_objfile->objfile));
+ return build_error_marker_type (cu, die);
+ }
}
/* Load the DIEs associated with type unit PER_CU into memory. */
@@ -16412,7 +19491,7 @@ load_full_type_unit (struct dwarf2_per_cu_data *per_cu)
static void
read_signatured_type_reader (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
+ const gdb_byte *info_ptr,
struct die_info *comp_unit_die,
int has_children,
void *data)
@@ -16458,6 +19537,7 @@ read_signatured_type (struct signatured_type *sig_type)
init_cutu_and_read_dies (per_cu, NULL, 0, 1,
read_signatured_type_reader, NULL);
+ sig_type->per_cu.tu_read = 1;
}
/* Decode simple location descriptions.
@@ -16485,9 +19565,9 @@ static CORE_ADDR
decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
- int i;
- int size = blk->size;
- gdb_byte *data = blk->data;
+ size_t i;
+ size_t size = blk->size;
+ const gdb_byte *data = blk->data;
CORE_ADDR stack[64];
int stacki;
unsigned int bytes_read, unsnd;
@@ -16752,12 +19832,12 @@ dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs)
/* Macro support. */
-/* Return the full name of file number I in *LH's file name table.
- Use COMP_DIR as the name of the current directory of the
- compilation. The result is allocated using xmalloc; the caller is
+/* Return file name relative to the compilation directory of file number I in
+ *LH's file name table. The result is allocated using xmalloc; the caller is
responsible for freeing it. */
+
static char *
-file_full_name (int file, struct line_header *lh, const char *comp_dir)
+file_file_name (int file, struct line_header *lh)
{
/* Is the file number a valid index into the line header's file name
table? Remember that file numbers start with one, not zero. */
@@ -16765,31 +19845,10 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir)
{
struct file_entry *fe = &lh->file_names[file - 1];
- if (IS_ABSOLUTE_PATH (fe->name))
+ if (IS_ABSOLUTE_PATH (fe->name) || fe->dir_index == 0)
return xstrdup (fe->name);
- else
- {
- const char *dir;
- int dir_len;
- char *full_name;
-
- if (fe->dir_index)
- dir = lh->include_dirs[fe->dir_index - 1];
- else
- dir = comp_dir;
-
- if (dir)
- {
- dir_len = strlen (dir);
- full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1);
- strcpy (full_name, dir);
- full_name[dir_len] = '/';
- strcpy (full_name + dir_len + 1, fe->name);
- return full_name;
- }
- else
- return xstrdup (fe->name);
- }
+ return concat (lh->include_dirs[fe->dir_index - 1], SLASH_STRING,
+ fe->name, NULL);
}
else
{
@@ -16798,7 +19857,8 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir)
won't be able to find the file by name. */
char fake_name[80];
- sprintf (fake_name, "<bad macro file number %d>", file);
+ xsnprintf (fake_name, sizeof (fake_name),
+ "<bad macro file number %d>", file);
complaint (&symfile_complaints,
_("bad file number in macro information (%d)"),
@@ -16808,6 +19868,27 @@ file_full_name (int file, struct line_header *lh, const char *comp_dir)
}
}
+/* Return the full name of file number I in *LH's file name table.
+ Use COMP_DIR as the name of the current directory of the
+ compilation. The result is allocated using xmalloc; the caller is
+ responsible for freeing it. */
+static char *
+file_full_name (int file, struct line_header *lh, const char *comp_dir)
+{
+ /* Is the file number a valid index into the line header's file name
+ table? Remember that file numbers start with one, not zero. */
+ if (1 <= file && file <= lh->num_file_names)
+ {
+ char *relative = file_file_name (file, lh);
+
+ if (IS_ABSOLUTE_PATH (relative) || comp_dir == NULL)
+ return relative;
+ return reconcat (relative, comp_dir, SLASH_STRING, relative, NULL);
+ }
+ else
+ return file_file_name (file, lh);
+}
+
static struct macro_source_file *
macro_start_file (int file, int line,
@@ -16815,26 +19896,24 @@ macro_start_file (int file, int line,
const char *comp_dir,
struct line_header *lh, struct objfile *objfile)
{
- /* The full name of this source file. */
- char *full_name = file_full_name (file, lh, comp_dir);
-
- /* We don't create a macro table for this compilation unit
- at all until we actually get a filename. */
- if (! pending_macros)
- pending_macros = new_macro_table (&objfile->objfile_obstack,
- objfile->macro_cache);
+ /* File name relative to the compilation directory of this source file. */
+ char *file_name = file_file_name (file, lh);
if (! current_file)
{
+ /* Note: We don't create a macro table for this compilation unit
+ at all until we actually get a filename. */
+ struct macro_table *macro_table = get_macro_table (objfile, comp_dir);
+
/* If we have no current file, then this must be the start_file
directive for the compilation unit's main source file. */
- current_file = macro_set_main (pending_macros, full_name);
- macro_define_special (pending_macros);
+ current_file = macro_set_main (macro_table, file_name);
+ macro_define_special (macro_table);
}
else
- current_file = macro_include (current_file, line, full_name);
+ current_file = macro_include (current_file, line, file_name);
- xfree (full_name);
+ xfree (file_name);
return current_file;
}
@@ -17014,8 +20093,8 @@ parse_macro_definition (struct macro_source_file *file, int line,
/* Skip some bytes from BYTES according to the form given in FORM.
Returns the new pointer. */
-static gdb_byte *
-skip_form_bytes (bfd *abfd, gdb_byte *bytes, gdb_byte *buffer_end,
+static const gdb_byte *
+skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
enum dwarf_form form,
unsigned int offset_size,
struct dwarf2_section_info *section)
@@ -17048,6 +20127,7 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, gdb_byte *buffer_end,
case DW_FORM_sec_offset:
case DW_FORM_strp:
+ case DW_FORM_GNU_strp_alt:
bytes += offset_size;
break;
@@ -17070,7 +20150,7 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, gdb_byte *buffer_end,
case DW_FORM_udata:
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
- bytes = (gdb_byte *) gdb_skip_leb128 (bytes, buffer_end);
+ bytes = gdb_skip_leb128 (bytes, buffer_end);
if (bytes == NULL)
{
dwarf2_section_buffer_overflow_complaint (section);
@@ -17083,8 +20163,7 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, gdb_byte *buffer_end,
complain:
complaint (&symfile_complaints,
_("invalid form 0x%x in `%s'"),
- form,
- section->asection->name);
+ form, get_section_name (section));
return NULL;
}
}
@@ -17096,17 +20175,17 @@ skip_form_bytes (bfd *abfd, gdb_byte *bytes, gdb_byte *buffer_end,
opcode. Returns an updated pointer to the macro data buffer; or,
on error, issues a complaint and returns NULL. */
-static gdb_byte *
+static const gdb_byte *
skip_unknown_opcode (unsigned int opcode,
- gdb_byte **opcode_definitions,
- gdb_byte *mac_ptr, gdb_byte *mac_end,
+ const gdb_byte **opcode_definitions,
+ const gdb_byte *mac_ptr, const gdb_byte *mac_end,
bfd *abfd,
unsigned int offset_size,
struct dwarf2_section_info *section)
{
unsigned int bytes_read, i;
unsigned long arg;
- gdb_byte *defn;
+ const gdb_byte *defn;
if (opcode_definitions[opcode] == NULL)
{
@@ -17139,10 +20218,10 @@ skip_unknown_opcode (unsigned int opcode,
then this updates *OFFSET_SIZE. Returns a pointer to just after
the header, or issues a complaint and returns NULL on error. */
-static gdb_byte *
-dwarf_parse_macro_header (gdb_byte **opcode_definitions,
+static const gdb_byte *
+dwarf_parse_macro_header (const gdb_byte **opcode_definitions,
bfd *abfd,
- gdb_byte *mac_ptr,
+ const gdb_byte *mac_ptr,
unsigned int *offset_size,
int section_is_gnu)
{
@@ -17199,18 +20278,19 @@ dwarf_parse_macro_header (gdb_byte **opcode_definitions,
including DW_MACRO_GNU_transparent_include. */
static void
-dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
+dwarf_decode_macro_bytes (bfd *abfd,
+ const gdb_byte *mac_ptr, const gdb_byte *mac_end,
struct macro_source_file *current_file,
- struct line_header *lh, char *comp_dir,
+ struct line_header *lh, const char *comp_dir,
struct dwarf2_section_info *section,
- int section_is_gnu,
+ int section_is_gnu, int section_is_dwz,
unsigned int offset_size,
struct objfile *objfile,
htab_t include_hash)
{
enum dwarf_macro_record_type macinfo_type;
int at_commandline;
- gdb_byte *opcode_definitions[256];
+ const gdb_byte *opcode_definitions[256];
mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
&offset_size, section_is_gnu);
@@ -17254,10 +20334,12 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
case DW_MACRO_GNU_undef:
case DW_MACRO_GNU_define_indirect:
case DW_MACRO_GNU_undef_indirect:
+ case DW_MACRO_GNU_define_indirect_alt:
+ case DW_MACRO_GNU_undef_indirect_alt:
{
unsigned int bytes_read;
int line;
- char *body;
+ const char *body;
int is_define;
line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
@@ -17276,11 +20358,21 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
str_offset = read_offset_1 (abfd, mac_ptr, offset_size);
mac_ptr += offset_size;
- body = read_indirect_string_at_offset (abfd, str_offset);
+ if (macinfo_type == DW_MACRO_GNU_define_indirect_alt
+ || macinfo_type == DW_MACRO_GNU_undef_indirect_alt
+ || section_is_dwz)
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+
+ body = read_indirect_string_from_dwz (dwz, str_offset);
+ }
+ else
+ body = read_indirect_string_at_offset (abfd, str_offset);
}
is_define = (macinfo_type == DW_MACRO_GNU_define
- || macinfo_type == DW_MACRO_GNU_define_indirect);
+ || macinfo_type == DW_MACRO_GNU_define_indirect
+ || macinfo_type == DW_MACRO_GNU_define_indirect_alt);
if (! current_file)
{
/* DWARF violation as no main source is present. */
@@ -17304,7 +20396,8 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
else
{
gdb_assert (macinfo_type == DW_MACRO_GNU_undef
- || macinfo_type == DW_MACRO_GNU_undef_indirect);
+ || macinfo_type == DW_MACRO_GNU_undef_indirect
+ || macinfo_type == DW_MACRO_GNU_undef_indirect_alt);
macro_undef (current_file, line, body);
}
}
@@ -17379,14 +20472,36 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
break;
case DW_MACRO_GNU_transparent_include:
+ case DW_MACRO_GNU_transparent_include_alt:
{
LONGEST offset;
void **slot;
+ bfd *include_bfd = abfd;
+ struct dwarf2_section_info *include_section = section;
+ struct dwarf2_section_info alt_section;
+ const gdb_byte *include_mac_end = mac_end;
+ int is_dwz = section_is_dwz;
+ const gdb_byte *new_mac_ptr;
offset = read_offset_1 (abfd, mac_ptr, offset_size);
mac_ptr += offset_size;
- slot = htab_find_slot (include_hash, mac_ptr, INSERT);
+ if (macinfo_type == DW_MACRO_GNU_transparent_include_alt)
+ {
+ struct dwz_file *dwz = dwarf2_get_dwz_file ();
+
+ dwarf2_read_section (dwarf2_per_objfile->objfile,
+ &dwz->macro);
+
+ include_section = &dwz->macro;
+ include_bfd = get_section_bfd_owner (include_section);
+ include_mac_end = dwz->macro.buffer + dwz->macro.size;
+ is_dwz = 1;
+ }
+
+ new_mac_ptr = include_section->buffer + offset;
+ slot = htab_find_slot (include_hash, new_mac_ptr, INSERT);
+
if (*slot != NULL)
{
/* This has actually happened; see
@@ -17397,16 +20512,15 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
}
else
{
- *slot = mac_ptr;
+ *slot = (void *) new_mac_ptr;
- dwarf_decode_macro_bytes (abfd,
- section->buffer + offset,
- mac_end, current_file,
+ dwarf_decode_macro_bytes (include_bfd, new_mac_ptr,
+ include_mac_end, current_file,
lh, comp_dir,
- section, section_is_gnu,
+ section, section_is_gnu, is_dwz,
offset_size, objfile, include_hash);
- htab_remove_elt (include_hash, mac_ptr);
+ htab_remove_elt (include_hash, (void *) new_mac_ptr);
}
}
break;
@@ -17440,16 +20554,16 @@ dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
static void
dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
- char *comp_dir, int section_is_gnu)
+ const char *comp_dir, int section_is_gnu)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct line_header *lh = cu->line_header;
bfd *abfd;
- gdb_byte *mac_ptr, *mac_end;
+ const 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];
+ const gdb_byte *opcode_definitions[256];
struct cleanup *cleanup;
htab_t include_hash;
void **slot;
@@ -17489,7 +20603,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
complaint (&symfile_complaints, _("missing %s section"), section_name);
return;
}
- abfd = section->asection->owner;
+ abfd = get_section_bfd_owner (section);
/* First pass: Find the name of the base filename.
This filename is needed in order to process all macros whose definition
@@ -17570,6 +20684,8 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
case DW_MACRO_GNU_define_indirect:
case DW_MACRO_GNU_undef_indirect:
+ case DW_MACRO_GNU_define_indirect_alt:
+ case DW_MACRO_GNU_undef_indirect_alt:
{
unsigned int bytes_read;
@@ -17580,6 +20696,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
break;
case DW_MACRO_GNU_transparent_include:
+ case DW_MACRO_GNU_transparent_include_alt:
/* Note that, according to the spec, a transparent include
chain cannot call DW_MACRO_GNU_start_file. So, we can just
skip this opcode. */
@@ -17620,9 +20737,10 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
cleanup = make_cleanup_htab_delete (include_hash);
mac_ptr = section->buffer + offset;
slot = htab_find_slot (include_hash, mac_ptr, INSERT);
- *slot = mac_ptr;
+ *slot = (void *) mac_ptr;
dwarf_decode_macro_bytes (abfd, mac_ptr, mac_end,
- current_file, lh, comp_dir, section, section_is_gnu,
+ current_file, lh, comp_dir, section,
+ section_is_gnu, 0,
offset_size, objfile, include_hash);
do_cleanups (cleanup);
}
@@ -17631,7 +20749,7 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
if so return true else false. */
static int
-attr_form_is_block (struct attribute *attr)
+attr_form_is_block (const struct attribute *attr)
{
return (attr == NULL ? 0 :
attr->form == DW_FORM_block1
@@ -17651,7 +20769,7 @@ attr_form_is_block (struct attribute *attr)
of them. */
static int
-attr_form_is_section_offset (struct attribute *attr)
+attr_form_is_section_offset (const struct attribute *attr)
{
return (attr->form == DW_FORM_data4
|| attr->form == DW_FORM_data8
@@ -17672,7 +20790,7 @@ attr_form_is_section_offset (struct attribute *attr)
taken as section offsets, not constants. */
static int
-attr_form_is_constant (struct attribute *attr)
+attr_form_is_constant (const struct attribute *attr)
{
switch (attr->form)
{
@@ -17688,6 +20806,28 @@ attr_form_is_constant (struct attribute *attr)
}
}
+
+/* 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
+attr_form_is_ref (const struct attribute *attr)
+{
+ switch (attr->form)
+ {
+ case DW_FORM_ref_addr:
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_ref_alt:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
/* Return the .debug_loc section to use for CU.
For DWO files use .debug_loc.dwo. */
@@ -17704,7 +20844,7 @@ cu_debug_loc_section (struct dwarf2_cu *cu)
static void
fill_in_loclist_baton (struct dwarf2_cu *cu,
struct dwarf2_loclist_baton *baton,
- struct attribute *attr)
+ const struct attribute *attr)
{
struct dwarf2_section_info *section = cu_debug_loc_section (cu);
@@ -17721,8 +20861,8 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
}
static void
-dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
- struct dwarf2_cu *cu)
+dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
+ struct dwarf2_cu *cu, int is_block)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwarf2_section_info *section = cu_debug_loc_section (cu);
@@ -17745,7 +20885,9 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
_("Location list used without "
"specifying the CU base address."));
- SYMBOL_COMPUTED_OPS (sym) = &dwarf2_loclist_funcs;
+ SYMBOL_ACLASS_INDEX (sym) = (is_block
+ ? dwarf2_loclist_block_index
+ : dwarf2_loclist_index);
SYMBOL_LOCATION_BATON (sym) = baton;
}
else
@@ -17774,7 +20916,9 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
baton->size = 0;
}
- SYMBOL_COMPUTED_OPS (sym) = &dwarf2_locexpr_funcs;
+ SYMBOL_ACLASS_INDEX (sym) = (is_block
+ ? dwarf2_locexpr_block_index
+ : dwarf2_locexpr_index);
SYMBOL_LOCATION_BATON (sym) = baton;
}
}
@@ -17804,12 +20948,12 @@ static const struct comp_unit_head *
per_cu_header_read_in (struct comp_unit_head *cu_headerp,
struct dwarf2_per_cu_data *per_cu)
{
- gdb_byte *info_ptr;
+ const gdb_byte *info_ptr;
if (per_cu->cu)
return &per_cu->cu->header;
- info_ptr = per_cu->info_or_types_section->buffer + per_cu->offset.sect_off;
+ info_ptr = per_cu->section->buffer + per_cu->offset.sect_off;
memset (cu_headerp, 0, sizeof (*cu_headerp));
read_comp_unit_head (cu_headerp, info_ptr, per_cu->objfile->obfd);
@@ -17877,28 +21021,35 @@ dwarf2_per_cu_text_offset (struct dwarf2_per_cu_data *per_cu)
static struct dwarf2_per_cu_data *
dwarf2_find_containing_comp_unit (sect_offset offset,
+ unsigned int offset_in_dwz,
struct objfile *objfile)
{
struct dwarf2_per_cu_data *this_cu;
int low, high;
+ const sect_offset *cu_off;
low = 0;
high = dwarf2_per_objfile->n_comp_units - 1;
while (high > low)
{
+ struct dwarf2_per_cu_data *mid_cu;
int mid = low + (high - low) / 2;
- if (dwarf2_per_objfile->all_comp_units[mid]->offset.sect_off
- >= offset.sect_off)
+ mid_cu = dwarf2_per_objfile->all_comp_units[mid];
+ cu_off = &mid_cu->offset;
+ if (mid_cu->is_dwz > offset_in_dwz
+ || (mid_cu->is_dwz == offset_in_dwz
+ && cu_off->sect_off >= offset.sect_off))
high = mid;
else
low = mid + 1;
}
gdb_assert (low == high);
- if (dwarf2_per_objfile->all_comp_units[low]->offset.sect_off
- > offset.sect_off)
+ this_cu = dwarf2_per_objfile->all_comp_units[low];
+ cu_off = &this_cu->offset;
+ if (this_cu->is_dwz != offset_in_dwz || cu_off->sect_off > offset.sect_off)
{
- if (low == 0)
+ if (low == 0 || this_cu->is_dwz != offset_in_dwz)
error (_("Dwarf Error: could not find partial DIE containing "
"offset 0x%lx [in module %s]"),
(long) offset.sect_off, bfd_get_filename (objfile->obfd));
@@ -18104,11 +21255,13 @@ dwarf2_free_objfile (struct objfile *objfile)
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. */
+ or the type may come from a DWO file. Furthermore, while it's more logical
+ to use per_cu->section+offset, with Fission the section with the data is in
+ the DWO file but we don't know that section at the point we need it.
+ We have to use something in dwarf2_per_cu_data (or the pointer to it)
+ because we can enter the lookup routine, get_die_type_at_offset, from
+ outside this file, and thus won't necessarily have PER_CU->cu.
+ Fortunately, PER_CU is stable for the life of the objfile. */
struct dwarf2_per_cu_offset_and_type
{
@@ -18202,8 +21355,8 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
return type;
}
-/* 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. */
+/* Look up the type for the die at OFFSET in PER_CU in die_type_hash,
+ or return NULL if the die does not have a saved type. */
static struct type *
get_die_type_at_offset (sect_offset offset,
@@ -18223,7 +21376,7 @@ get_die_type_at_offset (sect_offset offset,
return NULL;
}
-/* Look up the type for DIE in the appropriate type_hash table,
+/* Look up the type for DIE in CU in die_type_hash,
or return NULL if DIE does not have a saved type. */
static struct type *
@@ -18340,62 +21493,35 @@ show_dwarf2_cmd (char *args, int from_tty)
cmd_show_list (show_dwarf2_cmdlist, from_tty, "");
}
-/* If section described by INFO was mmapped, munmap it now. */
-
-static void
-munmap_section_buffer (struct dwarf2_section_info *info)
-{
- if (info->map_addr != NULL)
- {
-#ifdef HAVE_MMAP
- int res;
-
- res = munmap (info->map_addr, info->map_len);
- gdb_assert (res == 0);
-#else
- /* Without HAVE_MMAP, we should never be here to begin with. */
- gdb_assert_not_reached ("no mmap support");
-#endif
- }
-}
-
-/* munmap debug sections for OBJFILE, if necessary. */
+/* Free data associated with OBJFILE, if necessary. */
static void
dwarf2_per_objfile_free (struct objfile *objfile, void *d)
{
struct dwarf2_per_objfile *data = d;
int ix;
- struct dwarf2_section_info *section;
- /* This is sorted according to the order they're defined in to make it easier
- to keep in sync. */
- munmap_section_buffer (&data->info);
- munmap_section_buffer (&data->abbrev);
- munmap_section_buffer (&data->line);
- munmap_section_buffer (&data->loc);
- munmap_section_buffer (&data->macinfo);
- munmap_section_buffer (&data->macro);
- munmap_section_buffer (&data->str);
- munmap_section_buffer (&data->ranges);
- munmap_section_buffer (&data->addr);
- munmap_section_buffer (&data->frame);
- munmap_section_buffer (&data->eh_frame);
- munmap_section_buffer (&data->gdb_index);
+ /* Make sure we don't accidentally use dwarf2_per_objfile while
+ cleaning up. */
+ dwarf2_per_objfile = NULL;
- for (ix = 0;
- VEC_iterate (dwarf2_section_info_def, data->types, ix, section);
- ++ix)
- munmap_section_buffer (section);
+ for (ix = 0; ix < data->n_comp_units; ++ix)
+ VEC_free (dwarf2_per_cu_ptr, data->all_comp_units[ix]->imported_symtabs);
- for (ix = 0; ix < dwarf2_per_objfile->n_comp_units; ++ix)
+ for (ix = 0; ix < data->n_type_units; ++ix)
VEC_free (dwarf2_per_cu_ptr,
- dwarf2_per_objfile->all_comp_units[ix]->s.imported_symtabs);
+ data->all_type_units[ix]->per_cu.imported_symtabs);
+ xfree (data->all_type_units);
VEC_free (dwarf2_section_info_def, data->types);
if (data->dwo_files)
free_dwo_files (data->dwo_files, objfile);
+ if (data->dwp_file)
+ gdb_bfd_unref (data->dwp_file->dbfd);
+
+ if (data->dwz_file && data->dwz_file->dwz_bfd)
+ gdb_bfd_unref (data->dwz_file->dwz_bfd);
}
@@ -18831,7 +21957,7 @@ add_address_entry (struct objfile *objfile, struct obstack *obstack,
CORE_ADDR start, CORE_ADDR end, unsigned int cu_index)
{
offset_type cu_index_to_write;
- char addr[8];
+ gdb_byte addr[8];
CORE_ADDR baseaddr;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
@@ -19015,8 +22141,7 @@ write_one_signatured_type (void **slot, void *d)
{
struct signatured_type_index_data *info = d;
struct signatured_type *entry = (struct signatured_type *) *slot;
- struct dwarf2_per_cu_data *per_cu = &entry->per_cu;
- struct partial_symtab *psymtab = per_cu->v.psymtab;
+ struct partial_symtab *psymtab = entry->per_cu.v.psymtab;
gdb_byte val[8];
write_psymbols (info->symtab,
@@ -19093,23 +22218,23 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
htab_t cu_index_htab;
struct psymtab_cu_index_map *psymtab_cu_index_map;
- if (!objfile->psymtabs || !objfile->psymtabs_addrmap)
- return;
-
if (dwarf2_per_objfile->using_index)
error (_("Cannot use an index to create the index"));
if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) > 1)
error (_("Cannot make an index when the file has multiple .debug_types sections"));
- if (stat (objfile->name, &st) < 0)
- perror_with_name (objfile->name);
+ if (!objfile->psymtabs || !objfile->psymtabs_addrmap)
+ return;
+
+ if (stat (objfile_name (objfile), &st) < 0)
+ perror_with_name (objfile_name (objfile));
- filename = concat (dir, SLASH_STRING, lbasename (objfile->name),
+ filename = concat (dir, SLASH_STRING, lbasename (objfile_name (objfile)),
INDEX_SUFFIX, (char *) NULL);
cleanup = make_cleanup (xfree, filename);
- out_file = fopen (filename, "wb");
+ out_file = gdb_fopen_cloexec (filename, "wb");
if (!out_file)
error (_("Can't open `%s' for writing"), filename);
@@ -19158,6 +22283,12 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
struct psymtab_cu_index_map *map;
void **slot;
+ /* CU of a shared file from 'dwz -m' may be unused by this main file.
+ It may be referenced from a local scope but in such case it does not
+ need to be present in .gdb_index. */
+ if (psymtab == NULL)
+ continue;
+
if (psymtab->user == NULL)
recursively_write_psymbols (objfile, psymtab, symtab, psyms_seen, i);
@@ -19209,7 +22340,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
total_len = size_of_contents;
/* The version number. */
- val = MAYBE_SWAP (7);
+ val = MAYBE_SWAP (8);
obstack_grow (&contents, &val, sizeof (val));
/* The offset of the CU list from the start of the file. */
@@ -19273,7 +22404,7 @@ save_gdb_index_command (char *arg, int from_tty)
struct stat st;
/* If the objfile does not correspond to an actual file, skip it. */
- if (stat (objfile->name, &st) < 0)
+ if (stat (objfile_name (objfile), &st) < 0)
continue;
dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
@@ -19288,7 +22419,7 @@ save_gdb_index_command (char *arg, int from_tty)
if (except.reason < 0)
exception_fprintf (gdb_stderr, except,
_("Error while writing index for `%s': "),
- objfile->name);
+ objfile_name (objfile));
}
}
}
@@ -19362,23 +22493,24 @@ conversational style, when possible."),
&set_dwarf2_cmdlist,
&show_dwarf2_cmdlist);
- add_setshow_boolean_cmd ("dwarf2-read", no_class, &dwarf2_read_debug, _("\
+ add_setshow_zuinteger_cmd ("dwarf2-read", no_class, &dwarf2_read_debug, _("\
Set debugging of the dwarf2 reader."), _("\
Show debugging of the dwarf2 reader."), _("\
-When enabled, debugging messages are printed during dwarf2 reading\n\
-and symtab expansion."),
+When enabled (non-zero), debugging messages are printed during dwarf2\n\
+reading and symtab expansion. A value of 1 (one) provides basic\n\
+information. A value greater than 1 provides more verbose information."),
NULL,
NULL,
&setdebuglist, &showdebuglist);
- add_setshow_zinteger_cmd ("dwarf2-die", no_class, &dwarf2_die_debug, _("\
+ add_setshow_zuinteger_cmd ("dwarf2-die", no_class, &dwarf2_die_debug, _("\
Set debugging of the dwarf2 DIE reader."), _("\
Show debugging of the dwarf2 DIE reader."), _("\
When enabled (non-zero), DIEs are dumped after they are read in.\n\
The value is the maximum depth to print."),
- NULL,
- NULL,
- &setdebuglist, &showdebuglist);
+ NULL,
+ NULL,
+ &setdebuglist, &showdebuglist);
add_setshow_boolean_cmd ("check-physname", no_class, &check_physname, _("\
Set cross-checking of \"physname\" code against demangler."), _("\
@@ -19406,4 +22538,14 @@ Save a gdb-index file.\n\
Usage: save gdb-index DIRECTORY"),
&save_cmdlist);
set_cmd_completer (c, filename_completer);
+
+ dwarf2_locexpr_index = register_symbol_computed_impl (LOC_COMPUTED,
+ &dwarf2_locexpr_funcs);
+ dwarf2_loclist_index = register_symbol_computed_impl (LOC_COMPUTED,
+ &dwarf2_loclist_funcs);
+
+ dwarf2_locexpr_block_index = register_symbol_block_impl (LOC_BLOCK,
+ &dwarf2_block_frame_base_locexpr_funcs);
+ dwarf2_loclist_block_index = register_symbol_block_impl (LOC_BLOCK,
+ &dwarf2_block_frame_base_loclist_funcs);
}
« no previous file with comments | « gdb/dwarf2loc.c ('k') | gdb/elfread.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698