【图片+代码】:GCC 链接过程中的【重定位】过程分析
符号表信息
指令:readelf -s main.o
重点看一下黄色矩形中的3个符号。
main符号:
1. Size=50: 长度是 30 个字节,也就对应着代码段的长度 0x32 ;
2. Type=FUNC:说明这是一个函数;
3. Bind=GLOBAL:说明这个符号是全局可见的,也就是在其他文件中可以调用;
4. Ndx=1:说明这个符号是属于第 1 个 段中,就是代码段(.text);
下面两个符号SubData和SubFunc,他们的Ndx都是UND,表示这2个符号被main.o使用,但是定义在其他文件中。
我们知道,当链接成可执行文件时,所有的符号都必须有确定的地址(虚拟地址),所以链接器就需要在链接的过程中找到这2个符号在可执行文件中的地址,然后把这两个地址填写到main的代码段中。
可以先来看一下main.o的反汇编代码:
指令:objdump -d main.o
黄色矩形框中是把数值0存储到eax寄存器中,然后把eax 压到栈中,然后红色矩形框调用了一个函数。
从示例代码(.c文件)中可知:main函数在调用sub.c中的SubFunc函数时,传入了变量SubData。
黄色部分的00 00 00 00就应该是符号SubData的地址,只不过此时main.o还不知道这个符号的将会被链接器安排在什么地址,所以只能空着(以4个字节的00来占位)。
红色部分的调用(call)地址为什么是fc ff ff ff?
按照小端格式计算一下:0xfffffffc,十进制的值就是-4,为什么设置成-4呢?
对于x86平台的ELF格式来说,对地址进行修正的方式有2种:绝对寻址和相对寻址。
绝对寻址
对于SubData符号就是绝对寻址,在链接成可执行文件时,这个地址在代码段中偏移0x12个字节(黄色矩形框指令码偏移0x11个字节,跨过一个字节的指令码a1就是0x12个字节),这个地方4个字节的当前值是 00 00 00 00。
链接器在修正的时候(就是链接成可执行文件的时候),会把这4个字节修改为SubData变量在可执行文件中的实际地址(虚拟地址)。
相对寻址
红色矩形框中的函数调用(SubFunc符号),就是相对寻址,就是说:当CPU执行到这条指令的时候,把PC寄存中的值加上这个偏移地址,就是被调用对象的实际地址。
链接器在重定位的时候,目的就是计算出相对地址,然后替换掉fc ff ff ff这四个字节。
PC寄存器中的值是确定的,当call这条指令被CPU取到之后,PC寄存器被自动增加,指向下一条指令的开始地址(偏移0x1f地址处)。
实际地址 = PC值 + xxxx_xxxx,所以得到:xxxx_xxxx = 实际地址 - PC值。
而PC值与 xxxx_xxxx 所在的地址之间是有关系的:PC值 + (-4)就得到 xxxx_xxxx 所在的地址,因此在main.o中预先在这个地址处填 fc ff ff ff(-4)。
问题来了,链接器怎么知道main.o中代码段的这两个地方,需要进行地址修正?
这就是下面介绍的重定位表的作用了!
重定位表信息
指令:objdump -r main.o
重定位表就表示: 该目标文件中,有哪些符号需要在链接的时候进行地址重定位。
从图中黄色矩形框可以看出:main.o中代码段(.text)的 SubData和SubFunc这 2 个符号都需要链接器对它进行重定位。
TYPE列:R_386_32表示绝对寻址, R_386_PC32 表示相对寻址; OFFSET列表示需要重定位的符号在main.o文件代码段中的偏移位置。
刚才已经看了main.o的反汇编代码,可以看到偏移0x12 和 0x1b的地方,就是需要进行地址重定位的两个符号。
可执行程序 main
有了 2 个目标文件:sub.o和main.o,就可以链接得到可执行程序了:
$ ld -m elf_i386 main.o sub.o -e main -o main
段信息
使用readelf工具来看一下main可执行文件中的段信息(指令:readelf -S main):
1. 红色矩形框是代码段(.text),链接器把它放在虚拟地址 0x0804_8094;
2. 黄色矩形框是数据段(.data),链接器把它放在虚拟地址 0x0804_9138;
从段信息中可以看到main文件中代码段和数据段的布局如下:
可执行程序main是由main.o和sub.o这两个目标文件组成的,所以main中的代码段是由main.o中的代码段和sub.o中的代码段组合得到的;对于数据段,由于 main.o中数据段的长度为0,所以main中的数据段就是sub.o中的数据段(长度为4),如下图所示:
图片新闻
技术文库
最新活动更多
-
即日-12.26立即报名>>> 【在线会议】村田用于AR/VR设计开发解决方案
-
1月8日火热报名中>> Allegro助力汽车电气化和底盘解决方案优化在线研讨会
-
1月9日立即预约>>> 【直播】ADI电能计量方案:新一代直流表、EV充电器和S级电能表
-
即日-1.14火热报名中>> OFweek2025中国智造CIO在线峰会
-
即日-1.16立即报名>>> 【在线会议】ImSym 开启全流程成像仿真时代
-
即日-1.20限时下载>>> 爱德克(IDEC)设备及工业现场安全解决方案
推荐专题
发表评论
请输入评论内容...
请输入评论/评论长度6~500个字
暂无评论
暂无评论