[haiku-commits] haiku: hrev46886 - src/system/kernel/arch/x86/32

  • From: pulkomandy@xxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 18 Feb 2014 20:57:18 +0100 (CET)

hrev46886 adds 1 changeset to branch 'master'
old head: 224641c4b5cd7489167bc06d611f09db2cfe12df
new head: 9046835de9260baab79fa1422096bf0f1a9509ca
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=9046835+%5E224641c

----------------------------------------------------------------------------

9046835: Patch by Ingo Weinhold: fix stack alignment on x86.
  
  This is required to use some SSE instructions, which are generated by
  gcc 4.8, most notably when compiling WebKit code (but it may happen
  elsewhere as well).
  
  Fixes about 900 crashes and 10000 test failures in WebKit, so this must
  be working. Fixes #10509 for x86.

                             [ Adrien Destugues <pulkomandy@xxxxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev46886
Commit:      9046835de9260baab79fa1422096bf0f1a9509ca
URL:         http://cgit.haiku-os.org/haiku/commit/?id=9046835
Author:      Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Date:        Tue Feb 18 19:47:12 2014 UTC

Ticket:      https://dev.haiku-os.org/ticket/10509

----------------------------------------------------------------------------

1 file changed, 18 insertions(+), 14 deletions(-)
src/system/kernel/arch/x86/32/thread.cpp | 32 ++++++++++++++++------------

----------------------------------------------------------------------------

diff --git a/src/system/kernel/arch/x86/32/thread.cpp 
b/src/system/kernel/arch/x86/32/thread.cpp
index a625755..aa9ce0d 100644
--- a/src/system/kernel/arch/x86/32/thread.cpp
+++ b/src/system/kernel/arch/x86/32/thread.cpp
@@ -114,12 +114,16 @@ arch_randomize_stack_pointer(addr_t value)
 {
        STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1);
        value -= random_value() & (B_PAGE_SIZE - 1);
-       return value & ~addr_t(0xf);
+       return (value & ~addr_t(0xf)) - 4;
+               // This means, result % 16 == 12, which is what esp 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, struct iframe* frame, struct sigaction* 
action)
+get_signal_stack(Thread* thread, struct iframe* frame, struct sigaction* 
action,
+       size_t spaceNeeded)
 {
        // use the alternate signal stack if we should and can
        if (thread->signal_stack_enabled
@@ -128,10 +132,11 @@ get_signal_stack(Thread* thread, struct 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);
        }
 
-       return (uint8*)frame->user_sp;
+       return (uint8*)((frame->user_sp - spaceNeeded) & ~addr_t(0xf)) - 4;
+               // align stack pointer (cf. arch_randomize_stack_pointer())
 }
 
 
@@ -223,7 +228,7 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, 
void* args1,
        TRACE(("arch_thread_enter_userspace: entry 0x%lx, args %p %p, "
                "ustack_top 0x%lx\n", entry, args1, args2, stackTop));
 
-       stackTop = arch_randomize_stack_pointer(stackTop);
+       stackTop = arch_randomize_stack_pointer(stackTop - sizeof(args));
 
        // 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
@@ -233,7 +238,6 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, 
void* args1,
                + commPageAddress;
        args[1] = (uint32)args1;
        args[2] = (uint32)args2;
-       stackTop -= sizeof(args);
 
        if (user_memcpy((void *)stackTop, args, sizeof(args)) < B_OK)
                return B_BAD_ADDRESS;
@@ -325,11 +329,13 @@ arch_setup_signal_frame(Thread* thread, struct sigaction* 
action,
 
        // get the stack to use -- that's either the current one or a special 
signal
        // stack
-       uint8* userStack = get_signal_stack(thread, frame, action);
+       uint32 stackFrame[2];
+       uint8* userStack = get_signal_stack(thread, frame, action,
+               sizeof(*signalFrameData) + sizeof(stackFrame));
 
        // copy the signal frame data onto the stack
-       userStack -= sizeof(*signalFrameData);
-       signal_frame_data* userSignalFrameData = (signal_frame_data*)userStack;
+       signal_frame_data* userSignalFrameData
+               = (signal_frame_data*)(userStack + sizeof(stackFrame));
        if (user_memcpy(userSignalFrameData, signalFrameData,
                        sizeof(*signalFrameData)) != B_OK) {
                return B_BAD_ADDRESS;
@@ -337,12 +343,10 @@ arch_setup_signal_frame(Thread* thread, struct sigaction* 
action,
 
        // prepare the user stack frame for a function call to the signal 
handler
        // wrapper function
-       uint32 stackFrame[2] = {
-               frame->ip,              // return address
-               (addr_t)userSignalFrameData, // parameter: pointer to signal 
frame data
-       };
+       stackFrame[0] = frame->ip;
+       stackFrame[1] = (addr_t)userSignalFrameData;
+               // parameter: pointer to signal frame data
 
-       userStack -= sizeof(stackFrame);
        if (user_memcpy(userStack, stackFrame, sizeof(stackFrame)) != B_OK)
                return B_BAD_ADDRESS;
 


Other related posts: