我想我已經重複你所看到的:
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的位置,然後從正確的位置訪問本地變量和全局變量。
所以loader和gcc/ld都需要同步。我的直接建議是不使用靜態本地,只使用全局。或者不用擔心位置獨立的代碼,畢竟它是一個cortex-m3並且資源有限,只是先定義內存映射。我假設的問題是,如何讓gcc使用.got作爲本地全局,並且我不知道答案,但是採用上面這樣的簡單示例,您可以使用許多命令行選項,直到找到一個改變輸出。
不幸的是這個應用程序,我需要得到位置獨立工作。很高興看到您能夠重現我目前發現的內容。以下工作: – Dan 2011-02-24 01:33:03
在鏈接器腳本中將GOT設置爲在SRAM中。在flash中保留.dynamic,以便可以找到符號表。使用符號表查找文本,數據,編輯等。從閃存複製GOT並修改內容? – Dan 2011-02-24 01:40:09
正如我在這裏所做的那樣,我會採取一個簡單的例子,就像上面創建一個超級簡單的啓動文件一樣,只需一個_Start:和bl樂趣,並使用各種鏈接器腳本構建,以確切查看工具鏈的功能。就我個人而言,我採用KISS方法,並且所有內容都位於不可重定位的.text段中,而.bss init並不重要,因爲在我第一次寫之前我從未閱讀過。基本上我不是一個gnu鏈接器專業人員,也許有人在聽誰可能知道如何操作這些段而不必在加載器中解決它。 – 2011-02-24 02:24:07