Linux環境下:程式的連結, 裝載和庫[靜態連結]

Aitozi發表於2023-02-04

看以下例子
main.c

extern int x;

int main()
{
    int y = 100;
    swap(&x,&y);
    return 0;
}
int x = 1;

void swap(int* x, int* y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

段的合併

main.o
image.png
swap.o
image.png

連結生成靜態庫: ld main.o swap.o -e main -o stlink 將多個目標連結生成可執行檔案,預設好像是靜態連結
image.png

可以看到生成的stlink的.text .data的大小是原先兩個檔案之和。2c + 2c = 58

重定位

main.o 反彙編 objdump -d -s main.o
image.png
swap.o
image.png
透過 objdump -r main.o檢視目標檔案中有哪些是需要重定位的符號
image.png
可以看到main.o中的.text 段有兩個符號需要重定位,一個是引數x,一個swap函式,OFFSET分別是17和21。從相應的從main.o 反彙編中可以看到這兩個offset處的地址都是 00 00 00 00 是因為在生成main.o的時候還無法確認這些符號的位置(中間b8也是00.. 是為啥?)。
透過readelf -s main.o也可以得到相同的結果(圖中的x和swap是UNDEFINED的)
image.png
重定位後 objdump -d -s stlink
image.png
可以上面需要relocate的位置已經被替換了 引數x 替換成了 600198 這個對應合併後 .data段的絕對地址。
函式swap則是使用的相對定址 絕對地址是400114,相對地址=下一定要執行的地址和真實swap地址的偏移(400114-40010d=7)
image.png

相關文章