Compilation 使用PLT&;的主要原因是什么;有共享库的表吗?

Compilation 使用PLT&;的主要原因是什么;有共享库的表吗?,compilation,linker,shared-libraries,Compilation,Linker,Shared Libraries,我正在读伊恩·兰斯·泰勒关于链接器的文章: 在第9页讨论共享对象时,他提到,由于共享库可以以不可预测的虚拟地址加载到进程中,因此一旦地址已知,动态链接器将需要处理大量的重新定位。这将减慢加载速度。为了避免动态链接器执行大量重定位,程序链接器将函数引用更改为PLT表中的PC相对调用,并将全局/静态变量引用转换为GET表中的引用。然后,动态链接器只需要重新定位PLT/GOT加载时间中的条目,而不处理整个二进制文件中的重新定位 然而,这种对加载时间优化的关注让我感到困惑,因为这里似乎有一个更为突出的问

我正在读伊恩·兰斯·泰勒关于链接器的文章:

在第9页讨论共享对象时,他提到,由于共享库可以以不可预测的虚拟地址加载到进程中,因此一旦地址已知,动态链接器将需要处理大量的重新定位。这将减慢加载速度。为了避免动态链接器执行大量重定位,程序链接器将函数引用更改为PLT表中的PC相对调用,并将全局/静态变量引用转换为GET表中的引用。然后,动态链接器只需要重新定位PLT/GOT加载时间中的条目,而不处理整个二进制文件中的重新定位

然而,这种对加载时间优化的关注让我感到困惑,因为这里似乎有一个更为突出的问题,加快加载速度是无关紧要的。共享对象的全部意义在于,加载到物理内存中的单个共享对象现在可以映射到每个需要它的进程的虚拟地址空间。这可以通过更改某些页表快速完成,并避免从磁盘加载库的新副本

因此,如果动态链接器在共享库的主体中进行了任何重新定位,这些更改将出现在也映射了该共享库的每个其他进程中,并且如果该库出现在不同的虚拟地址,这些更改将破坏该库

正是因为这个原因,我们有一个GOT和PLT。程序链接器将所有引用修改为GOT和PLT中的位置独立引用。然后,动态链接器为每个进程唯一地重新定位GOT和PLT中的条目。共享库的主要内容在每个进程中共享,但GOT和PLT对于每个进程都是唯一的,不共享


对PLT的理解是否正确?根据我的理解,我已经推断出了一些机制,但我看不到任何其他方法可以起作用。

您似乎缺少或不理解(CoW)页面的概念

两个进程可以
mmap
将磁盘上的同一文件映射到其不同的虚拟地址,并且操作系统可以为两个映射使用一个物理内存页(即,进程共享一个物理内存页)。但一旦一个进程更改了内存,就会为该进程创建一个副本,而更改不会出现在另一个进程中(物理内存页不再共享)

因此,如果动态链接器在共享库的主体中进行了任何重新定位,那么这些更改将出现在也映射了该共享库的每个其他进程中

如果记忆是牛的话就不会了

正是因为这个原因,我们有一个GOT和PLT


不,原因是优化(需要复制的页面要少得多),而不是您(错误)理解所暗示的正确性。

您似乎缺少或不理解(CoW)页面的概念

两个进程可以
mmap
将磁盘上的同一文件映射到其不同的虚拟地址,并且操作系统可以为两个映射使用一个物理内存页(即,进程共享一个物理内存页)。但一旦一个进程更改了内存,就会为该进程创建一个副本,而更改不会出现在另一个进程中(物理内存页不再共享)

因此,如果动态链接器在共享库的主体中进行了任何重新定位,那么这些更改将出现在也映射了该共享库的每个其他进程中

如果记忆是牛的话就不会了

正是因为这个原因,我们有一个GOT和PLT

不,原因是优化(需要复制的页面要少得多),而不是您(错误)理解所暗示的正确性