Sorry for the delay. I had a long vacation.

Before I went on vacation I read some Microsoft documentation.
This documentation send me in the wrong direction.
So the patch is now much simpler (see attachment).

Regards,

    Herman

On 2019-10-30 15:58, Michael Matz wrote:
Hi,

On Wed, 30 Oct 2019, Herman ten Brugge via Tinycc-devel wrote:

I had a good night sleep and realized that I could copy the .init/.fini
arrays relocations to the text section
Why to the text section (and not, say .data, .init_array contains
pointers, not code), and why copying at all?  The link process (i.e.
pe_assign_addresses) merely needs to make sure that .init/.fini becomes
part of the loaded image (which should already be the case without any
changes?), then the start/stop symbols (why aren't you using
add_init_array_defines?) point to the correct areas in that image and
should be accessible just fine from the crt startup code.


Ciao,
Michael.

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 <windows.h>
 
+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)
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to