From b0b4c3c7fab812b42d932d555601794d296a51d6 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 15 Jan 2016 15:48:20 +0100 Subject: [PATCH] noux: consider stack alignment constraints The interim stack in a forked noux process has to consider the architecture dependent stack alignment constraints. Fix #1852 --- repos/base/include/base/thread.h | 9 ++------- repos/base/include/spec/arm/cpu/consts.h | 9 +++++---- repos/base/include/spec/x86/cpu/consts.h | 7 +++++-- repos/ports/src/lib/libc_noux/plugin.cc | 4 ++-- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/repos/base/include/base/thread.h b/repos/base/include/base/thread.h index 2c0f0939a5..3f8841b6b3 100644 --- a/repos/base/include/base/thread.h +++ b/repos/base/include/base/thread.h @@ -110,14 +110,9 @@ class Genode::Thread_base /** * Top of stack * - * The alignment matches an initial stack frame, which is - * sufficient for the AMD64 ABI (stack top + adjustment is 16-byte - * aligned). + * The alignment constrains are enforced by the CPU-specific ABI. */ - addr_t stack_top() const - { - return ((addr_t)_stack & ~0xf) - Abi::stack_adjustment(); - } + addr_t stack_top() const { return Abi::stack_align((addr_t)_stack); } /** * Ensure that the stack has a given size at the minimum diff --git a/repos/base/include/spec/arm/cpu/consts.h b/repos/base/include/spec/arm/cpu/consts.h index 7bcbc71be7..19a3bc5e42 100644 --- a/repos/base/include/spec/arm/cpu/consts.h +++ b/repos/base/include/spec/arm/cpu/consts.h @@ -18,11 +18,12 @@ namespace Abi { - /** - * On ARM a call (or branch) will not change the stack pointer, so we do not - * need stack adjustment + /* + * On ARM we align the stack top to 16-byte. As a call (or branch) will not + * change the stack pointer, we need no further stack adjustment. */ - static constexpr Genode::size_t stack_adjustment() { return 0; } + static Genode::addr_t stack_align(Genode::addr_t addr) { + return (addr & ~0xf); } /** * Do ABI specific initialization to a freshly created stack diff --git a/repos/base/include/spec/x86/cpu/consts.h b/repos/base/include/spec/x86/cpu/consts.h index 3b7ccbf318..4c67311872 100644 --- a/repos/base/include/spec/x86/cpu/consts.h +++ b/repos/base/include/spec/x86/cpu/consts.h @@ -37,9 +37,12 @@ namespace X86 { namespace Abi { /** - * On x86 a call will result in a growth of the stack by machine word size + * On x86, we align the stack top to 16 byte. As a call will result in + * growth of the stack, we further adjust the stack-top address to comply + * to the AMD64 ABI rule "stack top + adjustment is 16-byte aligned". */ - static constexpr Genode::size_t stack_adjustment() { return sizeof(Genode::addr_t); } + static Genode::addr_t stack_align(Genode::addr_t addr) { + return (addr & ~0xf) - sizeof(Genode::addr_t); } /** * Do ABI specific initialization to a freshly created stack diff --git a/repos/ports/src/lib/libc_noux/plugin.cc b/repos/ports/src/lib/libc_noux/plugin.cc index bd27ae1676..7c1dd81d35 100644 --- a/repos/ports/src/lib/libc_noux/plugin.cc +++ b/repos/ports/src/lib/libc_noux/plugin.cc @@ -564,8 +564,8 @@ extern "C" pid_t fork(void) stack_in_context_area = &dummy; /* got here during the normal control flow of the fork call */ - sysio()->fork_in.ip = (Genode::addr_t)(&fork_trampoline); - sysio()->fork_in.sp = (Genode::addr_t)(&stack[STACK_SIZE]); + sysio()->fork_in.ip = (Genode::addr_t)(&fork_trampoline); + sysio()->fork_in.sp = Abi::stack_align((Genode::addr_t)&stack[STACK_SIZE]); sysio()->fork_in.parent_cap_addr = (Genode::addr_t)(&new_parent); if (!noux_syscall(Noux::Session::SYSCALL_FORK)) {