Alexandre Julliard : ntdll: Ensure alignment of static TLS data and free it at thread exit.

Alexandre Julliard julliard at winehq.org
Wed Dec 15 11:29:58 CST 2010


Module: wine
Branch: master
Commit: e272b31b6bdc87307019c00da1be097c23a19e0e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e272b31b6bdc87307019c00da1be097c23a19e0e

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Dec 15 13:16:55 2010 +0100

ntdll: Ensure alignment of static TLS data and free it at thread exit.

---

 dlls/ntdll/loader.c |   24 ++++++++++--------------
 1 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 0724879..19d484a 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -97,6 +97,8 @@ static HANDLE main_exe_file;
 static UINT tls_module_count;      /* number of modules with TLS directory */
 static UINT tls_total_size;        /* total size of TLS storage */
 static const IMAGE_TLS_DIRECTORY **tls_dirs;  /* array of TLS directories */
+#define TLS_ALIGNMENT (2 * sizeof(void *))
+#define TLS_ALIGN(size) (((size) + TLS_ALIGNMENT - 1) & ~(TLS_ALIGNMENT - 1))
 
 static RTL_CRITICAL_SECTION loader_section;
 static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
@@ -843,7 +845,7 @@ static NTSTATUS alloc_process_tls(void)
             continue;
         size = (dir->EndAddressOfRawData - dir->StartAddressOfRawData) + dir->SizeOfZeroFill;
         if (!size && !dir->AddressOfCallBacks) continue;
-        tls_total_size += size;
+        tls_total_size += TLS_ALIGN(size);
         tls_module_count++;
     }
     if (!tls_module_count) return STATUS_SUCCESS;
@@ -878,24 +880,19 @@ static NTSTATUS alloc_thread_tls(void)
 {
     void **pointers;
     char *data;
-    UINT i;
+    UINT i, size;
 
     if (!tls_module_count) return STATUS_SUCCESS;
 
-    if (!(pointers = RtlAllocateHeap( GetProcessHeap(), 0,
-                                      tls_module_count * sizeof(*pointers) )))
+    size = TLS_ALIGN( tls_module_count * sizeof(*pointers) );
+    if (!(pointers = RtlAllocateHeap( GetProcessHeap(), 0, size + tls_total_size )))
         return STATUS_NO_MEMORY;
-
-    if (!(data = RtlAllocateHeap( GetProcessHeap(), 0, tls_total_size )))
-    {
-        RtlFreeHeap( GetProcessHeap(), 0, pointers );
-        return STATUS_NO_MEMORY;
-    }
+    data = (char *)pointers + size;
 
     for (i = 0; i < tls_module_count; i++)
     {
         const IMAGE_TLS_DIRECTORY *dir = tls_dirs[i];
-        ULONG size = dir->EndAddressOfRawData - dir->StartAddressOfRawData;
+        size = dir->EndAddressOfRawData - dir->StartAddressOfRawData;
 
         TRACE( "thread %04x idx %d: %d/%d bytes from %p to %p\n",
                GetCurrentThreadId(), i, size, dir->SizeOfZeroFill,
@@ -903,9 +900,8 @@ static NTSTATUS alloc_thread_tls(void)
 
         pointers[i] = data;
         memcpy( data, (void *)dir->StartAddressOfRawData, size );
-        data += size;
-        memset( data, 0, dir->SizeOfZeroFill );
-        data += dir->SizeOfZeroFill;
+        memset( data + size, 0, dir->SizeOfZeroFill );
+        data += TLS_ALIGN( size + dir->SizeOfZeroFill );
     }
     NtCurrentTeb()->ThreadLocalStoragePointer = pointers;
     return STATUS_SUCCESS;




More information about the wine-cvs mailing list