Re: [arm-gnu] thumb code calling arm subroutine causes undefined insn exception
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [arm-gnu] thumb code calling arm subroutine causes undefined insn exception
- To: arm-gnu@xxxxxxxxxxxxxxxx
- Subject: Re: [arm-gnu] thumb code calling arm subroutine causes undefined insn exception
- From: "Andrew Kohlsmith (mailing lists account)" <aklists@xxxxxxxxxx>
- Date: Wed, 28 Apr 2010 10:02:45 -0400
On Sunday 25 April 2010 10:43:51 pm Mark Mitchell wrote:
> Andrew Kohlsmith (mailing lists account) wrote:
> > Since I am already using -mcpu=arm7tdmi, would this indicate that there
> > is a bug in the compiler wherein it is assuming that the BLX instruction
> > exists on the ARM7TDMI/TDMI-S?
>
> Please post your exact options for all of (a) code compiled with
> GCC/G++, (b) code assembled with GAS, (c) link line.
Actually some further inspection seems to lead to the conclusion that
incorrect bootup code (in my case it's using msr in thumb mode) causes the
linker to become confused.
-A.
boot.s:
------------------
.equ MIN_STACK, 0x0004 /* enough for a RET */
.equ IRQ_STACK_LEN, 0x0080 /* 128 words */
.equ STACK_LEN, 0x0200 /* 512 words */
/* .text is used instead of .section .text so it works with arm-aout too. */
.text
.code 32
.align 0
.extern main
.global start
.global endless_loop
start:
ldr r0, =thumb_start + 1 /* +1 to set LSB to identify
destination as thumb code */
bx r0
.code 16
thumb_start:
ldr r0, =.asm_arm_code
bx r0
/* ARM code section to set up stack for all modes */
.code 32
.asm_arm_code:
ldr r0, =.asm_back_to_thumb
bx r0
/* back to Thumb mode for the rest of the initialization */
.code 16
.asm_back_to_thumb:
ldr r6, =main + 1
/* set up call stack */
ldr r3, =exit + 1 /* return address */
mov lr, r3
mov r0, #0 /* argc = 0 */
mov r1, #0 /* **argv = NULL */
bx r6
/*** Uncomment this and change the exit + 1 to just exit above to "fix" the bug
.align 4
.code 32
*/
exit:
mov r4, #0
msr CPSR_c, r4
b exit
endless_loop:
b endless_loop
.section .startup,"ax"
.code 32
.align 0
b start
b undefined_instruction_exception
b software_interrupt_exception
b prefetch_abort_exception
b data_abort_exception
b reserved_exception
b interrupt_exception
b fast_interrupt_exception
/* end */
.end
main.c
-----------------------
unsigned int alloword;
void thumb_func(void)
{
}
int allo_main(void)
{
}
int main(void)
{
irq_init();
do {
arm_func();
thumb_func();
} while(1);
return 0;
}
irq.c:
------------------------------
void irq_handler(void) __attribute__ ((interrupt("IRQ")));
void irq_handler(void)
{
}
void arm_func(void)
{
}
void irq_init(void)
{
}
rom.ld:
---------------------
ENTRY(start);
MEMORY {
flash : ORIGIN = 0, LENGTH = 32K
ram : ORIGIN = 0x40000000, LENGTH = 8K
}
_stack_end = 0x40000000 + 8K - 4;
SECTIONS {
. = 0;
. = ALIGN(0x4);
/* interrupt vector table and CRC of the image */
startup : { KEEP(*(.startup)) } >flash
.text : {
*(.text .text.* .gnu.linkonce.t.*)
*(.glue_7 .glue_7t)
*(.rodata .rodata.*)
} >flash
_etext = .;
.data : {
_data = .;
*(.data .data.*)
} >ram AT>flash
_data_src = LOADADDR(.data);
_data_len = SIZEOF(.data);
.bss : {
_bss = .;
*(.bss .bss.*)
} >ram
_bss_len = SIZEOF(.bss);
/*
* Align here to ensure that the .bss section occupies space up to
* _end. Align after .bss to ensure correct alignment even if the
* .bss section disappears because there are no input sections.
*/
. = ALIGN(0x4);
}
Makefile:
-----------------
AS=arm-none-eabi-as
CC=arm-none-eabi-gcc
LD=arm-none-eabi-ld
OBJCOPY=arm-none-eabi-objcopy
DEBUG=-g -O0
THUMB=-mthumb -mthumb-interwork
#CFLAGS=$(DEBUG) -std=gnu99 -fno-builtin -mcpu=arm7tdmi-s $(THUMB)
CFLAGS=$(DEBUG) -fno-builtin -mcpu=arm7tdmi-s $(THUMB)
OBJS=boot.o main.o irq.o
blxtest: $(OBJS)
$(CC) -T rom.ld -Wl,-Map=$@.map -Wl,--cref -Wl,--gc-sections -o $@ $^
# irq code cannot be thumb
irq.o: irq.c
$(CC) $(DEBUG) -fno-builtin -mcpu=arm7tdmi-s -c -o $@ $<
clean:
rm -f *.o blxtest*
With boot.s as pasted here:
$ arm-none-eabi-objdump -S blxtest | grep blx
blxtest: file format elf32-littlearm
7c: f000 e81a blx b4 <irq_init>
80: f000 e80e blx a0 <arm_func>
With boot.s properly using msr in .code32:
$ arm-none-eabi-objdump -S blxtest | grep blx
blxtest: file format elf32-littlearm
$ arm-none-eabi-gcc -v
Using built-in specs.
Target: arm-none-eabi
Configured with: /scratch/julian/2009q3-respin-eabi-lite/src/gcc-4.4/configure
--build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-eabi --
enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --
enable-extra-sgxxlite-multilibs --with-gnu-as --with-gnu-ld --with-
specs='%{O2:%{!fno-remove-local-statics: -fremove-local-statics}} %{O*:%{O|O0|
O1|O2|Os:;:%{!fno-remove-local-statics: -fremove-local-statics}}}' --enable-
languages=c,c++ --disable-shared --disable-lto --with-newlib --with-
pkgversion='Sourcery G++ Lite 2009q3-68' --with-
bugurl=https://support.codesourcery.com/GNUToolchain/ --disable-nls --
prefix=/opt/codesourcery --with-headers=yes --with-
sysroot=/opt/codesourcery/arm-none-eabi --with-build-
sysroot=/scratch/julian/2009q3-respin-eabi-lite/install/arm-none-eabi --with-
gmp=/scratch/julian/2009q3-respin-eabi-lite/obj/host-libs-2009q3-68-arm-none-
eabi-i686-pc-linux-gnu/usr --with-mpfr=/scratch/julian/2009q3-respin-eabi-
lite/obj/host-libs-2009q3-68-arm-none-eabi-i686-pc-linux-gnu/usr --with-
ppl=/scratch/julian/2009q3-respin-eabi-lite/obj/host-libs-2009q3-68-arm-none-
eabi-i686-pc-linux-gnu/usr --with-host-libstdcxx='-static-libgcc -Wl,-
Bstatic,-lstdc++,-Bdynamic -lm' --with-cloog=/scratch/julian/2009q3-respin-
eabi-lite/obj/host-libs-2009q3-68-arm-none-eabi-i686-pc-linux-gnu/usr --
disable-libgomp --enable-poison-system-directories --with-build-time-
tools=/scratch/julian/2009q3-respin-eabi-lite/install/arm-none-eabi/bin --
with-build-time-tools=/scratch/julian/2009q3-respin-eabi-lite/install/arm-
none-eabi/bin
Thread model: single
gcc version 4.4.1 (Sourcery G++ Lite 2009q3-68)