GDB如何知道可执行文件的重定位位置?

时间:2014-12-02 18:18:45

标签: gdb relocation

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

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

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

3 个答案:

答案 0 :(得分:3)

  

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

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

  

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

正确。

  

GDB如何计算偏移?

GDB计算共享库的偏移量的方式相同(PIE可执行文件实际上是共享库的特例)。 ld.so和GDB之间有一个定义的接口,由_dl_debug_state()函数组成(GDB在其上设置内部断点,并且每当映射新的ld.so图像时ELF调用进入过程)和struct r_debug。后者指向struct link_map s的链接列表,该结构的l_addr成员是linked-at和loaded-at地址之间的偏移量。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

在Linux上,每个进程在address space中都有自己的virtual memory

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