如何通过加载时重定位处理共享共享库?

问题描述

当共享库没有被编译为PIC时,它仍然可以通过加载时重定位与可执行文件链接

如果我理解正确,动态加载器会查找重定位表中列出的条目,并根据内存映射修改它们。即共享库的代码在加载时适应当前进程。

我的问题是,另一个进程如何同时使用同一个共享库,加载程序是否保证两个进程的内存映射一致?或者库无法共享,操作系统只会将共享库的另一个副本加载到内存中?

解决方法

当共享库没有被编译为PIC时,它仍然可以通过加载时重定位与可执行文件链接。

此语句需要限定符:这仅在某些平台上可行(例如 ELF32 ix86),而在其他平台上不可行(例如,具有默认中等内存模型的 ELF64 x86_64)。

动态加载器会查找重定位表中列出的条目,并根据内存映射修改它们。即共享库的代码在加载时适应当前进程。

正确。请注意,加载器必须更新的任何内存页面都将成为非共享

另一个进程如何同时使用同一个共享库

另一个进程将拥有自己的加载器更新页面的副本,但将与第一个进程共享任何未修改的页面。

加载器是否保证两个进程的内存映射一致?

没有

或者库无法共享,操作系统只会将共享库的另一个副本加载到内存中?

不完全:根据加载器需要修改的页面数量,一些共享仍然可以发生。

附言当您使用 -fPIC 构建共享库时,加载器需要更新的页面数量被最小化(所有需要更新的地方都集中在 .got 部分,而不是将这些地方分散贯穿整个 .text 部分)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...