Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=05dc16d6a175139a5872d08db56ee277ec90df5b
Commit:     05dc16d6a175139a5872d08db56ee277ec90df5b
Parent:     e036306aa1832963cd147849b282259a32f5ac08
Author:     Randolph Chung <[EMAIL PROTECTED]>
AuthorDate: Tue Jun 12 14:27:32 2007 +0800
Committer:  Kyle McMartin <[EMAIL PROTECTED]>
CommitDate: Thu Jun 21 17:46:22 2007 -0400

    [PARISC] unwinder improvements
    
    Add special-case handling for "handle_interruption" so that we can rewind
    past the interruption. This is useful for seeing what caused a BUG() or
    WARN_ON(); otherwise the unwind stops at the interruption.
    
    Signed-off-by: Randolph Chung <[EMAIL PROTECTED]>
    Signed-off-by: Kyle McMartin <[EMAIL PROTECTED]>
---
 arch/parisc/kernel/unwind.c |   41 ++++++++++++++++++++++++++++++++++-------
 1 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index cad9d78..3221677 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -16,6 +16,8 @@
 
 #include <asm/uaccess.h>
 #include <asm/assembly.h>
+#include <asm/asm-offsets.h>
+#include <asm/ptrace.h>
 
 #include <asm/unwind.h>
 
@@ -199,6 +201,29 @@ static int unwind_init(void)
        return 0;
 }
 
+#ifdef CONFIG_64BIT
+#define get_func_addr(fptr) fptr[2]
+#else
+#define get_func_addr(fptr) fptr[0]
+#endif
+
+static int unwind_special(struct unwind_frame_info *info, unsigned long pc, 
int frame_size)
+{
+       void handle_interruption(int, struct pt_regs *);
+       static unsigned long *hi = (unsigned long)&handle_interruption;
+
+       if (pc == get_func_addr(hi)) {
+               struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size 
- PT_SZ_ALGN);
+               dbg("Unwinding through handle_interruption()\n");
+               info->prev_sp = regs->gr[30];
+               info->prev_ip = regs->iaoq[0];
+
+               return 1;
+       }
+
+       return 0;
+}
+
 static void unwind_frame_regs(struct unwind_frame_info *info)
 {
        const struct unwind_table_entry *e;
@@ -312,13 +337,15 @@ static void unwind_frame_regs(struct unwind_frame_info 
*info)
                        }
                }
 
-               info->prev_sp = info->sp - frame_size;
-               if (e->Millicode)
-                       info->rp = info->r31;
-               else if (rpoffset)
-                       info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
-               info->prev_ip = info->rp;
-               info->rp = 0;
+               if (!unwind_special(info, e->region_start, frame_size)) {
+                       info->prev_sp = info->sp - frame_size;
+                       if (e->Millicode)
+                               info->rp = info->r31;
+                       else if (rpoffset)
+                               info->rp = *(unsigned long *)(info->prev_sp - 
rpoffset);
+                       info->prev_ip = info->rp;
+                       info->rp = 0;
+               }
 
                dbg("analyzing func @ %lx, setting prev_sp=%lx "
                    "prev_ip=%lx npc=%lx\n", info->ip, info->prev_sp, 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to