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