summaryrefslogtreecommitdiffstats
path: root/runtime/uprobes/uprobes.c
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2009-12-21 12:42:11 -0500
committerDave Brolley <brolley@redhat.com>2009-12-21 12:42:11 -0500
commit25a0404570724499bcdf1ebfd9f03084c2e00137 (patch)
treef9824f847b407790ab10116c2ebcc7e664d53253 /runtime/uprobes/uprobes.c
parent08098abb6b206dc3aea984f18b5054d34e015185 (diff)
parentc6fcc4c1ca5f222cf90bf3968e34a10f09b30be4 (diff)
downloadsystemtap-steved-25a0404570724499bcdf1ebfd9f03084c2e00137.tar.gz
systemtap-steved-25a0404570724499bcdf1ebfd9f03084c2e00137.tar.xz
systemtap-steved-25a0404570724499bcdf1ebfd9f03084c2e00137.zip
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Diffstat (limited to 'runtime/uprobes/uprobes.c')
-rw-r--r--runtime/uprobes/uprobes.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/runtime/uprobes/uprobes.c b/runtime/uprobes/uprobes.c
index 60c84509..cdb98707 100644
--- a/runtime/uprobes/uprobes.c
+++ b/runtime/uprobes/uprobes.c
@@ -2596,6 +2596,44 @@ static void uretprobe_set_trampoline(struct uprobe_process *uproc,
}
}
+unsigned long uprobe_get_pc(struct uretprobe_instance *ri, unsigned long pc,
+ unsigned long sp)
+{
+ struct uretprobe *rp;
+ struct uprobe_kimg *uk;
+ struct uprobe_process *uproc;
+ unsigned long trampoline_addr;
+ struct hlist_node *r;
+ struct uretprobe_instance *ret_inst;
+
+ if (!ri)
+ return 0;
+ rp = ri->rp;
+ uk = (struct uprobe_kimg *)rp->u.kdata;
+ if (!uk)
+ return 0;
+ uproc = uk->ppt->uproc;
+ if (IS_ERR(uproc->uretprobe_trampoline_addr))
+ return pc;
+ trampoline_addr = (unsigned long)uproc->uretprobe_trampoline_addr;
+ if (pc != trampoline_addr)
+ return pc;
+ r = &ri->hlist;
+ hlist_for_each_entry_from(ret_inst, r, hlist) {
+ if (ret_inst->ret_addr == trampoline_addr)
+ continue;
+ /* First handler with a stack pointer lower than the
+ address (or equal) must be the one. */
+ if (ret_inst->sp == sp || compare_stack_ptrs(ret_inst->sp, sp))
+ return ret_inst->ret_addr;
+ }
+ printk(KERN_ERR "Original return address for trampoline not found at "
+ "0x%lx pid/tgid=%d/%d\n", sp, current->pid, current->tgid);
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(uprobe_get_pc);
+
#else /* ! CONFIG_URETPROBES */
static void uretprobe_handle_entry(struct uprobe *u, struct pt_regs *regs,