|
@@ -47,14 +47,51 @@ GLOBAL(\trace_label)
|
|
|
#endif
|
|
|
.endm
|
|
|
|
|
|
+#ifdef CONFIG_FRAME_POINTER
|
|
|
+/*
|
|
|
+ * Stack traces will stop at the ftrace trampoline if the frame pointer
|
|
|
+ * is not set up properly. If fentry is used, we need to save a frame
|
|
|
+ * pointer for the parent as well as the function traced, because the
|
|
|
+ * fentry is called before the stack frame is set up, where as mcount
|
|
|
+ * is called afterward.
|
|
|
+ */
|
|
|
+.macro create_frame parent rip
|
|
|
+#ifdef CC_USING_FENTRY
|
|
|
+ pushq \parent
|
|
|
+ pushq %rbp
|
|
|
+ movq %rsp, %rbp
|
|
|
+#endif
|
|
|
+ pushq \rip
|
|
|
+ pushq %rbp
|
|
|
+ movq %rsp, %rbp
|
|
|
+.endm
|
|
|
+
|
|
|
+.macro restore_frame
|
|
|
+#ifdef CC_USING_FENTRY
|
|
|
+ addq $16, %rsp
|
|
|
+#endif
|
|
|
+ popq %rbp
|
|
|
+ addq $8, %rsp
|
|
|
+.endm
|
|
|
+#else
|
|
|
+.macro create_frame parent rip
|
|
|
+.endm
|
|
|
+.macro restore_frame
|
|
|
+.endm
|
|
|
+#endif /* CONFIG_FRAME_POINTER */
|
|
|
+
|
|
|
ENTRY(ftrace_caller)
|
|
|
ftrace_caller_setup ftrace_caller_op_ptr
|
|
|
/* regs go into 4th parameter (but make it NULL) */
|
|
|
movq $0, %rcx
|
|
|
|
|
|
+ create_frame %rsi, %rdi
|
|
|
+
|
|
|
GLOBAL(ftrace_call)
|
|
|
call ftrace_stub
|
|
|
|
|
|
+ restore_frame
|
|
|
+
|
|
|
MCOUNT_RESTORE_FRAME
|
|
|
|
|
|
/*
|
|
@@ -105,9 +142,13 @@ ENTRY(ftrace_regs_caller)
|
|
|
/* regs go into 4th parameter */
|
|
|
leaq (%rsp), %rcx
|
|
|
|
|
|
+ create_frame %rsi, %rdi
|
|
|
+
|
|
|
GLOBAL(ftrace_regs_call)
|
|
|
call ftrace_stub
|
|
|
|
|
|
+ restore_frame
|
|
|
+
|
|
|
/* Copy flags back to SS, to restore them */
|
|
|
movq EFLAGS(%rsp), %rax
|
|
|
movq %rax, SS(%rsp)
|