summaryrefslogtreecommitdiffstats
path: root/dwflpp.cxx
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-07-07 14:35:10 +0200
committerMark Wielaard <mjw@redhat.com>2009-07-08 16:20:48 +0200
commit619d9aaf011c975159a79d34259083a596162bf1 (patch)
tree16599882e087d793b4ba69c602b46271204f0ec2 /dwflpp.cxx
parent51305196f1d078849da1718bb6ccfbed5af182ed (diff)
downloadsystemtap-steved-619d9aaf011c975159a79d34259083a596162bf1.tar.gz
systemtap-steved-619d9aaf011c975159a79d34259083a596162bf1.tar.xz
systemtap-steved-619d9aaf011c975159a79d34259083a596162bf1.zip
Add support for constant struct member field offsets.
* loc2c.h (c_translate_add_offset): New function prototype. * loc2c.c (c_translate_add_offset): New function implementation. * loc2c-test.c (handle_variable): Use c_translate_add_offset if appropriate. * dwflpp.cxx (translate_location): Likewise.
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r--dwflpp.cxx20
1 files changed, 19 insertions, 1 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index de994c18..17bce608 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -1449,6 +1449,24 @@ dwflpp::translate_location(struct obstack *pool,
struct location **tail,
const target_symbol *e)
{
+
+ /* DW_AT_data_member_location, can be either constant offsets
+ (struct member fields), or full blown location expressions. */
+ 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 *expr;
size_t len;
@@ -1470,7 +1488,7 @@ dwflpp::translate_location(struct obstack *pool,
default: /* Shouldn't happen. */
case -1:
- throw semantic_error (string ("dwarf_getlocation_addr failed") +
+ throw semantic_error (string ("dwarf_getlocation_addr failed, ") +
string (dwarf_errmsg (-1)),
e->tok);
}