Alexandre Julliard : ntdll: Allocate a separate pointer for each TLS slot.

Alexandre Julliard julliard at winehq.org
Mon Dec 23 13:44:58 CST 2013


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Dec 23 12:27:39 2013 +0100

ntdll: Allocate a separate pointer for each TLS slot.

---

 dlls/ntdll/loader.c |   39 +++++++++++++++++++++++----------------
 1 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 5eb8755..817cf8a 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -96,10 +96,7 @@ static struct builtin_load_info *builtin_load_info = &default_load_info;
 
 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 =
@@ -887,12 +884,11 @@ static NTSTATUS alloc_process_tls(void)
             continue;
         size = (dir->EndAddressOfRawData - dir->StartAddressOfRawData) + dir->SizeOfZeroFill;
         if (!size && !dir->AddressOfCallBacks) continue;
-        tls_total_size += TLS_ALIGN(size);
         tls_module_count++;
     }
     if (!tls_module_count) return STATUS_SUCCESS;
 
-    TRACE( "count %u size %u\n", tls_module_count, tls_total_size );
+    TRACE( "count %u\n", tls_module_count );
 
     tls_dirs = RtlAllocateHeap( GetProcessHeap(), 0, tls_module_count * sizeof(*tls_dirs) );
     if (!tls_dirs) return STATUS_NO_MEMORY;
@@ -921,29 +917,34 @@ static NTSTATUS alloc_process_tls(void)
 static NTSTATUS alloc_thread_tls(void)
 {
     void **pointers;
-    char *data;
     UINT i, size;
 
     if (!tls_module_count) return STATUS_SUCCESS;
 
-    size = TLS_ALIGN( tls_module_count * sizeof(*pointers) );
-    if (!(pointers = RtlAllocateHeap( GetProcessHeap(), 0, size + tls_total_size )))
+    if (!(pointers = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                      tls_module_count * sizeof(*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];
+
+        if (!dir) continue;
         size = dir->EndAddressOfRawData - dir->StartAddressOfRawData;
+        if (!size && !dir->SizeOfZeroFill) continue;
+
+        if (!(pointers[i] = RtlAllocateHeap( GetProcessHeap(), 0, size + dir->SizeOfZeroFill )))
+        {
+            while (i) RtlFreeHeap( GetProcessHeap(), 0, pointers[--i] );
+            RtlFreeHeap( GetProcessHeap(), 0, pointers );
+            return STATUS_NO_MEMORY;
+        }
+        memcpy( pointers[i], (void *)dir->StartAddressOfRawData, size );
+        memset( (char *)pointers[i] + size, 0, dir->SizeOfZeroFill );
 
         TRACE( "thread %04x idx %d: %d/%d bytes from %p to %p\n",
                GetCurrentThreadId(), i, size, dir->SizeOfZeroFill,
-               (void *)dir->StartAddressOfRawData, data );
-
-        pointers[i] = data;
-        memcpy( data, (void *)dir->StartAddressOfRawData, size );
-        memset( data + size, 0, dir->SizeOfZeroFill );
-        data += TLS_ALIGN( size + dir->SizeOfZeroFill );
+               (void *)dir->StartAddressOfRawData, pointers[i] );
     }
     NtCurrentTeb()->ThreadLocalStoragePointer = pointers;
     return STATUS_SUCCESS;
@@ -2482,6 +2483,8 @@ void WINAPI LdrShutdownThread(void)
 {
     PLIST_ENTRY mark, entry;
     PLDR_MODULE mod;
+    UINT i;
+    void **pointers;
 
     TRACE("()\n");
 
@@ -2504,8 +2507,12 @@ void WINAPI LdrShutdownThread(void)
                         DLL_THREAD_DETACH, NULL );
     }
 
+    if ((pointers = NtCurrentTeb()->ThreadLocalStoragePointer))
+    {
+        for (i = 0; i < tls_module_count; i++) RtlFreeHeap( GetProcessHeap(), 0, pointers[i] );
+        RtlFreeHeap( GetProcessHeap(), 0, pointers );
+    }
     RtlLeaveCriticalSection( &loader_section );
-    RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->ThreadLocalStoragePointer );
 }
 
 




More information about the wine-cvs mailing list