PLT与GOT详解
PLT表和GOT表应用于Unix/Linux上的ELF文件,至于Windows系统PE文件使用的是IAT表。
PLT 过程链接表,用于调用链接时地址未知的外部函数,并在首次调用时访问并进行地址解析(获取真正的地址)。
GOT 全局偏移表,用于储存真正的地址。这是链接器在执行链接时需要填充的部分,保存了所有外部符号的地址信息。
服务对象:为处理共享库中的全局变量和导出函数。
下图完美解释了PLT与GOT的使用过程。
在首次调用导出函数时,由于未知函数真正地址(这时表现为xxx@plt),去访问plt表中该函数所在的项(为一段代码,三条指令如上图所示),之后去访问GOT表,又跳到PLT[0]的中(代码段)调用函数_dl_runtime_resolve去获取真正的函数地址并修改对应的GOT表项。
- GOT[0] 是.dynamic段的装载地址,.dynamic段包含了动态链接器用来绑定过程地址的信息,比如符号的位置和重定位信息;
- GOT[1] 是动态链接器的标识
link_map
的地址; - GOT[2] 包含动态链接器的延迟绑定代码
_dl_runtime_resolve
的入口点,用于得到真正的函数地址,回写到对应的got表中; - 从 GOT[3] 开始就是函数的地址。
plt表存在的意义:
plt表是为了实现延迟绑定出现的一层间接跳转,延迟绑定提高程序启动的效率,延迟绑定减少进程启动开销的原理则要通过延迟绑定整个机制来解释。