From 86598ebfa13479b4ba3b6b7a9de25c3e497ff57e Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 16 Sep 2009 12:22:04 +0200 Subject: Clean up dwflpp::translate_location workaround for DW_AT_data_member_location. Do the same workaround as loc2c-test.c does. Just treat a constant member location offset as a DW_OP_plus_uconst and call c_translate_location for it. Also Remove c_translate_add_offset. * dwflpp.cxx (dwflpp::translate_location): Check elfutils version and only do workaround for elfutils < 0.142. * loc2c.h (c_translate_add_offset): Removed. * loc2c.c (c_translate_add_offset): Likewise. --- dwflpp.cxx | 23 +++++++++++------------ loc2c.c | 34 ---------------------------------- loc2c.h | 7 ------- 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. */ -- cgit