ARM (Thumb) read from R15
PATCH 1/1 ARM (Thumb) read from R15
Hi!
QEMU does not set the Thumb bit when reading from R15 in Thumb mode. Here's the fix:
Index: target-arm/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-arm/translate.c,v retrieving revision 1.53
translate.c 28 Jun 2007 14:29:15 -0000 renamed from translate.c 11 Jun 2007 18:59:35 -0000 1.53 +1 -1
@@ -307,7 +307,7 @@ if (reg == 15) { /* normaly, since we updated PC, we need only to add one insn */ if (s->thumb) - val = (long)s->pc + 2; + val = (long)s->pc + 3; else val = (long)s->pc + 4; gen_op_movl_TN_im[t](val);
CU
Uli
Signature · 1 line
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
Quoted 2 lines · Ulrich Hecht
QEMU does not set the Thumb bit when reading from R15 in Thumb mode. Here's the fix:
Maybe not; this seems to break some cases ... :(
CU
Uli
Signature · 1 line
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
Quoted 5 lines · Ulrich Hecht
Quoted 2 lines · Ulrich Hecht
QEMU does not set the Thumb bit when reading from R15 in Thumb mode. Here's the fix:
Maybe not; this seems to break some cases ... :(
This works in all my cases, although I am not sure if it is correct:
Index: target-arm/translate.c
===================================================================
RCS file: /sources/qemu/qemu/target-arm/translate.c,v retrieving revision 1.53
translate.c 28 Jun 2007 15:48:59 -0000 renamed from translate.c 11 Jun 2007 18:59:35 -0000 1.53 +5 -2
@@ -307,7 +307,7 @@ if (reg == 15) { /* normaly, since we updated PC, we need only to add one insn */ if (s->thumb) - val = (long)s->pc + 2; + val = (long)s->pc + 3; else val = (long)s->pc + 4; gen_op_movl_TN_im[t](val);
@@ -3062,7 +3062,10 @@ gen_op_movl_T1_im(val); gen_movl_reg_T1(s, 14); } - gen_movl_T0_reg(s, rm); + if (rm == 15) + gen_op_movl_T0_im(s->pc + 2); + else + gen_movl_T0_reg(s, rm); gen_bx(s); break; }
CU
Uli
Signature · 1 line
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
Quoted 1 line
QEMU does not set the Thumb bit when reading from R15 in Thumb mode.
Neither does real hardware.
Paul
Quoted 3 lines · Paul Brook
Quoted 1 line
QEMU does not set the Thumb bit when reading from R15 in Thumb mode.
Neither does real hardware.
You are, unsurprisingly, right. The problem seems to be a different one. Quoting the ARM on "pop pc":
"In ARM architecture 5 and above, bit[0] of the loaded value determines whether execution continues after this branch in ARM state or in Thumb state[...] In T variants of architecture version 4, bit[0] of the loaded value is ignored and execution continues in Thumb state[...]"
My code is supposed to run on a 4T. I guess I'll have to implement an ARM_FEATURE_THUMB1.
CU
Uli
Signature · 1 line
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
Quoted 8 lines · Ulrich Hecht
Quoted 3 lines · Paul Brook
Quoted 1 line
QEMU does not set the Thumb bit when reading from R15 in Thumb mode.
Neither does real hardware.
You are, unsurprisingly, right. The problem seems to be a different one. Quoting the ARM on "pop pc":
Quoted 7 lines
"In ARM architecture 5 and above, bit[0] of the loaded value determines whether execution continues after this branch in ARM state or in Thumb state[...] In T variants of architecture version 4, bit[0] of the loaded value is ignored and execution continues in Thumb state[...]"
My code is supposed to run on a 4T. I guess I'll have to implement an
ARM_FEATURE_THUMB1.
As you have found out, qemu doesn't currently emulate v4t. There are a couple of other instructions that should be disabled (blx) if you do this.
Paul