一、背景
动态链接库被装载到物理内存后,不管多少个进程使用它始终只有一份,但是对于每一个进程都会将其映射到虚拟地址空间,对于不同进程,虚拟映射的基址是不一样的,因此需要用到代码无关技术(PIC)
二、存在场景
1、模块内部的函数调用,跳转
2、模块内部的数据访问
3、模块外部的函数调用,跳转
4、模块外部的数据访问

情况1、2模块内部符号的相互引用,可以通过相对寻址的方式实现与地址无关;
情况3、4,库中的一些绝对地址将不可避免被多次调用,需要重定位。例如外部变量b,对于进程A假设存放虚拟地址为 0x08048100,但是对于进程B存放虚拟地址可能为 0x08048200,此时如果存放在物理地址中b的地址为0x08048100,那么进程B使用变量b时就会出问题,因此需要使用一种叫GOT表的东西。
三、全局偏移表
每个应用程序将引用的动态库(绝对地址)符号收集起来,保存到一个叫全局偏移表(GOT)中,GOT表以Section的形式保存在可执行文件中,这个表的地址在编译阶段就已经确定,因此可以通过相对地址的方式做到无地址无关。当程序需要运行需要引用动态库中的函数时,会将动态库加载到内存,根据动态库被加载到内存中的具体地址,更新GOT表中各个符号(函数)的地址。
例如当引用外部变量b时,不再通过b的地址得到b的值,而是跳转到GOT表查询该符号的地址,得到b实际存放的地址得到值,通过间接访问的方式做到了地址无关。
881





