进程如何通过加载时重定位共享共享库?

How can process share shared library with load-time relocation?

当共享库未被编译为 PIC 时,它仍然可以通过加载时重定位与 executable 链接。

如果我没理解错的话,动态加载器会查找重定位table中列出的条目,并根据内存映射修改它们。也就是说,共享库的代码在加载时针对当前进程进行了适配。

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

When shared library was not complied as PIC, it still can be linked with the executable thorugh load-time relocation.

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

dynamic loader would look for entries listed in relocation table, and modifies them according to the memory mapping. That is, the code of shared library was adapted for the current process during load time.

正确。请注意,加载程序必须更新的任何内存页面都变为 unshared.

how can another process uses the same shared library at the same time

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

dose the loader guarantee the memory mapping of the two processes are consistent?

没有

Or the library cannot be shared, and the OS would just load another copy of shared library into the memory?

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

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