Module: wine Branch: stable Commit: 7f92f04ba6529bc993654ad5798bb7f99b2c7002 URL: http://source.winehq.org/git/wine.git/?a=commit;h=7f92f04ba6529bc993654ad579...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Dec 15 13:16:55 2010 +0100
ntdll: Ensure alignment of static TLS data and free it at thread exit. (cherry picked from commit e272b31b6bdc87307019c00da1be097c23a19e0e)
---
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 c30243e..04c04ac 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;