noux: consider stack alignment constraints

The interim stack in a forked noux process has to consider the architecture
dependent stack alignment constraints.

Fix #1852
This commit is contained in:
Stefan Kalkowski 2016-01-15 15:48:20 +01:00 committed by Christian Helmuth
parent 040cd95580
commit b0b4c3c7fa
4 changed files with 14 additions and 15 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)) {