sync to trunk revision 36100
[reactos.git] / reactos / lib / 3rdparty / mingw / gs_support.c
1 #include <windows.h>
2 #ifdef _WIN64
3 #include <intrin.h>
4 #endif
5
6 #ifdef _WIN64
7 #define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
8 #else
9 #define DEFAULT_SECURITY_COOKIE 0xBB40E64E
10 #endif
11
12 /* Externals. */
13 #ifdef _WIN64
14 PRUNTIME_FUNCTION RtlLookupFunctionEntry (ULONG64, PULONG64, PVOID);
15 PVOID RtlVirtualUnwind (ULONG HandlerType, ULONG64, ULONG64, PRUNTIME_FUNCTION,
16 PCONTEXT, PVOID *, PULONG64, PKNONVOLATILE_CONTEXT_POINTERS);
17 #endif
18
19 typedef LONG NTSTATUS;
20
21 #define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS)0xC0000409L)
22
23 typedef union
24 {
25 unsigned __int64 ft_scalar;
26 FILETIME ft_struct;
27 } FT;
28
29 static EXCEPTION_RECORD GS_ExceptionRecord;
30 static CONTEXT GS_ContextRecord;
31
32 static const EXCEPTION_POINTERS GS_ExceptionPointers = {
33 &GS_ExceptionRecord,&GS_ContextRecord
34 };
35
36 __declspec(selectany) UINT_PTR __security_cookie = DEFAULT_SECURITY_COOKIE;
37 __declspec(selectany) UINT_PTR __security_cookie_complement = ~(DEFAULT_SECURITY_COOKIE);
38
39 void __cdecl
40 __security_init_cookie (void)
41 {
42 UINT_PTR cookie;
43 FT systime = { 0, };
44 LARGE_INTEGER perfctr;
45
46 if (__security_cookie != DEFAULT_SECURITY_COOKIE)
47 {
48 __security_cookie_complement = ~__security_cookie;
49 return;
50 }
51
52 GetSystemTimeAsFileTime (&systime.ft_struct);
53 #ifdef _WIN64
54 cookie = systime.ft_scalar;
55 #else
56 cookie = systime.ft_struct.dwLowDateTime;
57 cookie ^= systime.ft_struct.dwHighDateTime;
58 #endif
59
60 cookie ^= GetCurrentProcessId ();
61 cookie ^= GetCurrentThreadId ();
62 cookie ^= GetTickCount ();
63
64 QueryPerformanceCounter (&perfctr);
65 #ifdef _WIN64
66 cookie ^= perfctr.QuadPart;
67 #else
68 cookie ^= perfctr.LowPart;
69 cookie ^= perfctr.HighPart;
70 #endif
71
72 #ifdef _WIN64
73 cookie &= 0x0000ffffffffffffll;
74 #endif
75
76 if (cookie == DEFAULT_SECURITY_COOKIE)
77 cookie = DEFAULT_SECURITY_COOKIE + 1;
78 __security_cookie = cookie;
79 __security_cookie_complement = ~cookie;
80 }
81
82 __declspec(noreturn) void __cdecl
83 __report_gsfailure (ULONGLONG StackCookie)
84 {
85 volatile UINT_PTR cookie[2];
86 #ifdef _WIN64
87 ULONG64 controlPC, imgBase, establisherFrame;
88 PRUNTIME_FUNCTION fctEntry;
89 PVOID hndData;
90 #endif
91
92
93 #ifdef _WIN64
94 RtlCaptureContext (&GS_ContextRecord);
95 controlPC = GS_ContextRecord.Rip;
96 fctEntry = RtlLookupFunctionEntry (controlPC, &imgBase, NULL);
97 if (fctEntry != NULL)
98 {
99 RtlVirtualUnwind (UNW_FLAG_NHANDLER, imgBase, controlPC, fctEntry,
100 &GS_ContextRecord, &hndData, &establisherFrame, NULL);
101 }
102 else
103 #endif
104 {
105 #ifdef _WIN64
106 GS_ContextRecord.Rip = (ULONGLONG) __builtin_return_address (0);
107 GS_ContextRecord.Rsp = (ULONGLONG) __builtin_frame_address (0) + 8;
108 #else
109 GS_ContextRecord.Eip = (DWORD) __builtin_return_address (0);
110 GS_ContextRecord.Esp = (DWORD) __builtin_frame_address (0) + 4;
111 #endif
112 }
113
114 #ifdef _WIN64
115 GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Rip;
116 GS_ContextRecord.Rcx = StackCookie;
117 #else
118 GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Eip;
119 GS_ContextRecord.Ecx = StackCookie;
120 #endif
121 GS_ExceptionRecord.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
122 GS_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
123 cookie[0] = __security_cookie;
124 cookie[1] = __security_cookie_complement;
125 SetUnhandledExceptionFilter (NULL);
126 UnhandledExceptionFilter ((EXCEPTION_POINTERS *) &GS_ExceptionPointers);
127 TerminateProcess (GetCurrentProcess (), STATUS_STACK_BUFFER_OVERRUN);
128 abort();
129 }