为什么后续动态链接的函数调用需要通过PLT进行额外的间接寻址?

时间:2017-02-24 17:55:28

标签: shared-libraries x86-64 elf dynamic-linking

假设我有一个名为P的程序,该程序与库动态链接。当调用一个用-fPIC编译的共享库中的函数时,我理解这些事情会发生

  1. call functionName@plt
  2. 中有类似P的内容
  3. 然后跳转到PLT表代码到相应的条目
  4. 从那里我们跳到相应的GOT入口点
  5. 如果这是第一次调用此函数,那么这就是绑定开始发生的时刻,GOT条目将指向我们返回绑定代码的PLT条目
  6. 然后绑定代码找到函数的地址,并将地址值放入GOT条目并运行它
  7. GOT条目存储一个地址,如果该函数尚未被调用,则该地址对应于相应PLT条目中的绑定代码,或者它指向functionName代码地址。我的问题是为什么在步骤1中的呼叫点处的P不存在类似call [functionName@GOT]的东西。

    意味着加载GOT条目的值并直接跳转到那里。除了第一个函数之外,这将为每个函数调用提供一个更少的间接。如果是第一次调用,它将跳转到PLT绑定代码,绑定将发生,GOT的值将更新。后续调用将直接指向函数代码,因为现在GOT条目指向函数。

    有一种怀疑是因为能够获取该功能的地址。是不是?

1 个答案:

答案 0 :(得分:0)

  

如果是第一次调用,它将跳转到PLT绑定代码,绑定将发生,GOT的值将被更新。

PLT绑定代码如何知道要查找的函数?

第一次调用时,PLT存根sets up parameters to the resolver每个 PLT存根的这些参数不同(这就是为每个导入函数需要一个PLT存根的原因)。