From 39b375aeafc43e00ecf68d0151e7df0597139949 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Sat, 19 Dec 2009 12:18:00 -0500 Subject: Recalculate sem address when tid changes. * tapsets.cxx (uprobe_derived_probe_group::emit_module_decls): Emit sdt_sem_tid. Use it to recalculate sem address when task changes. --- tapsets.cxx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 007aea6d..a97fa5a2 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -4672,6 +4672,10 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) for (unsigned i =0; iline() << "0,"; s.op->line() << "0};"; + s.op->newline() << "unsigned long sdt_sem_tid [] = {"; + for (unsigned i =0; iline() << "0,"; + s.op->line() << "0};"; s.op->newline() << "static const struct stap_uprobe_spec {"; // NB: read-only structure s.op->newline(1) << "unsigned tfi;"; // index into stap_uprobe_finders[] s.op->newline() << "unsigned return_p:1;"; @@ -4815,17 +4819,19 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) // was full (registration; MAXUPROBES) or that no matching entry was // found (unregistration; should not happen). - s.op->newline() << "if (sups->sdt_sem_offset && sdt_sem_address[spec_index] == 0) {"; + s.op->newline() << "if (sups->sdt_sem_offset && (sdt_sem_tid[spec_index] != tsk->tgid || sdt_sem_address[spec_index] == 0)) {"; s.op->indent(1); // If the probe is in the executable itself, the offset *is* the address. s.op->newline() << "if (vm_flags & VM_EXECUTABLE) {"; s.op->indent(1); s.op->newline() << "sdt_sem_address[spec_index] = relocation + sups->sdt_sem_offset;"; + s.op->newline() << "sdt_sem_tid[spec_index] = tsk->tgid;"; s.op->newline(-1) << "}"; // If the probe is in a .so, we have to calculate the address. s.op->newline() << "else {"; s.op->indent(1); s.op->newline() << "sdt_sem_address[spec_index] = (relocation - offset) + sups->sdt_sem_offset;"; + s.op->newline() << "sdt_sem_tid[spec_index] = tsk->tgid;"; s.op->newline(-1) << "}"; s.op->newline(-1) << "}"; // sdt_sem_offset -- cgit From b5a0dd413a3e4f521df7febca6b88f0ec6b9ff36 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Fri, 18 Dec 2009 12:20:52 -0500 Subject: PR10601 part 1: i386 and x86-64 regset for dwarf fetch/store_register()s * runtime/loc2c-runtime.h (fetch_register, store_register): forked into k_ (kernel) and u_ (user) varieties. Implement i386 and x86_64 in terms of regset.h; fall back to k_* for other architectures. * tapsets.cxx: (*::visit_target_symbol): Emit macros to map loc2c's fetch/store_register to loc2c-runtime's k_ or u_ as appopriate. --- tapsets.cxx | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index a97fa5a2..cfd21bff 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -2400,9 +2400,14 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) try { + // PR10601: adapt to kernel-vs-userspace loc2c-runtime + ec->code += "\n#define fetch_register " + string(q.has_process?"u":"k") + "_fetch_register\n"; + ec->code += "#define store_register " + string(q.has_process?"u":"k") + "_store_register\n"; + ec->code += "#define deref " + string(q.has_process?"u":"k") + "_deref\n"; + if (q.has_return && (e->base_name == "$return")) { - ec->code = q.dw.literal_stmt_for_return (scope_die, + ec->code += q.dw.literal_stmt_for_return (scope_die, addr, e, lvalue, @@ -2410,7 +2415,7 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) } else { - ec->code = q.dw.literal_stmt_for_local (getscopes(e), + ec->code += q.dw.literal_stmt_for_local (getscopes(e), addr, e->base_name.substr(1), e, @@ -2422,6 +2427,11 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) ec->code += "/* pure */"; ec->code += "/* unprivileged */"; + + // PR10601 + ec->code += "\n#undef fetch_register\n"; + ec->code += "\n#undef store_register\n"; + ec->code += "\n#undef deref\n"; } catch (const semantic_error& er) { @@ -2687,6 +2697,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) // split the module string by ':' for alternatives vector modules; tokenize(e->module, modules, ":"); + bool userspace_p=false; // PR10601 for (unsigned i = 0; code.empty() && i < modules.size(); ++i) { string& module = modules[i]; @@ -2697,7 +2708,8 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) dwflpp* dw; try { - if (! is_user_module (module)) + userspace_p=is_user_module (module); + if (! userspace_p) { // kernel or kernel module target dw = db.get_kern_dw(s, module); @@ -2739,9 +2751,15 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) embeddedcode *ec = new embeddedcode; ec->tok = e->tok; - ec->code = code; fdecl->body = ec; + // PR10601: adapt to kernel-vs-userspace loc2c-runtime + ec->code += "\n#define fetch_register " + string(userspace_p?"u":"k") + "_fetch_register\n"; + ec->code += "#define store_register " + string(userspace_p?"u":"k") + "_store_register\n"; + ec->code += "#define deref " + string(userspace_p?"u":"k") + "_deref\n"; + + ec->code += code; + // Give the fdecl an argument for the pointer we're trying to cast vardecl *v1 = new vardecl; v1->type = pe_long; @@ -2781,6 +2799,11 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) ec->code += "/* unprivileged */"; + // PR10601 + ec->code += "\n#undef fetch_register\n"; + ec->code += "\n#undef store_register\n"; + ec->code += "\n#undef deref\n"; + s.functions[fdecl->name] = fdecl; // Synthesize a functioncall. @@ -5764,9 +5787,14 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) fdecl->name = fname; fdecl->body = ec; + // PR10601: adapt to kernel-vs-userspace loc2c-runtime + ec->code += "\n#define fetch_register k_fetch_register\n"; + ec->code += "#define store_register k_store_register\n"; + ec->code += "#define deref k_deref\n"; + try { - ec->code = dw.literal_stmt_for_pointer (&arg->type_die, e, + ec->code += dw.literal_stmt_for_pointer (&arg->type_die, e, lvalue, fdecl->type); } catch (const semantic_error& er) @@ -5824,6 +5852,11 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) ec->code += "/* unprivileged */"; + // PR10601 + ec->code += "\n#undef fetch_register\n"; + ec->code += "\n#undef store_register\n"; + ec->code += "\n#undef deref\n"; + dw.sess.functions[fdecl->name] = fdecl; // Synthesize a functioncall. -- cgit From a87e40ba65ede2a884e4bce31ba7a1d87e71f981 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sun, 20 Dec 2009 16:54:27 -0500 Subject: PR10601: unfork deref() * runtime/loc2c-runtime.h: Remove k_ vs u_[store_]deref; share instead. * tapsets.cxx: Remove k_ vs u_ redirection for *deref(). --- tapsets.cxx | 6 ------ 1 file changed, 6 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index cfd21bff..a5e2c7a0 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -2403,7 +2403,6 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) // PR10601: adapt to kernel-vs-userspace loc2c-runtime ec->code += "\n#define fetch_register " + string(q.has_process?"u":"k") + "_fetch_register\n"; ec->code += "#define store_register " + string(q.has_process?"u":"k") + "_store_register\n"; - ec->code += "#define deref " + string(q.has_process?"u":"k") + "_deref\n"; if (q.has_return && (e->base_name == "$return")) { @@ -2431,7 +2430,6 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) // PR10601 ec->code += "\n#undef fetch_register\n"; ec->code += "\n#undef store_register\n"; - ec->code += "\n#undef deref\n"; } catch (const semantic_error& er) { @@ -2756,7 +2754,6 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) // PR10601: adapt to kernel-vs-userspace loc2c-runtime ec->code += "\n#define fetch_register " + string(userspace_p?"u":"k") + "_fetch_register\n"; ec->code += "#define store_register " + string(userspace_p?"u":"k") + "_store_register\n"; - ec->code += "#define deref " + string(userspace_p?"u":"k") + "_deref\n"; ec->code += code; @@ -2802,7 +2799,6 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) // PR10601 ec->code += "\n#undef fetch_register\n"; ec->code += "\n#undef store_register\n"; - ec->code += "\n#undef deref\n"; s.functions[fdecl->name] = fdecl; @@ -5790,7 +5786,6 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) // PR10601: adapt to kernel-vs-userspace loc2c-runtime ec->code += "\n#define fetch_register k_fetch_register\n"; ec->code += "#define store_register k_store_register\n"; - ec->code += "#define deref k_deref\n"; try { @@ -5855,7 +5850,6 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) // PR10601 ec->code += "\n#undef fetch_register\n"; ec->code += "\n#undef store_register\n"; - ec->code += "\n#undef deref\n"; dw.sess.functions[fdecl->name] = fdecl; -- cgit From ea549ffc2915aa58861637472b12196222673fa2 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Mon, 21 Dec 2009 13:02:19 +0100 Subject: PR11015 Support shared library reloading (in different processes) * runtime/task_finder_vma.c (stap_remove_vma_map_info): Return negative status on failure. (stap_find_vma_map_info): Likewise. (stap_find_vma_map_info_user): New function. (stap_drop_vma_maps): New function. * runtime/sym.h (addr): Renamed to static_addr, to store addresses for sections which are always mapped at the same address. (_stp_module_relocate): Add extra struct task_struct *tsk argument. * runtime/sym.c (_stp_tf_exec_cb): New callback, calls stap_drop_vma_maps. (_stp_tf_mmap_cb): Don't store address in module.section, but call stap_add_vma_map_info() per tsk->group_leader for matched module. Don't register empty/null modules. (_stp_module_relocate): Take extra struct task_struct *tsk argument, cache last tsk used. Only use section->static_addr for none dynamic modules. Use stap_find_vma_map_info_user() to locate dynamic modules. (_stp_mod_sec_lookup): Add extra argument unsigned long *rel_addr to optionally store relative address when module/section found. (_stp_kallsyms_lookup): Use _stp_mod_sec_lookup to find relative address. (_stp_sym_init): Register _stp_tf_exec_cb in stap_task_finder_target. Add error check to see if task finder could be initialized. * dwflpp.cxx (emit_address): Pass NULL for kernel/modules and current for user tasks to _stp_module_relocate. * runtime/transport/symbols.c (_stp_do_relocation): Set new static_addr _stp_section field. * runtime/unwind.c (adjustStartLoc): Take new struct task_struct *tsk argument and pass to stap_find_vma_map_info_user and _stp_module_relocate to find adjusted addr. (_stp_search_unwind_hdr): Pass through struct task_struct *tsk. (unwind_frame): Likewise. * tapset/context-symbols.stp (probemod): Add NULL to _stp_mod_sec_lookup call to indicate we aren't interested in relative address. * tapsets.cxx (dwarf_derived_probe_group::emit_module_init): Pass NULL to _stp_module_relocate to indicate kernel/module address. --- tapsets.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index a5e2c7a0..e14cc496 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -3429,7 +3429,7 @@ dwarf_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {"; s.op->newline(1) << "struct stap_dwarf_probe *sdp = & stap_dwarf_probes[i];"; s.op->newline() << "struct stap_dwarf_kprobe *kp = & stap_dwarf_kprobes[i];"; - s.op->newline() << "unsigned long relocated_addr = _stp_module_relocate (sdp->module, sdp->section, sdp->address);"; + s.op->newline() << "unsigned long relocated_addr = _stp_module_relocate (sdp->module, sdp->section, sdp->address, NULL);"; s.op->newline() << "if (relocated_addr == 0) continue;"; // quietly; assume module is absent s.op->newline() << "probe_point = sdp->pp;"; // for error messages s.op->newline() << "if (sdp->return_p) {"; -- cgit