ntdll: Only allocate TLS data when resolving imports.

This commit is contained in:
Alexandre Julliard 2014-02-17 17:33:30 +01:00
parent f5fc925f0e
commit ff08cd597d
2 changed files with 26 additions and 2 deletions

View File

@ -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;
}

View File

@ -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;