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 (§ions, 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, §ions)) |
+ { |
+ error (_("Dwarf Error: bad DWP hash table, invalid section found" |
+ " [in module %s]"), |
+ dwp_file->name); |
+ } |
+ } |
+ |
+ if (i < 2 |
+ || dwarf2_section_empty_p (§ions.info_or_types) |
+ || dwarf2_section_empty_p (§ions.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 (§ions.abbrev), |
+ get_section_id (§ions.line), |
+ get_section_id (§ions.loc), |
+ get_section_id (§ions.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 (§ions, 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, §ions->str); |
- dwarf2_read_section (objfile, §ions->str_offsets); |
- if (sections->str.buffer == NULL) |
- error (_("DW_FORM_str_index used without .debug_str.dwo section" |
+ 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); |
} |