[arm-gnu] thumb code calling arm subroutine causes undefined insn exception
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[arm-gnu] thumb code calling arm subroutine causes undefined insn exception
- To: "arm-gnu@xxxxxxxxxxxxxxxx" <arm-gnu@xxxxxxxxxxxxxxxx>
- Subject: [arm-gnu] thumb code calling arm subroutine causes undefined insn exception
- From: "Andrew Kohlsmith (mailing lists account)" <aklists@xxxxxxxxxx>
- Date: Sun, 25 Apr 2010 16:29:25 -0400
Good afternoon, everyone,
I received a really good education on my last post regarding compiler sections
and was able to put that knowledge to some good use, but I've run into a
problem that I am having a real difficult time getting myself out of.
I have a little arm7tdmi board that has been the subject of all my
experiments. I'm now playing with size optimization and have changed my
lowlevel bootup (reset vector) code from ARM to Thumb instructions.
It works great, but I seem to be running into a problem where if I'm running
in thumb mode and I call an ARM subroutine, the call fails.
The bootup code is in assembly, but it jumps to a C main() routine. That
routine executes just fine until it calls the ARM subroutine.
I'm building the code with CodeSourcery's G++ Lite 2009q3-68 (GCC 4.4.1).
arm-none-eabi-as -o boot.o boot.s
arm-none-eabi-gcc -o irq.o -c -std=gnu99 -g -O0 -fno-builtin -nostdlib -
mcpu=arm7tdmi -mthumb-interwork -DNDEBUG -ffunction-sections -fdata-sections
irq.c
arm-none-eabi-gcc -o main.o -c -std=gnu99 -g -O0 -fno-builtin -nostdlib -
mcpu=arm7tdmi -mthumb -mthumb-interwork -DNDEBUG -ffunction-sections -fdata-
sections main.c
As you can see, I am running with -mthumb-interwork, and I've disabled -Os for
now. Linking is done with this command:
arm-none-eabi-gcc -o foo -std=gnu99 -g -O0 -fno-builtin -nostdlib -
mcpu=arm7tdmi -mthumb -mthumb-interwork -DNDEBUG -Trom.ld -Wl,-Map=foo.map -
Wl,--cref -Wl,--gc-sections boot.o main.o irq.o
objdumping the resultant file where the undefined instruction exception occurs
looks ok (to me, but I'm not an expert):
000007f4 <hw_init>:
7f4: b580 push {r7, lr}
7f6: af00 add r7, sp, #0
7f8: f000 e9a4 blx b44 <irq_setup>
7fc: f7ff fe1e bl 43c <rtc_init>
800: f7ff ff8c bl 71c <vibe_init>
804: f7ff feba bl 57c <spiflash_init>
The undefined instruction handler shows LR at 0x7fc, which, if my math is
correct, puts the undefined instruction at 0x7fa.
Now the irq_setup() routine lives in irq.c, which is compiled for ARM
instructions. It too seems fine to my untrained eye:
00000b44 <irq_setup>:
b44: e59fc048 ldr ip, [pc, #72] ; b94 <irq_setup+0x50>
b48: e59f3048 ldr r3, [pc, #72] ; b98 <irq_setup+0x54>
b4c: e3a00000 mov r0, #0
b50: e58c0000 str r0, [ip]
b54: e3a0c002 mov ip, #2
b58: e583c004 str ip, [r3, #4]
b5c: e59fc038 ldr ip, [pc, #56] ; b9c <irq_setup+0x58>
b60: e3a01001 mov r1, #1
b64: e583100c str r1, [r3, #12]
b68: e583c01c str ip, [r3, #28]
b6c: e3a0c018 mov ip, #24
b70: e583c014 str ip, [r3, #20]
b74: e3e02000 mvn r2, #0
b78: e583003c str r0, [r3, #60] ; 0x3c
b7c: e5831004 str r1, [r3, #4]
b80: e3a03010 mov r3, #16
b84: e5023fef str r3, [r2, #-4079] ; 0xfef
b88: e59f3010 ldr r3, [pc, #16] ; ba0 <irq_setup+0x5c>
b8c: e5023fcf str r3, [r2, #-4047] ; 0xfcf
b90: e12fff1e bx lr
b94: 40000c68 .word 0x40000c68
b98: e0004000 .word 0xe0004000
b9c: 00006590 .word 0x00006590
ba0: 00000b08 .word 0x00000b08
Now irq_setup() itself not having to be in ARM instructions (only the
interrupt handler itself), aside, why on earth would this code cause the ARM
to abort on an undefined instruction exception?
Any hints or guidance would be very much appreciated.
Regards,
Andrew