From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/loader.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index ebdb08569c0..5d0f03a76da 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1294,6 +1294,7 @@ static BOOL alloc_tls_slot( LDR_DATA_TABLE_ENTRY *mod ) ULONG i, size; void *new_ptr; LIST_ENTRY *entry; + UINT old_module_count = tls_module_count;
if (!(dir = RtlImageDirectoryEntryToData( mod->DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_TLS, &size ))) return FALSE; @@ -1319,16 +1320,22 @@ static BOOL alloc_tls_slot( LDR_DATA_TABLE_ENTRY *mod ) new_ptr = RtlReAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, tls_dirs, new_count * sizeof(*tls_dirs) ); if (!new_ptr) return FALSE; + tls_dirs = new_ptr; + tls_module_count = new_count; + }
- /* resize the pointer block in all running threads */ - for (entry = tls_links.Flink; entry != &tls_links; entry = entry->Flink) + /* allocate the data block in all running threads */ + for (entry = tls_links.Flink; entry != &tls_links; entry = entry->Flink) + { + TEB *teb = CONTAINING_RECORD( entry, TEB, TlsLinks ); + + if (old_module_count < tls_module_count) { - TEB *teb = CONTAINING_RECORD( entry, TEB, TlsLinks ); void **old = teb->ThreadLocalStoragePointer; - void **new = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*new)); + void **new = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, tls_module_count * sizeof(*new));
if (!new) return FALSE; - if (old) memcpy( new, old, tls_module_count * sizeof(*new) ); + if (old) memcpy( new, old, old_module_count * sizeof(*new) ); teb->ThreadLocalStoragePointer = new; #ifdef __x86_64__ /* macOS-specific hack */ if (teb->Instrumentation[0]) ((TEB *)teb->Instrumentation[0])->ThreadLocalStoragePointer = new; @@ -1337,15 +1344,6 @@ static BOOL alloc_tls_slot( LDR_DATA_TABLE_ENTRY *mod ) /* FIXME: can't free old block here, should be freed at thread exit */ }
- tls_dirs = new_ptr; - tls_module_count = new_count; - } - - /* allocate the data block in all running threads */ - for (entry = tls_links.Flink; entry != &tls_links; entry = entry->Flink) - { - TEB *teb = CONTAINING_RECORD( entry, TEB, TlsLinks ); - if (!(new_ptr = RtlAllocateHeap( GetProcessHeap(), 0, size + dir->SizeOfZeroFill ))) return -1; memcpy( new_ptr, (void *)dir->StartAddressOfRawData, size ); memset( (char *)new_ptr + size, 0, dir->SizeOfZeroFill );