1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
12 CoreCLR Platform Adaptation Layer (PAL) header file. This file
13 defines all types and API calls required by the CoreCLR when
14 compiled for Unix-like systems.
16 Defines which control the behavior of this include file:
17 UNICODE - define it to set the Ansi/Unicode neutral names to
18 be the ...W names. Otherwise the neutral names default
20 PAL_IMPLEMENTATION - define it when implementing the PAL. Otherwise
21 leave it undefined when consuming the PAL.
23 Note: some fields in structs have been renamed from the original
24 SDK documentation names, with _PAL_Undefined appended. This leaves
25 the structure layout identical to its Win32 version, but prevents
26 PAL consumers from inadvertently referencing undefined fields.
28 If you want to add a PAL_ wrapper function to a native function in
29 here, you also need to edit palinternal.h and win32pal.h.
38 #ifdef PAL_STDCPP_COMPAT
50 #include <sys/types.h>
58 // This macro is used to standardize the wide character string literals between UNIX and Windows.
59 // Unix L"" is UTF32, and on windows it's UTF16. Because of built-in assumptions on the size
60 // of string literals, it's important to match behaviour between Unix and Windows. Unix will be defined
64 // Undefine the QUOTE_MACRO_L helper and redefine it in terms of u.
65 // The reason that we do this is that quote macro is defined in ndp\common\inc,
66 // not inside of coreclr sources.
68 #define QUOTE_MACRO_L(x) QUOTE_MACRO_u(x)
69 #define QUOTE_MACRO_u_HELPER(x) u###x
70 #define QUOTE_MACRO_u(x) QUOTE_MACRO_u_HELPER(x)
72 #include <pal_error.h>
73 #include <pal_mstypes.h>
75 // Native system libray handle.
76 // On Unix systems, NATIVE_LIBRARY_HANDLE type represents a library handle not registered with the PAL.
77 typedef PVOID NATIVE_LIBRARY_HANDLE;
79 /******************* Processor-specific glue *****************************/
83 #if defined(__i686__) && !defined(_M_IX86)
85 #elif defined(__i586__) && !defined(_M_IX86)
87 #elif defined(__i486__) && !defined(_M_IX86)
89 #elif defined(__i386__) && !defined(_M_IX86)
91 #elif defined(__x86_64__) && !defined(_M_AMD64)
93 #elif defined(__arm__) && !defined(_M_ARM)
95 #elif defined(__aarch64__) && !defined(_M_ARM64)
99 #if defined(_M_IX86) && !defined(HOST_X86)
101 #elif defined(_M_AMD64) && !defined(HOST_AMD64)
103 #elif defined(_M_ARM) && !defined(HOST_ARM)
105 #elif defined(_M_ARM64) && !defined(HOST_ARM64)
111 /******************* ABI-specific glue *******************************/
114 #define _MAX_PATH 260
115 #define _MAX_DRIVE 3 /* max. length of drive component */
116 #define _MAX_DIR 256 /* max. length of path component */
117 #define _MAX_FNAME 256 /* max. length of file name component */
118 #define _MAX_EXT 256 /* max. length of extension component */
120 // In some Win32 APIs MAX_PATH is used for file names (even though 256 is the normal file system limit)
121 // use _MAX_PATH_FNAME to indicate these cases
122 #define MAX_PATH_FNAME MAX_PATH
123 #define MAX_LONGPATH 1024 /* max. length of full pathname */
125 #define MAXSHORT 0x7fff
126 #define MAXLONG 0x7fffffff
128 #define MAXDWORD 0xffffffff
132 // Note that the named locale APIs (eg CompareStringExEx) are recommended.
135 #define LANG_ENGLISH 0x09
137 /******************* Compiler-specific glue *******************************/
139 #if defined(_MSC_VER) || !defined(__cplusplus)
142 #define THROW_DECL throw()
144 #endif // !THROW_DECL
146 #if defined(_MSC_VER)
147 #define DECLSPEC_ALIGN(x) __declspec(align(x))
149 #define DECLSPEC_ALIGN(x) __attribute__ ((aligned(x)))
152 #define DECLSPEC_NORETURN PAL_NORETURN
154 #ifdef __clang_analyzer__
155 #define ANALYZER_NORETURN __attribute((analyzer_noreturn))
157 #define ANALYZER_NORETURN
160 #define EMPTY_BASES_DECL
163 #if !defined(_MSC_VER) || defined(SOURCE_FORMATTING)
164 #define __assume(x) (void)0
165 #define __annotation(x)
172 #define FORCEINLINE inline
174 #define FORCEINLINE __forceinline
178 #ifndef NOOPT_ATTRIBUTE
179 #if defined(__llvm__)
180 #define NOOPT_ATTRIBUTE optnone
181 #elif defined(__GNUC__)
182 #define NOOPT_ATTRIBUTE optimize("O0")
186 #ifndef NODEBUG_ATTRIBUTE
187 #if defined(__llvm__)
188 #define NODEBUG_ATTRIBUTE __nodebug__
189 #elif defined(__GNUC__)
190 #define NODEBUG_ATTRIBUTE __artificial__
194 #ifndef __has_cpp_attribute
195 #define __has_cpp_attribute(x) (0)
199 #if __has_cpp_attribute(fallthrough)
200 #define FALLTHROUGH [[fallthrough]]
201 #else // __has_cpp_attribute(fallthrough)
203 #endif // __has_cpp_attribute(fallthrough)
204 #endif // FALLTHROUGH
206 #ifndef PAL_STDCPP_COMPAT
210 typedef __builtin_va_list va_list;
212 /* We should consider if the va_arg definition here is actually necessary.
213 Could we use the standard va_arg definition? */
215 #define va_start __builtin_va_start
216 #define va_arg __builtin_va_arg
218 #define va_copy __builtin_va_copy
219 #define va_end __builtin_va_end
225 typedef char * va_list;
227 #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
232 #define _ADDRESSOF(v) ( &reinterpret_cast<const char &>(v) )
234 #define _ADDRESSOF(v) ( &(v) )
237 #define _crt_va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
238 #define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
239 #define _crt_va_end(ap) ( ap = (va_list)0 )
241 #define va_start _crt_va_start
242 #define va_arg _crt_va_arg
243 #define va_end _crt_va_end
247 #define va_start(ap,v) (ap = (va_list) (&(v)) + _INTSIZEOF(v))
248 #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
253 #define va_copy(dest,src) (dest = src)
259 #define SCHAR_MIN (-128)
260 #define SCHAR_MAX 127
261 #define UCHAR_MAX 0xff
263 #define SHRT_MIN (-32768)
264 #define SHRT_MAX 32767
265 #define USHRT_MAX 0xffff
267 #define INT_MIN (-2147483647 - 1)
268 #define INT_MAX 2147483647
269 #define UINT_MAX 0xffffffff
271 // LONG_MIN, LONG_MAX, ULONG_MAX -- use INT32_MIN etc. instead.
273 #define FLT_MAX 3.402823466e+38F
274 #define DBL_MAX 1.7976931348623157e+308
276 #endif // !PAL_STDCPP_COMPAT
278 /******************* PAL-Specific Entrypoints *****************************/
280 #define IsDebuggerPresent PAL_IsDebuggerPresent
285 PAL_IsDebuggerPresent();
287 /* minimum signed 64 bit value */
288 #define _I64_MIN (I64(-9223372036854775807) - 1)
289 /* maximum signed 64 bit value */
290 #define _I64_MAX I64(9223372036854775807)
291 /* maximum unsigned 64 bit value */
292 #define _UI64_MAX UI64(0xffffffffffffffff)
294 #define _I8_MAX SCHAR_MAX
295 #define _I8_MIN SCHAR_MIN
296 #define _I16_MAX SHRT_MAX
297 #define _I16_MIN SHRT_MIN
298 #define _I32_MAX INT_MAX
299 #define _I32_MIN INT_MIN
300 #define _UI8_MAX UCHAR_MAX
301 #define _UI8_MIN UCHAR_MIN
302 #define _UI16_MAX USHRT_MAX
303 #define _UI16_MIN USHRT_MIN
304 #define _UI32_MAX UINT_MAX
305 #define _UI32_MIN UINT_MIN
309 #if defined(__cplusplus)
312 #define NULL ((PVOID)0)
315 #if defined(PAL_STDCPP_COMPAT) && !defined(__cplusplus)
317 #endif // defined(PAL_STDCPP_COMPAT) && !defined(__cplusplus)
319 #ifndef PAL_STDCPP_COMPAT
321 #if HOST_64BIT || _MSC_VER >= 1400
322 typedef __int64 time_t;
326 #define _TIME_T_DEFINED
327 #endif // !PAL_STDCPP_COMPAT
329 #define DLL_PROCESS_ATTACH 1
330 #define DLL_THREAD_ATTACH 2
331 #define DLL_THREAD_DETACH 3
332 #define DLL_PROCESS_DETACH 0
334 #define PAL_INITIALIZE_NONE 0x00
335 #define PAL_INITIALIZE_SYNC_THREAD 0x01
336 #define PAL_INITIALIZE_EXEC_ALLOCATOR 0x02
337 #define PAL_INITIALIZE_STD_HANDLES 0x04
338 #define PAL_INITIALIZE_REGISTER_SIGTERM_HANDLER 0x08
339 #define PAL_INITIALIZE_DEBUGGER_EXCEPTIONS 0x10
340 #define PAL_INITIALIZE_ENSURE_STACK_SIZE 0x20
341 #define PAL_INITIALIZE_REGISTER_SIGNALS 0x40
343 // PAL_Initialize() flags
344 #define PAL_INITIALIZE (PAL_INITIALIZE_SYNC_THREAD | \
345 PAL_INITIALIZE_STD_HANDLES)
347 // PAL_InitializeDLL() flags - don't start any of the helper threads or register any exceptions
348 #define PAL_INITIALIZE_DLL PAL_INITIALIZE_NONE
350 // PAL_InitializeCoreCLR() flags
351 #define PAL_INITIALIZE_CORECLR (PAL_INITIALIZE | \
352 PAL_INITIALIZE_EXEC_ALLOCATOR | \
353 PAL_INITIALIZE_REGISTER_SIGTERM_HANDLER | \
354 PAL_INITIALIZE_DEBUGGER_EXCEPTIONS | \
355 PAL_INITIALIZE_ENSURE_STACK_SIZE | \
356 PAL_INITIALIZE_REGISTER_SIGNALS)
358 typedef DWORD (PALAPI_NOEXPORT *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
359 typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
361 /******************* PAL-Specific Entrypoints *****************************/
368 char * const argv[]);
373 PAL_InitializeWithFlags(
384 PAL_SetInitializeDLLFlags(
390 PAL_InitializeCoreCLR(
391 const char *szExePath, BOOL runningInExe);
394 /// This function shuts down PAL WITHOUT exiting the current process.
403 /// This function shuts down PAL and exits the current process.
412 /// This function shuts down PAL and exits the current process with
413 /// the specified exit code.
421 typedef VOID (*PSHUTDOWN_CALLBACK)(void);
426 PAL_SetShutdownCallback(
427 IN PSHUTDOWN_CALLBACK callback);
432 PAL_GenerateCoreDump(
437 typedef VOID (*PPAL_STARTUP_CALLBACK)(
445 PAL_RegisterForRuntimeStartup(
446 IN DWORD dwProcessId,
447 IN LPCWSTR lpApplicationGroupId,
448 IN PPAL_STARTUP_CALLBACK pfnCallback,
450 OUT PVOID *ppUnregisterToken);
455 PAL_UnregisterForRuntimeStartup(
456 IN PVOID pUnregisterToken);
461 PAL_NotifyRuntimeStarted();
466 PAL_GetApplicationGroupId();
468 static const unsigned int MAX_DEBUGGER_TRANSPORT_PIPE_NAME_LENGTH = MAX_PATH;
473 PAL_GetTransportName(
474 const unsigned int MAX_TRANSPORT_NAME_LENGTH,
476 IN const char *prefix,
478 IN const char *applicationGroupId,
479 IN const char *suffix);
484 PAL_GetTransportPipeName(
487 IN const char *applicationGroupId,
488 IN const char *suffix);
493 PAL_IgnoreProfileSignal(int signalNum);
499 IN LPCSTR lpLibFileName);
504 PAL_UnregisterModule(
505 IN HINSTANCE hInstance);
511 IN OUT LPVOID lpBuffer,
517 PAL_OpenProcessMemory(
525 PAL_CloseProcessMemory(
532 PAL_ReadProcessMemory(
537 OUT SIZE_T* numberOfBytesRead
551 // Start the jitdump file
552 PAL_PerfJitDump_Start(const char* path);
557 // Log a method to the jitdump file.
558 PAL_PerfJitDump_LogMethod(void* pCode, size_t codeSize, const char* symbol, void* debugInfo, void* unwindInfo);
563 // Finish the jitdump file
564 PAL_PerfJitDump_Finish();
566 /******************* winuser.h Entrypoints *******************************/
568 #define MB_OK 0x00000000L
569 #define MB_OKCANCEL 0x00000001L
570 #define MB_ABORTRETRYIGNORE 0x00000002L
571 #define MB_YESNO 0x00000004L
572 #define MB_RETRYCANCEL 0x00000005L
574 #define MB_ICONHAND 0x00000010L
575 #define MB_ICONQUESTION 0x00000020L
576 #define MB_ICONEXCLAMATION 0x00000030L
577 #define MB_ICONASTERISK 0x00000040L
579 #define MB_ICONINFORMATION MB_ICONASTERISK
580 #define MB_ICONSTOP MB_ICONHAND
581 #define MB_ICONERROR MB_ICONHAND
583 #define MB_DEFBUTTON1 0x00000000L
584 #define MB_DEFBUTTON2 0x00000100L
585 #define MB_DEFBUTTON3 0x00000200L
587 #define MB_SYSTEMMODAL 0x00001000L
588 #define MB_TASKMODAL 0x00002000L
589 #define MB_SETFOREGROUND 0x00010000L
590 #define MB_TOPMOST 0x00040000L
592 #define MB_NOFOCUS 0x00008000L
593 #define MB_DEFAULT_DESKTOP_ONLY 0x00020000L
595 // Note: this is the NT 4.0 and greater value.
596 #define MB_SERVICE_NOTIFICATION 0x00200000L
598 #define MB_TYPEMASK 0x0000000FL
599 #define MB_ICONMASK 0x000000F0L
600 #define MB_DEFMASK 0x00000F00L
615 IN LPVOID hWnd, // NOTE: diff from winuser.h
617 IN LPCWSTR lpCaption,
622 #define MessageBox MessageBoxW
624 #define MessageBox MessageBoxA
632 #define _CRTIMP __declspec(dllimport)
636 /******************* winbase.h Entrypoints and defines ************************/
637 typedef struct _SECURITY_ATTRIBUTES {
639 LPVOID lpSecurityDescriptor;
641 } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
643 #define _SH_DENYWR 0x20 /* deny write mode */
645 #define FILE_READ_DATA ( 0x0001 ) // file & pipe
646 #define FILE_APPEND_DATA ( 0x0004 ) // file
648 #define GENERIC_READ (0x80000000L)
649 #define GENERIC_WRITE (0x40000000L)
651 #define FILE_SHARE_READ 0x00000001
652 #define FILE_SHARE_WRITE 0x00000002
653 #define FILE_SHARE_DELETE 0x00000004
656 #define CREATE_ALWAYS 2
657 #define OPEN_EXISTING 3
658 #define OPEN_ALWAYS 4
659 #define TRUNCATE_EXISTING 5
661 #define FILE_ATTRIBUTE_READONLY 0x00000001
662 #define FILE_ATTRIBUTE_HIDDEN 0x00000002
663 #define FILE_ATTRIBUTE_SYSTEM 0x00000004
664 #define FILE_ATTRIBUTE_DIRECTORY 0x00000010
665 #define FILE_ATTRIBUTE_ARCHIVE 0x00000020
666 #define FILE_ATTRIBUTE_DEVICE 0x00000040
667 #define FILE_ATTRIBUTE_NORMAL 0x00000080
669 #define FILE_FLAG_WRITE_THROUGH 0x80000000
670 #define FILE_FLAG_NO_BUFFERING 0x20000000
671 #define FILE_FLAG_RANDOM_ACCESS 0x10000000
672 #define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000
673 #define FILE_FLAG_BACKUP_SEMANTICS 0x02000000
676 #define FILE_CURRENT 1
679 #define STILL_ACTIVE (0x00000103L)
681 #define INVALID_SET_FILE_POINTER ((DWORD)-1)
688 IN LPCWSTR lpFileName,
689 IN DWORD dwDesiredAccess,
690 IN DWORD dwShareMode,
691 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
692 IN DWORD dwCreationDisposition,
693 IN DWORD dwFlagsAndAttributes,
694 IN HANDLE hTemplateFile);
697 #define CreateFile CreateFileW
699 #define CreateFile CreateFileA
708 IN LPCWSTR lpFileName,
709 IN LPCWSTR lpExtension,
710 IN DWORD nBufferLength,
712 OUT LPWSTR *lpFilePart
715 #define SearchPath SearchPathW
721 IN LPCWSTR lpExistingFileName,
722 IN LPCWSTR lpNewFileName,
723 IN BOOL bFailIfExists);
726 #define CopyFile CopyFileW
728 #define CopyFile CopyFileA
735 IN LPCWSTR lpFileName);
738 #define DeleteFile DeleteFileW
740 #define DeleteFile DeleteFileA
743 #define MOVEFILE_REPLACE_EXISTING 0x00000001
744 #define MOVEFILE_COPY_ALLOWED 0x00000002
750 IN LPCWSTR lpExistingFileName,
751 IN LPCWSTR lpNewFileName,
755 #define MoveFileEx MoveFileExW
757 #define MoveFileEx MoveFileExA
760 typedef struct _BY_HANDLE_FILE_INFORMATION {
761 DWORD dwFileAttributes;
762 FILETIME ftCreationTime;
763 FILETIME ftLastAccessTime;
764 FILETIME ftLastWriteTime;
765 DWORD dwVolumeSerialNumber;
768 DWORD nNumberOfLinks;
769 DWORD nFileIndexHigh;
771 } BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION, *LPBY_HANDLE_FILE_INFORMATION;
773 typedef struct _WIN32_FIND_DATAA {
774 DWORD dwFileAttributes;
775 FILETIME ftCreationTime;
776 FILETIME ftLastAccessTime;
777 FILETIME ftLastWriteTime;
782 CHAR cFileName[ MAX_PATH_FNAME ];
783 CHAR cAlternateFileName[ 14 ];
784 } WIN32_FIND_DATAA, *PWIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
786 typedef struct _WIN32_FIND_DATAW {
787 DWORD dwFileAttributes;
788 FILETIME ftCreationTime;
789 FILETIME ftLastAccessTime;
790 FILETIME ftLastWriteTime;
795 WCHAR cFileName[ MAX_PATH_FNAME ];
796 WCHAR cAlternateFileName[ 14 ];
797 } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;
800 typedef WIN32_FIND_DATAW WIN32_FIND_DATA;
801 typedef PWIN32_FIND_DATAW PWIN32_FIND_DATA;
802 typedef LPWIN32_FIND_DATAW LPWIN32_FIND_DATA;
804 typedef WIN32_FIND_DATAA WIN32_FIND_DATA;
805 typedef PWIN32_FIND_DATAA PWIN32_FIND_DATA;
806 typedef LPWIN32_FIND_DATAA LPWIN32_FIND_DATA;
813 IN LPCWSTR lpFileName,
814 OUT LPWIN32_FIND_DATAW lpFindFileData);
817 #define FindFirstFile FindFirstFileW
819 #define FindFirstFile FindFirstFileA
827 OUT LPWIN32_FIND_DATAW lpFindFileData);
830 #define FindNextFile FindNextFileW
832 #define FindNextFile FindNextFileA
839 IN OUT HANDLE hFindFile);
845 IN LPCWSTR lpFileName);
848 #define GetFileAttributes GetFileAttributesW
850 #define GetFileAttributes GetFileAttributesA
853 typedef enum _GET_FILEEX_INFO_LEVELS {
854 GetFileExInfoStandard
855 } GET_FILEEX_INFO_LEVELS;
857 typedef enum _FINDEX_INFO_LEVELS {
860 FindExInfoMaxInfoLevel
861 } FINDEX_INFO_LEVELS;
863 typedef enum _FINDEX_SEARCH_OPS {
864 FindExSearchNameMatch,
865 FindExSearchLimitToDirectories,
866 FindExSearchLimitToDevices,
867 FindExSearchMaxSearchOp
870 typedef struct _WIN32_FILE_ATTRIBUTE_DATA {
871 DWORD dwFileAttributes;
872 FILETIME ftCreationTime;
873 FILETIME ftLastAccessTime;
874 FILETIME ftLastWriteTime;
877 } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA;
882 GetFileAttributesExW(
883 IN LPCWSTR lpFileName,
884 IN GET_FILEEX_INFO_LEVELS fInfoLevelId,
885 OUT LPVOID lpFileInformation);
888 #define GetFileAttributesEx GetFileAttributesExW
891 typedef struct _OVERLAPPED {
893 ULONG_PTR InternalHigh;
897 } OVERLAPPED, *LPOVERLAPPED;
905 IN DWORD nNumberOfBytesToWrite,
906 OUT LPDWORD lpNumberOfBytesWritten,
907 IN LPOVERLAPPED lpOverlapped);
915 IN DWORD nNumberOfBytesToRead,
916 OUT LPDWORD lpNumberOfBytesRead,
917 IN LPOVERLAPPED lpOverlapped);
919 #define STD_INPUT_HANDLE ((DWORD)-10)
920 #define STD_OUTPUT_HANDLE ((DWORD)-11)
921 #define STD_ERROR_HANDLE ((DWORD)-12)
927 IN DWORD nStdHandle);
940 IN LONG lDistanceToMove,
941 IN PLONG lpDistanceToMoveHigh,
942 IN DWORD dwMoveMethod);
949 IN LARGE_INTEGER liDistanceToMove,
950 OUT PLARGE_INTEGER lpNewFilePointer,
951 IN DWORD dwMoveMethod);
958 OUT LPDWORD lpFileSizeHigh);
962 PALAPI GetFileSizeEx(
964 OUT PLARGE_INTEGER lpFileSize);
969 GetSystemTimeAsFileTime(
970 OUT LPFILETIME lpSystemTimeAsFileTime);
972 typedef struct _SYSTEMTIME {
981 } SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
987 OUT LPSYSTEMTIME lpSystemTime);
992 FileTimeToSystemTime(
993 IN CONST FILETIME *lpFileTime,
994 OUT LPSYSTEMTIME lpSystemTime);
1007 GetConsoleOutputCP();
1013 IN LPCWSTR lpFileName,
1014 IN DWORD nBufferLength,
1015 OUT LPWSTR lpBuffer,
1016 OUT LPWSTR *lpFilePart);
1019 #define GetFullPathName GetFullPathNameW
1021 #define GetFullPathName GetFullPathNameA
1028 IN LPCWSTR lpPathName,
1029 IN LPCWSTR lpPrefixString,
1031 OUT LPWSTR lpTempFileName);
1034 #define GetTempFileName GetTempFileNameW
1036 #define GetTempFileName GetTempFileNameA
1043 IN DWORD nBufferLength,
1044 OUT LPWSTR lpBuffer);
1050 IN DWORD nBufferLength,
1051 OUT LPSTR lpBuffer);
1055 #define GetTempPath GetTempPathW
1057 #define GetTempPath GetTempPathA
1063 GetCurrentDirectoryW(
1064 IN DWORD nBufferLength,
1065 OUT LPWSTR lpBuffer);
1068 #define GetCurrentDirectory GetCurrentDirectoryW
1070 #define GetCurrentDirectory GetCurrentDirectoryA
1077 IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
1078 IN LONG lInitialCount,
1079 IN LONG lMaximumCount,
1081 IN /*_Reserved_*/ DWORD dwFlags,
1082 IN DWORD dwDesiredAccess);
1088 IN DWORD dwDesiredAccess,
1089 IN BOOL bInheritHandle,
1092 #define CreateSemaphoreEx CreateSemaphoreExW
1098 IN HANDLE hSemaphore,
1099 IN LONG lReleaseCount,
1100 OUT LPLONG lpPreviousCount);
1106 IN LPSECURITY_ATTRIBUTES lpEventAttributes,
1107 IN BOOL bManualReset,
1108 IN BOOL bInitialState,
1115 IN LPSECURITY_ATTRIBUTES lpEventAttributes,
1118 IN DWORD dwDesiredAccess);
1120 // CreateEventExW: dwFlags
1121 #define CREATE_EVENT_MANUAL_RESET ((DWORD)0x1)
1122 #define CREATE_EVENT_INITIAL_SET ((DWORD)0x2)
1124 #define CreateEvent CreateEventW
1142 IN DWORD dwDesiredAccess,
1143 IN BOOL bInheritHandle,
1147 #define OpenEvent OpenEventW
1154 IN LPSECURITY_ATTRIBUTES lpMutexAttributes,
1155 IN BOOL bInitialOwner,
1162 IN LPSECURITY_ATTRIBUTES lpMutexAttributes,
1165 IN DWORD dwDesiredAccess);
1167 // CreateMutexExW: dwFlags
1168 #define CREATE_MUTEX_INITIAL_OWNER ((DWORD)0x1)
1170 #define CreateMutex CreateMutexW
1176 IN DWORD dwDesiredAccess,
1177 IN BOOL bInheritHandle,
1181 #define OpenMutex OpenMutexW
1193 GetCurrentProcessId();
1198 GetCurrentSessionId();
1203 GetCurrentProcess();
1208 GetCurrentThreadId();
1213 PAL_GetCurrentOSThreadId();
1215 // To work around multiply-defined symbols in the Carbon framework.
1216 #define GetCurrentThread PAL_GetCurrentThread
1223 #define STARTF_USESTDHANDLES 0x00000100
1225 typedef struct _STARTUPINFOW {
1227 LPWSTR lpReserved_PAL_Undefined;
1228 LPWSTR lpDesktop_PAL_Undefined;
1229 LPWSTR lpTitle_PAL_Undefined;
1230 DWORD dwX_PAL_Undefined;
1231 DWORD dwY_PAL_Undefined;
1232 DWORD dwXSize_PAL_Undefined;
1233 DWORD dwYSize_PAL_Undefined;
1234 DWORD dwXCountChars_PAL_Undefined;
1235 DWORD dwYCountChars_PAL_Undefined;
1236 DWORD dwFillAttribute_PAL_Undefined;
1238 WORD wShowWindow_PAL_Undefined;
1239 WORD cbReserved2_PAL_Undefined;
1240 LPBYTE lpReserved2_PAL_Undefined;
1244 } STARTUPINFOW, *LPSTARTUPINFOW;
1246 typedef STARTUPINFOW STARTUPINFO;
1247 typedef LPSTARTUPINFOW LPSTARTUPINFO;
1249 #define CREATE_NEW_CONSOLE 0x00000010
1251 #define NORMAL_PRIORITY_CLASS 0x00000020
1253 typedef struct _PROCESS_INFORMATION {
1257 DWORD dwThreadId_PAL_Undefined;
1258 } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
1264 IN LPCWSTR lpApplicationName,
1265 IN LPWSTR lpCommandLine,
1266 IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
1267 IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
1268 IN BOOL bInheritHandles,
1269 IN DWORD dwCreationFlags,
1270 IN LPVOID lpEnvironment,
1271 IN LPCWSTR lpCurrentDirectory,
1272 IN LPSTARTUPINFOW lpStartupInfo,
1273 OUT LPPROCESS_INFORMATION lpProcessInformation);
1275 #define CreateProcess CreateProcessW
1296 IN LPDWORD lpExitCode);
1303 OUT LPFILETIME lpCreationTime,
1304 OUT LPFILETIME lpExitTime,
1305 OUT LPFILETIME lpKernelTime,
1306 OUT LPFILETIME lpUserTime);
1308 #define MAXIMUM_WAIT_OBJECTS 64
1309 #define WAIT_OBJECT_0 0
1310 #define WAIT_ABANDONED 0x00000080
1311 #define WAIT_ABANDONED_0 0x00000080
1312 #define WAIT_TIMEOUT 258
1313 #define WAIT_FAILED ((DWORD)0xFFFFFFFF)
1315 #define INFINITE 0xFFFFFFFF // Infinite timeout
1320 WaitForSingleObject(
1322 IN DWORD dwMilliseconds);
1327 PAL_WaitForSingleObjectPrioritized(
1329 IN DWORD dwMilliseconds);
1334 WaitForSingleObjectEx(
1336 IN DWORD dwMilliseconds,
1337 IN BOOL bAlertable);
1342 WaitForMultipleObjects(
1344 IN CONST HANDLE *lpHandles,
1346 IN DWORD dwMilliseconds);
1351 WaitForMultipleObjectsEx(
1353 IN CONST HANDLE *lpHandles,
1355 IN DWORD dwMilliseconds,
1356 IN BOOL bAlertable);
1361 SignalObjectAndWait(
1362 IN HANDLE hObjectToSignal,
1363 IN HANDLE hObjectToWaitOn,
1364 IN DWORD dwMilliseconds,
1365 IN BOOL bAlertable);
1367 #define DUPLICATE_CLOSE_SOURCE 0x00000001
1368 #define DUPLICATE_SAME_ACCESS 0x00000002
1374 IN HANDLE hSourceProcessHandle,
1375 IN HANDLE hSourceHandle,
1376 IN HANDLE hTargetProcessHandle,
1377 OUT LPHANDLE lpTargetHandle,
1378 IN DWORD dwDesiredAccess,
1379 IN BOOL bInheritHandle,
1380 IN DWORD dwOptions);
1386 IN DWORD dwMilliseconds);
1392 IN DWORD dwMilliseconds,
1393 IN BOOL bAlertable);
1400 #define DEBUG_PROCESS 0x00000001
1401 #define DEBUG_ONLY_THIS_PROCESS 0x00000002
1402 #define CREATE_SUSPENDED 0x00000004
1403 #define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000
1409 IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
1410 IN DWORD dwStackSize,
1411 IN LPTHREAD_START_ROUTINE lpStartAddress,
1412 IN LPVOID lpParameter,
1413 IN DWORD dwCreationFlags,
1414 OUT LPDWORD lpThreadId);
1420 IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
1421 IN DWORD dwStackSize,
1422 IN LPTHREAD_START_ROUTINE lpStartAddress,
1423 IN LPVOID lpParameter,
1424 IN DWORD dwCreationFlags,
1425 OUT SIZE_T* pThreadId);
1432 IN DWORD dwExitCode);
1440 typedef VOID (PALAPI_NOEXPORT *PAPCFUNC)(ULONG_PTR dwParam);
1448 IN ULONG_PTR dwData);
1453 // ***********************************************************************************
1455 // NOTE: These context definitions are replicated in ndp/clr/src/debug/inc/DbgTargetContext.h (for the
1456 // purposes manipulating contexts from different platforms during remote debugging). Be sure to keep those
1457 // definitions in sync if you make any changes here.
1459 // ***********************************************************************************
1462 #define SIZE_OF_80387_REGISTERS 80
1464 #define CONTEXT_i386 0x00010000
1465 #define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
1466 #define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
1467 #define CONTEXT_SEGMENTS (CONTEXT_i386 | 0x00000004L)
1468 #define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 0x00000008L) // 387 state
1469 #define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L)
1471 #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)
1472 #define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386 | 0x00000020L)
1473 #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS)
1475 #define MAXIMUM_SUPPORTED_EXTENSION 512
1477 #define CONTEXT_XSTATE (CONTEXT_i386 | 0x40L)
1479 #define CONTEXT_EXCEPTION_ACTIVE 0x8000000L
1480 #define CONTEXT_SERVICE_ACTIVE 0x10000000L
1481 #define CONTEXT_EXCEPTION_REQUEST 0x40000000L
1482 #define CONTEXT_EXCEPTION_REPORTING 0x80000000L
1485 // This flag is set by the unwinder if it has unwound to a call
1486 // site, and cleared whenever it unwinds through a trap frame.
1487 // It is used by language-specific exception handlers to help
1488 // differentiate exception scopes during dispatching.
1491 #define CONTEXT_UNWOUND_TO_CALL 0x20000000
1493 typedef struct _FLOATING_SAVE_AREA {
1498 DWORD ErrorSelector;
1501 BYTE RegisterArea[SIZE_OF_80387_REGISTERS];
1503 } FLOATING_SAVE_AREA;
1505 typedef FLOATING_SAVE_AREA *PFLOATING_SAVE_AREA;
1507 typedef struct _CONTEXT {
1510 ULONG Dr0_PAL_Undefined;
1511 ULONG Dr1_PAL_Undefined;
1512 ULONG Dr2_PAL_Undefined;
1513 ULONG Dr3_PAL_Undefined;
1514 ULONG Dr6_PAL_Undefined;
1515 ULONG Dr7_PAL_Undefined;
1517 FLOATING_SAVE_AREA FloatSave;
1519 ULONG SegGs_PAL_Undefined;
1520 ULONG SegFs_PAL_Undefined;
1521 ULONG SegEs_PAL_Undefined;
1522 ULONG SegDs_PAL_Undefined;
1538 UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
1539 } CONTEXT, *PCONTEXT, *LPCONTEXT;
1541 // To support saving and loading xmm register context we need to know the offset in the ExtendedRegisters
1542 // section at which they are stored. This has been determined experimentally since I have found no
1543 // documentation thus far but it corresponds to the offset we'd expect if a fxsave instruction was used to
1544 // store the regular FP state along with the XMM registers at the start of the extended registers section.
1545 // Technically the offset doesn't really matter if no code in the PAL or runtime knows what the offset should
1546 // be either (as long as we're consistent across GetThreadContext() and SetThreadContext() and we don't
1547 // support any other values in the ExtendedRegisters) but we might as well be as accurate as we can.
1548 #define CONTEXT_EXREG_XMM_OFFSET 160
1550 typedef struct _KNONVOLATILE_CONTEXT {
1557 } KNONVOLATILE_CONTEXT, *PKNONVOLATILE_CONTEXT;
1559 typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
1561 // The ordering of these fields should be aligned with that
1562 // of corresponding fields in CONTEXT
1564 // (See FillRegDisplay in inc/regdisp.h for details)
1574 } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
1576 #elif defined(HOST_AMD64)
1577 // copied from winnt.h
1579 #define CONTEXT_AMD64 0x100000
1581 #define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x1L)
1582 #define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x2L)
1583 #define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x4L)
1584 #define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x8L)
1585 #define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L)
1587 #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
1589 #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
1591 #define CONTEXT_XSTATE (CONTEXT_AMD64 | 0x40L)
1593 #define CONTEXT_EXCEPTION_ACTIVE 0x8000000
1594 #define CONTEXT_SERVICE_ACTIVE 0x10000000
1595 #define CONTEXT_EXCEPTION_REQUEST 0x40000000
1596 #define CONTEXT_EXCEPTION_REPORTING 0x80000000
1598 typedef struct DECLSPEC_ALIGN(16) _M128A {
1603 typedef struct _XMM_SAVE_AREA32 {
1617 M128A FloatRegisters[8];
1618 M128A XmmRegisters[16];
1620 } XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
1622 #define LEGACY_SAVE_AREA_LENGTH sizeof(XMM_SAVE_AREA32)
1627 // This frame has a several purposes: 1) it is used as an argument to
1628 // NtContinue, 2) is is used to constuct a call frame for APC delivery,
1629 // and 3) it is used in the user level thread creation routines.
1632 // The flags field within this record controls the contents of a CONTEXT
1635 // If the context record is used as an input parameter, then for each
1636 // portion of the context record controlled by a flag whose value is
1637 // set, it is assumed that that portion of the context record contains
1638 // valid context. If the context record is being used to modify a threads
1639 // context, then only that portion of the threads context is modified.
1641 // If the context record is used as an output parameter to capture the
1642 // context of a thread, then only those portions of the thread's context
1643 // corresponding to set flags will be returned.
1645 // CONTEXT_CONTROL specifies SegSs, Rsp, SegCs, Rip, and EFlags.
1647 // CONTEXT_INTEGER specifies Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, and R8-R15.
1649 // CONTEXT_SEGMENTS specifies SegDs, SegEs, SegFs, and SegGs.
1651 // CONTEXT_DEBUG_REGISTERS specifies Dr0-Dr3 and Dr6-Dr7.
1653 // CONTEXT_MMX_REGISTERS specifies the floating point and extended registers
1654 // Mm0/St0-Mm7/St7 and Xmm0-Xmm15).
1657 typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
1660 // Register parameter home addresses.
1662 // N.B. These fields are for convience - they could be used to extend the
1663 // context record in the future.
1681 // Segment Registers and processor flags.
1704 // Integer registers.
1731 // Floating point state.
1735 XMM_SAVE_AREA32 FltSave;
1759 // Vector registers.
1762 M128A VectorRegister[26];
1763 DWORD64 VectorControl;
1766 // Special debug control registers.
1769 DWORD64 DebugControl;
1770 DWORD64 LastBranchToRip;
1771 DWORD64 LastBranchFromRip;
1772 DWORD64 LastExceptionToRip;
1773 DWORD64 LastExceptionFromRip;
1774 } CONTEXT, *PCONTEXT, *LPCONTEXT;
1777 // Nonvolatile context pointer record.
1780 typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
1782 PM128A FloatingContext[16];
1804 PDWORD64 IntegerContext[16];
1825 } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
1827 #elif defined(HOST_ARM)
1829 #define CONTEXT_ARM 0x00200000L
1833 #define CONTEXT_CONTROL (CONTEXT_ARM | 0x1L)
1834 #define CONTEXT_INTEGER (CONTEXT_ARM | 0x2L)
1835 #define CONTEXT_FLOATING_POINT (CONTEXT_ARM | 0x4L)
1836 #define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM | 0x8L)
1838 #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
1840 #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
1842 #define CONTEXT_EXCEPTION_ACTIVE 0x8000000L
1843 #define CONTEXT_SERVICE_ACTIVE 0x10000000L
1844 #define CONTEXT_EXCEPTION_REQUEST 0x40000000L
1845 #define CONTEXT_EXCEPTION_REPORTING 0x80000000L
1848 // This flag is set by the unwinder if it has unwound to a call
1849 // site, and cleared whenever it unwinds through a trap frame.
1850 // It is used by language-specific exception handlers to help
1851 // differentiate exception scopes during dispatching.
1854 #define CONTEXT_UNWOUND_TO_CALL 0x20000000
1857 // Specify the number of breakpoints and watchpoints that the OS
1858 // will track. Architecturally, ARM supports up to 16. In practice,
1859 // however, almost no one implements more than 4 of each.
1862 #define ARM_MAX_BREAKPOINTS 8
1863 #define ARM_MAX_WATCHPOINTS 1
1865 typedef struct _NEON128 {
1868 } NEON128, *PNEON128;
1873 // This frame has a several purposes: 1) it is used as an argument to
1874 // NtContinue, 2) it is used to constuct a call frame for APC delivery,
1875 // and 3) it is used in the user level thread creation routines.
1878 // The flags field within this record controls the contents of a CONTEXT
1881 // If the context record is used as an input parameter, then for each
1882 // portion of the context record controlled by a flag whose value is
1883 // set, it is assumed that that portion of the context record contains
1884 // valid context. If the context record is being used to modify a threads
1885 // context, then only that portion of the threads context is modified.
1887 // If the context record is used as an output parameter to capture the
1888 // context of a thread, then only those portions of the thread's context
1889 // corresponding to set flags will be returned.
1891 // CONTEXT_CONTROL specifies Sp, Lr, Pc, and Cpsr
1893 // CONTEXT_INTEGER specifies R0-R12
1895 // CONTEXT_FLOATING_POINT specifies Q0-Q15 / D0-D31 / S0-S31
1897 // CONTEXT_DEBUG_REGISTERS specifies up to 16 of DBGBVR, DBGBCR, DBGWVR,
1901 typedef struct DECLSPEC_ALIGN(8) _CONTEXT {
1910 // Integer registers
1928 // Control Registers
1937 // Floating Point/NEON Registers
1952 DWORD Bvr[ARM_MAX_BREAKPOINTS];
1953 DWORD Bcr[ARM_MAX_BREAKPOINTS];
1954 DWORD Wvr[ARM_MAX_WATCHPOINTS];
1955 DWORD Wcr[ARM_MAX_WATCHPOINTS];
1959 } CONTEXT, *PCONTEXT, *LPCONTEXT;
1962 // Nonvolatile context pointer record.
1965 typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
1986 } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
1988 typedef struct _IMAGE_ARM_RUNTIME_FUNCTION_ENTRY {
1995 DWORD FunctionLength : 11;
2002 DWORD StackAdjust : 10;
2005 } IMAGE_ARM_RUNTIME_FUNCTION_ENTRY, * PIMAGE_ARM_RUNTIME_FUNCTION_ENTRY;
2007 #elif defined(HOST_ARM64)
2009 #define CONTEXT_ARM64 0x00400000L
2011 #define CONTEXT_CONTROL (CONTEXT_ARM64 | 0x1L)
2012 #define CONTEXT_INTEGER (CONTEXT_ARM64 | 0x2L)
2013 #define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | 0x4L)
2014 #define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM64 | 0x8L)
2016 #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
2018 #define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
2020 #define CONTEXT_EXCEPTION_ACTIVE 0x8000000L
2021 #define CONTEXT_SERVICE_ACTIVE 0x10000000L
2022 #define CONTEXT_EXCEPTION_REQUEST 0x40000000L
2023 #define CONTEXT_EXCEPTION_REPORTING 0x80000000L
2026 // This flag is set by the unwinder if it has unwound to a call
2027 // site, and cleared whenever it unwinds through a trap frame.
2028 // It is used by language-specific exception handlers to help
2029 // differentiate exception scopes during dispatching.
2032 #define CONTEXT_UNWOUND_TO_CALL 0x20000000
2035 // Define initial Cpsr/Fpscr value
2038 #define INITIAL_CPSR 0x10
2039 #define INITIAL_FPSCR 0
2044 // Specify the number of breakpoints and watchpoints that the OS
2045 // will track. Architecturally, ARM64 supports up to 16. In practice,
2046 // however, almost no one implements more than 4 of each.
2049 #define ARM64_MAX_BREAKPOINTS 8
2050 #define ARM64_MAX_WATCHPOINTS 2
2055 // This frame has a several purposes: 1) it is used as an argument to
2056 // NtContinue, 2) it is used to constuct a call frame for APC delivery,
2057 // and 3) it is used in the user level thread creation routines.
2060 // The flags field within this record controls the contents of a CONTEXT
2063 // If the context record is used as an input parameter, then for each
2064 // portion of the context record controlled by a flag whose value is
2065 // set, it is assumed that that portion of the context record contains
2066 // valid context. If the context record is being used to modify a threads
2067 // context, then only that portion of the threads context is modified.
2069 // If the context record is used as an output parameter to capture the
2070 // context of a thread, then only those portions of the thread's context
2071 // corresponding to set flags will be returned.
2073 // CONTEXT_CONTROL specifies Sp, Lr, Pc, and Cpsr
2075 // CONTEXT_INTEGER specifies R0-R12
2077 // CONTEXT_FLOATING_POINT specifies Q0-Q15 / D0-D31 / S0-S31
2079 // CONTEXT_DEBUG_REGISTERS specifies up to 16 of DBGBVR, DBGBCR, DBGWVR,
2083 typedef struct _NEON128 {
2086 } NEON128, *PNEON128;
2088 typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
2094 /* +0x000 */ DWORD ContextFlags;
2097 // Integer registers
2100 /* +0x004 */ DWORD Cpsr; // NZVF + DAIF + CurrentEL + SPSel
2101 /* +0x008 */ union {
2135 /* +0x0f0 */ DWORD64 Fp;
2136 /* +0x0f8 */ DWORD64 Lr;
2137 /* +0x100 */ DWORD64 Sp;
2138 /* +0x108 */ DWORD64 Pc;
2141 // Floating Point/NEON Registers
2144 /* +0x110 */ NEON128 V[32];
2145 /* +0x310 */ DWORD Fpcr;
2146 /* +0x314 */ DWORD Fpsr;
2152 /* +0x318 */ DWORD Bcr[ARM64_MAX_BREAKPOINTS];
2153 /* +0x338 */ DWORD64 Bvr[ARM64_MAX_BREAKPOINTS];
2154 /* +0x378 */ DWORD Wcr[ARM64_MAX_WATCHPOINTS];
2155 /* +0x380 */ DWORD64 Wvr[ARM64_MAX_WATCHPOINTS];
2158 } CONTEXT, *PCONTEXT, *LPCONTEXT;
2161 // Nonvolatile context pointer record.
2164 typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
2188 } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
2191 #error Unknown architecture for defining CONTEXT.
2200 IN OUT LPCONTEXT lpContext);
2207 IN CONST CONTEXT *lpContext);
2209 #define THREAD_BASE_PRIORITY_LOWRT 15
2210 #define THREAD_BASE_PRIORITY_MAX 2
2211 #define THREAD_BASE_PRIORITY_MIN (-2)
2212 #define THREAD_BASE_PRIORITY_IDLE (-15)
2214 #define THREAD_PRIORITY_LOWEST THREAD_BASE_PRIORITY_MIN
2215 #define THREAD_PRIORITY_BELOW_NORMAL (THREAD_PRIORITY_LOWEST+1)
2216 #define THREAD_PRIORITY_NORMAL 0
2217 #define THREAD_PRIORITY_HIGHEST THREAD_BASE_PRIORITY_MAX
2218 #define THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST-1)
2219 #define THREAD_PRIORITY_ERROR_RETURN (MAXLONG)
2221 #define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT
2222 #define THREAD_PRIORITY_IDLE THREAD_BASE_PRIORITY_IDLE
2242 OUT LPFILETIME lpCreationTime,
2243 OUT LPFILETIME lpExitTime,
2244 OUT LPFILETIME lpKernelTime,
2245 OUT LPFILETIME lpUserTime);
2250 SetThreadDescription(
2252 IN PCWSTR lpThreadDescription
2255 #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
2265 PAL_GetStackLimit();
2270 PAL_GetLogicalCpuCountFromOS();
2275 PAL_GetTotalCpuCount();
2280 PAL_GetRestrictedPhysicalMemoryLimit();
2285 PAL_GetPhysicalMemoryUsed(size_t* val);
2290 PAL_GetCpuLimit(UINT* val);
2295 PAL_GetLogicalProcessorCacheSizeFromOS();
2297 typedef BOOL(*UnwindReadMemoryCallback)(PVOID address, PVOID buffer, SIZE_T size);
2299 PALIMPORT BOOL PALAPI PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers);
2301 PALIMPORT BOOL PALAPI PAL_VirtualUnwindOutOfProc(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers, SIZE_T baseAddress, UnwindReadMemoryCallback readMemoryCallback);
2303 #define GetLogicalProcessorCacheSizeFromOS PAL_GetLogicalProcessorCacheSizeFromOS
2305 /* PAL_CS_NATIVE_DATA_SIZE is defined as sizeof(PAL_CRITICAL_SECTION_NATIVE_DATA) */
2307 #if defined(__APPLE__) && defined(__i386__)
2308 #define PAL_CS_NATIVE_DATA_SIZE 76
2309 #elif defined(__APPLE__) && defined(__x86_64__)
2310 #define PAL_CS_NATIVE_DATA_SIZE 120
2311 #elif defined(__APPLE__) && defined(HOST_ARM64)
2312 #define PAL_CS_NATIVE_DATA_SIZE 120
2313 #elif defined(__FreeBSD__) && defined(HOST_X86)
2314 #define PAL_CS_NATIVE_DATA_SIZE 12
2315 #elif defined(__FreeBSD__) && defined(__x86_64__)
2316 #define PAL_CS_NATIVE_DATA_SIZE 24
2317 #elif defined(__linux__) && defined(HOST_ARM)
2318 #define PAL_CS_NATIVE_DATA_SIZE 80
2319 #elif defined(__linux__) && defined(HOST_ARM64)
2320 #define PAL_CS_NATIVE_DATA_SIZE 116
2321 #elif defined(__linux__) && defined(__i386__)
2322 #define PAL_CS_NATIVE_DATA_SIZE 76
2323 #elif defined(__linux__) && defined(__x86_64__)
2324 #define PAL_CS_NATIVE_DATA_SIZE 96
2325 #elif defined(__NetBSD__) && defined(__amd64__)
2326 #define PAL_CS_NATIVE_DATA_SIZE 96
2327 #elif defined(__NetBSD__) && defined(__earm__)
2328 #define PAL_CS_NATIVE_DATA_SIZE 56
2329 #elif defined(__NetBSD__) && defined(__i386__)
2330 #define PAL_CS_NATIVE_DATA_SIZE 56
2331 #elif defined(__sun) && defined(__x86_64__)
2332 #define PAL_CS_NATIVE_DATA_SIZE 48
2335 #error PAL_CS_NATIVE_DATA_SIZE is not defined for this architecture
2339 typedef struct _CRITICAL_SECTION {
2342 LONG RecursionCount;
2343 HANDLE OwningThread;
2344 ULONG_PTR SpinCount;
2346 #ifdef PAL_TRACK_CRITICAL_SECTIONS_DATA
2348 #endif // PAL_TRACK_CRITICAL_SECTIONS_DATA
2349 volatile DWORD dwInitState;
2351 union CSNativeDataStorage
2353 BYTE rgNativeDataStorage[PAL_CS_NATIVE_DATA_SIZE];
2354 PVOID pvAlign; // make sure the storage is machine-pointer-size aligned
2356 } CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
2358 PALIMPORT VOID PALAPI EnterCriticalSection(IN OUT LPCRITICAL_SECTION lpCriticalSection);
2359 PALIMPORT VOID PALAPI LeaveCriticalSection(IN OUT LPCRITICAL_SECTION lpCriticalSection);
2360 PALIMPORT VOID PALAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection);
2361 PALIMPORT BOOL PALAPI InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags);
2362 PALIMPORT VOID PALAPI DeleteCriticalSection(IN OUT LPCRITICAL_SECTION lpCriticalSection);
2363 PALIMPORT BOOL PALAPI TryEnterCriticalSection(IN OUT LPCRITICAL_SECTION lpCriticalSection);
2365 #define SEM_FAILCRITICALERRORS 0x0001
2366 #define SEM_NOOPENFILEERRORBOX 0x8000
2374 #define PAGE_NOACCESS 0x01
2375 #define PAGE_READONLY 0x02
2376 #define PAGE_READWRITE 0x04
2377 #define PAGE_WRITECOPY 0x08
2378 #define PAGE_EXECUTE 0x10
2379 #define PAGE_EXECUTE_READ 0x20
2380 #define PAGE_EXECUTE_READWRITE 0x40
2381 #define PAGE_EXECUTE_WRITECOPY 0x80
2382 #define MEM_COMMIT 0x1000
2383 #define MEM_RESERVE 0x2000
2384 #define MEM_DECOMMIT 0x4000
2385 #define MEM_RELEASE 0x8000
2386 #define MEM_RESET 0x80000
2387 #define MEM_FREE 0x10000
2388 #define MEM_PRIVATE 0x20000
2389 #define MEM_MAPPED 0x40000
2390 #define MEM_TOP_DOWN 0x100000
2391 #define MEM_WRITE_WATCH 0x200000
2392 #define MEM_LARGE_PAGES 0x20000000
2393 #define MEM_RESERVE_EXECUTABLE 0x40000000 // reserve memory using executable memory allocator
2400 IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
2402 IN DWORD dwMaxmimumSizeHigh,
2403 IN DWORD dwMaximumSizeLow,
2406 #define CreateFileMapping CreateFileMappingW
2408 #define SECTION_QUERY 0x0001
2409 #define SECTION_MAP_WRITE 0x0002
2410 #define SECTION_MAP_READ 0x0004
2411 #define SECTION_ALL_ACCESS (SECTION_MAP_READ | SECTION_MAP_WRITE) // diff from winnt.h
2413 #define FILE_MAP_WRITE SECTION_MAP_WRITE
2414 #define FILE_MAP_READ SECTION_MAP_READ
2415 #define FILE_MAP_ALL_ACCESS SECTION_ALL_ACCESS
2416 #define FILE_MAP_COPY SECTION_QUERY
2422 IN DWORD dwDesiredAccess,
2423 IN BOOL bInheritHandle,
2426 #define OpenFileMapping OpenFileMappingW
2428 typedef INT_PTR (PALAPI_NOEXPORT *FARPROC)();
2434 IN HANDLE hFileMappingObject,
2435 IN DWORD dwDesiredAccess,
2436 IN DWORD dwFileOffsetHigh,
2437 IN DWORD dwFileOffsetLow,
2438 IN SIZE_T dwNumberOfBytesToMap);
2444 IN HANDLE hFileMappingObject,
2445 IN DWORD dwDesiredAccess,
2446 IN DWORD dwFileOffsetHigh,
2447 IN DWORD dwFileOffsetLow,
2448 IN SIZE_T dwNumberOfBytesToMap,
2449 IN LPVOID lpBaseAddress);
2455 IN LPCVOID lpBaseAddress);
2462 IN LPCWSTR lpLibFileName);
2468 IN LPCWSTR lpLibFileName,
2469 IN /*Reserved*/ HANDLE hFile,
2473 NATIVE_LIBRARY_HANDLE
2475 PAL_LoadLibraryDirect(
2476 IN LPCWSTR lpLibFileName);
2481 PAL_FreeLibraryDirect(
2482 IN NATIVE_LIBRARY_HANDLE dl_handle);
2487 PAL_GetPalHostModule();
2492 PAL_GetProcAddressDirect(
2493 IN NATIVE_LIBRARY_HANDLE dl_handle,
2494 IN LPCSTR lpProcName);
2501 Loads a PE file into memory. Properly maps all of the sections in the PE file. Returns a pointer to the
2505 IN hFile - The file to load
2506 IN offset - offset within hFile where the PE "file" is located
2509 A valid base address if successful.
2515 PAL_LOADLoadPEFile(HANDLE hFile, size_t offset);
2518 PAL_LOADUnloadPEFile
2520 Unload a PE file that was loaded by PAL_LOADLoadPEFile().
2523 IN ptr - the file pointer returned by PAL_LOADLoadPEFile()
2527 FALSE - failure (incorrect ptr, etc.)
2532 PAL_LOADUnloadPEFile(PVOID ptr);
2535 PAL_LOADMarkSectionAsNotNeeded
2537 Mark a section as NotNeeded that was loaded by PAL_LOADLoadPEFile().
2540 IN ptr - the section address mapped by PAL_LOADLoadPEFile()
2544 FALSE - failure (incorrect ptr, etc.)
2548 PAL_LOADMarkSectionAsNotNeeded(void * ptr);
2551 #define LoadLibrary LoadLibraryW
2552 #define LoadLibraryEx LoadLibraryExW
2554 #define LoadLibrary LoadLibraryA
2555 #define LoadLibraryEx LoadLibraryExA
2563 IN LPCSTR lpProcName);
2569 IN OUT HMODULE hLibModule);
2575 FreeLibraryAndExitThread(
2576 IN HMODULE hLibModule,
2577 IN DWORD dwExitCode);
2582 DisableThreadLibraryCalls(
2583 IN HMODULE hLibModule);
2590 OUT LPWSTR lpFileName,
2594 #define GetModuleFileName GetModuleFileNameW
2596 #define GetModuleFileName GetModuleFileNameA
2602 GetModuleFileNameExW(
2605 OUT LPWSTR lpFilename,
2610 #define GetModuleFileNameEx GetModuleFileNameExW
2613 // Get base address of the module containing a given symbol
2617 PAL_GetSymbolModuleBase(PVOID symbol);
2622 PAL_GetLoadLibraryError();
2627 PAL_VirtualReserveFromExecutableMemoryAllocatorWithinRange(
2628 IN LPCVOID lpBeginAddress,
2629 IN LPCVOID lpEndAddress,
2636 IN LPVOID lpAddress,
2638 IN DWORD flAllocationType,
2639 IN DWORD flProtect);
2645 IN LPVOID lpAddress,
2647 IN DWORD dwFreeType);
2649 #if defined(HOST_OSX) && defined(HOST_ARM64)
2652 struct PAL_JITWriteEnableHolder
2655 PAL_JITWriteEnableHolder(bool jitWriteEnable)
2657 m_jitWriteEnableRestore = JITWriteEnable(jitWriteEnable);
2659 ~PAL_JITWriteEnableHolder()
2661 JITWriteEnable(m_jitWriteEnableRestore);
2665 bool JITWriteEnable(bool enable);
2666 bool m_jitWriteEnableRestore;
2670 PAL_JITWriteEnableHolder
2671 PAL_JITWriteEnable(IN bool enable) { return PAL_JITWriteEnableHolder(enable); }
2673 #endif // __cplusplus
2674 #endif // defined(HOST_OSX) && defined(HOST_ARM64)
2680 IN LPVOID lpAddress,
2682 IN DWORD flNewProtect,
2683 OUT PDWORD lpflOldProtect);
2685 typedef struct _MEMORYSTATUSEX {
2688 DWORDLONG ullTotalPhys;
2689 DWORDLONG ullAvailPhys;
2690 DWORDLONG ullTotalPageFile;
2691 DWORDLONG ullAvailPageFile;
2692 DWORDLONG ullTotalVirtual;
2693 DWORDLONG ullAvailVirtual;
2694 DWORDLONG ullAvailExtendedVirtual;
2695 } MEMORYSTATUSEX, *LPMEMORYSTATUSEX;
2700 GlobalMemoryStatusEx(
2701 IN OUT LPMEMORYSTATUSEX lpBuffer);
2703 typedef struct _MEMORY_BASIC_INFORMATION {
2705 PVOID AllocationBase_PAL_Undefined;
2706 DWORD AllocationProtect;
2711 } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
2717 IN LPCVOID lpAddress,
2718 OUT PMEMORY_BASIC_INFORMATION lpBuffer,
2719 IN SIZE_T dwLength);
2721 #define MoveMemory memmove
2722 #define CopyMemory memcpy
2723 #define FillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
2724 #define ZeroMemory(Destination,Length) memset((Destination),0,(Length))
2726 #define LMEM_FIXED 0x0000
2727 #define LMEM_MOVEABLE 0x0002
2728 #define LMEM_ZEROINIT 0x0040
2729 #define LPTR (LMEM_FIXED | LMEM_ZEROINIT)
2747 FlushInstructionCache(
2749 IN LPCVOID lpBaseAddress,
2752 #define MAX_LEADBYTES 12
2753 #define MAX_DEFAULTCHAR 2
2760 typedef struct _cpinfo {
2762 BYTE DefaultChar[MAX_DEFAULTCHAR];
2763 BYTE LeadByte[MAX_LEADBYTES];
2764 } CPINFO, *LPCPINFO;
2766 #define MB_PRECOMPOSED 0x00000001
2767 #define MB_ERR_INVALID_CHARS 0x00000008
2772 MultiByteToWideChar(
2775 IN LPCSTR lpMultiByteStr,
2777 OUT LPWSTR lpWideCharStr,
2778 IN int cchWideChar);
2780 #define WC_NO_BEST_FIT_CHARS 0x00000400
2785 WideCharToMultiByte(
2788 IN LPCWSTR lpWideCharStr,
2790 OUT LPSTR lpMultiByteStr,
2792 IN LPCSTR lpDefaultChar,
2793 OUT LPBOOL lpUsedDefaultChar);
2795 #define EXCEPTION_NONCONTINUABLE 0x1
2796 #define EXCEPTION_UNWINDING 0x2
2798 #define EXCEPTION_EXIT_UNWIND 0x4 // Exit unwind is in progress (not used by PAL SEH)
2799 #define EXCEPTION_NESTED_CALL 0x10 // Nested exception handler call
2800 #define EXCEPTION_TARGET_UNWIND 0x20 // Target unwind in progress
2801 #define EXCEPTION_COLLIDED_UNWIND 0x40 // Collided exception handler call
2802 #define EXCEPTION_SKIP_VEH 0x200
2804 #define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | \
2805 EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND)
2807 #define IS_DISPATCHING(Flag) ((Flag & EXCEPTION_UNWIND) == 0)
2808 #define IS_UNWINDING(Flag) ((Flag & EXCEPTION_UNWIND) != 0)
2809 #define IS_TARGET_UNWIND(Flag) (Flag & EXCEPTION_TARGET_UNWIND)
2811 #define EXCEPTION_IS_SIGNAL 0x100
2813 #define EXCEPTION_MAXIMUM_PARAMETERS 15
2815 // Index in the ExceptionInformation array where we will keep the reference
2816 // to the native exception that needs to be deleted when dispatching
2817 // exception in managed code.
2818 #define NATIVE_EXCEPTION_ASYNC_SLOT (EXCEPTION_MAXIMUM_PARAMETERS-1)
2820 typedef struct _EXCEPTION_RECORD {
2821 DWORD ExceptionCode;
2822 DWORD ExceptionFlags;
2823 struct _EXCEPTION_RECORD *ExceptionRecord;
2824 PVOID ExceptionAddress;
2825 DWORD NumberParameters;
2826 ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
2827 } EXCEPTION_RECORD, *PEXCEPTION_RECORD;
2829 typedef struct _EXCEPTION_POINTERS {
2830 PEXCEPTION_RECORD ExceptionRecord;
2831 PCONTEXT ContextRecord;
2832 } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS, *LPEXCEPTION_POINTERS;
2834 typedef LONG EXCEPTION_DISPOSITION;
2837 ExceptionContinueExecution,
2838 ExceptionContinueSearch,
2839 ExceptionNestedException,
2840 ExceptionCollidedUnwind,
2844 // A function table entry is generated for each frame function.
2846 typedef struct _RUNTIME_FUNCTION {
2852 } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
2854 #define STANDARD_RIGHTS_REQUIRED (0x000F0000L)
2855 #define SYNCHRONIZE (0x00100000L)
2856 #define READ_CONTROL (0x00020000L)
2857 #define MAXIMUM_ALLOWED (0x02000000L)
2859 #define EVENT_MODIFY_STATE (0x0002)
2860 #define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3)
2862 #define MUTANT_QUERY_STATE (0x0001)
2863 #define MUTANT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | MUTANT_QUERY_STATE)
2864 #define MUTEX_ALL_ACCESS MUTANT_ALL_ACCESS
2866 #define SEMAPHORE_MODIFY_STATE (0x0002)
2867 #define SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3)
2869 #define PROCESS_TERMINATE (0x0001)
2870 #define PROCESS_CREATE_THREAD (0x0002)
2871 #define PROCESS_SET_SESSIONID (0x0004)
2872 #define PROCESS_VM_OPERATION (0x0008)
2873 #define PROCESS_VM_READ (0x0010)
2874 #define PROCESS_VM_WRITE (0x0020)
2875 #define PROCESS_DUP_HANDLE (0x0040)
2876 #define PROCESS_CREATE_PROCESS (0x0080)
2877 #define PROCESS_SET_QUOTA (0x0100)
2878 #define PROCESS_SET_INFORMATION (0x0200)
2879 #define PROCESS_QUERY_INFORMATION (0x0400)
2880 #define PROCESS_SUSPEND_RESUME (0x0800)
2881 #define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
2888 IN DWORD dwDesiredAccess, /* PROCESS_DUP_HANDLE or PROCESS_ALL_ACCESS */
2889 IN BOOL bInheritHandle,
2890 IN DWORD dwProcessId
2898 OUT HMODULE *lphModule,
2900 OUT LPDWORD lpcbNeeded
2907 IN LPCSTR lpOutputString);
2913 IN LPCWSTR lpOutputStrig);
2916 #define OutputDebugString OutputDebugStringW
2918 #define OutputDebugString OutputDebugStringA
2929 GetEnvironmentVariableW(
2931 OUT LPWSTR lpBuffer,
2935 #define GetEnvironmentVariable GetEnvironmentVariableW
2937 #define GetEnvironmentVariable GetEnvironmentVariableA
2943 SetEnvironmentVariableW(
2945 IN LPCWSTR lpValue);
2948 #define SetEnvironmentVariable SetEnvironmentVariableW
2950 #define SetEnvironmentVariable SetEnvironmentVariableA
2956 GetEnvironmentStringsW();
2958 #define GetEnvironmentStrings GetEnvironmentStringsW
2963 FreeEnvironmentStringsW(
2966 #define FreeEnvironmentStrings FreeEnvironmentStringsW
2972 IN OUT HANDLE hObject);
2978 IN DWORD dwExceptionCode,
2979 IN DWORD dwExceptionFlags,
2980 IN DWORD nNumberOfArguments,
2981 IN CONST ULONG_PTR *lpArguments);
2986 RaiseFailFastException(
2987 IN PEXCEPTION_RECORD pExceptionRecord,
2988 IN PCONTEXT pContextRecord,
3004 QueryPerformanceCounter(
3005 OUT LARGE_INTEGER *lpPerformanceCount
3011 QueryPerformanceFrequency(
3012 OUT LARGE_INTEGER *lpFrequency
3018 QueryThreadCycleTime(
3019 IN HANDLE ThreadHandle,
3020 OUT PULONG64 CycleTime);
3028 typedef EXCEPTION_DISPOSITION (PALAPI_NOEXPORT *PVECTORED_EXCEPTION_HANDLER)(
3029 struct _EXCEPTION_POINTERS *ExceptionPointers);
3031 // Define BitScanForward64 and BitScanForward
3032 // Per MSDN, BitScanForward64 will search the mask data from LSB to MSB for a set bit.
3033 // If one is found, its bit position is stored in the out PDWORD argument and 1 is returned;
3034 // otherwise, an undefined value is stored in the out PDWORD argument and 0 is returned.
3036 // On GCC, the equivalent function is __builtin_ffsll. It returns 1+index of the least
3037 // significant set bit, or 0 if if mask is zero.
3039 // The same is true for BitScanForward, except that the GCC function is __builtin_ffs.
3046 IN OUT PDWORD Index,
3049 int iIndex = __builtin_ffs(qwMask);
3050 // Set the Index after deducting unity
3051 *Index = (DWORD)(iIndex - 1);
3052 // Both GCC and Clang generate better, smaller code if we check whether the
3053 // mask was/is zero rather than the equivalent check that iIndex is zero.
3054 return qwMask != 0 ? TRUE : FALSE;
3063 IN OUT PDWORD Index,
3066 int iIndex = __builtin_ffsll(qwMask);
3067 // Set the Index after deducting unity
3068 *Index = (DWORD)(iIndex - 1);
3069 // Both GCC and Clang generate better, smaller code if we check whether the
3070 // mask was/is zero rather than the equivalent check that iIndex is zero.
3071 return qwMask != 0 ? TRUE : FALSE;
3074 // Define BitScanReverse64 and BitScanReverse
3075 // Per MSDN, BitScanReverse64 will search the mask data from MSB to LSB for a set bit.
3076 // If one is found, its bit position is stored in the out PDWORD argument and 1 is returned.
3077 // Otherwise, an undefined value is stored in the out PDWORD argument and 0 is returned.
3079 // GCC/clang don't have a directly equivalent intrinsic; they do provide the __builtin_clzll
3080 // intrinsic, which returns the number of leading 0-bits in x starting at the most significant
3081 // bit position (the result is undefined when x = 0).
3083 // The same is true for BitScanReverse, except that the GCC function is __builtin_clzl.
3091 IN OUT PDWORD Index,
3094 // The result of __builtin_clzl is undefined when qwMask is zero,
3095 // but it's still OK to call the intrinsic in that case (just don't use the output).
3096 // Unconditionally calling the intrinsic in this way allows the compiler to
3097 // emit branchless code for this function when possible (depending on how the
3098 // intrinsic is implemented for the target platform).
3099 int lzcount = __builtin_clzl(qwMask);
3100 *Index = (DWORD)(31 - lzcount);
3110 IN OUT PDWORD Index,
3113 // The result of __builtin_clzll is undefined when qwMask is zero,
3114 // but it's still OK to call the intrinsic in that case (just don't use the output).
3115 // Unconditionally calling the intrinsic in this way allows the compiler to
3116 // emit branchless code for this function when possible (depending on how the
3117 // intrinsic is implemented for the target platform).
3118 int lzcount = __builtin_clzll(qwMask);
3119 *Index = (DWORD)(63 - lzcount);
3123 FORCEINLINE void PAL_ArmInterlockedOperationBarrier()
3126 // On arm64, most of the __sync* functions generate a code sequence like:
3128 // ldaxr (load acquire exclusive)
3130 // stlxr (store release exclusive)
3133 // It is possible for a load following the code sequence above to be reordered to occur prior to the store above due to the
3134 // release barrier, this is substantiated by https://github.com/dotnet/coreclr/pull/17508. Interlocked operations in the PAL
3135 // require the load to occur after the store. This memory barrier should be used following a call to a __sync* function to
3136 // prevent that reordering. Code generated for arm32 includes a 'dmb' after 'cbnz', so no issue there at the moment.
3137 __sync_synchronize();
3138 #endif // HOST_ARM64
3143 InterlockedIncrement
3145 The InterlockedIncrement function increments (increases by one) the
3146 value of the specified variable and checks the resulting value. The
3147 function prevents more than one thread from using the same variable
3153 [in/out] Pointer to the variable to increment.
3157 The return value is the resulting incremented value.
3165 InterlockedIncrement(
3166 IN OUT LONG volatile *lpAddend)
3168 LONG result = __sync_add_and_fetch(lpAddend, (LONG)1);
3169 PAL_ArmInterlockedOperationBarrier();
3178 InterlockedIncrement64(
3179 IN OUT LONGLONG volatile *lpAddend)
3181 LONGLONG result = __sync_add_and_fetch(lpAddend, (LONGLONG)1);
3182 PAL_ArmInterlockedOperationBarrier();
3188 InterlockedDecrement
3190 The InterlockedDecrement function decrements (decreases by one) the
3191 value of the specified variable and checks the resulting value. The
3192 function prevents more than one thread from using the same variable
3198 [in/out] Pointer to the variable to decrement.
3202 The return value is the resulting decremented value.
3210 InterlockedDecrement(
3211 IN OUT LONG volatile *lpAddend)
3213 LONG result = __sync_sub_and_fetch(lpAddend, (LONG)1);
3214 PAL_ArmInterlockedOperationBarrier();
3218 #define InterlockedDecrementAcquire InterlockedDecrement
3219 #define InterlockedDecrementRelease InterlockedDecrement
3226 InterlockedDecrement64(
3227 IN OUT LONGLONG volatile *lpAddend)
3229 LONGLONG result = __sync_sub_and_fetch(lpAddend, (LONGLONG)1);
3230 PAL_ArmInterlockedOperationBarrier();
3238 The InterlockedExchange function atomically exchanges a pair of
3239 values. The function prevents more than one thread from using the same
3240 variable simultaneously.
3245 [in/out] Pointer to the value to exchange. The function sets
3246 this variable to Value, and returns its prior value.
3248 [in] Specifies a new value for the variable pointed to by Target.
3252 The function returns the initial value pointed to by Target.
3260 InterlockedExchange(
3261 IN OUT LONG volatile *Target,
3264 LONG result = __atomic_exchange_n(Target, Value, __ATOMIC_ACQ_REL);
3265 PAL_ArmInterlockedOperationBarrier();
3274 InterlockedExchange64(
3275 IN OUT LONGLONG volatile *Target,
3278 LONGLONG result = __atomic_exchange_n(Target, Value, __ATOMIC_ACQ_REL);
3279 PAL_ArmInterlockedOperationBarrier();
3285 InterlockedCompareExchange
3287 The InterlockedCompareExchange function performs an atomic comparison
3288 of the specified values and exchanges the values, based on the outcome
3289 of the comparison. The function prevents more than one thread from
3290 using the same variable simultaneously.
3292 If you are exchanging pointer values, this function has been
3293 superseded by the InterlockedCompareExchangePointer function.
3297 Destination [in/out] Specifies the address of the destination value. The sign is ignored.
3298 Exchange [in] Specifies the exchange value. The sign is ignored.
3299 Comperand [in] Specifies the value to compare to Destination. The sign is ignored.
3303 The return value is the initial value of the destination.
3311 InterlockedCompareExchange(
3312 IN OUT LONG volatile *Destination,
3317 __sync_val_compare_and_swap(
3318 Destination, /* The pointer to a variable whose value is to be compared with. */
3319 Comperand, /* The value to be compared */
3320 Exchange /* The value to be stored */);
3321 PAL_ArmInterlockedOperationBarrier();
3325 #define InterlockedCompareExchangeAcquire InterlockedCompareExchange
3326 #define InterlockedCompareExchangeRelease InterlockedCompareExchange
3328 // See the 32-bit variant in interlock2.s
3334 InterlockedCompareExchange64(
3335 IN OUT LONGLONG volatile *Destination,
3336 IN LONGLONG Exchange,
3337 IN LONGLONG Comperand)
3340 __sync_val_compare_and_swap(
3341 Destination, /* The pointer to a variable whose value is to be compared with. */
3342 Comperand, /* The value to be compared */
3343 Exchange /* The value to be stored */);
3344 PAL_ArmInterlockedOperationBarrier();
3350 InterlockedExchangeAdd
3352 The InterlockedExchangeAdd function atomically adds the value of 'Value'
3353 to the variable that 'Addend' points to.
3358 [in/out] Pointer to the variable to to added.
3362 The return value is the original value that 'Addend' pointed to.
3370 InterlockedExchangeAdd(
3371 IN OUT LONG volatile *Addend,
3374 LONG result = __sync_fetch_and_add(Addend, Value);
3375 PAL_ArmInterlockedOperationBarrier();
3384 InterlockedExchangeAdd64(
3385 IN OUT LONGLONG volatile *Addend,
3388 LONGLONG result = __sync_fetch_and_add(Addend, Value);
3389 PAL_ArmInterlockedOperationBarrier();
3399 IN OUT LONG volatile *Destination,
3402 LONG result = __sync_fetch_and_and(Destination, Value);
3403 PAL_ArmInterlockedOperationBarrier();
3413 IN OUT LONG volatile *Destination,
3416 LONG result = __sync_fetch_and_or(Destination, Value);
3417 PAL_ArmInterlockedOperationBarrier();
3426 InterlockedBitTestAndReset(
3427 IN OUT LONG volatile *Base,
3430 return (InterlockedAnd(Base, ~(1 << Bit)) & (1 << Bit)) != 0;
3438 InterlockedBitTestAndSet(
3439 IN OUT LONG volatile *Base,
3442 return (InterlockedOr(Base, (1 << Bit)) & (1 << Bit)) != 0;
3445 #if defined(HOST_64BIT)
3446 #define InterlockedExchangePointer(Target, Value) \
3447 ((PVOID)InterlockedExchange64((PLONG64)(Target), (LONGLONG)(Value)))
3449 #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \
3450 ((PVOID)InterlockedCompareExchange64((PLONG64)(Destination), (LONGLONG)(ExChange), (LONGLONG)(Comperand)))
3452 #define InterlockedExchangePointer(Target, Value) \
3453 ((PVOID)(UINT_PTR)InterlockedExchange((PLONG)(UINT_PTR)(Target), (LONG)(UINT_PTR)(Value)))
3455 #define InterlockedCompareExchangePointer(Destination, ExChange, Comperand) \
3456 ((PVOID)(UINT_PTR)InterlockedCompareExchange((PLONG)(UINT_PTR)(Destination), (LONG)(UINT_PTR)(ExChange), (LONG)(UINT_PTR)(Comperand)))
3463 The MemoryBarrier function creates a full memory barrier.
3473 __sync_synchronize();
3483 #if defined(HOST_X86) || defined(HOST_AMD64)
3484 __asm__ __volatile__(
3487 #elif defined(HOST_ARM64)
3488 __asm__ __volatile__( "yield");
3497 GetCurrentProcessorNumber();
3501 PAL_HasGetCurrentProcessorNumber
3503 Checks if GetCurrentProcessorNumber is available in the current environment
3509 PAL_HasGetCurrentProcessorNumber();
3511 #define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
3512 #define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200
3513 #define FORMAT_MESSAGE_FROM_STRING 0x00000400
3514 #define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
3515 #define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x00002000
3516 #define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF
3523 IN LPCVOID lpSource,
3524 IN DWORD dwMessageId,
3525 IN DWORD dwLanguageId,
3528 IN va_list *Arguments);
3531 #define FormatMessage FormatMessageW
3544 IN DWORD dwErrCode);
3552 #define GetCommandLine GetCommandLineW
3559 IN PCONTEXT ContextRecord,
3560 IN PEXCEPTION_RECORD ExceptionRecord
3567 OUT PCONTEXT ContextRecord
3573 FlushProcessWriteBuffers();
3575 typedef void (*PAL_ActivationFunction)(CONTEXT *context);
3576 typedef BOOL (*PAL_SafeActivationCheckFunction)(SIZE_T ip, BOOL checkingCurrentThread);
3581 PAL_SetActivationFunction(
3582 IN PAL_ActivationFunction pActivationFunction,
3583 IN PAL_SafeActivationCheckFunction pSafeActivationCheckFunction);
3588 PAL_InjectActivation(
3592 #define VER_PLATFORM_WIN32_WINDOWS 1
3593 #define VER_PLATFORM_WIN32_NT 2
3594 #define VER_PLATFORM_UNIX 10
3595 #define VER_PLATFORM_MACOSX 11
3597 typedef struct _OSVERSIONINFOA {
3598 DWORD dwOSVersionInfoSize;
3599 DWORD dwMajorVersion;
3600 DWORD dwMinorVersion;
3601 DWORD dwBuildNumber;
3603 CHAR szCSDVersion[ 128 ];
3604 } OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA;
3606 typedef struct _OSVERSIONINFOW {
3607 DWORD dwOSVersionInfoSize;
3608 DWORD dwMajorVersion;
3609 DWORD dwMinorVersion;
3610 DWORD dwBuildNumber;
3612 WCHAR szCSDVersion[ 128 ];
3613 } OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW;
3616 typedef OSVERSIONINFOW OSVERSIONINFO;
3617 typedef POSVERSIONINFOW POSVERSIONINFO;
3618 typedef LPOSVERSIONINFOW LPOSVERSIONINFO;
3620 typedef OSVERSIONINFOA OSVERSIONINFO;
3621 typedef POSVERSIONINFOA POSVERSIONINFO;
3622 typedef LPOSVERSIONINFOA LPOSVERSIONINFO;
3625 typedef struct _OSVERSIONINFOEXA {
3626 DWORD dwOSVersionInfoSize;
3627 DWORD dwMajorVersion;
3628 DWORD dwMinorVersion;
3629 DWORD dwBuildNumber;
3631 CHAR szCSDVersion[ 128 ];
3632 WORD wServicePackMajor;
3633 WORD wServicePackMinor;
3637 } OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA;
3639 typedef struct _OSVERSIONINFOEXW {
3640 DWORD dwOSVersionInfoSize;
3641 DWORD dwMajorVersion;
3642 DWORD dwMinorVersion;
3643 DWORD dwBuildNumber;
3645 WCHAR szCSDVersion[ 128 ];
3646 WORD wServicePackMajor;
3647 WORD wServicePackMinor;
3651 } OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW;
3654 typedef OSVERSIONINFOEXW OSVERSIONINFOEX;
3655 typedef POSVERSIONINFOEXW POSVERSIONINFOEX;
3656 typedef LPOSVERSIONINFOEXW LPOSVERSIONINFOEX;
3658 typedef OSVERSIONINFOEXA OSVERSIONINFOEX;
3659 typedef POSVERSIONINFOEXA POSVERSIONINFOEX;
3660 typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX;
3663 #define IMAGE_FILE_MACHINE_I386 0x014c
3664 #define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian
3666 typedef struct _SYSTEM_INFO {
3667 WORD wProcessorArchitecture_PAL_Undefined;
3668 WORD wReserved_PAL_Undefined; // NOTE: diff from winbase.h - no obsolete dwOemId union
3670 LPVOID lpMinimumApplicationAddress;
3671 LPVOID lpMaximumApplicationAddress;
3672 DWORD_PTR dwActiveProcessorMask_PAL_Undefined;
3673 DWORD dwNumberOfProcessors;
3674 DWORD dwProcessorType_PAL_Undefined;
3675 DWORD dwAllocationGranularity;
3676 WORD wProcessorLevel_PAL_Undefined;
3677 WORD wProcessorRevision_PAL_Undefined;
3678 } SYSTEM_INFO, *LPSYSTEM_INFO;
3684 OUT LPSYSTEM_INFO lpSystemInfo);
3690 OUT PHANDLE hReadPipe,
3691 OUT PHANDLE hWritePipe,
3692 IN LPSECURITY_ATTRIBUTES lpPipeAttributes,
3697 // NUMA related APIs
3703 GetNumaHighestNodeNumber(
3704 OUT PULONG HighestNodeNumber
3710 PAL_GetNumaProcessorNode(WORD procNo, WORD* node);
3717 IN OPTIONAL LPVOID lpAddress,
3719 IN DWORD flAllocationType,
3721 IN DWORD nndPreferred
3727 PAL_SetCurrentThreadAffinity(WORD procNo);
3732 PAL_GetCurrentThreadAffinitySet(SIZE_T size, UINT_PTR* data);
3735 // The types of events that can be logged.
3737 #define EVENTLOG_SUCCESS 0x0000
3738 #define EVENTLOG_ERROR_TYPE 0x0001
3739 #define EVENTLOG_WARNING_TYPE 0x0002
3740 #define EVENTLOG_INFORMATION_TYPE 0x0004
3741 #define EVENTLOG_AUDIT_SUCCESS 0x0008
3742 #define EVENTLOG_AUDIT_FAILURE 0x0010
3744 #if defined FEATURE_PAL_ANSI
3745 #include "palprivate.h"
3746 #endif //FEATURE_PAL_ANSI
3747 /******************* C Runtime Entrypoints *******************************/
3749 /* Some C runtime functions needs to be reimplemented by the PAL.
3750 To avoid name collisions, those functions have been renamed using
3752 #ifndef PAL_STDCPP_COMPAT
3753 #define exit PAL_exit
3754 #define printf PAL_printf
3755 #define vprintf PAL_vprintf
3756 #define wprintf PAL_wprintf
3757 #define wcstod PAL_wcstod
3758 #define wcstoul PAL_wcstoul
3759 #define wcscat PAL_wcscat
3760 #define wcscpy PAL_wcscpy
3761 #define wcslen PAL_wcslen
3762 #define wcsncmp PAL_wcsncmp
3763 #define wcschr PAL_wcschr
3764 #define wcsrchr PAL_wcsrchr
3765 #define wcsstr PAL_wcsstr
3766 #define swscanf PAL_swscanf
3767 #define wcspbrk PAL_wcspbrk
3768 #define wcscmp PAL_wcscmp
3769 #define wcsncpy PAL_wcsncpy
3770 #define wcstok PAL_wcstok
3771 #define wcscspn PAL_wcscspn
3772 #define realloc PAL_realloc
3773 #define fopen PAL_fopen
3774 #define strtok PAL_strtok
3775 #define strtoul PAL_strtoul
3776 #define strtoull PAL_strtoull
3777 #define fprintf PAL_fprintf
3778 #define fwprintf PAL_fwprintf
3779 #define vfprintf PAL_vfprintf
3780 #define vfwprintf PAL_vfwprintf
3781 #define rand PAL_rand
3782 #define time PAL_time
3783 #define getenv PAL_getenv
3784 #define fgets PAL_fgets
3785 #define qsort PAL_qsort
3786 #define bsearch PAL_bsearch
3787 #define ferror PAL_ferror
3788 #define fread PAL_fread
3789 #define fwrite PAL_fwrite
3790 #define ftell PAL_ftell
3791 #define fclose PAL_fclose
3792 #define fflush PAL_fflush
3793 #define fputs PAL_fputs
3794 #define fseek PAL_fseek
3795 #define fgetpos PAL_fgetpos
3796 #define fsetpos PAL_fsetpos
3797 #define setvbuf PAL_setvbuf
3798 #define acos PAL_acos
3799 #define acosh PAL_acosh
3800 #define asin PAL_asin
3801 #define asinh PAL_asinh
3802 #define atan2 PAL_atan2
3805 #define ilogb PAL_ilogb
3807 #define log2 PAL_log2
3808 #define log10 PAL_log10
3810 #define sincos PAL_sincos
3811 #define acosf PAL_acosf
3812 #define acoshf PAL_acoshf
3813 #define asinf PAL_asinf
3814 #define asinhf PAL_asinhf
3815 #define atan2f PAL_atan2f
3816 #define expf PAL_expf
3817 #define fmaf PAL_fmaf
3818 #define ilogbf PAL_ilogbf
3819 #define logf PAL_logf
3820 #define log2f PAL_log2f
3821 #define log10f PAL_log10f
3822 #define powf PAL_powf
3823 #define sincosf PAL_sincosf
3824 #define malloc PAL_malloc
3825 #define free PAL_free
3826 #define _strdup PAL__strdup
3827 #define _open PAL__open
3828 #define _pread PAL__pread
3829 #define _close PAL__close
3830 #define _wcstoui64 PAL__wcstoui64
3831 #define _flushall PAL__flushall
3832 #define strnlen PAL_strnlen
3833 #define wcsnlen PAL_wcsnlen
3836 #define _mm_getcsr PAL__mm_getcsr
3837 #define _mm_setcsr PAL__mm_setcsr
3838 #endif // HOST_AMD64
3840 #endif // !PAL_STDCPP_COMPAT
3842 #ifndef _CONST_RETURN
3844 #define _CONST_RETURN const
3845 #define _CRT_CONST_CORRECT_OVERLOADS
3847 #define _CONST_RETURN
3851 /* For backwards compatibility */
3852 #define _WConst_return _CONST_RETURN
3856 typedef int errno_t;
3858 #if defined(__WINT_TYPE__)
3859 typedef __WINT_TYPE__ wint_t;
3861 typedef unsigned int wint_t;
3864 #ifndef PAL_STDCPP_COMPAT
3872 Overlapping buffer-safe version of memcpy.
3873 See MSDN doc for memcpy
3878 void *PAL_memcpy (void *dest, const void * src, size_t count);
3880 PALIMPORT void * __cdecl memcpy(void *, const void *, size_t) THROW_DECL;
3882 #define memcpy PAL_memcpy
3883 #define IS_PAL_memcpy 1
3884 #define TEST_PAL_DEFERRED(def) IS_##def
3885 #define IS_REDEFINED_IN_PAL(def) TEST_PAL_DEFERRED(def)
3886 #else //defined(_DEBUG)
3887 PALIMPORT void * __cdecl memcpy(void *, const void *, size_t);
3888 #endif //defined(_DEBUG)
3889 PALIMPORT int __cdecl memcmp(const void *, const void *, size_t);
3890 PALIMPORT void * __cdecl memset(void *, int, size_t);
3891 PALIMPORT void * __cdecl memmove(void *, const void *, size_t);
3892 PALIMPORT void * __cdecl memchr(const void *, int, size_t);
3893 PALIMPORT long long int __cdecl atoll(const char *)
3898 PALIMPORT size_t __cdecl strlen(const char *);
3899 PALIMPORT int __cdecl strcmp(const char*, const char *);
3900 PALIMPORT int __cdecl strncmp(const char*, const char *, size_t);
3901 PALIMPORT int __cdecl _strnicmp(const char *, const char *, size_t);
3902 PALIMPORT char * __cdecl strcat(char *, const char *);
3903 PALIMPORT char * __cdecl strncat(char *, const char *, size_t);
3904 PALIMPORT char * __cdecl strcpy(char *, const char *);
3905 PALIMPORT char * __cdecl strncpy(char *, const char *, size_t);
3906 PALIMPORT char * __cdecl strchr(const char *, int);
3907 PALIMPORT char * __cdecl strrchr(const char *, int);
3908 PALIMPORT char * __cdecl strpbrk(const char *, const char *);
3909 PALIMPORT char * __cdecl strstr(const char *, const char *);
3910 PALIMPORT char * __cdecl strtok(char *, const char *);
3911 PALIMPORT size_t __cdecl strspn(const char *, const char *);
3912 PALIMPORT size_t __cdecl strcspn(const char *, const char *);
3913 PALIMPORT int __cdecl atoi(const char *);
3914 PALIMPORT ULONG __cdecl strtoul(const char *, char **, int);
3915 PALIMPORT ULONGLONG __cdecl strtoull(const char *, char **, int);
3916 PALIMPORT double __cdecl atof(const char *);
3917 PALIMPORT double __cdecl strtod(const char *, char **);
3918 PALIMPORT int __cdecl isprint(int);
3919 PALIMPORT int __cdecl isspace(int);
3920 PALIMPORT int __cdecl isalpha(int);
3921 PALIMPORT int __cdecl isalnum(int);
3922 PALIMPORT int __cdecl isdigit(int);
3923 PALIMPORT int __cdecl isxdigit(int);
3924 PALIMPORT int __cdecl isupper(int);
3925 PALIMPORT int __cdecl islower(int);
3926 PALIMPORT int __cdecl tolower(int);
3927 PALIMPORT int __cdecl toupper(int);
3928 PALIMPORT int __cdecl iswalpha(wint_t);
3929 PALIMPORT int __cdecl iswdigit(wint_t);
3930 PALIMPORT int __cdecl iswupper(wint_t);
3931 PALIMPORT int __cdecl iswprint(wint_t);
3932 PALIMPORT int __cdecl iswspace(wint_t);
3933 PALIMPORT int __cdecl iswxdigit(wint_t);
3934 PALIMPORT wint_t __cdecl towupper(wint_t);
3935 PALIMPORT wint_t __cdecl towlower(wint_t);
3936 #endif // PAL_STDCPP_COMPAT
3939 #if !defined(_TRUNCATE)
3940 #define _TRUNCATE ((size_t)-1)
3943 PALIMPORT DLLEXPORT errno_t __cdecl memcpy_s(void *, size_t, const void *, size_t) THROW_DECL;
3944 PALIMPORT errno_t __cdecl memmove_s(void *, size_t, const void *, size_t);
3945 PALIMPORT DLLEXPORT int __cdecl _stricmp(const char *, const char *);
3946 PALIMPORT DLLEXPORT int __cdecl vsprintf_s(char *, size_t, const char *, va_list);
3947 PALIMPORT char * __cdecl _gcvt_s(char *, int, double, int);
3948 PALIMPORT int __cdecl __iscsym(int);
3949 PALIMPORT DLLEXPORT int __cdecl _wcsicmp(const WCHAR *, const WCHAR*);
3950 PALIMPORT int __cdecl _wcsnicmp(const WCHAR *, const WCHAR *, size_t);
3951 PALIMPORT int __cdecl _vsnprintf(char *, size_t, const char *, va_list);
3952 PALIMPORT DLLEXPORT int __cdecl _vsnprintf_s(char *, size_t, size_t, const char *, va_list);
3953 PALIMPORT DLLEXPORT int __cdecl _vsnwprintf_s(WCHAR *, size_t, size_t, const WCHAR *, va_list);
3954 PALIMPORT DLLEXPORT int __cdecl _snwprintf_s(WCHAR *, size_t, size_t, const WCHAR *, ...);
3955 PALIMPORT DLLEXPORT int __cdecl _snprintf_s(char *, size_t, size_t, const char *, ...);
3956 PALIMPORT DLLEXPORT int __cdecl sprintf_s(char *, size_t, const char *, ... );
3957 PALIMPORT DLLEXPORT int __cdecl swprintf_s(WCHAR *, size_t, const WCHAR *, ... );
3958 PALIMPORT int __cdecl _snwprintf_s(WCHAR *, size_t, size_t, const WCHAR *, ...);
3959 PALIMPORT int __cdecl vswprintf_s( WCHAR *, size_t, const WCHAR *, va_list);
3960 PALIMPORT DLLEXPORT int __cdecl sscanf_s(const char *, const char *, ...);
3961 PALIMPORT DLLEXPORT errno_t __cdecl _itow_s(int, WCHAR *, size_t, int);
3963 PALIMPORT DLLEXPORT size_t __cdecl PAL_wcslen(const WCHAR *);
3964 PALIMPORT DLLEXPORT int __cdecl PAL_wcscmp(const WCHAR*, const WCHAR*);
3965 PALIMPORT DLLEXPORT int __cdecl PAL_wcsncmp(const WCHAR *, const WCHAR *, size_t);
3966 PALIMPORT DLLEXPORT WCHAR * __cdecl PAL_wcscat(WCHAR *, const WCHAR *);
3967 PALIMPORT WCHAR * __cdecl PAL_wcscpy(WCHAR *, const WCHAR *);
3968 PALIMPORT WCHAR * __cdecl PAL_wcsncpy(WCHAR *, const WCHAR *, size_t);
3969 PALIMPORT DLLEXPORT const WCHAR * __cdecl PAL_wcschr(const WCHAR *, WCHAR);
3970 PALIMPORT DLLEXPORT const WCHAR * __cdecl PAL_wcsrchr(const WCHAR *, WCHAR);
3971 PALIMPORT WCHAR _WConst_return * __cdecl PAL_wcspbrk(const WCHAR *, const WCHAR *);
3972 PALIMPORT DLLEXPORT WCHAR _WConst_return * __cdecl PAL_wcsstr(const WCHAR *, const WCHAR *);
3973 PALIMPORT WCHAR * __cdecl PAL_wcstok(WCHAR *, const WCHAR *);
3974 PALIMPORT DLLEXPORT size_t __cdecl PAL_wcscspn(const WCHAR *, const WCHAR *);
3975 PALIMPORT int __cdecl PAL_swprintf(WCHAR *, const WCHAR *, ...);
3976 PALIMPORT int __cdecl PAL_vswprintf(WCHAR *, const WCHAR *, va_list);
3977 PALIMPORT int __cdecl PAL_swscanf(const WCHAR *, const WCHAR *, ...);
3978 PALIMPORT DLLEXPORT ULONG __cdecl PAL_wcstoul(const WCHAR *, WCHAR **, int);
3979 PALIMPORT double __cdecl PAL_wcstod(const WCHAR *, WCHAR **);
3981 PALIMPORT errno_t __cdecl _wcslwr_s(WCHAR *, size_t sz);
3982 PALIMPORT DLLEXPORT ULONGLONG _wcstoui64(const WCHAR *, WCHAR **, int);
3983 PALIMPORT DLLEXPORT errno_t __cdecl _i64tow_s(long long, WCHAR *, size_t, int);
3984 PALIMPORT int __cdecl _wtoi(const WCHAR *);
3988 inline WCHAR *PAL_wcschr(WCHAR* S, WCHAR C)
3989 {return ((WCHAR *)PAL_wcschr((const WCHAR *)S, C)); }
3990 inline WCHAR *PAL_wcsrchr(WCHAR* S, WCHAR C)
3991 {return ((WCHAR *)PAL_wcsrchr((const WCHAR *)S, C)); }
3992 inline WCHAR *PAL_wcspbrk(WCHAR* S, const WCHAR* P)
3993 {return ((WCHAR *)PAL_wcspbrk((const WCHAR *)S, P)); }
3994 inline WCHAR *PAL_wcsstr(WCHAR* S, const WCHAR* P)
3995 {return ((WCHAR *)PAL_wcsstr((const WCHAR *)S, P)); }
3999 #if defined(__llvm__)
4000 #define HAS_ROTL __has_builtin(_rotl)
4001 #define HAS_ROTR __has_builtin(_rotr)
4017 unsigned int __cdecl _rotl(unsigned int value, int shift)
4019 unsigned int retval = 0;
4022 retval = (value << shift) | (value >> (sizeof(int) * CHAR_BIT - shift));
4027 // On 64 bit unix, make the long an int.
4029 #define _lrotl _rotl
4030 #endif // HOST_64BIT
4043 unsigned int __cdecl _rotr(unsigned int value, int shift)
4045 unsigned int retval;
4048 retval = (value >> shift) | (value << (sizeof(int) * CHAR_BIT - shift));
4054 PALIMPORT int __cdecl abs(int);
4055 // clang complains if this is declared with __int64
4056 PALIMPORT long long __cdecl llabs(long long);
4057 #ifndef PAL_STDCPP_COMPAT
4059 PALIMPORT int __cdecl _finite(double);
4060 PALIMPORT int __cdecl _isnan(double);
4061 PALIMPORT double __cdecl _copysign(double, double);
4062 PALIMPORT double __cdecl acos(double);
4063 PALIMPORT double __cdecl acosh(double);
4064 PALIMPORT double __cdecl asin(double);
4065 PALIMPORT double __cdecl asinh(double);
4066 PALIMPORT double __cdecl atan(double) THROW_DECL;
4067 PALIMPORT double __cdecl atanh(double)
4072 PALIMPORT double __cdecl atan2(double, double);
4073 PALIMPORT double __cdecl cbrt(double)
4078 PALIMPORT double __cdecl ceil(double);
4079 PALIMPORT double __cdecl cos(double);
4080 PALIMPORT double __cdecl cosh(double);
4081 PALIMPORT double __cdecl exp(double);
4082 PALIMPORT double __cdecl fabs(double);
4083 PALIMPORT double __cdecl floor(double);
4084 PALIMPORT double __cdecl fmod(double, double);
4085 PALIMPORT double __cdecl fma(double, double, double);
4086 PALIMPORT int __cdecl ilogb(double);
4087 PALIMPORT double __cdecl log(double);
4088 PALIMPORT double __cdecl log2(double);
4089 PALIMPORT double __cdecl log10(double);
4090 PALIMPORT double __cdecl modf(double, double*);
4091 PALIMPORT double __cdecl pow(double, double);
4092 PALIMPORT double __cdecl sin(double);
4093 PALIMPORT void __cdecl sincos(double, double*, double*);
4094 PALIMPORT double __cdecl sinh(double);
4095 PALIMPORT double __cdecl sqrt(double);
4096 PALIMPORT double __cdecl tan(double);
4097 PALIMPORT double __cdecl tanh(double);
4099 PALIMPORT int __cdecl _finitef(float);
4100 PALIMPORT int __cdecl _isnanf(float);
4101 PALIMPORT float __cdecl _copysignf(float, float);
4102 PALIMPORT float __cdecl acosf(float);
4103 PALIMPORT float __cdecl acoshf(float);
4104 PALIMPORT float __cdecl asinf(float);
4105 PALIMPORT float __cdecl asinhf(float);
4106 PALIMPORT float __cdecl atanf(float)
4111 PALIMPORT float __cdecl atanhf(float)
4116 PALIMPORT float __cdecl atan2f(float, float);
4117 PALIMPORT float __cdecl cbrtf(float)
4122 PALIMPORT float __cdecl ceilf(float);
4123 PALIMPORT float __cdecl cosf(float);
4124 PALIMPORT float __cdecl coshf(float);
4125 PALIMPORT float __cdecl expf(float);
4126 PALIMPORT float __cdecl fabsf(float);
4127 PALIMPORT float __cdecl floorf(float);
4128 PALIMPORT float __cdecl fmodf(float, float);
4129 PALIMPORT float __cdecl fmaf(float, float, float);
4130 PALIMPORT int __cdecl ilogbf(float);
4131 PALIMPORT float __cdecl logf(float);
4132 PALIMPORT float __cdecl log2f(float);
4133 PALIMPORT float __cdecl log10f(float);
4134 PALIMPORT float __cdecl modff(float, float*);
4135 PALIMPORT float __cdecl powf(float, float);
4136 PALIMPORT float __cdecl sinf(float);
4137 PALIMPORT void __cdecl sincosf(float, float*, float*);
4138 PALIMPORT float __cdecl sinhf(float);
4139 PALIMPORT float __cdecl sqrtf(float);
4140 PALIMPORT float __cdecl tanf(float);
4141 PALIMPORT float __cdecl tanhf(float);
4142 #endif // !PAL_STDCPP_COMPAT
4144 #ifndef PAL_STDCPP_COMPAT
4149 inline __int64 abs(__int64 _X) {
4156 PALIMPORT DLLEXPORT void * __cdecl malloc(size_t);
4157 PALIMPORT DLLEXPORT void __cdecl free(void *);
4158 PALIMPORT DLLEXPORT void * __cdecl realloc(void *, size_t);
4159 PALIMPORT char * __cdecl _strdup(const char *);
4161 #if defined(_MSC_VER)
4162 #define alloca _alloca
4164 #define _alloca alloca
4167 #define alloca __builtin_alloca
4169 #define max(a, b) (((a) > (b)) ? (a) : (b))
4170 #define min(a, b) (((a) < (b)) ? (a) : (b))
4172 #endif // !PAL_STDCPP_COMPAT
4174 PALIMPORT PAL_NORETURN void __cdecl exit(int);
4176 #ifndef PAL_STDCPP_COMPAT
4178 PALIMPORT DLLEXPORT void __cdecl qsort(void *, size_t, size_t, int(__cdecl *)(const void *, const void *));
4179 PALIMPORT DLLEXPORT void * __cdecl bsearch(const void *, const void *, size_t, size_t,
4180 int(__cdecl *)(const void *, const void *));
4182 PALIMPORT time_t __cdecl time(time_t *);
4184 #endif // !PAL_STDCPP_COMPAT
4186 PALIMPORT DLLEXPORT int __cdecl _open(const char *szPath, int nFlags, ...);
4187 PALIMPORT DLLEXPORT size_t __cdecl _pread(int fd, void *buf, size_t nbytes, ULONG64 offset);
4188 PALIMPORT DLLEXPORT int __cdecl _close(int);
4189 PALIMPORT DLLEXPORT int __cdecl _flushall();
4191 #ifdef PAL_STDCPP_COMPAT
4194 typedef struct _PAL_FILE PAL_FILE;
4196 #else // PAL_STDCPP_COMPAT
4199 typedef struct _FILE FILE;
4200 typedef struct _FILE PAL_FILE;
4206 /* Locale categories */
4208 #define LC_COLLATE 1
4210 #define LC_MONETARY 3
4211 #define LC_NUMERIC 4
4214 #define _IOFBF 0 /* setvbuf should set fully buffered */
4215 #define _IOLBF 1 /* setvbuf should set line buffered */
4216 #define _IONBF 2 /* setvbuf should set unbuffered */
4218 #endif // PAL_STDCPP_COMPAT
4220 PALIMPORT int __cdecl PAL_fclose(PAL_FILE *);
4221 PALIMPORT DLLEXPORT int __cdecl PAL_fflush(PAL_FILE *);
4222 PALIMPORT size_t __cdecl PAL_fwrite(const void *, size_t, size_t, PAL_FILE *);
4223 PALIMPORT size_t __cdecl PAL_fread(void *, size_t, size_t, PAL_FILE *);
4224 PALIMPORT char * __cdecl PAL_fgets(char *, int, PAL_FILE *);
4225 PALIMPORT int __cdecl PAL_fputs(const char *, PAL_FILE *);
4226 PALIMPORT DLLEXPORT int __cdecl PAL_fprintf(PAL_FILE *, const char *, ...);
4227 PALIMPORT int __cdecl PAL_vfprintf(PAL_FILE *, const char *, va_list);
4228 PALIMPORT int __cdecl PAL_fseek(PAL_FILE *, LONG, int);
4229 PALIMPORT LONG __cdecl PAL_ftell(PAL_FILE *);
4230 PALIMPORT int __cdecl PAL_ferror(PAL_FILE *);
4231 PALIMPORT PAL_FILE * __cdecl PAL_fopen(const char *, const char *);
4232 PALIMPORT int __cdecl PAL_setvbuf(PAL_FILE *stream, char *, int, size_t);
4233 PALIMPORT DLLEXPORT int __cdecl PAL_fwprintf(PAL_FILE *, const WCHAR *, ...);
4234 PALIMPORT int __cdecl PAL_vfwprintf(PAL_FILE *, const WCHAR *, va_list);
4235 PALIMPORT int __cdecl PAL_wprintf(const WCHAR*, ...);
4237 PALIMPORT int __cdecl _getw(PAL_FILE *);
4238 PALIMPORT int __cdecl _putw(int, PAL_FILE *);
4239 PALIMPORT PAL_FILE * __cdecl _fdopen(int, const char *);
4240 PALIMPORT PAL_FILE * __cdecl _wfopen(const WCHAR *, const WCHAR *);
4242 /* Maximum value that can be returned by the rand function. */
4244 #ifndef PAL_STDCPP_COMPAT
4245 #define RAND_MAX 0x7fff
4246 #endif // !PAL_STDCPP_COMPAT
4248 PALIMPORT int __cdecl rand(void);
4249 PALIMPORT void __cdecl srand(unsigned int);
4251 PALIMPORT DLLEXPORT int __cdecl printf(const char *, ...);
4252 PALIMPORT int __cdecl vprintf(const char *, va_list);
4255 #define PAL_get_caller _MSC_VER
4257 #define PAL_get_caller 0
4260 PALIMPORT DLLEXPORT PAL_FILE * __cdecl PAL_get_stdout(int caller);
4261 PALIMPORT PAL_FILE * __cdecl PAL_get_stdin(int caller);
4262 PALIMPORT DLLEXPORT PAL_FILE * __cdecl PAL_get_stderr(int caller);
4263 PALIMPORT DLLEXPORT int * __cdecl PAL_errno(int caller);
4265 #ifdef PAL_STDCPP_COMPAT
4266 #define PAL_stdout (PAL_get_stdout(PAL_get_caller))
4267 #define PAL_stdin (PAL_get_stdin(PAL_get_caller))
4268 #define PAL_stderr (PAL_get_stderr(PAL_get_caller))
4269 #define PAL_errno (*PAL_errno(PAL_get_caller))
4270 #else // PAL_STDCPP_COMPAT
4271 #define stdout (PAL_get_stdout(PAL_get_caller))
4272 #define stdin (PAL_get_stdin(PAL_get_caller))
4273 #define stderr (PAL_get_stderr(PAL_get_caller))
4274 #define errno (*PAL_errno(PAL_get_caller))
4275 #endif // PAL_STDCPP_COMPAT
4277 PALIMPORT DLLEXPORT char * __cdecl getenv(const char *);
4278 PALIMPORT DLLEXPORT int __cdecl _putenv(const char *);
4282 PALIMPORT WCHAR __cdecl PAL_ToUpperInvariant(WCHAR);
4283 PALIMPORT WCHAR __cdecl PAL_ToLowerInvariant(WCHAR);
4285 /******************* PAL-specific I/O completion port *****************/
4287 typedef struct _PAL_IOCP_CPU_INFORMATION {
4289 FILETIME ftLastRecordedIdleTime;
4290 FILETIME ftLastRecordedCurrentTime;
4292 FILETIME ftLastRecordedKernelTime;
4293 FILETIME ftLastRecordedUserTime;
4294 } PAL_IOCP_CPU_INFORMATION;
4300 IN OUT PAL_IOCP_CPU_INFORMATION *lpPrevCPUInfo);
4302 /****************PAL Perf functions for PInvoke*********************/
4307 PAL_EnableProcessProfile();
4312 PAL_DisableProcessProfile();
4317 PAL_IsProcessProfileEnabled();
4322 PAL_GetCpuTickCount();
4325 /******************* PAL functions for SIMD extensions *****************/
4328 unsigned int _mm_getcsr(void);
4331 void _mm_setcsr(unsigned int i);
4333 /******************* PAL functions for CPU capability detection *******/
4342 PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags);
4351 PAL_FreeExceptionRecords(
4352 IN EXCEPTION_RECORD *exceptionRecord,
4353 IN CONTEXT *contextRecord);
4355 #define EXCEPTION_CONTINUE_SEARCH 0
4356 #define EXCEPTION_EXECUTE_HANDLER 1
4357 #define EXCEPTION_CONTINUE_EXECUTION -1
4359 struct PAL_SEHException
4362 static const SIZE_T NoTargetFrameSp = (SIZE_T)SIZE_MAX;
4364 void Move(PAL_SEHException& ex)
4366 ExceptionPointers.ExceptionRecord = ex.ExceptionPointers.ExceptionRecord;
4367 ExceptionPointers.ContextRecord = ex.ExceptionPointers.ContextRecord;
4368 TargetFrameSp = ex.TargetFrameSp;
4369 RecordsOnStack = ex.RecordsOnStack;
4376 if (ExceptionPointers.ExceptionRecord != NULL && !RecordsOnStack )
4378 PAL_FreeExceptionRecords(ExceptionPointers.ExceptionRecord, ExceptionPointers.ContextRecord);
4379 ExceptionPointers.ExceptionRecord = NULL;
4380 ExceptionPointers.ContextRecord = NULL;
4385 EXCEPTION_POINTERS ExceptionPointers;
4386 // Target frame stack pointer set before the 2nd pass.
4387 SIZE_T TargetFrameSp;
4388 bool RecordsOnStack;
4390 PAL_SEHException(EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContextRecord, bool onStack = false)
4392 ExceptionPointers.ExceptionRecord = pExceptionRecord;
4393 ExceptionPointers.ContextRecord = pContextRecord;
4394 TargetFrameSp = NoTargetFrameSp;
4395 RecordsOnStack = onStack;
4403 // The copy constructor and copy assignment operators are deleted so that the PAL_SEHException
4404 // can never be copied, only moved. This enables simple lifetime management of the exception and
4405 // context records, since there is always just one PAL_SEHException instance referring to the same records.
4406 PAL_SEHException(const PAL_SEHException& ex) = delete;
4407 PAL_SEHException& operator=(const PAL_SEHException& ex) = delete;
4409 PAL_SEHException(PAL_SEHException&& ex)
4414 PAL_SEHException& operator=(PAL_SEHException&& ex)
4428 ExceptionPointers.ExceptionRecord = NULL;
4429 ExceptionPointers.ContextRecord = NULL;
4430 TargetFrameSp = NoTargetFrameSp;
4431 RecordsOnStack = false;
4434 CONTEXT* GetContextRecord()
4436 return ExceptionPointers.ContextRecord;
4439 EXCEPTION_RECORD* GetExceptionRecord()
4441 return ExceptionPointers.ExceptionRecord;
4446 return (TargetFrameSp == NoTargetFrameSp);
4449 void SecondPassDone()
4451 TargetFrameSp = NoTargetFrameSp;
4455 typedef BOOL (*PHARDWARE_EXCEPTION_HANDLER)(PAL_SEHException* ex);
4456 typedef BOOL (*PHARDWARE_EXCEPTION_SAFETY_CHECK_FUNCTION)(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord);
4457 typedef VOID (*PTERMINATION_REQUEST_HANDLER)(int terminationExitCode);
4458 typedef DWORD (*PGET_GCMARKER_EXCEPTION_CODE)(LPVOID ip);
4463 PAL_SetHardwareExceptionHandler(
4464 IN PHARDWARE_EXCEPTION_HANDLER exceptionHandler,
4465 IN PHARDWARE_EXCEPTION_SAFETY_CHECK_FUNCTION exceptionCheckFunction);
4470 PAL_SetGetGcMarkerExceptionCode(
4471 IN PGET_GCMARKER_EXCEPTION_CODE getGcMarkerExceptionCode);
4476 PAL_ThrowExceptionFromContext(
4477 IN CONTEXT* context,
4478 IN PAL_SEHException* ex);
4483 PAL_SetTerminationRequestHandler(
4484 IN PTERMINATION_REQUEST_HANDLER terminationRequestHandler);
4489 PAL_CatchHardwareExceptionHolderEnter();
4494 PAL_CatchHardwareExceptionHolderExit();
4497 // This holder is used to indicate that a hardware
4498 // exception should be raised as a C++ exception
4499 // to better emulate SEH on the xplat platforms.
4501 class CatchHardwareExceptionHolder
4504 CatchHardwareExceptionHolder()
4506 PAL_CatchHardwareExceptionHolderEnter();
4509 ~CatchHardwareExceptionHolder()
4511 PAL_CatchHardwareExceptionHolderExit();
4514 static bool IsEnabled();
4518 // NOTE: This is only defined in one PAL test.
4520 #ifdef FEATURE_ENABLE_HARDWARE_EXCEPTIONS
4521 #define HardwareExceptionHolder CatchHardwareExceptionHolder __catchHardwareException;
4523 #define HardwareExceptionHolder
4524 #endif // FEATURE_ENABLE_HARDWARE_EXCEPTIONS
4526 class NativeExceptionHolderBase;
4530 NativeExceptionHolderBase **
4531 PAL_GetNativeExceptionHolderHead();
4536 // This is the base class of native exception holder used to provide
4537 // the filter function to the exception dispatcher. This allows the
4538 // filter to be called during the first pass to better emulate SEH
4539 // the xplat platforms that only have C++ exception support.
4541 class NativeExceptionHolderBase
4543 // Save the address of the holder head so the destructor
4544 // doesn't have access the slow (on Linux) TLS value again.
4545 NativeExceptionHolderBase **m_head;
4547 // The next holder on the stack
4548 NativeExceptionHolderBase *m_next;
4551 NativeExceptionHolderBase()
4557 ~NativeExceptionHolderBase()
4559 // Only destroy if Push was called
4560 if (m_head != nullptr)
4569 // Calls the holder's filter handler.
4570 virtual EXCEPTION_DISPOSITION InvokeFilter(PAL_SEHException& ex) = 0;
4572 // Adds the holder to the "stack" of holders. This is done explicitly instead
4573 // of in the constructor was to avoid the mess of move constructors combined
4574 // with return value optimization (in CreateHolder).
4577 NativeExceptionHolderBase **head = PAL_GetNativeExceptionHolderHead();
4583 // Given the currentHolder and locals stack range find the next holder starting with this one
4584 // To find the first holder, pass nullptr as the currentHolder.
4585 static NativeExceptionHolderBase *FindNextHolder(NativeExceptionHolderBase *currentHolder, PVOID frameLowAddress, PVOID frameHighAddress);
4589 // This is the second part of the native exception filter holder. It is
4590 // templated because the lambda used to wrap the exception filter is a
4593 template<class FilterType>
4594 class NativeExceptionHolder : public NativeExceptionHolderBase
4596 FilterType* m_exceptionFilter;
4599 NativeExceptionHolder(FilterType* exceptionFilter)
4600 : NativeExceptionHolderBase()
4602 m_exceptionFilter = exceptionFilter;
4605 virtual EXCEPTION_DISPOSITION InvokeFilter(PAL_SEHException& ex)
4607 return (*m_exceptionFilter)(ex);
4612 // This is a native exception holder that is used when the catch catches
4615 class NativeExceptionHolderCatchAll : public NativeExceptionHolderBase
4619 NativeExceptionHolderCatchAll()
4620 : NativeExceptionHolderBase()
4624 virtual EXCEPTION_DISPOSITION InvokeFilter(PAL_SEHException& ex)
4626 return EXCEPTION_EXECUTE_HANDLER;
4630 // This is a native exception holder that doesn't catch any exceptions.
4631 class NativeExceptionHolderNoCatch : public NativeExceptionHolderBase
4635 NativeExceptionHolderNoCatch()
4636 : NativeExceptionHolderBase()
4640 virtual EXCEPTION_DISPOSITION InvokeFilter(PAL_SEHException& ex)
4642 return EXCEPTION_CONTINUE_SEARCH;
4647 // This factory class for the native exception holder is necessary because
4648 // templated functions don't need the explicit type parameter and can infer
4649 // the template type from the parameter.
4651 class NativeExceptionHolderFactory
4654 template<class FilterType>
4655 static NativeExceptionHolder<FilterType> CreateHolder(FilterType* exceptionFilter)
4657 return NativeExceptionHolder<FilterType>(exceptionFilter);
4661 // Start of a try block for exceptions raised by RaiseException
4662 #define PAL_TRY(__ParamType, __paramDef, __paramRef) \
4664 __ParamType __param = __paramRef; \
4665 auto tryBlock = [](__ParamType __paramDef) \
4668 // Start of an exception handler. If an exception raised by the RaiseException
4669 // occurs in the try block and the disposition is EXCEPTION_EXECUTE_HANDLER,
4670 // the handler code is executed. If the disposition is EXCEPTION_CONTINUE_SEARCH,
4671 // the exception is rethrown. The EXCEPTION_CONTINUE_EXECUTION disposition is
4673 #define PAL_EXCEPT(dispositionExpression) \
4675 const bool isFinally = false; \
4676 auto finallyBlock = []() {}; \
4677 EXCEPTION_DISPOSITION disposition = EXCEPTION_CONTINUE_EXECUTION; \
4678 auto exceptionFilter = [&disposition, &__param](PAL_SEHException& ex) \
4681 disposition = dispositionExpression; \
4682 _ASSERTE(disposition != EXCEPTION_CONTINUE_EXECUTION); \
4683 return disposition; \
4687 HardwareExceptionHolder \
4688 auto __exceptionHolder = NativeExceptionHolderFactory::CreateHolder(&exceptionFilter); \
4689 __exceptionHolder.Push(); \
4690 tryBlock(__param); \
4692 catch (PAL_SEHException& ex) \
4694 if (disposition == EXCEPTION_CONTINUE_EXECUTION) \
4696 exceptionFilter(ex); \
4698 if (disposition == EXCEPTION_CONTINUE_SEARCH) \
4702 ex.SecondPassDone();
4704 // Start of an exception handler. It works the same way as the PAL_EXCEPT except
4705 // that the disposition is obtained by calling the specified filter.
4706 #define PAL_EXCEPT_FILTER(filter) PAL_EXCEPT(filter(&ex.ExceptionPointers, __param))
4708 // Start of a finally block. The finally block is executed both when the try block
4709 // finishes or when an exception is raised using the RaiseException in it.
4710 #define PAL_FINALLY \
4712 const bool isFinally = true; \
4713 auto finallyBlock = [&]() \
4716 // End of an except or a finally block.
4717 #define PAL_ENDTRY \
4723 tryBlock(__param); \
4736 #define PAL_CPP_THROW(type, obj) { throw obj; }
4737 #define PAL_CPP_RETHROW { throw; }
4738 #define PAL_CPP_TRY try { HardwareExceptionHolder
4739 #define PAL_CPP_CATCH_EXCEPTION(ident) } catch (Exception *ident) {
4740 #define PAL_CPP_CATCH_EXCEPTION_NOARG } catch (Exception *) {
4741 #define PAL_CPP_CATCH_DERIVED(type, ident) } catch (type *ident) {
4742 #define PAL_CPP_CATCH_ALL } catch (...) { \
4744 catch (PAL_SEHException& ex) { ex.SecondPassDone(); } \
4747 #define PAL_CPP_ENDTRY }
4750 #pragma warning(disable:4611) // interaction between '_setjmp' and C++ object destruction is non-portable
4753 #define PAL_TRY_FOR_DLLMAIN(ParamType, paramDef, paramRef, _reason) PAL_TRY(ParamType, paramDef, paramRef)
4755 #endif // __cplusplus
4757 // Platform-specific library naming
4760 #define MAKEDLLNAME_W(name) u"lib" name u".dylib"
4761 #define MAKEDLLNAME_A(name) "lib" name ".dylib"
4763 #define MAKEDLLNAME_W(name) u"lib" name u".so"
4764 #define MAKEDLLNAME_A(name) "lib" name ".so"
4768 #define MAKEDLLNAME(x) MAKEDLLNAME_W(x)
4770 #define MAKEDLLNAME(x) MAKEDLLNAME_A(x)
4773 #define PAL_SHLIB_PREFIX "lib"
4774 #define PAL_SHLIB_PREFIX_W u"lib"
4777 #define PAL_SHLIB_SUFFIX ".dylib"
4778 #define PAL_SHLIB_SUFFIX_W u".dylib"
4780 #define PAL_SHLIB_SUFFIX ".so"
4781 #define PAL_SHLIB_SUFFIX_W u".so"
4784 #define DBG_EXCEPTION_HANDLED ((DWORD )0x00010001L)
4785 #define DBG_CONTINUE ((DWORD )0x00010002L)
4786 #define DBG_EXCEPTION_NOT_HANDLED ((DWORD )0x80010001L)
4788 #define DBG_TERMINATE_THREAD ((DWORD )0x40010003L)
4789 #define DBG_TERMINATE_PROCESS ((DWORD )0x40010004L)
4790 #define DBG_CONTROL_C ((DWORD )0x40010005L)
4791 #define DBG_RIPEXCEPTION ((DWORD )0x40010007L)
4792 #define DBG_CONTROL_BREAK ((DWORD )0x40010008L)
4793 #define DBG_COMMAND_EXCEPTION ((DWORD )0x40010009L)
4795 #define STATUS_USER_APC ((DWORD )0x000000C0L)
4796 #define STATUS_GUARD_PAGE_VIOLATION ((DWORD )0x80000001L)
4797 #define STATUS_DATATYPE_MISALIGNMENT ((DWORD )0x80000002L)
4798 #define STATUS_BREAKPOINT ((DWORD )0x80000003L)
4799 #define STATUS_SINGLE_STEP ((DWORD )0x80000004L)
4800 #define STATUS_LONGJUMP ((DWORD )0x80000026L)
4801 #define STATUS_UNWIND_CONSOLIDATE ((DWORD )0x80000029L)
4802 #define STATUS_ACCESS_VIOLATION ((DWORD )0xC0000005L)
4803 #define STATUS_IN_PAGE_ERROR ((DWORD )0xC0000006L)
4804 #define STATUS_INVALID_HANDLE ((DWORD )0xC0000008L)
4805 #define STATUS_NO_MEMORY ((DWORD )0xC0000017L)
4806 #define STATUS_ILLEGAL_INSTRUCTION ((DWORD )0xC000001DL)
4807 #define STATUS_NONCONTINUABLE_EXCEPTION ((DWORD )0xC0000025L)
4808 #define STATUS_INVALID_DISPOSITION ((DWORD )0xC0000026L)
4809 #define STATUS_ARRAY_BOUNDS_EXCEEDED ((DWORD )0xC000008CL)
4810 #define STATUS_FLOAT_DENORMAL_OPERAND ((DWORD )0xC000008DL)
4811 #define STATUS_FLOAT_DIVIDE_BY_ZERO ((DWORD )0xC000008EL)
4812 #define STATUS_FLOAT_INEXACT_RESULT ((DWORD )0xC000008FL)
4813 #define STATUS_FLOAT_INVALID_OPERATION ((DWORD )0xC0000090L)
4814 #define STATUS_FLOAT_OVERFLOW ((DWORD )0xC0000091L)
4815 #define STATUS_FLOAT_STACK_CHECK ((DWORD )0xC0000092L)
4816 #define STATUS_FLOAT_UNDERFLOW ((DWORD )0xC0000093L)
4817 #define STATUS_INTEGER_DIVIDE_BY_ZERO ((DWORD )0xC0000094L)
4818 #define STATUS_INTEGER_OVERFLOW ((DWORD )0xC0000095L)
4819 #define STATUS_PRIVILEGED_INSTRUCTION ((DWORD )0xC0000096L)
4820 #define STATUS_STACK_OVERFLOW ((DWORD )0xC00000FDL)
4821 #define STATUS_CONTROL_C_EXIT ((DWORD )0xC000013AL)
4823 #define WAIT_IO_COMPLETION STATUS_USER_APC
4825 #define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
4826 #define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT
4827 #define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT
4828 #define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP
4829 #define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED
4830 #define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND
4831 #define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO
4832 #define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT
4833 #define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION
4834 #define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW
4835 #define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK
4836 #define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW
4837 #define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO
4838 #define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW
4839 #define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION
4840 #define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR
4841 #define EXCEPTION_ILLEGAL_INSTRUCTION STATUS_ILLEGAL_INSTRUCTION
4842 #define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION
4843 #define EXCEPTION_STACK_OVERFLOW STATUS_STACK_OVERFLOW
4844 #define EXCEPTION_INVALID_DISPOSITION STATUS_INVALID_DISPOSITION
4845 #define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION
4846 #define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE
4848 #define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT
4850 /******************* HRESULT types ****************************************/
4852 #define FACILITY_WINDOWS 8
4853 #define FACILITY_URT 19
4854 #define FACILITY_UMI 22
4855 #define FACILITY_SXS 23
4856 #define FACILITY_STORAGE 3
4857 #define FACILITY_SSPI 9
4858 #define FACILITY_SCARD 16
4859 #define FACILITY_SETUPAPI 15
4860 #define FACILITY_SECURITY 9
4861 #define FACILITY_RPC 1
4862 #define FACILITY_WIN32 7
4863 #define FACILITY_CONTROL 10
4864 #define FACILITY_NULL 0
4865 #define FACILITY_MSMQ 14
4866 #define FACILITY_MEDIASERVER 13
4867 #define FACILITY_INTERNET 12
4868 #define FACILITY_ITF 4
4869 #define FACILITY_DPLAY 21
4870 #define FACILITY_DISPATCH 2
4871 #define FACILITY_COMPLUS 17
4872 #define FACILITY_CERT 11
4873 #define FACILITY_ACS 20
4874 #define FACILITY_AAF 18
4878 #define SEVERITY_SUCCESS 0
4879 #define SEVERITY_ERROR 1
4881 #define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
4882 #define FAILED(Status) ((HRESULT)(Status)<0)
4883 #define IS_ERROR(Status) ((ULONG)(Status) >> 31 == SEVERITY_ERROR) // diff from win32
4884 #define HRESULT_CODE(hr) ((hr) & 0xFFFF)
4885 #define SCODE_CODE(sc) ((sc) & 0xFFFF)
4886 #define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff)
4887 #define SCODE_FACILITY(sc) (((sc) >> 16) & 0x1fff)
4888 #define HRESULT_SEVERITY(hr) (((hr) >> 31) & 0x1)
4889 #define SCODE_SEVERITY(sc) (((sc) >> 31) & 0x1)
4891 // both macros diff from Win32
4892 #define MAKE_HRESULT(sev,fac,code) \
4893 ((HRESULT) (((ULONG)(sev)<<31) | ((ULONG)(fac)<<16) | ((ULONG)(code))) )
4894 #define MAKE_SCODE(sev,fac,code) \
4895 ((SCODE) (((ULONG)(sev)<<31) | ((ULONG)(fac)<<16) | ((LONG)(code))) )
4897 #define FACILITY_NT_BIT 0x10000000
4898 #define HRESULT_FROM_WIN32(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))
4899 #define __HRESULT_FROM_WIN32(x) HRESULT_FROM_WIN32(x)
4901 #define HRESULT_FROM_NT(x) ((HRESULT) ((x) | FACILITY_NT_BIT))