Мне кажется, я повторил то, что вы видите:
statloc.c
unsigned int glob;
unsigned int fun ( unsigned int a )
{
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
Что дает:
.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
Я также добавил код запуска, скомпилировал двоичный файл и разобрал его, чтобы лучше понять / проверить, что происходит.
this is the offset from the pc to the .got
ldr r3, .L6
add pc so r3 holds a position independent offset to the .got
add r3, pc
offset in the got for the address of the glob
ldr ip, .L6+8
read the absolute address for the global variable from the got
ldr r1, [r3, ip]
finally read the global variable into r3
ldr r3, [r1, #0]
this is the offset from the pc to the static local in .bss
ldr r2, .L6+12
add pc so that r2 holds a position independent offset to the static local
in .bss
add r2, pc
read the static local in .bss
ldr r2, [r2]
Таким образом, если бы вы изменили место загрузки .text и изменили местоположение загрузки .got и .bss относительно .text, то есть содержимое .got будет неправильным, а глобальная переменная будет загружен не с того места.
если вам нужно изменить место загрузки .text, оставьте .bss там, где его разместил компоновщик, и переместите .got относительно .text. тогда глобальный будет вытащен из правильного места, а локальный не будет
если бы вы изменили место загрузки .text, измените место загрузки .got и .bss относительно .text и измените содержимое .got так, чтобы оно отражало место загрузки .text, тогда локальная и глобальная переменная будут Доступ из правильного места.
Так что загрузчик и gcc / ld должны быть синхронизированы. Моя непосредственная рекомендация - не использовать статический локальный, а просто использовать глобальный. Это или не беспокоиться о позиционно-независимом коде, это все-таки cortex-m3 и несколько ограниченный ресурс, просто определите карту памяти заранее. Я предполагаю, что вопрос заключается в том, как заставить gcc использовать .got для локального глобала, и на который я не знаю ответа, но на простом примере, подобном приведенному выше, вы можете работать с множеством параметров командной строки, пока не найдете тот, который изменяет вывод.