dde_linux: stack alignment on x86_64 in wifi/usb

platform_execute() is used to initially switch the stack of a
routine/task. While Thread_base::alloc_secondary_stack() properly aligns
the returned stack pointer the x86_64 assembler implementation did not
comply to stack frame management specified in the ABI.

The used (and most simple) stack-alignment check may pass a float to a
varargs function on x86, which requires the compiler to properly save
some XMM registers on stack.
This commit is contained in:
Christian Helmuth 2015-09-29 17:05:58 +02:00
parent 92541c49a6
commit 08541b68f7
2 changed files with 18 additions and 10 deletions

View File

@ -20,11 +20,15 @@
static inline
void platform_execute(void *sp, void *func, void *arg)
{
asm volatile ("movq %2, %%rdi;"
"movq %1, 0(%0);"
"movq %0, %%rsp;"
"call *0(%%rsp);"
: "+r" (sp), "+r" (func), "+r" (arg) : : "memory");
asm volatile ("movq %0, %%rsp;" /* load stack pointer */
"movq %%rsp, %%rbp;" /* caller stack frame (for GDB debugging) */
"movq %0, -8(%%rbp);"
"movq %1, -16(%%rbp);"
"movq %2, -24(%%rbp);"
"sub $24, %%rsp;" /* adjust to next stack frame */
"movq %2, %%rdi;" /* 1st argument */
"call *-16(%%rbp);" /* call func */
: : "r" (sp), "r" (func), "r" (arg));
}
#endif /* _X86_64__PLATFORM_H_ */

View File

@ -19,11 +19,15 @@
static inline
void platform_execute(void *sp, void *func, void *arg)
{
asm volatile ("movq %2, %%rdi;"
"movq %1, 0(%0);"
"movq %0, %%rsp;"
"call *0(%%rsp);"
: "+r" (sp), "+r" (func), "+r" (arg) : : "memory");
asm volatile ("movq %0, %%rsp;" /* load stack pointer */
"movq %%rsp, %%rbp;" /* caller stack frame (for GDB debugging) */
"movq %0, -8(%%rbp);"
"movq %1, -16(%%rbp);"
"movq %2, -24(%%rbp);"
"sub $24, %%rsp;" /* adjust to next stack frame */
"movq %2, %%rdi;" /* 1st argument */
"call *-16(%%rbp);" /* call func */
: : "r" (sp), "r" (func), "r" (arg));
}
#endif /* _X86_64__PLATFORM_H_ */