summaryrefslogtreecommitdiffstats
path: root/tapset-procfs.cxx
diff options
context:
space:
mode:
authorDavid Smith <dsmith@redhat.com>2010-02-23 12:48:49 -0600
committerDavid Smith <dsmith@redhat.com>2010-02-23 12:48:49 -0600
commita50de93955fe1272731dccfb3520514a9545f434 (patch)
tree162aba6d10ab730eb1383c71f2745e00ab7cdad9 /tapset-procfs.cxx
parentd6c273473f7bea4d696c95ca48d55ca26e25ab2f (diff)
downloadsystemtap-steved-a50de93955fe1272731dccfb3520514a9545f434.tar.gz
systemtap-steved-a50de93955fe1272731dccfb3520514a9545f434.tar.xz
systemtap-steved-a50de93955fe1272731dccfb3520514a9545f434.zip
PR 10690 (partial fix). Handle '.=' operator in procfs probes.
* tapsets.h (var_expanding_visitor): Add 'valid_ops' and 'op' member variables. * tapsets.cxx (var_expanding_visitor::var_expanding_visitor): Set 'valid_ops' to '='. By default, var_expanding_visitor classes only handle the '=' operator. (var_expanding_visitor::visit_assignment): Remember what operator we're handling. When an operator is found that isn't in the 'valid_ops' set, error. * tapset-procfs.cxx (procfs_var_expanding_visitor::procfs_var_expanding_visitor): Add '.=' to the 'valid_ops' set. (procfs_var_expanding_visitor::visit_target_symbol): Handle the '.=' operator when the target variable is an lvalue.
Diffstat (limited to 'tapset-procfs.cxx')
-rw-r--r--tapset-procfs.cxx65
1 files changed, 51 insertions, 14 deletions
diff --git a/tapset-procfs.cxx b/tapset-procfs.cxx
index c4eb54f3..d05ab52c 100644
--- a/tapset-procfs.cxx
+++ b/tapset-procfs.cxx
@@ -74,9 +74,7 @@ public:
struct procfs_var_expanding_visitor: public var_expanding_visitor
{
procfs_var_expanding_visitor(systemtap_session& s, const string& pn,
- string path, bool write_probe):
- sess (s), probe_name (pn), path (path), write_probe (write_probe),
- target_symbol_seen (false) {}
+ string path, bool write_probe);
systemtap_session& sess;
string probe_name;
@@ -342,6 +340,18 @@ procfs_derived_probe_group::emit_module_exit (systemtap_session& s)
}
+procfs_var_expanding_visitor::procfs_var_expanding_visitor (systemtap_session& s,
+ const string& pn,
+ string path,
+ bool write_probe):
+ sess (s), probe_name (pn), path (path), write_probe (write_probe),
+ target_symbol_seen (false)
+{
+ // procfs probes can also handle '.='.
+ valid_ops.insert (".=");
+}
+
+
void
procfs_var_expanding_visitor::visit_target_symbol (target_symbol* e)
{
@@ -371,21 +381,48 @@ procfs_var_expanding_visitor::visit_target_symbol (target_symbol* e)
embeddedcode *ec = new embeddedcode;
ec->tok = e->tok;
- string fname = (string(lvalue ? "_procfs_value_set" : "_procfs_value_get"));
+ string fname;
string locvalue = "CONTEXT->data";
if (! lvalue)
- ec->code = string(" struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string("); /* pure */\n")
+ {
+ if (*op == "=")
+ {
+ fname = "_procfs_value_get";
+ ec->code = string(" struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string("); /* pure */\n")
- + string(" _stp_copy_from_user(THIS->__retvalue, data->buffer, data->count);\n")
- + string(" THIS->__retvalue[data->count] = '\\0';\n");
- else
- ec->code = string("int bytes = 0;\n")
- + string(" struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string(");\n")
- + string(" bytes = strnlen(THIS->value, MAXSTRINGLEN - 1);\n")
- + string(" memcpy((void *)data->buffer, THIS->value, bytes);\n")
- + string(" data->buffer[bytes] = '\\0';\n")
- + string(" data->count = bytes;\n");
+ + string(" _stp_copy_from_user(THIS->__retvalue, data->buffer, data->count);\n")
+ + string(" THIS->__retvalue[data->count] = '\\0';\n");
+ }
+ else
+ {
+ throw semantic_error ("Operator-assign expressions on procfs write"
+ " target variables not implemented", e->tok);
+ }
+ }
+ else // lvalue
+ {
+ if (*op == "=")
+ {
+ fname = "_procfs_value_set";
+ ec->code = string("struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string(");\n")
+ + string(" strlcpy(data->buffer, THIS->value, MAXSTRINGLEN);\n")
+ + string(" data->count = strlen(data->buffer);\n");
+ }
+ else if (*op == ".=")
+ {
+ fname = "_procfs_value_append";
+ ec->code = string("struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string(");\n")
+ + string(" strlcat(data->buffer, THIS->value, MAXSTRINGLEN);\n")
+ + string(" data->count = strlen(data->buffer);\n");
+ }
+ else
+ {
+ throw semantic_error ("Only the following assign operators are"
+ " implemented on procfs read target variables:"
+ " '=', '.='", e->tok);
+ }
+ }
fdecl->name = fname;
fdecl->body = ec;