Mips and mipsel toolchain giving different stack information for same executable

1k views Asked by At

I have a test application which I compiled first using 'mips-linux-gnu-gcc -EL ' to create "exec_sigma" and then using 'mipsel-linux-uclibc-gcc' to create "exec_bcm" .

After doing readelf of these executables, I got many differences. I am mainly concerned about difference in .debug_info section

In elf_sigma : it is:

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

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

and in elf_bcm : it is :

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

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

This difference (in size) is causing a bug in my application to do a stack trace. It works for mips-linux-gnu-gcc -EL but not for mipsel-linux-uclibc-gcc. I want to know why this difference in the sections for same executable and is it normal ??

Thanks for reading the question..

1

There are 1 answers

0
old_timer On BEST ANSWER

you are essentially compiling the same code with two different compilers, sure the compilers may come from the same source code themselves but are built to do a different job and do a different job. You cannot expect the executables to match, the bug here is your expectation.

One might hope that "All you have to do" is flip some addresses around and flip all the byte and halfword data around but otherwise have the same binary. Here is one very simple problem with that theory. Lets say there is a byte the compiler wants to access and it is at address 0x100000 using one endian. a single instruction lui can load that address into a register for later reading the byte. If for any reason an endian change causes that address to need lower bits, for example 0x100003 now it takes two instructions to load that address into the register and/or a memory location and a single read of that memory location. It should be possible to make a compiler whose goal it is to be indian independent until the last possible moment, generate endianless code (load all addresses into registers using a load word from .text dont use any load immediates), then somehow keep track of all that and patch it at the end. You have to ask why that would anyone want to make such a compiler, it is such a small use case not to take the time. Normally you want performance out of your compiler not something like this.

Take your compiled programs, either disassemble or objcopy to binary, then compare the two binaries, you should quickly see where the two diverge, then using the disassembly the flavor of thing I described above probably not the specific example but that kind of thing. As soon as a single byte or word or instruction has to be added by one compiler and not the other (assuming the compilers were otherwise identical which they are not) the change in addressing can and will cause more instruction differences resulting in the binaries continuing to diverge.