diff mbox

sh: Check for return_to_handler when unwinding the stack

Message ID 1256410617-16860-1-git-send-email-matt@console-pimps.org (mailing list archive)
State Accepted
Headers show

Commit Message

Matt Fleming Oct. 24, 2009, 6:56 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index 4d8c7bd..6c9d0c1 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -21,6 +21,7 @@ 
 #include <linux/mempool.h>
 #include <linux/mm.h>
 #include <linux/elf.h>
+#include <linux/ftrace.h>
 #include <asm/dwarf.h>
 #include <asm/unwinder.h>
 #include <asm/sections.h>
@@ -569,6 +570,27 @@  struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
 	if (!pc && !prev)
 		pc = (unsigned long)current_text_addr();
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+	/*
+	 * If our stack has been patched by the function graph tracer
+	 * then we might see the address of return_to_handler() where we
+	 * expected to find the real return address.
+	 */
+	if (pc == (unsigned long)&return_to_handler) {
+		int index = current->curr_ret_stack;
+
+		/*
+		 * We currently have no way of tracking how many
+		 * return_to_handler()'s we've seen. If there is more
+		 * than one patched return address on our stack,
+		 * complain loudly.
+		 */
+		WARN_ON(index > 0);
+
+		pc = current->ret_stack[index].ret;
+	}
+#endif
+
 	frame = mempool_alloc(dwarf_frame_pool, GFP_ATOMIC);
 	if (!frame) {
 		printk(KERN_ERR "Unable to allocate a dwarf frame\n");