观察调用动态链接库中函数的过程

本文详述了在Linux系统中,程序如何调用动态链接库中的函数,涉及重定位问题、编译期、链接期、运行期以及延迟重定位等关键步骤。在运行期,动态链接器通过PLT和GOT节完成函数地址的查找和重定位,以实现动态链接库函数的调用。此外,还介绍了延迟重定位机制,以减少程序初始化时间。
摘要由CSDN通过智能技术生成

观察调用动态链接库中函数的过程

重定位问题

在程序运行阶段函数A调用函数B时,需要知道函数B位于内存当中的地址,并执行对应区域内的指令才可以完成函数调用,这会面临函数A如何获得函数B地址的问题,想要解决这个问题需要编译器、链接器、动态链接器的共同协作。

编译期

在编译期,编译器只负责将文件内容翻译成指令,它是无法知晓函数B加载内存后的地址,因为无法给call指令一个明确的地址。在这个阶段,编译器会给一个函数B的假地址,用于给后续阶段提供重定位的位置。

main.o文件反汇编结果:
000000000000000f <main>:
   f:   f3 0f 1e fa             endbr64 
  13:   55                      push   %rbp
  14:   48 89 e5                mov    %rsp,%rbp
  17:   48 83 ec 10             sub    $0x10,%rsp
  1b:   e8 00 00 00 00          call   20 <main+0x11>        假地址,指向下一条指令
  20:   89 45 fc                mov    %eax,-0x4(%rbp)
  23:   8b 45 fc                mov    -0x4(%rbp),%eax
  26:   89 c6                   mov    %eax,%esi
  28:   48 8d 05 00 00 00 00    lea    0x0(%rip),%rax        # 2f <main+0x20>
  2f:   48 89 c7                mov    %rax,%rdi
  32:   b8 00 00 00 00          mov    $0x0,%eax
  37:   e8 00 00 00 00          call   3c <main+0x2d>        假地址,指向下一条指令
  3c:   e8 00 00 00 00          call   41 <main+0x32>        假地址,指向下一条指令
  41:   89 45 fc                mov    %eax,-0x4(%rbp)
  44:   8b 45 fc                mov    -0x4(%rbp),%eax
  47:   c9                      leave  
  48:   c3                      ret    

除了给假地址之外,编译器还会生成包含重定位信息的节。

main.o文件查看重定位信息结果:
Relocation section '.rela.text' at offset 0x248 contains 4 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
00000000001c  000400000004 R_X86_64_PLT32    0000000000000000 test_func1 - 4
00000000002b  000300000002 R_X86_64_PC32     0000000000000000 .rodata - 4
000000000038  000600000004 R_X86_64_PLT32    0000000000000000 printf - 4
00000000003d  000700000004 R_X86_64_PLT32    0000000000000000 test_func2 - 4

链接期

在链接期,链接器根据目标文件中的符号节获取完整的符号信息,通过这些符号信息可以看到与main函数处于同一文件中的test_func1函数有明确的类型(SECTION、1)、查找方式是借助局部符号表(LOCAl),而与main函数处于不同文件的printf函数和test_func2函数就没有明确的类型(NOTYPE、UND-undefined),查找方式是借

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值