This is the mail archive of the
systemtap@sources.redhat.com
mailing list for the systemtap project.
[RFC][PATCH] retprobes - remove orig_ret_addr usage
- From: Ananth N Mavinakayanahalli <amavin at redhat dot com>
- To: SystemTAP <systemtap at sources dot redhat dot com>
- Date: Wed, 08 Jun 2005 09:34:56 -0400
- Subject: [RFC][PATCH] retprobes - remove orig_ret_addr usage
Hi,
Here is a patch against 2.6.12-rc6-mm1 that removes usage of the static
void *orig_ret_addr. We now populate the ret_addr from the previous
kretprobe_instance in cases where the return address on stack has been
changed to kretprobe_trampoline().
Changes only done to i386. x86_64 may be similar. Rusty?
Ananth
Populate ri->ret_addr from the previous kretprobe_instance in cases where
the return address has been replaced to kretprobe_trampoline().
Signed-off-by: Ananth N Mavinakayanahalli <amavin@redhat.com>
arch/i386/kernel/kprobes.c | 31 +++++++++++++++++--------------
1 files changed, 17 insertions(+), 14 deletions(-)
Index: linux-2.6.12-rc6/arch/i386/kernel/kprobes.c
===================================================================
--- linux-2.6.12-rc6.orig/arch/i386/kernel/kprobes.c 2005-06-08 09:20:16.000000000 -0400
+++ linux-2.6.12-rc6/arch/i386/kernel/kprobes.c 2005-06-08 09:27:19.000000000 -0400
@@ -137,25 +137,28 @@ void arch_prepare_kretprobe(struct kretp
{
unsigned long *sara = (unsigned long *)®s->esp;
struct kretprobe_instance *ri;
- static void *orig_ret_addr;
-
- /*
- * Save the return address when the return probe hits
- * the first time, and use it to populate the (krprobe
- * instance)->ret_addr for subsequent return probes at
- * the same addrress since stack address would have
- * the kretprobe_trampoline by then.
- */
- if (((void*) *sara) != kretprobe_trampoline)
- orig_ret_addr = (void*) *sara;
if ((ri = get_free_rp_inst(rp)) != NULL) {
ri->rp = rp;
ri->stack_addr = sara;
- ri->ret_addr = orig_ret_addr;
+ if (likely((void *)*sara != kretprobe_trampoline)) {
+ /*
+ * First time hit - replace the return addr
+ * with trampoline addr
+ */
+ ri->ret_addr = (void *)*sara;
+ *sara = (unsigned long) &kretprobe_trampoline;
+ } else {
+ /*
+ * return address on stack has been replaced
+ * in the case of multiple retprobes - populate
+ * the correct ret_addr from the previous ri
+ */
+ struct kretprobe_instance *old_ri = get_rp_inst(sara);
+ BUG_ON(!old_ri);
+ ri->ret_addr = old_ri->ret_addr;
+ }
add_rp_inst(ri);
- /* Replace the return addr with trampoline addr */
- *sara = (unsigned long) &kretprobe_trampoline;
} else {
rp->nmissed++;
}