Closed
Description
When cross-compiling a minimal no_std
/no_main
/no_stack_check
program for i686-unknown-linux-gnu
on OS X 10.10, rustc inserts two anomalous instructions during machine code generation. Notice the call/pop eax just after .Ltmp2
.
From assembly:
ain:
.cfi_startproc
pushl %ebx
.Ltmp0:
.cfi_def_cfa_offset 8
subl $24, %esp
.Ltmp1:
.cfi_def_cfa_offset 32
.Ltmp2:
.cfi_offset %ebx, -8
calll .L0$pb
.L0$pb:
popl %eax
.Ltmp3:
addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp3-.L0$pb), %eax
...
From disassembly:
Disassembly of section .text:Disassembly of section .text.main:
main:
0: 53 pushl %ebx
1: 83 ec 18 subl $24, %esp
4: e8 00 00 00 00 calll 0
9: 58 popl %eax
a: 81 c0 03 00 00 00 addl $3, %eax
...
Popping the former frame pointer would seem to destroy the stack frame. Actually what is depicted above just pops an IP; however it does destroy the stack later. Note that it is never re-pushed later in the function.
Now, this is does not happen when rustc instead emits LLVM IR that is separately compiled with clang. The issue occurs in larger code, and since executables produced with this issue segfault in qemu, I'm forced to compile/assemble separately with clang.