diff options
| author | Masami Hiramatsu <[email protected]> | 2021-10-21 00:55:35 +0000 |
|---|---|---|
| committer | Steven Rostedt (VMware) <[email protected]> | 2021-10-22 16:16:53 +0000 |
| commit | fed240d9c9743815fcbc0ca5c0913292ce1f25e2 (patch) | |
| tree | 332b5002123a3db9bd9b6bc9a5f0144f008374eb /arch/arm/include/asm/stacktrace.h | |
| parent | ARM: kprobes: Make a frame pointer on __kretprobe_trampoline (diff) | |
| download | kernel-fed240d9c9743815fcbc0ca5c0913292ce1f25e2.tar.gz kernel-fed240d9c9743815fcbc0ca5c0913292ce1f25e2.zip | |
ARM: Recover kretprobe modified return address in stacktrace
Since the kretprobe replaces the function return address with
the kretprobe_trampoline on the stack, arm unwinder shows it
instead of the correct return address.
This finds the correct return address from the per-task
kretprobe_instances list and verify it is in between the
caller fp and callee fp.
Note that this supports both GCC and clang if CONFIG_FRAME_POINTER=y
and CONFIG_ARM_UNWIND=n. For the ARM unwinder, this is still
not working correctly.
Signed-off-by: Masami Hiramatsu <[email protected]>
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
Diffstat (limited to 'arch/arm/include/asm/stacktrace.h')
| -rw-r--r-- | arch/arm/include/asm/stacktrace.h | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h index 2d76a2e29f05..8f54f9ad8a9b 100644 --- a/arch/arm/include/asm/stacktrace.h +++ b/arch/arm/include/asm/stacktrace.h @@ -3,6 +3,7 @@ #define __ASM_STACKTRACE_H #include <asm/ptrace.h> +#include <linux/llist.h> struct stackframe { /* @@ -13,6 +14,10 @@ struct stackframe { unsigned long sp; unsigned long lr; unsigned long pc; +#ifdef CONFIG_KRETPROBES + struct llist_node *kr_cur; + struct task_struct *tsk; +#endif }; static __always_inline @@ -22,6 +27,10 @@ void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame) frame->sp = regs->ARM_sp; frame->lr = regs->ARM_lr; frame->pc = regs->ARM_pc; +#ifdef CONFIG_KRETPROBES + frame->kr_cur = NULL; + frame->tsk = current; +#endif } extern int unwind_frame(struct stackframe *frame); |
