提问人:Essometer 提问时间:9/26/2022 更新时间:9/27/2022 访问量:100
将 prel31 地址从 .ARM.exidx 部分
Converting an prel31 address to the actual address from an .ARM.exidx section
问:
我想了解 ARM 堆栈展开,因此,我仔细研究了 .我的二进制文件的 ARM.exidx 部分。二进制文件是使用 gcc 为 arm 构建的,用于 Cortex M0 32 位。
不出所料,我得到了 exidx 表,这是我用 objdump 转储的一个例子:
8012d34 c09bff7f ab07b180 909cff7f a907b180 ................
8012d44 c09cff7f b0ab0e80 509eff7f b0ab0c80 ........P.......
8012d54 249fff7f b0aa0580 b49fff7f b0ab0880 $...............
8012d64 aca0ff7f b0ab1080 74a1ff7f b0ab0880 ........t.......
8012d74 dca1ff7f b0b0b080 e4a1ff7f aa03b180 ................
8012d84 34a2ff7f b0ab0880 20a3ff7f b0ab1280 4....... .......
8012d94 20a4ff7f b0b0b080 28a4ff7f b0b0a880 .......(.......
8012da4 44a4ff7f 01000000 10a6ff7f b0b0b080 D...............
据我了解,第一个条目是我的程序中函数的调用地址(以 0x7f 结尾的那个),并且采用 prel31 格式以指示一般模型。
现在,我的问题是,如何将这些地址转换为实际的函数地址? 我在 linux for ARM 内核的 unwind.h 中找到了转换
/* Convert a prel31 symbol to an absolute address */
#define prel31_to_addr(ptr) \
({ \
/* sign-extend to 32 bits */ \
long offset = (((long)*(ptr)) << 1) >> 1; \
(unsigned long)(ptr) + offset; \
})
但是我无法从 exidx 部分获取地址以匹配我可以在地图文件中查找的地址。
exidx 中的地址应该与地图文件中的地址匹配还是我这边有误解?如果应该匹配,我该如何转换它们?
答:
1赞
artless noise
9/27/2022
#1
请参见:ARM extab 的结构。
该部分与可执行文件链接。和代码之间的距离很重要。您可以让链接器转储表地址。它实际上是“二进制偏移量”。例如exidx
exidx
10000: 8012d34 c09bff7f
然后,你拿0x7fff9bc0,第二个小端条目,并通过宏运行它。
偏移量为 0xffff9bc0 -> 6440 所以二进制偏移量是 10000-6440 -> 9bc0。
不幸的是,您的“exidx”偏移量可能没有0x10000那么好。如果有链接器文件,则可以添加填充,使其易于翻译以用于试验。
偏移量很重要,这就是使长度为 31 的 pointer 与地址 (prel31addr) 相关的原因。
评论