Alexandre Julliard : ntdll: Only allocate TLS data when resolving imports.
Alexandre Julliard
julliard at winehq.org
Mon Feb 17 13:45:15 CST 2014
Module: wine
Branch: master
Commit: ff08cd597d1d8b4e806d7ace9f3667ac6022b852
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ff08cd597d1d8b4e806d7ace9f3667ac6022b852
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Feb 17 17:33:30 2014 +0100
ntdll: Only allocate TLS data when resolving imports.
---
dlls/kernel32/tests/loader.c | 23 +++++++++++++++++++++++
dlls/ntdll/loader.c | 5 +++--
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index cd64a34..e749238 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -1214,6 +1214,7 @@ static void test_import_resolution(void)
char dll_name[MAX_PATH];
DWORD dummy;
void *expect;
+ char *str;
HANDLE hfile;
HMODULE mod, mod2;
struct imports
@@ -1223,6 +1224,9 @@ static void test_import_resolution(void)
IMAGE_THUNK_DATA thunks[2];
char module[16];
struct { WORD hint; char name[32]; } function;
+ IMAGE_TLS_DIRECTORY tls;
+ char tls_data[16];
+ SHORT tls_index;
} data, *ptr;
IMAGE_NT_HEADERS nt;
IMAGE_SECTION_HEADER section;
@@ -1243,6 +1247,8 @@ static void test_import_resolution(void)
memset( nt.OptionalHeader.DataDirectory, 0, sizeof(nt.OptionalHeader.DataDirectory) );
nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = sizeof(data.descr);
nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = DATA_RVA(data.descr);
+ nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size = sizeof(data.tls);
+ nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress = DATA_RVA(&data.tls);
memset( &data, 0, sizeof(data) );
data.descr[0].u.OriginalFirstThunk = DATA_RVA( data.original_thunks );
@@ -1253,6 +1259,12 @@ static void test_import_resolution(void)
data.original_thunks[0].u1.AddressOfData = DATA_RVA( &data.function );
data.thunks[0].u1.AddressOfData = 0xdeadbeef;
+ data.tls.StartAddressOfRawData = nt.OptionalHeader.ImageBase + DATA_RVA( data.tls_data );
+ data.tls.EndAddressOfRawData = data.tls.StartAddressOfRawData + sizeof(data.tls_data);
+ data.tls.AddressOfIndex = nt.OptionalHeader.ImageBase + DATA_RVA( &data.tls_index );
+ strcpy( data.tls_data, "hello world" );
+ data.tls_index = 9999;
+
GetTempPathA(MAX_PATH, temp_path);
GetTempFileNameA(temp_path, "ldr", 0, dll_name);
@@ -1286,6 +1298,13 @@ static void test_import_resolution(void)
expect = GetProcAddress( GetModuleHandleA( data.module ), data.function.name );
ok( (void *)ptr->thunks[0].u1.Function == expect, "thunk %p instead of %p for %s.%s\n",
(void *)ptr->thunks[0].u1.Function, expect, data.module, data.function.name );
+ ok( ptr->tls_index < 32 || broken(ptr->tls_index == 9999), /* before vista */
+ "wrong tls index %d\n", ptr->tls_index );
+ if (ptr->tls_index != 9999)
+ {
+ str = ((char **)NtCurrentTeb()->ThreadLocalStoragePointer)[ptr->tls_index];
+ ok( !strcmp( str, "hello world" ), "wrong tls data '%s' at %p\n", str, str );
+ }
FreeLibrary( mod );
break;
case 1: /* load with DONT_RESOLVE_DLL_REFERENCES doesn't resolve imports */
@@ -1295,10 +1314,13 @@ static void test_import_resolution(void)
ptr = (struct imports *)((char *)mod + page_size);
ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
(void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
+ ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index );
+
mod2 = LoadLibraryA( dll_name );
ok( mod2 == mod, "loaded twice %p / %p\n", mod, mod2 );
ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
(void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
+ ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index );
FreeLibrary( mod );
break;
case 2: /* load without IMAGE_FILE_DLL doesn't resolve imports */
@@ -1308,6 +1330,7 @@ static void test_import_resolution(void)
ptr = (struct imports *)((char *)mod + page_size);
ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
(void *)ptr->thunks[0].u1.Function, data.module, data.function.name );
+ ok( ptr->tls_index == 9999, "wrong tls index %d\n", ptr->tls_index );
FreeLibrary( mod );
break;
}
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 8414ec5..a8d675a 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -852,6 +852,8 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) return STATUS_SUCCESS; /* already done */
wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
+ wm->ldr.TlsIndex = alloc_tls_slot( &wm->ldr );
+
if (!(imports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT, &size )))
return STATUS_SUCCESS;
@@ -907,6 +909,7 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
wm->ldr.EntryPoint = NULL;
wm->ldr.SizeOfImage = nt->OptionalHeader.SizeOfImage;
wm->ldr.Flags = LDR_DONT_RESOLVE_REFS;
+ wm->ldr.TlsIndex = -1;
wm->ldr.LoadCount = 1;
wm->ldr.SectionHandle = NULL;
wm->ldr.CheckSum = 0;
@@ -944,8 +947,6 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
wm->ldr.InInitializationOrderModuleList.Flink = NULL;
wm->ldr.InInitializationOrderModuleList.Blink = NULL;
- wm->ldr.TlsIndex = alloc_tls_slot( &wm->ldr );
-
if (!(nt->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NX_COMPAT))
{
ULONG flags = MEM_EXECUTE_OPTION_ENABLE;
More information about the wine-cvs
mailing list