diff --git a/tccelf.c b/tccelf.c index 8644005..dfc7b5f 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1404,7 +1404,6 @@ static void put_dt(Section *dynamic, int dt, addr_t val) dyn->d_un.d_val = val; } -#ifndef TCC_TARGET_PE static void add_init_array_defines(TCCState *s1, const char *section_name) { Section *s; @@ -1433,6 +1432,7 @@ static void add_init_array_defines(TCCState *s1, const char *section_name) s->sh_num, sym_end); } +#ifndef TCC_TARGET_PE static int tcc_add_support(TCCState *s1, const char *filename) { char buf[1024]; @@ -1550,12 +1550,10 @@ static void tcc_add_linker_symbols(TCCState *s1) ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, data_section->sh_num, "__global_pointer$"); #endif -#ifndef TCC_TARGET_PE /* horrible new standard ldscript defines */ add_init_array_defines(s1, ".preinit_array"); add_init_array_defines(s1, ".init_array"); add_init_array_defines(s1, ".fini_array"); -#endif /* add start and stop symbols for sections whose name can be expressed in C */ diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile index e7f2ecb..cec5b50 100644 --- a/tests/tests2/Makefile +++ b/tests/tests2/Makefile @@ -33,7 +33,6 @@ ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-) endif ifneq (-$(CONFIG_WIN32)$(CONFIG_WIN64)-,--) SKIP += 106_pthread.test # No pthread support - SKIP += 108_constructor.test # No contructor/destructor support endif # Some tests might need arguments diff --git a/win32/lib/crt1.c b/win32/lib/crt1.c index c5047ed..7f7e798 100644 --- a/win32/lib/crt1.c +++ b/win32/lib/crt1.c @@ -34,6 +34,27 @@ int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int glob void __cdecl __set_app_type(int apptype); unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask); extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]); +extern void (*__init_array_start[]) (void); +extern void (*__init_array_end[]) (void); +extern void (*__fini_array_start[]) (void); +extern void (*__fini_array_end[]) (void); + +static int do_main (int argc, _TCHAR * argv[], _TCHAR * env[]) +{ + int retval; + long i; + + i = 0; + while (&__init_array_start[i] != __init_array_end) { + (*__init_array_start[i++])(); + } + retval = _tmain(__argc, __targv, _tenviron); + i = 0; + while (&__fini_array_end[i] != __fini_array_start) { + (*__fini_array_end[--i])(); + } + return retval; +} /* Allow command-line globbing with "int _dowildcard = 1;" in the user source */ int _dowildcard; @@ -57,7 +78,7 @@ void _tstart(void) #endif __tgetmainargs( &__argc, &__targv, &_tenviron, _dowildcard, &start_info); - exit(_tmain(__argc, __targv, _tenviron)); + exit(do_main(__argc, __targv, _tenviron)); } int _runtmain(int argc, /* as tcc passed in */ char **argv) @@ -78,7 +99,7 @@ int _runtmain(int argc, /* as tcc passed in */ char **argv) #if defined __i386__ || defined __x86_64__ _controlfp(_PC_53, _MCW_PC); #endif - return _tmain(__argc, __targv, _tenviron); + return do_main(__argc, __targv, _tenviron); } // ============================================= diff --git a/win32/lib/dllcrt1.c b/win32/lib/dllcrt1.c index ba1dbd0..7c9be14 100644 --- a/win32/lib/dllcrt1.c +++ b/win32/lib/dllcrt1.c @@ -2,12 +2,31 @@ #include +extern void (*__init_array_start[]) (void); +extern void (*__init_array_end[]) (void); +extern void (*__fini_array_start[]) (void); +extern void (*__fini_array_end[]) (void); + BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved); BOOL WINAPI _dllstart(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) { - BOOL bRet; - bRet = DllMain (hDll, dwReason, lpReserved); - return bRet; + BOOL bRet; + int i; + + if (dwReason == DLL_PROCESS_ATTACH) { /* ignore DLL_THREAD_ATTACH */ + i = 0; + while (&__init_array_start[i] != __init_array_end) { + (*__init_array_start[i++])(); + } + } + if (dwReason == DLL_PROCESS_DETACH) { /* ignore DLL_THREAD_DETACH */ + i = 0; + while (&__fini_array_end[i] != __fini_array_start) { + (*__fini_array_end[--i])(); + } + } + bRet = DllMain (hDll, dwReason, lpReserved); + return bRet; } diff --git a/win32/lib/wincrt1.c b/win32/lib/wincrt1.c index 5ea10ea..95ed3df 100644 --- a/win32/lib/wincrt1.c +++ b/win32/lib/wincrt1.c @@ -23,6 +23,11 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); #define _runtwinmain _runwinmain #endif +extern void (*__init_array_start[]) (void); +extern void (*__init_array_end[]) (void); +extern void (*__fini_array_start[]) (void); +extern void (*__fini_array_end[]) (void); + typedef struct { int newmode; } _startupinfo; int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); @@ -31,6 +36,8 @@ static int go_winmain(TCHAR *arg1) STARTUPINFO si; _TCHAR *szCmd, *p; int fShow; + int retval; + int i; GetStartupInfo(&si); if (si.dwFlags & STARTF_USESHOWWINDOW) @@ -48,7 +55,16 @@ static int go_winmain(TCHAR *arg1) #if defined __i386__ || defined __x86_64__ _controlfp(0x10000, 0x30000); #endif - return _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); + i = 0; + while (&__init_array_start[i] != __init_array_end) { + (*__init_array_start[i++])(); + } + retval = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); + i = 0; + while (&__fini_array_end[i] != __fini_array_start) { + (*__fini_array_end[--i])(); + } + return retval; } static LONG WINAPI catch_sig(EXCEPTION_POINTERS *ex)