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.

Reply via email to