[haiku-commits] haiku: hrev51774 - src/system/kernel/arch/x86/64

  • From: pulkomandy@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 24 Jan 2018 02:59:57 -0500 (EST)

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;
 


Other related posts:

  • » [haiku-commits] haiku: hrev51774 - src/system/kernel/arch/x86/64 - pulkomandy