diff options
-rw-r--r-- | elaborate.h | 4 | ||||
-rw-r--r-- | runtime/regs-ia64.c | 30 | ||||
-rw-r--r-- | tapsets.cxx | 8 | ||||
-rw-r--r-- | translate.cxx | 3 |
4 files changed, 45 insertions, 0 deletions
diff --git a/elaborate.h b/elaborate.h index c0e35477..afc0c569 100644 --- a/elaborate.h +++ b/elaborate.h @@ -132,6 +132,10 @@ struct derived_probe: public probe // From within unparser::emit_probe, initialized any extra variables // in this probe's context locals. + virtual void emit_probe_local_init (translator_output*) {} + // From within unparser::emit_probe, emit any extra processing block + // for this probe. + public: static void emit_common_header (translator_output* o); // from c_unparser::emit_common_header diff --git a/runtime/regs-ia64.c b/runtime/regs-ia64.c index 66dc60f3..fd8d8ca8 100644 --- a/runtime/regs-ia64.c +++ b/runtime/regs-ia64.c @@ -35,6 +35,32 @@ static void ia64_stap_get_arbsp(struct unw_frame_info *info, void *arg) lp->address = 0; } +/* + * bspcache: get cached unwound address and + * set a probe local cache of the offset of unwound address. + */ +#define bspcache(cache, regs, pp)\ + if(regs) {\ + static unsigned __offset = 0; /* probe local cache */\ + static const char * __pp = NULL; /* reference probe point */\ + unsigned long *bsp;\ + asm volatile("{ flushrs }\n"); /* flushrs for fixing bsp */\ + bsp = (void*)ia64_getreg(_IA64_REG_AR_BSP);\ + if (__offset == 0) {\ + struct ia64_stap_get_arbsp_param pa;\ + pa.ip = regs->cr_iip;\ + unw_init_running(ia64_stap_get_arbsp, &pa);\ + if (pa.address != 0) {\ + __offset = ia64_rse_num_regs(pa.address, bsp)\ + -(regs->cr_ifs & 127);\ + __pp = (const char *)pp;\ + cache = pa.address;\ + }\ + } else if (pp == __pp)\ + cache = ia64_rse_skip_regs(bsp,\ + -(__offset + (regs->cr_ifs & 127)));\ + } + static long ia64_fetch_register(int regno, struct pt_regs *pt_regs, unsigned long **cache) { struct ia64_stap_get_arbsp_param pa; @@ -89,6 +115,10 @@ static void ia64_store_register(int regno, return; } +#else /* if defined __ia64__ */ + +#define bspcache(cache, regs, pp) do {} while(0) + #endif /* if defined __ia64__ */ diff --git a/tapsets.cxx b/tapsets.cxx index 3d5af360..5cd6f8a2 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -2329,6 +2329,8 @@ struct dwarf_derived_probe: public derived_probe void join_group (systemtap_session& s); + void emit_probe_local_init(translator_output * o); + // Pattern registration helpers. static void register_statement_variants(match_node * root, dwarf_builder * dw); @@ -4528,6 +4530,12 @@ dwarf_derived_probe::register_patterns(match_node * root) // register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw); } +void +dwarf_derived_probe::emit_probe_local_init(translator_output * o) +{ + // emit bsp cache setup + o->newline() << "bspcache(c->unwaddr, c->regs, c->probe_point);"; +} // ------------------------------------------------------------------------ diff --git a/translate.cxx b/translate.cxx index c69dc201..c62ba9fd 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1515,6 +1515,9 @@ c_unparser::emit_probe (derived_probe* v) o->newline() << "c->statp = & time_" << v->basest()->name << ";"; o->newline() << "#endif"; + // emit probe local initialization block + v->emit_probe_local_init(o); + // emit all read/write locks for global variables varuse_collecting_visitor vut; if (v->needs_global_locks ()) |