OSDN Git Service

Fix alignment error for pthread_internal_t/pthread stack.
authorYabin Cui <yabinc@google.com>
Fri, 20 Mar 2015 17:58:04 +0000 (10:58 -0700)
committerYabin Cui <yabinc@google.com>
Fri, 20 Mar 2015 21:41:52 +0000 (14:41 -0700)
aligned attribute can only control compiler's behavior, but we
are manually allocating pthread_internal_t. So we need to make
sure of alignment manually.

Change-Id: Iea4c46eadf10dfd15dc955c5f41cf6063cfd8536

libc/bionic/pthread_create.cpp
libc/bionic/pthread_internal.h

index a4bd054..5389f14 100644 (file)
@@ -162,15 +162,16 @@ static int __allocate_thread(pthread_attr_t* attr, pthread_internal_t** threadp,
   }
 
   // Mapped space(or user allocated stack) is used for:
-  //   thread_internal_t
+  //   pthread_internal_t
   //   thread stack (including guard page)
-  stack_top -= sizeof(pthread_internal_t);
+
+  // To safely access the pthread_internal_t and thread stack, we need to find a 16-byte aligned boundary.
+  stack_top = reinterpret_cast<uint8_t*>(
+                (reinterpret_cast<uintptr_t>(stack_top) - sizeof(pthread_internal_t)) & ~0xf);
+
   pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(stack_top);
   attr->stack_size = stack_top - reinterpret_cast<uint8_t*>(attr->stack_base);
 
-  // No need to check stack_top alignment. The size of pthread_internal_t is 16-bytes aligned,
-  // and user allocated stack is guaranteed by pthread_attr_setstack.
-
   thread->mmap_size = mmap_size;
   thread->attr = *attr;
   __init_tls(thread);
index 538e0da..13964c2 100644 (file)
@@ -103,7 +103,7 @@ struct pthread_internal_t {
    */
 #define __BIONIC_DLERROR_BUFFER_SIZE 512
   char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
-} __attribute__((aligned(16))); // Align it as thread stack top below it should be aligned.
+};
 
 __LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread, bool add_to_thread_list);
 __LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread);