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



我已经查找了有关got,动态链接和共享库的大量文章。但是我仍然无法弄清楚为什么无法通过Dynamic Linker直接修改" MOV"指令的" fix"符号的" mov"指令的地址来实现共享库?

这将效率降低。这是想到的,可能还有更多:

  • 这打破了跨加载相同共享库的不同过程的代码共享
  • 通常会有很多需要更新的呼叫(而不仅仅是在GOT中更新单个地址(
  • Loader需要将代码页重新映射为可写的,然后再次将其映射为"只读";那是2*num_pages系统的调用,非常慢
  • 静态链接器将需要在呼叫说明中保留最大的字节数,以适应最大可能的地址(X86_64上的8个(,这将增加代码尺寸

您也松散的懒惰符号分辨率。

原因是共享库的.text确实是共享(使用该共享对象的所有进程(,如果您修改了它,它将被修改在中,它的所有实例(因此您实际上正在修改其他过程的代码(。这就是必须以PIC(位置独立代码(模式编译共享库的原因,因为根据将使用它们的最终可执行文件,在不同地址的同一共享文本负载的所有实例。

仅在内核(例如freeBSD允许的(系统中,允许.text段加载在写入模式下,这是允许的。但是,在复制整个代码的开销中,以供处理私人访问的整个页面,因为您已经触摸(一次(几个指针。

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

最新更新