devkitARM thumb stack exposure bug
Posted: Sun Nov 16, 2008 7:04 pm
Hi Gents,
I've been trying to get the NDS version of ScummVM to build using thumb mode, and I've run into a problem that I believe is down to a code generation/optimisation bug with thumb, that results in valid data being exposed below the stack pointer.
First, the smallest cutdown example I have been able to produce. Save the following as test.c:
Then build using:
arm-eabi-gcc -c test.c -o test.o -mcpu=arm9tdmi -mthumb -Os
Then disassemble the resulting object file using:
arm-eabi-objdump -x -d test.o
The important bit of the output is as follows:
Keen eyed observers with spot the problem at offset 16. r4 points to sp+7 at this point. When we execute add sp,#8 we expose the data that r4 points to. If we get an interrupt at this point, which executes code on the same stack (exactly as the libnds IRQ handler does), this will overwrite the value pointed to by r4.
The next instruction then reads from r4, which may by now be bogus.
I'm using devkitARM release 23b 4.3.0.
I hope I've given enough information here, and that this is the right forum to raise this issue. If I've missed anything, or I should be raising a bug report anywhere else, please tell me.
Thanks,
Robin
I've been trying to get the NDS version of ScummVM to build using thumb mode, and I've run into a problem that I believe is down to a code generation/optimisation bug with thumb, that results in valid data being exposed below the stack pointer.
First, the smallest cutdown example I have been able to produce. Save the following as test.c:
Code: Select all
extern doStreamReadBlock(int *, char *, int size, int);
char readStream(int *s)
{
char c = 0;
doStreamReadBlock(s, &c, 1, *s);
return c;
}
arm-eabi-gcc -c test.c -o test.o -mcpu=arm9tdmi -mthumb -Os
Then disassemble the resulting object file using:
arm-eabi-objdump -x -d test.o
The important bit of the output is as follows:
Code: Select all
Disassembly of section .text:
00000000 <readStream>:
0: b510 push {r4, lr}
2: b082 sub sp, #8
4: 466c mov r4, sp
6: 3407 adds r4, #7
8: 2300 movs r3, #0
a: 7023 strb r3, [r4, #0]
c: 6803 ldr r3, [r0, #0]
e: 1c21 adds r1, r4, #0
10: 2201 movs r2, #1
12: f7ff fffe bl 0 <doStreamReadBlock>
12: R_ARM_THM_CALL doStreamReadBlock
16: b002 add sp, #8
18: 7820 ldrb r0, [r4, #0]
1a: bc10 pop {r4}
1c: bc02 pop {r1}
1e: 4708 bx r1
The next instruction then reads from r4, which may by now be bogus.
I'm using devkitARM release 23b 4.3.0.
I hope I've given enough information here, and that this is the right forum to raise this issue. If I've missed anything, or I should be raising a bug report anywhere else, please tell me.
Thanks,
Robin