diff options
author | Dave Brolley <brolley@redhat.com> | 2009-12-17 16:59:26 -0500 |
---|---|---|
committer | Dave Brolley <brolley@redhat.com> | 2009-12-17 16:59:26 -0500 |
commit | 6dd4e32114264ccda20395cb07bb877de3c062b2 (patch) | |
tree | 6ea4eb4e631df7832c07eafeda2ca4031870b335 /runtime/uprobes2/uprobes.c | |
parent | 089ed967ce3894c3569091db70db423a5316b04e (diff) | |
parent | 4180475982d87f720897baa6f988a48b4c654ee5 (diff) | |
download | systemtap-steved-6dd4e32114264ccda20395cb07bb877de3c062b2.tar.gz systemtap-steved-6dd4e32114264ccda20395cb07bb877de3c062b2.tar.xz systemtap-steved-6dd4e32114264ccda20395cb07bb877de3c062b2.zip |
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Diffstat (limited to 'runtime/uprobes2/uprobes.c')
-rw-r--r-- | runtime/uprobes2/uprobes.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/runtime/uprobes2/uprobes.c b/runtime/uprobes2/uprobes.c index bf454752..4c3a9c9c 100644 --- a/runtime/uprobes2/uprobes.c +++ b/runtime/uprobes2/uprobes.c @@ -2810,6 +2810,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, |