为什么linkage会影响同一段的相对跳转是否需要重定位? [英] Why does linkage affect whether relocations are needed for relative jumps in the same section?
问题描述
在这个简单的程序中,我在 main
中获得了 compute
的重定位,但不是 compute2
:
In this simple program, I get a relocation in main
for compute
, but not for compute2
:
static int compute2()
{
return 2;
}
int compute()
{
return 1;
}
int main()
{
return compute() + compute2();
}
我使用 gcc -c main.cpp
在 Ubuntu 21.10 上使用 gcc 11.2.0 编译它.
I compile this with gcc -c main.cpp
using gcc 11.2.0 on Ubuntu 21.10.
以下是 objdump
关于 main
的说明:
Here's what objdump
says about main
:
000000000000001e <main>:
1e: f3 0f 1e fa endbr64
22: 55 push rbp
23: 48 89 e5 mov rbp,rsp
26: 53 push rbx
27: e8 00 00 00 00 call 2c <main+0xe> 28: R_X86_64_PLT32 compute()-0x4
2c: 89 c3 mov ebx,eax
2e: e8 cd ff ff ff call 0 <compute2()>
33: 01 d8 add eax,ebx
35: 48 8b 5d f8 mov rbx,QWORD PTR [rbp-0x8]
39: c9 leave
3a: c3 ret
如您所见,对于compute2
(内部链接)的调用,有一个没有重定位的相对跳转.但是对于对 compute
(外部链接)的调用,即使所有三个函数都在同一目标文件的同一部分中,也会发生重定位.
As you can see, for the call to compute2
(internal linkage) there is a relative jump with no relocation. But for the call to compute
(external linkage) there is a relocation, even if all three functions are in the same section in the same object file.
为什么需要搬迁?我认为链接器永远不会拆分一个部分,所以无论这个部分在哪里加载,相对地址应该仍然相同吗?为什么链接似乎会影响这一点?
Why is that relocation needed? I thought the linker would never split up a section, so no matter where this section gets loaded, relative addresses should still be the same? Why does linkage seemingly affect this?
推荐答案
我相信实现此行为是为了启用符号插入——通过将 compute
调用公开为可重定位操作码,你可以像
I believe this behavior is implemented to enable symbol interposition – by exposing the compute
call as a relocatable opcode, you can run your code like
> LD_PRELOAD=custom_compute.so ./main
并且您的 compute
调用将重定位到 .so
中定义的自定义 compute
函数.
and your compute
call will be relocated to a custom compute
function defined in the .so
.
对于 compute2
等静态函数禁用此功能 - 它们是内部链接的,不应用于符号插入.
This functionality is disabled for static functions like compute2
- which are internally linked and shouldn't be available for symbol interposition.
正如评论中提到的,这种行为不仅适用于 LD_PRELOAD
,而且更普遍地与共享库相关 - 例如,在本例中,如果要加载两个共享库,它们都定义了 compute
- 第二个库对 compute
的调用将被重定位到第一个库的函数.
As mentioned in comments, this behavior is not just for LD_PRELOAD
but is more generally relevant for shared libraries - for instance, in this example, if two shared libraries were to be loaded, both defining compute
- the second library's call to compute
would be relocated to the first library's function.
这篇关于为什么linkage会影响同一段的相对跳转是否需要重定位?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!