I'm debugging a crash in linux, and am going through the assembly of the function cxa_finalize
The crash happens on a source line that appears unreachable:
cmp %edx,%esi // f >= &funcs->fns[0]
jae 0xb6e17b88 // enter for loop
jmp 0xb6e17c08 // exit for loop
lea 0x0(%esi,%eiz,1),%esi // crashes here - how do we even get here since there is a
// jmp above us, and nothing jumps to here
cmp %edi,0xc(%esi) // d == f->func.cxa.dso_handle (jumped to from below)
later on in this method, there is another lea 0x0(%esi,%eiz,1),%esi instruction that appears after a jmp and nop that also appears unreachable. In that case, the jmp is also exiting a for loop.
Is there some paradigm going on here that puts in unreachable instructions?
Edit: Turns out it wasn't crashing on the lea instruction, but on the cmp instruction after it, when accessing the memory at esi.
I found the answer here
Sometimes GCC inserts NOP instructions into the code stream to ensure proper alignment and stuff like that. The NOP instruction takes one byte, so you would think that you could just add as many as needed. But according to Ian Lance Taylor, it’s faster for the chip to execute one long instruction than many short instructions. So rather than inserting seven NOP instructions, they instead use one bizarro LEA, which uses up seven bytes and is semantically equivalent to a NOP
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With