From: "Ali Tamur via gdb-patches" <gdb-patches@sourceware.org>
To: gdb-patches@sourceware.org
Cc: Ali Tamur <tamur@google.com>
Subject: [PATCH 1/4] Increasing support for dwarf 5.
Date: Tue, 27 Aug 2019 23:41:00 -0000 [thread overview]
Message-ID: <20190827234148.243410-1-tamur@google.com> (raw)
* DW_UT_skeleton and DW_UT_split_compile compilation units also have signatures
to match the compilation unit in the skeleton and .dwo files. The signature is
part of the header.
gdb/ChangeLog:
2019-08-26 Ali Tamur <tamur@google.com>
* gdb/dwarf2read.c (comp_unit_head): Update comment.
(dwarf2_dwo_name): New function declaration.
(read_comp_unit_head): Add support for new compilation units,
DW_UT_partial, DW_UT_skeleton, DW_UT_split_compile, DW_UT_split_type.
Particularly, DW_UT_skeleton and DW_UT_split_compile also have signature
in their header.
(lookup_signature): New function. Returns the signature of the given
compile unit.
(lookup_dwo_unit): API change. Use the new lookup_signature function.
(init_cutu_and_read_dies): Use dwarf2_dwo_name to find the dwo name.
(create_dwo_cu_reader): Use the added lookup_signature function.
(dwarf2_dwo_name): Get the dwo name if present.
---
gdb/dwarf2read.c | 101 ++++++++++++++++++++++++++++++++---------------
1 file changed, 69 insertions(+), 32 deletions(-)
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index de9755f6ce..91a4e48c8f 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -373,8 +373,9 @@ struct comp_unit_head
This will be the first byte following the compilation unit header. */
cu_offset first_die_cu_offset;
- /* 64-bit signature of this type unit - it is valid only for
- UNIT_TYPE DW_UT_type. */
+ /* 64-bit signature of this type unit. In dwarf 4, it is valid only for
+ UNIT_TYPE DW_UT_type. In dwarf 5, DW_UT_split_type, DW_UT_partial,
+ DW_UT_skeleton, DW_UT_split_compile also contain a signature. */
ULONGEST signature;
/* For types, offset in the type's DIE of the type defined by this TU. */
@@ -1579,6 +1580,8 @@ static struct attribute *dwarf2_attr_no_follow (struct die_info *,
static const char *dwarf2_string_attr (struct die_info *die, unsigned int name,
struct dwarf2_cu *cu);
+static const char *dwarf2_dwo_name (struct die_info *die, struct dwarf2_cu *cu);
+
static int dwarf2_flag_true_p (struct die_info *die, unsigned name,
struct dwarf2_cu *cu);
@@ -6384,18 +6387,24 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
switch (cu_header->unit_type)
{
case DW_UT_compile:
+ 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 DW_UT_compile, should be DW_UT_type) [in module %s]"),
- filename);
+ "(is %d, should be DW_UT_type) [in module %s]"),
+ cu_header->unit_type, filename);
break;
case DW_UT_type:
+ case DW_UT_split_type:
section_kind = rcuh_kind::TYPE;
break;
default:
error (_("Dwarf Error: wrong unit_type in compilation unit header "
- "(is %d, should be %d or %d) [in module %s]"),
- cu_header->unit_type, DW_UT_compile, DW_UT_type, filename);
+ "(is %d, should be one of: %d, %d, %d, %d or %d) "
+ "[in module %s]"),
+ cu_header->unit_type, DW_UT_compile, DW_UT_skeleton,
+ DW_UT_split_compile, DW_UT_type, DW_UT_split_type, filename);
}
cu_header->addr_size = read_1_byte (abfd, info_ptr);
@@ -6416,13 +6425,19 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
_("read_comp_unit_head: dwarf from non elf file"));
cu_header->signed_addr_p = signed_addr;
- if (section_kind == rcuh_kind::TYPE)
- {
- LONGEST type_offset;
+ bool header_has_signature = section_kind == rcuh_kind::TYPE
+ || cu_header->unit_type == DW_UT_skeleton
+ || cu_header->unit_type == DW_UT_split_compile;
+ if (header_has_signature)
+ {
cu_header->signature = read_8_bytes (abfd, info_ptr);
info_ptr += 8;
+ }
+ if (section_kind == rcuh_kind::TYPE)
+ {
+ LONGEST type_offset;
type_offset = read_offset (abfd, info_ptr, cu_header, &bytes_read);
info_ptr += bytes_read;
cu_header->type_cu_offset_in_tu = (cu_offset) type_offset;
@@ -7291,46 +7306,59 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
return 1;
}
+/* Return the signature of the compile unit. In dwarf 4 and before, the
+ signature is in the DW_AT_GNU_dwo_id attribute. In dwarf 5 and later, the
+ signature is part of the header. Returns 0 if the signature is not found. */
+static ULONGEST
+lookup_signature (struct dwarf2_cu *cu, struct die_info* comp_unit_die)
+{
+ ULONGEST signature = 0;
+ struct attribute *attr;
+
+ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu);
+ if (attr)
+ signature = DW_UNSND (attr);
+ else if (cu->header.signature)
+ signature = cu->header.signature;
+ return signature;
+}
+
/* 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,
+lookup_dwo_unit (const struct die_reader_specs *reader,
struct die_info *comp_unit_die)
{
- struct dwarf2_cu *cu = this_cu->cu;
- ULONGEST signature;
+ struct dwarf2_cu *cu = reader->cu;
+ struct dwarf2_per_cu_data *per_cu = cu->per_cu;
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. */
- dwo_name = dwarf2_string_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu);
+ dwo_name = dwarf2_dwo_name (comp_unit_die, cu);
comp_dir = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
- if (this_cu->is_debug_types)
+ if (per_cu->is_debug_types)
{
struct signatured_type *sig_type;
- /* Since this_cu is the first member of struct signatured_type,
+ /* Since per_cu is the first member of struct signatured_type,
we can go from a pointer to one to a pointer to the other. */
- sig_type = (struct signatured_type *) this_cu;
- signature = sig_type->signature;
+ sig_type = (struct signatured_type *) per_cu;
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)
+ ULONGEST signature = lookup_signature(cu, comp_unit_die);
+ if (!signature)
error (_("Dwarf Error: missing dwo_id for dwo_name %s"
" [in module %s]"),
- dwo_name, objfile_name (this_cu->dwarf2_per_objfile->objfile));
- signature = DW_UNSND (attr);
- dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir,
+ dwo_name, objfile_name (per_cu->dwarf2_per_objfile->objfile));
+ dwo_unit = lookup_dwo_comp_unit (per_cu, dwo_name, comp_dir,
signature);
}
@@ -7443,7 +7471,6 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
struct die_reader_specs reader;
struct die_info *comp_unit_die;
int has_children;
- struct attribute *attr;
struct signatured_type *sig_type = NULL;
struct dwarf2_section_info *abbrev_section;
/* Non-zero if CU currently points to a DWO file and we need to
@@ -7580,9 +7607,9 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
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);
+ const char *dwo_name = dwarf2_dwo_name (comp_unit_die, cu);
abbrev_table_up dwo_abbrev_table;
- if (attr)
+ if (dwo_name)
{
struct dwo_unit *dwo_unit;
struct die_info *dwo_comp_unit_die;
@@ -7594,7 +7621,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
sect_offset_str (this_cu->sect_off),
bfd_get_filename (abfd));
}
- dwo_unit = lookup_dwo_unit (this_cu, comp_unit_die);
+ dwo_unit = lookup_dwo_unit (&reader, comp_unit_die);
if (dwo_unit != NULL)
{
if (read_cutu_die_from_dwo (this_cu, dwo_unit,
@@ -11833,10 +11860,9 @@ create_dwo_cu_reader (const struct die_reader_specs *reader,
struct create_dwo_cu_data *data = (struct create_dwo_cu_data *) datap;
struct dwo_file *dwo_file = data->dwo_file;
struct dwo_unit *dwo_unit = &data->dwo_unit;
- struct attribute *attr;
- attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu);
- if (attr == NULL)
+ ULONGEST signature = lookup_signature(cu, comp_unit_die);
+ if (!signature)
{
complaint (_("Dwarf Error: debug entry at offset %s is missing"
" its dwo_id [in module %s]"),
@@ -11845,7 +11871,7 @@ create_dwo_cu_reader (const struct die_reader_specs *reader,
}
dwo_unit->dwo_file = dwo_file;
- dwo_unit->signature = DW_UNSND (attr);
+ dwo_unit->signature = signature;
dwo_unit->section = section;
dwo_unit->sect_off = sect_off;
dwo_unit->length = cu->per_cu->length;
@@ -20102,6 +20128,17 @@ dwarf2_string_attr (struct die_info *die, unsigned int name, struct dwarf2_cu *c
return str;
}
+/* Return the dwo name or NULL if not present. If present, it is in either
+ DW_AT_GNU_dwo_name or DW_AT_dwo_name atrribute. */
+static const char *
+dwarf2_dwo_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+ const char *dwo_name = dwarf2_string_attr (die, DW_AT_GNU_dwo_name, cu);
+ if (!dwo_name)
+ dwo_name = dwarf2_string_attr (die, DW_AT_dwo_name, cu);
+ return dwo_name;
+}
+
/* Return non-zero iff the attribute NAME is defined for the given DIE,
and holds a non-zero value. This function should only be used for
DW_FORM_flag or DW_FORM_flag_present attributes. */
--
2.23.0.187.g17f5b7556c-goog
next reply other threads:[~2019-08-27 23:41 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-27 23:41 Ali Tamur via gdb-patches [this message]
2019-08-28 5:16 ` Simon Marchi
2019-09-06 21:52 ` [PATCH v2 1/4] DWARF 5 support: Handle dwo_id Ali Tamur via gdb-patches
2019-09-07 20:30 ` Simon Marchi
2019-09-09 18:58 ` Ali Tamur via gdb-patches
2019-09-09 21:21 ` Simon Marchi
2019-09-10 1:37 ` Ali Tamur via gdb-patches
2019-09-10 18:45 ` [PATCH v2 2/4] DWARF 5 support: Handle DW_FORM_strx Ali Tamur via gdb-patches
2019-09-18 3:08 ` Simon Marchi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190827234148.243410-1-tamur@google.com \
--to=gdb-patches@sourceware.org \
--cc=tamur@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).