hrev51774 adds 1 changeset to branch 'master'
old head: 34cdda1dd5ebd4611eb2d1ae2dd0f50bf48bb227
new head: 13daa9299ebf06b9db6d6a06fa8724df274fc84f
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=13daa9299ebf+%5E34cdda1dd5eb
----------------------------------------------------------------------------
13daa9299ebf: Fix initial stack alignment on 64-bit systems.
gcc does re-align the stack in the main() function prologue, however,
we still need to set the right alignment for other cases: thread entry,
.init and .fini code that is executed before main() is called or after
it has returned, and signal handlers which may use a separate stack.
Part of #10509
[ Jérôme Duval <korli@xxxxxxxxxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev51774
Commit: 13daa9299ebf06b9db6d6a06fa8724df274fc84f
URL: http://cgit.haiku-os.org/haiku/commit/?id=13daa9299ebf
Author: Jérôme Duval <korli@xxxxxxxxxxxxxxxx>
Date: Sun Jan 14 08:54:25 2018 UTC
Committer: Adrien Destugues <pulkomandy@xxxxxxxxx>
Commit-Date: Wed Jan 24 07:59:55 2018 UTC
Ticket: https://dev.haiku-os.org/ticket/10509
----------------------------------------------------------------------------
1 file changed, 16 insertions(+), 11 deletions(-)
src/system/kernel/arch/x86/64/thread.cpp | 27 ++++++++++++++++-----------
----------------------------------------------------------------------------
diff --git a/src/system/kernel/arch/x86/64/thread.cpp
b/src/system/kernel/arch/x86/64/thread.cpp
index 9e535fefbe..1aab1a43a1 100644
--- a/src/system/kernel/arch/x86/64/thread.cpp
+++ b/src/system/kernel/arch/x86/64/thread.cpp
@@ -101,12 +101,16 @@ arch_randomize_stack_pointer(addr_t value)
static_assert(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1,
"randomization range is too big");
value -= random_value() & (B_PAGE_SIZE - 1);
- return value & ~addr_t(0xf);
+ return (value & ~addr_t(0xf)) - 8;
+ // This means, result % 16 == 8, which is what rsp should
adhere to
+ // when a function is entered for the stack to be considered
aligned to
+ // 16 byte.
}
static uint8*
-get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action)
+get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action,
+ size_t spaceNeeded)
{
// Use the alternate signal stack if we should and can.
if (thread->signal_stack_enabled
@@ -115,14 +119,15 @@ get_signal_stack(Thread* thread, iframe* frame, struct
sigaction* action)
|| frame->user_sp >= thread->signal_stack_base
+ thread->signal_stack_size)) {
addr_t stackTop = thread->signal_stack_base +
thread->signal_stack_size;
- return (uint8*)arch_randomize_stack_pointer(stackTop);
+ return (uint8*)arch_randomize_stack_pointer(stackTop -
spaceNeeded);
}
// We are going to use the stack that we are already on. We must not
touch
// the red zone (128 byte area below the stack pointer, reserved for use
// by functions to store temporary data and guaranteed not to be
modified
// by signal handlers).
- return (uint8*)(frame->user_sp - 128);
+ return (uint8*)((frame->user_sp - 128 - spaceNeeded) & ~addr_t(0xf)) -
8;
+ // align stack pointer (cf. arch_randomize_stack_pointer())
}
@@ -207,19 +212,19 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry,
void* args1,
void* args2)
{
addr_t stackTop = thread->user_stack_base + thread->user_stack_size;
+ addr_t codeAddr;
TRACE("arch_thread_enter_userspace: entry %#lx, args %p %p, "
"stackTop %#lx\n", entry, args1, args2, stackTop);
- stackTop = arch_randomize_stack_pointer(stackTop);
+ stackTop = arch_randomize_stack_pointer(stackTop - sizeof(codeAddr));
// Copy the address of the stub that calls exit_thread() when the thread
// entry function returns to the top of the stack to act as the return
// address. The stub is inside commpage.
addr_t commPageAddress = (addr_t)thread->team->commpage_address;
- addr_t codeAddr =
((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT]
+ codeAddr = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT]
+ commPageAddress;
- stackTop -= sizeof(codeAddr);
if (user_memcpy((void*)stackTop, (const void*)&codeAddr,
sizeof(codeAddr))
!= B_OK)
return B_BAD_ADDRESS;
@@ -315,10 +320,11 @@ arch_setup_signal_frame(Thread* thread, struct sigaction*
action,
signalFrameData->syscall_restart_return_value = frame->orig_rax;
// Get the stack to use and copy the frame data to it.
- uint8* userStack = get_signal_stack(thread, frame, action);
+ uint8* userStack = get_signal_stack(thread, frame, action,
+ sizeof(*signalFrameData) + sizeof(frame->ip));
- userStack -= sizeof(*signalFrameData);
- signal_frame_data* userSignalFrameData = (signal_frame_data*)userStack;
+ signal_frame_data* userSignalFrameData
+ = (signal_frame_data*)(userStack + sizeof(frame->ip));
if (user_memcpy(userSignalFrameData, signalFrameData,
sizeof(*signalFrameData)) != B_OK) {
@@ -326,7 +332,6 @@ arch_setup_signal_frame(Thread* thread, struct sigaction*
action,
}
// Copy a return address to the stack so that backtraces will be
correct.
- userStack -= sizeof(frame->ip);
if (user_memcpy(userStack, &frame->ip, sizeof(frame->ip)) != B_OK)
return B_BAD_ADDRESS;