arm - Problems with static local variables with relocatable code -


i building project has relocatable code on bare metal. cortex m3 embedded application. not have dynamic linker , have implemented relocations in startup code.

mostly working local static variables appear incorrectly located. address offset amount executable offset in memory - ie compile code if loaded @ memory location 0 load in memory located @ 0x8000. static local variable have memory address offset 0x8000 not good.

my global variables located got static local variables not in got @ (at least don't appear when run readelf -r). compiling code -fpic , linker has -fpic , -pie specified. think must missing compile and/or link option either instruct gcc use got static local variables or instruct use absolute addressing them.

it seems code adds pc location of static local variables.

i think have repeated seeing:

 statloc.c  unsigned int glob;  unsigned int fun ( unsigned int ) {     static unsigned int loc;      if(a==0) loc=7;     return(a+glob+loc); }  
 arm-none-linux-gnueabi-gcc -mcpu=cortex-m3 -wall -werror -o2 -nostdlib -nostartfiles -ffreestanding -mthumb -fpic -pie -s statloc.c 

which gives:

    .cpu cortex-m3     .fpu softvfp     .thumb     .text     .align  2     .global fun     .thumb     .thumb_func fun:     ldr r3, .l6 .lpic2:     add r3, pc     cbnz    r0, .l5     ldr r1, .l6+4     movs    r2, #7 .lpic1:     add r1, pc     ldr ip, .l6+8     str r2, [r1, #0]     ldr r1, [r3, ip]     ldr r3, [r1, #0]     adds    r0, r0, r3     adds    r0, r0, r2     bx  lr .l5:     ldr ip, .l6+8     ldr r2, .l6+12     ldr r1, [r3, ip] .lpic0:     add r2, pc     ldr r2, [r2]     ldr r3, [r1, #0]     adds    r0, r0, r3     adds    r0, r0, r2     bx  lr .l7:     .align  2 .l6:     .word   _global_offset_table_-(.lpic2+4)     .word   .lanchor0-(.lpic1+4)     .word   glob(got)     .word   .lanchor0-(.lpic0+4)     .size   fun, .-fun     .comm   glob,4,4     .bss     .align  2 .lanchor0 = . + 0     .type   loc.823, %object     .size   loc.823, 4 loc.823:     .space  4 

i added startup code , compiled binary , disassembled further understand/verify going on.

 offset pc .got     ldr r3, .l6   add pc r3 holds position independent offset .got     add r3, pc    offset in got address of glob      ldr ip, .l6+8  read absolute address global variable got     ldr r1, [r3, ip]  read global variable r3     ldr r3, [r1, #0]    offset pc static local in .bss     ldr r2, .l6+12 add pc r2 holds position independent offset static local in .bss         add r2, pc read static local in .bss         ldr r2, [r2]  

so if change .text loaded , change both .got , .bss loaded relative .text , contents of .got wrong , global variable loaded wrong place.

if change .text loaded, leave .bss linker put , move .got relative .text. global pulled right place , local not

if change .text loaded, change both .got , .bss loaded relative .text , modify .got contents reflect .text loaded, both local , global variable accessed right place.

so loader , gcc/ld need in sync. immediate recommendation not use static local , use global. or dont worry position independent code, cortex-m3 after , resource limited, define memory map front. assume question how make gcc use .got local global, , 1 dont know answer to, taking simple example 1 above can work through many command line options until find 1 changes output.


Comments

Popular posts from this blog

linux - Mailx and Gmail nss config dir -

c# - Is it possible to remove an existing registration from Autofac container builder? -

php - Mysql PK and FK char(36) vs int(10) -