This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
dwarflint versus data_member_location
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Fri, 16 Jul 2010 11:20:48 +0200
- Subject: dwarflint versus data_member_location
Hi,
dwarflint (from the dwarf branch) gives the following error:
error: .debug_abbrev: abbr. attribute 0x2a: data_member_location with
invalid form "sdata".
But that is actually valid. The Dwarf spec says that
DW_AT_data_member_location may be either a constant, exprloc or
loclistptr. If it is a constant then it should be interpreted as the
offset into the struct.
The following patch fixes it. Does that make sense to commit to the
dwarf branch?
Thanks,
Mark
>From 1531bd43674049bd976bc7c8d2575d7074a74064 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mjw@redhat.com>
Date: Fri, 16 Jul 2010 11:18:46 +0200
Subject: [PATCH] dwarflint: DW_AT_data_member_location may have constant form.
---
src/ChangeLog | 6 ++++++
src/dwarflint.c | 36 ++++++++++++++++++++++++++++++++----
2 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 21aed9d..6921d4c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2010-07-16 Mark Wielaard <mjw@redhat.com>
+
+ * dwarflint.cc (check_abbrev_constant_form): New function.
+ (abbrev_table_load): Check whether DW_AT_data_member_location
+ is constant.
+
2010-07-13 Roland McGrath <roland@redhat.com>
* dwarfcmp.cc (talker): Replace visit method with visitor type.
diff --git a/src/dwarflint.c b/src/dwarflint.c
index a2a4290..f251511 100644
--- a/src/dwarflint.c
+++ b/src/dwarflint.c
@@ -1463,6 +1463,28 @@ check_abbrev_location_form (uint64_t form)
};
}
+/* check that given form encodes a constant. */
+static bool
+check_abbrev_constant_form (uint64_t form)
+{
+ switch (form)
+ {
+ /* fixed length, opaque */
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+
+ /* variable length, signed, unsigned */
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
static bool
is_location_attrib (uint64_t name)
{
@@ -1713,10 +1735,16 @@ abbrev_table_load (struct read_ctx *ctx)
else if (is_location_attrib (attrib_name))
{
if (!check_abbrev_location_form (attrib_form))
- wr_error (&where,
- ": %s with invalid form \"%s\".\n",
- dwarf_attr_string (attrib_name),
- dwarf_form_string (attrib_form));
+ {
+ // DW_AT_data_member_location is special, might also
+ // be a constant offset.
+ if (attrib_name != DW_AT_data_member_location
+ || ! check_abbrev_constant_form (attrib_form))
+ wr_error (&where,
+ ": %s with invalid form \"%s\".\n",
+ dwarf_attr_string (attrib_name),
+ dwarf_form_string (attrib_form));
+ }
}
/* Similar for DW_AT_ranges. */
else if (attrib_name == DW_AT_ranges
--
1.7.1