Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arm32 unwind fix #1102

Merged
merged 4 commits into from
Oct 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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*/
12 changes: 8 additions & 4 deletions core/arch/arm/kernel/unwind_arm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ static bool unwind_exec_insn(struct unwind_state *state)

mask = unwind_exec_read_byte(state);
if (mask == 0 || (mask & 0xf0) != 0)
return 1;
return false;

/* Update SP */
update_vsp = 1;
Expand Down Expand Up @@ -283,7 +283,7 @@ static bool unwind_exec_insn(struct unwind_state *state)
}

/* Performs the unwind of a function */
static int unwind_tab(struct unwind_state *state)
static bool unwind_tab(struct unwind_state *state)
{
uint32_t entry;

Expand Down 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));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this is a stupid question: why zero-ing only the registers sub structure ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because, that's the only part that contains input arguments. The rest is used internally by the unwinding code, so it doesn't look like it is the responsibility of the caller to initialize it (To which value BTW? Is zero acceptable for all fields?).

/* r7: Thumb-style frame pointer */
state.registers[7] = read_r7();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency, could you use a R7 label defined next to FP, SP and friends above ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not for two reasons: (1) it does not improve legibility and (2) the above code is mostly copied from FreeBSD so the less we change it, the better.

/* 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
2 changes: 1 addition & 1 deletion core/arch/arm/tee/arch_svc_a32.S
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
*/
FUNC tee_svc_do_call , :
UNWIND( .fnstart)
UNWIND( .cantunwind)
push {r5-r9, lr}
UNWIND( .save {r5-r9, lr})
mov r7, sp
mov r8, r0
mov r9, r1
Expand Down