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