summaryrefslogtreecommitdiffstats
path: root/tapset-procfs.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tapset-procfs.cxx')
-rw-r--r--tapset-procfs.cxx182
1 files changed, 95 insertions, 87 deletions
diff --git a/tapset-procfs.cxx b/tapset-procfs.cxx
index 1926582b..517a4a22 100644
--- a/tapset-procfs.cxx
+++ b/tapset-procfs.cxx
@@ -1,5 +1,5 @@
// tapset for procfs
-// Copyright (C) 2005-2009 Red Hat Inc.
+// Copyright (C) 2005-2010 Red Hat Inc.
// Copyright (C) 2005-2007 Intel Corporation.
// Copyright (C) 2008 James.Bottomley@HansenPartnership.com
//
@@ -355,100 +355,108 @@ procfs_var_expanding_visitor::procfs_var_expanding_visitor (systemtap_session& s
void
procfs_var_expanding_visitor::visit_target_symbol (target_symbol* e)
{
- assert(e->base_name.size() > 0 && e->base_name[0] == '$');
-
- if (e->base_name != "$value")
- throw semantic_error ("invalid target symbol for procfs probe, $value expected",
- e->tok);
-
- e->assert_no_components("procfs");
-
- bool lvalue = is_active_lvalue(e);
- if (write_probe && lvalue)
- throw semantic_error("procfs $value variable is read-only in a procfs write probe", e->tok);
+ try
+ {
+ assert(e->base_name.size() > 0 && e->base_name[0] == '$');
+
+ if (e->base_name != "$value")
+ throw semantic_error ("invalid target symbol for procfs probe, $value expected",
+ e->tok);
+
+ e->assert_no_components("procfs");
+
+ bool lvalue = is_active_lvalue(e);
+ if (write_probe && lvalue)
+ throw semantic_error("procfs $value variable is read-only in a procfs write probe", e->tok);
else if (! write_probe && ! lvalue)
throw semantic_error("procfs $value variable cannot be read in a procfs read probe", e->tok);
-
- if (e->addressof)
- throw semantic_error("cannot take address of procfs variable", e->tok);
-
- // Remember that we've seen a target variable.
- target_symbol_seen = true;
-
- // Synthesize a function.
- functiondecl *fdecl = new functiondecl;
- fdecl->tok = e->tok;
- embeddedcode *ec = new embeddedcode;
- ec->tok = e->tok;
-
- string fname;
- string locvalue = "CONTEXT->data";
-
- if (! lvalue)
- {
- 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 // lvalue
- {
- if (*op == "=")
+
+ if (e->addressof)
+ throw semantic_error("cannot take address of procfs variable", e->tok);
+
+ // Remember that we've seen a target variable.
+ target_symbol_seen = true;
+
+ // Synthesize a function.
+ functiondecl *fdecl = new functiondecl;
+ fdecl->tok = e->tok;
+ embeddedcode *ec = new embeddedcode;
+ ec->tok = e->tok;
+
+ string fname;
+ string locvalue = "CONTEXT->data";
+
+ if (! lvalue)
{
- 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_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 // lvalue
{
- 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
+ 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;
+ fdecl->type = pe_string;
+
+ if (lvalue)
{
- throw semantic_error ("Only the following assign operators are"
- " implemented on procfs read target variables:"
- " '=', '.='", e->tok);
- }
- }
-
- fdecl->name = fname;
- fdecl->body = ec;
- fdecl->type = pe_string;
-
- if (lvalue)
- {
- // Modify the fdecl so it carries a single pe_string formal
- // argument called "value".
-
- vardecl *v = new vardecl;
- v->type = pe_string;
- v->name = "value";
- v->tok = e->tok;
- fdecl->formal_args.push_back(v);
+ // Modify the fdecl so it carries a single pe_string formal
+ // argument called "value".
+
+ vardecl *v = new vardecl;
+ v->type = pe_string;
+ v->name = "value";
+ v->tok = e->tok;
+ fdecl->formal_args.push_back(v);
+ }
+ sess.functions[fdecl->name]=fdecl;
+
+ // Synthesize a functioncall.
+ functioncall* n = new functioncall;
+ n->tok = e->tok;
+ n->function = fname;
+ n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
+
+ if (lvalue)
+ {
+ // Provide the functioncall to our parent, so that it can be
+ // used to substitute for the assignment node immediately above
+ // us.
+ assert(!target_symbol_setter_functioncalls.empty());
+ *(target_symbol_setter_functioncalls.top()) = n;
+ }
+
+ provide (n);
}
- sess.functions[fdecl->name]=fdecl;
-
- // Synthesize a functioncall.
- functioncall* n = new functioncall;
- n->tok = e->tok;
- n->function = fname;
- n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
-
- if (lvalue)
+ catch (const semantic_error &er)
{
- // Provide the functioncall to our parent, so that it can be
- // used to substitute for the assignment node immediately above
- // us.
- assert(!target_symbol_setter_functioncalls.empty());
- *(target_symbol_setter_functioncalls.top()) = n;
+ e->chain (new semantic_error(er));
+ provide (e);
}
-
- provide (n);
}