summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaroline Tice <cmtice@google.com>2020-09-15 14:27:09 -0700
committerCaroline Tice <cmtice@google.com>2020-09-16 11:03:11 -0700
commit234e271db36e2a8be022f7a4bbabfa1623a6ae9a (patch)
tree17f674b4cb887856523e4c611da37358b2e01381
parent64aeaaf059770dea70e5fe6dc4ef17b7c7e2118a (diff)
downloadgdb-234e271db36e2a8be022f7a4bbabfa1623a6ae9a.tar.gz
Minimum updates to add proper handling for DWARF v5. Test: built gdb, ran gdb on 4 variants of test program: dwarf4 with dwo files; dwarf4 with .dwp file; dwarf5 with dwo files; dwarf5 with dwp file. Change-Id: Ibf752386adb14b7bf4e60d8ec79851f29bf17e11
-rw-r--r--gdb-9.2/gdb/dwarf2read.c1478
-rw-r--r--gdb-9.2/gdb/dwarf2read.h1
-rw-r--r--gdb-9.2/gdb/gdbtypes.h26
-rw-r--r--gdb-9.2/gdb/symfile.h1
-rw-r--r--gdb-9.2/include/dwarf2.h43
5 files changed, 1250 insertions, 299 deletions
diff --git a/gdb-9.2/gdb/dwarf2read.c b/gdb-9.2/gdb/dwarf2read.c
index cc5bb00c5..b6f9976e5 100644
--- a/gdb-9.2/gdb/dwarf2read.c
+++ b/gdb-9.2/gdb/dwarf2read.c
@@ -104,6 +104,12 @@ static int dwarf2_loclist_index;
static int dwarf2_locexpr_block_index;
static int dwarf2_loclist_block_index;
+/* Size of .debug_loclist section header for 32-bit DWARF format. */
+#define LOCLIST_HEADER_SIZE32 12;
+
+/* Size of .debug_loclist section header for 64-bit DWARF format. */
+#define LOCLIST_HEADER_SIZE64 20;
+
/* An index into a (C++) symbol name component in a symbol name as
recorded in the mapped_index's symbol table. For each C++ symbol
in the symbol table, we record one entry for the start of each
@@ -287,6 +293,7 @@ static const struct dwarf2_debug_sections dwarf2_elf_names =
{ ".debug_macinfo", ".zdebug_macinfo" },
{ ".debug_macro", ".zdebug_macro" },
{ ".debug_str", ".zdebug_str" },
+ { ".debug_str_offsets", ".zdebug_str_offsets" },
{ ".debug_line_str", ".zdebug_line_str" },
{ ".debug_ranges", ".zdebug_ranges" },
{ ".debug_rnglists", ".zdebug_rnglists" },
@@ -311,6 +318,7 @@ static const struct dwop_section_names
struct dwarf2_section_names loclists_dwo;
struct dwarf2_section_names macinfo_dwo;
struct dwarf2_section_names macro_dwo;
+ struct dwarf2_section_names rnglists_dwo;
struct dwarf2_section_names str_dwo;
struct dwarf2_section_names str_offsets_dwo;
struct dwarf2_section_names types_dwo;
@@ -326,6 +334,7 @@ dwop_section_names =
{ ".debug_loclists.dwo", ".zdebug_loclists.dwo" },
{ ".debug_macinfo.dwo", ".zdebug_macinfo.dwo" },
{ ".debug_macro.dwo", ".zdebug_macro.dwo" },
+ { ".debug_rnglists.dwo", ".zdebug_rnglists.dwo" },
{ ".debug_str.dwo", ".zdebug_str.dwo" },
{ ".debug_str_offsets.dwo", ".zdebug_str_offsets.dwo" },
{ ".debug_types.dwo", ".zdebug_types.dwo" },
@@ -392,6 +401,30 @@ struct delayed_method_info
struct die_info *die;
};
+/* The location list and range list section (.debug_loclist) begins with a
+ header, which contains the following information. */
+struct loclist_header
+{
+ /* A 4-byte or 12-byte length containing the length of the
+ set of entries for this compilation unit, not including the
+ length field itself. */
+ unsigned int length;
+
+ /* A 2-byte version identifier. */
+ short version;
+
+ /* A 1-byte unsigned integer containing the size in bytes of an address on
+ the target system. */
+ unsigned char addr_size;
+
+/* A 1-byte unsigned integer containing the size in bytes of a segment selector
+ on the target system. */
+ unsigned char segment_collector_size;
+
+ /* A 4-byte count of the number of offsets that follow the header. */
+ unsigned int offset_entry_count;
+};
+
/* Internal state when decoding a particular compilation unit. */
struct dwarf2_cu
{
@@ -425,6 +458,9 @@ struct dwarf2_cu
/* Non-zero if base_address has been set. */
int base_known = 0;
+ /* CU rnglist ranges came from skeleton unit. */
+ int cu_ranges_from_skeleton = 0;
+
/* The language we are debugging. */
enum language language = language_unknown;
const struct language_defn *language_defn = nullptr;
@@ -500,30 +536,31 @@ public:
There is an invariant here that is important to remember:
Except for attributes copied from the top level DIE in the "main"
(or "stub") file in preparation for reading the DWO file
- (e.g., DW_AT_GNU_addr_base), we KISS: there is only *one* CU.
+ (e.g., DW_AT_addr_base), we KISS: there is only *one* CU.
Either there isn't a DWO file (in which case this is NULL and the point
is moot), or there is and either we're not going to read it (in which
case this is NULL) or there is and we are reading it (in which case this
is non-NULL). */
struct dwo_unit *dwo_unit = nullptr;
- /* The DW_AT_addr_base attribute if present, zero otherwise
- (zero is a valid value though).
+ /* The DW_AT_addr_base (DW_AT_GNU_addr_base) attribute if present.
Note this value comes from the Fission stub CU/TU's DIE. */
- ULONGEST addr_base = 0;
+ gdb::optional<ULONGEST> addr_base;
- /* The DW_AT_ranges_base attribute if present, zero otherwise
- (zero is a valid value though).
+ /* The DW_AT_rnglists_base attribute if present.
Note this value comes from the Fission stub CU/TU's DIE.
Also note that the value is zero in the non-DWO case so this value can
be used without needing to know whether DWO files are in use or not.
N.B. This does not apply to DW_AT_ranges appearing in
DW_TAG_compile_unit dies. This is a bit of a wart, consider if ever
DW_AT_ranges appeared in the DW_TAG_compile_unit of DWO DIEs: then
- DW_AT_ranges_base *would* have to be applied, and we'd have to care
+ DW_AT_rnglists_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 = 0;
+ /* The DW_AT_loclistss_base attribute if present. */
+ gdb::optional<ULONGEST> loclist_base;
+
/* When reading debug info generated by older versions of rustc, we
have to rewrite some union types to be struct types with a
variant part. This rewriting must be done after the CU is fully
@@ -532,6 +569,12 @@ public:
all such types here and process them after expansion. */
std::vector<struct type *> rust_unions;
+ /* The DW_AT_str_offsets_base attribute if present. For DWARF 4 version DWO
+ files, the value is implicitly zero. For DWARF 5 version DWO files, the
+ value is often implicit and is the size of the header of
+ .debug_str_offsets section (8 or 4, depending on the address size). */
+ gdb::optional<ULONGEST> str_offsets_base;
+
/* Mark used when releasing cached dies. */
bool mark : 1;
@@ -642,6 +685,7 @@ struct dwo_sections
struct dwarf2_section_info loclists;
struct dwarf2_section_info macinfo;
struct dwarf2_section_info macro;
+ struct dwarf2_section_info rnglists;
struct dwarf2_section_info str;
struct dwarf2_section_info str_offsets;
/* In the case of a virtual DWO file, these two are unused. */
@@ -697,7 +741,7 @@ struct dwo_file
dwo_file () = default;
DISABLE_COPY_AND_ASSIGN (dwo_file);
- /* The DW_AT_GNU_dwo_name attribute.
+ /* The DW_AT_GNU_dwo_name or DW_AT_dwo_name 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. */
@@ -711,7 +755,7 @@ struct dwo_file
gdb_bfd_ref_ptr dbfd;
/* The sections that make up this DWO file.
- Remember that for virtual DWO files in DWP V2, these are virtual
+ Remember that for virtual DWO files in DWP V2 or DWP V5, these are virtual
sections (for lack of a better name). */
struct dwo_sections sections {};
@@ -730,12 +774,12 @@ struct dwo_file
struct dwp_sections
{
- /* These are used by both DWP version 1 and 2. */
+ /* These are used by DWP versions 1, 2 and 5. */
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.
+ /* These are only used by DWP version 2 and version 5 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
@@ -747,8 +791,10 @@ struct dwp_sections
struct dwarf2_section_info info;
struct dwarf2_section_info line;
struct dwarf2_section_info loc;
+ struct dwarf2_section_info loclists;
struct dwarf2_section_info macinfo;
struct dwarf2_section_info macro;
+ struct dwarf2_section_info rnglists;
struct dwarf2_section_info str_offsets;
struct dwarf2_section_info types;
};
@@ -769,7 +815,7 @@ struct virtual_v1_dwo_sections
struct dwarf2_section_info info_or_types;
};
-/* Similar to virtual_v1_dwo_sections, but for DWP version 2.
+/* Similar to virtual_v1_dwo_sections, but for DWP version 2 or 5.
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. */
@@ -785,12 +831,18 @@ struct virtual_v2_dwo_sections
bfd_size_type loc_offset;
bfd_size_type loc_size;
+ bfd_size_type loclists_offset;
+ bfd_size_type loclists_size;
+
bfd_size_type macinfo_offset;
bfd_size_type macinfo_size;
bfd_size_type macro_offset;
bfd_size_type macro_size;
+ bfd_size_type rnglists_offset;
+ bfd_size_type rnglists_size;
+
bfd_size_type str_offsets_offset;
bfd_size_type str_offsets_size;
@@ -828,6 +880,20 @@ struct dwp_hash_table
const gdb_byte *offsets;
const gdb_byte *sizes;
} v2;
+ struct
+ {
+#define MAX_NR_V5_DWO_SECTIONS \
+ (1 /* .debug_info or .debug_types */ \
+ + 1 /* .debug_abbrev */ \
+ + 1 /* .debug_line */ \
+ + 1 /* .debug_loclists */ \
+ + 1 /* .debug_str_offsets */ \
+ + 1 /* .debug_macro */ \
+ + 1 /* .debug_rnglists */)
+ int section_ids[MAX_NR_V5_DWO_SECTIONS];
+ const gdb_byte *offsets;
+ const gdb_byte *sizes;
+ } v5;
} section_pool;
};
@@ -1519,7 +1585,12 @@ static const struct cu_partial_die_info find_partial_die (sect_offset, int,
static const gdb_byte *read_attribute (const struct die_reader_specs *,
struct attribute *, struct attr_abbrev *,
- const gdb_byte *);
+ const gdb_byte *, bool *need_reprocess);
+
+static void read_attribute_reprocess (const struct die_reader_specs *reader,
+ struct attribute *attr);
+
+static CORE_ADDR read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index);
static unsigned int read_1_byte (bfd *, const gdb_byte *);
@@ -1578,8 +1649,11 @@ static CORE_ADDR read_addr_index_from_leb128 (struct dwarf2_cu *,
const gdb_byte *,
unsigned int *);
-static const char *read_str_index (const struct die_reader_specs *reader,
- ULONGEST str_index);
+static const char *read_dwo_str_index (const struct die_reader_specs *reader,
+ ULONGEST str_index);
+
+static const char *read_stub_str_index (struct dwarf2_cu *cu,
+ ULONGEST str_index);
static void set_cu_language (unsigned int, struct dwarf2_cu *);
@@ -1665,7 +1739,19 @@ static void read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu);
static void read_variable (struct die_info *die, struct dwarf2_cu *cu);
static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
- struct dwarf2_cu *, struct partial_symtab *);
+ struct dwarf2_cu *, struct partial_symtab *,
+ dwarf_tag tag);
+
+static struct dwarf2_section_info *cu_debug_loc_section (struct dwarf2_cu *cu);
+static struct dwarf2_section_info
+*cu_debug_rnglist_section (struct dwarf2_cu *cu);
+
+static CORE_ADDR read_loclist_index (struct dwarf2_cu *cu,
+ ULONGEST loclist_index);
+static ULONGEST lookup_loclist_base (struct dwarf2_cu *cu);
+static struct loclist_header read_loclist_header (struct dwarf2_cu *cu,
+ bfd *abfd,
+ const gdb_byte *info_ptr);
/* How dwarf2_get_pc_bounds constructed its *LOWPC and *HIGHPC return
values. Keep the items ordered with increasing constraints compliance. */
@@ -2412,6 +2498,11 @@ dwarf2_per_objfile::locate_sections (bfd *abfd, asection *sectp,
this->str.s.section = sectp;
this->str.size = bfd_section_size (sectp);
}
+ else if (section_is_p (sectp->name, &names.str_offsets))
+ {
+ this->str_offsets.s.section = sectp;
+ this->str_offsets.size = bfd_section_size (sectp);
+ }
else if (section_is_p (sectp->name, &names.line_str))
{
this->line_str.s.section = sectp;
@@ -3728,8 +3819,14 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
XOBNEWVEC (&objfile->objfile_obstack, const char *, qfn->num_file_names);
if (offset != 0)
qfn->file_names[0] = xstrdup (fnd.name);
- for (int i = 0; i < lh->file_names_size (); ++i)
- qfn->file_names[i + offset] = file_full_name (i + 1, lh.get (), fnd.comp_dir);
+ if (lh->version >= 5) {
+ for (int i = 0; i < lh->file_names_size (); ++i)
+ qfn->file_names[i + offset] = file_full_name (i, lh.get (), fnd.comp_dir);
+ } else {
+ for (int i = 0; i < lh->file_names_size (); ++i)
+ qfn->file_names[i + offset] = file_full_name (i + 1, lh.get (),
+ fnd.comp_dir);
+ }
qfn->real_names = NULL;
lh_cu->v.quick->file_names = qfn;
@@ -6488,11 +6585,6 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
case DW_UT_partial:
case DW_UT_skeleton:
case DW_UT_split_compile:
- if (section_kind != rcuh_kind::COMPILE)
- error (_("Dwarf Error: wrong unit_type in compilation unit header "
- "(is %s, should be %s) [in module %s]"),
- dwarf_unit_type_name (cu_header->unit_type),
- dwarf_unit_type_name (DW_UT_type), filename);
break;
case DW_UT_type:
case DW_UT_split_type:
@@ -6819,7 +6911,8 @@ create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
/* Skip dummy type units. */
if (ptr >= info_ptr + length
|| peek_abbrev_code (abfd, ptr) == 0
- || header.unit_type != DW_UT_type)
+ || (header.unit_type != DW_UT_type
+ && header.unit_type != DW_UT_split_type))
{
info_ptr += length;
continue;
@@ -7114,6 +7207,7 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
struct dwo_unit *dwo_entry;
struct signatured_type find_sig_entry, *sig_entry;
void **slot;
+ unsigned int is_debug_types = 1;
gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index);
gdb_assert (dwp_file != NULL);
@@ -7139,8 +7233,9 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
if (dwp_file->tus == NULL)
return NULL;
+
dwo_entry = lookup_dwo_unit_in_dwp (dwarf2_per_objfile, dwp_file, NULL,
- sig, 1 /* is_debug_types */);
+ sig, is_debug_types);
if (dwo_entry == NULL)
return NULL;
@@ -7182,7 +7277,62 @@ lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
return entry;
}
}
-
+
+/* Return the address base of the compile unit, which, if exists, is stored
+ either at the attribute DW_AT_GNU_addr_base, or DW_AT_addr_base. */
+static gdb::optional<ULONGEST>
+lookup_addr_base (struct die_info *comp_unit_die)
+{
+ struct attribute *attr;
+ attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_addr_base);
+ if (attr == nullptr)
+ attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_GNU_addr_base);
+ if (attr == nullptr)
+ return gdb::optional<ULONGEST> ();
+ return DW_UNSND (attr);
+}
+
+/* Return range lists base of the compile unit, which, if exists, is stored
+ either at the attribute DW_AT_rnglists_base or DW_AT_GNU_ranges_base. */
+static gdb::optional<ULONGEST>
+lookup_ranges_base (struct die_info *comp_unit_die)
+{
+ struct attribute *attr;
+ attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_rnglists_base);
+ if (attr == nullptr)
+ attr = dwarf2_attr_no_follow (comp_unit_die, DW_AT_GNU_ranges_base);
+ if (attr == nullptr)
+ return gdb::optional<ULONGEST> ();
+ return DW_UNSND (attr);
+}
+
+/* Calculate the offset into the .debug_rnglists or .debug_ranges section to
+ read the range for an DW_AT_ranges attribute. For DW_FORM_rnglistx
+ introduced in DWARF 5, the ranges base attribute (DW_AT_rnglists_base or
+ DW_AT_GNU_ranges_base) have already been taken into account. For other forms,
+ the range base should be added to the form value. DW_TAG_compile_unit does
+ not need ranges base, per existing comments. */
+static ULONGEST
+calculate_ranges_offset(struct dwarf2_cu &cu, struct attribute &attr,
+ dwarf_tag tag)
+{
+ if (attr.name != DW_AT_ranges)
+ error(_("Internal error, wrong attribute sent to "
+ "calculate_ranges_offset"));
+ bool need_ranges_base = true;
+ /* DW_AT_rnglists_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. */
+ if (tag == DW_TAG_compile_unit)
+ need_ranges_base = false;
+ if (attr.form == DW_FORM_rnglistx)
+ need_ranges_base = false;
+ ULONGEST result = DW_UNSND (&attr);
+ if (need_ranges_base)
+ result += cu.ranges_base;
+ return result;
+}
+
/* Low level DIE reading support. */
/* Initialize a die_reader_specs struct from a dwarf2_cu struct. */
@@ -7243,7 +7393,6 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
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 die_info *comp_unit_die;
/* At most one of these may be provided. */
@@ -7274,20 +7423,14 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_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
- or DW_FORM_addrx. */
- cu->addr_base = 0;
- attr = dwarf2_attr (stub_comp_unit_die, DW_AT_GNU_addr_base, cu);
- if (attr != nullptr)
- cu->addr_base = DW_UNSND (attr);
+ cu->addr_base = lookup_addr_base (stub_comp_unit_die);
- /* 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 != nullptr)
- cu->ranges_base = DW_UNSND (attr);
+ /* There should be a DW_AT_rnglists_base (DW_AT_GNU_ranges_base) attribute
+ here (if needed). We need the value before we can process
+ DW_AT_ranges. */
+ auto maybe_ranges_base = lookup_ranges_base (stub_comp_unit_die);
+ if (maybe_ranges_base.has_value ())
+ cu->ranges_base = *maybe_ranges_base;
}
else if (stub_comp_dir != NULL)
{
@@ -7732,6 +7875,10 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
/* Dummy die. */
return;
}
+ if (dwarf2_attr_no_follow (comp_unit_die, DW_AT_ranges))
+ {
+ this_cu->cu->cu_ranges_from_skeleton = 1;
+ }
comp_unit_die = dwo_comp_unit_die;
}
else
@@ -7758,9 +7905,9 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
}
}
-/* Read CU/TU THIS_CU 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).
+/* Read CU/TU THIS_CU but do not follow DW_AT_GNU_dwo_name (DW_AT_dwo_name)
+ if present. DWO_FILE, if non-NULL, is the DWO file to read (the caller is
+ assumed to have already done the lookup to find the DWO file).
The caller is required to fill in THIS_CU->section, THIS_CU->offset, and
THIS_CU->is_debug_types, but nothing else.
@@ -7772,10 +7919,14 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
THIS_CU->cu is always freed when done.
This is done in order to not leave THIS_CU->cu in a state where we have
- to care whether it refers to the "main" CU or the DWO CU. */
+ to care whether it refers to the "main" CU or the DWO CU.
+
+ When parent_cu is passed, it is used to provide a default value for
+ str_offsets_base and addr_base from the parent. */
static void
init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
+ struct dwarf2_cu *parent_cu,
struct dwo_file *dwo_file,
die_reader_func_ftype *die_reader_func,
void *data)
@@ -7814,6 +7965,12 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
? rcuh_kind::TYPE
: rcuh_kind::COMPILE));
+ if (parent_cu != nullptr)
+ {
+ cu.str_offsets_base = parent_cu->str_offsets_base;
+ cu.addr_base = parent_cu->addr_base;
+ cu.ranges_base = parent_cu->ranges_base;
+ }
this_cu->length = get_cu_length (&cu.header);
/* Skip dummy compilation units. */
@@ -7831,8 +7988,8 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu,
die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data);
}
-/* Read a CU/TU, except that this does not look for DW_AT_GNU_dwo_name and
- does not lookup the specified DWO file.
+/* Read a CU/TU, except that this does not look for DW_AT_GNU_dwo_name
+ (DW_AT_dwo_name) and does not lookup the specified DWO file.
This cannot be used to read DWO files.
THIS_CU->cu is always freed when done.
@@ -7845,7 +8002,7 @@ init_cutu_and_read_dies_simple (struct dwarf2_per_cu_data *this_cu,
die_reader_func_ftype *die_reader_func,
void *data)
{
- init_cutu_and_read_dies_no_follow (this_cu, NULL, die_reader_func, data);
+ init_cutu_and_read_dies_no_follow (this_cu, NULL, NULL, die_reader_func, data);
}
/* Type Unit Groups.
@@ -8077,7 +8234,8 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
/* This must be done before calling dwarf2_build_include_psymtabs. */
pst->dirname = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
- baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ baseaddr = ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
dwarf2_find_base_address (comp_unit_die, cu);
@@ -9356,7 +9514,9 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
/* The only abbrev we care about is DW_AT_sibling. */
if (abbrev->attrs[i].name == DW_AT_sibling)
{
- read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
+ bool ignored;
+ read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr,
+ &ignored);
if (attr.form == DW_FORM_ref_addr)
complaint (_("ignoring absolute DW_AT_sibling"));
else
@@ -9452,6 +9612,8 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
case DW_FORM_ref_udata:
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
+ case DW_FORM_loclistx:
+ case DW_FORM_rnglistx:
info_ptr = safe_skip_leb128 (info_ptr, buffer_end);
break;
case DW_FORM_indirect:
@@ -10662,6 +10824,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
break;
case DW_TAG_compile_unit:
case DW_TAG_partial_unit:
+ case DW_TAG_skeleton_unit:
read_file_scope (die, cu);
break;
case DW_TAG_type_unit:
@@ -11996,8 +12159,8 @@ create_dwo_cu_reader (const struct die_reader_specs *reader,
static void
create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
- struct dwo_file &dwo_file, dwarf2_section_info &section,
- htab_t &cus_htab)
+ dwarf2_cu *cu, struct dwo_file &dwo_file,
+ dwarf2_section_info &section, htab_t &cus_htab)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
const gdb_byte *info_ptr, *end_ptr;
@@ -12034,7 +12197,7 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
create_dwo_cu_data.dwo_file = &dwo_file;
init_cutu_and_read_dies_no_follow (
- &per_cu, &dwo_file, create_dwo_cu_reader, &create_dwo_cu_data);
+ &per_cu, cu, &dwo_file, create_dwo_cu_reader, &create_dwo_cu_data);
info_ptr += per_cu.length;
// If the unit could not be parsed, skip it.
@@ -12108,9 +12271,9 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
---
- DWP Version 2:
+ DWP Versions 2 and 5:
- DWP Version 2 combines all the .debug_info, etc. sections into one,
+ DWP Versions 2 and 5 combine 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.
@@ -12119,8 +12282,8 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
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
+ Table of Section Offsets dwp_hash_table.v2|v5.{section_ids,offsets}
+ Table of Section Sizes dwp_hash_table.v2|v5.sizes
The index section header consists of:
@@ -12143,7 +12306,7 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
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:
+ refer to that section. The section identifiers for Version 2 are:
DW_SECT_INFO 1 .debug_info.dwo
DW_SECT_TYPES 2 .debug_types.dwo
@@ -12154,6 +12317,17 @@ create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
DW_SECT_MACINFO 7 .debug_macinfo.dwo
DW_SECT_MACRO 8 .debug_macro.dwo
+ The section identifiers for Version 5 are:
+
+ DW_SECT_INFO_V5 1 .debug_info.dwo
+ DW_SECT_RESERVED_V5 2 --
+ DW_SECT_ABBREV_V5 3 .debug_abbrev.dwo
+ DW_SECT_LINE_V5 4 .debug_line.dwo
+ DW_SECT_LOCLISTS_V5 5 .debug_loclists.dwo
+ DW_SECT_STR_OFFSETS_V5 6 .debug_str_offsets.dwo
+ DW_SECT_MACRO_V5 7 .debug_macro.dwo
+ DW_SECT_RNGLISTS_V5 8 .debug_rnglists.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
@@ -12222,10 +12396,14 @@ create_dwp_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
index_ptr = index->buffer;
index_end = index_ptr + index->size;
+ /* For Version 5, the version is really 2 bytes of data & 2 bytes of
+ padding. For now it's safe to just read 4 bytes (particularly as it's
+ difficult to tell if you're dealing with Version 5 before you've read the
+ version). */
version = read_4_bytes (dbfd, index_ptr);
index_ptr += 4;
- if (version == 2)
- nr_columns = read_4_bytes (dbfd, index_ptr);
+ if ((version == 2) || (version == 5))
+ nr_columns = read_4_bytes (dbfd, index_ptr);
else
nr_columns = 0;
index_ptr += 4;
@@ -12234,7 +12412,7 @@ create_dwp_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
nr_slots = read_4_bytes (dbfd, index_ptr);
index_ptr += 4;
- if (version != 1 && version != 2)
+ if (version != 1 && version != 2 && version != 5)
{
error (_("Dwarf Error: unsupported DWP file version (%s)"
" [in module %s]"),
@@ -12257,11 +12435,13 @@ create_dwp_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
/* Exit early if the table is empty. */
if (nr_slots == 0 || nr_units == 0
- || (version == 2 && nr_columns == 0))
+ || (version == 2 && nr_columns == 0)
+ || (version == 5 && nr_columns == 0))
{
/* All must be zero. */
if (nr_slots != 0 || nr_units != 0
- || (version == 2 && nr_columns != 0))
+ || (version == 2 && nr_columns != 0)
+ || (version == 5 && nr_columns != 0))
{
complaint (_("Empty DWP but nr_slots,nr_units,nr_columns not"
" all zero [in modules %s]"),
@@ -12277,7 +12457,7 @@ create_dwp_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
/* It's harder to decide whether the section is too small in v1.
V1 is deprecated anyway so we punt. */
}
- else
+ else if (version == 2)
{
const gdb_byte *ids_ptr = htab->unit_table + sizeof (uint32_t) * nr_slots;
int *ids = htab->section_pool.v2.section_ids;
@@ -12348,6 +12528,76 @@ create_dwp_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
dwp_file->name);
}
}
+ else // version == 5
+ {
+ const gdb_byte *ids_ptr = htab->unit_table + sizeof (uint32_t) * nr_slots;
+
+ int *ids = htab->section_pool.v5.section_ids;
+ size_t sizeof_ids = sizeof (htab->section_pool.v5.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_V5_DWO_SECTIONS)
+ {
+ error (_("Dwarf Error: bad DWP hash table, too many columns"
+ " in section table [in module %s]"),
+ dwp_file->name);
+ }
+ memset (ids, 255, sizeof_ids);
+ memset (ids_seen, 255, sizeof (ids_seen));
+ 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_V5)
+ {
+ 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 an info section. */
+ if (ids_seen[DW_SECT_INFO_V5] == -1)
+ {
+ error (_("Dwarf Error: bad DWP hash table, missing/duplicate"
+ " DWO info section [in module %s]"),
+ dwp_file->name);
+ }
+ /* Must have an abbrev section. */
+ if (ids_seen[DW_SECT_ABBREV_V5] == -1)
+ {
+ error (_("Dwarf Error: bad DWP hash table, missing DWO abbrev"
+ " section [in module %s]"),
+ dwp_file->name);
+ }
+ htab->section_pool.v5.offsets = ids_ptr + sizeof (uint32_t) * nr_columns;
+ htab->section_pool.v5.sizes =
+ htab->section_pool.v5.offsets + (sizeof (uint32_t)
+ * nr_units * nr_columns);
+ if ((htab->section_pool.v5.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;
}
@@ -12596,9 +12846,9 @@ create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
of just that piece. */
static struct dwarf2_section_info
-create_dwp_v2_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
- struct dwarf2_section_info *section,
- bfd_size_type offset, bfd_size_type size)
+create_dwp_v2_or_v5_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ struct dwarf2_section_info *section,
+ bfd_size_type offset, bfd_size_type size)
{
struct dwarf2_section_info result;
asection *sectp;
@@ -12621,7 +12871,7 @@ create_dwp_v2_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
if (sectp == NULL
|| offset + size > bfd_section_size (sectp))
{
- error (_("Dwarf Error: Bad DWP V2 section info, doesn't fit"
+ error (_("Dwarf Error: Bad DWP V2 or V5 section info, doesn't fit"
" in section %s [in module %s]"),
sectp ? bfd_section_name (sectp) : "<unknown>",
objfile_name (dwarf2_per_objfile->objfile));
@@ -12749,43 +12999,52 @@ create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
virtual_dwo_name);
dwo_file->comp_dir = comp_dir;
dwo_file->sections.abbrev =
- create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.abbrev,
- sections.abbrev_offset, sections.abbrev_size);
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &dwp_file->sections.abbrev,
+ sections.abbrev_offset,
+ sections.abbrev_size);
dwo_file->sections.line =
- create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.line,
- sections.line_offset, sections.line_size);
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &dwp_file->sections.line,
+ sections.line_offset,
+ sections.line_size);
dwo_file->sections.loc =
- create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.loc,
- sections.loc_offset, sections.loc_size);
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &dwp_file->sections.loc,
+ sections.loc_offset, sections.loc_size);
dwo_file->sections.macinfo =
- create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.macinfo,
- sections.macinfo_offset, sections.macinfo_size);
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &dwp_file->sections.macinfo,
+ sections.macinfo_offset,
+ sections.macinfo_size);
dwo_file->sections.macro =
- create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.macro,
- sections.macro_offset, sections.macro_size);
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &dwp_file->sections.macro,
+ sections.macro_offset,
+ sections.macro_size);
dwo_file->sections.str_offsets =
- create_dwp_v2_section (dwarf2_per_objfile,
- &dwp_file->sections.str_offsets,
- sections.str_offsets_offset,
- sections.str_offsets_size);
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &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. */
+ 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 (dwarf_read_debug)
- {
- fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
- virtual_dwo_name.c_str ());
- }
+ {
+ fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
+ virtual_dwo_name.c_str ());
+ }
dwo_file = (struct dwo_file *) *dwo_file_slot;
}
@@ -12794,12 +13053,198 @@ create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
dwo_unit->signature = signature;
dwo_unit->section =
XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
- *dwo_unit->section = create_dwp_v2_section (dwarf2_per_objfile,
- is_debug_types
- ? &dwp_file->sections.types
- : &dwp_file->sections.info,
- sections.info_or_types_offset,
- sections.info_or_types_size);
+ *dwo_unit->section = create_dwp_v2_or_v5_section
+ (dwarf2_per_objfile,
+ 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;
+}
+
+/* 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 5 files. */
+
+static struct dwo_unit *
+create_dwo_unit_in_dwp_v5 (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ 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.get ();
+ 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;
+ int i;
+
+ gdb_assert (dwp_file->version == 5);
+
+ if (dwarf_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Reading %s %s/%s in DWP V5 file: %s\n",
+ kind,
+ pulongest (unit_index), hex_string (signature),
+ dwp_file->name);
+ }
+
+ /* Fetch the section offsets of this DWO unit. */
+
+ memset (&sections, 0, sizeof (sections));
+
+ for (i = 0; i < dwp_htab->nr_columns; ++i)
+ {
+ uint32_t offset = read_4_bytes (dbfd,
+ dwp_htab->section_pool.v5.offsets
+ + (((unit_index - 1)
+ * dwp_htab->nr_columns
+ + i)
+ * sizeof (uint32_t)));
+ uint32_t size = read_4_bytes (dbfd,
+ dwp_htab->section_pool.v5.sizes
+ + (((unit_index - 1) * dwp_htab->nr_columns
+ + i)
+ * sizeof (uint32_t)));
+
+ switch (dwp_htab->section_pool.v5.section_ids[i])
+ {
+ case DW_SECT_ABBREV_V5:
+ sections.abbrev_offset = offset;
+ sections.abbrev_size = size;
+ break;
+ case DW_SECT_INFO_V5:
+ sections.info_or_types_offset = offset;
+ sections.info_or_types_size = size;
+ break;
+ case DW_SECT_LINE_V5:
+ sections.line_offset = offset;
+ sections.line_size = size;
+ break;
+ case DW_SECT_LOCLISTS_V5:
+ sections.loclists_offset = offset;
+ sections.loclists_size = size;
+ break;
+ case DW_SECT_MACRO_V5:
+ sections.macro_offset = offset;
+ sections.macro_size = size;
+ break;
+ case DW_SECT_RNGLISTS_V5:
+ sections.rnglists_offset = offset;
+ sections.rnglists_size = size;
+ break;
+ case DW_SECT_STR_OFFSETS_V5:
+ sections.str_offsets_offset = offset;
+ sections.str_offsets_size = size;
+ break;
+ case DW_SECT_RESERVED_V5:
+ default:
+ 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. */
+
+ std::string virtual_dwo_name =
+ string_printf ("virtual-dwo/%ld-%ld-%ld-%ld-%ld-%ld",
+ (long) (sections.abbrev_size ? sections.abbrev_offset : 0),
+ (long) (sections.line_size ? sections.line_offset : 0),
+ (long) (sections.loclists_size ? sections.loclists_offset : 0),
+ (long) (sections.str_offsets_size
+ ? sections.str_offsets_offset : 0),
+ (long) (sections.macro_size ? sections.macro_offset : 0),
+ (long) (sections.rnglists_size ? sections.rnglists_offset: 0));
+ /* Can we use an existing virtual DWO file? */
+ dwo_file_slot = lookup_dwo_file_slot (dwarf2_per_objfile,
+ virtual_dwo_name.c_str (),
+ comp_dir);
+ /* Create one if necessary. */
+ if (*dwo_file_slot == NULL)
+ {
+ if (dwarf_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
+ virtual_dwo_name.c_str ());
+ }
+ dwo_file = new struct dwo_file;
+ dwo_file->dwo_name = obstack_strdup (&objfile->objfile_obstack,
+ virtual_dwo_name);
+ dwo_file->comp_dir = comp_dir;
+ dwo_file->sections.abbrev =
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &dwp_file->sections.abbrev,
+ sections.abbrev_offset,
+ sections.abbrev_size);
+ dwo_file->sections.line =
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &dwp_file->sections.line,
+ sections.line_offset, sections.line_size);
+ dwo_file->sections.macro =
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &dwp_file->sections.macro,
+ sections.macro_offset,
+ sections.macro_size);
+ dwo_file->sections.loclists =
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &dwp_file->sections.loclists,
+ sections.loclists_offset,
+ sections.loclists_size);
+ dwo_file->sections.rnglists =
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &dwp_file->sections.rnglists,
+ sections.rnglists_offset,
+ sections.rnglists_size);
+ dwo_file->sections.str_offsets =
+ create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &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 (dwarf_read_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog, "Using existing virtual DWO: %s\n",
+ virtual_dwo_name.c_str ());
+ }
+ dwo_file = (struct dwo_file *) *dwo_file_slot;
+ }
+
+ dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ dwo_unit->dwo_file = dwo_file;
+ dwo_unit->signature = signature;
+ dwo_unit->section =
+ XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
+ *dwo_unit->section = create_dwp_v2_or_v5_section (dwarf2_per_objfile,
+ &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;
@@ -12853,13 +13298,20 @@ lookup_dwo_unit_in_dwp (struct dwarf2_per_objfile *dwarf2_per_objfile,
comp_dir, signature,
is_debug_types);
}
- else
+ else if (dwp_file->version == 2)
{
*slot = create_dwo_unit_in_dwp_v2 (dwarf2_per_objfile,
dwp_file, unit_index,
comp_dir, signature,
is_debug_types);
}
+ else // dwp_file->version == 5
+ {
+ *slot = create_dwo_unit_in_dwp_v5 (dwarf2_per_objfile,
+ dwp_file, unit_index,
+ comp_dir, signature,
+ is_debug_types);
+ }
return (struct dwo_unit *) *slot;
}
if (signature_in_table == 0)
@@ -12911,9 +13363,13 @@ try_open_dwop_file (struct dwarf2_per_objfile *dwarf2_per_objfile,
else
search_path = debug_file_directory;
+ search_path_holder.reset(
+ concat(ldirname(dwarf2_per_objfile->objfile->original_name).c_str(),
+ dirname_separator_string, search_path, (char *) NULL));
+ search_path = search_path_holder.get();
+
openp_flags flags = OPF_RETURN_REALPATH;
- if (is_dwp)
- flags |= OPF_SEARCH_IN_PATH;
+ flags |= OPF_SEARCH_IN_PATH;
gdb::unique_xmalloc_ptr<char> absolute_name;
desc = openp (search_path, flags, file_name,
@@ -13021,6 +13477,16 @@ dwarf2_locate_dwo_sections (bfd *abfd, asection *sectp, void *dwo_sections_ptr)
dwo_sections->macro.s.section = sectp;
dwo_sections->macro.size = bfd_section_size (sectp);
}
+ else if (section_is_p(sectp->name, &names->loclists_dwo))
+ {
+ dwo_sections->loclists.s.section = sectp;
+ dwo_sections->loclists.size = bfd_section_size(sectp);
+ }
+ else if (section_is_p(sectp->name, &names->rnglists_dwo))
+ {
+ dwo_sections->rnglists.s.section = sectp;
+ dwo_sections->rnglists.size = bfd_section_size(sectp);
+ }
else if (section_is_p (sectp->name, &names->str_dwo))
{
dwo_sections->str.s.section = sectp;
@@ -13068,11 +13534,20 @@ open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu,
bfd_map_over_sections (dwo_file->dbfd.get (), dwarf2_locate_dwo_sections,
&dwo_file->sections);
- create_cus_hash_table (dwarf2_per_objfile, *dwo_file, dwo_file->sections.info,
- dwo_file->cus);
+ create_cus_hash_table (dwarf2_per_objfile, per_cu->cu, *dwo_file,
+ dwo_file->sections.info, dwo_file->cus);
- create_debug_types_hash_table (dwarf2_per_objfile, dwo_file.get (),
- dwo_file->sections.types, dwo_file->tus);
+ if (dwo_file->sections.types.size() > 0 || per_cu->dwarf_version < 5)
+ {
+ create_debug_types_hash_table (dwarf2_per_objfile, dwo_file.get (),
+ dwo_file->sections.types, dwo_file->tus);
+ }
+ else
+ {
+ create_debug_type_hash_table (dwarf2_per_objfile, dwo_file.get (),
+ &(dwo_file->sections.info), dwo_file->tus,
+ rcuh_kind::TYPE);
+ }
if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, "DWO file found: %s\n", dwo_name);
@@ -13118,7 +13593,7 @@ dwarf2_locate_common_dwp_sections (bfd *abfd, asection *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. */
+ have version 1 or 2 or 5 until we parse the cu_index/tu_index sections. */
static void
dwarf2_locate_v2_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
@@ -13175,6 +13650,61 @@ dwarf2_locate_v2_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
}
}
+/* This function is mapped across the sections and remembers the offset and
+ size of each of the DWP version 5 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 or 5 until we parse the cu_index/tu_index sections. */
+
+static void
+dwarf2_locate_v5_dwp_sections (bfd *abfd, asection *sectp, void *dwp_file_ptr)
+{
+ struct dwp_file *dwp_file = (struct 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.section = sectp;
+ dwp_file->sections.abbrev.size = bfd_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->info_dwo))
+ {
+ dwp_file->sections.info.s.section = sectp;
+ dwp_file->sections.info.size = bfd_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->line_dwo))
+ {
+ dwp_file->sections.line.s.section = sectp;
+ dwp_file->sections.line.size = bfd_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->loclists_dwo))
+ {
+ dwp_file->sections.loclists.s.section = sectp;
+ dwp_file->sections.loclists.size = bfd_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->macro_dwo))
+ {
+ dwp_file->sections.macro.s.section = sectp;
+ dwp_file->sections.macro.size = bfd_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->rnglists_dwo))
+ {
+ dwp_file->sections.rnglists.s.section = sectp;
+ dwp_file->sections.rnglists.size = bfd_section_size (sectp);
+ }
+ else if (section_is_p (sectp->name, &names->str_offsets_dwo))
+ {
+ dwp_file->sections.str_offsets.s.section = sectp;
+ dwp_file->sections.str_offsets.size = bfd_section_size (sectp);
+ }
+}
+
/* Hash function for dwp_file loaded CUs/TUs. */
static hashval_t
@@ -13335,6 +13865,10 @@ open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
bfd_map_over_sections (dwp_file->dbfd.get (),
dwarf2_locate_v2_dwp_sections,
dwp_file.get ());
+ else if (dwp_file->version == 5)
+ bfd_map_over_sections (dwp_file->dbfd.get (),
+ dwarf2_locate_v5_dwp_sections,
+ dwp_file.get ());
dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table (objfile);
dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table (objfile);
@@ -13631,7 +14165,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
present in the abstract instance but not referenced in the concrete
one. */
if (child_die->tag == DW_TAG_call_site
- || child_die->tag == DW_TAG_GNU_call_site)
+ || child_die->tag == DW_TAG_GNU_call_site)
continue;
/* For each CHILD_DIE, find the corresponding child of
@@ -13736,7 +14270,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
}
}
- baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ baseaddr = ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
name = dwarf2_name (die, cu);
@@ -14361,7 +14896,7 @@ read_variable (struct die_info *die, struct dwarf2_cu *cu)
template <typename Callback>
static bool
dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
- Callback &&callback)
+ dwarf_tag tag, Callback &&callback)
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
@@ -14373,27 +14908,53 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
const gdb_byte *buffer;
CORE_ADDR baseaddr;
bool overflow = false;
+ ULONGEST addr_index;
+ struct dwarf2_section_info *rnglists_section;
+ int ignore_dwo_unit = 0;
found_base = cu->base_known;
base = cu->base_address;
- dwarf2_read_section (objfile, &dwarf2_per_objfile->rnglists);
- if (offset >= dwarf2_per_objfile->rnglists.size)
+ /* If the DW_AT_ranges attribute was part of a DW_TAG_skeleton_unit that was
+ changed into a DW_TAG_compile_unit after calling read_cutu_die_from_dwo, we
+ want to use the rnglist in the objfile rather than the one in the
+ dwo_unit. */
+ if (tag == DW_TAG_compile_unit &&
+ cu->cu_ranges_from_skeleton)
+ ignore_dwo_unit = 1;
+
+
+ /* Otherwise, if there's a dwo_unit, we want that rnglist. */
+ if (cu->dwo_unit &&
+ cu->dwo_unit->dwo_file->sections.rnglists.size > 0 &&
+ !ignore_dwo_unit)
+ {
+ rnglists_section = &cu->dwo_unit->dwo_file->sections.rnglists;
+ }
+ else
+ {
+ rnglists_section = &dwarf2_per_objfile->rnglists;
+ }
+
+ dwarf2_read_section (objfile, rnglists_section);
+ if (offset >= rnglists_section->size)
{
complaint (_("Offset %d out of bounds for DW_AT_ranges attribute"),
offset);
return false;
}
- buffer = dwarf2_per_objfile->rnglists.buffer + offset;
+ buffer = rnglists_section->buffer + offset;
- baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ baseaddr = ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ // FIXME: We should calculate the end per range list entry, not per section.
+ const gdb_byte *buf_end = (rnglists_section->buffer
+ + rnglists_section->size);
while (1)
{
/* Initialize it due to a false compiler warning. */
CORE_ADDR range_beginning = 0, range_end = 0;
- const gdb_byte *buf_end = (dwarf2_per_objfile->rnglists.buffer
- + dwarf2_per_objfile->rnglists.size);
unsigned int bytes_read;
if (buffer == buf_end)
@@ -14413,8 +14974,14 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
break;
}
base = read_address (obfd, buffer, cu, &bytes_read);
+ buffer += bytes_read;
found_base = 1;
+ break;
+ case DW_RLE_base_addressx:
+ addr_index = read_unsigned_leb128 (obfd, buffer, &bytes_read);
buffer += bytes_read;
+ base = read_addr_index (cu, addr_index);
+ found_base = 1;
break;
case DW_RLE_start_length:
if (buffer + cu->header.addr_size > buf_end)
@@ -14424,14 +14991,27 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
}
range_beginning = read_address (obfd, buffer, cu, &bytes_read);
buffer += bytes_read;
+ if (buffer > buf_end)
+ {
+ overflow = true;
+ break;
+ }
range_end = (range_beginning
+ read_unsigned_leb128 (obfd, buffer, &bytes_read));
buffer += bytes_read;
+ break;
+ case DW_RLE_startx_length:
+ addr_index = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+ buffer += bytes_read;
+ range_beginning = read_addr_index (cu, addr_index);
if (buffer > buf_end)
{
overflow = true;
break;
}
+ range_end = (range_beginning
+ + read_unsigned_leb128 (obfd, buffer, &bytes_read));
+ buffer += bytes_read;
break;
case DW_RLE_offset_pair:
range_beginning = read_unsigned_leb128 (obfd, buffer, &bytes_read);
@@ -14443,11 +15023,6 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
}
range_end = read_unsigned_leb128 (obfd, buffer, &bytes_read);
buffer += bytes_read;
- if (buffer > buf_end)
- {
- overflow = true;
- break;
- }
break;
case DW_RLE_start_end:
if (buffer + 2 * cu->header.addr_size > buf_end)
@@ -14460,13 +15035,28 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
range_end = read_address (obfd, buffer, cu, &bytes_read);
buffer += bytes_read;
break;
+ case DW_RLE_startx_endx:
+ addr_index = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+ buffer += bytes_read;
+ range_beginning = read_addr_index (cu, addr_index);
+ if (buffer > buf_end)
+ {
+ overflow = true;
+ break;
+ }
+ addr_index = read_unsigned_leb128 (obfd, buffer, &bytes_read);
+ buffer += bytes_read;
+ range_end = read_addr_index (cu, addr_index);
+ break;
default:
complaint (_("Invalid .debug_rnglists data (no base address)"));
return false;
}
+ if (buffer > buf_end)
+ overflow = true;
if (rlet == DW_RLE_end_of_list || overflow)
break;
- if (rlet == DW_RLE_base_address)
+ if (rlet == DW_RLE_base_address || rlet == DW_RLE_base_addressx)
continue;
if (!found_base)
@@ -14488,19 +15078,18 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
if (range_beginning == range_end)
continue;
- range_beginning += base;
- range_end += base;
+ /* DW_RLE_offset_pair needs the base address added to the addresses */
+ if (rlet == DW_RLE_offset_pair)
+ {
+ range_beginning += base;
+ range_end += base;
+ }
- /* A not-uncommon case of bad debug info.
- Don't pollute the addrmap with bad data. */
+ /* Sometimes a function is inlined or removed, leaving behind a range with
+ start address of zero. Ignore the range and continue. */
if (range_beginning + baseaddr == 0
&& !dwarf2_per_objfile->has_section_at_zero)
- {
- complaint (_(".debug_rnglists entry has start address of zero"
- " [in module %s]"), objfile_name (objfile));
continue;
- }
-
callback (range_beginning, range_end);
}
@@ -14523,6 +15112,7 @@ dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
template <typename Callback>
static int
dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
+ dwarf_tag tag,
Callback &&callback)
{
struct dwarf2_per_objfile *dwarf2_per_objfile
@@ -14540,7 +15130,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
CORE_ADDR baseaddr;
if (cu_header->version >= 5)
- return dwarf2_rnglists_process (offset, cu, callback);
+ return dwarf2_rnglists_process (offset, cu, tag, callback);
found_base = cu->base_known;
base = cu->base_address;
@@ -14628,7 +15218,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
static int
dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
CORE_ADDR *high_return, struct dwarf2_cu *cu,
- struct partial_symtab *ranges_pst)
+ struct partial_symtab *ranges_pst, dwarf_tag tag)
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
@@ -14639,7 +15229,7 @@ dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
CORE_ADDR high = 0;
int retval;
- retval = dwarf2_ranges_process (offset, cu,
+ retval = dwarf2_ranges_process (offset, cu, tag,
[&] (CORE_ADDR range_beginning, CORE_ADDR range_end)
{
if (ranges_pst != NULL)
@@ -14730,18 +15320,9 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
attr = dwarf2_attr (die, DW_AT_ranges, cu);
if (attr != NULL)
{
- /* DW_AT_ranges_base does not apply to DIEs from the DWO skeleton.
- We take advantage of the fact that DW_AT_ranges does not appear
- in DW_TAG_compile_unit of DWO files. */
- int need_ranges_base = die->tag != DW_TAG_compile_unit;
- unsigned int ranges_offset = (DW_UNSND (attr)
- + (need_ranges_base
- ? cu->ranges_base
- : 0));
-
- /* Value of the DW_AT_ranges attribute is the offset in the
- .debug_ranges section. */
- if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst))
+ ULONGEST ranges_offset = calculate_ranges_offset (*cu, *attr, die->tag);
+ if (!dwarf2_ranges_read (ranges_offset, &low, &high, cu, pst,
+ die->tag))
return PC_BOUNDS_INVALID;
/* Found discontinuous range of addresses. */
ret = PC_BOUNDS_RANGES;
@@ -14901,18 +15482,9 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
attr = dwarf2_attr (die, DW_AT_ranges, cu);
if (attr != nullptr)
{
- /* 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)
- + (need_ranges_base ? cu->ranges_base : 0));
-
+ ULONGEST offset = calculate_ranges_offset (*cu, *attr, die->tag);
std::vector<blockrange> blockvec;
- dwarf2_ranges_process (offset, cu,
+ dwarf2_ranges_process (offset, cu, die->tag,
[&] (CORE_ADDR start, CORE_ADDR end)
{
start += baseaddr;
@@ -15130,20 +15702,20 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
{
/* For big endian bits, the DW_AT_bit_offset gives the
- additional bit offset from the MSB of the containing
- anonymous object to the MSB of the field. We don't
- have to do anything special since we don't need to
- know the size of the anonymous object. */
+ additional bit offset from the MSB of the containing
+ anonymous object to the MSB of the field. We don't
+ have to do anything special since we don't need to
+ know the size of the anonymous object. */
SET_FIELD_BITPOS (*fp, FIELD_BITPOS (*fp) + DW_UNSND (attr));
}
else
{
/* For little endian bits, compute the bit offset to the
- MSB of the anonymous object, subtract off the number of
- bits from the MSB of the field to the MSB of the
- object, and then subtract off the number of bits of
- the field itself. The result is the bit offset of
- the LSB of the field. */
+ MSB of the anonymous object, subtract off the number of
+ bits from the MSB of the field to the MSB of the
+ object, and then subtract off the number of bits of
+ the field itself. The result is the bit offset of
+ the LSB of the field. */
int anonymous_size;
int bit_offset = DW_UNSND (attr);
@@ -15472,6 +16044,25 @@ dwarf2_is_constructor (struct die_info *die, struct dwarf2_cu *cu)
&& (type_name[len] == '\0' || type_name[len] == '<'));
}
+/* Check if the given VALUE is a recognized enum
+ dwarf_defaulted_attribute constant according to DWARF5 spec,
+ Table 7.24. */
+
+static bool
+is_valid_DW_AT_defaulted (ULONGEST value)
+{
+ switch (value)
+ {
+ case DW_DEFAULTED_no:
+ case DW_DEFAULTED_in_class:
+ case DW_DEFAULTED_out_of_class:
+ return true;
+ }
+
+ complaint (_("unrecognized DW_AT_defaulted value (%s)"), pulongest (value));
+ return false;
+}
+
/* Add a member function to the proper fieldlist. */
static void
@@ -15584,6 +16175,16 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
if (attr && DW_UNSND (attr) != 0)
fnp->is_artificial = 1;
+ /* Check for defaulted methods. */
+ attr = dwarf2_attr (die, DW_AT_defaulted, cu);
+ if (attr != nullptr && is_valid_DW_AT_defaulted (DW_UNSND (attr)))
+ fnp->defaulted = (enum dwarf_defaulted_attribute) DW_UNSND (attr);
+
+ /* Check for deleted methods. */
+ attr = dwarf2_attr (die, DW_AT_deleted, cu);
+ if (attr != nullptr && DW_UNSND (attr) != 0)
+ fnp->is_deleted = 1;
+
fnp->is_constructor = dwarf2_is_constructor (die, cu);
/* Get index in virtual function table if it is a virtual member
@@ -15823,6 +16424,52 @@ maybe_set_alignment (struct dwarf2_cu *cu, struct die_info *die,
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
}
+/* Check if the given VALUE is a valid enum dwarf_calling_convention
+ constant for a type, according to DWARF5 spec, Table 5.5. */
+
+static bool
+is_valid_DW_AT_calling_convention_for_type (ULONGEST value)
+{
+ switch (value)
+ {
+ case DW_CC_normal:
+ case DW_CC_pass_by_reference:
+ case DW_CC_pass_by_value:
+ return true;
+
+ default:
+ complaint (_("unrecognized DW_AT_calling_convention value "
+ "(%s) for a type"), pulongest (value));
+ return false;
+ }
+}
+
+/* Check if the given VALUE is a valid enum dwarf_calling_convention
+ constant for a subroutine, according to DWARF5 spec, Table 3.3, and
+ also according to GNU-specific values (see include/dwarf2.h). */
+
+static bool
+is_valid_DW_AT_calling_convention_for_subroutine (ULONGEST value)
+{
+ switch (value)
+ {
+ case DW_CC_normal:
+ case DW_CC_program:
+ case DW_CC_nocall:
+ return true;
+
+ case DW_CC_GNU_renesas_sh:
+ case DW_CC_GNU_borland_fastcall_i386:
+ case DW_CC_GDB_IBM_OpenCL:
+ return true;
+
+ default:
+ complaint (_("unrecognized DW_AT_calling_convention value "
+ "(%s) for a subroutine"), pulongest (value));
+ return false;
+ }
+}
+
/* 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
@@ -15904,6 +16551,18 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
TYPE_DECLARED_CLASS (type) = 1;
+ /* Store the calling convention in the type if it's available in
+ the die. Otherwise the calling convention remains set to
+ the default value DW_CC_normal. */
+ attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
+ if (attr != nullptr
+ && is_valid_DW_AT_calling_convention_for_type (DW_UNSND (attr)))
+ {
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_CPLUS_CALLING_CONVENTION (type)
+ = (enum dwarf_calling_convention) (DW_UNSND (attr));
+ }
+
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
{
@@ -16461,8 +17120,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
{
struct die_info *child_die;
struct symbol *sym;
- struct field *fields = NULL;
- int num_fields = 0;
+ std::vector<struct field> fields;
const char *name;
child_die = die->child;
@@ -16479,34 +17137,26 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
{
sym = new_symbol (child_die, this_type, cu);
- if ((num_fields % DW_FIELD_ALLOC_CHUNK) == 0)
- {
- fields = (struct field *)
- xrealloc (fields,
- (num_fields + DW_FIELD_ALLOC_CHUNK)
- * sizeof (struct field));
- }
+ fields.emplace_back ();
+ struct field &field = fields.back ();
- FIELD_NAME (fields[num_fields]) = sym->linkage_name ();
- FIELD_TYPE (fields[num_fields]) = NULL;
- SET_FIELD_ENUMVAL (fields[num_fields], SYMBOL_VALUE (sym));
- FIELD_BITSIZE (fields[num_fields]) = 0;
-
- num_fields++;
+ FIELD_NAME (field) = sym->linkage_name ();
+ FIELD_TYPE (field) = NULL;
+ SET_FIELD_ENUMVAL (field, SYMBOL_VALUE (sym));
+ FIELD_BITSIZE (field) = 0;
}
}
child_die = sibling_die (child_die);
}
- if (num_fields)
+ if (!fields.empty ())
{
- TYPE_NFIELDS (this_type) = num_fields;
+ TYPE_NFIELDS (this_type) = fields.size ();
TYPE_FIELDS (this_type) = (struct field *)
- TYPE_ALLOC (this_type, sizeof (struct field) * num_fields);
- memcpy (TYPE_FIELDS (this_type), fields,
- sizeof (struct field) * num_fields);
- xfree (fields);
+ TYPE_ALLOC (this_type, sizeof (struct field) * fields.size ());
+ memcpy (TYPE_FIELDS (this_type), fields.data (),
+ sizeof (struct field) * fields.size ());
}
}
@@ -17479,8 +18129,10 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
the subroutine die. Otherwise set the calling convention to
the default value DW_CC_normal. */
attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
- if (attr != nullptr)
- TYPE_CALLING_CONVENTION (ftype) = DW_UNSND (attr);
+ if (attr != nullptr
+ && is_valid_DW_AT_calling_convention_for_subroutine (DW_UNSND (attr)))
+ TYPE_CALLING_CONVENTION (ftype)
+ = (enum dwarf_calling_convention) (DW_UNSND (attr));
else if (cu->producer && strstr (cu->producer, "IBM XL C for OpenCL"))
TYPE_CALLING_CONVENTION (ftype) = DW_CC_GDB_IBM_OpenCL;
else
@@ -18392,10 +19044,34 @@ read_full_die_1 (const struct die_reader_specs *reader,
attributes. */
die->num_attrs = abbrev->num_attrs;
+ std::vector<int> indexes_that_need_reprocess;
for (i = 0; i < abbrev->num_attrs; ++i)
- info_ptr = read_attribute (reader, &die->attrs[i], &abbrev->attrs[i],
- info_ptr);
+ {
+ bool need_reprocess;
+ info_ptr =
+ read_attribute (reader, &die->attrs[i], &abbrev->attrs[i],
+ info_ptr, &need_reprocess);
+ if (need_reprocess)
+ indexes_that_need_reprocess.push_back (i);
+ }
+
+ struct attribute *attr = dwarf2_attr_no_follow (die, DW_AT_str_offsets_base);
+ if (attr != nullptr)
+ cu->str_offsets_base = DW_UNSND (attr);
+
+ auto maybe_addr_base = lookup_addr_base(die);
+ if (maybe_addr_base.has_value ())
+ cu->addr_base = *maybe_addr_base;
+ attr = dwarf2_attr_no_follow (die, DW_AT_loclists_base);
+ if (attr)
+ cu->loclist_base = DW_UNSND (attr);
+
+ auto maybe_ranges_base = lookup_ranges_base(die);
+ if (maybe_ranges_base.has_value ())
+ cu->ranges_base = *maybe_ranges_base;
+ for (int index : indexes_that_need_reprocess)
+ read_attribute_reprocess (reader, &die->attrs[index]);
*diep = die;
*has_children = abbrev->has_children;
return info_ptr;
@@ -18495,8 +19171,7 @@ abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
struct abbrev_info *cur_abbrev;
unsigned int abbrev_number, bytes_read, abbrev_name;
unsigned int abbrev_form;
- struct attr_abbrev *cur_attrs;
- unsigned int allocated_attrs;
+ std::vector<struct attr_abbrev> cur_attrs;
abbrev_table_up abbrev_table (new struct abbrev_table (sect_off));
@@ -18505,12 +19180,10 @@ abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
- allocated_attrs = ATTR_ALLOC_CHUNK;
- cur_attrs = XNEWVEC (struct attr_abbrev, allocated_attrs);
-
/* Loop until we reach an abbrev number of 0. */
while (abbrev_number)
{
+ cur_attrs.clear ();
cur_abbrev = abbrev_table->alloc_abbrev ();
/* read in abbrev header */
@@ -18545,25 +19218,18 @@ abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
if (abbrev_name == 0)
break;
- if (cur_abbrev->num_attrs == allocated_attrs)
- {
- allocated_attrs += ATTR_ALLOC_CHUNK;
- cur_attrs
- = XRESIZEVEC (struct attr_abbrev, cur_attrs, allocated_attrs);
- }
-
- cur_attrs[cur_abbrev->num_attrs].name
- = (enum dwarf_attribute) abbrev_name;
- cur_attrs[cur_abbrev->num_attrs].form
- = (enum dwarf_form) abbrev_form;
- cur_attrs[cur_abbrev->num_attrs].implicit_const = implicit_const;
+ cur_attrs.emplace_back ();
+ struct attr_abbrev &cur_attr = cur_attrs.back ();
+ cur_attr.name = (enum dwarf_attribute) abbrev_name;
+ cur_attr.form = (enum dwarf_form) abbrev_form;
+ cur_attr.implicit_const = implicit_const;
++cur_abbrev->num_attrs;
}
cur_abbrev->attrs =
XOBNEWVEC (&abbrev_table->abbrev_obstack, struct attr_abbrev,
cur_abbrev->num_attrs);
- memcpy (cur_abbrev->attrs, cur_attrs,
+ memcpy (cur_abbrev->attrs, cur_attrs.data (),
cur_abbrev->num_attrs * sizeof (struct attr_abbrev));
abbrev_table->add_abbrev (abbrev_number, cur_abbrev);
@@ -18583,7 +19249,6 @@ abbrev_table_read_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
break;
}
- xfree (cur_attrs);
return abbrev_table;
}
@@ -18907,14 +19572,20 @@ partial_die_info::read (const struct die_reader_specs *reader,
int has_high_pc_attr = 0;
int high_pc_relative = 0;
+ std::vector<struct attribute> attr_vec (abbrev.num_attrs);
for (i = 0; i < abbrev.num_attrs; ++i)
{
- struct attribute attr;
-
- info_ptr = read_attribute (reader, &attr, &abbrev.attrs[i], info_ptr);
-
+ bool need_reprocess;
+ info_ptr = read_attribute (reader, &attr_vec[i], &abbrev.attrs[i],
+ info_ptr, &need_reprocess);
+ /* String and address offsets that need to do the reprocessing have
+ already been read at this point, so there is no need to wait until
+ the loop terminates to do the reprocessing. */
+ if (need_reprocess)
+ read_attribute_reprocess (reader, &attr_vec[i]);
+ attribute &attr = attr_vec[i];
/* Store the data if it is of an attribute we want to keep in a
- partial symbol table. */
+ partial symbol table. */
switch (attr.name)
{
case DW_AT_name:
@@ -19057,19 +19728,11 @@ partial_die_info::read (const struct die_reader_specs *reader,
case DW_AT_ranges:
{
- /* It would be nice to reuse dwarf2_get_pc_bounds here,
- but that requires a full DIE, so instead we just
- reimplement it. */
- int need_ranges_base = tag != DW_TAG_compile_unit;
- unsigned int ranges_offset = (DW_UNSND (&attr)
- + (need_ranges_base
- ? cu->ranges_base
- : 0));
-
+ ULONGEST ranges_offset = calculate_ranges_offset (*cu, attr, tag);
/* Value of the DW_AT_ranges attribute is the offset in the
.debug_ranges section. */
if (dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, cu,
- nullptr))
+ nullptr, tag))
has_pc_info = 1;
}
break;
@@ -19354,12 +20017,203 @@ partial_die_info::fixup (struct dwarf2_cu *cu)
fixup_called = 1;
}
+/* Currently loclists and rnglists have exactly the same header structure, so we use
+ the same struct and function for reading both of them. */
+
+struct loclist_header
+read_loclist_header (struct dwarf2_cu *cu, bfd *abfd, const gdb_byte *info_ptr)
+{
+ unsigned int bytes_read;
+ struct loclist_header result;
+ result.length = read_initial_length (abfd, info_ptr,
+ &bytes_read);
+ info_ptr += bytes_read;
+ result.version = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ result.addr_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ result.segment_collector_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ result.offset_entry_count = read_4_bytes (abfd, info_ptr);
+ return result;
+}
+
+/* Currently loclist and rnglist has the same header size, so we use the same function
+ for both. */
+static int
+loclist_header_size(struct dwarf2_cu *cu) {
+ if (cu->header.initial_length_size == 4)
+ return LOCLIST_HEADER_SIZE32;
+ return LOCLIST_HEADER_SIZE64;
+}
+
+static int
+rnglist_header_size(struct dwarf2_cu *cu)
+{
+ return loclist_header_size(cu);
+}
+
+ULONGEST
+lookup_loclist_base (struct dwarf2_cu *cu)
+{
+ /* For the .dwo unit, the loclist_base points to the first offset following
+ the header. The header consists of the following entities-
+ 1. Unit Length (4 bytes for 32 bit DWARF format, and 12 bytes for the 64
+ bit format)
+ 2. version (2 bytes)
+ 3. address size (1 byte)
+ 4. segment selector size (1 byte)
+ 5. offset entry count (4 bytes)
+ These sizes are derived as per the DWARFv5 standard. */
+ if (cu->dwo_unit)
+ return loclist_header_size(cu);
+ return *cu->loclist_base;
+}
+
+ULONGEST
+lookup_rnglist_base (struct dwarf2_cu *cu)
+{
+ /* For the .dwo unit, the rnglist_base points to the first offset following
+ the header. The header consists of the following entities-
+ 1. Unit Length (4 bytes for 32 bit DWARF format, and 12 bytes for the 64
+ bit format)
+ 2. version (2 bytes)
+ 3. address size (1 byte)
+ 4. segment selector size (1 byte)
+ 5. offset entry count (4 bytes)
+ These sizes are derived as per the DWARFv5 standard. */
+ if (cu->dwo_unit)
+ return rnglist_header_size(cu);
+ return cu->ranges_base;
+}
+
+/* Given a DW_FORM_loclistx value loclist_index, fetch the offset from the array
+ of offsets in the .debug_loclists section. */
+CORE_ADDR
+read_loclist_index (struct dwarf2_cu *cu, ULONGEST loclist_index)
+{
+ struct dwarf2_per_objfile *dwarf2_per_objfile
+ = cu->per_cu->dwarf2_per_objfile;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *abfd = objfile->obfd;
+ ULONGEST loclist_base = lookup_loclist_base (cu);
+ struct dwarf2_section_info *section = cu_debug_loc_section (cu);
+ dwarf2_read_section (objfile, section);
+ if (section->buffer == NULL)
+ error(_("DW_FORM_loclistx used without .debug_loclist section "
+ "[in module %s]"),
+ objfile_name (objfile));
+ int header_size = loclist_header_size(cu);
+ const gdb_byte *info_ptr = (section->buffer) + loclist_base - header_size;
+ struct loclist_header header =
+ read_loclist_header (cu, get_section_bfd_owner (section), info_ptr);
+ if (loclist_index >= header.offset_entry_count)
+ error(_("DW_FORM_loclistx pointing outside of "
+ ".debug_loclist offset array [in module %s]"),
+ objfile_name (objfile));
+ info_ptr += header_size + loclist_index * cu->header.offset_size;
+ if (info_ptr >= section->buffer + section->size)
+ error(_("DW_FORM_loclistx pointing outside of "
+ ".debug_loclist section [in module %s]"),
+ objfile_name(objfile));
+ if (cu->header.offset_size == 4)
+ return read_4_bytes (abfd, info_ptr) + loclist_base;
+ else
+ return read_8_bytes (abfd, info_ptr) + loclist_base;
+}
+
+/* Given a DW_FORM_rnglistx value rnglist_index, fetch the offset from the array
+ of offsets in the .debug_rnglists section. */
+CORE_ADDR
+read_rnglist_index (struct dwarf2_cu *cu, ULONGEST rnglist_index)
+{
+ struct dwarf2_per_objfile *dwarf2_per_objfile
+ = cu->per_cu->dwarf2_per_objfile;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *abfd = objfile->obfd;
+ ULONGEST rnglist_base =
+ (cu->dwo_unit) ? rnglist_header_size(cu) : cu->ranges_base;
+
+ struct dwarf2_section_info *section = cu_debug_rnglist_section (cu);
+ if (section == nullptr)
+ error(_("Cannot find .debug_rnglists section [in module %s]"),
+ objfile_name(objfile));
+ dwarf2_read_section (objfile, section);
+ if (section->buffer == NULL)
+ error(_("DW_FORM_rnglistx used without .debug_rnglists section "
+ "[in module %s]"),
+ objfile_name (objfile));
+ int header_size = rnglist_header_size(cu);
+ const gdb_byte *info_ptr = (section->buffer) + rnglist_base - header_size;
+ struct loclist_header header =
+ read_loclist_header (cu, get_section_bfd_owner (section), info_ptr);
+ if (rnglist_index >= header.offset_entry_count)
+ error(_("DW_FORM_rnglistx index %lu pointing outside of "
+ ".debug_rnglists offset array of size %d [in module %s]"),
+ rnglist_index, header.offset_entry_count, objfile_name(objfile));
+ info_ptr += header_size + rnglist_index * cu->header.offset_size;
+ if (info_ptr >= section->buffer + section->size)
+ error(_("DW_FORM_rnglistx pointing outside of "
+ ".debug_rnglists section [in module %s]"),
+ objfile_name(objfile));
+ if (cu->header.offset_size == 4)
+ return read_4_bytes (abfd, info_ptr) + rnglist_base;
+ else
+ return read_8_bytes (abfd, info_ptr) + rnglist_base;
+}
+
+/* Process the attributes that had to be skipped in the first round. These
+ attributes are the ones that need str_offsets_base or addr_base attributes.
+ They could not have been processed in the first round, because at the time
+ the values of str_offsets_base or addr_base may not have been known. */
+void read_attribute_reprocess (const struct die_reader_specs *reader,
+ struct attribute *attr)
+{
+ struct dwarf2_cu *cu = reader->cu;
+ switch (attr->form)
+ {
+ case DW_FORM_loclistx:
+ DW_UNSND (attr) = read_loclist_index (cu, DW_UNSND (attr));
+ break;
+ case DW_FORM_rnglistx:
+ DW_UNSND (attr) = read_rnglist_index (cu, DW_UNSND (attr));
+ break;
+ case DW_FORM_addrx:
+ case DW_FORM_GNU_addr_index:
+ DW_ADDR (attr) = read_addr_index (cu, DW_UNSND (attr));
+ break;
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
+ case DW_FORM_GNU_str_index:
+ {
+ unsigned int str_index = DW_UNSND (attr);
+ if (reader->dwo_file != NULL)
+ {
+ DW_STRING (attr) = read_dwo_str_index (reader, str_index);
+ DW_STRING_IS_CANONICAL (attr) = 0;
+ }
+ else
+ {
+ DW_STRING (attr) = read_stub_str_index (cu, str_index);
+ DW_STRING_IS_CANONICAL (attr) = 0;
+ }
+ break;
+ }
+ default:
+ gdb_assert_not_reached (_("Unexpected DWARF form."));
+ }
+}
+
/* Read an attribute value described by an attribute form. */
static const gdb_byte *
read_attribute_value (const struct die_reader_specs *reader,
struct attribute *attr, unsigned form,
- LONGEST implicit_const, const gdb_byte *info_ptr)
+ LONGEST implicit_const, const gdb_byte *info_ptr,
+ bool *need_reprocess)
{
struct dwarf2_cu *cu = reader->cu;
struct dwarf2_per_objfile *dwarf2_per_objfile
@@ -19370,10 +20224,23 @@ read_attribute_value (const struct die_reader_specs *reader,
struct comp_unit_head *cu_header = &cu->header;
unsigned int bytes_read;
struct dwarf_block *blk;
+ *need_reprocess = false;
attr->form = (enum dwarf_form) form;
switch (form)
{
+ case DW_FORM_loclistx:
+ {
+ *need_reprocess = true;
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ }
+ break;
+ case DW_FORM_rnglistx:
+ *need_reprocess = true;
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ break;
case DW_FORM_ref_addr:
if (cu->header.version == 2)
DW_UNSND (attr) = read_address (abfd, info_ptr, cu, &bytes_read);
@@ -19543,22 +20410,15 @@ read_attribute_value (const struct die_reader_specs *reader,
info_ptr += bytes_read;
}
info_ptr = read_attribute_value (reader, attr, form, implicit_const,
- info_ptr);
+ info_ptr, need_reprocess);
break;
case DW_FORM_implicit_const:
DW_SND (attr) = implicit_const;
break;
case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
- if (reader->dwo_file == NULL)
- {
- /* For now flag a hard error.
- Later we can turn this into a complaint. */
- error (_("Dwarf Error: %s found in non-DWO CU [in module %s]"),
- dwarf_form_name (form),
- bfd_get_filename (abfd));
- }
- DW_ADDR (attr) = read_addr_index_from_leb128 (cu, info_ptr, &bytes_read);
+ *need_reprocess = true;
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
break;
case DW_FORM_strx:
@@ -19567,14 +20427,6 @@ read_attribute_value (const struct die_reader_specs *reader,
case DW_FORM_strx3:
case DW_FORM_strx4:
case DW_FORM_GNU_str_index:
- if (reader->dwo_file == NULL)
- {
- /* For now flag a hard error.
- Later we can turn this into a complaint if warranted. */
- error (_("Dwarf Error: %s found in non-DWO CU [in module %s]"),
- dwarf_form_name (form),
- bfd_get_filename (abfd));
- }
{
ULONGEST str_index;
if (form == DW_FORM_strx1)
@@ -19602,9 +20454,9 @@ read_attribute_value (const struct die_reader_specs *reader,
str_index = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
}
- DW_STRING (attr) = read_str_index (reader, str_index);
- DW_STRING_IS_CANONICAL (attr) = 0;
- }
+ *need_reprocess = true;
+ DW_UNSND (attr) = str_index;
+ }
break;
default:
error (_("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]"),
@@ -19640,11 +20492,12 @@ read_attribute_value (const struct die_reader_specs *reader,
static const gdb_byte *
read_attribute (const struct die_reader_specs *reader,
struct attribute *attr, struct attr_abbrev *abbrev,
- const gdb_byte *info_ptr)
+ const gdb_byte *info_ptr, bool *need_reprocess)
{
attr->name = abbrev->name;
return read_attribute_value (reader, attr, abbrev->form,
- abbrev->implicit_const, info_ptr);
+ abbrev->implicit_const, info_ptr,
+ need_reprocess);
}
/* Read dwarf information from a buffer. */
@@ -20071,27 +20924,30 @@ read_signed_leb128 (bfd *abfd, const gdb_byte *buf,
}
/* Given index ADDR_INDEX in .debug_addr, fetch the value.
- ADDR_BASE is the DW_AT_GNU_addr_base attribute or zero.
+ ADDR_BASE is the DW_AT_addr_base (DW_AT_GNU_addr_base) attribute or zero.
ADDR_SIZE is the size of addresses from the CU header. */
static CORE_ADDR
read_addr_index_1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
- unsigned int addr_index, ULONGEST addr_base, int addr_size)
+ unsigned int addr_index, gdb::optional<ULONGEST> addr_base,
+ int addr_size)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
bfd *abfd = objfile->obfd;
const gdb_byte *info_ptr;
+ ULONGEST addr_base_or_zero = addr_base.has_value () ? *addr_base : 0;
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));
- if (addr_base + addr_index * addr_size >= dwarf2_per_objfile->addr.size)
+ if (addr_base_or_zero + 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));
info_ptr = (dwarf2_per_objfile->addr.buffer
- + addr_base + addr_index * addr_size);
+ + addr_base_or_zero + addr_index * addr_size);
if (addr_size == 4)
return bfd_get_32 (abfd, info_ptr);
else
@@ -20124,7 +20980,7 @@ read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr,
struct dwarf2_read_addr_index_data
{
- ULONGEST addr_base;
+ gdb::optional<ULONGEST> addr_base;
int addr_size;
};
@@ -20156,7 +21012,7 @@ dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
{
struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
struct dwarf2_cu *cu = per_cu->cu;
- ULONGEST addr_base;
+ gdb::optional<ULONGEST> addr_base;
int addr_size;
/* We need addr_base and addr_size.
@@ -20196,21 +21052,21 @@ dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu,
addr_size);
}
-/* Given a DW_FORM_GNU_str_index or DW_FORM_strx, fetch the string.
- This is only used by the Fission support. */
+/* Given a DW_FORM_GNU_str_index value STR_INDEX, fetch the string.
+ STR_SECTION, STR_OFFSETS_SECTION can be from a Fission stub or a
+ DWO file. */
static const char *
-read_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
+read_str_index (struct dwarf2_cu *cu,
+ struct dwarf2_section_info *str_section,
+ struct dwarf2_section_info *str_offsets_section,
+ ULONGEST str_offsets_base, ULONGEST str_index)
{
- struct dwarf2_cu *cu = reader->cu;
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
const char *objf_name = objfile_name (objfile);
bfd *abfd = objfile->obfd;
- 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 or DW_FORM_strx";
@@ -20218,18 +21074,17 @@ read_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
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"
+ error (_("%s used without %s section"
" in CU at offset %s [in module %s]"),
- form_name, sect_offset_str (cu->header.sect_off), objf_name);
+ form_name, get_section_name (str_section),
+ sect_offset_str (cu->header.sect_off), objf_name);
if (str_offsets_section->buffer == NULL)
- error (_("%s used without .debug_str_offsets.dwo section"
+ error (_("%s used without %s section"
" in CU at offset %s [in module %s]"),
- form_name, sect_offset_str (cu->header.sect_off), objf_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 %s [in module %s]"),
- form_name, sect_offset_str (cu->header.sect_off), objf_name);
+ form_name, get_section_name (str_section),
+ sect_offset_str (cu->header.sect_off), objf_name);
info_ptr = (str_offsets_section->buffer
+ + str_offsets_base
+ str_index * cu->header.offset_size);
if (cu->header.offset_size == 4)
str_offset = bfd_get_32 (abfd, info_ptr);
@@ -20242,6 +21097,41 @@ read_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
return (const char *) (str_section->buffer + str_offset);
}
+/* Given a DW_FORM_GNU_str_index from a DWO file, fetch the string. */
+
+static const char *
+read_dwo_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
+{
+ ULONGEST str_offsets_base = reader->cu->header.version >= 5
+ ? reader->cu->header.addr_size : 0;
+ return read_str_index (reader->cu,
+ &reader->dwo_file->sections.str,
+ &reader->dwo_file->sections.str_offsets,
+ str_offsets_base, str_index);
+}
+
+/* Given a DW_FORM_GNU_str_index from a Fission stub, fetch the string. */
+
+static const char *
+read_stub_str_index (struct dwarf2_cu *cu, ULONGEST str_index)
+{
+ struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ const char *objf_name = objfile_name (objfile);
+ static const char form_name[] = "DW_FORM_GNU_str_index";
+ static const char str_offsets_attr_name[] = "DW_AT_str_offsets";
+
+ if (!cu->str_offsets_base.has_value ())
+ error (_("%s used in Fission stub without %s"
+ " in CU at offset 0x%lx [in module %s]"),
+ form_name, str_offsets_attr_name,
+ (long) cu->header.offset_size, objf_name);
+
+ return read_str_index (cu,
+ &cu->per_cu->dwarf2_per_objfile->str,
+ &cu->per_cu->dwarf2_per_objfile->str_offsets,
+ *cu->str_offsets_base, str_index);
+}
+
/* Return the length of an LEB128 number in BUF. */
static int
@@ -20943,7 +21833,7 @@ public:
we're processing the end of a sequence. */
void record_line (bool end_sequence);
- /* Check ADDRESS is zero and less than UNRELOCATED_LOWPC and if true
+ /* Check ADDRESS is -1, or zero and less than UNRELOCATED_LOWPC, and if true
nop-out rest of the lines in this sequence. */
void check_line_address (struct dwarf2_cu *cu,
const gdb_byte *line_ptr,
@@ -21293,12 +22183,13 @@ lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
const gdb_byte *line_ptr,
CORE_ADDR unrelocated_lowpc, CORE_ADDR address)
{
- /* If ADDRESS < UNRELOCATED_LOWPC then it's not a usable value, it's outside
- the pc range of the CU. However, we restrict the test to only ADDRESS
- values of zero to preserve GDB's previous behaviour which is to handle
- the specific case of a function being GC'd by the linker. */
+ /* Linkers resolve a symbolic relocation referencing a GC'd function to 0 or
+ -1. If ADDRESS is 0, ignoring the opcode will err if the text section is
+ located at 0x0. In this case, additionaly check that
+ if ADDRESS < UNRELOCATED_LOWPC. */
- if (address == 0 && address < unrelocated_lowpc)
+ if ((address == 0 && address < unrelocated_lowpc)
+ || address == (CORE_ADDR) -1)
{
/* This line table is for a function which has been
GCd by the linker. Ignore it. PR gdb/12528 */
@@ -21792,7 +22683,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
&& symbol_get_demangled_name (sym) == NULL)
symbol_set_demangled_name (sym,
dwarf2_full_name (name, die, cu),
- NULL);
+ NULL);
/* Default assumptions.
Use the passed type or decode it from the die. */
@@ -21963,11 +22854,11 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
else
{
/* We do not know the address of this symbol.
- If it is an external symbol and we have type information
- for it, enter the symbol as a LOC_UNRESOLVED symbol.
- The address of the variable will then be determined from
- the minimal symbol table whenever the variable is
- referenced. */
+ If it is an external symbol and we have type information
+ for it, enter the symbol as a LOC_UNRESOLVED symbol.
+ The address of the variable will then be determined from
+ the minimal symbol table whenever the variable is
+ referenced. */
attr2 = dwarf2_attr (die, DW_AT_external, cu);
/* Fortran explicitly imports any global symbols to the local
@@ -23035,8 +23926,7 @@ 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 = gdb_demangle (DW_STRING (attr), DMGL_TYPES);
-
+ demangled = gdb_demangle (DW_STRING (attr), DMGL_TYPES);
if (demangled)
{
const char *base;
@@ -25336,7 +26226,8 @@ attr_form_is_section_offset (const struct attribute *attr)
{
return (attr->form == DW_FORM_data4
|| attr->form == DW_FORM_data8
- || attr->form == DW_FORM_sec_offset);
+ || attr->form == DW_FORM_sec_offset
+ || attr->form == DW_FORM_loclistx);
}
/* Return non-zero if ATTR's value falls in the 'constant' class, or
@@ -25414,6 +26305,27 @@ cu_debug_loc_section (struct dwarf2_cu *cu)
: &dwarf2_per_objfile->loc);
}
+/* Return the .debug_rnglists section to use for CU. */
+static struct dwarf2_section_info *
+cu_debug_rnglist_section (struct dwarf2_cu *cu)
+{
+ if (cu->header.version < 5)
+ error (_(".debug_rnglists section cannot be used in DWARF %d"),
+ cu->header.version);
+ struct dwarf2_per_objfile *dwarf2_per_objfile =
+ cu->per_cu->dwarf2_per_objfile;
+
+ if (cu->dwo_unit)
+ {
+ struct dwo_sections *sections = &cu->dwo_unit->dwo_file->sections;
+
+ /* Only return dwo rnglist section if the dwo actually had one. */
+ if (sections->rnglists.size > 0)
+ return &sections->rnglists;
+ }
+ return &dwarf2_per_objfile->rnglists;
+}
+
/* A helper function that fills in a dwarf2_loclist_baton. */
static void
diff --git a/gdb-9.2/gdb/dwarf2read.h b/gdb-9.2/gdb/dwarf2read.h
index ae1f74ab6..bc8087ba4 100644
--- a/gdb-9.2/gdb/dwarf2read.h
+++ b/gdb-9.2/gdb/dwarf2read.h
@@ -156,6 +156,7 @@ public:
dwarf2_section_info macinfo {};
dwarf2_section_info macro {};
dwarf2_section_info str {};
+ dwarf2_section_info str_offsets {};
dwarf2_section_info line_str {};
dwarf2_section_info ranges {};
dwarf2_section_info rnglists {};
diff --git a/gdb-9.2/gdb/gdbtypes.h b/gdb-9.2/gdb/gdbtypes.h
index d3fd216a4..744984358 100644
--- a/gdb-9.2/gdb/gdbtypes.h
+++ b/gdb-9.2/gdb/gdbtypes.h
@@ -50,6 +50,7 @@
#include "gdbsupport/enum-flags.h"
#include "gdbsupport/underlying.h"
#include "gdbsupport/print-utils.h"
+#include "dwarf2.h"
/* Forward declarations for prototypes. */
struct field;
@@ -957,9 +958,18 @@ struct fn_field
unsigned int is_constructor : 1;
+ /* * True if this function is deleted, false otherwise. */
+
+ unsigned int is_deleted : 1;
+
+ /* * DW_AT_defaulted attribute for this function. The value is one
+ of the DW_DEFAULTED constants. */
+
+ ENUM_BITFIELD (dwarf_defaulted_attribute) defaulted : 2;
+
/* * Unused. */
- unsigned int dummy:9;
+ unsigned int dummy:6;
/* * Index into that baseclass's virtual function table, minus 2;
else if static: VOFFSET_STATIC; else: 0. */
@@ -1033,6 +1043,12 @@ struct cplus_struct_type
int is_dynamic : 2;
+ /* * The calling convention for this type, fetched from the
+ DW_AT_calling_convention attribute. The value is one of the
+ DW_CC constants. */
+
+ ENUM_BITFIELD (dwarf_calling_convention) calling_convention : 8;
+
/* * The base class which defined the virtual function table pointer. */
struct type *vptr_basetype;
@@ -1141,9 +1157,9 @@ struct func_type
/* * The calling convention for targets supporting multiple ABIs.
Right now this is only fetched from the Dwarf-2
DW_AT_calling_convention attribute. The value is one of the
- DW_CC enum dwarf_calling_convention constants. */
+ DW_CC constants. */
- unsigned calling_convention : 8;
+ ENUM_BITFIELD (dwarf_calling_convention) calling_convention : 8;
/* * Whether this function normally returns to its caller. It is
set from the DW_AT_noreturn attribute if set on the
@@ -1437,6 +1453,8 @@ extern void set_type_vptr_basetype (struct type *, struct type *);
? (struct cplus_struct_type*)&cplus_struct_default \
: TYPE_RAW_CPLUS_SPECIFIC(thistype))
#define TYPE_RAW_CPLUS_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff
+#define TYPE_CPLUS_CALLING_CONVENTION(thistype) \
+ TYPE_MAIN_TYPE(thistype)->type_specific.cplus_stuff->calling_convention
#define TYPE_FLOATFORMAT(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.floatformat
#define TYPE_GNAT_SPECIFIC(thistype) TYPE_MAIN_TYPE(thistype)->type_specific.gnat_stuff
#define TYPE_DESCRIPTIVE_TYPE(thistype) TYPE_GNAT_SPECIFIC(thistype)->descriptive_type
@@ -1553,6 +1571,8 @@ extern void set_type_vptr_basetype (struct type *, struct type *);
#define TYPE_FN_FIELD_VOFFSET(thisfn, n) ((thisfn)[n].voffset-2)
#define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1)
#define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC)
+#define TYPE_FN_FIELD_DEFAULTED(thisfn, n) ((thisfn)[n].defaulted)
+#define TYPE_FN_FIELD_DELETED(thisfn, n) ((thisfn)[n].is_deleted)
/* Accessors for typedefs defined by a class. */
#define TYPE_TYPEDEF_FIELD_ARRAY(thistype) \
diff --git a/gdb-9.2/gdb/symfile.h b/gdb-9.2/gdb/symfile.h
index 17e02a9da..ce02a2c50 100644
--- a/gdb-9.2/gdb/symfile.h
+++ b/gdb-9.2/gdb/symfile.h
@@ -569,6 +569,7 @@ struct dwarf2_debug_sections {
struct dwarf2_section_names macinfo;
struct dwarf2_section_names macro;
struct dwarf2_section_names str;
+ struct dwarf2_section_names str_offsets;
struct dwarf2_section_names line_str;
struct dwarf2_section_names ranges;
struct dwarf2_section_names rnglists;
diff --git a/gdb-9.2/include/dwarf2.h b/gdb-9.2/include/dwarf2.h
index a4a183155..bd33e06a7 100644
--- a/gdb-9.2/include/dwarf2.h
+++ b/gdb-9.2/include/dwarf2.h
@@ -1,6 +1,6 @@
/* Declarations and definitions of codes relating to the DWARF2 and
DWARF3 symbolic debugging information formats.
- Copyright (C) 1992-2019 Free Software Foundation, Inc.
+ Copyright (C) 1992-2020 Free Software Foundation, Inc.
Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
Office (AJPO), Florida State University and Silicon Graphics Inc.
@@ -488,19 +488,36 @@ enum dwarf_unit_type
#define DW_EH_PE_indirect 0x80
/* Codes for the debug sections in a dwarf package (.dwp) file.
- Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFissionDWP. */
+ (From the pre-standard formats Extensions for Fission.
+ See http://gcc.gnu.org/wiki/DebugFissionDWP). */
enum dwarf_sect
- {
- DW_SECT_INFO = 1,
- DW_SECT_TYPES = 2,
- DW_SECT_ABBREV = 3,
- DW_SECT_LINE = 4,
- DW_SECT_LOC = 5,
- DW_SECT_STR_OFFSETS = 6,
- DW_SECT_MACINFO = 7,
- DW_SECT_MACRO = 8,
- DW_SECT_MAX = 8
- };
+{
+ DW_SECT_INFO = 1,
+ DW_SECT_TYPES = 2,
+ DW_SECT_ABBREV = 3,
+ DW_SECT_LINE = 4,
+ DW_SECT_LOC = 5,
+ DW_SECT_STR_OFFSETS = 6,
+ DW_SECT_MACINFO = 7,
+ DW_SECT_MACRO = 8,
+ DW_SECT_MAX = 8
+};
+
+/* Codes for the debug sections in a dwarf package (.dwp) file.
+ (From the official DWARF v5 spec.
+ See http://dwarfstd.org/doc/DWARF5.pdf, section 7.3.5). */
+enum dwarf_sect_v5
+{
+ DW_SECT_INFO_V5 = 1,
+ DW_SECT_RESERVED_V5 = 2,
+ DW_SECT_ABBREV_V5 = 3,
+ DW_SECT_LINE_V5 = 4,
+ DW_SECT_LOCLISTS_V5 = 5,
+ DW_SECT_STR_OFFSETS_V5 = 6,
+ DW_SECT_MACRO_V5 = 7,
+ DW_SECT_RNGLISTS_V5 = 8,
+ DW_SECT_MAX_V5 = 8
+};
#ifdef __cplusplus
extern "C" {