3

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

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

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

4

3 回答 3

5

我知道现代操作系统(如 Linux)并不总是在最初链接的同一地址执行应用程序。

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

但是,当调试器开始环顾四周时,它需要知道原始链接地址和最终执行地址之间的关系。

正确的。

GDB如何计算偏移量?

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

于 2014-12-02T19:55:40.690 回答
0

如果我理解您的意思,我认为您实际上指的是虚拟内存寻址这不是由 GDB 处理的,而是由操作系统处理的。

http://www.cs.utexas.edu/users/witchel/372/lectures/15.VirtualMemory.pdf

于 2014-12-02T18:23:33.447 回答
-1

在 Linux 上,每个进程在虚拟内存中都有自己的地址空间

ELF可执行文件包含一个标头,描述内存中的段(以及它们在可执行文件中的相应部分)。

于 2014-12-02T18:23:17.873 回答