aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/kernel/unwind.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 1dedc2c7ff49..dd56e11f339a 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -212,7 +212,8 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
212 ctrl->vrs[14] = *vsp++; 212 ctrl->vrs[14] = *vsp++;
213 ctrl->vrs[SP] = (unsigned long)vsp; 213 ctrl->vrs[SP] = (unsigned long)vsp;
214 } else if (insn == 0xb0) { 214 } else if (insn == 0xb0) {
215 ctrl->vrs[PC] = ctrl->vrs[LR]; 215 if (ctrl->vrs[PC] == 0)
216 ctrl->vrs[PC] = ctrl->vrs[LR];
216 /* no further processing */ 217 /* no further processing */
217 ctrl->entries = 0; 218 ctrl->entries = 0;
218 } else if (insn == 0xb1) { 219 } else if (insn == 0xb1) {
@@ -309,18 +310,20 @@ int unwind_frame(struct stackframe *frame)
309 } 310 }
310 311
311 while (ctrl.entries > 0) { 312 while (ctrl.entries > 0) {
312 int urc; 313 int urc = unwind_exec_insn(&ctrl);
313
314 if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
315 return -URC_FAILURE;
316 urc = unwind_exec_insn(&ctrl);
317 if (urc < 0) 314 if (urc < 0)
318 return urc; 315 return urc;
316 if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
317 return -URC_FAILURE;
319 } 318 }
320 319
321 if (ctrl.vrs[PC] == 0) 320 if (ctrl.vrs[PC] == 0)
322 ctrl.vrs[PC] = ctrl.vrs[LR]; 321 ctrl.vrs[PC] = ctrl.vrs[LR];
323 322
323 /* check for infinite loop */
324 if (frame->pc == ctrl.vrs[PC])
325 return -URC_FAILURE;
326
324 frame->fp = ctrl.vrs[FP]; 327 frame->fp = ctrl.vrs[FP];
325 frame->sp = ctrl.vrs[SP]; 328 frame->sp = ctrl.vrs[SP];
326 frame->lr = ctrl.vrs[LR]; 329 frame->lr = ctrl.vrs[LR];
@@ -332,7 +335,6 @@ int unwind_frame(struct stackframe *frame)
332void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk) 335void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
333{ 336{
334 struct stackframe frame; 337 struct stackframe frame;
335 unsigned long high, low;
336 register unsigned long current_sp asm ("sp"); 338 register unsigned long current_sp asm ("sp");
337 339
338 pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); 340 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)
362 frame.pc = thread_saved_pc(tsk); 364 frame.pc = thread_saved_pc(tsk);
363 } 365 }
364 366
365 low = frame.sp & ~(THREAD_SIZE - 1);
366 high = low + THREAD_SIZE;
367
368 while (1) { 367 while (1) {
369 int urc; 368 int urc;
370 unsigned long where = frame.pc; 369 unsigned long where = frame.pc;