deepwzh的技术笔记
  • Golang
  • Python
  • Cpp
杂项
前端开发
  • 计算机网络
  • 操作系统
  • 数据库
云原生
Devops
AIGC
关于作者
  • Golang
  • Python
  • Cpp
杂项
前端开发
  • 计算机网络
  • 操作系统
  • 数据库
云原生
Devops
AIGC
关于作者
  • Cpp
  • c++ 模块
  • 类

    • 类
    • 友元
  • 开发工具

    • 开发工具
    • Vscode

      • Vscode
      • vscode 相关插件
  • 协程

    • 协程
    • test
  • 构建工具

    • 构建工具
    • Make
    • Cmake

      • Cmake
      • 常见问题
      • cmake 基本用法
      • cmake 集成 conan
      • cmake 生成器
      • cmake 库查找
  • 链接库

    • 链接库
    • 动态链接库
  • 编译器

    • 编译器
    • gcc

      • gcc
      • 常用选项
  • 包管理工具

    • 包管理工具
    • Canan

动态链接库

相关的段

啊对,我之前的解释有误,让我重新详细解释一下 .plt、.got.plt 和 .rela.plt 的关系:

  1. .plt (Procedure Linkage Table):
  • 是一个代码段,包含了跳转指令
  • 每个动态链接的函数在 .plt 中都有一个对应的条目
  • 第一次调用时,会跳转到动态链接器进行符号解析
  • 解析完成后,会跳转到 .got.plt 中存储的地址
  1. .got.plt (Global Offset Table for PLT):
  • 是一个数据段,存储了函数地址
  • 初始时存储的是 .plt 中解析函数的代码地址
  • 动态链接器解析完符号后,会将实际函数地址写入这里
  • 后续调用时,.plt 会直接跳转到 .got.plt 中存储的地址
  1. .rela.plt (Relocation Table for PLT):
  • 是一个重定位表,包含了重定位信息
  • 存储了 .got.plt 中需要重定位的条目的信息
  • 动态链接器使用这些信息来解析符号地址

工作流程:

  1. 第一次调用动态链接函数时:

    • .plt 跳转到动态链接器
    • 动态链接器使用 .rela.plt 中的信息解析符号地址
    • 将解析后的地址写入 .got.plt 中
    • 跳转到实际函数地址
  2. 后续调用时:

    • .plt 直接跳转到 .got.plt 中存储的地址
    • 不需要再次进行符号解析

你可以使用以下命令查看这些段的内容:

readelf -S your_program    # 查看段信息
objdump -d -j .plt your_program    # 查看 .plt 段内容
objdump -s -j .got.plt your_program    # 查看 .got.plt 段内容
readelf -r your_program    # 查看重定位表内容

这种设计的主要优点是:

  • 实现了延迟绑定,提高了程序启动速度
  • 只有实际使用的函数才会被解析
  • 减少了内存占用和启动时间
  • 支持动态加载和卸载共享库
  • .rela.dyn 和 .rela.plt 是重定位信息表

typedef struct {

Elf64_Addr r_offset;    // 需要重定位的位置(相对于段基址的偏移)

Elf64_Xword r_info;     // 重定位类型和符号表索引

Elf64_Sxword r_addend;  // 重定位的加数

} Elf64_Rela;

  • 查看重定位表
readelf -r -C HelloWorld 

Relocation section '.rela.dyn' at offset 0x7e0 contains 10 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000003d98  000000000008 R_X86_64_RELATIVE                    1160
000000003da0  000000000008 R_X86_64_RELATIVE                    1120
000000004008  000000000008 R_X86_64_RELATIVE                    4008
000000003fd0  000a00000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0
000000003fd8  000100000006 R_X86_64_GLOB_DAT 0000000000000000 std::basic_ostrea[...]@GLIBCXX_3.4 + 0
000000003fe0  000200000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.34 + 0
000000003fe8  000600000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTM[...] + 0
000000003ff0  000700000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
000000003ff8  000800000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCl[...] + 0
000000004040  001200000005 R_X86_64_COPY     0000000000004040 std::cout@GLIBCXX_3.4 + 0

Relocation section '.rela.plt' at offset 0x8d0 contains 2 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000003fc0  000300000007 R_X86_64_JUMP_SLO 0000000000000000 std::basic_ostrea[...]@GLIBCXX_3.4 + 0
000000003fc8  000400000007 R_X86_64_JUMP_SLO 0000000000000000 std::ostream::operator@GLIBCXX_3.4 + 0
  • 查看动态重定位表
objdump -R HelloWorld 

HelloWorld:     file format elf64-x86-64

DYNAMIC RELOCATION RECORDS
OFFSET           TYPE              VALUE
0000000000003d98 R_X86_64_RELATIVE  *ABS*+0x0000000000001160
0000000000003da0 R_X86_64_RELATIVE  *ABS*+0x0000000000001120
0000000000004008 R_X86_64_RELATIVE  *ABS*+0x0000000000004008
0000000000003fd0 R_X86_64_GLOB_DAT  __cxa_finalize@GLIBC_2.2.5
0000000000003fd8 R_X86_64_GLOB_DAT  _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GLIBCXX_3.4
0000000000003fe0 R_X86_64_GLOB_DAT  __libc_start_main@GLIBC_2.34
0000000000003fe8 R_X86_64_GLOB_DAT  _ITM_deregisterTMCloneTable@Base
0000000000003ff0 R_X86_64_GLOB_DAT  __gmon_start__@Base
0000000000003ff8 R_X86_64_GLOB_DAT  _ITM_registerTMCloneTable@Base
0000000000004040 R_X86_64_COPY     _ZSt4cout@GLIBCXX_3.4
0000000000003fc0 R_X86_64_JUMP_SLOT  _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@GLIBCXX_3.4
0000000000003fc8 R_X86_64_JUMP_SLOT  _ZNSolsEPFRSoS_E@GLIBCXX_3.4

查看 plt 与 got 相关的信息

objdump -d -j .plt.got HelloWorld 

HelloWorld:     file format elf64-x86-64


Disassembly of section .plt.got:

0000000000001050 <__cxa_finalize@plt>:
    1050:       f3 0f 1e fa             endbr64
    1054:       ff 25 76 2f 00 00       jmp    *0x2f76(%rip)        # 3fd0 <__cxa_finalize@GLIBC_2.2.5>
    105a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
objdump -d -j .plt HelloWorld 

HelloWorld:     file format elf64-x86-64


Disassembly of section .plt:

0000000000001020 <.plt>:
    1020:       ff 35 8a 2f 00 00       push   0x2f8a(%rip)        # 3fb0 <_GLOBAL_OFFSET_TABLE_+0x8>
    1026:       ff 25 8c 2f 00 00       jmp    *0x2f8c(%rip)        # 3fb8 <_GLOBAL_OFFSET_TABLE_+0x10>
    102c:       0f 1f 40 00             nopl   0x0(%rax)
    1030:       f3 0f 1e fa             endbr64
    1034:       68 00 00 00 00          push   $0x0
    1039:       e9 e2 ff ff ff          jmp    1020 <_init+0x20>
    103e:       66 90                   xchg   %ax,%ax
    1040:       f3 0f 1e fa             endbr64
    1044:       68 01 00 00 00          push   $0x1
    1049:       e9 d2 ff ff ff          jmp    1020 <_init+0x20>
    104e:       66 90                   xchg   %ax,%ax

查看动态符号

objdump -R -C HelloWorld 

HelloWorld:     file format elf64-x86-64

DYNAMIC RELOCATION RECORDS
OFFSET           TYPE              VALUE
0000000000003d98 R_X86_64_RELATIVE  *ABS*+0x0000000000001160
0000000000003da0 R_X86_64_RELATIVE  *ABS*+0x0000000000001120
0000000000004008 R_X86_64_RELATIVE  *ABS*+0x0000000000004008
0000000000003fd0 R_X86_64_GLOB_DAT  __cxa_finalize@GLIBC_2.2.5
0000000000003fd8 R_X86_64_GLOB_DAT  std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)@GLIBCXX_3.4
0000000000003fe0 R_X86_64_GLOB_DAT  __libc_start_main@GLIBC_2.34
0000000000003fe8 R_X86_64_GLOB_DAT  _ITM_deregisterTMCloneTable@Base
0000000000003ff0 R_X86_64_GLOB_DAT  __gmon_start__@Base
0000000000003ff8 R_X86_64_GLOB_DAT  _ITM_registerTMCloneTable@Base
0000000000004040 R_X86_64_COPY     std::cout@GLIBCXX_3.4
0000000000003fc0 R_X86_64_JUMP_SLOT  std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@GLIBCXX_3.4
0000000000003fc8 R_X86_64_JUMP_SLOT  std::ostream::operator<<(std::ostream& (*)(std::ostream&))@GLIBCXX_3.4
Prev
链接库