静态库(.a)和动态库(.so)在Linux中总是可重定位吗?

静态库(.a)和动态库(.so)在Linux中总是可重定位吗?

我知道目标文件(.o)总是可重定位的,

.a和文件怎么样.so

答案1

文件.a只是其他文件的存档。通常,这些文件是.o您已经知道答案的文件。但它们不一定是目标代码 - 事实上,它们根本不一定是目标代码 - 它们实际上可以是任何您喜欢的文件。

文件.so必须是可重定位才能工作,因为它必须能够根据运行时可用的地址在不同的进程中加载​​到不同的地址。

答案2

让我们先了解一下可重定位的既定定义。如果一段代码可以放置在内存中的任何位置而无需更改并正确执行,则该代码是可重定位的。因此 .o 和 .a 文件都不是可重定位的,因为它们不是代码片段 (!)。.o 文件包含一段代码及其附带信息,而 .a 文件则是任意文件的集合,可能是 .o。

那么,.o 中包含的代码是否可重定位?不,一般来说不是,因为必须由链接器对其进行增强,才能使用 .o 文件提供的信息填写地址。例如,使用多项式求值器计算正弦,而该求值器位于只有链接器知道的其他库中。因此,多项式求值器的调用地址仍然必须填写;换句话说,代码不能这样执行。

最后,.so 文件中的代码是可重定位的,因为这些代码是共享的,可由多个进程同时执行。如果所有这些进程都必须将代码放在一个正确执行的地址上,那就很不方便了。

答案3

可能有点晚了,但让我试试:

  • *.o:对象模块,可能是“pic”或“non-pic”
  • *.a: 对象模块的集合
  • *.so:共享对象/库,必须从“pic”对象构建
  • 'pic' 代码:位置无关代码,可以在任何位置加载并通过重定位运行。
  • “非 pic” 代码:必须将其放置在固定地址;或者必须在加载到内存后重新定位;链接共享对象时不能使用“非 pic”对象模块

额外好处:可执行文件不一定是“pic”,但如果是,则可以在运行它时使用 ASLR:https://en.wikipedia.org/wiki/Address_space_layout_randomization

相关内容