forked from Mirrors/wine-wine
ntdll: Ensure alignment of static TLS data and free it at thread exit.
parent
156f611ba8
commit
e272b31b6b
|
@ -97,6 +97,8 @@ static HANDLE main_exe_file;
|
||||||
static UINT tls_module_count; /* number of modules with TLS directory */
|
static UINT tls_module_count; /* number of modules with TLS directory */
|
||||||
static UINT tls_total_size; /* total size of TLS storage */
|
static UINT tls_total_size; /* total size of TLS storage */
|
||||||
static const IMAGE_TLS_DIRECTORY **tls_dirs; /* array of TLS directories */
|
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 loader_section;
|
||||||
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
||||||
|
@ -843,7 +845,7 @@ static NTSTATUS alloc_process_tls(void)
|
||||||
continue;
|
continue;
|
||||||
size = (dir->EndAddressOfRawData - dir->StartAddressOfRawData) + dir->SizeOfZeroFill;
|
size = (dir->EndAddressOfRawData - dir->StartAddressOfRawData) + dir->SizeOfZeroFill;
|
||||||
if (!size && !dir->AddressOfCallBacks) continue;
|
if (!size && !dir->AddressOfCallBacks) continue;
|
||||||
tls_total_size += size;
|
tls_total_size += TLS_ALIGN(size);
|
||||||
tls_module_count++;
|
tls_module_count++;
|
||||||
}
|
}
|
||||||
if (!tls_module_count) return STATUS_SUCCESS;
|
if (!tls_module_count) return STATUS_SUCCESS;
|
||||||
|
@ -878,24 +880,19 @@ static NTSTATUS alloc_thread_tls(void)
|
||||||
{
|
{
|
||||||
void **pointers;
|
void **pointers;
|
||||||
char *data;
|
char *data;
|
||||||
UINT i;
|
UINT i, size;
|
||||||
|
|
||||||
if (!tls_module_count) return STATUS_SUCCESS;
|
if (!tls_module_count) return STATUS_SUCCESS;
|
||||||
|
|
||||||
if (!(pointers = RtlAllocateHeap( GetProcessHeap(), 0,
|
size = TLS_ALIGN( tls_module_count * sizeof(*pointers) );
|
||||||
tls_module_count * sizeof(*pointers) )))
|
if (!(pointers = RtlAllocateHeap( GetProcessHeap(), 0, size + tls_total_size )))
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
data = (char *)pointers + size;
|
||||||
if (!(data = RtlAllocateHeap( GetProcessHeap(), 0, tls_total_size )))
|
|
||||||
{
|
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, pointers );
|
|
||||||
return STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < tls_module_count; i++)
|
for (i = 0; i < tls_module_count; i++)
|
||||||
{
|
{
|
||||||
const IMAGE_TLS_DIRECTORY *dir = tls_dirs[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",
|
TRACE( "thread %04x idx %d: %d/%d bytes from %p to %p\n",
|
||||||
GetCurrentThreadId(), i, size, dir->SizeOfZeroFill,
|
GetCurrentThreadId(), i, size, dir->SizeOfZeroFill,
|
||||||
|
@ -903,9 +900,8 @@ static NTSTATUS alloc_thread_tls(void)
|
||||||
|
|
||||||
pointers[i] = data;
|
pointers[i] = data;
|
||||||
memcpy( data, (void *)dir->StartAddressOfRawData, size );
|
memcpy( data, (void *)dir->StartAddressOfRawData, size );
|
||||||
data += size;
|
memset( data + size, 0, dir->SizeOfZeroFill );
|
||||||
memset( data, 0, dir->SizeOfZeroFill );
|
data += TLS_ALIGN( size + dir->SizeOfZeroFill );
|
||||||
data += dir->SizeOfZeroFill;
|
|
||||||
}
|
}
|
||||||
NtCurrentTeb()->ThreadLocalStoragePointer = pointers;
|
NtCurrentTeb()->ThreadLocalStoragePointer = pointers;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
Loading…
Reference in New Issue