summaryrefslogtreecommitdiffstats
path: root/mkspecs/win32-g++/qtcrtentrypoint.cpp
blob: 3d047e8a714145cda75539c4f1104c1d226ce5dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231

//This code is need to get the WinMain function called. Current MinGW runtimes tries to call main
//before WinMain. Untill such time as MinGw runtime has been changed this is need.
//Most of this code is taken from the MinGw runtime sources.


#include <signal.h>
#include <process.h>
#include <float.h>
#include <io.h>


/*
 * Setup the default file handles to have the _CRT_fmode mode, as well as
 * any new files created by the user.
 */

extern int _fmode; 
extern "C"  int* __p__fmode(void); /* To access the dll _fmode */
extern int _CRT_fmode;

static void _mingw32_init_fmode ()
{
  /* Don't set the std file mode if the user hasn't set any value for it. */
  if (_CRT_fmode)
    {
      _fmode = _CRT_fmode;

      /*
       * This overrides the default file mode settings for stdin,
       * stdout and stderr. At first I thought you would have to
       * test with isatty, but it seems that the DOS console at
       * least is smart enough to handle _O_BINARY stdout and
       * still display correctly.
       */
      if (stdin)
	{
	  _setmode (_fileno (stdin), _CRT_fmode);
	}
      if (stdout)
	{
	  _setmode (_fileno (stdout), _CRT_fmode);
	}
      if (stderr)
	{
	  _setmode (_fileno (stderr), _CRT_fmode);
	}
    }

    /*  Now sync  the dll _fmode to the  one for this .exe.  */
    *__p__fmode() = _fmode;	

}

/* This function will be called when a trap occurs. Thanks to Jacob
   Navia for his contribution. */
static CALLBACK long _gnu_exception_handler (EXCEPTION_POINTERS * exception_data)
{
  void (*old_handler) (int);
  long action = EXCEPTION_CONTINUE_SEARCH;
  int reset_fpu = 0;

  switch (exception_data->ExceptionRecord->ExceptionCode)
    {
    case EXCEPTION_ACCESS_VIOLATION:
      /* test if the user has set SIGSEGV */
      old_handler = signal (SIGSEGV, SIG_DFL);
      if (old_handler == SIG_IGN)
	{
	  /* this is undefined if the signal was raised by anything other
	     than raise ().  */
	  signal (SIGSEGV, SIG_IGN);
	  action = EXCEPTION_CONTINUE_EXECUTION;
	}
      else if (old_handler != SIG_DFL)
	{
	  /* This means 'old' is a user defined function. Call it */
	  (*old_handler) (SIGSEGV);
	  action = EXCEPTION_CONTINUE_EXECUTION;
	}
      break;

    case EXCEPTION_FLT_INVALID_OPERATION:
    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
    case EXCEPTION_FLT_DENORMAL_OPERAND:
    case EXCEPTION_FLT_OVERFLOW:
    case EXCEPTION_FLT_UNDERFLOW:
    case EXCEPTION_FLT_INEXACT_RESULT:
      reset_fpu = 1;
      /* fall through. */

    case EXCEPTION_INT_DIVIDE_BY_ZERO:
      /* test if the user has set SIGFPE */
      old_handler = signal (SIGFPE, SIG_DFL);
      if (old_handler == SIG_IGN)
	{
	  signal (SIGFPE, SIG_IGN);
	  if (reset_fpu)
	    _fpreset ();
	  action = EXCEPTION_CONTINUE_EXECUTION;
	}
      else if (old_handler != SIG_DFL)
	{
	  /* This means 'old' is a user defined function. Call it */
	  (*old_handler) (SIGFPE);
	  action = EXCEPTION_CONTINUE_EXECUTION;
	}
      break;

    default:
      break;
    }
  return action;
}


extern char __RUNTIME_PSEUDO_RELOC_LIST__;
extern char __RUNTIME_PSEUDO_RELOC_LIST_END__;
extern char _image_base__;

typedef struct {
    DWORD addend;
    DWORD target;
} runtime_pseudo_reloc;

static void do_pseudo_reloc (void* start, void* end, void* base)
{
    DWORD reloc_target;
    runtime_pseudo_reloc* r;
    for (r = (runtime_pseudo_reloc*) start; r < (runtime_pseudo_reloc*) end; r++) {
        reloc_target = (DWORD) base + r->target;
        *((DWORD*) reloc_target) += r->addend;
    }
}

void _pei386_runtime_relocator ()
{
    do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
                     &__RUNTIME_PSEUDO_RELOC_LIST_END__,
                     &_image_base__);
}


#ifdef __MSVCRT__
#define __UNKNOWN_APP    0
#define __CONSOLE_APP    1
#define __GUI_APP        2
extern "C" void __set_app_type(int);
#endif /* __MSVCRT__ */

#define ISSPACE(a)	(a == ' ' || a == '\t')

int TQtWinMainCRTStartup()
{
#ifdef __MSVCRT__
    __set_app_type (__GUI_APP);
#endif
        
    SetUnhandledExceptionFilter (_gnu_exception_handler);
    
    /*
    * Initialize floating point unit.
    */
    _fpreset ();			/* Supplied by the runtime library. */
    
    /*
    * Sets the default file mode.
    * If _CRT_fmode is set, also set mode for stdin, stdout
    * and stderr, as well
    * NOTE: DLLs don't do this because that would be rude!
    */
    _mingw32_init_fmode ();
    
    /* Adust references to dllimported data that have non-zero offsets.  */
    _pei386_runtime_relocator ();
    
    char *szCmd;
    STARTUPINFO startinfo;
    int nRet;
    
    /* Get the command line passed to the process. */
    szCmd = GetCommandLineA ();
    GetStartupInfo (&startinfo);
    
    /* Strip off the name of the application and any leading
    * whitespace. */
    if (szCmd) {
        
        while (ISSPACE (*szCmd)) {
            szCmd++;
        }
        
        /* On my system I always get the app name enclosed
        * in quotes... */
        if (*szCmd == '\"') {
            do {
                szCmd++;
            } while (*szCmd != '\"' && *szCmd != '\0');
            
            if (*szCmd == '\"') {
                szCmd++;
            }
        } else {
        /* If no quotes then assume first token is program
        * name. */
            while (!ISSPACE (*szCmd) && *szCmd != '\0') {
                szCmd++;
            }
        }
        
        while (ISSPACE (*szCmd)) {
            szCmd++;
        }
    }
    
    nRet = WinMain (GetModuleHandle (NULL), NULL, szCmd,
                    (startinfo.dwFlags & STARTF_USESHOWWINDOW) ?
                     startinfo.wShowWindow : SW_SHOWDEFAULT);
    
    /*
    * Perform exit processing for the C library. This means
    * flushing output and calling 'atexit' registered functions.
    */
    _cexit ();
    
    ExitProcess (nRet);
    
    return 0;
    
}