我试图从这里 [1] 了解 Linux 中的动态库加载,并想澄清这个概念。具体来说,当在 Linux 环境中的进程中加载动态库时,它会加载到地址空间中的任意一点。现在,一个库有一个代码段和一个数据段。代码段的地址没有定义预链接,所以它是0x0000000,而对于数据段,一些数字被定义为地址。
但这里有个窍门,这个数据段地址实际上并不是真正的地址。实际上,无论代码段被加载到什么位置,数据段的预定义地址都会被添加到它上面。
我在这里是正确的吗?
引用文章中的另一件事。这个声明是什么意思?
但是,我们有一个限制,即共享库在每个进程中仍然必须有一个唯一的数据实例。虽然可以在运行时将库数据放在我们想要的任何位置,但这需要留下重定位来修补代码并通知它在哪里实际找到数据——破坏代码始终只读的属性,从而破坏可共享性。
[1] http://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html
最佳答案
Actually, at whatever position code segment is loaded, data segment's pre-defined address is added to it.
是的。数据段的“VirtAddr”将添加到基地址。
What does this statement mean?
这意味着当库访问它自己的静态数据时,我们不应该在库代码中使用重定位。否则链接器可能需要修补二进制代码,这会导致进程之间不共享库代码的某些部分(如果进程 1 在 0x40000000 处加载库 lib1,而进程 2 在 0x50000000 处加载 lib1,则它们的数据重定位将不同)。
因此,在现实生活中会使用不同的解决方案。库代码和数据一起加载,代码和数据之间的偏移量在所有情况下都是固定的。您引用的文本后有“解决方案”:http://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html
As you can see from the above headers, the solution is that the read-write data section is always put at a known offset from the code section of the library. This way, via the magic of virtual-memory, every process sees its own data section but can share the unmodified code. All that is needed to access data is some simple maths; address of thing I want = my current address + known fixed offset.
关于c++ - 了解 Linux 中的动态库加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22540320/