ntdll: Only allocate TLS data when resolving imports.
This commit is contained in:
parent
f5fc925f0e
commit
ff08cd597d
|
@ -1214,6 +1214,7 @@ static void test_import_resolution(void)
|
||||||
char dll_name[MAX_PATH];
|
char dll_name[MAX_PATH];
|
||||||
DWORD dummy;
|
DWORD dummy;
|
||||||
void *expect;
|
void *expect;
|
||||||
|
char *str;
|
||||||
HANDLE hfile;
|
HANDLE hfile;
|
||||||
HMODULE mod, mod2;
|
HMODULE mod, mod2;
|
||||||
struct imports
|
struct imports
|
||||||
|
@ -1223,6 +1224,9 @@ static void test_import_resolution(void)
|
||||||
IMAGE_THUNK_DATA thunks[2];
|
IMAGE_THUNK_DATA thunks[2];
|
||||||
char module[16];
|
char module[16];
|
||||||
struct { WORD hint; char name[32]; } function;
|
struct { WORD hint; char name[32]; } function;
|
||||||
|
IMAGE_TLS_DIRECTORY tls;
|
||||||
|
char tls_data[16];
|
||||||
|
SHORT tls_index;
|
||||||
} data, *ptr;
|
} data, *ptr;
|
||||||
IMAGE_NT_HEADERS nt;
|
IMAGE_NT_HEADERS nt;
|
||||||
IMAGE_SECTION_HEADER section;
|
IMAGE_SECTION_HEADER section;
|
||||||
|
@ -1243,6 +1247,8 @@ static void test_import_resolution(void)
|
||||||
memset( nt.OptionalHeader.DataDirectory, 0, sizeof(nt.OptionalHeader.DataDirectory) );
|
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].Size = sizeof(data.descr);
|
||||||
nt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = DATA_RVA(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) );
|
memset( &data, 0, sizeof(data) );
|
||||||
data.descr[0].u.OriginalFirstThunk = DATA_RVA( data.original_thunks );
|
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.original_thunks[0].u1.AddressOfData = DATA_RVA( &data.function );
|
||||||
data.thunks[0].u1.AddressOfData = 0xdeadbeef;
|
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);
|
GetTempPathA(MAX_PATH, temp_path);
|
||||||
GetTempFileNameA(temp_path, "ldr", 0, dll_name);
|
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 );
|
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",
|
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 );
|
(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 );
|
FreeLibrary( mod );
|
||||||
break;
|
break;
|
||||||
case 1: /* load with DONT_RESOLVE_DLL_REFERENCES doesn't resolve imports */
|
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);
|
ptr = (struct imports *)((char *)mod + page_size);
|
||||||
ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
|
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 );
|
(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 );
|
mod2 = LoadLibraryA( dll_name );
|
||||||
ok( mod2 == mod, "loaded twice %p / %p\n", mod, mod2 );
|
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",
|
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 );
|
(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 );
|
FreeLibrary( mod );
|
||||||
break;
|
break;
|
||||||
case 2: /* load without IMAGE_FILE_DLL doesn't resolve imports */
|
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);
|
ptr = (struct imports *)((char *)mod + page_size);
|
||||||
ok( ptr->thunks[0].u1.Function == 0xdeadbeef, "thunk resolved to %p for %s.%s\n",
|
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 );
|
(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 );
|
FreeLibrary( mod );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) return STATUS_SUCCESS; /* already done */
|
||||||
wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
|
wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
|
||||||
|
|
||||||
|
wm->ldr.TlsIndex = alloc_tls_slot( &wm->ldr );
|
||||||
|
|
||||||
if (!(imports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
|
if (!(imports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
|
||||||
IMAGE_DIRECTORY_ENTRY_IMPORT, &size )))
|
IMAGE_DIRECTORY_ENTRY_IMPORT, &size )))
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -907,6 +909,7 @@ static WINE_MODREF *alloc_module( HMODULE hModule, LPCWSTR filename )
|
||||||
wm->ldr.EntryPoint = NULL;
|
wm->ldr.EntryPoint = NULL;
|
||||||
wm->ldr.SizeOfImage = nt->OptionalHeader.SizeOfImage;
|
wm->ldr.SizeOfImage = nt->OptionalHeader.SizeOfImage;
|
||||||
wm->ldr.Flags = LDR_DONT_RESOLVE_REFS;
|
wm->ldr.Flags = LDR_DONT_RESOLVE_REFS;
|
||||||
|
wm->ldr.TlsIndex = -1;
|
||||||
wm->ldr.LoadCount = 1;
|
wm->ldr.LoadCount = 1;
|
||||||
wm->ldr.SectionHandle = NULL;
|
wm->ldr.SectionHandle = NULL;
|
||||||
wm->ldr.CheckSum = 0;
|
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.Flink = NULL;
|
||||||
wm->ldr.InInitializationOrderModuleList.Blink = NULL;
|
wm->ldr.InInitializationOrderModuleList.Blink = NULL;
|
||||||
|
|
||||||
wm->ldr.TlsIndex = alloc_tls_slot( &wm->ldr );
|
|
||||||
|
|
||||||
if (!(nt->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NX_COMPAT))
|
if (!(nt->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NX_COMPAT))
|
||||||
{
|
{
|
||||||
ULONG flags = MEM_EXECUTE_OPTION_ENABLE;
|
ULONG flags = MEM_EXECUTE_OPTION_ENABLE;
|
||||||
|
|
Loading…
Reference in New Issue