我知道像Linux这样的现代操作系统并不总是在最初链接的同一地址执行应用程序。当调试器开始环顾四周时,它需要知道原始链接地址和最终执行地址之间的关系。 GDB如何计算偏移量?
澄清:我不是在谈论虚拟内存。也就是说,我(我相信是)对虚拟内存如何工作以及完全在该地址空间中运行的合理理解。当我从ELF转储符号表时,我在一个位置有符号,但是当我从内存中取出它们的地址时,我在另一个位置。
在这种特殊情况下,我有一个字符串,链接的可执行文件位于地址0x0E984141。在该进程的内存转储中,它位于地址0x0E3F2781。 .rodata部分中的所有内容至少已经移位了0x5919C0。它看起来像地址空间布局随机化。
答案 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可执行文件包含一个描述内存中段的标题(以及它们在可执行文件中的相应部分)。