对于位置无关代码的理解

这个概念其实很好理解。对于一个可重定位目标文件,里面一定有很多需要重定位的符号。这些符号需要在静态链接器进行链接的时候回填绝对的虚拟内存地址。这种叫做位置有关代码。

而位置无关代码的意思是,在动态链接阶段(这个阶段可以发生在装载时也可以发生在运行时)无需回填具体的代码段,而是只需要回填全局偏移量表(GOT)与过程链接表(PLT)即可。

位置无关代码与位置有关代码的根本区别在于:

链接阶段是否需要修改具体的代码段中的符号地址。在静态链接中需要回填,而在动态链接中借助GOT与PLT很好的规避了对代码段的修改。

具体来说,分为对变量的引用与对函数的引用。

1.对变量的引用

对于位置无关代码的理解_第1张图片

动态链接阶段只用将具体的虚拟地址回填到GOT[3]条目即可,无需修改代码段

2.对函数的引用

对于位置无关代码的理解_第2张图片

如果用伪代码来表示,我个人觉得可以写成下面的代码

static void* func;
void real_func()
{
    ....
}

void load_linker()
{
    ......
    func = real_func(); // 3
    ......
}
void init()
{
    load_linker(); // 2
}

func = init(); // 1 

void call_func()
{
    func(); 
}

这种惰性加载是不是很熟悉?第一次加载的时候,代码实际上是加载了动态链接器给共享代码分配虚拟内存地址并回填到GOT表,好了,之后所有的访问都是直接跳转到真正的函数地址。

你可能感兴趣的:(操作系统)