summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dwflpp.cxx23
-rw-r--r--loc2c.c34
-rw-r--r--loc2c.h7
3 files changed, 11 insertions, 53 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 10127c61..ee13d0b2 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -1674,21 +1674,20 @@ dwflpp::translate_location(struct obstack *pool,
{
/* DW_AT_data_member_location, can be either constant offsets
- (struct member fields), or full blown location expressions. */
+ (struct member fields), or full blown location expressions.
+ In older elfutils, dwarf_getlocation_addr would not handle the
+ constant for us, but newer ones do. For older ones, we work
+ it by faking an expression, which is what newer ones do. */
+#if !_ELFUTILS_PREREQ (0,142)
if (dwarf_whatattr (attr) == DW_AT_data_member_location)
{
- unsigned int form = dwarf_whatform (attr);
- if (form == DW_FORM_data1 || form == DW_FORM_data2
- || form == DW_FORM_sdata || form == DW_FORM_udata)
- {
- Dwarf_Sword off;
- if (dwarf_formsdata (attr, &off) != 0)
- throw semantic_error (string ("dwarf_formsdata failed, ")
- + string (dwarf_errmsg (-1)), e->tok);
- c_translate_add_offset (pool, 1, NULL, off, tail);
- return *tail;
- }
+ Dwarf_Op offset_loc = { .atom = DW_OP_plus_uconst };
+ if (dwarf_formudata (attr, &offset_loc.number) == 0)
+ return c_translate_location (pool, &loc2c_error, this,
+ &loc2c_emit_address, 1, 0, pc,
+ &offset_loc, 1, NULL, NULL);
}
+#endif
Dwarf_Op *expr;
size_t len;
diff --git a/loc2c.c b/loc2c.c
index d4cb4666..5cf59691 100644
--- a/loc2c.c
+++ b/loc2c.c
@@ -1711,40 +1711,6 @@ c_translate_pointer_store (struct obstack *pool, int indent,
// XXX: what about multiple-location lvalues?
}
-
-/* Translate a fragment to add an offset to the currently calculated
- address of the input location. Used for struct fields. Only works
- when location is already an actual base address.
-*/
-
-void
-c_translate_add_offset (struct obstack *pool, int indent, const char *comment,
- Dwarf_Sword off, struct location **input)
-{
- indent++;
- if (comment == NULL || comment[0] == '\0')
- comment = "field offset";
- switch ((*input)->type)
- {
- case loc_address:
- obstack_printf (pool, "%*saddr += " SFORMAT "; // %s\n",
- indent * 2 + 2, "", off, comment);
- *input = (*input)->next = new_synthetic_loc (pool, *input, false);
- break;
-
- case loc_register:
- FAIL (*input, N_("cannot add offset of object in register"));
- break;
- case loc_noncontiguous:
- FAIL (*input, N_("cannot add offset of noncontiguous object"));
- break;
-
- default:
- abort ();
- break;
- }
-}
-
/* Determine the element stride of an array type. */
static Dwarf_Word
array_stride (Dwarf_Die *typedie, struct location *origin)
diff --git a/loc2c.h b/loc2c.h
index 449d4499..8bc59d29 100644
--- a/loc2c.h
+++ b/loc2c.h
@@ -87,13 +87,6 @@ c_translate_pointer_store (struct obstack *pool, int indent,
Dwarf_Die *typedie, struct location **input,
const char *rvalue);
-/* Translate a fragment to add an offset to the currently calculated
- address of the input location. Used for struct fields. Only works
- when location is already an actual base address. */
-void
-c_translate_add_offset (struct obstack *pool, int indent, const char *comment,
- Dwarf_Sword off, struct location **input);
-
/* Translate a C fragment for a direct argument VALUE. On errors, call FAIL,
which should not return. Any later errors will use FAIL and FAIL_ARG from
this translate call. On success, return the fragment created. */