linux - Mips 和 mipsel 工具链为同一可执行文件提供不同的堆栈信息

标签 linux mips endianness toolchain gnu-toolchain

我有一个测试应用程序,我首先使用“mips-linux-gnu-gcc -EL”编译创建“exec_sigma”,然后使用“mipsel-linux-uclibc-gcc”创建“exec_bcm”。

在读完这些可执行文件后,我发现了很多差异。我主要关心 .debug_info 部分的差异

在 elf_sigma 中:它是:

[33].debug_info MIPS_DWARF 00000000 01357b 02fa1e 00 0 0 1

[34].debug_abbrev MIPS_DWARF 00000000 042f99 0040cd 00 0 0 1

在 elf_bcm 中:它是:

[32].debug_info MIPS_DWARF 00000000 02329b 0058ba 00 0 0 1

[33].debug_abbrev MIPS_DWARF 00000000 028b55 000619 00 0 0 1

这种差异(在大小上)导致我的应用程序中出现错误以执行堆栈跟踪。它适用于 mips-linux-gnu-gcc -EL 但不适用于 mipsel-linux-uclibc-gcc。我想知道为什么相同可执行文件的部分存在这种差异,这是否正常?

感谢阅读问题..

最佳答案

您实际上是在用两个不同的编译器编译相同的代码,确保编译器本身可能来自相同的源代码,但它们是为完成不同的工作而构建的,并且完成不同的工作。您不能期望可执行文件匹配,这里的错误是您的期望。

人们可能希望“您所要做的”就是翻转一些地址并翻转所有字节和半字数据,但除此之外具有相同的二进制文件。这是该理论的一个非常简单的问题。假设有一个编译器想要访问的字节,它位于地址 0x100000,使用一个字节序。单个指令 lui 可以将该地址加载到寄存器中,以便稍后读取字节。如果出于任何原因,字节序更改导致该地址需要较低的位,例如 0x100003,现在需要两条指令将该地址加载到寄存器和/或内存位置,并单次读取该内存位置。应该有可能制作一个编译器,其目标是在最后一刻之前独立于印度,生成无序代码(使用 .text 中的加载字将所有地址加载到寄存器中,不要使用任何立即加载),然后以某种方式跟踪所有这些并在最后修补它。你不得不问为什么会有人想要制作这样的编译器,这是一个不花时间的小用例。通常您希望编译器的性能不是这样的。

将编译后的程序反汇编或 objcopy 为二进制文件,然后比较两个二进制文件,您应该很快就能看出两者的不同之处,然后使用反汇编我上面描述的东西的味道可能不是具体的例子,而是那种事物。一旦必须由一个编译器而不是另一个编译器添加单个字节或字或指令(假设编译器在其他方面是相同的,但它们不是),寻址的变化可能并且将导致更多的指令差异,导致二进制文件继续发散。

关于linux - Mips 和 mipsel 工具链为同一可执行文件提供不同的堆栈信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10831214/

相关文章:

c - Little Endian 和 Big Endian 中的内存表示字符串

iOS CryptoSwift AES 加密到 Python 解密有效 - 但不是相反

c++ - libCurl 上传数据不活动超时不起作用

将 while 循环从 C 转换为 MIPS

c - MIPS 动态单链表

c - C语言中的字节序和移位运算符,我做得正确吗?

c++ - 之前缺少模板参数

linux - 更改外部硬盘的安装位置时出错

assembly - 如何在 MPLAB X 中使用 mips 汇编为每个宏调用创建唯一标签

c++ - 用mysql原生函数进行字节序转换