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