为什么linkage会影响同一段的相对跳转是否需要重定位? [英] Why does linkage affect whether relocations are needed for relative jumps in the same section?

查看:32
本文介绍了为什么linkage会影响同一段的相对跳转是否需要重定位?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个简单的程序中,我在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆