c++ - 了解 Linux 中的动态库加载

标签 c++ c linux shared-libraries

我试图从这里 [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/

相关文章:

c++ - 为什么在 C++ 中有这么多不同的方法来使用 new 运算符

c - 在 C 中打印 long int 值

c - 指向 char 的指针 - 增量运算符

linux - XResizeWindow后,绘制的新窗口内容不显示

C++ typelist make 子列表

c++ - 当应用于命名空间范围内的类时,静态意味着什么?

c++ - 在c++中的while条件表达式中自动声明变量

c - 使用 AES 作为具有真正随机种子的可移植 RNG?

linux - 在 Redhat Linux 2.6.32 上使用带有 HTTP/2 的 Tomcat 的损坏页面

linux - 为 pthread 函数传递结构指针 als 参数