linker - 为什么解析 PIC 函数地址需要 .rela.plt?

标签 linker shared-libraries elf relocation

在探索 ELF 结构时,我看到了这个(这是 objdump -dreadelf -r 与 PIC 链接的二进制文件。so 包含 ml_func):

0000000000400480 <_Z7ml_funcii@plt>:
  400480:       ff 25 92 0b 20 00       jmpq   *0x200b92(%rip)        # 601018 <_Z7ml_funcii>

Relocation section '.rela.plt' at offset 0x438 contains 1 entry:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000601018  000100000007 R_X86_64_JUMP_SLO 0000000000000000 _Z7ml_funcii + 0

.rela.plt 不是多余的吗?它似乎存储了已在 ml_func@plt 处计算的相同偏移量 601018。

或者它对一些更复杂的情况有用,比如不同的搬迁类型吗?还是它只是某种优化(比如,我想从 ml_func@plt... 外部获取 601018 可能并不简单)?..

我想这个问题类似于 Why does the linker generate seemingly useless relocations in .rela.plt? ,他们写的地方

.rela.plt is used to resolve function addresses, even during lazy linking.

我想我想知道为什么解析器在没有 .rela.plt 的情况下无法工作。

最佳答案

您在 .plt 中看到的 601018 实际上并不是来自该部分。这只是 readelf 提供给您的有用注释。 readelf 本身通过查看 .rela.plt 发现了这些信息。

当您的程序启动时,全局偏移表 (GOT) 需要在过程链接表 (PLT) 中包含一个地址,以便引导动态链接逻辑。然而,当你的程序被编译时,编译器还不知道 PLT 的绝对地址。这就是 .rela.plt 部分存在的原因。当您的程序启动时,动态链接器使用此信息来修补 GOT。

关于linker - 为什么解析 PIC 函数地址需要 .rela.plt?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72568388/

相关文章:

c++ - 针对 GNU++98/libstdc++ 编译的应用程序能否链接到针对 C++11/libc++ 构建的 dylib?

c++ - Linux 上的 GMP(MPIR) 链接器错误

linux - 为什么共享库要用GOT(Global Offset Table)来实现?

检查 elf 可执行文件是否在 UNIX 上使用 GUI 或 CUI 运行

c++ - 如何在 Linux 上热重载共享库

c - 将符号表中的符号名称替换为可重定位 ELF 目标文件中的新的较长名称

c++ - 寻找符号依赖的起源

linux - 是否可以启动缺少共享库的程序

shared-libraries - 使用 coreutils install 安装符号链接(symbolic link)

无法链接到 WinPcap 库 wpcap.lib ("undefined reference to")