diff options
author | Stan Cox <scox@redhat.com> | 2009-06-08 21:57:44 -0400 |
---|---|---|
committer | Stan Cox <scox@redhat.com> | 2009-06-08 21:57:44 -0400 |
commit | ad002306b50c6cc3c3601fac31dfe3ecf23749fb (patch) | |
tree | 02636a51560f9e998fa922466b018333d0d5fe26 | |
parent | f517ee24c58413f7de89ede71c728579c12ace5b (diff) | |
download | systemtap-steved-ad002306b50c6cc3c3601fac31dfe3ecf23749fb.tar.gz systemtap-steved-ad002306b50c6cc3c3601fac31dfe3ecf23749fb.tar.xz systemtap-steved-ad002306b50c6cc3c3601fac31dfe3ecf23749fb.zip |
* tapsets.cxx (probe_table): Make mark_name and sess refs.
(probe_table::get_next_probe): Dissect using struct probe_table.
(sdt_var_expanding_visitor): Use lex_cast.
(dwarf_builder::build): Copy probe and location for TOK_MARK cases.
Call derive_probes for kprobe and utrace cases.
-rw-r--r-- | tapsets.cxx | 230 |
1 files changed, 115 insertions, 115 deletions
diff --git a/tapsets.cxx b/tapsets.cxx index d8fe8f8e..b684adc2 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -663,19 +663,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; @@ -684,11 +684,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; @@ -698,12 +699,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))) { @@ -716,18 +713,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); @@ -738,9 +731,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; @@ -755,14 +745,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) { @@ -772,28 +768,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" @@ -2353,9 +2343,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; @@ -3225,13 +3215,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) { @@ -3249,7 +3238,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; @@ -3261,34 +3250,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 @@ -3325,10 +3311,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; @@ -3336,22 +3324,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) @@ -3368,28 +3365,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; @@ -3398,22 +3403,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; @@ -3423,48 +3420,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; @@ -3473,19 +3478,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; @@ -3508,7 +3508,7 @@ dwarf_builder::build(systemtap_session & sess, dw->module = 0; } - + dwarf_query q(sess, base, location, *dw, parameters, finished_results); @@ -5427,7 +5427,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) |