符号重新定位

时间:2018-05-28 09:11:42

标签: linker symbols relocation

以下是如何在PIC中解决函数调用(第一次)

  1. 跳转到我们符号的PLT条目。
  2. 跳转到我们符号的GOT条目。
  3. 跳回PLT条目并在堆栈上推送偏移量。那个 offset实际上是一个描述如何修补符号的Elf_Rel结构。
  4. 跳转到PLT存根条目。
  5. 将指针推送到link_map结构,以便链接器可以 找到符号所属的库。
  6. 调用解析程序例程。
  7. 修补GOT条目。
  8. 这与仅使用GOT

    的数据引用的方式不同

    那么,为什么会出现这种差异呢?为什么有两种不同的方法?

1 个答案:

答案 0 :(得分:1)

  

为什么会出现这种差异?为什么有两种不同的方法?

您所描述的是 lazy 重定位。

LD_BIND_NOW=1已在环境中设置。

它是一种优化:当特定程序调用不执行许多可能的程序执行路径时,它允许您减少动态链接器必须执行的工作量。

想象一个程序可以根据参数调用foo()bar()baz(),并且在任何给定的执行中调用完全其中一个例程

如果您没有使用延迟重定位,动态加载程序必须在程序启动时解析所有3个例程。延迟重定位允许动态加载器仅执行任何给定执行中实际需要的一个重定位(正在调用的一个函数),并且在恰当的时间( 正在调用该函数。)

现在,为什么变量也能以这种方式解决?

因为没有方便的方法让动态加载程序知道何时执行重定位。

假设全局变量为abcfoo()引用abbar()引用bc以及baz()引用ac。从理论上讲,动态加载程序可以扫描foobarbaz的主体,并构建一个&#34的映射;如果调用foo,则还可以解析全局a 1}}和b"等等。但是在启动时解决对全局变量的所有引用要简单得多,速度更快。