Added C# implementation of System.Math.ScaleB and System.MathF.ScaleB… (#42476)
[platform/upstream/dotnet/runtime.git] / src / coreclr / pal / inc / pal.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3
4 /*++
5
6 Module Name:
7
8     pal.h
9
10 Abstract:
11
12     CoreCLR Platform Adaptation Layer (PAL) header file.  This file
13     defines all types and API calls required by the CoreCLR when
14     compiled for Unix-like systems.
15
16     Defines which control the behavior of this include file:
17       UNICODE - define it to set the Ansi/Unicode neutral names to
18                 be the ...W names.  Otherwise the neutral names default
19                 to be the ...A names.
20       PAL_IMPLEMENTATION - define it when implementing the PAL.  Otherwise
21                 leave it undefined when consuming the PAL.
22
23     Note:  some fields in structs have been renamed from the original
24     SDK documentation names, with _PAL_Undefined appended.  This leaves
25     the structure layout identical to its Win32 version, but prevents
26     PAL consumers from inadvertently referencing undefined fields.
27
28     If you want to add a PAL_ wrapper function to a native function in
29     here, you also need to edit palinternal.h and win32pal.h.
30
31
32
33 --*/
34
35 #ifndef __PAL_H__
36 #define __PAL_H__
37
38 #ifdef PAL_STDCPP_COMPAT
39 #include <float.h>
40 #include <limits.h>
41 #include <stddef.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <stdarg.h>
45 #include <stdint.h>
46 #include <string.h>
47 #include <errno.h>
48 #include <ctype.h>
49 #include <sys/stat.h>
50 #include <sys/types.h>
51 #include <unistd.h>
52 #endif
53
54 #ifdef  __cplusplus
55 extern "C" {
56 #endif
57
58 // This macro is used to standardize the wide character string literals between UNIX and Windows.
59 // Unix L"" is UTF32, and on windows it's UTF16.  Because of built-in assumptions on the size
60 // of string literals, it's important to match behaviour between Unix and Windows.  Unix will be defined
61 // as u"" (char16_t)
62 #define W(str)  u##str
63
64 // Undefine the QUOTE_MACRO_L helper and redefine it in terms of u.
65 // The reason that we do this is that quote macro is defined in ndp\common\inc,
66 // not inside of coreclr sources.
67
68 #define QUOTE_MACRO_L(x) QUOTE_MACRO_u(x)
69 #define QUOTE_MACRO_u_HELPER(x)     u###x
70 #define QUOTE_MACRO_u(x)            QUOTE_MACRO_u_HELPER(x)
71
72 #include <pal_error.h>
73 #include <pal_mstypes.h>
74
75 // Native system libray handle.
76 // On Unix systems, NATIVE_LIBRARY_HANDLE type represents a library handle not registered with the PAL.
77 typedef PVOID NATIVE_LIBRARY_HANDLE;
78
79 /******************* Processor-specific glue  *****************************/
80
81 #ifndef _MSC_VER
82
83 #if defined(__i686__) && !defined(_M_IX86)
84 #define _M_IX86 600
85 #elif defined(__i586__) && !defined(_M_IX86)
86 #define _M_IX86 500
87 #elif defined(__i486__) && !defined(_M_IX86)
88 #define _M_IX86 400
89 #elif defined(__i386__) && !defined(_M_IX86)
90 #define _M_IX86 300
91 #elif defined(__x86_64__) && !defined(_M_AMD64)
92 #define _M_AMD64 100
93 #elif defined(__arm__) && !defined(_M_ARM)
94 #define _M_ARM 7
95 #elif defined(__aarch64__) && !defined(_M_ARM64)
96 #define _M_ARM64 1
97 #endif
98
99 #if defined(_M_IX86) && !defined(HOST_X86)
100 #define HOST_X86
101 #elif defined(_M_AMD64) && !defined(HOST_AMD64)
102 #define HOST_AMD64
103 #elif defined(_M_ARM) && !defined(HOST_ARM)
104 #define HOST_ARM
105 #elif defined(_M_ARM64) && !defined(HOST_ARM64)
106 #define HOST_ARM64
107 #endif
108
109 #endif // !_MSC_VER
110
111 /******************* ABI-specific glue *******************************/
112
113 #define MAX_PATH 260
114 #define _MAX_PATH 260
115 #define _MAX_DRIVE  3   /* max. length of drive component */
116 #define _MAX_DIR    256 /* max. length of path component */
117 #define _MAX_FNAME  256 /* max. length of file name component */
118 #define _MAX_EXT    256 /* max. length of extension component */
119
120 // In some Win32 APIs MAX_PATH is used for file names (even though 256 is the normal file system limit)
121 // use _MAX_PATH_FNAME to indicate these cases
122 #define MAX_PATH_FNAME MAX_PATH
123 #define MAX_LONGPATH   1024  /* max. length of full pathname */
124
125 #define MAXSHORT      0x7fff
126 #define MAXLONG       0x7fffffff
127 #define MAXCHAR       0x7f
128 #define MAXDWORD      0xffffffff
129
130 //  Sorting IDs.
131 //
132 //  Note that the named locale APIs (eg CompareStringExEx) are recommended.
133 //
134
135 #define LANG_ENGLISH                     0x09
136
137 /******************* Compiler-specific glue *******************************/
138 #ifndef THROW_DECL
139 #if defined(_MSC_VER) || !defined(__cplusplus)
140 #define THROW_DECL
141 #else
142 #define THROW_DECL throw()
143 #endif // !_MSC_VER
144 #endif // !THROW_DECL
145
146 #if defined(_MSC_VER)
147 #define DECLSPEC_ALIGN(x)   __declspec(align(x))
148 #else
149 #define DECLSPEC_ALIGN(x)   __attribute__ ((aligned(x)))
150 #endif
151
152 #define DECLSPEC_NORETURN   PAL_NORETURN
153
154 #ifdef __clang_analyzer__
155 #define ANALYZER_NORETURN __attribute((analyzer_noreturn))
156 #else
157 #define ANALYZER_NORETURN
158 #endif
159
160 #define EMPTY_BASES_DECL
161
162
163 #if !defined(_MSC_VER) || defined(SOURCE_FORMATTING)
164 #define __assume(x) (void)0
165 #define __annotation(x)
166 #endif //!MSC_VER
167
168 #define UNALIGNED
169
170 #ifndef FORCEINLINE
171 #if _MSC_VER < 1200
172 #define FORCEINLINE inline
173 #else
174 #define FORCEINLINE __forceinline
175 #endif
176 #endif
177
178 #ifndef NOOPT_ATTRIBUTE
179 #if defined(__llvm__)
180 #define NOOPT_ATTRIBUTE optnone
181 #elif defined(__GNUC__)
182 #define NOOPT_ATTRIBUTE optimize("O0")
183 #endif
184 #endif
185
186 #ifndef NODEBUG_ATTRIBUTE
187 #if defined(__llvm__)
188 #define NODEBUG_ATTRIBUTE __nodebug__
189 #elif defined(__GNUC__)
190 #define NODEBUG_ATTRIBUTE __artificial__
191 #endif
192 #endif
193
194 #ifndef __has_cpp_attribute
195 #define __has_cpp_attribute(x) (0)
196 #endif
197
198 #ifndef FALLTHROUGH
199 #if __has_cpp_attribute(fallthrough)
200 #define FALLTHROUGH [[fallthrough]]
201 #else // __has_cpp_attribute(fallthrough)
202 #define FALLTHROUGH
203 #endif // __has_cpp_attribute(fallthrough)
204 #endif // FALLTHROUGH
205
206 #ifndef PAL_STDCPP_COMPAT
207
208 #if __GNUC__
209
210 typedef __builtin_va_list va_list;
211
212 /* We should consider if the va_arg definition here is actually necessary.
213    Could we use the standard va_arg definition? */
214
215 #define va_start    __builtin_va_start
216 #define va_arg      __builtin_va_arg
217
218 #define va_copy     __builtin_va_copy
219 #define va_end      __builtin_va_end
220
221 #define VOID void
222
223 #else // __GNUC__
224
225 typedef char * va_list;
226
227 #define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
228
229 #if _MSC_VER >= 1400
230
231 #ifdef  __cplusplus
232 #define _ADDRESSOF(v)   ( &reinterpret_cast<const char &>(v) )
233 #else
234 #define _ADDRESSOF(v)   ( &(v) )
235 #endif
236
237 #define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
238 #define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
239 #define _crt_va_end(ap)      ( ap = (va_list)0 )
240
241 #define va_start _crt_va_start
242 #define va_arg _crt_va_arg
243 #define va_end _crt_va_end
244
245 #else  // _MSC_VER
246
247 #define va_start(ap,v)    (ap = (va_list) (&(v)) + _INTSIZEOF(v))
248 #define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
249 #define va_end(ap)
250
251 #endif // _MSC_VER
252
253 #define va_copy(dest,src) (dest = src)
254
255 #endif // __GNUC__
256
257 #define CHAR_BIT      8
258
259 #define SCHAR_MIN   (-128)
260 #define SCHAR_MAX     127
261 #define UCHAR_MAX     0xff
262
263 #define SHRT_MIN    (-32768)
264 #define SHRT_MAX      32767
265 #define USHRT_MAX     0xffff
266
267 #define INT_MIN     (-2147483647 - 1)
268 #define INT_MAX       2147483647
269 #define UINT_MAX      0xffffffff
270
271 // LONG_MIN, LONG_MAX, ULONG_MAX -- use INT32_MIN etc. instead.
272
273 #define FLT_MAX 3.402823466e+38F
274 #define DBL_MAX 1.7976931348623157e+308
275
276 #endif // !PAL_STDCPP_COMPAT
277
278 /******************* PAL-Specific Entrypoints *****************************/
279
280 #define IsDebuggerPresent PAL_IsDebuggerPresent
281
282 PALIMPORT
283 BOOL
284 PALAPI
285 PAL_IsDebuggerPresent();
286
287 /* minimum signed 64 bit value */
288 #define _I64_MIN    (I64(-9223372036854775807) - 1)
289 /* maximum signed 64 bit value */
290 #define _I64_MAX      I64(9223372036854775807)
291 /* maximum unsigned 64 bit value */
292 #define _UI64_MAX     UI64(0xffffffffffffffff)
293
294 #define _I8_MAX   SCHAR_MAX
295 #define _I8_MIN   SCHAR_MIN
296 #define _I16_MAX  SHRT_MAX
297 #define _I16_MIN  SHRT_MIN
298 #define _I32_MAX  INT_MAX
299 #define _I32_MIN  INT_MIN
300 #define _UI8_MAX  UCHAR_MAX
301 #define _UI8_MIN  UCHAR_MIN
302 #define _UI16_MAX USHRT_MAX
303 #define _UI16_MIN USHRT_MIN
304 #define _UI32_MAX UINT_MAX
305 #define _UI32_MIN UINT_MIN
306
307 #undef NULL
308
309 #if defined(__cplusplus)
310 #define NULL    0
311 #else
312 #define NULL    ((PVOID)0)
313 #endif
314
315 #if defined(PAL_STDCPP_COMPAT) && !defined(__cplusplus)
316 #define nullptr NULL
317 #endif // defined(PAL_STDCPP_COMPAT) && !defined(__cplusplus)
318
319 #ifndef PAL_STDCPP_COMPAT
320
321 #if HOST_64BIT || _MSC_VER >= 1400
322 typedef __int64 time_t;
323 #else
324 typedef long time_t;
325 #endif
326 #define _TIME_T_DEFINED
327 #endif // !PAL_STDCPP_COMPAT
328
329 #define DLL_PROCESS_ATTACH 1
330 #define DLL_THREAD_ATTACH  2
331 #define DLL_THREAD_DETACH  3
332 #define DLL_PROCESS_DETACH 0
333
334 #define PAL_INITIALIZE_NONE                         0x00
335 #define PAL_INITIALIZE_SYNC_THREAD                  0x01
336 #define PAL_INITIALIZE_EXEC_ALLOCATOR               0x02
337 #define PAL_INITIALIZE_STD_HANDLES                  0x04
338 #define PAL_INITIALIZE_REGISTER_SIGTERM_HANDLER     0x08
339 #define PAL_INITIALIZE_DEBUGGER_EXCEPTIONS          0x10
340 #define PAL_INITIALIZE_ENSURE_STACK_SIZE            0x20
341 #define PAL_INITIALIZE_REGISTER_SIGNALS             0x40
342
343 // PAL_Initialize() flags
344 #define PAL_INITIALIZE                 (PAL_INITIALIZE_SYNC_THREAD | \
345                                         PAL_INITIALIZE_STD_HANDLES)
346
347 // PAL_InitializeDLL() flags - don't start any of the helper threads or register any exceptions
348 #define PAL_INITIALIZE_DLL              PAL_INITIALIZE_NONE
349
350 // PAL_InitializeCoreCLR() flags
351 #define PAL_INITIALIZE_CORECLR         (PAL_INITIALIZE | \
352                                         PAL_INITIALIZE_EXEC_ALLOCATOR | \
353                                         PAL_INITIALIZE_REGISTER_SIGTERM_HANDLER | \
354                                         PAL_INITIALIZE_DEBUGGER_EXCEPTIONS | \
355                                         PAL_INITIALIZE_ENSURE_STACK_SIZE | \
356                                         PAL_INITIALIZE_REGISTER_SIGNALS)
357
358 typedef DWORD (PALAPI_NOEXPORT *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
359 typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
360
361 /******************* PAL-Specific Entrypoints *****************************/
362
363 PALIMPORT
364 int
365 PALAPI
366 PAL_Initialize(
367     int argc,
368     char * const argv[]);
369
370 PALIMPORT
371 void
372 PALAPI
373 PAL_InitializeWithFlags(
374     DWORD flags);
375
376 PALIMPORT
377 int
378 PALAPI
379 PAL_InitializeDLL();
380
381 PALIMPORT
382 void
383 PALAPI
384 PAL_SetInitializeDLLFlags(
385     DWORD flags);
386
387 PALIMPORT
388 DWORD
389 PALAPI
390 PAL_InitializeCoreCLR(
391     const char *szExePath, BOOL runningInExe);
392
393 /// <summary>
394 /// This function shuts down PAL WITHOUT exiting the current process.
395 /// </summary>
396 PALIMPORT
397 void
398 PALAPI
399 PAL_Shutdown(
400     void);
401
402 /// <summary>
403 /// This function shuts down PAL and exits the current process.
404 /// </summary>
405 PALIMPORT
406 void
407 PALAPI
408 PAL_Terminate(
409     void);
410
411 /// <summary>
412 /// This function shuts down PAL and exits the current process with
413 /// the specified exit code.
414 /// </summary>
415 PALIMPORT
416 void
417 PALAPI
418 PAL_TerminateEx(
419     int exitCode);
420
421 typedef VOID (*PSHUTDOWN_CALLBACK)(void);
422
423 PALIMPORT
424 VOID
425 PALAPI
426 PAL_SetShutdownCallback(
427     IN PSHUTDOWN_CALLBACK callback);
428
429 PALIMPORT
430 BOOL
431 PALAPI
432 PAL_GenerateCoreDump(
433     IN LPCSTR dumpName,
434     IN INT dumpType,
435     IN BOOL diag);
436
437 typedef VOID (*PPAL_STARTUP_CALLBACK)(
438     char *modulePath,
439     HMODULE hModule,
440     PVOID parameter);
441
442 PALIMPORT
443 DWORD
444 PALAPI
445 PAL_RegisterForRuntimeStartup(
446     IN DWORD dwProcessId,
447     IN LPCWSTR lpApplicationGroupId,
448     IN PPAL_STARTUP_CALLBACK pfnCallback,
449     IN PVOID parameter,
450     OUT PVOID *ppUnregisterToken);
451
452 PALIMPORT
453 DWORD
454 PALAPI
455 PAL_UnregisterForRuntimeStartup(
456     IN PVOID pUnregisterToken);
457
458 PALIMPORT
459 BOOL
460 PALAPI
461 PAL_NotifyRuntimeStarted();
462
463 PALIMPORT
464 LPCSTR
465 PALAPI
466 PAL_GetApplicationGroupId();
467
468 static const unsigned int MAX_DEBUGGER_TRANSPORT_PIPE_NAME_LENGTH = MAX_PATH;
469
470 PALIMPORT
471 VOID
472 PALAPI
473 PAL_GetTransportName(
474     const unsigned int MAX_TRANSPORT_NAME_LENGTH,
475     OUT char *name,
476     IN const char *prefix,
477     IN DWORD id,
478     IN const char *applicationGroupId,
479     IN const char *suffix);
480
481 PALIMPORT
482 VOID
483 PALAPI
484 PAL_GetTransportPipeName(
485     OUT char *name,
486     IN DWORD id,
487     IN const char *applicationGroupId,
488     IN const char *suffix);
489
490 PALIMPORT
491 void
492 PALAPI
493 PAL_IgnoreProfileSignal(int signalNum);
494
495 PALIMPORT
496 HINSTANCE
497 PALAPI
498 PAL_RegisterModule(
499     IN LPCSTR lpLibFileName);
500
501 PALIMPORT
502 VOID
503 PALAPI
504 PAL_UnregisterModule(
505     IN HINSTANCE hInstance);
506
507 PALIMPORT
508 VOID
509 PALAPI
510 PAL_Random(
511     IN OUT LPVOID lpBuffer,
512     IN DWORD dwLength);
513
514 PALIMPORT
515 BOOL
516 PALAPI
517 PAL_OpenProcessMemory(
518     IN DWORD processId,
519     OUT DWORD* pHandle
520 );
521
522 PALIMPORT
523 VOID
524 PALAPI
525 PAL_CloseProcessMemory(
526     IN DWORD handle
527 );
528
529 PALIMPORT
530 BOOL
531 PALAPI
532 PAL_ReadProcessMemory(
533     IN DWORD handle,
534     IN ULONG64 address,
535     IN LPVOID buffer,
536     IN SIZE_T size,
537     OUT SIZE_T* numberOfBytesRead
538 );
539
540 PALIMPORT
541 BOOL
542 PALAPI
543 PAL_ProbeMemory(
544     PVOID pBuffer,
545     DWORD cbBuffer,
546     BOOL fWriteAccess);
547
548 PALIMPORT
549 int
550 PALAPI
551 // Start the jitdump file
552 PAL_PerfJitDump_Start(const char* path);
553
554 PALIMPORT
555 int
556 PALAPI
557 // Log a method to the jitdump file.
558 PAL_PerfJitDump_LogMethod(void* pCode, size_t codeSize, const char* symbol, void* debugInfo, void* unwindInfo);
559
560 PALIMPORT
561 int
562 PALAPI
563 // Finish the jitdump file
564 PAL_PerfJitDump_Finish();
565
566 /******************* winuser.h Entrypoints *******************************/
567
568 #define MB_OK                   0x00000000L
569 #define MB_OKCANCEL             0x00000001L
570 #define MB_ABORTRETRYIGNORE     0x00000002L
571 #define MB_YESNO                0x00000004L
572 #define MB_RETRYCANCEL          0x00000005L
573
574 #define MB_ICONHAND             0x00000010L
575 #define MB_ICONQUESTION         0x00000020L
576 #define MB_ICONEXCLAMATION      0x00000030L
577 #define MB_ICONASTERISK         0x00000040L
578
579 #define MB_ICONINFORMATION      MB_ICONASTERISK
580 #define MB_ICONSTOP             MB_ICONHAND
581 #define MB_ICONERROR            MB_ICONHAND
582
583 #define MB_DEFBUTTON1           0x00000000L
584 #define MB_DEFBUTTON2           0x00000100L
585 #define MB_DEFBUTTON3           0x00000200L
586
587 #define MB_SYSTEMMODAL          0x00001000L
588 #define MB_TASKMODAL            0x00002000L
589 #define MB_SETFOREGROUND        0x00010000L
590 #define MB_TOPMOST              0x00040000L
591
592 #define MB_NOFOCUS                  0x00008000L
593 #define MB_DEFAULT_DESKTOP_ONLY     0x00020000L
594
595 // Note: this is the NT 4.0 and greater value.
596 #define MB_SERVICE_NOTIFICATION 0x00200000L
597
598 #define MB_TYPEMASK             0x0000000FL
599 #define MB_ICONMASK             0x000000F0L
600 #define MB_DEFMASK              0x00000F00L
601
602 #define IDOK                    1
603 #define IDCANCEL                2
604 #define IDABORT                 3
605 #define IDRETRY                 4
606 #define IDIGNORE                5
607 #define IDYES                   6
608 #define IDNO                    7
609
610
611 PALIMPORT
612 int
613 PALAPI
614 MessageBoxW(
615         IN LPVOID hWnd,  // NOTE: diff from winuser.h
616         IN LPCWSTR lpText,
617         IN LPCWSTR lpCaption,
618         IN UINT uType);
619
620
621 #ifdef UNICODE
622 #define MessageBox MessageBoxW
623 #else
624 #define MessageBox MessageBoxA
625 #endif
626
627 // From win32.h
628 #ifndef _CRTIMP
629 #ifdef __GNUC__
630 #define _CRTIMP
631 #else // __GNUC__
632 #define _CRTIMP __declspec(dllimport)
633 #endif // __GNUC__
634 #endif // _CRTIMP
635
636 /******************* winbase.h Entrypoints and defines ************************/
637 typedef struct _SECURITY_ATTRIBUTES {
638             DWORD nLength;
639             LPVOID lpSecurityDescriptor;
640             BOOL bInheritHandle;
641 } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
642
643 #define _SH_DENYWR      0x20    /* deny write mode */
644
645 #define FILE_READ_DATA            ( 0x0001 )    // file & pipe
646 #define FILE_APPEND_DATA          ( 0x0004 )    // file
647
648 #define GENERIC_READ               (0x80000000L)
649 #define GENERIC_WRITE              (0x40000000L)
650
651 #define FILE_SHARE_READ            0x00000001
652 #define FILE_SHARE_WRITE           0x00000002
653 #define FILE_SHARE_DELETE          0x00000004
654
655 #define CREATE_NEW                 1
656 #define CREATE_ALWAYS              2
657 #define OPEN_EXISTING              3
658 #define OPEN_ALWAYS                4
659 #define TRUNCATE_EXISTING          5
660
661 #define FILE_ATTRIBUTE_READONLY                 0x00000001
662 #define FILE_ATTRIBUTE_HIDDEN                   0x00000002
663 #define FILE_ATTRIBUTE_SYSTEM                   0x00000004
664 #define FILE_ATTRIBUTE_DIRECTORY                0x00000010
665 #define FILE_ATTRIBUTE_ARCHIVE                  0x00000020
666 #define FILE_ATTRIBUTE_DEVICE                   0x00000040
667 #define FILE_ATTRIBUTE_NORMAL                   0x00000080
668
669 #define FILE_FLAG_WRITE_THROUGH    0x80000000
670 #define FILE_FLAG_NO_BUFFERING     0x20000000
671 #define FILE_FLAG_RANDOM_ACCESS    0x10000000
672 #define FILE_FLAG_SEQUENTIAL_SCAN  0x08000000
673 #define FILE_FLAG_BACKUP_SEMANTICS 0x02000000
674
675 #define FILE_BEGIN                 0
676 #define FILE_CURRENT               1
677 #define FILE_END                   2
678
679 #define STILL_ACTIVE (0x00000103L)
680
681 #define INVALID_SET_FILE_POINTER   ((DWORD)-1)
682
683
684 PALIMPORT
685 HANDLE
686 PALAPI
687 CreateFileW(
688         IN LPCWSTR lpFileName,
689         IN DWORD dwDesiredAccess,
690         IN DWORD dwShareMode,
691         IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
692         IN DWORD dwCreationDisposition,
693         IN DWORD dwFlagsAndAttributes,
694         IN HANDLE hTemplateFile);
695
696 #ifdef UNICODE
697 #define CreateFile CreateFileW
698 #else
699 #define CreateFile CreateFileA
700 #endif
701
702
703 PALIMPORT
704 DWORD
705 PALAPI
706 SearchPathW(
707     IN LPCWSTR lpPath,
708     IN LPCWSTR lpFileName,
709     IN LPCWSTR lpExtension,
710     IN DWORD nBufferLength,
711     OUT LPWSTR lpBuffer,
712     OUT LPWSTR *lpFilePart
713     );
714
715 #define SearchPath  SearchPathW
716
717 PALIMPORT
718 BOOL
719 PALAPI
720 CopyFileW(
721       IN LPCWSTR lpExistingFileName,
722       IN LPCWSTR lpNewFileName,
723       IN BOOL bFailIfExists);
724
725 #ifdef UNICODE
726 #define CopyFile CopyFileW
727 #else
728 #define CopyFile CopyFileA
729 #endif
730
731 PALIMPORT
732 BOOL
733 PALAPI
734 DeleteFileW(
735         IN LPCWSTR lpFileName);
736
737 #ifdef UNICODE
738 #define DeleteFile DeleteFileW
739 #else
740 #define DeleteFile DeleteFileA
741 #endif
742
743 #define MOVEFILE_REPLACE_EXISTING      0x00000001
744 #define MOVEFILE_COPY_ALLOWED          0x00000002
745
746 PALIMPORT
747 BOOL
748 PALAPI
749 MoveFileExW(
750         IN LPCWSTR lpExistingFileName,
751         IN LPCWSTR lpNewFileName,
752         IN DWORD dwFlags);
753
754 #ifdef UNICODE
755 #define MoveFileEx MoveFileExW
756 #else
757 #define MoveFileEx MoveFileExA
758 #endif
759
760 typedef struct _BY_HANDLE_FILE_INFORMATION {
761     DWORD dwFileAttributes;
762     FILETIME ftCreationTime;
763     FILETIME ftLastAccessTime;
764     FILETIME ftLastWriteTime;
765     DWORD dwVolumeSerialNumber;
766     DWORD nFileSizeHigh;
767     DWORD nFileSizeLow;
768     DWORD nNumberOfLinks;
769     DWORD nFileIndexHigh;
770     DWORD nFileIndexLow;
771 } BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION, *LPBY_HANDLE_FILE_INFORMATION;
772
773 typedef struct _WIN32_FIND_DATAA {
774     DWORD dwFileAttributes;
775     FILETIME ftCreationTime;
776     FILETIME ftLastAccessTime;
777     FILETIME ftLastWriteTime;
778     DWORD nFileSizeHigh;
779     DWORD nFileSizeLow;
780     DWORD dwReserved0;
781     DWORD dwReserved1;
782     CHAR cFileName[ MAX_PATH_FNAME ];
783     CHAR cAlternateFileName[ 14 ];
784 } WIN32_FIND_DATAA, *PWIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
785
786 typedef struct _WIN32_FIND_DATAW {
787     DWORD dwFileAttributes;
788     FILETIME ftCreationTime;
789     FILETIME ftLastAccessTime;
790     FILETIME ftLastWriteTime;
791     DWORD nFileSizeHigh;
792     DWORD nFileSizeLow;
793     DWORD dwReserved0;
794     DWORD dwReserved1;
795     WCHAR cFileName[ MAX_PATH_FNAME ];
796     WCHAR cAlternateFileName[ 14 ];
797 } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;
798
799 #ifdef UNICODE
800 typedef WIN32_FIND_DATAW WIN32_FIND_DATA;
801 typedef PWIN32_FIND_DATAW PWIN32_FIND_DATA;
802 typedef LPWIN32_FIND_DATAW LPWIN32_FIND_DATA;
803 #else
804 typedef WIN32_FIND_DATAA WIN32_FIND_DATA;
805 typedef PWIN32_FIND_DATAA PWIN32_FIND_DATA;
806 typedef LPWIN32_FIND_DATAA LPWIN32_FIND_DATA;
807 #endif
808
809 PALIMPORT
810 HANDLE
811 PALAPI
812 FindFirstFileW(
813            IN LPCWSTR lpFileName,
814            OUT LPWIN32_FIND_DATAW lpFindFileData);
815
816 #ifdef UNICODE
817 #define FindFirstFile FindFirstFileW
818 #else
819 #define FindFirstFile FindFirstFileA
820 #endif
821
822 PALIMPORT
823 BOOL
824 PALAPI
825 FindNextFileW(
826           IN HANDLE hFindFile,
827           OUT LPWIN32_FIND_DATAW lpFindFileData);
828
829 #ifdef UNICODE
830 #define FindNextFile FindNextFileW
831 #else
832 #define FindNextFile FindNextFileA
833 #endif
834
835 PALIMPORT
836 BOOL
837 PALAPI
838 FindClose(
839       IN OUT HANDLE hFindFile);
840
841 PALIMPORT
842 DWORD
843 PALAPI
844 GetFileAttributesW(
845            IN LPCWSTR lpFileName);
846
847 #ifdef UNICODE
848 #define GetFileAttributes GetFileAttributesW
849 #else
850 #define GetFileAttributes GetFileAttributesA
851 #endif
852
853 typedef enum _GET_FILEEX_INFO_LEVELS {
854   GetFileExInfoStandard
855 } GET_FILEEX_INFO_LEVELS;
856
857 typedef enum _FINDEX_INFO_LEVELS {
858     FindExInfoStandard,
859     FindExInfoBasic,
860     FindExInfoMaxInfoLevel
861 } FINDEX_INFO_LEVELS;
862
863 typedef enum _FINDEX_SEARCH_OPS {
864     FindExSearchNameMatch,
865     FindExSearchLimitToDirectories,
866     FindExSearchLimitToDevices,
867     FindExSearchMaxSearchOp
868 } FINDEX_SEARCH_OPS;
869
870 typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
871     DWORD      dwFileAttributes;
872     FILETIME   ftCreationTime;
873     FILETIME   ftLastAccessTime;
874     FILETIME   ftLastWriteTime;
875     DWORD      nFileSizeHigh;
876     DWORD      nFileSizeLow;
877 } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA;
878
879 PALIMPORT
880 BOOL
881 PALAPI
882 GetFileAttributesExW(
883              IN LPCWSTR lpFileName,
884              IN GET_FILEEX_INFO_LEVELS fInfoLevelId,
885              OUT LPVOID lpFileInformation);
886
887 #ifdef UNICODE
888 #define GetFileAttributesEx GetFileAttributesExW
889 #endif
890
891 typedef struct _OVERLAPPED {
892     ULONG_PTR Internal;
893     ULONG_PTR InternalHigh;
894     DWORD Offset;
895     DWORD OffsetHigh;
896     HANDLE  hEvent;
897 } OVERLAPPED, *LPOVERLAPPED;
898
899 PALIMPORT
900 BOOL
901 PALAPI
902 WriteFile(
903       IN HANDLE hFile,
904       IN LPCVOID lpBuffer,
905       IN DWORD nNumberOfBytesToWrite,
906       OUT LPDWORD lpNumberOfBytesWritten,
907       IN LPOVERLAPPED lpOverlapped);
908
909 PALIMPORT
910 BOOL
911 PALAPI
912 ReadFile(
913      IN HANDLE hFile,
914      OUT LPVOID lpBuffer,
915      IN DWORD nNumberOfBytesToRead,
916      OUT LPDWORD lpNumberOfBytesRead,
917      IN LPOVERLAPPED lpOverlapped);
918
919 #define STD_INPUT_HANDLE         ((DWORD)-10)
920 #define STD_OUTPUT_HANDLE        ((DWORD)-11)
921 #define STD_ERROR_HANDLE         ((DWORD)-12)
922
923 PALIMPORT
924 HANDLE
925 PALAPI
926 GetStdHandle(
927          IN DWORD nStdHandle);
928
929 PALIMPORT
930 BOOL
931 PALAPI
932 SetEndOfFile(
933          IN HANDLE hFile);
934
935 PALIMPORT
936 DWORD
937 PALAPI
938 SetFilePointer(
939            IN HANDLE hFile,
940            IN LONG lDistanceToMove,
941            IN PLONG lpDistanceToMoveHigh,
942            IN DWORD dwMoveMethod);
943
944 PALIMPORT
945 BOOL
946 PALAPI
947 SetFilePointerEx(
948            IN HANDLE hFile,
949            IN LARGE_INTEGER liDistanceToMove,
950            OUT PLARGE_INTEGER lpNewFilePointer,
951            IN DWORD dwMoveMethod);
952
953 PALIMPORT
954 DWORD
955 PALAPI
956 GetFileSize(
957         IN HANDLE hFile,
958         OUT LPDWORD lpFileSizeHigh);
959
960 PALIMPORT
961 BOOL
962 PALAPI GetFileSizeEx(
963         IN   HANDLE hFile,
964         OUT  PLARGE_INTEGER lpFileSize);
965
966 PALIMPORT
967 VOID
968 PALAPI
969 GetSystemTimeAsFileTime(
970             OUT LPFILETIME lpSystemTimeAsFileTime);
971
972 typedef struct _SYSTEMTIME {
973     WORD wYear;
974     WORD wMonth;
975     WORD wDayOfWeek;
976     WORD wDay;
977     WORD wHour;
978     WORD wMinute;
979     WORD wSecond;
980     WORD wMilliseconds;
981 } SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
982
983 PALIMPORT
984 VOID
985 PALAPI
986 GetSystemTime(
987           OUT LPSYSTEMTIME lpSystemTime);
988
989 PALIMPORT
990 BOOL
991 PALAPI
992 FileTimeToSystemTime(
993             IN CONST FILETIME *lpFileTime,
994             OUT LPSYSTEMTIME lpSystemTime);
995
996
997
998 PALIMPORT
999 BOOL
1000 PALAPI
1001 FlushFileBuffers(
1002          IN HANDLE hFile);
1003
1004 PALIMPORT
1005 UINT
1006 PALAPI
1007 GetConsoleOutputCP();
1008
1009 PALIMPORT
1010 DWORD
1011 PALAPI
1012 GetFullPathNameW(
1013          IN LPCWSTR lpFileName,
1014          IN DWORD nBufferLength,
1015          OUT LPWSTR lpBuffer,
1016          OUT LPWSTR *lpFilePart);
1017
1018 #ifdef UNICODE
1019 #define GetFullPathName GetFullPathNameW
1020 #else
1021 #define GetFullPathName GetFullPathNameA
1022 #endif
1023
1024 PALIMPORT
1025 UINT
1026 PALAPI
1027 GetTempFileNameW(
1028          IN LPCWSTR lpPathName,
1029          IN LPCWSTR lpPrefixString,
1030          IN UINT uUnique,
1031          OUT LPWSTR lpTempFileName);
1032
1033 #ifdef UNICODE
1034 #define GetTempFileName GetTempFileNameW
1035 #else
1036 #define GetTempFileName GetTempFileNameA
1037 #endif
1038
1039 PALIMPORT
1040 DWORD
1041 PALAPI
1042 GetTempPathW(
1043          IN DWORD nBufferLength,
1044          OUT LPWSTR lpBuffer);
1045
1046 PALIMPORT
1047 DWORD
1048 PALAPI
1049 GetTempPathA(
1050          IN DWORD nBufferLength,
1051          OUT LPSTR lpBuffer);
1052
1053
1054 #ifdef UNICODE
1055 #define GetTempPath GetTempPathW
1056 #else
1057 #define GetTempPath GetTempPathA
1058 #endif
1059
1060 PALIMPORT
1061 DWORD
1062 PALAPI
1063 GetCurrentDirectoryW(
1064              IN DWORD nBufferLength,
1065              OUT LPWSTR lpBuffer);
1066
1067 #ifdef UNICODE
1068 #define GetCurrentDirectory GetCurrentDirectoryW
1069 #else
1070 #define GetCurrentDirectory GetCurrentDirectoryA
1071 #endif
1072
1073 PALIMPORT
1074 HANDLE
1075 PALAPI
1076 CreateSemaphoreExW(
1077         IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
1078         IN LONG lInitialCount,
1079         IN LONG lMaximumCount,
1080         IN LPCWSTR lpName,
1081         IN /*_Reserved_*/  DWORD dwFlags,
1082         IN DWORD dwDesiredAccess);
1083
1084 PALIMPORT
1085 HANDLE
1086 PALAPI
1087 OpenSemaphoreW(
1088     IN DWORD dwDesiredAccess,
1089     IN BOOL bInheritHandle,
1090     IN LPCWSTR lpName);
1091
1092 #define CreateSemaphoreEx CreateSemaphoreExW
1093
1094 PALIMPORT
1095 BOOL
1096 PALAPI
1097 ReleaseSemaphore(
1098          IN HANDLE hSemaphore,
1099          IN LONG lReleaseCount,
1100          OUT LPLONG lpPreviousCount);
1101
1102 PALIMPORT
1103 HANDLE
1104 PALAPI
1105 CreateEventW(
1106          IN LPSECURITY_ATTRIBUTES lpEventAttributes,
1107          IN BOOL bManualReset,
1108          IN BOOL bInitialState,
1109          IN LPCWSTR lpName);
1110
1111 PALIMPORT
1112 HANDLE
1113 PALAPI
1114 CreateEventExW(
1115          IN LPSECURITY_ATTRIBUTES lpEventAttributes,
1116          IN LPCWSTR lpName,
1117          IN DWORD dwFlags,
1118          IN DWORD dwDesiredAccess);
1119
1120 // CreateEventExW: dwFlags
1121 #define CREATE_EVENT_MANUAL_RESET ((DWORD)0x1)
1122 #define CREATE_EVENT_INITIAL_SET ((DWORD)0x2)
1123
1124 #define CreateEvent CreateEventW
1125
1126 PALIMPORT
1127 BOOL
1128 PALAPI
1129 SetEvent(
1130      IN HANDLE hEvent);
1131
1132 PALIMPORT
1133 BOOL
1134 PALAPI
1135 ResetEvent(
1136        IN HANDLE hEvent);
1137
1138 PALIMPORT
1139 HANDLE
1140 PALAPI
1141 OpenEventW(
1142        IN DWORD dwDesiredAccess,
1143        IN BOOL bInheritHandle,
1144        IN LPCWSTR lpName);
1145
1146 #ifdef UNICODE
1147 #define OpenEvent OpenEventW
1148 #endif
1149
1150 PALIMPORT
1151 HANDLE
1152 PALAPI
1153 CreateMutexW(
1154     IN LPSECURITY_ATTRIBUTES lpMutexAttributes,
1155     IN BOOL bInitialOwner,
1156     IN LPCWSTR lpName);
1157
1158 PALIMPORT
1159 HANDLE
1160 PALAPI
1161 CreateMutexExW(
1162     IN LPSECURITY_ATTRIBUTES lpMutexAttributes,
1163     IN LPCWSTR lpName,
1164     IN DWORD dwFlags,
1165     IN DWORD dwDesiredAccess);
1166
1167 // CreateMutexExW: dwFlags
1168 #define CREATE_MUTEX_INITIAL_OWNER ((DWORD)0x1)
1169
1170 #define CreateMutex CreateMutexW
1171
1172 PALIMPORT
1173 HANDLE
1174 PALAPI
1175 OpenMutexW(
1176        IN DWORD dwDesiredAccess,
1177        IN BOOL bInheritHandle,
1178        IN LPCWSTR lpName);
1179
1180 #ifdef UNICODE
1181 #define OpenMutex  OpenMutexW
1182 #endif
1183
1184 PALIMPORT
1185 BOOL
1186 PALAPI
1187 ReleaseMutex(
1188     IN HANDLE hMutex);
1189
1190 PALIMPORT
1191 DWORD
1192 PALAPI
1193 GetCurrentProcessId();
1194
1195 PALIMPORT
1196 DWORD
1197 PALAPI
1198 GetCurrentSessionId();
1199
1200 PALIMPORT
1201 HANDLE
1202 PALAPI
1203 GetCurrentProcess();
1204
1205 PALIMPORT
1206 DWORD
1207 PALAPI
1208 GetCurrentThreadId();
1209
1210 PALIMPORT
1211 size_t
1212 PALAPI
1213 PAL_GetCurrentOSThreadId();
1214
1215 // To work around multiply-defined symbols in the Carbon framework.
1216 #define GetCurrentThread PAL_GetCurrentThread
1217 PALIMPORT
1218 HANDLE
1219 PALAPI
1220 GetCurrentThread();
1221
1222
1223 #define STARTF_USESTDHANDLES       0x00000100
1224
1225 typedef struct _STARTUPINFOW {
1226     DWORD cb;
1227     LPWSTR lpReserved_PAL_Undefined;
1228     LPWSTR lpDesktop_PAL_Undefined;
1229     LPWSTR lpTitle_PAL_Undefined;
1230     DWORD dwX_PAL_Undefined;
1231     DWORD dwY_PAL_Undefined;
1232     DWORD dwXSize_PAL_Undefined;
1233     DWORD dwYSize_PAL_Undefined;
1234     DWORD dwXCountChars_PAL_Undefined;
1235     DWORD dwYCountChars_PAL_Undefined;
1236     DWORD dwFillAttribute_PAL_Undefined;
1237     DWORD dwFlags;
1238     WORD wShowWindow_PAL_Undefined;
1239     WORD cbReserved2_PAL_Undefined;
1240     LPBYTE lpReserved2_PAL_Undefined;
1241     HANDLE hStdInput;
1242     HANDLE hStdOutput;
1243     HANDLE hStdError;
1244 } STARTUPINFOW, *LPSTARTUPINFOW;
1245
1246 typedef STARTUPINFOW STARTUPINFO;
1247 typedef LPSTARTUPINFOW LPSTARTUPINFO;
1248
1249 #define CREATE_NEW_CONSOLE          0x00000010
1250
1251 #define NORMAL_PRIORITY_CLASS             0x00000020
1252
1253 typedef struct _PROCESS_INFORMATION {
1254     HANDLE hProcess;
1255     HANDLE hThread;
1256     DWORD dwProcessId;
1257     DWORD dwThreadId_PAL_Undefined;
1258 } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
1259
1260 PALIMPORT
1261 BOOL
1262 PALAPI
1263 CreateProcessW(
1264            IN LPCWSTR lpApplicationName,
1265            IN LPWSTR lpCommandLine,
1266            IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
1267            IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
1268            IN BOOL bInheritHandles,
1269            IN DWORD dwCreationFlags,
1270            IN LPVOID lpEnvironment,
1271            IN LPCWSTR lpCurrentDirectory,
1272            IN LPSTARTUPINFOW lpStartupInfo,
1273            OUT LPPROCESS_INFORMATION lpProcessInformation);
1274
1275 #define CreateProcess CreateProcessW
1276
1277 PALIMPORT
1278 PAL_NORETURN
1279 VOID
1280 PALAPI
1281 ExitProcess(
1282         IN UINT uExitCode);
1283
1284 PALIMPORT
1285 BOOL
1286 PALAPI
1287 TerminateProcess(
1288          IN HANDLE hProcess,
1289          IN UINT uExitCode);
1290
1291 PALIMPORT
1292 BOOL
1293 PALAPI
1294 GetExitCodeProcess(
1295            IN HANDLE hProcess,
1296            IN LPDWORD lpExitCode);
1297
1298 PALIMPORT
1299 BOOL
1300 PALAPI
1301 GetProcessTimes(
1302         IN HANDLE hProcess,
1303         OUT LPFILETIME lpCreationTime,
1304         OUT LPFILETIME lpExitTime,
1305         OUT LPFILETIME lpKernelTime,
1306         OUT LPFILETIME lpUserTime);
1307
1308 #define MAXIMUM_WAIT_OBJECTS  64
1309 #define WAIT_OBJECT_0 0
1310 #define WAIT_ABANDONED   0x00000080
1311 #define WAIT_ABANDONED_0 0x00000080
1312 #define WAIT_TIMEOUT 258
1313 #define WAIT_FAILED ((DWORD)0xFFFFFFFF)
1314
1315 #define INFINITE 0xFFFFFFFF // Infinite timeout
1316
1317 PALIMPORT
1318 DWORD
1319 PALAPI
1320 WaitForSingleObject(
1321             IN HANDLE hHandle,
1322             IN DWORD dwMilliseconds);
1323
1324 PALIMPORT
1325 DWORD
1326 PALAPI
1327 PAL_WaitForSingleObjectPrioritized(
1328             IN HANDLE hHandle,
1329             IN DWORD dwMilliseconds);
1330
1331 PALIMPORT
1332 DWORD
1333 PALAPI
1334 WaitForSingleObjectEx(
1335             IN HANDLE hHandle,
1336             IN DWORD dwMilliseconds,
1337             IN BOOL bAlertable);
1338
1339 PALIMPORT
1340 DWORD
1341 PALAPI
1342 WaitForMultipleObjects(
1343                IN DWORD nCount,
1344                IN CONST HANDLE *lpHandles,
1345                IN BOOL bWaitAll,
1346                IN DWORD dwMilliseconds);
1347
1348 PALIMPORT
1349 DWORD
1350 PALAPI
1351 WaitForMultipleObjectsEx(
1352              IN DWORD nCount,
1353              IN CONST HANDLE *lpHandles,
1354              IN BOOL bWaitAll,
1355              IN DWORD dwMilliseconds,
1356              IN BOOL bAlertable);
1357
1358 PALIMPORT
1359 DWORD
1360 PALAPI
1361 SignalObjectAndWait(
1362     IN HANDLE hObjectToSignal,
1363     IN HANDLE hObjectToWaitOn,
1364     IN DWORD dwMilliseconds,
1365     IN BOOL bAlertable);
1366
1367 #define DUPLICATE_CLOSE_SOURCE      0x00000001
1368 #define DUPLICATE_SAME_ACCESS       0x00000002
1369
1370 PALIMPORT
1371 BOOL
1372 PALAPI
1373 DuplicateHandle(
1374         IN HANDLE hSourceProcessHandle,
1375         IN HANDLE hSourceHandle,
1376         IN HANDLE hTargetProcessHandle,
1377         OUT LPHANDLE lpTargetHandle,
1378         IN DWORD dwDesiredAccess,
1379         IN BOOL bInheritHandle,
1380         IN DWORD dwOptions);
1381
1382 PALIMPORT
1383 VOID
1384 PALAPI
1385 Sleep(
1386       IN DWORD dwMilliseconds);
1387
1388 PALIMPORT
1389 DWORD
1390 PALAPI
1391 SleepEx(
1392     IN DWORD dwMilliseconds,
1393     IN BOOL bAlertable);
1394
1395 PALIMPORT
1396 BOOL
1397 PALAPI
1398 SwitchToThread();
1399
1400 #define DEBUG_PROCESS                     0x00000001
1401 #define DEBUG_ONLY_THIS_PROCESS           0x00000002
1402 #define CREATE_SUSPENDED                  0x00000004
1403 #define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
1404
1405 PALIMPORT
1406 HANDLE
1407 PALAPI
1408 CreateThread(
1409          IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
1410          IN DWORD dwStackSize,
1411          IN LPTHREAD_START_ROUTINE lpStartAddress,
1412          IN LPVOID lpParameter,
1413          IN DWORD dwCreationFlags,
1414          OUT LPDWORD lpThreadId);
1415
1416 PALIMPORT
1417 HANDLE
1418 PALAPI
1419 PAL_CreateThread64(
1420     IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
1421     IN DWORD dwStackSize,
1422     IN LPTHREAD_START_ROUTINE lpStartAddress,
1423     IN LPVOID lpParameter,
1424     IN DWORD dwCreationFlags,
1425     OUT SIZE_T* pThreadId);
1426
1427 PALIMPORT
1428 PAL_NORETURN
1429 VOID
1430 PALAPI
1431 ExitThread(
1432        IN DWORD dwExitCode);
1433
1434 PALIMPORT
1435 DWORD
1436 PALAPI
1437 ResumeThread(
1438          IN HANDLE hThread);
1439
1440 typedef VOID (PALAPI_NOEXPORT *PAPCFUNC)(ULONG_PTR dwParam);
1441
1442 PALIMPORT
1443 DWORD
1444 PALAPI
1445 QueueUserAPC(
1446          IN PAPCFUNC pfnAPC,
1447          IN HANDLE hThread,
1448          IN ULONG_PTR dwData);
1449
1450 #ifdef HOST_X86
1451
1452 //
1453 // ***********************************************************************************
1454 //
1455 // NOTE: These context definitions are replicated in ndp/clr/src/debug/inc/DbgTargetContext.h (for the
1456 // purposes manipulating contexts from different platforms during remote debugging). Be sure to keep those
1457 // definitions in sync if you make any changes here.
1458 //
1459 // ***********************************************************************************
1460 //
1461
1462 #define SIZE_OF_80387_REGISTERS      80
1463
1464 #define CONTEXT_i386            0x00010000
1465 #define CONTEXT_CONTROL         (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
1466 #define CONTEXT_INTEGER         (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
1467 #define CONTEXT_SEGMENTS        (CONTEXT_i386 | 0x00000004L)
1468 #define CONTEXT_FLOATING_POINT  (CONTEXT_i386 | 0x00000008L) // 387 state
1469 #define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L)
1470
1471 #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)
1472 #define CONTEXT_EXTENDED_REGISTERS  (CONTEXT_i386 | 0x00000020L)
1473 #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS)
1474
1475 #define MAXIMUM_SUPPORTED_EXTENSION     512
1476
1477 #define CONTEXT_XSTATE (CONTEXT_i386 | 0x40L)
1478
1479 #define CONTEXT_EXCEPTION_ACTIVE 0x8000000L
1480 #define CONTEXT_SERVICE_ACTIVE 0x10000000L
1481 #define CONTEXT_EXCEPTION_REQUEST 0x40000000L
1482 #define CONTEXT_EXCEPTION_REPORTING 0x80000000L
1483
1484 //
1485 // This flag is set by the unwinder if it has unwound to a call
1486 // site, and cleared whenever it unwinds through a trap frame.
1487 // It is used by language-specific exception handlers to help
1488 // differentiate exception scopes during dispatching.
1489 //
1490
1491 #define CONTEXT_UNWOUND_TO_CALL 0x20000000
1492
1493 typedef struct _FLOATING_SAVE_AREA {
1494     DWORD   ControlWord;
1495     DWORD   StatusWord;
1496     DWORD   TagWord;
1497     DWORD   ErrorOffset;
1498     DWORD   ErrorSelector;
1499     DWORD   DataOffset;
1500     DWORD   DataSelector;
1501     BYTE    RegisterArea[SIZE_OF_80387_REGISTERS];
1502     DWORD   Cr0NpxState;
1503 } FLOATING_SAVE_AREA;
1504
1505 typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;
1506
1507 typedef struct _CONTEXT {
1508     ULONG ContextFlags;
1509
1510     ULONG   Dr0_PAL_Undefined;
1511     ULONG   Dr1_PAL_Undefined;
1512     ULONG   Dr2_PAL_Undefined;
1513     ULONG   Dr3_PAL_Undefined;
1514     ULONG   Dr6_PAL_Undefined;
1515     ULONG   Dr7_PAL_Undefined;
1516
1517     FLOATING_SAVE_AREA FloatSave;
1518
1519     ULONG   SegGs_PAL_Undefined;
1520     ULONG   SegFs_PAL_Undefined;
1521     ULONG   SegEs_PAL_Undefined;
1522     ULONG   SegDs_PAL_Undefined;
1523
1524     ULONG   Edi;
1525     ULONG   Esi;
1526     ULONG   Ebx;
1527     ULONG   Edx;
1528     ULONG   Ecx;
1529     ULONG   Eax;
1530
1531     ULONG   Ebp;
1532     ULONG   Eip;
1533     ULONG   SegCs;
1534     ULONG   EFlags;
1535     ULONG   Esp;
1536     ULONG   SegSs;
1537
1538     UCHAR   ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
1539 } CONTEXT, *PCONTEXT, *LPCONTEXT;
1540
1541 // To support saving and loading xmm register context we need to know the offset in the ExtendedRegisters
1542 // section at which they are stored. This has been determined experimentally since I have found no
1543 // documentation thus far but it corresponds to the offset we'd expect if a fxsave instruction was used to
1544 // store the regular FP state along with the XMM registers at the start of the extended registers section.
1545 // Technically the offset doesn't really matter if no code in the PAL or runtime knows what the offset should
1546 // be either (as long as we're consistent across GetThreadContext() and SetThreadContext() and we don't
1547 // support any other values in the ExtendedRegisters) but we might as well be as accurate as we can.
1548 #define CONTEXT_EXREG_XMM_OFFSET 160
1549
1550 typedef struct _KNONVOLATILE_CONTEXT {
1551
1552     DWORD Edi;
1553     DWORD Esi;
1554     DWORD Ebx;
1555     DWORD Ebp;
1556
1557 } KNONVOLATILE_CONTEXT, *PKNONVOLATILE_CONTEXT;
1558
1559 typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
1560
1561     // The ordering of these fields should be aligned with that
1562     // of corresponding fields in CONTEXT
1563     //
1564     // (See FillRegDisplay in inc/regdisp.h for details)
1565     PDWORD Edi;
1566     PDWORD Esi;
1567     PDWORD Ebx;
1568     PDWORD Edx;
1569     PDWORD Ecx;
1570     PDWORD Eax;
1571
1572     PDWORD Ebp;
1573
1574 } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
1575
1576 #elif defined(HOST_AMD64)
1577 // copied from winnt.h
1578
1579 #define CONTEXT_AMD64   0x100000
1580
1581 #define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x1L)
1582 #define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x2L)
1583 #define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x4L)
1584 #define CONTEXT_FLOATING_POINT  (CONTEXT_AMD64 | 0x8L)
1585 #define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L)
1586
1587 #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
1588
1589 #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
1590
1591 #define CONTEXT_XSTATE (CONTEXT_AMD64 | 0x40L)
1592
1593 #define CONTEXT_EXCEPTION_ACTIVE 0x8000000
1594 #define CONTEXT_SERVICE_ACTIVE 0x10000000
1595 #define CONTEXT_EXCEPTION_REQUEST 0x40000000
1596 #define CONTEXT_EXCEPTION_REPORTING 0x80000000
1597
1598 typedef struct DECLSPEC_ALIGN(16) _M128A {
1599     ULONGLONG Low;
1600     LONGLONG High;
1601 } M128A, *PM128A;
1602
1603 typedef struct _XMM_SAVE_AREA32 {
1604     WORD   ControlWord;
1605     WORD   StatusWord;
1606     BYTE  TagWord;
1607     BYTE  Reserved1;
1608     WORD   ErrorOpcode;
1609     DWORD ErrorOffset;
1610     WORD   ErrorSelector;
1611     WORD   Reserved2;
1612     DWORD DataOffset;
1613     WORD   DataSelector;
1614     WORD   Reserved3;
1615     DWORD MxCsr;
1616     DWORD MxCsr_Mask;
1617     M128A FloatRegisters[8];
1618     M128A XmmRegisters[16];
1619     BYTE  Reserved4[96];
1620 } XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
1621
1622 #define LEGACY_SAVE_AREA_LENGTH sizeof(XMM_SAVE_AREA32)
1623
1624 //
1625 // Context Frame
1626 //
1627 //  This frame has a several purposes: 1) it is used as an argument to
1628 //  NtContinue, 2) is is used to constuct a call frame for APC delivery,
1629 //  and 3) it is used in the user level thread creation routines.
1630 //
1631 //
1632 // The flags field within this record controls the contents of a CONTEXT
1633 // record.
1634 //
1635 // If the context record is used as an input parameter, then for each
1636 // portion of the context record controlled by a flag whose value is
1637 // set, it is assumed that that portion of the context record contains
1638 // valid context. If the context record is being used to modify a threads
1639 // context, then only that portion of the threads context is modified.
1640 //
1641 // If the context record is used as an output parameter to capture the
1642 // context of a thread, then only those portions of the thread's context
1643 // corresponding to set flags will be returned.
1644 //
1645 // CONTEXT_CONTROL specifies SegSs, Rsp, SegCs, Rip, and EFlags.
1646 //
1647 // CONTEXT_INTEGER specifies Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, and R8-R15.
1648 //
1649 // CONTEXT_SEGMENTS specifies SegDs, SegEs, SegFs, and SegGs.
1650 //
1651 // CONTEXT_DEBUG_REGISTERS specifies Dr0-Dr3 and Dr6-Dr7.
1652 //
1653 // CONTEXT_MMX_REGISTERS specifies the floating point and extended registers
1654 //     Mm0/St0-Mm7/St7 and Xmm0-Xmm15).
1655 //
1656
1657 typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
1658
1659     //
1660     // Register parameter home addresses.
1661     //
1662     // N.B. These fields are for convience - they could be used to extend the
1663     //      context record in the future.
1664     //
1665
1666     DWORD64 P1Home;
1667     DWORD64 P2Home;
1668     DWORD64 P3Home;
1669     DWORD64 P4Home;
1670     DWORD64 P5Home;
1671     DWORD64 P6Home;
1672
1673     //
1674     // Control flags.
1675     //
1676
1677     DWORD ContextFlags;
1678     DWORD MxCsr;
1679
1680     //
1681     // Segment Registers and processor flags.
1682     //
1683
1684     WORD   SegCs;
1685     WORD   SegDs;
1686     WORD   SegEs;
1687     WORD   SegFs;
1688     WORD   SegGs;
1689     WORD   SegSs;
1690     DWORD EFlags;
1691
1692     //
1693     // Debug registers
1694     //
1695
1696     DWORD64 Dr0;
1697     DWORD64 Dr1;
1698     DWORD64 Dr2;
1699     DWORD64 Dr3;
1700     DWORD64 Dr6;
1701     DWORD64 Dr7;
1702
1703     //
1704     // Integer registers.
1705     //
1706
1707     DWORD64 Rax;
1708     DWORD64 Rcx;
1709     DWORD64 Rdx;
1710     DWORD64 Rbx;
1711     DWORD64 Rsp;
1712     DWORD64 Rbp;
1713     DWORD64 Rsi;
1714     DWORD64 Rdi;
1715     DWORD64 R8;
1716     DWORD64 R9;
1717     DWORD64 R10;
1718     DWORD64 R11;
1719     DWORD64 R12;
1720     DWORD64 R13;
1721     DWORD64 R14;
1722     DWORD64 R15;
1723
1724     //
1725     // Program counter.
1726     //
1727
1728     DWORD64 Rip;
1729
1730     //
1731     // Floating point state.
1732     //
1733
1734     union {
1735         XMM_SAVE_AREA32 FltSave;
1736         struct {
1737             M128A Header[2];
1738             M128A Legacy[8];
1739             M128A Xmm0;
1740             M128A Xmm1;
1741             M128A Xmm2;
1742             M128A Xmm3;
1743             M128A Xmm4;
1744             M128A Xmm5;
1745             M128A Xmm6;
1746             M128A Xmm7;
1747             M128A Xmm8;
1748             M128A Xmm9;
1749             M128A Xmm10;
1750             M128A Xmm11;
1751             M128A Xmm12;
1752             M128A Xmm13;
1753             M128A Xmm14;
1754             M128A Xmm15;
1755         };
1756     };
1757
1758     //
1759     // Vector registers.
1760     //
1761
1762     M128A VectorRegister[26];
1763     DWORD64 VectorControl;
1764
1765     //
1766     // Special debug control registers.
1767     //
1768
1769     DWORD64 DebugControl;
1770     DWORD64 LastBranchToRip;
1771     DWORD64 LastBranchFromRip;
1772     DWORD64 LastExceptionToRip;
1773     DWORD64 LastExceptionFromRip;
1774 } CONTEXT, *PCONTEXT, *LPCONTEXT;
1775
1776 //
1777 // Nonvolatile context pointer record.
1778 //
1779
1780 typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
1781     union {
1782         PM128A FloatingContext[16];
1783         struct {
1784             PM128A Xmm0;
1785             PM128A Xmm1;
1786             PM128A Xmm2;
1787             PM128A Xmm3;
1788             PM128A Xmm4;
1789             PM128A Xmm5;
1790             PM128A Xmm6;
1791             PM128A Xmm7;
1792             PM128A Xmm8;
1793             PM128A Xmm9;
1794             PM128A Xmm10;
1795             PM128A Xmm11;
1796             PM128A Xmm12;
1797             PM128A Xmm13;
1798             PM128A Xmm14;
1799             PM128A Xmm15;
1800         } ;
1801     } ;
1802
1803     union {
1804         PDWORD64 IntegerContext[16];
1805         struct {
1806             PDWORD64 Rax;
1807             PDWORD64 Rcx;
1808             PDWORD64 Rdx;
1809             PDWORD64 Rbx;
1810             PDWORD64 Rsp;
1811             PDWORD64 Rbp;
1812             PDWORD64 Rsi;
1813             PDWORD64 Rdi;
1814             PDWORD64 R8;
1815             PDWORD64 R9;
1816             PDWORD64 R10;
1817             PDWORD64 R11;
1818             PDWORD64 R12;
1819             PDWORD64 R13;
1820             PDWORD64 R14;
1821             PDWORD64 R15;
1822         } ;
1823     } ;
1824
1825 } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
1826
1827 #elif defined(HOST_ARM)
1828
1829 #define CONTEXT_ARM   0x00200000L
1830
1831 // end_wx86
1832
1833 #define CONTEXT_CONTROL (CONTEXT_ARM | 0x1L)
1834 #define CONTEXT_INTEGER (CONTEXT_ARM | 0x2L)
1835 #define CONTEXT_FLOATING_POINT  (CONTEXT_ARM | 0x4L)
1836 #define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM | 0x8L)
1837
1838 #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
1839
1840 #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
1841
1842 #define CONTEXT_EXCEPTION_ACTIVE 0x8000000L
1843 #define CONTEXT_SERVICE_ACTIVE 0x10000000L
1844 #define CONTEXT_EXCEPTION_REQUEST 0x40000000L
1845 #define CONTEXT_EXCEPTION_REPORTING 0x80000000L
1846
1847 //
1848 // This flag is set by the unwinder if it has unwound to a call
1849 // site, and cleared whenever it unwinds through a trap frame.
1850 // It is used by language-specific exception handlers to help
1851 // differentiate exception scopes during dispatching.
1852 //
1853
1854 #define CONTEXT_UNWOUND_TO_CALL 0x20000000
1855
1856 //
1857 // Specify the number of breakpoints and watchpoints that the OS
1858 // will track. Architecturally, ARM supports up to 16. In practice,
1859 // however, almost no one implements more than 4 of each.
1860 //
1861
1862 #define ARM_MAX_BREAKPOINTS     8
1863 #define ARM_MAX_WATCHPOINTS     1
1864
1865 typedef struct _NEON128 {
1866     ULONGLONG Low;
1867     LONGLONG High;
1868 } NEON128, *PNEON128;
1869
1870 //
1871 // Context Frame
1872 //
1873 //  This frame has a several purposes: 1) it is used as an argument to
1874 //  NtContinue, 2) it is used to constuct a call frame for APC delivery,
1875 //  and 3) it is used in the user level thread creation routines.
1876 //
1877 //
1878 // The flags field within this record controls the contents of a CONTEXT
1879 // record.
1880 //
1881 // If the context record is used as an input parameter, then for each
1882 // portion of the context record controlled by a flag whose value is
1883 // set, it is assumed that that portion of the context record contains
1884 // valid context. If the context record is being used to modify a threads
1885 // context, then only that portion of the threads context is modified.
1886 //
1887 // If the context record is used as an output parameter to capture the
1888 // context of a thread, then only those portions of the thread's context
1889 // corresponding to set flags will be returned.
1890 //
1891 // CONTEXT_CONTROL specifies Sp, Lr, Pc, and Cpsr
1892 //
1893 // CONTEXT_INTEGER specifies R0-R12
1894 //
1895 // CONTEXT_FLOATING_POINT specifies Q0-Q15 / D0-D31 / S0-S31
1896 //
1897 // CONTEXT_DEBUG_REGISTERS specifies up to 16 of DBGBVR, DBGBCR, DBGWVR,
1898 //      DBGWCR.
1899 //
1900
1901 typedef struct DECLSPEC_ALIGN(8) _CONTEXT {
1902
1903     //
1904     // Control flags.
1905     //
1906
1907     DWORD ContextFlags;
1908
1909     //
1910     // Integer registers
1911     //
1912
1913     DWORD R0;
1914     DWORD R1;
1915     DWORD R2;
1916     DWORD R3;
1917     DWORD R4;
1918     DWORD R5;
1919     DWORD R6;
1920     DWORD R7;
1921     DWORD R8;
1922     DWORD R9;
1923     DWORD R10;
1924     DWORD R11;
1925     DWORD R12;
1926
1927     //
1928     // Control Registers
1929     //
1930
1931     DWORD Sp;
1932     DWORD Lr;
1933     DWORD Pc;
1934     DWORD Cpsr;
1935
1936     //
1937     // Floating Point/NEON Registers
1938     //
1939
1940     DWORD Fpscr;
1941     DWORD Padding;
1942     union {
1943         NEON128 Q[16];
1944         ULONGLONG D[32];
1945         DWORD S[32];
1946     };
1947
1948     //
1949     // Debug registers
1950     //
1951
1952     DWORD Bvr[ARM_MAX_BREAKPOINTS];
1953     DWORD Bcr[ARM_MAX_BREAKPOINTS];
1954     DWORD Wvr[ARM_MAX_WATCHPOINTS];
1955     DWORD Wcr[ARM_MAX_WATCHPOINTS];
1956
1957     DWORD Padding2[2];
1958
1959 } CONTEXT, *PCONTEXT, *LPCONTEXT;
1960
1961 //
1962 // Nonvolatile context pointer record.
1963 //
1964
1965 typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
1966
1967     PDWORD R4;
1968     PDWORD R5;
1969     PDWORD R6;
1970     PDWORD R7;
1971     PDWORD R8;
1972     PDWORD R9;
1973     PDWORD R10;
1974     PDWORD R11;
1975     PDWORD Lr;
1976
1977     PULONGLONG D8;
1978     PULONGLONG D9;
1979     PULONGLONG D10;
1980     PULONGLONG D11;
1981     PULONGLONG D12;
1982     PULONGLONG D13;
1983     PULONGLONG D14;
1984     PULONGLONG D15;
1985
1986 } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
1987
1988 typedef struct _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY {
1989     DWORD BeginAddress;
1990     DWORD EndAddress;
1991     union {
1992         DWORD UnwindData;
1993         struct {
1994             DWORD Flag : 2;
1995             DWORD FunctionLength : 11;
1996             DWORD Ret : 2;
1997             DWORD H : 1;
1998             DWORD Reg : 3;
1999             DWORD R : 1;
2000             DWORD L : 1;
2001             DWORD C : 1;
2002             DWORD StackAdjust : 10;
2003         };
2004     };
2005 } IMAGE_ARM_RUNTIME_FUNCTION_ENTRY, * PIMAGE_ARM_RUNTIME_FUNCTION_ENTRY;
2006
2007 #elif defined(HOST_ARM64)
2008
2009 #define CONTEXT_ARM64   0x00400000L
2010
2011 #define CONTEXT_CONTROL (CONTEXT_ARM64 | 0x1L)
2012 #define CONTEXT_INTEGER (CONTEXT_ARM64 | 0x2L)
2013 #define CONTEXT_FLOATING_POINT  (CONTEXT_ARM64 | 0x4L)
2014 #define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM64 | 0x8L)
2015
2016 #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
2017
2018 #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
2019
2020 #define CONTEXT_EXCEPTION_ACTIVE 0x8000000L
2021 #define CONTEXT_SERVICE_ACTIVE 0x10000000L
2022 #define CONTEXT_EXCEPTION_REQUEST 0x40000000L
2023 #define CONTEXT_EXCEPTION_REPORTING 0x80000000L
2024
2025 //
2026 // This flag is set by the unwinder if it has unwound to a call
2027 // site, and cleared whenever it unwinds through a trap frame.
2028 // It is used by language-specific exception handlers to help
2029 // differentiate exception scopes during dispatching.
2030 //
2031
2032 #define CONTEXT_UNWOUND_TO_CALL 0x20000000
2033
2034 //
2035 // Define initial Cpsr/Fpscr value
2036 //
2037
2038 #define INITIAL_CPSR 0x10
2039 #define INITIAL_FPSCR 0
2040
2041 // begin_ntoshvp
2042
2043 //
2044 // Specify the number of breakpoints and watchpoints that the OS
2045 // will track. Architecturally, ARM64 supports up to 16. In practice,
2046 // however, almost no one implements more than 4 of each.
2047 //
2048
2049 #define ARM64_MAX_BREAKPOINTS     8
2050 #define ARM64_MAX_WATCHPOINTS     2
2051
2052 //
2053 // Context Frame
2054 //
2055 //  This frame has a several purposes: 1) it is used as an argument to
2056 //  NtContinue, 2) it is used to constuct a call frame for APC delivery,
2057 //  and 3) it is used in the user level thread creation routines.
2058 //
2059 //
2060 // The flags field within this record controls the contents of a CONTEXT
2061 // record.
2062 //
2063 // If the context record is used as an input parameter, then for each
2064 // portion of the context record controlled by a flag whose value is
2065 // set, it is assumed that that portion of the context record contains
2066 // valid context. If the context record is being used to modify a threads
2067 // context, then only that portion of the threads context is modified.
2068 //
2069 // If the context record is used as an output parameter to capture the
2070 // context of a thread, then only those portions of the thread's context
2071 // corresponding to set flags will be returned.
2072 //
2073 // CONTEXT_CONTROL specifies Sp, Lr, Pc, and Cpsr
2074 //
2075 // CONTEXT_INTEGER specifies R0-R12
2076 //
2077 // CONTEXT_FLOATING_POINT specifies Q0-Q15 / D0-D31 / S0-S31
2078 //
2079 // CONTEXT_DEBUG_REGISTERS specifies up to 16 of DBGBVR, DBGBCR, DBGWVR,
2080 //      DBGWCR.
2081 //
2082
2083 typedef struct _NEON128 {
2084     ULONGLONG Low;
2085     LONGLONG High;
2086 } NEON128, *PNEON128;
2087
2088 typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
2089
2090     //
2091     // Control flags.
2092     //
2093
2094     /* +0x000 */ DWORD ContextFlags;
2095
2096     //
2097     // Integer registers
2098     //
2099
2100     /* +0x004 */ DWORD Cpsr;       // NZVF + DAIF + CurrentEL + SPSel
2101     /* +0x008 */ union {
2102                     struct {
2103                         DWORD64 X0;
2104                         DWORD64 X1;
2105                         DWORD64 X2;
2106                         DWORD64 X3;
2107                         DWORD64 X4;
2108                         DWORD64 X5;
2109                         DWORD64 X6;
2110                         DWORD64 X7;
2111                         DWORD64 X8;
2112                         DWORD64 X9;
2113                         DWORD64 X10;
2114                         DWORD64 X11;
2115                         DWORD64 X12;
2116                         DWORD64 X13;
2117                         DWORD64 X14;
2118                         DWORD64 X15;
2119                         DWORD64 X16;
2120                         DWORD64 X17;
2121                         DWORD64 X18;
2122                         DWORD64 X19;
2123                         DWORD64 X20;
2124                         DWORD64 X21;
2125                         DWORD64 X22;
2126                         DWORD64 X23;
2127                         DWORD64 X24;
2128                         DWORD64 X25;
2129                         DWORD64 X26;
2130                         DWORD64 X27;
2131                         DWORD64 X28;
2132                     };
2133                     DWORD64 X[29];
2134                 };
2135     /* +0x0f0 */ DWORD64 Fp;
2136     /* +0x0f8 */ DWORD64 Lr;
2137     /* +0x100 */ DWORD64 Sp;
2138     /* +0x108 */ DWORD64 Pc;
2139
2140     //
2141     // Floating Point/NEON Registers
2142     //
2143
2144     /* +0x110 */ NEON128 V[32];
2145     /* +0x310 */ DWORD Fpcr;
2146     /* +0x314 */ DWORD Fpsr;
2147
2148     //
2149     // Debug registers
2150     //
2151
2152     /* +0x318 */ DWORD Bcr[ARM64_MAX_BREAKPOINTS];
2153     /* +0x338 */ DWORD64 Bvr[ARM64_MAX_BREAKPOINTS];
2154     /* +0x378 */ DWORD Wcr[ARM64_MAX_WATCHPOINTS];
2155     /* +0x380 */ DWORD64 Wvr[ARM64_MAX_WATCHPOINTS];
2156     /* +0x390 */
2157
2158 } CONTEXT, *PCONTEXT, *LPCONTEXT;
2159
2160 //
2161 // Nonvolatile context pointer record.
2162 //
2163
2164 typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
2165
2166     PDWORD64 X19;
2167     PDWORD64 X20;
2168     PDWORD64 X21;
2169     PDWORD64 X22;
2170     PDWORD64 X23;
2171     PDWORD64 X24;
2172     PDWORD64 X25;
2173     PDWORD64 X26;
2174     PDWORD64 X27;
2175     PDWORD64 X28;
2176     PDWORD64 Fp;
2177     PDWORD64 Lr;
2178
2179     PDWORD64 D8;
2180     PDWORD64 D9;
2181     PDWORD64 D10;
2182     PDWORD64 D11;
2183     PDWORD64 D12;
2184     PDWORD64 D13;
2185     PDWORD64 D14;
2186     PDWORD64 D15;
2187
2188 } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
2189
2190 #else
2191 #error Unknown architecture for defining CONTEXT.
2192 #endif
2193
2194
2195 PALIMPORT
2196 BOOL
2197 PALAPI
2198 GetThreadContext(
2199          IN HANDLE hThread,
2200          IN OUT LPCONTEXT lpContext);
2201
2202 PALIMPORT
2203 BOOL
2204 PALAPI
2205 SetThreadContext(
2206          IN HANDLE hThread,
2207          IN CONST CONTEXT *lpContext);
2208
2209 #define THREAD_BASE_PRIORITY_LOWRT    15
2210 #define THREAD_BASE_PRIORITY_MAX      2
2211 #define THREAD_BASE_PRIORITY_MIN      (-2)
2212 #define THREAD_BASE_PRIORITY_IDLE     (-15)
2213
2214 #define THREAD_PRIORITY_LOWEST        THREAD_BASE_PRIORITY_MIN
2215 #define THREAD_PRIORITY_BELOW_NORMAL  (THREAD_PRIORITY_LOWEST+1)
2216 #define THREAD_PRIORITY_NORMAL        0
2217 #define THREAD_PRIORITY_HIGHEST       THREAD_BASE_PRIORITY_MAX
2218 #define THREAD_PRIORITY_ABOVE_NORMAL  (THREAD_PRIORITY_HIGHEST-1)
2219 #define THREAD_PRIORITY_ERROR_RETURN  (MAXLONG)
2220
2221 #define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT
2222 #define THREAD_PRIORITY_IDLE          THREAD_BASE_PRIORITY_IDLE
2223
2224 PALIMPORT
2225 int
2226 PALAPI
2227 GetThreadPriority(
2228           IN HANDLE hThread);
2229
2230 PALIMPORT
2231 BOOL
2232 PALAPI
2233 SetThreadPriority(
2234           IN HANDLE hThread,
2235           IN int nPriority);
2236
2237 PALIMPORT
2238 BOOL
2239 PALAPI
2240 GetThreadTimes(
2241         IN HANDLE hThread,
2242         OUT LPFILETIME lpCreationTime,
2243         OUT LPFILETIME lpExitTime,
2244         OUT LPFILETIME lpKernelTime,
2245         OUT LPFILETIME lpUserTime);
2246
2247 PALIMPORT
2248 HRESULT
2249 PALAPI
2250 SetThreadDescription(
2251     IN HANDLE hThread,
2252     IN PCWSTR lpThreadDescription
2253 );
2254
2255 #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
2256
2257 PALIMPORT
2258 PVOID
2259 PALAPI
2260 PAL_GetStackBase();
2261
2262 PALIMPORT
2263 PVOID
2264 PALAPI
2265 PAL_GetStackLimit();
2266
2267 PALIMPORT
2268 DWORD
2269 PALAPI
2270 PAL_GetLogicalCpuCountFromOS();
2271
2272 PALIMPORT
2273 DWORD
2274 PALAPI
2275 PAL_GetTotalCpuCount();
2276
2277 PALIMPORT
2278 size_t
2279 PALAPI
2280 PAL_GetRestrictedPhysicalMemoryLimit();
2281
2282 PALIMPORT
2283 BOOL
2284 PALAPI
2285 PAL_GetPhysicalMemoryUsed(size_t* val);
2286
2287 PALIMPORT
2288 BOOL
2289 PALAPI
2290 PAL_GetCpuLimit(UINT* val);
2291
2292 PALIMPORT
2293 size_t
2294 PALAPI
2295 PAL_GetLogicalProcessorCacheSizeFromOS();
2296
2297 typedef BOOL(*UnwindReadMemoryCallback)(PVOID address, PVOID buffer, SIZE_T size);
2298
2299 PALIMPORT BOOL PALAPI PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers);
2300
2301 PALIMPORT BOOL PALAPI PAL_VirtualUnwindOutOfProc(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers, SIZE_T baseAddress, UnwindReadMemoryCallback readMemoryCallback);
2302
2303 #define GetLogicalProcessorCacheSizeFromOS PAL_GetLogicalProcessorCacheSizeFromOS
2304
2305 /* PAL_CS_NATIVE_DATA_SIZE is defined as sizeof(PAL_CRITICAL_SECTION_NATIVE_DATA) */
2306
2307 #if defined(__APPLE__) && defined(__i386__)
2308 #define PAL_CS_NATIVE_DATA_SIZE 76
2309 #elif defined(__APPLE__) && defined(__x86_64__)
2310 #define PAL_CS_NATIVE_DATA_SIZE 120
2311 #elif defined(__APPLE__) && defined(HOST_ARM64)
2312 #define PAL_CS_NATIVE_DATA_SIZE 120
2313 #elif defined(__FreeBSD__) && defined(HOST_X86)
2314 #define PAL_CS_NATIVE_DATA_SIZE 12
2315 #elif defined(__FreeBSD__) && defined(__x86_64__)
2316 #define PAL_CS_NATIVE_DATA_SIZE 24
2317 #elif defined(__linux__) && defined(HOST_ARM)
2318 #define PAL_CS_NATIVE_DATA_SIZE 80
2319 #elif defined(__linux__) && defined(HOST_ARM64)
2320 #define PAL_CS_NATIVE_DATA_SIZE 116
2321 #elif defined(__linux__) && defined(__i386__)
2322 #define PAL_CS_NATIVE_DATA_SIZE 76
2323 #elif defined(__linux__) && defined(__x86_64__)
2324 #define PAL_CS_NATIVE_DATA_SIZE 96
2325 #elif defined(__NetBSD__) && defined(__amd64__)
2326 #define PAL_CS_NATIVE_DATA_SIZE 96
2327 #elif defined(__NetBSD__) && defined(__earm__)
2328 #define PAL_CS_NATIVE_DATA_SIZE 56
2329 #elif defined(__NetBSD__) && defined(__i386__)
2330 #define PAL_CS_NATIVE_DATA_SIZE 56
2331 #elif defined(__sun) && defined(__x86_64__)
2332 #define PAL_CS_NATIVE_DATA_SIZE 48
2333 #else
2334 #warning
2335 #error  PAL_CS_NATIVE_DATA_SIZE is not defined for this architecture
2336 #endif
2337
2338 //
2339 typedef struct _CRITICAL_SECTION {
2340     PVOID DebugInfo;
2341     LONG LockCount;
2342     LONG RecursionCount;
2343     HANDLE OwningThread;
2344     ULONG_PTR SpinCount;
2345
2346 #ifdef PAL_TRACK_CRITICAL_SECTIONS_DATA
2347     BOOL bInternal;
2348 #endif // PAL_TRACK_CRITICAL_SECTIONS_DATA
2349     volatile DWORD dwInitState;
2350
2351     union CSNativeDataStorage
2352     {
2353         BYTE rgNativeDataStorage[PAL_CS_NATIVE_DATA_SIZE];
2354         PVOID pvAlign; // make sure the storage is machine-pointer-size aligned
2355     } csnds;
2356 } CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
2357
2358 PALIMPORT VOID PALAPI EnterCriticalSection(IN OUT LPCRITICAL_SECTION lpCriticalSection);
2359 PALIMPORT VOID PALAPI LeaveCriticalSection(IN OUT LPCRITICAL_SECTION lpCriticalSection);
2360 PALIMPORT VOID PALAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection);
2361 PALIMPORT BOOL PALAPI InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags);
2362 PALIMPORT VOID PALAPI DeleteCriticalSection(IN OUT LPCRITICAL_SECTION lpCriticalSection);
2363 PALIMPORT BOOL PALAPI TryEnterCriticalSection(IN OUT LPCRITICAL_SECTION lpCriticalSection);
2364
2365 #define SEM_FAILCRITICALERRORS          0x0001
2366 #define SEM_NOOPENFILEERRORBOX          0x8000
2367
2368 PALIMPORT
2369 UINT
2370 PALAPI
2371 SetErrorMode(
2372          IN UINT uMode);
2373
2374 #define PAGE_NOACCESS                   0x01
2375 #define PAGE_READONLY                   0x02
2376 #define PAGE_READWRITE                  0x04
2377 #define PAGE_WRITECOPY                  0x08
2378 #define PAGE_EXECUTE                    0x10
2379 #define PAGE_EXECUTE_READ               0x20
2380 #define PAGE_EXECUTE_READWRITE          0x40
2381 #define PAGE_EXECUTE_WRITECOPY          0x80
2382 #define MEM_COMMIT                      0x1000
2383 #define MEM_RESERVE                     0x2000
2384 #define MEM_DECOMMIT                    0x4000
2385 #define MEM_RELEASE                     0x8000
2386 #define MEM_RESET                       0x80000
2387 #define MEM_FREE                        0x10000
2388 #define MEM_PRIVATE                     0x20000
2389 #define MEM_MAPPED                      0x40000
2390 #define MEM_TOP_DOWN                    0x100000
2391 #define MEM_WRITE_WATCH                 0x200000
2392 #define MEM_LARGE_PAGES                 0x20000000
2393 #define MEM_RESERVE_EXECUTABLE          0x40000000 // reserve memory using executable memory allocator
2394
2395 PALIMPORT
2396 HANDLE
2397 PALAPI
2398 CreateFileMappingW(
2399            IN HANDLE hFile,
2400            IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
2401            IN DWORD flProtect,
2402            IN DWORD dwMaxmimumSizeHigh,
2403            IN DWORD dwMaximumSizeLow,
2404            IN LPCWSTR lpName);
2405
2406 #define CreateFileMapping CreateFileMappingW
2407
2408 #define SECTION_QUERY       0x0001
2409 #define SECTION_MAP_WRITE   0x0002
2410 #define SECTION_MAP_READ    0x0004
2411 #define SECTION_ALL_ACCESS  (SECTION_MAP_READ | SECTION_MAP_WRITE) // diff from winnt.h
2412
2413 #define FILE_MAP_WRITE      SECTION_MAP_WRITE
2414 #define FILE_MAP_READ       SECTION_MAP_READ
2415 #define FILE_MAP_ALL_ACCESS SECTION_ALL_ACCESS
2416 #define FILE_MAP_COPY       SECTION_QUERY
2417
2418 PALIMPORT
2419 HANDLE
2420 PALAPI
2421 OpenFileMappingW(
2422          IN DWORD dwDesiredAccess,
2423          IN BOOL bInheritHandle,
2424          IN LPCWSTR lpName);
2425
2426 #define OpenFileMapping OpenFileMappingW
2427
2428 typedef INT_PTR (PALAPI_NOEXPORT *FARPROC)();
2429
2430 PALIMPORT
2431 LPVOID
2432 PALAPI
2433 MapViewOfFile(
2434           IN HANDLE hFileMappingObject,
2435           IN DWORD dwDesiredAccess,
2436           IN DWORD dwFileOffsetHigh,
2437           IN DWORD dwFileOffsetLow,
2438           IN SIZE_T dwNumberOfBytesToMap);
2439
2440 PALIMPORT
2441 LPVOID
2442 PALAPI
2443 MapViewOfFileEx(
2444           IN HANDLE hFileMappingObject,
2445           IN DWORD dwDesiredAccess,
2446           IN DWORD dwFileOffsetHigh,
2447           IN DWORD dwFileOffsetLow,
2448           IN SIZE_T dwNumberOfBytesToMap,
2449           IN LPVOID lpBaseAddress);
2450
2451 PALIMPORT
2452 BOOL
2453 PALAPI
2454 UnmapViewOfFile(
2455         IN LPCVOID lpBaseAddress);
2456
2457
2458 PALIMPORT
2459 HMODULE
2460 PALAPI
2461 LoadLibraryW(
2462         IN LPCWSTR lpLibFileName);
2463
2464 PALIMPORT
2465 HMODULE
2466 PALAPI
2467 LoadLibraryExW(
2468         IN LPCWSTR lpLibFileName,
2469         IN /*Reserved*/ HANDLE hFile,
2470         IN DWORD dwFlags);
2471
2472 PALIMPORT
2473 NATIVE_LIBRARY_HANDLE
2474 PALAPI
2475 PAL_LoadLibraryDirect(
2476         IN LPCWSTR lpLibFileName);
2477
2478 PALIMPORT
2479 BOOL
2480 PALAPI
2481 PAL_FreeLibraryDirect(
2482         IN NATIVE_LIBRARY_HANDLE dl_handle);
2483
2484 PALIMPORT
2485 HMODULE
2486 PALAPI
2487 PAL_GetPalHostModule();
2488
2489 PALIMPORT
2490 FARPROC
2491 PALAPI
2492 PAL_GetProcAddressDirect(
2493         IN NATIVE_LIBRARY_HANDLE dl_handle,
2494         IN LPCSTR lpProcName);
2495
2496 /*++
2497 Function:
2498   PAL_LOADLoadPEFile
2499
2500 Abstract
2501   Loads a PE file into memory.  Properly maps all of the sections in the PE file.  Returns a pointer to the
2502   loaded base.
2503
2504 Parameters:
2505     IN hFile    - The file to load
2506     IN offset - offset within hFile where the PE "file" is located
2507
2508 Return value:
2509     A valid base address if successful.
2510     0 if failure
2511 --*/
2512 PALIMPORT
2513 PVOID
2514 PALAPI
2515 PAL_LOADLoadPEFile(HANDLE hFile, size_t offset);
2516
2517 /*++
2518     PAL_LOADUnloadPEFile
2519
2520     Unload a PE file that was loaded by PAL_LOADLoadPEFile().
2521
2522 Parameters:
2523     IN ptr - the file pointer returned by PAL_LOADLoadPEFile()
2524
2525 Return value:
2526     TRUE - success
2527     FALSE - failure (incorrect ptr, etc.)
2528 --*/
2529 PALIMPORT
2530 BOOL
2531 PALAPI
2532 PAL_LOADUnloadPEFile(PVOID ptr);
2533
2534 /*++
2535     PAL_LOADMarkSectionAsNotNeeded
2536
2537     Mark a section as NotNeeded that was loaded by PAL_LOADLoadPEFile().
2538
2539 Parameters:
2540     IN ptr - the section address mapped by PAL_LOADLoadPEFile()
2541
2542 Return value:
2543     TRUE - success
2544     FALSE - failure (incorrect ptr, etc.)
2545 --*/
2546 BOOL
2547 PALAPI
2548 PAL_LOADMarkSectionAsNotNeeded(void * ptr);
2549
2550 #ifdef UNICODE
2551 #define LoadLibrary LoadLibraryW
2552 #define LoadLibraryEx LoadLibraryExW
2553 #else
2554 #define LoadLibrary LoadLibraryA
2555 #define LoadLibraryEx LoadLibraryExA
2556 #endif
2557
2558 PALIMPORT
2559 FARPROC
2560 PALAPI
2561 GetProcAddress(
2562     IN HMODULE hModule,
2563     IN LPCSTR lpProcName);
2564
2565 PALIMPORT
2566 BOOL
2567 PALAPI
2568 FreeLibrary(
2569     IN OUT HMODULE hLibModule);
2570
2571 PALIMPORT
2572 PAL_NORETURN
2573 VOID
2574 PALAPI
2575 FreeLibraryAndExitThread(
2576     IN HMODULE hLibModule,
2577     IN DWORD dwExitCode);
2578
2579 PALIMPORT
2580 BOOL
2581 PALAPI
2582 DisableThreadLibraryCalls(
2583     IN HMODULE hLibModule);
2584
2585 PALIMPORT
2586 DWORD
2587 PALAPI
2588 GetModuleFileNameW(
2589     IN HMODULE hModule,
2590     OUT LPWSTR lpFileName,
2591     IN DWORD nSize);
2592
2593 #ifdef UNICODE
2594 #define GetModuleFileName GetModuleFileNameW
2595 #else
2596 #define GetModuleFileName GetModuleFileNameA
2597 #endif
2598
2599 PALIMPORT
2600 DWORD
2601 PALAPI
2602 GetModuleFileNameExW(
2603     IN HANDLE hProcess,
2604     IN HMODULE hModule,
2605     OUT LPWSTR lpFilename,
2606     IN DWORD nSize
2607     );
2608
2609 #ifdef UNICODE
2610 #define GetModuleFileNameEx GetModuleFileNameExW
2611 #endif
2612
2613 // Get base address of the module containing a given symbol
2614 PALIMPORT
2615 LPCVOID
2616 PALAPI
2617 PAL_GetSymbolModuleBase(PVOID symbol);
2618
2619 PALIMPORT
2620 LPCSTR
2621 PALAPI
2622 PAL_GetLoadLibraryError();
2623
2624 PALIMPORT
2625 LPVOID
2626 PALAPI
2627 PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange(
2628     IN LPCVOID lpBeginAddress,
2629     IN LPCVOID lpEndAddress,
2630     IN SIZE_T dwSize);
2631
2632 PALIMPORT
2633 LPVOID
2634 PALAPI
2635 VirtualAlloc(
2636          IN LPVOID lpAddress,
2637          IN SIZE_T dwSize,
2638          IN DWORD flAllocationType,
2639          IN DWORD flProtect);
2640
2641 PALIMPORT
2642 BOOL
2643 PALAPI
2644 VirtualFree(
2645         IN LPVOID lpAddress,
2646         IN SIZE_T dwSize,
2647         IN DWORD dwFreeType);
2648
2649 #if defined(HOST_OSX) && defined(HOST_ARM64)
2650 #ifdef __cplusplus
2651 extern "C++" {
2652 struct PAL_JITWriteEnableHolder
2653 {
2654 public:
2655   PAL_JITWriteEnableHolder(bool jitWriteEnable)
2656   {
2657       m_jitWriteEnableRestore = JITWriteEnable(jitWriteEnable);
2658   };
2659   ~PAL_JITWriteEnableHolder()
2660   {
2661       JITWriteEnable(m_jitWriteEnableRestore);
2662   }
2663
2664 private:
2665   bool JITWriteEnable(bool enable);
2666   bool m_jitWriteEnableRestore;
2667 };
2668
2669 inline
2670 PAL_JITWriteEnableHolder
2671 PAL_JITWriteEnable(IN bool enable) { return PAL_JITWriteEnableHolder(enable); }
2672 }
2673 #endif // __cplusplus
2674 #endif // defined(HOST_OSX) && defined(HOST_ARM64)
2675
2676 PALIMPORT
2677 BOOL
2678 PALAPI
2679 VirtualProtect(
2680            IN LPVOID lpAddress,
2681            IN SIZE_T dwSize,
2682            IN DWORD flNewProtect,
2683            OUT PDWORD lpflOldProtect);
2684
2685 typedef struct _MEMORYSTATUSEX {
2686   DWORD     dwLength;
2687   DWORD     dwMemoryLoad;
2688   DWORDLONG ullTotalPhys;
2689   DWORDLONG ullAvailPhys;
2690   DWORDLONG ullTotalPageFile;
2691   DWORDLONG ullAvailPageFile;
2692   DWORDLONG ullTotalVirtual;
2693   DWORDLONG ullAvailVirtual;
2694   DWORDLONG ullAvailExtendedVirtual;
2695 } MEMORYSTATUSEX, *LPMEMORYSTATUSEX;
2696
2697 PALIMPORT
2698 BOOL
2699 PALAPI
2700 GlobalMemoryStatusEx(
2701             IN OUT LPMEMORYSTATUSEX lpBuffer);
2702
2703 typedef struct _MEMORY_BASIC_INFORMATION {
2704     PVOID BaseAddress;
2705     PVOID AllocationBase_PAL_Undefined;
2706     DWORD AllocationProtect;
2707     SIZE_T RegionSize;
2708     DWORD State;
2709     DWORD Protect;
2710     DWORD Type;
2711 } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
2712
2713 PALIMPORT
2714 SIZE_T
2715 PALAPI
2716 VirtualQuery(
2717          IN LPCVOID lpAddress,
2718          OUT PMEMORY_BASIC_INFORMATION lpBuffer,
2719          IN SIZE_T dwLength);
2720
2721 #define MoveMemory memmove
2722 #define CopyMemory memcpy
2723 #define FillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
2724 #define ZeroMemory(Destination,Length) memset((Destination),0,(Length))
2725
2726 #define LMEM_FIXED          0x0000
2727 #define LMEM_MOVEABLE       0x0002
2728 #define LMEM_ZEROINIT       0x0040
2729 #define LPTR                (LMEM_FIXED | LMEM_ZEROINIT)
2730
2731 PALIMPORT
2732 HLOCAL
2733 PALAPI
2734 LocalAlloc(
2735        IN UINT uFlags,
2736        IN SIZE_T uBytes);
2737
2738 PALIMPORT
2739 HLOCAL
2740 PALAPI
2741 LocalFree(
2742       IN HLOCAL hMem);
2743
2744 PALIMPORT
2745 BOOL
2746 PALAPI
2747 FlushInstructionCache(
2748               IN HANDLE hProcess,
2749               IN LPCVOID lpBaseAddress,
2750               IN SIZE_T dwSize);
2751
2752 #define MAX_LEADBYTES         12
2753 #define MAX_DEFAULTCHAR       2
2754
2755 PALIMPORT
2756 UINT
2757 PALAPI
2758 GetACP(void);
2759
2760 typedef struct _cpinfo {
2761     UINT MaxCharSize;
2762     BYTE DefaultChar[MAX_DEFAULTCHAR];
2763     BYTE LeadByte[MAX_LEADBYTES];
2764 } CPINFO, *LPCPINFO;
2765
2766 #define MB_PRECOMPOSED            0x00000001
2767 #define MB_ERR_INVALID_CHARS      0x00000008
2768
2769 PALIMPORT
2770 int
2771 PALAPI
2772 MultiByteToWideChar(
2773             IN UINT CodePage,
2774             IN DWORD dwFlags,
2775             IN LPCSTR lpMultiByteStr,
2776             IN int cbMultiByte,
2777             OUT LPWSTR lpWideCharStr,
2778             IN int cchWideChar);
2779
2780 #define WC_NO_BEST_FIT_CHARS      0x00000400
2781
2782 PALIMPORT
2783 int
2784 PALAPI
2785 WideCharToMultiByte(
2786             IN UINT CodePage,
2787             IN DWORD dwFlags,
2788             IN LPCWSTR lpWideCharStr,
2789             IN int cchWideChar,
2790             OUT LPSTR lpMultiByteStr,
2791             IN int cbMultyByte,
2792             IN LPCSTR lpDefaultChar,
2793             OUT LPBOOL lpUsedDefaultChar);
2794
2795 #define EXCEPTION_NONCONTINUABLE 0x1
2796 #define EXCEPTION_UNWINDING 0x2
2797
2798 #define EXCEPTION_EXIT_UNWIND 0x4       // Exit unwind is in progress (not used by PAL SEH)
2799 #define EXCEPTION_NESTED_CALL 0x10      // Nested exception handler call
2800 #define EXCEPTION_TARGET_UNWIND 0x20    // Target unwind in progress
2801 #define EXCEPTION_COLLIDED_UNWIND 0x40  // Collided exception handler call
2802 #define EXCEPTION_SKIP_VEH 0x200
2803
2804 #define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | \
2805                           EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND)
2806
2807 #define IS_DISPATCHING(Flag) ((Flag & EXCEPTION_UNWIND) == 0)
2808 #define IS_UNWINDING(Flag) ((Flag & EXCEPTION_UNWIND) != 0)
2809 #define IS_TARGET_UNWIND(Flag) (Flag & EXCEPTION_TARGET_UNWIND)
2810
2811 #define EXCEPTION_IS_SIGNAL 0x100
2812
2813 #define EXCEPTION_MAXIMUM_PARAMETERS 15
2814
2815 // Index in the ExceptionInformation array where we will keep the reference
2816 // to the native exception that needs to be deleted when dispatching
2817 // exception in managed code.
2818 #define NATIVE_EXCEPTION_ASYNC_SLOT (EXCEPTION_MAXIMUM_PARAMETERS-1)
2819
2820 typedef struct _EXCEPTION_RECORD {
2821     DWORD ExceptionCode;
2822     DWORD ExceptionFlags;
2823     struct _EXCEPTION_RECORD *ExceptionRecord;
2824     PVOID ExceptionAddress;
2825     DWORD NumberParameters;
2826     ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
2827 } EXCEPTION_RECORD, *PEXCEPTION_RECORD;
2828
2829 typedef struct _EXCEPTION_POINTERS {
2830     PEXCEPTION_RECORD ExceptionRecord;
2831     PCONTEXT ContextRecord;
2832 } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS, *LPEXCEPTION_POINTERS;
2833
2834 typedef LONG EXCEPTION_DISPOSITION;
2835
2836 enum {
2837     ExceptionContinueExecution,
2838     ExceptionContinueSearch,
2839     ExceptionNestedException,
2840     ExceptionCollidedUnwind,
2841 };
2842
2843 //
2844 // A function table entry is generated for each frame function.
2845 //
2846 typedef struct _RUNTIME_FUNCTION {
2847     DWORD BeginAddress;
2848 #ifdef TARGET_AMD64
2849     DWORD EndAddress;
2850 #endif
2851     DWORD UnwindData;
2852 } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
2853
2854 #define STANDARD_RIGHTS_REQUIRED  (0x000F0000L)
2855 #define SYNCHRONIZE               (0x00100000L)
2856 #define READ_CONTROL              (0x00020000L)
2857 #define MAXIMUM_ALLOWED           (0x02000000L)
2858
2859 #define EVENT_MODIFY_STATE        (0x0002)
2860 #define EVENT_ALL_ACCESS          (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3)
2861
2862 #define MUTANT_QUERY_STATE        (0x0001)
2863 #define MUTANT_ALL_ACCESS         (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | MUTANT_QUERY_STATE)
2864 #define MUTEX_ALL_ACCESS          MUTANT_ALL_ACCESS
2865
2866 #define SEMAPHORE_MODIFY_STATE    (0x0002)
2867 #define SEMAPHORE_ALL_ACCESS      (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3)
2868
2869 #define PROCESS_TERMINATE         (0x0001)
2870 #define PROCESS_CREATE_THREAD     (0x0002)
2871 #define PROCESS_SET_SESSIONID     (0x0004)
2872 #define PROCESS_VM_OPERATION      (0x0008)
2873 #define PROCESS_VM_READ           (0x0010)
2874 #define PROCESS_VM_WRITE          (0x0020)
2875 #define PROCESS_DUP_HANDLE        (0x0040)
2876 #define PROCESS_CREATE_PROCESS    (0x0080)
2877 #define PROCESS_SET_QUOTA         (0x0100)
2878 #define PROCESS_SET_INFORMATION   (0x0200)
2879 #define PROCESS_QUERY_INFORMATION (0x0400)
2880 #define PROCESS_SUSPEND_RESUME    (0x0800)
2881 #define PROCESS_ALL_ACCESS        (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
2882                                    0xFFF)
2883
2884 PALIMPORT
2885 HANDLE
2886 PALAPI
2887 OpenProcess(
2888     IN DWORD dwDesiredAccess, /* PROCESS_DUP_HANDLE or PROCESS_ALL_ACCESS */
2889     IN BOOL bInheritHandle,
2890     IN DWORD dwProcessId
2891     );
2892
2893 PALIMPORT
2894 BOOL
2895 PALAPI
2896 EnumProcessModules(
2897     IN HANDLE hProcess,
2898     OUT HMODULE *lphModule,
2899     IN DWORD cb,
2900     OUT LPDWORD lpcbNeeded
2901     );
2902
2903 PALIMPORT
2904 VOID
2905 PALAPI
2906 OutputDebugStringA(
2907     IN LPCSTR lpOutputString);
2908
2909 PALIMPORT
2910 VOID
2911 PALAPI
2912 OutputDebugStringW(
2913     IN LPCWSTR lpOutputStrig);
2914
2915 #ifdef UNICODE
2916 #define OutputDebugString OutputDebugStringW
2917 #else
2918 #define OutputDebugString OutputDebugStringA
2919 #endif
2920
2921 PALIMPORT
2922 VOID
2923 PALAPI
2924 DebugBreak();
2925
2926 PALIMPORT
2927 DWORD
2928 PALAPI
2929 GetEnvironmentVariableW(
2930             IN LPCWSTR lpName,
2931             OUT LPWSTR lpBuffer,
2932             IN DWORD nSize);
2933
2934 #ifdef UNICODE
2935 #define GetEnvironmentVariable GetEnvironmentVariableW
2936 #else
2937 #define GetEnvironmentVariable GetEnvironmentVariableA
2938 #endif
2939
2940 PALIMPORT
2941 BOOL
2942 PALAPI
2943 SetEnvironmentVariableW(
2944             IN LPCWSTR lpName,
2945             IN LPCWSTR lpValue);
2946
2947 #ifdef UNICODE
2948 #define SetEnvironmentVariable SetEnvironmentVariableW
2949 #else
2950 #define SetEnvironmentVariable SetEnvironmentVariableA
2951 #endif
2952
2953 PALIMPORT
2954 LPWSTR
2955 PALAPI
2956 GetEnvironmentStringsW();
2957
2958 #define GetEnvironmentStrings GetEnvironmentStringsW
2959
2960 PALIMPORT
2961 BOOL
2962 PALAPI
2963 FreeEnvironmentStringsW(
2964             IN LPWSTR);
2965
2966 #define FreeEnvironmentStrings FreeEnvironmentStringsW
2967
2968 PALIMPORT
2969 BOOL
2970 PALAPI
2971 CloseHandle(
2972         IN OUT HANDLE hObject);
2973
2974 PALIMPORT
2975 VOID
2976 PALAPI
2977 RaiseException(
2978            IN DWORD dwExceptionCode,
2979            IN DWORD dwExceptionFlags,
2980            IN DWORD nNumberOfArguments,
2981            IN CONST ULONG_PTR *lpArguments);
2982
2983 PALIMPORT
2984 VOID
2985 PALAPI
2986 RaiseFailFastException(
2987     IN PEXCEPTION_RECORD pExceptionRecord,
2988     IN PCONTEXT pContextRecord,
2989     IN DWORD dwFlags);
2990
2991 PALIMPORT
2992 DWORD
2993 PALAPI
2994 GetTickCount();
2995
2996 PALIMPORT
2997 ULONGLONG
2998 PALAPI
2999 GetTickCount64();
3000
3001 PALIMPORT
3002 BOOL
3003 PALAPI
3004 QueryPerformanceCounter(
3005     OUT LARGE_INTEGER *lpPerformanceCount
3006     );
3007
3008 PALIMPORT
3009 BOOL
3010 PALAPI
3011 QueryPerformanceFrequency(
3012     OUT LARGE_INTEGER *lpFrequency
3013     );
3014
3015 PALIMPORT
3016 BOOL
3017 PALAPI
3018 QueryThreadCycleTime(
3019     IN HANDLE ThreadHandle,
3020     OUT PULONG64 CycleTime);
3021
3022 PALIMPORT
3023 INT
3024 PALAPI
3025 PAL_nanosleep(
3026     IN long timeInNs);
3027
3028 typedef EXCEPTION_DISPOSITION (PALAPI_NOEXPORT *PVECTORED_EXCEPTION_HANDLER)(
3029                            struct _EXCEPTION_POINTERS *ExceptionPointers);
3030
3031 // Define BitScanForward64 and BitScanForward
3032 // Per MSDN, BitScanForward64 will search the mask data from LSB to MSB for a set bit.
3033 // If one is found, its bit position is stored in the out PDWORD argument and 1 is returned;
3034 // otherwise, an undefined value is stored in the out PDWORD argument and 0 is returned.
3035 //
3036 // On GCC, the equivalent function is __builtin_ffsll. It returns 1+index of the least
3037 // significant set bit, or 0 if if mask is zero.
3038 //
3039 // The same is true for BitScanForward, except that the GCC function is __builtin_ffs.
3040 EXTERN_C
3041 PALIMPORT
3042 inline
3043 unsigned char
3044 PALAPI
3045 BitScanForward(
3046     IN OUT PDWORD Index,
3047     IN UINT qwMask)
3048 {
3049     int iIndex = __builtin_ffs(qwMask);
3050     // Set the Index after deducting unity
3051     *Index = (DWORD)(iIndex - 1);
3052     // Both GCC and Clang generate better, smaller code if we check whether the
3053     // mask was/is zero rather than the equivalent check that iIndex is zero.
3054     return qwMask != 0 ? TRUE : FALSE;
3055 }
3056
3057 EXTERN_C
3058 PALIMPORT
3059 inline
3060 unsigned char
3061 PALAPI
3062 BitScanForward64(
3063     IN OUT PDWORD Index,
3064     IN UINT64 qwMask)
3065 {
3066     int iIndex = __builtin_ffsll(qwMask);
3067     // Set the Index after deducting unity
3068     *Index = (DWORD)(iIndex - 1);
3069     // Both GCC and Clang generate better, smaller code if we check whether the
3070     // mask was/is zero rather than the equivalent check that iIndex is zero.
3071     return qwMask != 0 ? TRUE : FALSE;
3072 }
3073
3074 // Define BitScanReverse64 and BitScanReverse
3075 // Per MSDN, BitScanReverse64 will search the mask data from MSB to LSB for a set bit.
3076 // If one is found, its bit position is stored in the out PDWORD argument and 1 is returned.
3077 // Otherwise, an undefined value is stored in the out PDWORD argument and 0 is returned.
3078 //
3079 // GCC/clang don't have a directly equivalent intrinsic; they do provide the __builtin_clzll
3080 // intrinsic, which returns the number of leading 0-bits in x starting at the most significant
3081 // bit position (the result is undefined when x = 0).
3082 //
3083 // The same is true for BitScanReverse, except that the GCC function is __builtin_clzl.
3084
3085 EXTERN_C
3086 PALIMPORT
3087 inline
3088 unsigned char
3089 PALAPI
3090 BitScanReverse(
3091     IN OUT PDWORD Index,
3092     IN UINT qwMask)
3093 {
3094     // The result of __builtin_clzl is undefined when qwMask is zero,
3095     // but it's still OK to call the intrinsic in that case (just don't use the output).
3096     // Unconditionally calling the intrinsic in this way allows the compiler to
3097     // emit branchless code for this function when possible (depending on how the
3098     // intrinsic is implemented for the target platform).
3099     int lzcount = __builtin_clzl(qwMask);
3100     *Index = (DWORD)(31 - lzcount);
3101     return qwMask != 0;
3102 }
3103
3104 EXTERN_C
3105 PALIMPORT
3106 inline
3107 unsigned char
3108 PALAPI
3109 BitScanReverse64(
3110     IN OUT PDWORD Index,
3111     IN UINT64 qwMask)
3112 {
3113     // The result of __builtin_clzll is undefined when qwMask is zero,
3114     // but it's still OK to call the intrinsic in that case (just don't use the output).
3115     // Unconditionally calling the intrinsic in this way allows the compiler to
3116     // emit branchless code for this function when possible (depending on how the
3117     // intrinsic is implemented for the target platform).
3118     int lzcount = __builtin_clzll(qwMask);
3119     *Index = (DWORD)(63 - lzcount);
3120     return qwMask != 0;
3121 }
3122
3123 FORCEINLINE void PAL_ArmInterlockedOperationBarrier()
3124 {
3125 #ifdef HOST_ARM64
3126     // On arm64, most of the __sync* functions generate a code sequence like:
3127     //   loop:
3128     //     ldaxr (load acquire exclusive)
3129     //     ...
3130     //     stlxr (store release exclusive)
3131     //     cbnz loop
3132     //
3133     // It is possible for a load following the code sequence above to be reordered to occur prior to the store above due to the
3134     // release barrier, this is substantiated by https://github.com/dotnet/coreclr/pull/17508. Interlocked operations in the PAL
3135     // require the load to occur after the store. This memory barrier should be used following a call to a __sync* function to
3136     // prevent that reordering. Code generated for arm32 includes a 'dmb' after 'cbnz', so no issue there at the moment.
3137     __sync_synchronize();
3138 #endif // HOST_ARM64
3139 }
3140
3141 /*++
3142 Function:
3143 InterlockedIncrement
3144
3145 The InterlockedIncrement function increments (increases by one) the
3146 value of the specified variable and checks the resulting value. The
3147 function prevents more than one thread from using the same variable
3148 simultaneously.
3149
3150 Parameters
3151
3152 lpAddend
3153 [in/out] Pointer to the variable to increment.
3154
3155 Return Values
3156
3157 The return value is the resulting incremented value.
3158
3159 --*/
3160 EXTERN_C
3161 PALIMPORT
3162 inline
3163 LONG
3164 PALAPI
3165 InterlockedIncrement(
3166     IN OUT LONG volatile *lpAddend)
3167 {
3168     LONG result = __sync_add_and_fetch(lpAddend, (LONG)1);
3169     PAL_ArmInterlockedOperationBarrier();
3170     return result;
3171 }
3172
3173 EXTERN_C
3174 PALIMPORT
3175 inline
3176 LONGLONG
3177 PALAPI
3178 InterlockedIncrement64(
3179     IN OUT LONGLONG volatile *lpAddend)
3180 {
3181     LONGLONG result = __sync_add_and_fetch(lpAddend, (LONGLONG)1);
3182     PAL_ArmInterlockedOperationBarrier();
3183     return result;
3184 }
3185
3186 /*++
3187 Function:
3188 InterlockedDecrement
3189
3190 The InterlockedDecrement function decrements (decreases by one) the
3191 value of the specified variable and checks the resulting value. The
3192 function prevents more than one thread from using the same variable
3193 simultaneously.
3194
3195 Parameters
3196
3197 lpAddend
3198 [in/out] Pointer to the variable to decrement.
3199
3200 Return Values
3201
3202 The return value is the resulting decremented value.
3203
3204 --*/
3205 EXTERN_C
3206 PALIMPORT
3207 inline
3208 LONG
3209 PALAPI
3210 InterlockedDecrement(
3211     IN OUT LONG volatile *lpAddend)
3212 {
3213     LONG result = __sync_sub_and_fetch(lpAddend, (LONG)1);
3214     PAL_ArmInterlockedOperationBarrier();
3215     return result;
3216 }
3217
3218 #define InterlockedDecrementAcquire InterlockedDecrement
3219 #define InterlockedDecrementRelease InterlockedDecrement
3220
3221 EXTERN_C
3222 PALIMPORT
3223 inline
3224 LONGLONG
3225 PALAPI
3226 InterlockedDecrement64(
3227     IN OUT LONGLONG volatile *lpAddend)
3228 {
3229     LONGLONG result = __sync_sub_and_fetch(lpAddend, (LONGLONG)1);
3230     PAL_ArmInterlockedOperationBarrier();
3231     return result;
3232 }
3233
3234 /*++
3235 Function:
3236 InterlockedExchange
3237
3238 The InterlockedExchange function atomically exchanges a pair of
3239 values. The function prevents more than one thread from using the same
3240 variable simultaneously.
3241
3242 Parameters
3243
3244 Target
3245 [in/out] Pointer to the value to exchange. The function sets
3246 this variable to Value, and returns its prior value.
3247 Value
3248 [in] Specifies a new value for the variable pointed to by Target.
3249
3250 Return Values
3251
3252 The function returns the initial value pointed to by Target.
3253
3254 --*/
3255 EXTERN_C
3256 PALIMPORT
3257 inline
3258 LONG
3259 PALAPI
3260 InterlockedExchange(
3261     IN OUT LONG volatile *Target,
3262     IN LONG Value)
3263 {
3264     LONG result = __atomic_exchange_n(Target, Value, __ATOMIC_ACQ_REL);
3265     PAL_ArmInterlockedOperationBarrier();
3266     return result;
3267 }
3268
3269 EXTERN_C
3270 PALIMPORT
3271 inline
3272 LONGLONG
3273 PALAPI
3274 InterlockedExchange64(
3275     IN OUT LONGLONG volatile *Target,
3276     IN LONGLONG Value)
3277 {
3278     LONGLONG result = __atomic_exchange_n(Target, Value, __ATOMIC_ACQ_REL);
3279     PAL_ArmInterlockedOperationBarrier();
3280     return result;
3281 }
3282
3283 /*++
3284 Function:
3285 InterlockedCompareExchange
3286
3287 The InterlockedCompareExchange function performs an atomic comparison
3288 of the specified values and exchanges the values, based on the outcome
3289 of the comparison. The function prevents more than one thread from
3290 using the same variable simultaneously.
3291
3292 If you are exchanging pointer values, this function has been
3293 superseded by the InterlockedCompareExchangePointer function.
3294
3295 Parameters
3296
3297 Destination     [in/out] Specifies the address of the destination value. The sign is ignored.
3298 Exchange        [in]     Specifies the exchange value. The sign is ignored.
3299 Comperand       [in]     Specifies the value to compare to Destination. The sign is ignored.
3300
3301 Return Values
3302
3303 The return value is the initial value of the destination.
3304
3305 --*/
3306 EXTERN_C
3307 PALIMPORT
3308 inline
3309 LONG
3310 PALAPI
3311 InterlockedCompareExchange(
3312     IN OUT LONG volatile *Destination,
3313     IN LONG Exchange,
3314     IN LONG Comperand)
3315 {
3316     LONG result =
3317         __sync_val_compare_and_swap(
3318             Destination, /* The pointer to a variable whose value is to be compared with. */
3319             Comperand, /* The value to be compared */
3320             Exchange /* The value to be stored */);
3321     PAL_ArmInterlockedOperationBarrier();
3322     return result;
3323 }
3324
3325 #define InterlockedCompareExchangeAcquire InterlockedCompareExchange
3326 #define InterlockedCompareExchangeRelease InterlockedCompareExchange
3327
3328 // See the 32-bit variant in interlock2.s
3329 EXTERN_C
3330 PALIMPORT
3331 inline
3332 LONGLONG
3333 PALAPI
3334 InterlockedCompareExchange64(
3335     IN OUT LONGLONG volatile *Destination,
3336     IN LONGLONG Exchange,
3337     IN LONGLONG Comperand)
3338 {
3339     LONGLONG result =
3340         __sync_val_compare_and_swap(
3341             Destination, /* The pointer to a variable whose value is to be compared with. */
3342             Comperand, /* The value to be compared */
3343             Exchange /* The value to be stored */);
3344     PAL_ArmInterlockedOperationBarrier();
3345     return result;
3346 }
3347
3348 /*++
3349 Function:
3350 InterlockedExchangeAdd
3351
3352 The InterlockedExchangeAdd function atomically adds the value of 'Value'
3353 to the variable that 'Addend' points to.
3354
3355 Parameters
3356
3357 lpAddend
3358 [in/out] Pointer to the variable to to added.
3359
3360 Return Values
3361
3362 The return value is the original value that 'Addend' pointed to.
3363
3364 --*/
3365 EXTERN_C
3366 PALIMPORT
3367 inline
3368 LONG
3369 PALAPI
3370 InterlockedExchangeAdd(
3371     IN OUT LONG volatile *Addend,
3372     IN LONG Value)
3373 {
3374     LONG result = __sync_fetch_and_add(Addend, Value);
3375     PAL_ArmInterlockedOperationBarrier();
3376     return result;
3377 }
3378
3379 EXTERN_C
3380 PALIMPORT
3381 inline
3382 LONGLONG
3383 PALAPI
3384 InterlockedExchangeAdd64(
3385     IN OUT LONGLONG volatile *Addend,
3386     IN LONGLONG Value)
3387 {
3388     LONGLONG result = __sync_fetch_and_add(Addend, Value);
3389     PAL_ArmInterlockedOperationBarrier();
3390     return result;
3391 }
3392
3393 EXTERN_C
3394 PALIMPORT
3395 inline
3396 LONG
3397 PALAPI
3398 InterlockedAnd(
3399     IN OUT LONG volatile *Destination,
3400     IN LONG Value)
3401 {
3402     LONG result = __sync_fetch_and_and(Destination, Value);
3403     PAL_ArmInterlockedOperationBarrier();
3404     return result;
3405 }
3406
3407 EXTERN_C
3408 PALIMPORT
3409 inline
3410 LONG
3411 PALAPI
3412 InterlockedOr(
3413     IN OUT LONG volatile *Destination,
3414     IN LONG Value)
3415 {
3416     LONG result = __sync_fetch_and_or(Destination, Value);
3417     PAL_ArmInterlockedOperationBarrier();
3418     return result;
3419 }
3420
3421 EXTERN_C
3422 PALIMPORT
3423 inline
3424 UCHAR
3425 PALAPI
3426 InterlockedBitTestAndReset(
3427     IN OUT LONG volatile *Base,
3428     IN LONG Bit)
3429 {
3430     return (InterlockedAnd(Base, ~(1 << Bit)) & (1 << Bit)) != 0;
3431 }
3432
3433 EXTERN_C
3434 PALIMPORT
3435 inline
3436 UCHAR
3437 PALAPI
3438 InterlockedBitTestAndSet(
3439     IN OUT LONG volatile *Base,
3440     IN LONG Bit)
3441 {
3442     return (InterlockedOr(Base, (1 << Bit)) & (1 << Bit)) != 0;
3443 }
3444
3445 #if defined(HOST_64BIT)
3446 #define InterlockedExchangePointer(Target, Value) \
3447     ((PVOID)InterlockedExchange64((PLONG64)(Target), (LONGLONG)(Value)))
3448
3449 #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \
3450     ((PVOID)InterlockedCompareExchange64((PLONG64)(Destination), (LONGLONG)(ExChange), (LONGLONG)(Comperand)))
3451 #else
3452 #define InterlockedExchangePointer(Target, Value) \
3453     ((PVOID)(UINT_PTR)InterlockedExchange((PLONG)(UINT_PTR)(Target), (LONG)(UINT_PTR)(Value)))
3454
3455 #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \
3456     ((PVOID)(UINT_PTR)InterlockedCompareExchange((PLONG)(UINT_PTR)(Destination), (LONG)(UINT_PTR)(ExChange), (LONG)(UINT_PTR)(Comperand)))
3457 #endif
3458
3459 /*++
3460 Function:
3461 MemoryBarrier
3462
3463 The MemoryBarrier function creates a full memory barrier.
3464
3465 --*/
3466 EXTERN_C
3467 PALIMPORT
3468 inline
3469 VOID
3470 PALAPI
3471 MemoryBarrier()
3472 {
3473     __sync_synchronize();
3474 }
3475
3476 EXTERN_C
3477 PALIMPORT
3478 inline
3479 VOID
3480 PALAPI
3481 YieldProcessor()
3482 {
3483 #if defined(HOST_X86) || defined(HOST_AMD64)
3484     __asm__ __volatile__(
3485         "rep\n"
3486         "nop");
3487 #elif defined(HOST_ARM64)
3488     __asm__ __volatile__( "yield");
3489 #else
3490     return;
3491 #endif
3492 }
3493
3494 PALIMPORT
3495 DWORD
3496 PALAPI
3497 GetCurrentProcessorNumber();
3498
3499 /*++
3500 Function:
3501 PAL_HasGetCurrentProcessorNumber
3502
3503 Checks if GetCurrentProcessorNumber is available in the current environment
3504
3505 --*/
3506 PALIMPORT
3507 BOOL
3508 PALAPI
3509 PAL_HasGetCurrentProcessorNumber();
3510
3511 #define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
3512 #define FORMAT_MESSAGE_IGNORE_INSERTS  0x00000200
3513 #define FORMAT_MESSAGE_FROM_STRING     0x00000400
3514 #define FORMAT_MESSAGE_FROM_SYSTEM     0x00001000
3515 #define FORMAT_MESSAGE_ARGUMENT_ARRAY  0x00002000
3516 #define FORMAT_MESSAGE_MAX_WIDTH_MASK  0x000000FF
3517
3518 PALIMPORT
3519 DWORD
3520 PALAPI
3521 FormatMessageW(
3522            IN DWORD dwFlags,
3523            IN LPCVOID lpSource,
3524            IN DWORD dwMessageId,
3525            IN DWORD dwLanguageId,
3526            OUT LPWSTR lpBffer,
3527            IN DWORD nSize,
3528            IN va_list *Arguments);
3529
3530 #ifdef UNICODE
3531 #define FormatMessage FormatMessageW
3532 #endif
3533
3534
3535 PALIMPORT
3536 DWORD
3537 PALAPI
3538 GetLastError();
3539
3540 PALIMPORT
3541 VOID
3542 PALAPI
3543 SetLastError(
3544          IN DWORD dwErrCode);
3545
3546 PALIMPORT
3547 LPWSTR
3548 PALAPI
3549 GetCommandLineW();
3550
3551 #ifdef UNICODE
3552 #define GetCommandLine GetCommandLineW
3553 #endif
3554
3555 PALIMPORT
3556 VOID
3557 PALAPI
3558 RtlRestoreContext(
3559   IN PCONTEXT ContextRecord,
3560   IN PEXCEPTION_RECORD ExceptionRecord
3561 );
3562
3563 PALIMPORT
3564 VOID
3565 PALAPI
3566 RtlCaptureContext(
3567   OUT PCONTEXT ContextRecord
3568 );
3569
3570 PALIMPORT
3571 VOID
3572 PALAPI
3573 FlushProcessWriteBuffers();
3574
3575 typedef void (*PAL_ActivationFunction)(CONTEXT *context);
3576 typedef BOOL (*PAL_SafeActivationCheckFunction)(SIZE_T ip, BOOL checkingCurrentThread);
3577
3578 PALIMPORT
3579 VOID
3580 PALAPI
3581 PAL_SetActivationFunction(
3582     IN PAL_ActivationFunction pActivationFunction,
3583     IN PAL_SafeActivationCheckFunction pSafeActivationCheckFunction);
3584
3585 PALIMPORT
3586 BOOL
3587 PALAPI
3588 PAL_InjectActivation(
3589     IN HANDLE hThread
3590 );
3591
3592 #define VER_PLATFORM_WIN32_WINDOWS        1
3593 #define VER_PLATFORM_WIN32_NT        2
3594 #define VER_PLATFORM_UNIX            10
3595 #define VER_PLATFORM_MACOSX          11
3596
3597 typedef struct _OSVERSIONINFOA {
3598     DWORD dwOSVersionInfoSize;
3599     DWORD dwMajorVersion;
3600     DWORD dwMinorVersion;
3601     DWORD dwBuildNumber;
3602     DWORD dwPlatformId;
3603     CHAR szCSDVersion[ 128 ];
3604 } OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA;
3605
3606 typedef struct _OSVERSIONINFOW {
3607     DWORD dwOSVersionInfoSize;
3608     DWORD dwMajorVersion;
3609     DWORD dwMinorVersion;
3610     DWORD dwBuildNumber;
3611     DWORD dwPlatformId;
3612     WCHAR szCSDVersion[ 128 ];
3613 } OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW;
3614
3615 #ifdef UNICODE
3616 typedef OSVERSIONINFOW OSVERSIONINFO;
3617 typedef POSVERSIONINFOW POSVERSIONINFO;
3618 typedef LPOSVERSIONINFOW LPOSVERSIONINFO;
3619 #else
3620 typedef OSVERSIONINFOA OSVERSIONINFO;
3621 typedef POSVERSIONINFOA POSVERSIONINFO;
3622 typedef LPOSVERSIONINFOA LPOSVERSIONINFO;
3623 #endif
3624
3625 typedef struct _OSVERSIONINFOEXA {
3626     DWORD dwOSVersionInfoSize;
3627     DWORD dwMajorVersion;
3628     DWORD dwMinorVersion;
3629     DWORD dwBuildNumber;
3630     DWORD dwPlatformId;
3631     CHAR szCSDVersion[ 128 ];
3632     WORD  wServicePackMajor;
3633     WORD  wServicePackMinor;
3634     WORD  wSuiteMask;
3635     BYTE  wProductType;
3636     BYTE  wReserved;
3637 } OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA;
3638
3639 typedef struct _OSVERSIONINFOEXW {
3640     DWORD dwOSVersionInfoSize;
3641     DWORD dwMajorVersion;
3642     DWORD dwMinorVersion;
3643     DWORD dwBuildNumber;
3644     DWORD dwPlatformId;
3645     WCHAR szCSDVersion[ 128 ];
3646     WORD  wServicePackMajor;
3647     WORD  wServicePackMinor;
3648     WORD  wSuiteMask;
3649     BYTE  wProductType;
3650     BYTE  wReserved;
3651 } OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW;
3652
3653 #ifdef UNICODE
3654 typedef OSVERSIONINFOEXW OSVERSIONINFOEX;
3655 typedef POSVERSIONINFOEXW POSVERSIONINFOEX;
3656 typedef LPOSVERSIONINFOEXW LPOSVERSIONINFOEX;
3657 #else
3658 typedef OSVERSIONINFOEXA OSVERSIONINFOEX;
3659 typedef POSVERSIONINFOEXA POSVERSIONINFOEX;
3660 typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX;
3661 #endif
3662
3663 #define IMAGE_FILE_MACHINE_I386              0x014c
3664 #define IMAGE_FILE_MACHINE_ARM64             0xAA64  // ARM64 Little-Endian
3665
3666 typedef struct _SYSTEM_INFO {
3667     WORD wProcessorArchitecture_PAL_Undefined;
3668     WORD wReserved_PAL_Undefined; // NOTE: diff from winbase.h - no obsolete dwOemId union
3669     DWORD dwPageSize;
3670     LPVOID lpMinimumApplicationAddress;
3671     LPVOID lpMaximumApplicationAddress;
3672     DWORD_PTR dwActiveProcessorMask_PAL_Undefined;
3673     DWORD dwNumberOfProcessors;
3674     DWORD dwProcessorType_PAL_Undefined;
3675     DWORD dwAllocationGranularity;
3676     WORD wProcessorLevel_PAL_Undefined;
3677     WORD wProcessorRevision_PAL_Undefined;
3678 } SYSTEM_INFO, *LPSYSTEM_INFO;
3679
3680 PALIMPORT
3681 VOID
3682 PALAPI
3683 GetSystemInfo(
3684           OUT LPSYSTEM_INFO lpSystemInfo);
3685
3686 PALIMPORT
3687 BOOL
3688 PALAPI
3689 CreatePipe(
3690     OUT PHANDLE hReadPipe,
3691     OUT PHANDLE hWritePipe,
3692     IN LPSECURITY_ATTRIBUTES lpPipeAttributes,
3693     IN DWORD nSize
3694     );
3695
3696 //
3697 // NUMA related APIs
3698 //
3699
3700 PALIMPORT
3701 BOOL
3702 PALAPI
3703 GetNumaHighestNodeNumber(
3704   OUT PULONG HighestNodeNumber
3705 );
3706
3707 PALIMPORT
3708 BOOL
3709 PALAPI
3710 PAL_GetNumaProcessorNode(WORD procNo, WORD* node);
3711
3712 PALIMPORT
3713 LPVOID
3714 PALAPI
3715 VirtualAllocExNuma(
3716   IN HANDLE hProcess,
3717   IN OPTIONAL LPVOID lpAddress,
3718   IN SIZE_T dwSize,
3719   IN DWORD flAllocationType,
3720   IN DWORD flProtect,
3721   IN DWORD nndPreferred
3722 );
3723
3724 PALIMPORT
3725 BOOL
3726 PALAPI
3727 PAL_SetCurrentThreadAffinity(WORD procNo);
3728
3729 PALIMPORT
3730 BOOL
3731 PALAPI
3732 PAL_GetCurrentThreadAffinitySet(SIZE_T size, UINT_PTR* data);
3733
3734 //
3735 // The types of events that can be logged.
3736 //
3737 #define EVENTLOG_SUCCESS                0x0000
3738 #define EVENTLOG_ERROR_TYPE             0x0001
3739 #define EVENTLOG_WARNING_TYPE           0x0002
3740 #define EVENTLOG_INFORMATION_TYPE       0x0004
3741 #define EVENTLOG_AUDIT_SUCCESS          0x0008
3742 #define EVENTLOG_AUDIT_FAILURE          0x0010
3743
3744 #if defined FEATURE_PAL_ANSI
3745 #include "palprivate.h"
3746 #endif //FEATURE_PAL_ANSI
3747 /******************* C Runtime Entrypoints *******************************/
3748
3749 /* Some C runtime functions needs to be reimplemented by the PAL.
3750    To avoid name collisions, those functions have been renamed using
3751    defines */
3752 #ifndef PAL_STDCPP_COMPAT
3753 #define exit          PAL_exit
3754 #define printf        PAL_printf
3755 #define vprintf       PAL_vprintf
3756 #define wprintf       PAL_wprintf
3757 #define wcstod        PAL_wcstod
3758 #define wcstoul       PAL_wcstoul
3759 #define wcscat        PAL_wcscat
3760 #define wcscpy        PAL_wcscpy
3761 #define wcslen        PAL_wcslen
3762 #define wcsncmp       PAL_wcsncmp
3763 #define wcschr        PAL_wcschr
3764 #define wcsrchr       PAL_wcsrchr
3765 #define wcsstr        PAL_wcsstr
3766 #define swscanf       PAL_swscanf
3767 #define wcspbrk       PAL_wcspbrk
3768 #define wcscmp        PAL_wcscmp
3769 #define wcsncpy       PAL_wcsncpy
3770 #define wcstok        PAL_wcstok
3771 #define wcscspn       PAL_wcscspn
3772 #define realloc       PAL_realloc
3773 #define fopen         PAL_fopen
3774 #define strtok        PAL_strtok
3775 #define strtoul       PAL_strtoul
3776 #define strtoull      PAL_strtoull
3777 #define fprintf       PAL_fprintf
3778 #define fwprintf      PAL_fwprintf
3779 #define vfprintf      PAL_vfprintf
3780 #define vfwprintf     PAL_vfwprintf
3781 #define rand          PAL_rand
3782 #define time          PAL_time
3783 #define getenv        PAL_getenv
3784 #define fgets         PAL_fgets
3785 #define qsort         PAL_qsort
3786 #define bsearch       PAL_bsearch
3787 #define ferror        PAL_ferror
3788 #define fread         PAL_fread
3789 #define fwrite        PAL_fwrite
3790 #define ftell         PAL_ftell
3791 #define fclose        PAL_fclose
3792 #define fflush        PAL_fflush
3793 #define fputs         PAL_fputs
3794 #define fseek         PAL_fseek
3795 #define fgetpos       PAL_fgetpos
3796 #define fsetpos       PAL_fsetpos
3797 #define setvbuf       PAL_setvbuf
3798 #define acos          PAL_acos
3799 #define acosh         PAL_acosh
3800 #define asin          PAL_asin
3801 #define asinh         PAL_asinh
3802 #define atan2         PAL_atan2
3803 #define exp           PAL_exp
3804 #define fma           PAL_fma
3805 #define ilogb         PAL_ilogb
3806 #define log           PAL_log
3807 #define log2          PAL_log2
3808 #define log10         PAL_log10
3809 #define pow           PAL_pow
3810 #define sincos        PAL_sincos
3811 #define acosf         PAL_acosf
3812 #define acoshf        PAL_acoshf
3813 #define asinf         PAL_asinf
3814 #define asinhf        PAL_asinhf
3815 #define atan2f        PAL_atan2f
3816 #define expf          PAL_expf
3817 #define fmaf          PAL_fmaf
3818 #define ilogbf        PAL_ilogbf
3819 #define logf          PAL_logf
3820 #define log2f         PAL_log2f
3821 #define log10f        PAL_log10f
3822 #define powf          PAL_powf
3823 #define sincosf       PAL_sincosf
3824 #define malloc        PAL_malloc
3825 #define free          PAL_free
3826 #define _strdup       PAL__strdup
3827 #define _open         PAL__open
3828 #define _pread        PAL__pread
3829 #define _close        PAL__close
3830 #define _wcstoui64    PAL__wcstoui64
3831 #define _flushall     PAL__flushall
3832 #define strnlen       PAL_strnlen
3833 #define wcsnlen       PAL_wcsnlen
3834
3835 #ifdef HOST_AMD64
3836 #define _mm_getcsr    PAL__mm_getcsr
3837 #define _mm_setcsr    PAL__mm_setcsr
3838 #endif // HOST_AMD64
3839
3840 #endif // !PAL_STDCPP_COMPAT
3841
3842 #ifndef _CONST_RETURN
3843 #ifdef  __cplusplus
3844 #define _CONST_RETURN  const
3845 #define _CRT_CONST_CORRECT_OVERLOADS
3846 #else
3847 #define _CONST_RETURN
3848 #endif
3849 #endif
3850
3851 /* For backwards compatibility */
3852 #define _WConst_return _CONST_RETURN
3853
3854 #define EOF     (-1)
3855
3856 typedef int errno_t;
3857
3858 #if defined(__WINT_TYPE__)
3859 typedef __WINT_TYPE__ wint_t;
3860 #else
3861 typedef unsigned int wint_t;
3862 #endif
3863
3864 #ifndef PAL_STDCPP_COMPAT
3865
3866 #if defined(_DEBUG)
3867
3868 /*++
3869 Function:
3870 PAL_memcpy
3871
3872 Overlapping buffer-safe version of memcpy.
3873 See MSDN doc for memcpy
3874 --*/
3875 EXTERN_C
3876 PALIMPORT
3877 DLLEXPORT
3878 void *PAL_memcpy (void *dest, const void * src, size_t count);
3879
3880 PALIMPORT void * __cdecl memcpy(void *, const void *, size_t) THROW_DECL;
3881
3882 #define memcpy PAL_memcpy
3883 #define IS_PAL_memcpy 1
3884 #define TEST_PAL_DEFERRED(def) IS_##def
3885 #define IS_REDEFINED_IN_PAL(def) TEST_PAL_DEFERRED(def)
3886 #else //defined(_DEBUG)
3887 PALIMPORT void * __cdecl memcpy(void *, const void *, size_t);
3888 #endif //defined(_DEBUG)
3889 PALIMPORT int    __cdecl memcmp(const void *, const void *, size_t);
3890 PALIMPORT void * __cdecl memset(void *, int, size_t);
3891 PALIMPORT void * __cdecl memmove(void *, const void *, size_t);
3892 PALIMPORT void * __cdecl memchr(const void *, int, size_t);
3893 PALIMPORT long long int __cdecl atoll(const char *)
3894 #ifndef __sun
3895 THROW_DECL
3896 #endif
3897 ;
3898 PALIMPORT size_t __cdecl strlen(const char *);
3899 PALIMPORT int __cdecl strcmp(const char*, const char *);
3900 PALIMPORT int __cdecl strncmp(const char*, const char *, size_t);
3901 PALIMPORT int __cdecl _strnicmp(const char *, const char *, size_t);
3902 PALIMPORT char * __cdecl strcat(char *, const char *);
3903 PALIMPORT char * __cdecl strncat(char *, const char *, size_t);
3904 PALIMPORT char * __cdecl strcpy(char *, const char *);
3905 PALIMPORT char * __cdecl strncpy(char *, const char *, size_t);
3906 PALIMPORT char * __cdecl strchr(const char *, int);
3907 PALIMPORT char * __cdecl strrchr(const char *, int);
3908 PALIMPORT char * __cdecl strpbrk(const char *, const char *);
3909 PALIMPORT char * __cdecl strstr(const char *, const char *);
3910 PALIMPORT char * __cdecl strtok(char *, const char *);
3911 PALIMPORT size_t __cdecl strspn(const char *, const char *);
3912 PALIMPORT size_t  __cdecl strcspn(const char *, const char *);
3913 PALIMPORT int __cdecl atoi(const char *);
3914 PALIMPORT ULONG __cdecl strtoul(const char *, char **, int);
3915 PALIMPORT ULONGLONG __cdecl strtoull(const char *, char **, int);
3916 PALIMPORT double __cdecl atof(const char *);
3917 PALIMPORT double __cdecl strtod(const char *, char **);
3918 PALIMPORT int __cdecl isprint(int);
3919 PALIMPORT int __cdecl isspace(int);
3920 PALIMPORT int __cdecl isalpha(int);
3921 PALIMPORT int __cdecl isalnum(int);
3922 PALIMPORT int __cdecl isdigit(int);
3923 PALIMPORT int __cdecl isxdigit(int);
3924 PALIMPORT int __cdecl isupper(int);
3925 PALIMPORT int __cdecl islower(int);
3926 PALIMPORT int __cdecl tolower(int);
3927 PALIMPORT int __cdecl toupper(int);
3928 PALIMPORT int __cdecl iswalpha(wint_t);
3929 PALIMPORT int __cdecl iswdigit(wint_t);
3930 PALIMPORT int __cdecl iswupper(wint_t);
3931 PALIMPORT int __cdecl iswprint(wint_t);
3932 PALIMPORT int __cdecl iswspace(wint_t);
3933 PALIMPORT int __cdecl iswxdigit(wint_t);
3934 PALIMPORT wint_t __cdecl towupper(wint_t);
3935 PALIMPORT wint_t __cdecl towlower(wint_t);
3936 #endif // PAL_STDCPP_COMPAT
3937
3938 /* _TRUNCATE */
3939 #if !defined(_TRUNCATE)
3940 #define _TRUNCATE ((size_t)-1)
3941 #endif
3942
3943 PALIMPORT DLLEXPORT errno_t __cdecl memcpy_s(void *, size_t, const void *, size_t) THROW_DECL;
3944 PALIMPORT errno_t __cdecl memmove_s(void *, size_t, const void *, size_t);
3945 PALIMPORT DLLEXPORT int __cdecl _stricmp(const char *, const char *);
3946 PALIMPORT DLLEXPORT int __cdecl vsprintf_s(char *, size_t, const char *, va_list);
3947 PALIMPORT char * __cdecl _gcvt_s(char *, int, double, int);
3948 PALIMPORT int __cdecl __iscsym(int);
3949 PALIMPORT DLLEXPORT int __cdecl _wcsicmp(const WCHAR *, const WCHAR*);
3950 PALIMPORT int __cdecl _wcsnicmp(const WCHAR *, const WCHAR *, size_t);
3951 PALIMPORT int __cdecl _vsnprintf(char *, size_t, const char *, va_list);
3952 PALIMPORT DLLEXPORT int __cdecl _vsnprintf_s(char *, size_t, size_t, const char *, va_list);
3953 PALIMPORT DLLEXPORT int __cdecl _vsnwprintf_s(WCHAR *, size_t, size_t, const WCHAR *, va_list);
3954 PALIMPORT DLLEXPORT int __cdecl _snwprintf_s(WCHAR *, size_t, size_t, const WCHAR *, ...);
3955 PALIMPORT DLLEXPORT int __cdecl _snprintf_s(char *, size_t, size_t, const char *, ...);
3956 PALIMPORT DLLEXPORT int __cdecl sprintf_s(char *, size_t, const char *, ... );
3957 PALIMPORT DLLEXPORT int __cdecl swprintf_s(WCHAR *, size_t, const WCHAR *, ... );
3958 PALIMPORT int __cdecl _snwprintf_s(WCHAR *, size_t, size_t, const WCHAR *, ...);
3959 PALIMPORT int __cdecl vswprintf_s( WCHAR *, size_t, const WCHAR *, va_list);
3960 PALIMPORT DLLEXPORT int __cdecl sscanf_s(const char *, const char *, ...);
3961 PALIMPORT DLLEXPORT errno_t __cdecl _itow_s(int, WCHAR *, size_t, int);
3962
3963 PALIMPORT DLLEXPORT size_t __cdecl PAL_wcslen(const WCHAR *);
3964 PALIMPORT DLLEXPORT int __cdecl PAL_wcscmp(const WCHAR*, const WCHAR*);
3965 PALIMPORT DLLEXPORT int __cdecl PAL_wcsncmp(const WCHAR *, const WCHAR *, size_t);
3966 PALIMPORT DLLEXPORT WCHAR * __cdecl PAL_wcscat(WCHAR *, const WCHAR *);
3967 PALIMPORT WCHAR * __cdecl PAL_wcscpy(WCHAR *, const WCHAR *);
3968 PALIMPORT WCHAR * __cdecl PAL_wcsncpy(WCHAR *, const WCHAR *, size_t);
3969 PALIMPORT DLLEXPORT const WCHAR * __cdecl PAL_wcschr(const WCHAR *, WCHAR);
3970 PALIMPORT DLLEXPORT const WCHAR * __cdecl PAL_wcsrchr(const WCHAR *, WCHAR);
3971 PALIMPORT WCHAR _WConst_return * __cdecl PAL_wcspbrk(const WCHAR *, const WCHAR *);
3972 PALIMPORT DLLEXPORT WCHAR _WConst_return * __cdecl PAL_wcsstr(const WCHAR *, const WCHAR *);
3973 PALIMPORT WCHAR * __cdecl PAL_wcstok(WCHAR *, const WCHAR *);
3974 PALIMPORT DLLEXPORT size_t __cdecl PAL_wcscspn(const WCHAR *, const WCHAR *);
3975 PALIMPORT int __cdecl PAL_swprintf(WCHAR *, const WCHAR *, ...);
3976 PALIMPORT int __cdecl PAL_vswprintf(WCHAR *, const WCHAR *, va_list);
3977 PALIMPORT int __cdecl PAL_swscanf(const WCHAR *, const WCHAR *, ...);
3978 PALIMPORT DLLEXPORT ULONG __cdecl PAL_wcstoul(const WCHAR *, WCHAR **, int);
3979 PALIMPORT double __cdecl PAL_wcstod(const WCHAR *, WCHAR **);
3980
3981 PALIMPORT errno_t __cdecl _wcslwr_s(WCHAR *, size_t sz);
3982 PALIMPORT DLLEXPORT ULONGLONG _wcstoui64(const WCHAR *, WCHAR **, int);
3983 PALIMPORT DLLEXPORT errno_t __cdecl _i64tow_s(long long, WCHAR *, size_t, int);
3984 PALIMPORT int __cdecl _wtoi(const WCHAR *);
3985
3986 #ifdef __cplusplus
3987 extern "C++" {
3988 inline WCHAR *PAL_wcschr(WCHAR* S, WCHAR C)
3989         {return ((WCHAR *)PAL_wcschr((const WCHAR *)S, C)); }
3990 inline WCHAR *PAL_wcsrchr(WCHAR* S, WCHAR C)
3991         {return ((WCHAR *)PAL_wcsrchr((const WCHAR *)S, C)); }
3992 inline WCHAR *PAL_wcspbrk(WCHAR* S, const WCHAR* P)
3993         {return ((WCHAR *)PAL_wcspbrk((const WCHAR *)S, P)); }
3994 inline WCHAR *PAL_wcsstr(WCHAR* S, const WCHAR* P)
3995         {return ((WCHAR *)PAL_wcsstr((const WCHAR *)S, P)); }
3996 }
3997 #endif
3998
3999 #if defined(__llvm__)
4000 #define HAS_ROTL __has_builtin(_rotl)
4001 #define HAS_ROTR __has_builtin(_rotr)
4002 #else
4003 #define HAS_ROTL 0
4004 #define HAS_ROTR 0
4005 #endif
4006
4007 #if !HAS_ROTL
4008 /*++
4009 Function:
4010 _rotl
4011
4012 See MSDN doc.
4013 --*/
4014 EXTERN_C
4015 PALIMPORT
4016 inline
4017 unsigned int __cdecl _rotl(unsigned int value, int shift)
4018 {
4019     unsigned int retval = 0;
4020
4021     shift &= 0x1f;
4022     retval = (value << shift) | (value >> (sizeof(int) * CHAR_BIT - shift));
4023     return retval;
4024 }
4025 #endif // !HAS_ROTL
4026
4027 // On 64 bit unix, make the long an int.
4028 #ifdef HOST_64BIT
4029 #define _lrotl _rotl
4030 #endif // HOST_64BIT
4031
4032 #if !HAS_ROTR
4033
4034 /*++
4035 Function:
4036 _rotr
4037
4038 See MSDN doc.
4039 --*/
4040 EXTERN_C
4041 PALIMPORT
4042 inline
4043 unsigned int __cdecl _rotr(unsigned int value, int shift)
4044 {
4045     unsigned int retval;
4046
4047     shift &= 0x1f;
4048     retval = (value >> shift) | (value << (sizeof(int) * CHAR_BIT - shift));
4049     return retval;
4050 }
4051
4052 #endif // !HAS_ROTR
4053
4054 PALIMPORT int __cdecl abs(int);
4055 // clang complains if this is declared with __int64
4056 PALIMPORT long long __cdecl llabs(long long);
4057 #ifndef PAL_STDCPP_COMPAT
4058
4059 PALIMPORT int __cdecl _finite(double);
4060 PALIMPORT int __cdecl _isnan(double);
4061 PALIMPORT double __cdecl _copysign(double, double);
4062 PALIMPORT double __cdecl acos(double);
4063 PALIMPORT double __cdecl acosh(double);
4064 PALIMPORT double __cdecl asin(double);
4065 PALIMPORT double __cdecl asinh(double);
4066 PALIMPORT double __cdecl atan(double) THROW_DECL;
4067 PALIMPORT double __cdecl atanh(double)
4068 #ifndef __sun
4069 THROW_DECL
4070 #endif
4071 ;
4072 PALIMPORT double __cdecl atan2(double, double);
4073 PALIMPORT double __cdecl cbrt(double)
4074 #ifndef __sun
4075 THROW_DECL
4076 #endif
4077 ;
4078 PALIMPORT double __cdecl ceil(double);
4079 PALIMPORT double __cdecl cos(double);
4080 PALIMPORT double __cdecl cosh(double);
4081 PALIMPORT double __cdecl exp(double);
4082 PALIMPORT double __cdecl fabs(double);
4083 PALIMPORT double __cdecl floor(double);
4084 PALIMPORT double __cdecl fmod(double, double);
4085 PALIMPORT double __cdecl fma(double, double, double);
4086 PALIMPORT int __cdecl ilogb(double);
4087 PALIMPORT double __cdecl log(double);
4088 PALIMPORT double __cdecl log2(double);
4089 PALIMPORT double __cdecl log10(double);
4090 PALIMPORT double __cdecl modf(double, double*);
4091 PALIMPORT double __cdecl pow(double, double);
4092 PALIMPORT double __cdecl sin(double);
4093 PALIMPORT void __cdecl sincos(double, double*, double*);
4094 PALIMPORT double __cdecl sinh(double);
4095 PALIMPORT double __cdecl sqrt(double);
4096 PALIMPORT double __cdecl tan(double);
4097 PALIMPORT double __cdecl tanh(double);
4098
4099 PALIMPORT int __cdecl _finitef(float);
4100 PALIMPORT int __cdecl _isnanf(float);
4101 PALIMPORT float __cdecl _copysignf(float, float);
4102 PALIMPORT float __cdecl acosf(float);
4103 PALIMPORT float __cdecl acoshf(float);
4104 PALIMPORT float __cdecl asinf(float);
4105 PALIMPORT float __cdecl asinhf(float);
4106 PALIMPORT float __cdecl atanf(float)
4107 #ifndef __sun
4108 THROW_DECL
4109 #endif
4110 ;
4111 PALIMPORT float __cdecl atanhf(float)
4112 #ifndef __sun
4113 THROW_DECL
4114 #endif
4115 ;
4116 PALIMPORT float __cdecl atan2f(float, float);
4117 PALIMPORT float __cdecl cbrtf(float)
4118 #ifndef __sun
4119 THROW_DECL
4120 #endif
4121 ;
4122 PALIMPORT float __cdecl ceilf(float);
4123 PALIMPORT float __cdecl cosf(float);
4124 PALIMPORT float __cdecl coshf(float);
4125 PALIMPORT float __cdecl expf(float);
4126 PALIMPORT float __cdecl fabsf(float);
4127 PALIMPORT float __cdecl floorf(float);
4128 PALIMPORT float __cdecl fmodf(float, float);
4129 PALIMPORT float __cdecl fmaf(float, float, float);
4130 PALIMPORT int __cdecl ilogbf(float);
4131 PALIMPORT float __cdecl logf(float);
4132 PALIMPORT float __cdecl log2f(float);
4133 PALIMPORT float __cdecl log10f(float);
4134 PALIMPORT float __cdecl modff(float, float*);
4135 PALIMPORT float __cdecl powf(float, float);
4136 PALIMPORT float __cdecl sinf(float);
4137 PALIMPORT void __cdecl sincosf(float, float*, float*);
4138 PALIMPORT float __cdecl sinhf(float);
4139 PALIMPORT float __cdecl sqrtf(float);
4140 PALIMPORT float __cdecl tanf(float);
4141 PALIMPORT float __cdecl tanhf(float);
4142 #endif // !PAL_STDCPP_COMPAT
4143
4144 #ifndef PAL_STDCPP_COMPAT
4145
4146 #ifdef __cplusplus
4147 extern "C++" {
4148
4149 inline __int64 abs(__int64 _X) {
4150     return llabs(_X);
4151 }
4152
4153 }
4154 #endif
4155
4156 PALIMPORT DLLEXPORT void * __cdecl malloc(size_t);
4157 PALIMPORT DLLEXPORT void   __cdecl free(void *);
4158 PALIMPORT DLLEXPORT void * __cdecl realloc(void *, size_t);
4159 PALIMPORT char * __cdecl _strdup(const char *);
4160
4161 #if defined(_MSC_VER)
4162 #define alloca _alloca
4163 #else
4164 #define _alloca alloca
4165 #endif //_MSC_VER
4166
4167 #define alloca  __builtin_alloca
4168
4169 #define max(a, b) (((a) > (b)) ? (a) : (b))
4170 #define min(a, b) (((a) < (b)) ? (a) : (b))
4171
4172 #endif // !PAL_STDCPP_COMPAT
4173
4174 PALIMPORT PAL_NORETURN void __cdecl exit(int);
4175
4176 #ifndef PAL_STDCPP_COMPAT
4177
4178 PALIMPORT DLLEXPORT void __cdecl qsort(void *, size_t, size_t, int(__cdecl *)(const void *, const void *));
4179 PALIMPORT DLLEXPORT void * __cdecl bsearch(const void *, const void *, size_t, size_t,
4180     int(__cdecl *)(const void *, const void *));
4181
4182 PALIMPORT time_t __cdecl time(time_t *);
4183
4184 #endif // !PAL_STDCPP_COMPAT
4185
4186 PALIMPORT DLLEXPORT int __cdecl _open(const char *szPath, int nFlags, ...);
4187 PALIMPORT DLLEXPORT size_t __cdecl _pread(int fd, void *buf, size_t nbytes, ULONG64 offset);
4188 PALIMPORT DLLEXPORT int __cdecl _close(int);
4189 PALIMPORT DLLEXPORT int __cdecl _flushall();
4190
4191 #ifdef PAL_STDCPP_COMPAT
4192
4193 struct _PAL_FILE;
4194 typedef struct _PAL_FILE PAL_FILE;
4195
4196 #else // PAL_STDCPP_COMPAT
4197
4198 struct _FILE;
4199 typedef struct _FILE FILE;
4200 typedef struct _FILE PAL_FILE;
4201
4202 #define SEEK_SET    0
4203 #define SEEK_CUR    1
4204 #define SEEK_END    2
4205
4206 /* Locale categories */
4207 #define LC_ALL          0
4208 #define LC_COLLATE      1
4209 #define LC_CTYPE        2
4210 #define LC_MONETARY     3
4211 #define LC_NUMERIC      4
4212 #define LC_TIME         5
4213
4214 #define _IOFBF  0       /* setvbuf should set fully buffered */
4215 #define _IOLBF  1       /* setvbuf should set line buffered */
4216 #define _IONBF  2       /* setvbuf should set unbuffered */
4217
4218 #endif // PAL_STDCPP_COMPAT
4219
4220 PALIMPORT int __cdecl PAL_fclose(PAL_FILE *);
4221 PALIMPORT DLLEXPORT int __cdecl PAL_fflush(PAL_FILE *);
4222 PALIMPORT size_t __cdecl PAL_fwrite(const void *, size_t, size_t, PAL_FILE *);
4223 PALIMPORT size_t __cdecl PAL_fread(void *, size_t, size_t, PAL_FILE *);
4224 PALIMPORT char * __cdecl PAL_fgets(char *, int, PAL_FILE *);
4225 PALIMPORT int __cdecl PAL_fputs(const char *, PAL_FILE *);
4226 PALIMPORT DLLEXPORT int __cdecl PAL_fprintf(PAL_FILE *, const char *, ...);
4227 PALIMPORT int __cdecl PAL_vfprintf(PAL_FILE *, const char *, va_list);
4228 PALIMPORT int __cdecl PAL_fseek(PAL_FILE *, LONG, int);
4229 PALIMPORT LONG __cdecl PAL_ftell(PAL_FILE *);
4230 PALIMPORT int __cdecl PAL_ferror(PAL_FILE *);
4231 PALIMPORT PAL_FILE * __cdecl PAL_fopen(const char *, const char *);
4232 PALIMPORT int __cdecl PAL_setvbuf(PAL_FILE *stream, char *, int, size_t);
4233 PALIMPORT DLLEXPORT int __cdecl PAL_fwprintf(PAL_FILE *, const WCHAR *, ...);
4234 PALIMPORT int __cdecl PAL_vfwprintf(PAL_FILE *, const WCHAR *, va_list);
4235 PALIMPORT int __cdecl PAL_wprintf(const WCHAR*, ...);
4236
4237 PALIMPORT int __cdecl _getw(PAL_FILE *);
4238 PALIMPORT int __cdecl _putw(int, PAL_FILE *);
4239 PALIMPORT PAL_FILE * __cdecl _fdopen(int, const char *);
4240 PALIMPORT PAL_FILE * __cdecl _wfopen(const WCHAR *, const WCHAR *);
4241
4242 /* Maximum value that can be returned by the rand function. */
4243
4244 #ifndef PAL_STDCPP_COMPAT
4245 #define RAND_MAX 0x7fff
4246 #endif // !PAL_STDCPP_COMPAT
4247
4248 PALIMPORT int __cdecl rand(void);
4249 PALIMPORT void __cdecl srand(unsigned int);
4250
4251 PALIMPORT DLLEXPORT int __cdecl printf(const char *, ...);
4252 PALIMPORT int __cdecl vprintf(const char *, va_list);
4253
4254 #ifdef _MSC_VER
4255 #define PAL_get_caller _MSC_VER
4256 #else
4257 #define PAL_get_caller 0
4258 #endif
4259
4260 PALIMPORT DLLEXPORT PAL_FILE * __cdecl PAL_get_stdout(int caller);
4261 PALIMPORT PAL_FILE * __cdecl PAL_get_stdin(int caller);
4262 PALIMPORT DLLEXPORT PAL_FILE * __cdecl PAL_get_stderr(int caller);
4263 PALIMPORT DLLEXPORT int * __cdecl PAL_errno(int caller);
4264
4265 #ifdef PAL_STDCPP_COMPAT
4266 #define PAL_stdout (PAL_get_stdout(PAL_get_caller))
4267 #define PAL_stdin  (PAL_get_stdin(PAL_get_caller))
4268 #define PAL_stderr (PAL_get_stderr(PAL_get_caller))
4269 #define PAL_errno   (*PAL_errno(PAL_get_caller))
4270 #else // PAL_STDCPP_COMPAT
4271 #define stdout (PAL_get_stdout(PAL_get_caller))
4272 #define stdin  (PAL_get_stdin(PAL_get_caller))
4273 #define stderr (PAL_get_stderr(PAL_get_caller))
4274 #define errno  (*PAL_errno(PAL_get_caller))
4275 #endif // PAL_STDCPP_COMPAT
4276
4277 PALIMPORT DLLEXPORT char * __cdecl getenv(const char *);
4278 PALIMPORT DLLEXPORT int __cdecl _putenv(const char *);
4279
4280 #define ERANGE          34
4281
4282 PALIMPORT WCHAR __cdecl PAL_ToUpperInvariant(WCHAR);
4283 PALIMPORT WCHAR __cdecl PAL_ToLowerInvariant(WCHAR);
4284
4285 /******************* PAL-specific I/O completion port *****************/
4286
4287 typedef struct _PAL_IOCP_CPU_INFORMATION {
4288     union {
4289         FILETIME ftLastRecordedIdleTime;
4290         FILETIME ftLastRecordedCurrentTime;
4291     } LastRecordedTime;
4292     FILETIME ftLastRecordedKernelTime;
4293     FILETIME ftLastRecordedUserTime;
4294 } PAL_IOCP_CPU_INFORMATION;
4295
4296 PALIMPORT
4297 INT
4298 PALAPI
4299 PAL_GetCPUBusyTime(
4300     IN OUT PAL_IOCP_CPU_INFORMATION *lpPrevCPUInfo);
4301
4302 /****************PAL Perf functions for PInvoke*********************/
4303 #if PAL_PERF
4304 PALIMPORT
4305 VOID
4306 PALAPI
4307 PAL_EnableProcessProfile();
4308
4309 PALIMPORT
4310 VOID
4311 PALAPI
4312 PAL_DisableProcessProfile();
4313
4314 PALIMPORT
4315 BOOL
4316 PALAPI
4317 PAL_IsProcessProfileEnabled();
4318
4319 PALIMPORT
4320 INT64
4321 PALAPI
4322 PAL_GetCpuTickCount();
4323 #endif // PAL_PERF
4324
4325 /******************* PAL functions for SIMD extensions *****************/
4326
4327 PALIMPORT
4328 unsigned int _mm_getcsr(void);
4329
4330 PALIMPORT
4331 void _mm_setcsr(unsigned int i);
4332
4333 /******************* PAL functions for CPU capability detection *******/
4334
4335 #ifdef  __cplusplus
4336
4337 class CORJIT_FLAGS;
4338
4339 PALIMPORT
4340 VOID
4341 PALAPI
4342 PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags);
4343
4344 #endif
4345
4346 #ifdef __cplusplus
4347
4348 PALIMPORT
4349 VOID
4350 PALAPI
4351 PAL_FreeExceptionRecords(
4352   IN EXCEPTION_RECORD *exceptionRecord,
4353   IN CONTEXT *contextRecord);
4354
4355 #define EXCEPTION_CONTINUE_SEARCH   0
4356 #define EXCEPTION_EXECUTE_HANDLER   1
4357 #define EXCEPTION_CONTINUE_EXECUTION -1
4358
4359 struct PAL_SEHException
4360 {
4361 private:
4362     static const SIZE_T NoTargetFrameSp = (SIZE_T)SIZE_MAX;
4363
4364     void Move(PAL_SEHException& ex)
4365     {
4366         ExceptionPointers.ExceptionRecord = ex.ExceptionPointers.ExceptionRecord;
4367         ExceptionPointers.ContextRecord = ex.ExceptionPointers.ContextRecord;
4368         TargetFrameSp = ex.TargetFrameSp;
4369         RecordsOnStack = ex.RecordsOnStack;
4370
4371         ex.Clear();
4372     }
4373
4374     void FreeRecords()
4375     {
4376         if (ExceptionPointers.ExceptionRecord != NULL && !RecordsOnStack )
4377         {
4378             PAL_FreeExceptionRecords(ExceptionPointers.ExceptionRecord, ExceptionPointers.ContextRecord);
4379             ExceptionPointers.ExceptionRecord = NULL;
4380             ExceptionPointers.ContextRecord = NULL;
4381         }
4382     }
4383
4384 public:
4385     EXCEPTION_POINTERS ExceptionPointers;
4386     // Target frame stack pointer set before the 2nd pass.
4387     SIZE_T TargetFrameSp;
4388     bool RecordsOnStack;
4389
4390     PAL_SEHException(EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContextRecord, bool onStack = false)
4391     {
4392         ExceptionPointers.ExceptionRecord = pExceptionRecord;
4393         ExceptionPointers.ContextRecord = pContextRecord;
4394         TargetFrameSp = NoTargetFrameSp;
4395         RecordsOnStack = onStack;
4396     }
4397
4398     PAL_SEHException()
4399     {
4400         Clear();
4401     }
4402
4403     // The copy constructor and copy assignment operators are deleted so that the PAL_SEHException
4404     // can never be copied, only moved. This enables simple lifetime management of the exception and
4405     // context records, since there is always just one PAL_SEHException instance referring to the same records.
4406     PAL_SEHException(const PAL_SEHException& ex) = delete;
4407     PAL_SEHException& operator=(const PAL_SEHException& ex) = delete;
4408
4409     PAL_SEHException(PAL_SEHException&& ex)
4410     {
4411         Move(ex);
4412     }
4413
4414     PAL_SEHException& operator=(PAL_SEHException&& ex)
4415     {
4416         FreeRecords();
4417         Move(ex);
4418         return *this;
4419     }
4420
4421     ~PAL_SEHException()
4422     {
4423         FreeRecords();
4424     }
4425
4426     void Clear()
4427     {
4428         ExceptionPointers.ExceptionRecord = NULL;
4429         ExceptionPointers.ContextRecord = NULL;
4430         TargetFrameSp = NoTargetFrameSp;
4431         RecordsOnStack = false;
4432     }
4433
4434     CONTEXT* GetContextRecord()
4435     {
4436         return ExceptionPointers.ContextRecord;
4437     }
4438
4439     EXCEPTION_RECORD* GetExceptionRecord()
4440     {
4441         return ExceptionPointers.ExceptionRecord;
4442     }
4443
4444     bool IsFirstPass()
4445     {
4446         return (TargetFrameSp == NoTargetFrameSp);
4447     }
4448
4449     void SecondPassDone()
4450     {
4451         TargetFrameSp = NoTargetFrameSp;
4452     }
4453 };
4454
4455 typedef BOOL (*PHARDWARE_EXCEPTION_HANDLER)(PAL_SEHException* ex);
4456 typedef BOOL (*PHARDWARE_EXCEPTION_SAFETY_CHECK_FUNCTION)(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord);
4457 typedef VOID (*PTERMINATION_REQUEST_HANDLER)(int terminationExitCode);
4458 typedef DWORD (*PGET_GCMARKER_EXCEPTION_CODE)(LPVOID ip);
4459
4460 PALIMPORT
4461 VOID
4462 PALAPI
4463 PAL_SetHardwareExceptionHandler(
4464     IN PHARDWARE_EXCEPTION_HANDLER exceptionHandler,
4465     IN PHARDWARE_EXCEPTION_SAFETY_CHECK_FUNCTION exceptionCheckFunction);
4466
4467 PALIMPORT
4468 VOID
4469 PALAPI
4470 PAL_SetGetGcMarkerExceptionCode(
4471     IN PGET_GCMARKER_EXCEPTION_CODE getGcMarkerExceptionCode);
4472
4473 PALIMPORT
4474 VOID
4475 PALAPI
4476 PAL_ThrowExceptionFromContext(
4477     IN CONTEXT* context,
4478     IN PAL_SEHException* ex);
4479
4480 PALIMPORT
4481 VOID
4482 PALAPI
4483 PAL_SetTerminationRequestHandler(
4484     IN PTERMINATION_REQUEST_HANDLER terminationRequestHandler);
4485
4486 PALIMPORT
4487 VOID
4488 PALAPI
4489 PAL_CatchHardwareExceptionHolderEnter();
4490
4491 PALIMPORT
4492 VOID
4493 PALAPI
4494 PAL_CatchHardwareExceptionHolderExit();
4495
4496 //
4497 // This holder is used to indicate that a hardware
4498 // exception should be raised as a C++ exception
4499 // to better emulate SEH on the xplat platforms.
4500 //
4501 class CatchHardwareExceptionHolder
4502 {
4503 public:
4504     CatchHardwareExceptionHolder()
4505     {
4506         PAL_CatchHardwareExceptionHolderEnter();
4507     }
4508
4509     ~CatchHardwareExceptionHolder()
4510     {
4511         PAL_CatchHardwareExceptionHolderExit();
4512     }
4513
4514     static bool IsEnabled();
4515 };
4516
4517 //
4518 // NOTE: This is only defined in one PAL test.
4519 //
4520 #ifdef FEATURE_ENABLE_HARDWARE_EXCEPTIONS
4521 #define HardwareExceptionHolder CatchHardwareExceptionHolder __catchHardwareException;
4522 #else
4523 #define HardwareExceptionHolder
4524 #endif // FEATURE_ENABLE_HARDWARE_EXCEPTIONS
4525
4526 class NativeExceptionHolderBase;
4527
4528 PALIMPORT
4529 PALAPI
4530 NativeExceptionHolderBase **
4531 PAL_GetNativeExceptionHolderHead();
4532
4533 extern "C++" {
4534
4535 //
4536 // This is the base class of native exception holder used to provide
4537 // the filter function to the exception dispatcher. This allows the
4538 // filter to be called during the first pass to better emulate SEH
4539 // the xplat platforms that only have C++ exception support.
4540 //
4541 class NativeExceptionHolderBase
4542 {
4543     // Save the address of the holder head so the destructor
4544     // doesn't have access the slow (on Linux) TLS value again.
4545     NativeExceptionHolderBase **m_head;
4546
4547     // The next holder on the stack
4548     NativeExceptionHolderBase *m_next;
4549
4550 protected:
4551     NativeExceptionHolderBase()
4552     {
4553         m_head = nullptr;
4554         m_next = nullptr;
4555     }
4556
4557     ~NativeExceptionHolderBase()
4558     {
4559         // Only destroy if Push was called
4560         if (m_head != nullptr)
4561         {
4562             *m_head = m_next;
4563             m_head = nullptr;
4564             m_next = nullptr;
4565         }
4566     }
4567
4568 public:
4569     // Calls the holder's filter handler.
4570     virtual EXCEPTION_DISPOSITION InvokeFilter(PAL_SEHException& ex) = 0;
4571
4572     // Adds the holder to the "stack" of holders. This is done explicitly instead
4573     // of in the constructor was to avoid the mess of move constructors combined
4574     // with return value optimization (in CreateHolder).
4575     void Push()
4576     {
4577         NativeExceptionHolderBase **head = PAL_GetNativeExceptionHolderHead();
4578         m_head = head;
4579         m_next = *head;
4580         *head = this;
4581     }
4582
4583     // Given the currentHolder and locals stack range find the next holder starting with this one
4584     // To find the first holder, pass nullptr as the currentHolder.
4585     static NativeExceptionHolderBase *FindNextHolder(NativeExceptionHolderBase *currentHolder, PVOID frameLowAddress, PVOID frameHighAddress);
4586 };
4587
4588 //
4589 // This is the second part of the native exception filter holder. It is
4590 // templated because the lambda used to wrap the exception filter is a
4591 // unknown type.
4592 //
4593 template<class FilterType>
4594 class NativeExceptionHolder : public NativeExceptionHolderBase
4595 {
4596     FilterType* m_exceptionFilter;
4597
4598 public:
4599     NativeExceptionHolder(FilterType* exceptionFilter)
4600         : NativeExceptionHolderBase()
4601     {
4602         m_exceptionFilter = exceptionFilter;
4603     }
4604
4605     virtual EXCEPTION_DISPOSITION InvokeFilter(PAL_SEHException& ex)
4606     {
4607         return (*m_exceptionFilter)(ex);
4608     }
4609 };
4610
4611 //
4612 // This is a native exception holder that is used when the catch catches
4613 // all exceptions.
4614 //
4615 class NativeExceptionHolderCatchAll : public NativeExceptionHolderBase
4616 {
4617
4618 public:
4619     NativeExceptionHolderCatchAll()
4620         : NativeExceptionHolderBase()
4621     {
4622     }
4623
4624     virtual EXCEPTION_DISPOSITION InvokeFilter(PAL_SEHException& ex)
4625     {
4626         return EXCEPTION_EXECUTE_HANDLER;
4627     }
4628 };
4629
4630 // This is a native exception holder that doesn't catch any exceptions.
4631 class NativeExceptionHolderNoCatch : public NativeExceptionHolderBase
4632 {
4633
4634 public:
4635     NativeExceptionHolderNoCatch()
4636         : NativeExceptionHolderBase()
4637     {
4638     }
4639
4640     virtual EXCEPTION_DISPOSITION InvokeFilter(PAL_SEHException& ex)
4641     {
4642         return EXCEPTION_CONTINUE_SEARCH;
4643     }
4644 };
4645
4646 //
4647 // This factory class for the native exception holder is necessary because
4648 // templated functions don't need the explicit type parameter and can infer
4649 // the template type from the parameter.
4650 //
4651 class NativeExceptionHolderFactory
4652 {
4653 public:
4654     template<class FilterType>
4655     static NativeExceptionHolder<FilterType> CreateHolder(FilterType* exceptionFilter)
4656     {
4657         return NativeExceptionHolder<FilterType>(exceptionFilter);
4658     }
4659 };
4660
4661 // Start of a try block for exceptions raised by RaiseException
4662 #define PAL_TRY(__ParamType, __paramDef, __paramRef)                            \
4663 {                                                                               \
4664     __ParamType __param = __paramRef;                                           \
4665     auto tryBlock = [](__ParamType __paramDef)                                  \
4666     {
4667
4668 // Start of an exception handler. If an exception raised by the RaiseException
4669 // occurs in the try block and the disposition is EXCEPTION_EXECUTE_HANDLER,
4670 // the handler code is executed. If the disposition is EXCEPTION_CONTINUE_SEARCH,
4671 // the exception is rethrown. The EXCEPTION_CONTINUE_EXECUTION disposition is
4672 // not supported.
4673 #define PAL_EXCEPT(dispositionExpression)                                       \
4674     };                                                                          \
4675     const bool isFinally = false;                                               \
4676     auto finallyBlock = []() {};                                                \
4677     EXCEPTION_DISPOSITION disposition = EXCEPTION_CONTINUE_EXECUTION;           \
4678     auto exceptionFilter = [&disposition, &__param](PAL_SEHException& ex)       \
4679     {                                                                           \
4680         (void)__param;                                                          \
4681         disposition = dispositionExpression;                                    \
4682         _ASSERTE(disposition != EXCEPTION_CONTINUE_EXECUTION);                  \
4683         return disposition;                                                     \
4684     };                                                                          \
4685     try                                                                         \
4686     {                                                                           \
4687         HardwareExceptionHolder                                                 \
4688         auto __exceptionHolder = NativeExceptionHolderFactory::CreateHolder(&exceptionFilter); \
4689         __exceptionHolder.Push();                                               \
4690         tryBlock(__param);                                                      \
4691     }                                                                           \
4692     catch (PAL_SEHException& ex)                                                \
4693     {                                                                           \
4694         if (disposition == EXCEPTION_CONTINUE_EXECUTION)                        \
4695         {                                                                       \
4696             exceptionFilter(ex);                                                \
4697         }                                                                       \
4698         if (disposition == EXCEPTION_CONTINUE_SEARCH)                           \
4699         {                                                                       \
4700             throw;                                                              \
4701         }                                                                       \
4702         ex.SecondPassDone();
4703
4704 // Start of an exception handler. It works the same way as the PAL_EXCEPT except
4705 // that the disposition is obtained by calling the specified filter.
4706 #define PAL_EXCEPT_FILTER(filter) PAL_EXCEPT(filter(&ex.ExceptionPointers, __param))
4707
4708 // Start of a finally block. The finally block is executed both when the try block
4709 // finishes or when an exception is raised using the RaiseException in it.
4710 #define PAL_FINALLY                     \
4711     };                                  \
4712     const bool isFinally = true;        \
4713     auto finallyBlock = [&]()           \
4714     {
4715
4716 // End of an except or a finally block.
4717 #define PAL_ENDTRY                      \
4718     };                                  \
4719     if (isFinally)                      \
4720     {                                   \
4721         try                             \
4722         {                               \
4723             tryBlock(__param);          \
4724         }                               \
4725         catch (...)                     \
4726         {                               \
4727             finallyBlock();             \
4728             throw;                      \
4729         }                               \
4730         finallyBlock();                 \
4731     }                                   \
4732 }
4733
4734 } // extern "C++"
4735
4736 #define PAL_CPP_THROW(type, obj) { throw obj; }
4737 #define PAL_CPP_RETHROW { throw; }
4738 #define PAL_CPP_TRY                     try { HardwareExceptionHolder
4739 #define PAL_CPP_CATCH_EXCEPTION(ident)  } catch (Exception *ident) {
4740 #define PAL_CPP_CATCH_EXCEPTION_NOARG   } catch (Exception *) {
4741 #define PAL_CPP_CATCH_DERIVED(type, ident) } catch (type *ident) {
4742 #define PAL_CPP_CATCH_ALL               } catch (...) {                                           \
4743                                             try { throw; }                                        \
4744                                             catch (PAL_SEHException& ex) { ex.SecondPassDone(); } \
4745                                             catch (...) {}
4746
4747 #define PAL_CPP_ENDTRY                  }
4748
4749 #ifdef _MSC_VER
4750 #pragma warning(disable:4611) // interaction between '_setjmp' and C++ object destruction is non-portable
4751 #endif
4752
4753 #define PAL_TRY_FOR_DLLMAIN(ParamType, paramDef, paramRef, _reason) PAL_TRY(ParamType, paramDef, paramRef)
4754
4755 #endif // __cplusplus
4756
4757 // Platform-specific library naming
4758 //
4759 #ifdef __APPLE__
4760 #define MAKEDLLNAME_W(name) u"lib" name u".dylib"
4761 #define MAKEDLLNAME_A(name)  "lib" name  ".dylib"
4762 #else
4763 #define MAKEDLLNAME_W(name) u"lib" name u".so"
4764 #define MAKEDLLNAME_A(name)  "lib" name  ".so"
4765 #endif
4766
4767 #ifdef UNICODE
4768 #define MAKEDLLNAME(x) MAKEDLLNAME_W(x)
4769 #else
4770 #define MAKEDLLNAME(x) MAKEDLLNAME_A(x)
4771 #endif
4772
4773 #define PAL_SHLIB_PREFIX    "lib"
4774 #define PAL_SHLIB_PREFIX_W  u"lib"
4775
4776 #if __APPLE__
4777 #define PAL_SHLIB_SUFFIX    ".dylib"
4778 #define PAL_SHLIB_SUFFIX_W  u".dylib"
4779 #else
4780 #define PAL_SHLIB_SUFFIX    ".so"
4781 #define PAL_SHLIB_SUFFIX_W  u".so"
4782 #endif
4783
4784 #define DBG_EXCEPTION_HANDLED            ((DWORD   )0x00010001L)
4785 #define DBG_CONTINUE                     ((DWORD   )0x00010002L)
4786 #define DBG_EXCEPTION_NOT_HANDLED        ((DWORD   )0x80010001L)
4787
4788 #define DBG_TERMINATE_THREAD             ((DWORD   )0x40010003L)
4789 #define DBG_TERMINATE_PROCESS            ((DWORD   )0x40010004L)
4790 #define DBG_CONTROL_C                    ((DWORD   )0x40010005L)
4791 #define DBG_RIPEXCEPTION                 ((DWORD   )0x40010007L)
4792 #define DBG_CONTROL_BREAK                ((DWORD   )0x40010008L)
4793 #define DBG_COMMAND_EXCEPTION            ((DWORD   )0x40010009L)
4794
4795 #define STATUS_USER_APC                  ((DWORD   )0x000000C0L)
4796 #define STATUS_GUARD_PAGE_VIOLATION      ((DWORD   )0x80000001L)
4797 #define STATUS_DATATYPE_MISALIGNMENT     ((DWORD   )0x80000002L)
4798 #define STATUS_BREAKPOINT                ((DWORD   )0x80000003L)
4799 #define STATUS_SINGLE_STEP               ((DWORD   )0x80000004L)
4800 #define STATUS_LONGJUMP                  ((DWORD   )0x80000026L)
4801 #define STATUS_UNWIND_CONSOLIDATE        ((DWORD   )0x80000029L)
4802 #define STATUS_ACCESS_VIOLATION          ((DWORD   )0xC0000005L)
4803 #define STATUS_IN_PAGE_ERROR             ((DWORD   )0xC0000006L)
4804 #define STATUS_INVALID_HANDLE            ((DWORD   )0xC0000008L)
4805 #define STATUS_NO_MEMORY                 ((DWORD   )0xC0000017L)
4806 #define STATUS_ILLEGAL_INSTRUCTION       ((DWORD   )0xC000001DL)
4807 #define STATUS_NONCONTINUABLE_EXCEPTION  ((DWORD   )0xC0000025L)
4808 #define STATUS_INVALID_DISPOSITION       ((DWORD   )0xC0000026L)
4809 #define STATUS_ARRAY_BOUNDS_EXCEEDED     ((DWORD   )0xC000008CL)
4810 #define STATUS_FLOAT_DENORMAL_OPERAND    ((DWORD   )0xC000008DL)
4811 #define STATUS_FLOAT_DIVIDE_BY_ZERO      ((DWORD   )0xC000008EL)
4812 #define STATUS_FLOAT_INEXACT_RESULT      ((DWORD   )0xC000008FL)
4813 #define STATUS_FLOAT_INVALID_OPERATION   ((DWORD   )0xC0000090L)
4814 #define STATUS_FLOAT_OVERFLOW            ((DWORD   )0xC0000091L)
4815 #define STATUS_FLOAT_STACK_CHECK         ((DWORD   )0xC0000092L)
4816 #define STATUS_FLOAT_UNDERFLOW           ((DWORD   )0xC0000093L)
4817 #define STATUS_INTEGER_DIVIDE_BY_ZERO    ((DWORD   )0xC0000094L)
4818 #define STATUS_INTEGER_OVERFLOW          ((DWORD   )0xC0000095L)
4819 #define STATUS_PRIVILEGED_INSTRUCTION    ((DWORD   )0xC0000096L)
4820 #define STATUS_STACK_OVERFLOW            ((DWORD   )0xC00000FDL)
4821 #define STATUS_CONTROL_C_EXIT            ((DWORD   )0xC000013AL)
4822
4823 #define WAIT_IO_COMPLETION                  STATUS_USER_APC
4824
4825 #define EXCEPTION_ACCESS_VIOLATION          STATUS_ACCESS_VIOLATION
4826 #define EXCEPTION_DATATYPE_MISALIGNMENT     STATUS_DATATYPE_MISALIGNMENT
4827 #define EXCEPTION_BREAKPOINT                STATUS_BREAKPOINT
4828 #define EXCEPTION_SINGLE_STEP               STATUS_SINGLE_STEP
4829 #define EXCEPTION_ARRAY_BOUNDS_EXCEEDED     STATUS_ARRAY_BOUNDS_EXCEEDED
4830 #define EXCEPTION_FLT_DENORMAL_OPERAND      STATUS_FLOAT_DENORMAL_OPERAND
4831 #define EXCEPTION_FLT_DIVIDE_BY_ZERO        STATUS_FLOAT_DIVIDE_BY_ZERO
4832 #define EXCEPTION_FLT_INEXACT_RESULT        STATUS_FLOAT_INEXACT_RESULT
4833 #define EXCEPTION_FLT_INVALID_OPERATION     STATUS_FLOAT_INVALID_OPERATION
4834 #define EXCEPTION_FLT_OVERFLOW              STATUS_FLOAT_OVERFLOW
4835 #define EXCEPTION_FLT_STACK_CHECK           STATUS_FLOAT_STACK_CHECK
4836 #define EXCEPTION_FLT_UNDERFLOW             STATUS_FLOAT_UNDERFLOW
4837 #define EXCEPTION_INT_DIVIDE_BY_ZERO        STATUS_INTEGER_DIVIDE_BY_ZERO
4838 #define EXCEPTION_INT_OVERFLOW              STATUS_INTEGER_OVERFLOW
4839 #define EXCEPTION_PRIV_INSTRUCTION          STATUS_PRIVILEGED_INSTRUCTION
4840 #define EXCEPTION_IN_PAGE_ERROR             STATUS_IN_PAGE_ERROR
4841 #define EXCEPTION_ILLEGAL_INSTRUCTION       STATUS_ILLEGAL_INSTRUCTION
4842 #define EXCEPTION_NONCONTINUABLE_EXCEPTION  STATUS_NONCONTINUABLE_EXCEPTION
4843 #define EXCEPTION_STACK_OVERFLOW            STATUS_STACK_OVERFLOW
4844 #define EXCEPTION_INVALID_DISPOSITION       STATUS_INVALID_DISPOSITION
4845 #define EXCEPTION_GUARD_PAGE                STATUS_GUARD_PAGE_VIOLATION
4846 #define EXCEPTION_INVALID_HANDLE            STATUS_INVALID_HANDLE
4847
4848 #define CONTROL_C_EXIT                      STATUS_CONTROL_C_EXIT
4849
4850 /******************* HRESULT types ****************************************/
4851
4852 #define FACILITY_WINDOWS                 8
4853 #define FACILITY_URT                     19
4854 #define FACILITY_UMI                     22
4855 #define FACILITY_SXS                     23
4856 #define FACILITY_STORAGE                 3
4857 #define FACILITY_SSPI                    9
4858 #define FACILITY_SCARD                   16
4859 #define FACILITY_SETUPAPI                15
4860 #define FACILITY_SECURITY                9
4861 #define FACILITY_RPC                     1
4862 #define FACILITY_WIN32                   7
4863 #define FACILITY_CONTROL                 10
4864 #define FACILITY_NULL                    0
4865 #define FACILITY_MSMQ                    14
4866 #define FACILITY_MEDIASERVER             13
4867 #define FACILITY_INTERNET                12
4868 #define FACILITY_ITF                     4
4869 #define FACILITY_DPLAY                   21
4870 #define FACILITY_DISPATCH                2
4871 #define FACILITY_COMPLUS                 17
4872 #define FACILITY_CERT                    11
4873 #define FACILITY_ACS                     20
4874 #define FACILITY_AAF                     18
4875
4876 #define NO_ERROR 0L
4877
4878 #define SEVERITY_SUCCESS    0
4879 #define SEVERITY_ERROR      1
4880
4881 #define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
4882 #define FAILED(Status) ((HRESULT)(Status)<0)
4883 #define IS_ERROR(Status) ((ULONG)(Status) >> 31 == SEVERITY_ERROR) // diff from win32
4884 #define HRESULT_CODE(hr)    ((hr) & 0xFFFF)
4885 #define SCODE_CODE(sc)      ((sc) & 0xFFFF)
4886 #define HRESULT_FACILITY(hr)  (((hr) >> 16) & 0x1fff)
4887 #define SCODE_FACILITY(sc)    (((sc) >> 16) & 0x1fff)
4888 #define HRESULT_SEVERITY(hr)  (((hr) >> 31) & 0x1)
4889 #define SCODE_SEVERITY(sc)    (((sc) >> 31) & 0x1)
4890
4891 // both macros diff from Win32
4892 #define MAKE_HRESULT(sev,fac,code) \
4893     ((HRESULT) (((ULONG)(sev)<<31) | ((ULONG)(fac)<<16) | ((ULONG)(code))) )
4894 #define MAKE_SCODE(sev,fac,code) \
4895     ((SCODE) (((ULONG)(sev)<<31) | ((ULONG)(fac)<<16) | ((LONG)(code))) )
4896
4897 #define FACILITY_NT_BIT                 0x10000000
4898 #define HRESULT_FROM_WIN32(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))
4899 #define __HRESULT_FROM_WIN32(x) HRESULT_FROM_WIN32(x)
4900
4901 #define HRESULT_FROM_NT(x)      ((HRESULT) ((x) | FACILITY_NT_BIT))
4902
4903 #ifdef  __cplusplus
4904 }
4905 #endif
4906
4907 #endif // __PAL_H__