4be8fe4573673d69bc3c2d359a719badb5f6bd2c
[reactos.git] / lib / 3rdparty / mingw / gs_support.c
1 /**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the w64 mingw-runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7 #include <windows.h>
8 #ifdef _WIN64
9 #include <intrin.h>
10 #endif
11
12 #ifdef _WIN64
13 #define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
14 #else
15 #define DEFAULT_SECURITY_COOKIE 0xBB40E64E
16 #endif
17
18 /* Externals. */
19 #ifdef _WIN64
20 PRUNTIME_FUNCTION RtlLookupFunctionEntry (ULONG64, PULONG64, PVOID);
21 PVOID RtlVirtualUnwind (ULONG HandlerType, ULONG64, ULONG64, PRUNTIME_FUNCTION,
22 PCONTEXT, PVOID *, PULONG64, PVOID);
23 #endif
24
25 typedef LONG NTSTATUS;
26
27 #define UNW_FLAG_NHANDLER 0x00
28 #define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS)0xC0000409L)
29
30 typedef union
31 {
32 unsigned __int64 ft_scalar;
33 FILETIME ft_struct;
34 } FT;
35
36 static EXCEPTION_RECORD GS_ExceptionRecord;
37 static CONTEXT GS_ContextRecord;
38
39 static const EXCEPTION_POINTERS GS_ExceptionPointers = {
40 &GS_ExceptionRecord,&GS_ContextRecord
41 };
42
43 DECLSPEC_SELECTANY UINT_PTR __security_cookie = DEFAULT_SECURITY_COOKIE;
44 DECLSPEC_SELECTANY UINT_PTR __security_cookie_complement = ~(DEFAULT_SECURITY_COOKIE);
45
46 void __cdecl __security_init_cookie (void);
47
48 void __cdecl
49 __security_init_cookie (void)
50 {
51 UINT_PTR cookie;
52 FT systime = { 0, };
53 LARGE_INTEGER perfctr;
54
55 if (__security_cookie != DEFAULT_SECURITY_COOKIE)
56 {
57 __security_cookie_complement = ~__security_cookie;
58 return;
59 }
60
61 GetSystemTimeAsFileTime (&systime.ft_struct);
62 #ifdef _WIN64
63 cookie = systime.ft_scalar;
64 #else
65 cookie = systime.ft_struct.dwLowDateTime;
66 cookie ^= systime.ft_struct.dwHighDateTime;
67 #endif
68
69 cookie ^= GetCurrentProcessId ();
70 cookie ^= GetCurrentThreadId ();
71 cookie ^= GetTickCount ();
72
73 QueryPerformanceCounter (&perfctr);
74 #ifdef _WIN64
75 cookie ^= perfctr.QuadPart;
76 #else
77 cookie ^= perfctr.LowPart;
78 cookie ^= perfctr.HighPart;
79 #endif
80
81 #ifdef _WIN64
82 cookie &= 0x0000ffffffffffffll;
83 #endif
84
85 if (cookie == DEFAULT_SECURITY_COOKIE)
86 cookie = DEFAULT_SECURITY_COOKIE + 1;
87 __security_cookie = cookie;
88 __security_cookie_complement = ~cookie;
89 }
90
91
92 #if defined(__GNUC__) /* wrap msvc intrinsics onto gcc builtins */
93 #undef _ReturnAddress
94 #undef _AddressOfReturnAddress
95 #define _ReturnAddress() __builtin_return_address(0)
96 #define _AddressOfReturnAddress() __builtin_frame_address (0)
97 #endif /* __GNUC__ */
98
99 __declspec(noreturn) void __cdecl __report_gsfailure (ULONGLONG);
100
101 __declspec(noreturn) void __cdecl
102 __report_gsfailure (ULONGLONG StackCookie)
103 {
104 volatile UINT_PTR __UNUSED_PARAM(cookie[2]);
105 #ifdef _WIN64
106 ULONG64 controlPC, imgBase, establisherFrame;
107 PRUNTIME_FUNCTION fctEntry;
108 PVOID hndData;
109
110 RtlCaptureContext (&GS_ContextRecord);
111 controlPC = GS_ContextRecord.Rip;
112 fctEntry = RtlLookupFunctionEntry (controlPC, &imgBase, NULL);
113 if (fctEntry != NULL)
114 {
115 RtlVirtualUnwind (UNW_FLAG_NHANDLER, imgBase, controlPC, fctEntry,
116 &GS_ContextRecord, &hndData, &establisherFrame, NULL);
117 }
118 else
119 #endif /* _WIN64 */
120 {
121 #ifdef _WIN64
122 GS_ContextRecord.Rip = (ULONGLONG) _ReturnAddress();
123 GS_ContextRecord.Rsp = (ULONGLONG) _AddressOfReturnAddress() + 8;
124 #else
125 GS_ContextRecord.Eip = (DWORD) _ReturnAddress();
126 GS_ContextRecord.Esp = (DWORD) _AddressOfReturnAddress() + 4;
127 #endif /* _WIN64 */
128 }
129
130 #ifdef _WIN64
131 GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Rip;
132 GS_ContextRecord.Rcx = StackCookie;
133 #else
134 GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Eip;
135 GS_ContextRecord.Ecx = StackCookie;
136 #endif /* _WIN64 */
137 GS_ExceptionRecord.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
138 GS_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
139 cookie[0] = __security_cookie;
140 cookie[1] = __security_cookie_complement;
141 SetUnhandledExceptionFilter (NULL);
142 UnhandledExceptionFilter ((EXCEPTION_POINTERS *) &GS_ExceptionPointers);
143 TerminateProcess (GetCurrentProcess (), STATUS_STACK_BUFFER_OVERRUN);
144 abort();
145 }
146