Sync to trunk (r47832)
[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 __declspec(noreturn) void __cdecl __report_gsfailure (ULONGLONG);
92
93 __declspec(noreturn) void __cdecl
94 __report_gsfailure (ULONGLONG StackCookie)
95 {
96 volatile UINT_PTR cookie[2];
97 #ifdef _WIN64
98 ULONG64 controlPC, imgBase, establisherFrame;
99 PRUNTIME_FUNCTION fctEntry;
100 PVOID hndData;
101 #endif
102
103 #ifdef _WIN64
104 RtlCaptureContext (&GS_ContextRecord);
105 controlPC = GS_ContextRecord.Rip;
106 fctEntry = RtlLookupFunctionEntry (controlPC, &imgBase, NULL);
107 if (fctEntry != NULL)
108 {
109 RtlVirtualUnwind (UNW_FLAG_NHANDLER, imgBase, controlPC, fctEntry,
110 &GS_ContextRecord, &hndData, &establisherFrame, NULL);
111 }
112 else
113 #endif
114 {
115 #ifdef __GNUC__
116 #ifdef _WIN64
117 GS_ContextRecord.Rip = (ULONGLONG) __builtin_return_address (0);
118 GS_ContextRecord.Rsp = (ULONGLONG) __builtin_frame_address (0) + 8;
119 #else
120 GS_ContextRecord.Eip = (DWORD) __builtin_return_address (0);
121 GS_ContextRecord.Esp = (DWORD) __builtin_frame_address (0) + 4;
122 #endif
123 #else
124 #ifdef _WIN64
125 GS_ContextRecord.Rip = (ULONGLONG) _ReturnAddress();
126 GS_ContextRecord.Rsp = (ULONGLONG) _AddressOfReturnAddress();
127 #else
128 GS_ContextRecord.Eip = (DWORD) _ReturnAddress();
129 GS_ContextRecord.Esp = (DWORD) _AddressOfReturnAddress();
130 #endif
131 #endif
132 }
133
134 #ifdef _WIN64
135 GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Rip;
136 GS_ContextRecord.Rcx = StackCookie;
137 #else
138 GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Eip;
139 GS_ContextRecord.Ecx = StackCookie;
140 #endif
141 GS_ExceptionRecord.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
142 GS_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
143 cookie[0] = __security_cookie;
144 cookie[1] = __security_cookie_complement;
145 SetUnhandledExceptionFilter (NULL);
146 UnhandledExceptionFilter ((EXCEPTION_POINTERS *) &GS_ExceptionPointers);
147 TerminateProcess (GetCurrentProcess (), STATUS_STACK_BUFFER_OVERRUN);
148 abort();
149 }