看以下例子
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
![Linux环境下:程序的链接, 装载和库[静态链接]](http://www.itfaba.com/wp-content/uploads/2023/02/20230204_63de6ecc74a79.png)
swap.o
![Linux环境下:程序的链接, 装载和库[静态链接]](http://www.itfaba.com/wp-content/themes/kemi/images/loading.gif)
链接生成静态库: ld main.o swap.o -e main -o stlink 将多个目标链接生成可执行文件,默认好像是静态链接
![Linux环境下:程序的链接, 装载和库[静态链接]](http://www.itfaba.com/wp-content/themes/kemi/images/loading.gif)
可以看到生成的stlink的.text .data的大小是原先两个文件之和。2c + 2c = 58
重定位
main.o 反汇编 objdump -d -s main.o
![Linux环境下:程序的链接, 装载和库[静态链接]](http://www.itfaba.com/wp-content/uploads/2023/02/20230204_63de6eccf0eed.png)
swap.o
![Linux环境下:程序的链接, 装载和库[静态链接]](http://www.itfaba.com/wp-content/uploads/2023/02/20230204_63de6ecd23305.png)
通过 objdump -r main.o查看目标文件中有哪些是需要重定位的符号
![Linux环境下:程序的链接, 装载和库[静态链接]](http://www.itfaba.com/wp-content/uploads/2023/02/20230204_63de6ecd4306d.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的)
![Linux环境下:程序的链接, 装载和库[静态链接]](http://www.itfaba.com/wp-content/uploads/2023/02/20230204_63de6ecd69388.png)
重定位后 objdump -d -s stlink
![Linux环境下:程序的链接, 装载和库[静态链接]](http://www.itfaba.com/wp-content/uploads/2023/02/20230204_63de6ecd946d5.png)
可以上面需要relocate的位置已经被替换了 参数x 替换成了 600198 这个对应合并后 .data段的绝对地址。
函数swap则是使用的相对寻址 绝对地址是400114,相对地址=下一定要执行的地址和真实swap地址的偏移(400114-40010d=7)
![Linux环境下:程序的链接, 装载和库[静态链接]](http://www.itfaba.com/wp-content/themes/kemi/images/loading.gif)