diff options
Diffstat (limited to 'tapset-procfs.cxx')
-rw-r--r-- | tapset-procfs.cxx | 182 |
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); } |