矮人偏移和共享对象与可执行文件

时间:2016-07-12 18:28:55

标签: backtrace dwarf

好的,我已经使用Linux Dwarf ldw 库将 backtrace_symbols 输出转换为源代码和行号,但我遇到了麻烦。 backtrace_symbols 给出了内存中的偏移量,在用作Dwarf的输入之前,我从中减去基地址(使用 dladdr()获得)。但似乎对于父可执行文件,我不应该减去基址,因为矮人偏移似乎包含它。

那么我如何区分我的代码中的EXE和SO(我希望有更好的东西比寻找结束.so')或者是否有不同的功能我可以调用它来获取父EXE的基址或零吗?

2 个答案:

答案 0 :(得分:2)

不确定这是否是最好的方法,但是 ldw 有一个函数 dwarf_getelf(),它可以让你获得ELF信息,从那里使用 elf32 / 64_getehdr(),然后查看 e_type 字段。如果 e_type ET_DYN ,则它是共享对象,您应该继续使用 dladdr 来查找要从其他地址删除的偏移量只需直接使用 backtrace 生成的地址。

答案 1 :(得分:1)

是的,你是对的。如果可执行文件是ET_EXEC(不是DT_DYN,即它不是与位置无关的可执行文件),则DWARF中的虚拟地址是程序映像中的真实虚拟地址。对于DT_DYN,DWARF中的地址是模块基址的偏移量。

这在DWARF规范的7.3中有解释:

  

可执行文件的调试信息中的重定位地址   对象是虚拟地址和重定位的地址   调试信息对于共享对象是偏移相对   到那个加载的最低内存区域的开头   共享内存。

您应该在ELF标题中使用e_type来区分它们。