Public bug reported: Hi all, we systematically tested the QEMU implementation for emulating arm user mode programs. We found that QEMU incorrectly emulate the FPSCR register. The following the proof of code:
/*********** Beginning of the bug: arm.c **********/ int printf(const char *format, ...); unsigned char i0[0x10]; unsigned char o[0x10]; int main() { int k = 0; asm("mov r2, %0\n" "ldr r0, [r2]\n"::"r"((char *)(i0)));; asm("vmsr fpscr, r0"); asm("mov r2, %0\n" "vmrs r4, fpscr\n" "str r4, [r2]\n"::"r"((char *)(o)));; for (k = 0; k < 0x10; k++) printf("%02x", o[0x10 - 1 - k]); printf("\n"); } unsigned char i0[0x10] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00}; /*********** End fo the bug **********/ When the program is compiled into arm binary code and running on a real arm machine, and running in qemu, we have the following result $ arm-linux-gnueabihf-gcc arm.c -o arm -static $ ./arm 000000000000000000000000fff7009f $ qemu-arm arm 000000000000000000000000ffffffff According to the ARM manual, bits[19, 14:13, 6:5] of FPSCR should be reserved as zero. However, arm qemu fails to keep these bits to be zero: these bits can be actually modified in QEMU. QEMU version is 2.7.0. The operating system is Linux 3.13.0. x86_64. Thanks! ** Affects: qemu Importance: Undecided Status: New ** Description changed: Hi all, we systematically tested the QEMU implementation for emulating arm user mode programs. We found that QEMU incorrectly emulate the FPSCR register. The following the proof of code: /*********** Beginning of the bug: arm.c **********/ int printf(const char *format, ...); unsigned char i0[0x10]; unsigned char o[0x10]; int main() { - int k = 0; - asm("mov r2, %0\n" - "ldr r0, [r2]\n"::"r"((char *)(i0)));; - asm("vmsr fpscr, r0"); - asm("mov r2, %0\n" - "vmrs r4, fpscr\n" - "str r4, [r2]\n"::"r"((char *)(o)));; - for (k = 0; k < 0x10; k++) - printf("%02x", o[0x10 - 1 - k]); - printf("\n"); + int k = 0; + asm("mov r2, %0\n" + "ldr r0, [r2]\n"::"r"((char *)(i0)));; + asm("vmsr fpscr, r0"); + asm("mov r2, %0\n" + "vmrs r4, fpscr\n" + "str r4, [r2]\n"::"r"((char *)(o)));; + for (k = 0; k < 0x10; k++) + printf("%02x", o[0x10 - 1 - k]); + printf("\n"); } unsigned char i0[0x10] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00}; /*********** End fo the bug **********/ When the program is compiled into arm binary code and running on a real arm machine, and running in qemu, we have the following result $ arm-linux-gnueabihf-gcc arm.c -o arm -static $ ./arm 000000000000000000000000fff7009f $ qemu-arm arm 000000000000000000000000ffffffff According to the ARM manual, bits[19, 14:13, 6:5] of FPSCR should be reserved as zero. However, arm qemu fails to keep these bits to be zero: these bits can be actually modified in QEMU. + QEMU version is 2.7.0. The operating system is Linux 3.13.0. x86_64. + Thanks! -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1641861 Title: fail to correctly emulate FPSCR register on arm Status in QEMU: New Bug description: Hi all, we systematically tested the QEMU implementation for emulating arm user mode programs. We found that QEMU incorrectly emulate the FPSCR register. The following the proof of code: /*********** Beginning of the bug: arm.c **********/ int printf(const char *format, ...); unsigned char i0[0x10]; unsigned char o[0x10]; int main() { int k = 0; asm("mov r2, %0\n" "ldr r0, [r2]\n"::"r"((char *)(i0)));; asm("vmsr fpscr, r0"); asm("mov r2, %0\n" "vmrs r4, fpscr\n" "str r4, [r2]\n"::"r"((char *)(o)));; for (k = 0; k < 0x10; k++) printf("%02x", o[0x10 - 1 - k]); printf("\n"); } unsigned char i0[0x10] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x28, 0x1c, 0xc7, 0x01, 0x00, 0x00, 0x00, 0x00}; /*********** End fo the bug **********/ When the program is compiled into arm binary code and running on a real arm machine, and running in qemu, we have the following result $ arm-linux-gnueabihf-gcc arm.c -o arm -static $ ./arm 000000000000000000000000fff7009f $ qemu-arm arm 000000000000000000000000ffffffff According to the ARM manual, bits[19, 14:13, 6:5] of FPSCR should be reserved as zero. However, arm qemu fails to keep these bits to be zero: these bits can be actually modified in QEMU. QEMU version is 2.7.0. The operating system is Linux 3.13.0. x86_64. Thanks! To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1641861/+subscriptions