summaryrefslogtreecommitdiff
path: root/arch/sh/kernel/dwarf.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-10-26 10:48:18 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-10-26 10:48:18 +0900
commit6253195b671b98a4e5da5d39c2df9f8f257bcea1 (patch)
tree3b7ca1d8ef5d9c50a77abf1d1cf5b2b5aa243284 /arch/sh/kernel/dwarf.c
parent15893fb565921507da80e500d85bb2575989bb57 (diff)
parent60339fad5c68c9c533cd14e67194ff8f727c41d9 (diff)
Merge branch 'sh/stable-updates'
Conflicts: arch/sh/kernel/dwarf.c
Diffstat (limited to 'arch/sh/kernel/dwarf.c')
-rw-r--r--arch/sh/kernel/dwarf.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index 4d8c7bd149df..6c9d0c10f2be 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");