Merge branch 'x86-asm-generic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / arch / arm / kernel / unwind.c
index 1dedc2c..dd56e11 100644 (file)
@@ -212,7 +212,8 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
                        ctrl->vrs[14] = *vsp++;
                ctrl->vrs[SP] = (unsigned long)vsp;
        } else if (insn == 0xb0) {
-               ctrl->vrs[PC] = ctrl->vrs[LR];
+               if (ctrl->vrs[PC] == 0)
+                       ctrl->vrs[PC] = ctrl->vrs[LR];
                /* no further processing */
                ctrl->entries = 0;
        } else if (insn == 0xb1) {
@@ -309,18 +310,20 @@ int unwind_frame(struct stackframe *frame)
        }
 
        while (ctrl.entries > 0) {
-               int urc;
-
-               if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
-                       return -URC_FAILURE;
-               urc = unwind_exec_insn(&ctrl);
+               int urc = unwind_exec_insn(&ctrl);
                if (urc < 0)
                        return urc;
+               if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
+                       return -URC_FAILURE;
        }
 
        if (ctrl.vrs[PC] == 0)
                ctrl.vrs[PC] = ctrl.vrs[LR];
 
+       /* check for infinite loop */
+       if (frame->pc == ctrl.vrs[PC])
+               return -URC_FAILURE;
+
        frame->fp = ctrl.vrs[FP];
        frame->sp = ctrl.vrs[SP];
        frame->lr = ctrl.vrs[LR];
@@ -332,7 +335,6 @@ int unwind_frame(struct stackframe *frame)
 void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
 {
        struct stackframe frame;
-       unsigned long high, low;
        register unsigned long current_sp asm ("sp");
 
        pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
@@ -362,9 +364,6 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
                frame.pc = thread_saved_pc(tsk);
        }
 
-       low = frame.sp & ~(THREAD_SIZE - 1);
-       high = low + THREAD_SIZE;
-
        while (1) {
                int urc;
                unsigned long where = frame.pc;