Skip to content

Commit

Permalink
arm32: unwind: print_stack(): fix unwind_state
Browse files Browse the repository at this point in the history
print_stack() must save r7 and r11 in the unwind_state structure. Not
doing so will likely result in a crash dunring unwind.
Register r7 is typically used as a frame pointer by GCC in Thumb2 mode,
while r11 (a.k.a. fp) is the frame pointer in ARM mode.

Also, set PC to the beginning of print_stack() since there's no point
in going further inside the function.

Fixes: OP-TEE/optee_os#1069
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (HiKey)
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (QEMU)
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
  • Loading branch information
jforissier authored and takuya-sakata committed Nov 2, 2017
1 parent 7095dc8 commit 0d46ead
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
16 changes: 16 additions & 0 deletions core/arch/arm/include/arm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,22 @@ static __always_inline uint32_t read_lr(void)
asm volatile ("mov %0, lr" : "=r" (val));
return val;
}

static __always_inline uint32_t read_fp(void)
{
uint32_t val;

asm volatile ("mov %0, fp" : "=r" (val));
return val;
}

static __always_inline uint32_t read_r7(void)
{
uint32_t val;

asm volatile ("mov %0, r7" : "=r" (val));
return val;
}
#endif /*ASM*/

#endif /*ARM32_H*/
8 changes: 6 additions & 2 deletions core/arch/arm/kernel/unwind_arm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,14 @@ void print_stack(int level)
{
struct unwind_state state;

memset(&state, 0, sizeof(state));
memset(state.registers, 0, sizeof(state.registers));
/* r7: Thumb-style frame pointer */
state.registers[7] = read_r7();
/* r11: ARM-style frame pointer */
state.registers[FP] = read_fp();
state.registers[SP] = read_sp();
state.registers[LR] = read_lr();
state.registers[PC] = read_pc();
state.registers[PC] = (uint32_t)print_stack;

do {
switch (level) {
Expand Down

0 comments on commit 0d46ead

Please sign in to comment.