linux - 动态库代码 stub 的执行流程

标签 linux dll shared-libraries glibc

StackOverflow 上有几个标题相似的问题,但这个问题解决的是不同的问题。

我创建了一个简单的 fprintf 程序,它在文件中打印特定值。我想了解有关库代码的程序执行流程。我对动态库的分析是,每个动态库都是使用 stub 调用的, stub 存储在目标文件的 plt 部分。目标文件的简单 objdump 揭示了三个主要部分:init、plt 和 text。 plt 部分中的所有 stub 由 3/4 相似的行组成。 fprintf 的示例:

00000000004004d0 <fprintf@plt>:
  4004d0: jmpq   *0x200b42(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x30>
  4004d6: pushq  $0x3
  4004db: jmpq   400490 <_init+0x18>

我使用 pintool 来跟踪程序的执行。显然,第一次调用fprintf时,执行流程是4004d0,4004d6,4004db。这意味着第一条指令即跳转第一次转到下一条指令,然后下一次,相同的跳转指令导致库代码(我可以从下一条指令的 ip 识别这一点)。

  1. 我的问题是目标文件中维护的_GLOBAL_OFFSET_TABLE_ 信息在哪里?我使用 readelf -a 命令读取目标文件内容,但在该目标文件中找不到感兴趣的指令指针。
  2. plt 部分和 stub 方法是我们访问共享库代码的唯一途径吗?

最佳答案

I used the pintool to trace the execution of the program. Apparently, the first time fprintf is called, the execution flow is 4004d0,4004d6,4004db. This means that the first instruction i.e. jump goes to the next instruction at the first time and then the next time, the same jump instruction leads to the library code(I could identify this from the ip of the next instruction).

恭喜,您已经观察到惰性符号重定位的作用。了解更多信息 here (尤其是“惰性绑定(bind)优化”部分)。

My query is where is the _GLOBAL_OFFSET_TABLE_ information maintained in the object file ?

不是(阅读引用博客文章会显示)。

关于linux - 动态库代码 stub 的执行流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23711473/

相关文章:

linux - 我如何在 Perl 中使用 paste 和 awk?

linux - 如何将文件从 ASCII 转换为 UTF-8?

winapi - VS 2012 命名修改仍然适用于 dll 导出

windows - .dll 和 .exe 的区别?

android - 另一个 ffmpeg/libx264 问题

PHP 不在某些用户的 session 中存储数据

linux - 所有操作系统库(给定的 linux 发行版)ABI 兼容吗?

c++ - 在 Qt 中创建 C++ 库

python - 使用自定义指标和 C++ DLL 时出现访问冲突读取错误和 MT4 崩溃

c++ - 使用 C/C++ 以外的语言构建共享库,特别是序言