gdb - GDB 如何知道可执行文件被重定位到哪里了?

标签 gdb relocation

我知道 Linux 等现代操作系统并不总是在应用程序最初链接的同一地址执行应用程序。但是,当调试器开始四处查看时,它需要知道原始链接地址和最终执行地址之间的关系。 GDB如何计算偏移量?

澄清:我不是在谈论虚拟内存。也就是说,我(我相信是)对虚拟内存如何工作以及如何在该地址空间中完全运行有一个合理的理解。当我从 ELF 中转储符号表时,我的符号位于一个位置,但当我从内存中获取它们的地址时,它们位于另一个位置。

在这种特殊情况下,我有一个字符串,它在链接的可执行文件中位于地址 0x0E984141。在该进程的内存转储中,它位于地址 0x0E3F2781。 .rodata 部分中的所有内容至少都被移动了 0x5919C0。它似乎类似于地址空间布局随机化。

最佳答案

I know modern OSs such as Linux don't always execute an application at the same address it was originally linked.

这仅适用于与位置无关的可执行文件(与 -pie 标志链接)。

When a debugger starts looking around though, it needs to know the relationship between the original link address and the final executing address.

正确。

How does GDB calculate the offset?

与 GDB 计算共享库偏移量的方式相同(PIE 可执行文件实际上是共享库的特例)。 ld.so 和 GDB 之间有一个已定义的接口(interface),由 _dl_debug_state() 函数组成(GDB 在该函数上设置内部断点,ld.so 在将新的 ELF 图像映射到进程中时调用)和 struct r_debug。后者指向 struct link_map 的链表,该结构的 l_addr 成员是链接地址和加载地址之间的偏移量。

关于gdb - GDB 如何知道可执行文件被重定位到哪里了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27256275/

相关文章:

gdb - 为什么 gdb 拒绝加载我的共享对象以及验证操作是什么

assembly - 什么是可重定位和绝对机器代码?

perl - ActivePerl 在安装过程中遇到 "relocates"文件时在做什么?

linux - GDB如何执行共享库的基地址[ info sharedlibrary 命令的内部结构]

c++ - PE注入(inject)图像重定位

macos - 在 OSX 中安装 GDBserver

android - 使用 gdb 附加到 android native 应用程序关闭设备上的应用程序

c++ - 链接器是做什么的?

macos - 如何在 Mac OSX El Capitan 中安装 gdb(调试器)?

c++ - gdb 输入/输出错误远程调试到 Android