我有一个测试应用程序,我首先使用'mips-linux-gnu-gcc -EL'编译创建“exec_sigma”,然后使用'mipsel-linux-uclibc-gcc'创建“exec_bcm”。
在对这些可执行文件进行readelf之后,我得到了许多不同之处。我主要关注.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。我想知道为什么相同的可执行文件中的这些差异,这是正常的??
感谢您阅读此问题..
答案 0 :(得分:0)
您实际上是使用两个不同的编译器编译相同的代码,确保编译器本身可能来自相同的源代码,但是可以用来完成不同的工作并完成不同的工作。您不能指望可执行文件匹配,这里的错误是您的期望。
有人可能希望“你所要做的就是”翻转一些地址并翻转所有的字节和半字数据,否则会有相同的二进制数。这是该理论的一个非常简单的问题。假设编译器想要访问一个字节,并且使用一个端点在地址0x100000。单个指令lui可以将该地址加载到寄存器中以便稍后读取该字节。如果由于任何原因,字节序更改导致该地址需要较低位,例如0x100003,则现在需要两条指令将该地址加载到寄存器和/或存储器位置以及该存储器位置的单次读取。应该可以制作一个编译器,其目标是印度独立直到最后可能的时刻,生成无字节代码(使用来自.text的加载字将所有地址加载到寄存器中,不要使用任何加载立即),然后以某种方式跟踪所有这些并在最后修补它。你必须问为什么有人想要制作这样的编译器,这是一个不花时间的小用例。通常,您希望编译器的性能不是这样的。
把你编译好的程序,反汇编或objcopy转换为二进制,然后比较两个二进制文件,你应该快速看到两个分歧的位置,然后使用反汇编我上面描述的东西的味道可能不是具体的例子,但那种事情。一旦一个字节或字或指令必须由一个编译器而不是另一个编译器添加(假设编译器在其他方面是相同的而不是它们),寻址的改变可以并且将导致更多的指令差异,从而导致二进制文件继续发散。