gcc - How do I link to external THUMB code? -


i'm writing thumb code embedded core (arm7tdmi) needs linked existing thumb code. i'm using gnu arm embedded toolchain (link). cannot linker treat existing external code thumb; seems think it's arm. existing code i'm linking absolutely static , cannot changed/recompiled (it's plain binary sitting on rom chip, basically).

here example program, multiply.c, demonstrates issue:

extern int externalfunction(int x); int multiply(int x, int y) {     return externalfunction(x * y); } 

compiled using:

arm-none-eabi-gcc -o multiply.o -c -o3 multiply.c -march=armv4t -mtune=arm7tdmi -mthumb arm-none-eabi-ld -o linked.o multiply.o -t symbols.txt 

where symbols.txt simple linker script:

sections {     .text 0x8000000 : { *(.text) } } externalfunction = 0x8002000; 

when objdump -d linked.o, get:

08000000 <multiply>:  8000000:       b510            push    {r4, lr}  8000002:       4348            muls    r0, r1  8000004:       f000 f804       bl      8000010 <__externalfunction_from_thumb>  8000008:       bc10            pop     {r4}  800000a:       bc02            pop     {r1}  800000c:       4708            bx      r1  800000e:       46c0            nop                     ; (mov r8, r8)  08000010 <__externalfunction_from_thumb>:  8000010:       4778            bx      pc  8000012:       46c0            nop                     ; (mov r8, r8)  8000014:       ea0007f9        b       8002000 <externalfunction> 

instead of branching directly 0x8002000, branches stub switches arm mode first , branches 0x8002000 in arm mode. want bl branch directly 0x8002000 , stay in thumb mode, i'd instead:

08000000 <multiply>:  8000000:       b510            push    {r4, lr}  8000002:       4348            muls    r0, r1  8000004:       ???? ????       bl      8002000 <__externalfunction>  8000008:       bc10            pop     {r4}  800000a:       bc02            pop     {r1}  800000c:       4708            bx      r1 

abi , calling convention issues aside, how achieve this?

one way make want

branchto.s

.thumb .thumb_func .globl branchto branchto:     bx r0 

so.c

extern unsigned int externalfunction; extern int branchto ( unsigned int, int ); int fun ( int x ) {     return(branchto(externalfunction,x)+3); } 

so.ld

sections {     .text 0x8000000 : { *(.text) } } externalfunction = 0x8002001; 

producing

08000000 <fun>:  8000000:   4b04        ldr r3, [pc, #16]   ; (8000014 <fun+0x14>)  8000002:   b510        push    {r4, lr}  8000004:   0001        movs    r1, r0  8000006:   6818        ldr r0, [r3, #0]  8000008:   f000 f806   bl  8000018 <branchto>  800000c:   3003        adds    r0, #3  800000e:   bc10        pop {r4}  8000010:   bc02        pop {r1}  8000012:   4708        bx  r1  8000014:   08002001    stmdaeq r0, {r0, sp}  08000018 <branchto>:  8000018:   4700        bx  r0 

ross ridge's solution in comments works

static int (* const externalfunction)(int x) = (int (*)(int)) 0x80002001; int fun ( int x ) {     return((* externalfunction)(x)+3); } 

but hardcoded address in code not linker script if matters, trying solve , couldnt.

08000000 <fun>:  8000000:   b510        push    {r4, lr}  8000002:   4b03        ldr r3, [pc, #12]   ; (8000010 <fun+0x10>)  8000004:   f000 f806   bl  8000014 <fun+0x14>  8000008:   3003        adds    r0, #3  800000a:   bc10        pop {r4}  800000c:   bc02        pop {r1}  800000e:   4708        bx  r1  8000010:   80002001    andhi   r2, r0, r1  8000014:   4718        bx  r3  8000016:   46c0        nop         ; (mov r8, r8) 

i prefer assembly solution force exact instruction want. naturally if had linked in external function would/should have worked (there exceptions gnu getting @ resolving , arm/thumb in linker).

i dont see gnu bug actually, instead need way in linker script declare variable thumb function address rather generic linker defined variable (likewise arm function address). .thumb_func (or longer function/procedure declaration)

.word branchto  .thumb .globl branchto branchto:     bx r0   8000018:   0800001c    stmdaeq r0, {r2, r3, r4}  0800001c <branchto>:  800001c:   4700        bx  r0   .word branchto  .thumb .thumb_func .globl branchto branchto:     bx r0   8000018:   0800001d    stmdaeq r0, {r0, r2, r3, r4}  0800001c <branchto>:  800001c:   4700        bx  r0 

by reading gnu linker documentation there may hope want

sections {     .text0 0x08000000 : { so.o }     .text1 0x08002000 (noload) : { ex.o } } 

ex.o comming dummy function make happy

int externalfunction ( int x ) {     return(x); }  08000000 <fun>:  8000000:   b510        push    {r4, lr}  8000002:   f001 fffd   bl  8002000 <externalfunction>  8000006:   3003        adds    r0, #3  8000008:   bc10        pop {r4}  800000a:   bc02        pop {r1}  800000c:   4708        bx  r1 

and noload keeps dummy function out of binary.

arm-none-eabi-objcopy so.elf -o srec --srec-forces3 so.srec  s00a0000736f2e7372656338 s3150800000010b501f0fdff033010bc02bc0847c0461e s315080000104743433a2028474e552920362e322e305c s31508000020004129000000616561626900011f000046 s3150800003000053454000602080109011204140115ca s31008000040011703180119011a011e021e s70500000000fa 

note wasnt perfect there garbage got pulled in, perhaps symbols

08000000 <fun>:  8000000:   b510        push    {r4, lr}  8000002:   f001 fffd   bl  8002000 <externalfunction>  8000006:   3003        adds    r0, #3  8000008:   bc10        pop {r4}  800000a:   bc02        pop {r1}  800000c:   4708        bx  r1  800000e:   46c0        nop         ; (mov r8, r8)  8000010:   3a434347      8000014:   4e472820      8000018:   36202955      800001c:   302e322e      8000020:   00294100      8000024:   65610000      8000028:   00696261      800002c:   00001f01      8000030:   54340500      8000034:   08020600      8000038:   12010901      800003c:   15011404      8000040:   18031701      8000044:   1a011901     

which can see in srec, 0x08002000 code not there actual external function called.

i go making instruction want or function pointers assignment if dont want asm.


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -