gpt4 book ai didi

c - nm 输出和 gdb 中的函数地址不同

转载 作者:IT王子 更新时间:2023-10-29 00:55:00 26 4
gpt4 key购买 nike

我们只关注 Rect_IsEmpty() 函数。

nm 命令给我这个输出:

(...)    
00021af0 T Rect_IsEmpty
(...)

另一方面,当我启动 gdb 并看到这个函数的地址时,我得到:

(gdb) info address Rect_IsEmpty
Symbol "Rect_IsEmpty" is at 0x8057c84 in a file compiled without debugging.

谁能解释一下为什么这些地址不一样? gdb 从哪里得到这个地址?

最佳答案

nm 为您提供错位名称符号表的地址偏移量,而 gdb 为您提供实际虚拟进程的内存地址,该地址在您每次运行该进程时都会更改。 (在GDB中runstart之前,它使用与nm相同的方法获取符号地址,在PIE可执行文件中使用相同的占位符基地址.)

nm 只是一个工具,它显示您从代码段开头的偏移量。在你的情况下:

00021af0 T Rect_IsEmpty

简单的意思是,如果可执行文件映射到 0x1000 的图像基址(一个虚拟占位符),则符号 Rect_IsEmpty 的地址为 00021af0 ld 在链接 PIE 时默认使用的值。通常代码段首先以 .text 开头,因此它的开头将在 nm 中显示 0x1000 的地址或objdump -d.

在 Linux 上运行与位置无关的可执行文件时,ASLR 机制用于将整个对象的基地址随机化为 0x1000 以外的地址。 ( Segments keep the same relative offset from each other ,因此 PC 相对寻址可以工作,例如对于 .data.rodata 来自 .text .)

GDB 禁用了实际的随机化,但内核仍然使用高基地址,而不是 0x1000。每次都是一样的。

( If you built a traditional non-PIE executable ,内核将无法选择加载它的位置,这将是链接器的选择,例如在 0x400000nmobjdump 可以看到,GDB 也可以在不启动程序的情况下看到。gcc -fno-pie -no-pie 如果你想要的话。)

当使用调试器查找函数的地址时,您会在 ASLR 完成其工作后看到进程代码段内的符号地址。

Here is来自 IBM 的一篇关于共享库和 another one 的好文章关于过程链接表和全局偏移表。

关于c - nm 输出和 gdb 中的函数地址不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31293871/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com