summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2008-07-10 16:39:17 -0400
committerFrank Ch. Eigler <fche@elastic.org>2008-07-18 17:47:23 -0400
commit9020300d0fca87336f84a8d40da9362735eda896 (patch)
treebc5920a41b3c4e62b2b343eb4f46ec836ded03bf
parent6908711142cf34dc1b67d32a68a91998891af764 (diff)
downloadsystemtap-steved-9020300d0fca87336f84a8d40da9362735eda896.tar.gz
systemtap-steved-9020300d0fca87336f84a8d40da9362735eda896.tar.xz
systemtap-steved-9020300d0fca87336f84a8d40da9362735eda896.zip
PR442528
-rw-r--r--elaborate.h4
-rw-r--r--runtime/regs-ia64.c30
-rw-r--r--tapsets.cxx8
-rw-r--r--translate.cxx3
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 ())