|
@@ -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;
|