summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-09-17 15:06:57 +0200
committerMark Wielaard <mjw@redhat.com>2009-09-17 17:01:38 +0200
commit24c7957b4dbddc8545d0e0c734377746a5ae6e60 (patch)
treee276329ae8a27bc46dda20c2ef665766cc97baa2
parent6287a9e628bcbe6192da8fd9f0ce659a8acc13fc (diff)
downloadsystemtap-steved-24c7957b4dbddc8545d0e0c734377746a5ae6e60.tar.gz
systemtap-steved-24c7957b4dbddc8545d0e0c734377746a5ae6e60.tar.xz
systemtap-steved-24c7957b4dbddc8545d0e0c734377746a5ae6e60.zip
PR10417 Pass around attributes for supporting DW_OP_{implicit,stack}_value.
Preparation for retrieving the Dwarf_Block that holds the value of an DW_OP_implicit_value. We need the Dwarf_Attribute that is associated with the location expression operants. Depends on new elfutils 0.143 functionality. Recognizes, but does not yet handle the new operants DW_OP_{implicit,stack}_value. * loc2c.h (c_translate_location): Take an Dwarf_Attribute. * loc2c.c (c_translate_location): Likewise and pass it on. (location_relative): Likewise. (location_from_address): Likewise. (translate): Likewise and capture Dwarf_Block. * loc2c-test.c (handle_variable): Pass in Dwarf_Attribute. * dwflpp.cxx (translate_location): Likewise. (literal_stmt_for_return): Pass in NULL to indicate no attribute.
-rw-r--r--dwflpp.cxx4
-rw-r--r--loc2c-test.c8
-rw-r--r--loc2c.c47
-rw-r--r--loc2c.h5
4 files changed, 47 insertions, 17 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index ee3985cb..f3015fcc 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -1774,7 +1774,7 @@ dwflpp::translate_location(struct obstack *pool,
return c_translate_location (pool, &loc2c_error, this,
&loc2c_emit_address,
1, 0 /* PR9768 */,
- pc, expr, len, tail, fb_attr, cfa_ops);
+ pc, attr, expr, len, tail, fb_attr, cfa_ops);
}
@@ -2397,7 +2397,7 @@ dwflpp::literal_stmt_for_return (Dwarf_Die *scope_die,
struct location *head = c_translate_location (&pool, &loc2c_error, this,
&loc2c_emit_address,
1, 0 /* PR9768 */,
- pc, locops, nlocops,
+ pc, NULL, locops, nlocops,
&tail, NULL, NULL);
/* Translate the ->bar->baz[NN] parts. */
diff --git a/loc2c-test.c b/loc2c-test.c
index b8883876..495a95f1 100644
--- a/loc2c-test.c
+++ b/loc2c-test.c
@@ -136,7 +136,7 @@ handle_variable (Dwarf_Die *lscopes, int lnscopes, int out,
struct location *head, *tail = NULL;
head = c_translate_location (&pool, &fail, NULL, NULL,
- 1, cubias, pc, locexpr, locexpr_len,
+ 1, cubias, pc, &attr_mem, locexpr, locexpr_len,
&tail, fb_attr, cfa_ops);
if (dwarf_attr_integrate (vardie, DW_AT_type, &attr_mem) == NULL)
@@ -238,7 +238,8 @@ handle_variable (Dwarf_Die *lscopes, int lnscopes, int out,
Dwarf_Op offset_loc = { .atom = DW_OP_plus_uconst };
if (dwarf_formudata (&attr_mem, &offset_loc.number) == 0)
c_translate_location (&pool, NULL, NULL, NULL,
- 1, cubias, pc, &offset_loc, 1,
+ 1, cubias, pc, &attr_mem,
+ &offset_loc, 1,
&tail, NULL, NULL);
else
#endif
@@ -246,7 +247,8 @@ handle_variable (Dwarf_Die *lscopes, int lnscopes, int out,
locexpr = get_location (cubias, pc, &attr_mem,
&locexpr_len);
c_translate_location (&pool, NULL, NULL, NULL,
- 1, cubias, pc, locexpr, locexpr_len,
+ 1, cubias, pc, &attr_mem,
+ locexpr, locexpr_len,
&tail, NULL, NULL);
}
}
diff --git a/loc2c.c b/loc2c.c
index 5cf59691..4bc6aa6e 100644
--- a/loc2c.c
+++ b/loc2c.c
@@ -151,7 +151,7 @@ lose (struct location *loc,
static const char *
translate (struct obstack *pool, int indent, Dwarf_Addr addrbias,
- const Dwarf_Op *expr, const size_t len,
+ Dwarf_Attribute *attr, const Dwarf_Op *expr, const size_t len,
struct location *input,
bool *need_fb, size_t *loser,
struct location *loc)
@@ -525,6 +525,28 @@ translate (struct obstack *pool, int indent, Dwarf_Addr addrbias,
}
break;
+ case DW_OP_stack_value:
+ DIE ("DW_OP_stack_value not supported");
+ break;
+
+ case DW_OP_implicit_value:
+ {
+ if (attr == NULL)
+ DIE ("No Dwarf_Attribute given, but DW_OP_implicit_value used");
+ else
+ {
+#if ! _ELFUTILS_PREREQ(0,142)
+ Dwarf_Block block;
+ Dwarf_Op *op = (Dwarf_Op *) &expr[i];
+ if (dwarf_getlocation_implicit_value (attr, op, &block) != 0)
+ DIE("DW_OP_implicit_value, dwarf_getlocation_implicit_value failed");
+ else
+#endif
+ DIE ("DW_OP_implicit_value not supported");
+ }
+ break;
+ }
+
case DW_OP_call_frame_cfa:
// We pick this out when processing DW_AT_frame_base in
// so it really shouldn't turn up here.
@@ -576,6 +598,7 @@ location_from_address (struct obstack *pool,
void (*emit_address) (void *fail_arg,
struct obstack *, Dwarf_Addr),
int indent, Dwarf_Addr dwbias,
+ Dwarf_Attribute *attr,
const Dwarf_Op *expr, size_t len, Dwarf_Addr address,
struct location **input, Dwarf_Attribute *fb_attr,
const Dwarf_Op *cfa_ops)
@@ -589,7 +612,7 @@ location_from_address (struct obstack *pool,
bool need_fb = false;
size_t loser;
- const char *failure = translate (pool, indent + 1, dwbias, expr, len,
+ const char *failure = translate (pool, indent + 1, dwbias, attr, expr, len,
*input, &need_fb, &loser, loc);
if (failure != NULL)
return lose (loc, failure, expr, loser);
@@ -637,7 +660,7 @@ location_from_address (struct obstack *pool,
fb_ops = fb_expr;
loc->frame_base = alloc_location (pool, loc);
- failure = translate (pool, indent + 1, dwbias, fb_ops, fb_len, NULL,
+ failure = translate (pool, indent + 1, dwbias, attr, fb_ops, fb_len, NULL,
NULL, &loser, loc->frame_base);
if (failure != NULL)
return lose (loc, failure, fb_expr, loser);
@@ -653,11 +676,11 @@ location_from_address (struct obstack *pool,
/* Translate a location starting from a non-address "on the top of the
stack". The *INPUT location is a register name or noncontiguous
object specification, and this expression wants to find the "address"
- of an object relative to that "address". */
+ of an object (or the actual value) relative to that "address". */
static struct location *
location_relative (struct obstack *pool,
- int indent, Dwarf_Addr dwbias,
+ int indent, Dwarf_Addr dwbias, Dwarf_Attribute *attr,
const Dwarf_Op *expr, size_t len, Dwarf_Addr address,
struct location **input, Dwarf_Attribute *fb_attr,
const Dwarf_Op *cfa_ops)
@@ -790,7 +813,7 @@ location_relative (struct obstack *pool,
/* This started from a register, but now it's following a pointer.
So we can do the translation starting from address here. */
return location_from_address (pool, NULL, NULL, NULL, indent, dwbias,
- expr, len, address, input, fb_attr,
+ attr, expr, len, address, input, fb_attr,
cfa_ops);
@@ -948,7 +971,7 @@ location_relative (struct obstack *pool,
computations now have an address to start with.
So we can punt to the address computation generator. */
loc = location_from_address (pool, NULL, NULL, NULL,
- indent, dwbias,
+ indent, dwbias, attr,
&expr[i + 1], len - i - 1,
address, input, fb_attr,
cfa_ops);
@@ -1033,6 +1056,7 @@ c_translate_location (struct obstack *pool,
void (*emit_address) (void *fail_arg,
struct obstack *, Dwarf_Addr),
int indent, Dwarf_Addr dwbias, Dwarf_Addr pc_address,
+ Dwarf_Attribute *attr,
const Dwarf_Op *expr, size_t len,
struct location **input, Dwarf_Attribute *fb_attr,
const Dwarf_Op *cfa_ops)
@@ -1046,15 +1070,16 @@ c_translate_location (struct obstack *pool,
This expression will compute starting with that on the stack. */
return location_from_address (pool, fail, fail_arg,
emit_address ?: &default_emit_address,
- indent, dwbias, expr, len, pc_address,
+ indent, dwbias, attr, expr, len, pc_address,
input, fb_attr, cfa_ops);
case loc_noncontiguous:
case loc_register:
/* The starting point is not an address computation, but a
- register. We can only handle limited computations from here. */
- return location_relative (pool, indent, dwbias, expr, len, pc_address,
- input, fb_attr, cfa_ops);
+ register or implicit value. We can only handle limited
+ computations from here. */
+ return location_relative (pool, indent, dwbias, attr, expr, len,
+ pc_address, input, fb_attr, cfa_ops);
default:
abort ();
diff --git a/loc2c.h b/loc2c.h
index 8bc59d29..becf2d85 100644
--- a/loc2c.h
+++ b/loc2c.h
@@ -12,7 +12,9 @@ struct location; /* Opaque */
as the starting location, begin from scratch if *INPUT is null.
If DW_OP_fbreg is used, it may have a subfragment computing from
the FB_ATTR location expression. The call_frame might need to be
- calculated by the cfa_ops for the given pc_address.
+ calculated by the cfa_ops for the given pc_address. If known the
+ locattr provides the attribute from which the locexpr array was
+ retrieved.
On errors, call FAIL, which should not return. Any later errors will use
FAIL and FAIL_ARG from the first c_translate_location call.
@@ -32,6 +34,7 @@ struct location *c_translate_location (struct obstack *,
int indent,
Dwarf_Addr bias,
Dwarf_Addr pc_address,
+ Dwarf_Attribute *attr,
const Dwarf_Op *locexpr,
size_t locexprlen,
struct location **input,