Module: wine Branch: master Commit: ff08cd597d1d8b4e806d7ace9f3667ac6022b852 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ff08cd597d1d8b4e806d7ace9f...
Author: Alexandre Julliard julliard@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;