master
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#ifndef _INC_INTERNAL
8#define _INC_INTERNAL
9
10#include <crtdefs.h>
11
12#ifdef __cplusplus
13extern "C" {
14#endif
15
16#include <limits.h>
17#include <fenv.h>
18#include <windows.h>
19
20#pragma pack(push,_CRT_PACKING)
21
22#define __IOINFO_TM_ANSI 0
23#define __IOINFO_TM_UTF8 1
24#define __IOINFO_TM_UTF16LE 2
25
26#ifdef _MSC_VER
27#pragma warning(push)
28#pragma warning(disable:4214)
29#pragma warning(disable:4820)
30#endif
31
32 typedef struct {
33 intptr_t osfhnd;
34 char osfile;
35 char pipech;
36 int lockinitflag;
37 CRITICAL_SECTION lock;
38 char textmode : 7;
39 char unicode : 1;
40 char pipech2[2];
41 } ioinfo;
42
43#ifdef _MSC_VER
44#pragma warning(pop)
45#endif
46
47#define IOINFO_ARRAY_ELTS (1 << 5)
48
49#define _pioinfo(i) (__pioinfo[(i) >> 5] + ((i) & (IOINFO_ARRAY_ELTS - 1)))
50#define _osfile(i) (_pioinfo(i)->osfile)
51#define _pipech2(i) (_pioinfo(i)->pipech2)
52#define _textmode(i) (_pioinfo(i)->textmode)
53#define _tm_unicode(i) (_pioinfo(i)->unicode)
54#define _pioinfo_safe(i) ((((i) != -1) && ((i) != -2)) ? _pioinfo(i) : &__badioinfo)
55#define _osfhnd_safe(i) (_pioinfo_safe(i)->osfhnd)
56#define _osfile_safe(i) (_pioinfo_safe(i)->osfile)
57#define _pipech_safe(i) (_pioinfo_safe(i)->pipech)
58#define _pipech2_safe(i) (_pioinfo_safe(i)->pipech2)
59#define _textmode_safe(i) (_pioinfo_safe(i)->textmode)
60#define _tm_unicode_safe(i) (_pioinfo_safe(i)->unicode)
61
62#ifndef __badioinfo
63 extern ioinfo * __MINGW_IMP_SYMBOL(__badioinfo);
64#define __badioinfo (* __MINGW_IMP_SYMBOL(__badioinfo))
65#endif
66
67#ifndef __pioinfo
68 extern ioinfo ** __MINGW_IMP_SYMBOL(__pioinfo)[];
69#define __pioinfo (* __MINGW_IMP_SYMBOL(__pioinfo))
70#endif
71
72#define _NO_CONSOLE_FILENO (intptr_t)-2
73
74#ifndef _FILE_DEFINED
75#define _FILE_DEFINED
76 struct _iobuf {
77 char *_ptr;
78 int _cnt;
79 char *_base;
80 int _flag;
81 int _file;
82 int _charbuf;
83 int _bufsiz;
84 char *_tmpfname;
85 };
86 typedef struct _iobuf FILE;
87#endif
88
89#if !defined (_FILEX_DEFINED) && defined (_WINDOWS_)
90#define _FILEX_DEFINED
91 typedef struct {
92 FILE f;
93 CRITICAL_SECTION lock;
94 } _FILEX;
95#endif
96
97 extern int _dowildcard;
98 extern int _newmode;
99
100 _CRTIMP wchar_t *** __cdecl __p___winitenv(void);
101#define __winitenv (*__p___winitenv())
102
103 _CRTIMP char *** __cdecl __p___initenv(void);
104#define __initenv (*__p___initenv())
105
106 _CRTIMP void __cdecl _amsg_exit(int) __MINGW_ATTRIB_NORETURN;
107
108 int __CRTDECL _setargv(void);
109 int __CRTDECL __setargv(void);
110 int __CRTDECL _wsetargv(void);
111 int __CRTDECL __wsetargv(void);
112
113 int __CRTDECL main(int _Argc, char **_Argv, char **_Env);
114 int __CRTDECL wmain(int _Argc, wchar_t **_Argv, wchar_t **_Env);
115
116#ifndef _STARTUP_INFO_DEFINED
117#define _STARTUP_INFO_DEFINED
118 typedef struct {
119 int newmode;
120 } _startupinfo;
121#endif
122
123 _CRTIMP int __cdecl __getmainargs(int * _Argc, char *** _Argv, char ***_Env, int _DoWildCard, _startupinfo *_StartInfo);
124 _CRTIMP int __cdecl __wgetmainargs(int * _Argc, wchar_t ***_Argv, wchar_t ***_Env, int _DoWildCard, _startupinfo *_StartInfo);
125
126#define _CONSOLE_APP 1
127#define _GUI_APP 2
128
129 typedef enum __enative_startup_state {
130 __uninitialized = 0, __initializing, __initialized
131 } __enative_startup_state;
132
133 extern volatile __enative_startup_state __native_startup_state;
134 extern void *volatile __native_startup_lock;
135
136 extern volatile unsigned int __native_dllmain_reason;
137 extern volatile unsigned int __native_vcclrit_reason;
138
139 _CRTIMP void __cdecl __set_app_type (int);
140
141 typedef LONG NTSTATUS;
142
143#include <crtdbg.h>
144#include <errno.h>
145
146 BOOL __cdecl _ValidateImageBase (PBYTE pImageBase);
147 PIMAGE_SECTION_HEADER __cdecl _FindPESection (PBYTE pImageBase, DWORD_PTR rva);
148 BOOL __cdecl _IsNonwritableInCurrentImage (PBYTE pTarget);
149
150#if defined(__SSE__)
151# define __mingw_has_sse() 1
152#elif defined(__i386__)
153 int __mingw_has_sse(void);
154#else
155# define __mingw_has_sse() 0
156#endif
157
158#if defined(__i386__) || defined(__x86_64__)
159enum fenv_masks
160{
161 /* x87 encoding constants */
162 FENV_X_INVALID = 0x00100010,
163 FENV_X_DENORMAL = 0x00200020,
164 FENV_X_ZERODIVIDE = 0x00080008,
165 FENV_X_OVERFLOW = 0x00040004,
166 FENV_X_UNDERFLOW = 0x00020002,
167 FENV_X_INEXACT = 0x00010001,
168 FENV_X_AFFINE = 0x00004000,
169 FENV_X_UP = 0x00800200,
170 FENV_X_DOWN = 0x00400100,
171 FENV_X_24 = 0x00002000,
172 FENV_X_53 = 0x00001000,
173 /* SSE encoding constants: they share the same lower word as their x87 counterparts
174 * but differ in the upper word */
175 FENV_Y_INVALID = 0x10000010,
176 FENV_Y_DENORMAL = 0x20000020,
177 FENV_Y_ZERODIVIDE = 0x08000008,
178 FENV_Y_OVERFLOW = 0x04000004,
179 FENV_Y_UNDERFLOW = 0x02000002,
180 FENV_Y_INEXACT = 0x01000001,
181 FENV_Y_UP = 0x80000200,
182 FENV_Y_DOWN = 0x40000100,
183 FENV_Y_FLUSH = 0x00000400,
184 FENV_Y_FLUSH_SAVE = 0x00000800
185};
186
187/* encodes the x87 (represented as x) or SSE (represented as y) control/status word in a ulong */
188static inline unsigned long fenv_encode(unsigned int x, unsigned int y)
189{
190 unsigned long ret = 0;
191
192 if (x & _EM_INVALID) ret |= FENV_X_INVALID;
193 if (x & _EM_DENORMAL) ret |= FENV_X_DENORMAL;
194 if (x & _EM_ZERODIVIDE) ret |= FENV_X_ZERODIVIDE;
195 if (x & _EM_OVERFLOW) ret |= FENV_X_OVERFLOW;
196 if (x & _EM_UNDERFLOW) ret |= FENV_X_UNDERFLOW;
197 if (x & _EM_INEXACT) ret |= FENV_X_INEXACT;
198 if (x & _IC_AFFINE) ret |= FENV_X_AFFINE;
199 if (x & _RC_UP) ret |= FENV_X_UP;
200 if (x & _RC_DOWN) ret |= FENV_X_DOWN;
201 if (x & _PC_24) ret |= FENV_X_24;
202 if (x & _PC_53) ret |= FENV_X_53;
203
204 if (y & _EM_INVALID) ret |= FENV_Y_INVALID;
205 if (y & _EM_DENORMAL) ret |= FENV_Y_DENORMAL;
206 if (y & _EM_ZERODIVIDE) ret |= FENV_Y_ZERODIVIDE;
207 if (y & _EM_OVERFLOW) ret |= FENV_Y_OVERFLOW;
208 if (y & _EM_UNDERFLOW) ret |= FENV_Y_UNDERFLOW;
209 if (y & _EM_INEXACT) ret |= FENV_Y_INEXACT;
210 if (y & _RC_UP) ret |= FENV_Y_UP;
211 if (y & _RC_DOWN) ret |= FENV_Y_DOWN;
212 if (y & _DN_FLUSH) ret |= FENV_Y_FLUSH;
213 if (y & _DN_FLUSH_OPERANDS_SAVE_RESULTS) ret |= FENV_Y_FLUSH_SAVE;
214
215 return ret;
216}
217
218/* decodes the x87 (represented as x) or SSE (represented as y) control/status word in a ulong */
219static inline BOOL fenv_decode(unsigned long enc, unsigned int *x, unsigned int *y)
220{
221 *x = *y = 0;
222 if ((enc & FENV_X_INVALID) == FENV_X_INVALID) *x |= _EM_INVALID;
223 if ((enc & FENV_X_DENORMAL) == FENV_X_DENORMAL) *x |= _EM_DENORMAL;
224 if ((enc & FENV_X_ZERODIVIDE) == FENV_X_ZERODIVIDE) *x |= _EM_ZERODIVIDE;
225 if ((enc & FENV_X_OVERFLOW) == FENV_X_OVERFLOW) *x |= _EM_OVERFLOW;
226 if ((enc & FENV_X_UNDERFLOW) == FENV_X_UNDERFLOW) *x |= _EM_UNDERFLOW;
227 if ((enc & FENV_X_INEXACT) == FENV_X_INEXACT) *x |= _EM_INEXACT;
228 if ((enc & FENV_X_AFFINE) == FENV_X_AFFINE) *x |= _IC_AFFINE;
229 if ((enc & FENV_X_UP) == FENV_X_UP) *x |= _RC_UP;
230 if ((enc & FENV_X_DOWN) == FENV_X_DOWN) *x |= _RC_DOWN;
231 if ((enc & FENV_X_24) == FENV_X_24) *x |= _PC_24;
232 if ((enc & FENV_X_53) == FENV_X_53) *x |= _PC_53;
233
234 if ((enc & FENV_Y_INVALID) == FENV_Y_INVALID) *y |= _EM_INVALID;
235 if ((enc & FENV_Y_DENORMAL) == FENV_Y_DENORMAL) *y |= _EM_DENORMAL;
236 if ((enc & FENV_Y_ZERODIVIDE) == FENV_Y_ZERODIVIDE) *y |= _EM_ZERODIVIDE;
237 if ((enc & FENV_Y_OVERFLOW) == FENV_Y_OVERFLOW) *y |= _EM_OVERFLOW;
238 if ((enc & FENV_Y_UNDERFLOW) == FENV_Y_UNDERFLOW) *y |= _EM_UNDERFLOW;
239 if ((enc & FENV_Y_INEXACT) == FENV_Y_INEXACT) *y |= _EM_INEXACT;
240 if ((enc & FENV_Y_UP) == FENV_Y_UP) *y |= _RC_UP;
241 if ((enc & FENV_Y_DOWN) == FENV_Y_DOWN) *y |= _RC_DOWN;
242 if ((enc & FENV_Y_FLUSH) == FENV_Y_FLUSH) *y |= _DN_FLUSH;
243 if ((enc & FENV_Y_FLUSH_SAVE) == FENV_Y_FLUSH_SAVE) *y |= _DN_FLUSH_OPERANDS_SAVE_RESULTS;
244
245 return fenv_encode(*x, *y) == enc;
246}
247#else
248static inline unsigned long fenv_encode(unsigned int x, unsigned int y)
249{
250 /* Encode _EM_DENORMAL as 0x20 for Windows compatibility. */
251 if (y & _EM_DENORMAL)
252 y = (y & ~_EM_DENORMAL) | 0x20;
253
254 return x | y;
255}
256
257static inline BOOL fenv_decode(unsigned long enc, unsigned int *x, unsigned int *y)
258{
259 /* Decode 0x20 as _EM_DENORMAL. */
260 if (enc & 0x20)
261 enc = (enc & ~0x20) | _EM_DENORMAL;
262
263 *x = *y = enc;
264 return TRUE;
265}
266#endif
267
268void __mingw_setfp( unsigned int *cw, unsigned int cw_mask, unsigned int *sw, unsigned int sw_mask );
269void __mingw_setfp_sse( unsigned int *cw, unsigned int cw_mask, unsigned int *sw, unsigned int sw_mask );
270unsigned int __mingw_controlfp(unsigned int newval, unsigned int mask);
271#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__))
272int __mingw_control87_2(unsigned int, unsigned int, unsigned int *, unsigned int *);
273#endif
274
275static inline unsigned int __mingw_statusfp(void)
276{
277 unsigned int flags = 0;
278#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__))
279 unsigned int x86_sw, sse2_sw = 0;
280 __mingw_setfp(NULL, 0, &x86_sw, 0);
281 if (__mingw_has_sse())
282 __mingw_setfp_sse(NULL, 0, &sse2_sw, 0);
283 flags = x86_sw | sse2_sw;
284#else
285 __mingw_setfp(NULL, 0, &flags, 0);
286#endif
287 return flags;
288}
289
290/* Use naked functions only on Clang. GCC doesn’t support them on ARM targets and
291 * has broken behavior on x86_64 by emitting .seh_endprologue. */
292#ifndef __clang__
293
294#define __ASM_DEFINE_FUNC(rettype, name, args, code) \
295 asm(".text\n\t" \
296 ".p2align 2\n\t" \
297 ".globl " __MINGW64_STRINGIFY(__MINGW_USYMBOL(name)) "\n\t" \
298 ".def " __MINGW64_STRINGIFY(__MINGW_USYMBOL(name)) "; .scl 2; .type 32; .endef\n\t" \
299 __MINGW64_STRINGIFY(__MINGW_USYMBOL(name)) ":\n\t" \
300 code "\n\t");
301
302#else
303
304#define __ASM_DEFINE_FUNC(rettype, name, args, code) \
305 rettype __attribute__((naked)) name args { \
306 asm(code "\n\t"); \
307 }
308
309#endif
310
311#ifdef __cplusplus
312}
313#endif
314
315#pragma pack(pop)
316#endif