mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 11:01:29 +00:00
kernel32/tests: Fix tls callback tests on Windows 7.
Also add a few more so the full set of callbacks is tested.
Fixes: 2203a8564c
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54657
This commit is contained in:
parent
67f992c831
commit
a7b49b0e86
|
@ -2144,6 +2144,19 @@ static void check_tls_index(HANDLE dll, BOOL tls_initialized)
|
|||
ok(found_dll, "Couldn't find dll %p in module list\n", dll);
|
||||
}
|
||||
|
||||
static int tls_init_fn_output;
|
||||
|
||||
static DWORD WINAPI tls_thread_fn(void* tlsidx_v)
|
||||
{
|
||||
int tls_index = (int)(DWORD_PTR)(tlsidx_v);
|
||||
const char* str = ((char **)NtCurrentTeb()->ThreadLocalStoragePointer)[tls_index];
|
||||
ok( !strcmp( str, "hello world" ), "wrong tls data '%s' at %p\n", str, str );
|
||||
ok( tls_init_fn_output == DLL_THREAD_ATTACH,
|
||||
"tls init function didn't run or got wrong reason: %d instead of %d\n", tls_init_fn_output, DLL_THREAD_ATTACH );
|
||||
tls_init_fn_output = 9999;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_import_resolution(void)
|
||||
{
|
||||
char temp_path[MAX_PATH];
|
||||
|
@ -2165,31 +2178,41 @@ static void test_import_resolution(void)
|
|||
char tls_data[16];
|
||||
SHORT tls_index;
|
||||
SHORT tls_index_hi;
|
||||
UCHAR tls_init_fn[64]; /* Note: Uses rip-relative address of tls_index, don't separate */
|
||||
int* tls_init_fn_output;
|
||||
UCHAR tls_init_fn[64]; /* Note: Uses rip-relative address of tls_init_fn_output, don't separate */
|
||||
UCHAR entry_point_fn[16];
|
||||
} data, *ptr;
|
||||
IMAGE_NT_HEADERS nt;
|
||||
IMAGE_SECTION_HEADER section;
|
||||
int test;
|
||||
int test, tls_index_save;
|
||||
#if defined(__i386__)
|
||||
static const UCHAR tls_init_code[] = {
|
||||
0xE8, 0x00, 0x00, 0x00, 0x00, /* call 1f */
|
||||
0x59, /* 1: pop ecx */
|
||||
0x8B, 0x49, 0xF7, /* mov ecx, [ecx - 9] ; mov ecx, [tls_index] */
|
||||
0x64, 0x8B, 0x15, 0x2C, 0x00, 0x00, 0x00, /* mov edx, fs:0x2c */
|
||||
0x8B, 0x14, 0x8A, /* mov edx, [edx + edx * 4] */
|
||||
0xC6, 0x42, 0x05, 0x21, /* mov byte [edx + 5], 0x21 */
|
||||
0xC2, 0x0C, 0x00, /* ret 12 */
|
||||
0xE8, 0x00, 0x00, 0x00, 0x00, /* call 1f */
|
||||
0x59, /* 1: pop ecx */
|
||||
0x8B, 0x49, 0xF7, /* mov ecx, [ecx - 9] ; mov ecx, [tls_init_fn_output] */
|
||||
0x8B, 0x54, 0x24, 0x08, /* mov edx, [esp + 8] */
|
||||
0x89, 0x11, /* mov [ecx], edx */
|
||||
0xB8, 0x01, 0x00, 0x00, 0x00, /* mov eax, 1 */
|
||||
0xC2, 0x0C, 0x00, /* ret 12 */
|
||||
};
|
||||
static const UCHAR entry_point_code[] = {
|
||||
0xB8, 0x01, 0x00, 0x00, 0x00, /* mov eax, 1 */
|
||||
0xC2, 0x0C, 0x00, /* ret 12 */
|
||||
};
|
||||
#elif defined(__x86_64__)
|
||||
static const UCHAR tls_init_code[] = {
|
||||
0x8B, 0x0D, 0xF6, 0xFF, 0xFF, 0xFF, /* mov ecx, [rip + tls_index] */
|
||||
0x65, 0x48, 0x8B, 0x14, 0x25, 0x58, 0x00, 0x00, 0x00, /* mov rdx, gs:0x58 */
|
||||
0x48, 0x8B, 0x14, 0xCA, /* mov rdx, [rdx + rcx * 8] */
|
||||
0xC6, 0x42, 0x05, 0x21, /* mov byte [rdx + 5], 0x21 */
|
||||
0xC3, /* ret */
|
||||
0x48, 0x8B, 0x0D, 0xF1, 0xFF, 0xFF, 0xFF, /* mov rcx, [rip + tls_init_fn_output] */
|
||||
0x89, 0x11, /* mov [rcx], edx */
|
||||
0xB8, 0x01, 0x00, 0x00, 0x00, /* mov eax, 1 */
|
||||
0xC3, /* ret */
|
||||
};
|
||||
static const UCHAR entry_point_code[] = {
|
||||
0xB8, 0x01, 0x00, 0x00, 0x00, /* mov eax, 1 */
|
||||
0xC3, /* ret */
|
||||
};
|
||||
#else
|
||||
static const UCHAR tls_init_code[] = { 0x00 };
|
||||
static const UCHAR entry_point_code[] = { 0x00 };
|
||||
#endif
|
||||
|
||||
for (test = 0; test < 4; test++)
|
||||
|
@ -2230,10 +2253,16 @@ static void test_import_resolution(void)
|
|||
|
||||
if (test == 3 && sizeof(tls_init_code) > 1)
|
||||
{
|
||||
/* Windows doesn't consistently call tls init functions on dlls without entry points */
|
||||
assert(sizeof(tls_init_code) <= sizeof(data.tls_init_fn));
|
||||
assert(sizeof(entry_point_code) <= sizeof(data.entry_point_fn));
|
||||
memcpy(data.tls_init_fn, tls_init_code, sizeof(tls_init_code));
|
||||
memcpy(data.entry_point_fn, entry_point_code, sizeof(entry_point_code));
|
||||
tls_init_fn_output = 9999;
|
||||
data.tls_init_fn_output = &tls_init_fn_output;
|
||||
data.tls_init_fn_list[0] = nt.OptionalHeader.ImageBase + DATA_RVA(&data.tls_init_fn);
|
||||
data.tls.AddressOfCallBacks = nt.OptionalHeader.ImageBase + DATA_RVA(&data.tls_init_fn_list);
|
||||
nt.OptionalHeader.AddressOfEntryPoint = DATA_RVA(&data.entry_point_fn);
|
||||
}
|
||||
|
||||
GetTempPathA(MAX_PATH, temp_path);
|
||||
|
@ -2315,16 +2344,27 @@ static void test_import_resolution(void)
|
|||
ok( mod != NULL, "failed to load err %lu\n", GetLastError() );
|
||||
if (!mod) break;
|
||||
ptr = (struct imports *)((char *)mod + page_size);
|
||||
tls_index_save = ptr->tls_index;
|
||||
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 && sizeof(tls_init_code) > 1)
|
||||
{
|
||||
/* tls init function will write an '!' over the space in "hello world" */
|
||||
str = ((char **)NtCurrentTeb()->ThreadLocalStoragePointer)[ptr->tls_index];
|
||||
ok( !strcmp( str, "hello!world" ), "wrong tls data '%s' at %p\n", str, str );
|
||||
ok( !strcmp( str, "hello world" ), "wrong tls data '%s' at %p\n", str, str );
|
||||
/* tls init function will write the reason to *tls_init_fn_output */
|
||||
ok( tls_init_fn_output == DLL_PROCESS_ATTACH,
|
||||
"tls init function didn't run or got wrong reason: %d instead of %d\n", tls_init_fn_output, DLL_PROCESS_ATTACH );
|
||||
tls_init_fn_output = 9999;
|
||||
WaitForSingleObject(CreateThread(NULL, 0, tls_thread_fn, (void*)(DWORD_PTR)ptr->tls_index, 0, NULL), INFINITE);
|
||||
ok( tls_init_fn_output == DLL_THREAD_DETACH,
|
||||
"tls init function didn't run or got wrong reason: %d instead of %d\n", tls_init_fn_output, DLL_THREAD_DETACH );
|
||||
}
|
||||
check_tls_index(mod, ptr->tls_index != 9999);
|
||||
tls_init_fn_output = 9999;
|
||||
FreeLibrary( mod );
|
||||
if (tls_index_save != 9999 && sizeof(tls_init_code) > 1)
|
||||
ok( tls_init_fn_output == DLL_PROCESS_DETACH,
|
||||
"tls init function didn't run or got wrong reason: %d instead of %d\n", tls_init_fn_output, DLL_PROCESS_DETACH );
|
||||
}
|
||||
DeleteFileA( dll_name );
|
||||
#undef DATA_RVA
|
||||
|
|
Loading…
Reference in a new issue