Fix stack pointer alignment for x86_64 platforms

The x86_64 ABI requires the stack pointer to be 16-byte aligned before the
call of a function and decreased by 8 at the function entrypoint (after
the return address has been pushed to the stack).

Currently, when a new Genode thread gets created, the initial stack
pointer is aligned to 16 byte. On Genode/Linux, the thread entry function
is entered by a 'call' instruction, so the stack pointer alignment at the
function entrypoint is correct. On Fiasco.OC and NOVA, however, the thread
entry function gets executed without a return address being pushed to the
stack, so at the function entrypoint the stack pointer is still aligned to
16 byte, which can cause problems with compiler-generated SSE
instructions.

With this patch, the stack pointer given to a new thread gets aligned to
16 bytes and decreased by 8 by default, since most of the currently
supported base platforms execute the thread entry function without pushing
a return address to the stack. For base-linux, the stack pointer gets
realigned to 16 bytes before the thread entry function gets called.

Fixes #1043.
This commit is contained in:
Christian Prochaska
2014-01-31 16:50:08 +01:00
committed by Christian Helmuth
parent a19d491fbd
commit 4b420f6e71
6 changed files with 26 additions and 9 deletions

View File

@ -122,9 +122,7 @@ void Thread_base::start()
threadlib_initialized = true;
}
/* align initial stack to 16 byte boundary */
void *thread_sp = (void *)((addr_t)(stack_top()) & ~0xf);
_tid.tid = lx_create_thread(Thread_base::_thread_start, thread_sp, this);
_tid.tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
_tid.pid = lx_getpid();
/* wait until the 'thread_start' function got entered */

View File

@ -83,8 +83,7 @@ L(thread_start):
.cfi_startproc;
/* Clearing frame pointer is insufficient, use CFI. */
.cfi_undefined %eip;
/* Note: %esi is zero. */
movl %esi,%ebp /* terminate the stack frame */
xorl %ebp,%ebp /* terminate the stack frame */
call *%ebx
#ifdef PIC
call L(here)

View File

@ -17,6 +17,9 @@
lx_clone:
.cfi_startproc
/* Align the new stack pointer to 16 bytes. */
andq $0xfffffffffffffff0, %rsi
/* Insert the argument onto the new stack. */
subq $16,%rsi
movq %rcx,8(%rsi)
@ -51,7 +54,7 @@ L(thread_start):
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
xorl %ebp, %ebp
xorq %rbp, %rbp
/* Set up arguments for the function call. */
popq %rax /* Function to call. */