标签:symbol 使用命令 inpu 偏移量 text 文件的 建立 第一个 comm
链接过程主要包括地址和空间的分配、符号决议、重定位
[toc]
分配的空间是指虚拟地址空间的分配。
综上所述,链接器分配空间的策略是采用相似段合并,并采用两步链接的方法。
查看各个文件的属性,可以看到ab的.text的大小正好是两个文件的.text大小和
符号地址的确定
因为各个符号在段内的相对位置是固定的,所以其实在合并之后的各个符号的地址就一定确定了,在段基址加上一个偏移值,或者原本的偏移值加上一个偏移值。
重定位 起始对于符号地址以及各个代码段的地址在上面部份已经解决,但是在代码段中的引用的外部符号的地址会在新的输出文件中发生改变,所以代码段中的引用外部符号的地址也需要进行改变,这个也就是重定位的过程。
0x14 向esi传入0x00 和 0x21 的main的地址也是0x00, 这些在a.o中作为符号保留位置,在链接成为ab之后,他们的地址被改写
可以看到shared的地址是0x00601000所以填入00 10 60 00
call指令是下一个指令的地址加上调用的偏移值所以 swap地址等于 0040010d + 00000002 = 40010f
问题: 如何确定在重定位的时候的每个符号的地址信息,就是如何找到代码段中哪些地方需要修改?
使用重定位表:
对于可重定位的ELF文件来说,他必须包含重定位表,用来专门保存重定位信息(重定位包含但不局限于代码段)。
可以使用objdump的-r选项查看重定位表信息,重定位的数据结构:
r_offset 重定位入口地址
r_info 重定位符号类型
符号解析
使用objdump -s 查看符号信息符号表 .symtab
指令修正方式
S是符号的实际地址, P是被修正的位置地址, A是修正位置的值
A是目的地址相对于下一条指令的偏移量
我的理解是 如果D是要填的值的话, 那么有使用call调用函数的地址是D+(-P+A) = S
所以有D = S + A -P
用于解决符号冲突问题,是对弱符号机制问题解决得办法
对于多个符号定义类型不一致情况:
可以使用ar命令查看lib.a这样得文件内部所存在得.o文件得种类
每个.o文件中只包含一个函数,这样来避免浪费,因为链接器链接静态库的单位是目标文件
使用链接器得方法:
Windows上得可执行文件PE类型,大体和Linux得Elf一样
标签:symbol 使用命令 inpu 偏移量 text 文件的 建立 第一个 comm
原文地址:https://www.cnblogs.com/Alruddy/p/9153049.html