blob: e7eb89237db0005772aac7334709fe232b9a4f93 [file]
#include <stdio.h>
#include <stdlib.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
/* mingw-w64 headers */
#include "libtest.h"
__attribute__((dllimport)) extern int libtlsnat_process_attach;
__attribute__((dllimport)) extern int libtlsnat_thread_attach;
__attribute__((dllimport)) extern int libtlsnat_process_detach;
__attribute__((dllimport)) extern int libtlsnat_thread_detach;
#if defined(__i386__)
/* We need to make sure that we align the stack to 16 bytes for the sake of SSE */
__attribute__((force_align_arg_pointer))
#endif
static DWORD WINAPI thread_main(LPVOID user_data __attribute__((unused)))
{
return 0;
}
int main(void)
{
mingw_test_init();
int ret = 0;
if (_osplatform == VER_PLATFORM_WIN32_WINDOWS) {
printf("PE TLS callbacks are not supported on Win9x\n");
return 77;
}
if (libtlsnat_process_attach != 1) {
printf("Error: PE TLS callback in libtlsnat.dll for DLL_PROCESS_ATTACH was not called\n");
ret = 1;
} else {
printf("PE TLS callback in libtlsnat.dll for DLL_PROCESS_ATTACH was called\n");
}
if (libtlsnat_thread_attach != 0) {
printf("Error: PE TLS callback in libtlsnat.dll for DLL_THREAD_ATTACH was called without spawning thread\n");
ret = 1;
}
if (libtlsnat_thread_detach != 0) {
printf("Error: PE TLS callback in libtlsnat.dll for DLL_THREAD_DETACH was called without spawning thread\n");
ret = 1;
}
printf("Creating new thread\n");
HANDLE thread = CreateThread(NULL, 0, thread_main, NULL, 0, &(DWORD){0} /*out: ThreadId*/);
if (!thread) {
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
printf("Error: failed: %lu\n", GetLastError());
ret = 1;
} else {
printf("Skipped: not supported\n");
}
} else {
DWORD tret;
WaitForSingleObject(thread, INFINITE);
GetExitCodeThread(thread, &tret);
CloseHandle(thread);
if (tret) {
printf("Error: thread failed\n");
ret = 1;
}
if (libtlsnat_thread_attach != 1) {
printf("Error: PE TLS callback in libtlsnat.dll for DLL_THREAD_ATTACH was not called\n");
ret = 1;
} else {
printf("PE TLS callback in libtlsnat.dll for DLL_THREAD_ATTACH was called\n");
}
if (libtlsnat_thread_detach != 1) {
printf("Error: PE TLS callback in libtlsnat.dll for DLL_THREAD_DETACH was not called\n");
ret = 1;
} else {
printf("PE TLS callback in libtlsnat.dll for DLL_THREAD_DETACH was called\n");
}
}
if (libtlsnat_process_detach != 0) {
printf("Error: PE TLS callback in libtlsnat.dll for DLL_PROCESS_DETACH was called before exiting process\n");
ret = 1;
}
if (ret) printf("FAILED\n"); else printf("PASSED\n");
return ret;
}