From a50de93955fe1272731dccfb3520514a9545f434 Mon Sep 17 00:00:00 2001 From: David Smith Date: Tue, 23 Feb 2010 12:48:49 -0600 Subject: 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. --- tapset-procfs.cxx | 65 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 14 deletions(-) (limited to 'tapset-procfs.cxx') 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; -- cgit From 4d3c480990cdbbd3e0c405be03a195a040b4dc4a Mon Sep 17 00:00:00 2001 From: David Smith Date: Tue, 23 Feb 2010 14:40:18 -0600 Subject: Removed rvalue operator check. * tapset-procfs.cxx (procfs_var_expanding_visitor::visit_target_symbol): Removed unneeded rvalue operator check. --- tapset-procfs.cxx | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'tapset-procfs.cxx') diff --git a/tapset-procfs.cxx b/tapset-procfs.cxx index d05ab52c..1926582b 100644 --- a/tapset-procfs.cxx +++ b/tapset-procfs.cxx @@ -386,19 +386,11 @@ procfs_var_expanding_visitor::visit_target_symbol (target_symbol* e) if (! lvalue) { - if (*op == "=") - { - fname = "_procfs_value_get"; - ec->code = string(" struct _stp_procfs_data *data = (struct _stp_procfs_data *)(") + locvalue + string("); /* pure */\n") + 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 - { - throw semantic_error ("Operator-assign expressions on procfs write" - " target variables not implemented", e->tok); - } + + string(" _stp_copy_from_user(THIS->__retvalue, data->buffer, data->count);\n") + + string(" THIS->__retvalue[data->count] = '\\0';\n"); } else // lvalue { -- cgit