为什么使用GOT(全局偏移表)实现共享库?

时间:2018-04-02 09:03:40

标签: linux shared-libraries dynamic-linking

我查了很多关于GOT,动态链接和共享库的文章。但我仍然无法弄清楚为什么共享库不能通过动态链接器直接修改" mov"的地址来实现。 " .text"中的说明部分到"修复"符号重新定位?

2 个答案:

答案 0 :(得分:1)

这样效率会低得多。这是我想到的,可能会有更多:

  • 这会破坏加载相同共享库的不同进程的代码共享
  • 通常会有很多需要更新的调用(而不仅仅是更新GOT中的单个地址)
  • loader需要将代码页重新映射为可写,然后将它们再次映射为只读;那个2*num_pages系统调用非常慢
  • 静态链接器需要在调用指令中保留最大字节数,以容纳可能增加代码大小的最大可能地址(x86_64上的8)

你也松了懒惰的符号分辨率。

答案 1 :(得分:0)

原因是共享库的.text部分确实共享(由使用该共享对象的所有进程),如果您修改它,它将在中被修改它的所有实例(因此您实际上正在修改其他进程的代码)。这就是必须在PIC(位置无关代码)模式下编译共享库的原因,因为相同共享文本的所有实例都会加载到不同的地址,具体取决于将要使用它们的最终可执行文件。

仅在内核(例如freebsd允许这样做)的系统中允许.text段在写入模式下加载副本,这是允许的。但是考虑到复制整页代码以进行进程私有访问的开销只是因为你已触及(只有一次)几个指针。

普通二进制文件的代码只读仅执行,因此您可以在使用它们的所有进程之间共享相同的代码页。认为内核通常不使用交换空间来存储这些页面,因为它可以转到可执行文件来重新加载页面,以防它被换出(它不是,页面只是从记忆中丢弃了)