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