summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-03-19 16:23:02 -0700
committerJosh Stone <jistone@redhat.com>2009-03-19 16:28:49 -0700
commitad370dccd460ebfc66f21d3d16f44807d789484f (patch)
tree7cec1667920e85b8ccaaacbeb3a45e1a2ea93896
parentc15b608343c5a0de8558b31650ed001177fb3892 (diff)
downloadsystemtap-steved-ad370dccd460ebfc66f21d3d16f44807d789484f.tar.gz
systemtap-steved-ad370dccd460ebfc66f21d3d16f44807d789484f.tar.xz
systemtap-steved-ad370dccd460ebfc66f21d3d16f44807d789484f.zip
PR9960: support tracepoint struct/union value arg
If a tracepoint arg is a structure or union that is passed by value, then this takes the address of the parameter so it can be used like a pointer in the rest of our code.
-rw-r--r--tapsets.cxx16
1 files changed, 13 insertions, 3 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 103c39fa..a8653d8a 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -9242,7 +9242,7 @@ mark_builder::build(systemtap_session & sess,
struct tracepoint_arg
{
- string name, c_type;
+ string name, c_type, typecast;
bool usable, used, isptr;
Dwarf_Die type_die;
tracepoint_arg(): usable(false), used(false), isptr(false) {}
@@ -9345,6 +9345,9 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e)
if (lvalue && (!dw.sess.guru_mode || e->components.empty()))
throw semantic_error("write to tracepoint variable '" + e->base_name
+ "' not permitted", e->tok);
+ // XXX: if a struct/union arg is passed by value, then writing to its fields
+ // is also meaningless until you dereference past a pointer member. It's
+ // harder to detect and prevent that though...
if (e->components.empty())
{
@@ -9685,6 +9688,14 @@ resolve_tracepoint_arg_type(tracepoint_arg& arg)
if (dwarf_attr_integrate(&arg.type_die, DW_AT_type, &type_attr)
&& dwarf_formref_die(&type_attr, &arg.type_die))
arg.isptr = true;
+ arg.typecast = "(intptr_t)";
+ return true;
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ // for structs/unions which are passed by value, we turn it into
+ // a pointer that can be dereferenced.
+ arg.isptr = true;
+ arg.typecast = "(intptr_t)&";
return true;
default:
// should we consider other types too?
@@ -9787,8 +9798,7 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s)
{
s.op->newline() << "c->locals[0]." << p->name << ".__tracepoint_arg_"
<< p->args[j].name << " = (int64_t)";
- if (p->args[j].isptr)
- s.op->line() << "(intptr_t)";
+ s.op->line() << p->args[j].typecast;
s.op->line() << "__tracepoint_arg_" << p->args[j].name << ";";
}
s.op->newline() << p->name << " (c);";