sim-card
/
qemu
Archived
10
0
Fork 0

tcg/arm: correctly save/restore registers in prologue/epilogue

Since commit 6113d6d316 QEMU crashes
on ARM hosts. This is not a bug of this commit, but a latent bug
revealed by this commit.

The TCG code is called through a procedure call using the prologue
and epilogue code. This code does not save and restore enough registers.
The "Procedure Call Standard for the ARM Architecture" says:

  A subroutine must preserve the contents of the registers r4-r8, r10,
  r11 and SP (and r9 in PCS variants that designate r9 as v6).

The current code only saves and restores r9 to r11, and misses r4 to
r8. The patch fixes that by saving r4 to r12. Theoretically there is
no need to save and restore r12, but an even number of registers have
to be saved as per EABI.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Aurelien Jarno 2010-03-05 08:35:07 +01:00
parent 2e21e7491f
commit 4e17eae9f2
1 changed files with 7 additions and 4 deletions

View File

@ -1752,12 +1752,15 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
void tcg_target_qemu_prologue(TCGContext *s)
{
/* stmdb sp!, { r9 - r11, lr } */
tcg_out32(s, (COND_AL << 28) | 0x092d4e00);
/* Theoretically there is no need to save r12, but an
even number of registers to be saved as per EABI */
/* stmdb sp!, { r4 - r12, lr } */
tcg_out32(s, (COND_AL << 28) | 0x092d5ff0);
tcg_out_bx(s, COND_AL, TCG_REG_R0);
tb_ret_addr = s->code_ptr;
/* ldmia sp!, { r9 - r11, pc } */
tcg_out32(s, (COND_AL << 28) | 0x08bd8e00);
/* ldmia sp!, { r4 - r12, pc } */
tcg_out32(s, (COND_AL << 28) | 0x08bd9ff0);
}