看以下例子
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
swap.o
連結生成靜態庫: ld main.o swap.o -e main -o stlink
將多個目標連結生成可執行檔案,預設好像是靜態連結
可以看到生成的stlink的.text
.data
的大小是原先兩個檔案之和。2c + 2c = 58
重定位
main.o 反彙編 objdump -d -s main.o
swap.o
透過 objdump -r main.o
檢視目標檔案中有哪些是需要重定位的符號
可以看到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的)
重定位後 objdump -d -s stlink
可以上面需要relocate的位置已經被替換了 引數x 替換成了 600198 這個對應合併後 .data
段的絕對地址。
函式swap則是使用的相對定址 絕對地址是400114,相對地址=下一定要執行的地址和真實swap地址的偏移(400114-40010d=7)