From: Nadav Har'El <n...@scylladb.com> Committer: Nadav Har'El <n...@scylladb.com> Branch: master
gcc 7: fix alignment of main()'s stack This patch fixes an early boot crash (a #GP) of the optimized build built with gcc 7. According to the x86_64 ABI, C functions must be called with the stack 16-byte aligned. The called function may and do use this assumption to create aligned objects on the stack without wasting time to verify the actual alignment of the stack. We've gone through great lengths to ensure this alignment guarantee is preserved throughout OSv, but one place we got it wrong: where we call loader.cc's main() function, we set up a properly aligned stack, but the used JMP instead of CALL to call the function main(). It might seem that using jmp to a function that will never return anyway is fine. But it is not fine, because CALL pushes an 8-byte return address on the stack, which means that JMP leaves the stack offset by 8 bytes from the expected 16-byte alignment. An interesting question is why we only noticed this now, with gcc 7, when this is one of the oldest lines of codes in OSv (from December 2012). The reason is that this bug only effects loader.cc's main() function, and no other function or thread in OSv, and main() is a tiny function which does very little and has little chance to care about alignment. However, one thing it does do is to create a "thread" object on the stack. The compiler thinks this thread object is 16-byte aligned (alignof(thread)==16) but it is not, it is offset by 8 bytes from this correct alignment. It appears that with gcc 7's optimizer, something in thread's constructor uses certain instructions which only work on 16-byte aligned data (e.g., MOVAPS), which the compiler assumes, and when we are wrongly aligned the result is a general protection fault and a crash. Without optimizations enabled, this wrong alignment doesn't cause this crash, even on gcc 7. The patch trivially fixes JMP to CALL, which is what the callee's (main()) expects we would call to preserve the stack's alignment. Signed-off-by: Nadav Har'El <n...@scylladb.com> Message-Id: <20170712185922.16302-1-...@scylladb.com> --- diff --git a/arch/x64/boot.S b/arch/x64/boot.S --- a/arch/x64/boot.S +++ b/arch/x64/boot.S @@ -108,7 +108,7 @@ start64: call premain mov __argc, %edi mov __argv, %rsi - jmp main + call main .cfi_endproc # The smp trampoline must be in the lower 1MB, so we manually relocate -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.