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