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