summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx236
1 files changed, 118 insertions, 118 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 08de4050..265fe939 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -666,19 +666,19 @@ struct dwarf_builder: public derived_probe_builder
public:
enum probe_types
{
- uprobe_type = 0x31425250,
- kprobe_type = 0x32425250,
- utrace_type = 0x33425250,
+ uprobe_type = 0x31425250, // "PRB1"
+ kprobe_type = 0x32425250, // "PRB2"
+ utrace_type = 0x33425250, // "PRB3"
} probe_type;
- bool have_probes;
__uint64_t probe_arg;
- string mark_name;
+ string & mark_name;
string probe_name;
- probe_table(systemtap_session & sess, dwflpp* dw, probe_point* location);
+ probe_table(string & mark_name, systemtap_session & sess, dwflpp * dw, probe_point * location);
bool get_next_probe();
private:
- systemtap_session sess;
+ bool have_probes;
+ systemtap_session & sess;
dwflpp* dw;
probe_point* location;
Elf_Data *pdata;
@@ -687,11 +687,12 @@ struct dwarf_builder: public derived_probe_builder
};
};
-dwarf_builder::probe_table::probe_table(systemtap_session & sess, dwflpp* dw, probe_point* location)
+dwarf_builder::probe_table::probe_table(string& mark_name, systemtap_session & sess, dwflpp* dw, probe_point* location):
+ mark_name(mark_name), sess(sess), dw(dw), location(location)
{
Elf* elf;
GElf_Shdr shdr_mem;
- GElf_Shdr *shdr = NULL;
+ GElf_Shdr *shdr;
Dwarf_Addr bias;
size_t shstrndx;
@@ -701,12 +702,8 @@ dwarf_builder::probe_table::probe_table(systemtap_session & sess, dwflpp* dw, pr
dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
- this->dw = dw;
- this->sess = sess;
- this->location = location;
- this->mark_name = location->components[1]->arg->tok->content;
have_probes = false;
-
+
// Is there a .probes section?
while ((probe_scn = elf_nextscn (elf, probe_scn)))
{
@@ -719,18 +716,14 @@ dwarf_builder::probe_table::probe_table(systemtap_session & sess, dwflpp* dw, pr
break;
}
}
-
- if (!have_probes)
- return;
-
+
// Older versions put .probes section in the debuginfo dwarf file,
// so check if it actually exists, if not take the main elf file
- if (shdr->sh_type == SHT_NOBITS)
+ if (have_probes && shdr->sh_type == SHT_NOBITS)
{
elf = dwfl_module_getelf (dw->module, &bias);
dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx));
probe_scn = NULL;
- have_probes = false;
while ((probe_scn = elf_nextscn (elf, probe_scn)))
{
shdr = gelf_getshdr (probe_scn, &shdr_mem);
@@ -741,9 +734,6 @@ dwarf_builder::probe_table::probe_table(systemtap_session & sess, dwflpp* dw, pr
}
}
- if (!have_probes)
- return;
-
pdata = elf_getdata_rawchunk (elf, shdr->sh_offset, shdr->sh_size, ELF_T_BYTE);
probe_scn_offset = 0;
probe_scn_addr = shdr->sh_addr;
@@ -758,14 +748,20 @@ dwarf_builder::probe_table::get_next_probe()
{
if (! have_probes)
return false;
-
+
// Extract probe info from the .probes section
if (sess.verbose > 3)
clog << "probe_type == use_uprobe, use statement addr" << endl;
-
+
while (probe_scn_offset < pdata->d_size)
{
- probe_type = (enum probe_types)*((int*)((char*)pdata->d_buf + probe_scn_offset));
+ struct probe_entry
+ {
+ __uint64_t name;
+ __uint64_t arg;
+ } *pbe;
+ __uint32_t *type = (__uint32_t*) ((char*)pdata->d_buf + probe_scn_offset);
+ probe_type = (enum probe_types)*type;
if (probe_type != uprobe_type && probe_type != kprobe_type
&& probe_type != utrace_type)
{
@@ -775,28 +771,22 @@ dwarf_builder::probe_table::get_next_probe()
if (sess.verbose > 5)
clog << "got unknown probe_type: 0x" << hex << probe_type
<< dec << endl;
- probe_scn_offset += sizeof(int);
+ probe_scn_offset += sizeof(__uint32_t);
continue;
}
- probe_scn_offset += sizeof(int);
- if (probe_scn_offset % (sizeof(__uint64_t)))
- probe_scn_offset += sizeof(__uint64_t) - (probe_scn_offset % sizeof(__uint64_t));
-
- probe_name = ((char*)((long)(pdata->d_buf) + (long)(*((long*)((char*)pdata->d_buf + probe_scn_offset)) - probe_scn_addr)));
- probe_scn_offset += sizeof(void*);
- if (probe_scn_offset % (sizeof(__uint64_t)))
- probe_scn_offset += sizeof(__uint64_t) - (probe_scn_offset % sizeof(__uint64_t));
- probe_arg = *((__uint64_t*)((char*)pdata->d_buf + probe_scn_offset));
+ probe_scn_offset += sizeof(__uint32_t);
+ probe_scn_offset += probe_scn_offset % sizeof(__uint64_t);
+ pbe = (struct probe_entry*) ((char*)pdata->d_buf + probe_scn_offset);
+ probe_name = (char*)((char*)pdata->d_buf + pbe->name - (char*)probe_scn_addr);
+ probe_arg = pbe->arg;
if (sess.verbose > 4)
clog << "saw .probes " << probe_name
<< "@0x" << hex << probe_arg << dec << endl;
-
- if (probe_scn_offset % (sizeof(__uint64_t)*2))
- probe_scn_offset = (probe_scn_offset + sizeof(__uint64_t)*2) - (probe_scn_offset % (sizeof(__uint64_t)*2));
- if ((strcmp (mark_name.c_str(), probe_name.c_str()) == 0)
- || (dw->name_has_wildcard (mark_name.c_str())
- && dw->function_name_matches_pattern
- (probe_name.c_str(), mark_name.c_str())))
+
+ probe_scn_offset += sizeof (struct probe_entry);
+ if ((mark_name == probe_name)
+ || (dw->name_has_wildcard (mark_name)
+ && dw->function_name_matches_pattern (probe_name, mark_name)))
{
if (sess.verbose > 3)
clog << "found probe_name" << probe_name << " at 0x"
@@ -1779,13 +1769,13 @@ query_module (Dwfl_Module *mod,
// If we have enough information in the pattern to skip a module and
// the module does not match that information, return early.
if (!q->dw.module_name_matches(q->module_val))
- return DWARF_CB_OK;
+ return pending_interrupts ? DWARF_CB_ABORT : DWARF_CB_OK;
// Don't allow module("*kernel*") type expressions to match the
// elfutils module "kernel", which we refer to in the probe
// point syntax exclusively as "kernel.*".
if (q->dw.module_name == TOK_KERNEL && ! q->has_kernel)
- return DWARF_CB_OK;
+ return pending_interrupts ? DWARF_CB_ABORT : DWARF_CB_OK;
if (mod)
validate_module_elf(mod, name, q);
@@ -1813,7 +1803,7 @@ query_module (Dwfl_Module *mod,
// If we know that there will be no more matches, abort early.
- if (q->dw.module_name_final_match(q->module_val))
+ if (q->dw.module_name_final_match(q->module_val) || pending_interrupts)
return DWARF_CB_ABORT;
else
return DWARF_CB_OK;
@@ -2356,9 +2346,9 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e)
saveme->chain = e->saved_conversion_error;
e->saved_conversion_error = saveme;
}
- else
+ else
{
- // Upon user request for ignoring context, the symbol is replaced
+ // Upon user request for ignoring context, the symbol is replaced
// with a literal 0 and a warning message displayed
literal_number* ln_zero = new literal_number (0);
ln_zero->tok = e->tok;
@@ -3230,13 +3220,12 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e)
provide(e);
return;
}
-
+
bool lvalue = is_active_lvalue(e);
string argname = e->base_name.substr(1);
functioncall *fc = new functioncall;
- const char *argno_str = argname.substr(3).c_str();
- int argno = atoi(argno_str); // first arg is "hidden" probe name
+ int argno = lex_cast<int>(argname.substr(3));
if (arg_count < 6)
{
@@ -3254,7 +3243,7 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e)
binary_expression *be = new binary_expression;
be->tok = e->tok;
functioncall *get_arg1 = new functioncall;
- get_arg1->function = "ulong_arg";
+ get_arg1->function = "pointer_arg";
get_arg1->tok = e->tok;
literal_number* num = new literal_number(2);
num->tok = e->tok;
@@ -3266,34 +3255,31 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e)
be->right = inc;
fc->args.push_back(be);
}
-
+
if (lvalue)
*(target_symbol_setter_functioncalls.top()) = fc;
+ if (e->components.empty())
+ {
+ provide(fc);
+ return;
+ }
cast_op *cast = new cast_op;
cast->base_name = "@cast";
cast->tok = e->tok;
cast->operand = fc;
cast->components = e->components;
- char *arg_type;
- if (asprintf (&arg_type, "%s_arg%d", probe_name.c_str(), argno) == -1)
- return;
- cast->type = arg_type;
+ cast->type = probe_name + "_arg" + lex_cast<string>(argno);
string sdt_include_path = "";
for (unsigned int i = 0; i < dw.sess.args.size(); i++)
if (dw.sess.args[i].find("isdt=") == 0)
sdt_include_path = dw.sess.args[i].substr(5);
- if (asprintf (&arg_type, "<%s>", sdt_include_path.c_str()) == -1)
- return;
- cast->module = arg_type;
+ cast->module = "<" + sdt_include_path + ">";
dwarf_builder *db = new dwarf_builder();
dwarf_cast_expanding_visitor *v = new dwarf_cast_expanding_visitor(this->dw.sess, *db);
v->visit_cast_op(cast);
- if (cast->components.empty())
- provide(fc);
- else
- provide(cast);
+ provide(cast);
}
void
@@ -3330,10 +3316,12 @@ dwarf_builder::build(systemtap_session & sess,
if (((probe_point::component*)(location->components[1]))->functor == TOK_MARK)
{
- probe_table probe_table(sess, dw, location);
+ string mark_name;
+ assert (get_param(parameters, TOK_MARK, mark_name));
+ probe_table probe_table(mark_name, sess, dw, location);
if (! probe_table.get_next_probe())
return;
-
+
if (sess.verbose > 3)
clog << "TOK_MARK: " << probe_table.mark_name << endl;
@@ -3341,22 +3329,31 @@ dwarf_builder::build(systemtap_session & sess,
{
do
{
- const token* sv_tok = location->components[1]->arg->tok;
- location->components[1]->functor = TOK_STATEMENT;
- location->components[1]->arg = new literal_number((long)probe_table.probe_arg);
- location->components[1]->arg->tok = sv_tok;
- ((literal_map_t&)parameters)[TOK_STATEMENT] = location->components[1]->arg;
+ probe *new_base = new probe;
+ *new_base = *base;
+
+ new_base->body = deep_copy_visitor::deep_copy(base->body);
+ probe_point *new_location = new probe_point;
+ *new_location = *location;
+ new_base->locations.clear();
+
+ const token* sv_tok = new_location->components[1]->arg->tok;
+ new_location->components[1]->functor = TOK_STATEMENT;
+ new_location->components[1]->arg = new literal_number((long)probe_table.probe_arg);
+ new_location->components[1]->arg->tok = sv_tok;
+ ((literal_map_t&)parameters)[TOK_STATEMENT] = new_location->components[1]->arg;
+ new_base->locations.push_back(new_location);
if (sess.verbose > 3)
clog << "probe_type == use_uprobe, use statement addr: 0x"
<< hex << probe_table.probe_arg << dec << endl;
-
+
// Now expand the local variables in the probe body
sdt_var_expanding_visitor svv (*dw, probe_table.mark_name,
probe_table.probe_arg, false);
- base->body = svv.require (base->body);
+ new_base->body = svv.require (new_base->body);
- dwarf_query q(sess, base, location, *dw, parameters, finished_results);
+ dwarf_query q(sess, new_base, new_location, *dw, parameters, finished_results);
q.has_mark = true;
dw->iterate_over_modules(&query_module, &q);
if (sess.listing_mode)
@@ -3373,28 +3370,36 @@ dwarf_builder::build(systemtap_session & sess,
{
do
{
- block *b = ((block*)(base->body));
+ probe *new_base = new probe;
+ *new_base = *base;
+
+ new_base->body = deep_copy_visitor::deep_copy(base->body);
+ probe_point *new_location = new probe_point;
+ *new_location = *location;
+ new_base->locations.clear();
+
+ block *b = ((block*)(new_base->body));
functioncall *fc = new functioncall;
fc->function = "ulong_arg";
- fc->tok = base->body->tok;
+ fc->tok = new_base->body->tok;
literal_number* num = new literal_number(1);
- num->tok = base->body->tok;
+ num->tok = new_base->body->tok;
fc->args.push_back(num);
functioncall *fcus = new functioncall;
fcus->function = "user_string";
fcus->type = pe_string;
- fcus->tok = base->body->tok;
+ fcus->tok = new_base->body->tok;
fcus->args.push_back(fc);
// Generate: if (arg1 != mark("label")) next;
if_statement *is = new if_statement;
is->thenblock = new next_statement;
is->elseblock = NULL;
- is->tok = base->body->tok;
+ is->tok = new_base->body->tok;
comparison *be = new comparison;
be->op = "!=";
- be->tok = base->body->tok;
+ be->tok = new_base->body->tok;
be->left = fcus;
be->right = new literal_string(probe_table.mark_name);
is->condition = be;
@@ -3403,22 +3408,14 @@ dwarf_builder::build(systemtap_session & sess,
// Now expand the local variables in the probe body
sdt_var_expanding_visitor svv (*dw, probe_table.mark_name,
probe_table.probe_arg, true);
- base->body = svv.require (base->body);
- location->components[0]->functor = "kernel";
- location->components[0]->arg = NULL;
- location->components[1]->functor = "function";
- location->components[1]->arg = new literal_string("*getegid*");
- ((literal_map_t&)parameters).erase(TOK_PROCESS);
- ((literal_map_t&)parameters).erase(TOK_MARK);
- ((literal_map_t&)parameters).insert(pair<string,literal*>("kernel", NULL));
- ((literal_map_t&)parameters).insert(pair<string,literal*>("function", location->components[1]->arg));
-
- dw = get_kern_dw(sess);
-
- dwarf_query q(sess, base, location, *dw, parameters, finished_results);
- q.has_mark = true;
-
- dw->iterate_over_modules(&query_module, &q);
+ new_base->body = svv.require (new_base->body);
+ new_location->components[0]->functor = "kernel";
+ new_location->components[0]->arg = NULL;
+ new_location->components[1]->functor = "function";
+ new_location->components[1]->arg = new literal_string("*getegid*");
+ new_base->locations.push_back(new_location);
+
+ derive_probes(sess, new_base, finished_results);
}
while (probe_table.get_next_probe());
return;
@@ -3428,48 +3425,56 @@ dwarf_builder::build(systemtap_session & sess,
{
do
{
- block *b = ((block*)(base->body));
+ probe *new_base = new probe;
+ *new_base = *base;
+
+ new_base->body = deep_copy_visitor::deep_copy(base->body);
+ probe_point *new_location = new probe_point;
+ *new_location = *location;
+ new_base->locations.clear();
+
+ block *b = ((block*)(new_base->body));
// Generate: if ($syscall != 0xbead) next;
if_statement *issc = new if_statement;
issc->thenblock = new next_statement;
issc->elseblock = NULL;
- issc->tok = base->body->tok;
+ issc->tok = new_base->body->tok;
comparison *besc = new comparison;
besc->op = "!=";
- besc->tok = base->body->tok;
+ besc->tok = new_base->body->tok;
functioncall* n = new functioncall;
- n->tok = base->body->tok;
+ n->tok = new_base->body->tok;
n->function = "_utrace_syscall_nr";
n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
besc->left = n;
literal_number* fake_syscall = new literal_number(0xbead);
- fake_syscall->tok = base->body->tok;
+ fake_syscall->tok = new_base->body->tok;
besc->right = fake_syscall;
issc->condition = besc;
b->statements.insert(b->statements.begin(),(statement*) issc);
functioncall *fc = new functioncall;
fc->function = "ulong_arg";
- fc->tok = base->body->tok;
+ fc->tok = new_base->body->tok;
literal_number* num = new literal_number(1);
- num->tok = base->body->tok;
+ num->tok = new_base->body->tok;
fc->args.push_back(num);
functioncall *fcus = new functioncall;
fcus->function = "user_string";
fcus->type = pe_string;
- fcus->tok = base->body->tok;
+ fcus->tok = new_base->body->tok;
fcus->args.push_back(fc);
// Generate: if (arg1 != mark("label")) next;
if_statement *is = new if_statement;
is->thenblock = new next_statement;
is->elseblock = NULL;
- is->tok = base->body->tok;
+ is->tok = new_base->body->tok;
comparison *be = new comparison;
be->op = "!=";
- be->tok = base->body->tok;
+ be->tok = new_base->body->tok;
be->left = fcus;
be->right = new literal_string(probe_table.mark_name);
is->condition = be;
@@ -3478,19 +3483,14 @@ dwarf_builder::build(systemtap_session & sess,
// Now expand the local variables in the probe body
sdt_var_expanding_visitor svv (*dw, probe_table.mark_name,
probe_table.probe_arg, true);
- base->body = svv.require (base->body);
+ new_base->body = svv.require (new_base->body);
// process("executable").syscall
- location->components[1]->functor = "syscall";
- location->components[1]->arg = NULL;
- ((literal_map_t&)parameters).erase(TOK_MARK);
- ((literal_map_t&)parameters).insert(pair<string,literal*>("syscall", NULL));
-
- // XXX: duplicates code above
- if (! kern_dw)
- dw = get_kern_dw(sess);
+ new_location->components[1]->functor = "syscall";
+ new_location->components[1]->arg = NULL;
+ new_base->locations.push_back(new_location);
- derive_probes(sess, base, finished_results);
+ derive_probes(sess, new_base, finished_results);
}
while (probe_table.get_next_probe());
return;
@@ -3513,7 +3513,7 @@ dwarf_builder::build(systemtap_session & sess,
dw->module = 0;
}
-
+
dwarf_query q(sess, base, location, *dw, parameters, finished_results);
@@ -5432,7 +5432,7 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s)
}
s.op->line() << ") {";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING",
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING",
lex_cast_qstring (*p->sole_location()));
s.op->newline() << "c->marker_name = "
<< lex_cast_qstring (p->tracepoint_name)