- Create another branch for networking fixes
[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 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
47 __security_init_cookie (void)
48 {
49 UINT_PTR cookie;
50 FT systime = { 0, };
51 LARGE_INTEGER perfctr;
52
53 if (__security_cookie != DEFAULT_SECURITY_COOKIE)
54 {
55 __security_cookie_complement = ~__security_cookie;
56 return;
57 }
58
59 GetSystemTimeAsFileTime (&systime.ft_struct);
60 #ifdef _WIN64
61 cookie = systime.ft_scalar;
62 #else
63 cookie = systime.ft_struct.dwLowDateTime;
64 cookie ^= systime.ft_struct.dwHighDateTime;
65 #endif
66
67 cookie ^= GetCurrentProcessId ();
68 cookie ^= GetCurrentThreadId ();
69 cookie ^= GetTickCount ();
70
71 QueryPerformanceCounter (&perfctr);
72 #ifdef _WIN64
73 cookie ^= perfctr.QuadPart;
74 #else
75 cookie ^= perfctr.LowPart;
76 cookie ^= perfctr.HighPart;
77 #endif
78
79 #ifdef _WIN64
80 cookie &= 0x0000ffffffffffffll;
81 #endif
82
83 if (cookie == DEFAULT_SECURITY_COOKIE)
84 cookie = DEFAULT_SECURITY_COOKIE + 1;
85 __security_cookie = cookie;
86 __security_cookie_complement = ~cookie;
87 }
88
89 __declspec(noreturn) void __cdecl
90 __report_gsfailure (ULONGLONG StackCookie)
91 {
92 volatile UINT_PTR cookie[2];
93 #ifdef _WIN64
94 ULONG64 controlPC, imgBase, establisherFrame;
95 PRUNTIME_FUNCTION fctEntry;
96 PVOID hndData;
97 #endif
98
99 #ifdef _WIN64
100 RtlCaptureContext (&GS_ContextRecord);
101 controlPC = GS_ContextRecord.Rip;
102 fctEntry = RtlLookupFunctionEntry (controlPC, &imgBase, NULL);
103 if (fctEntry != NULL)
104 {
105 RtlVirtualUnwind (UNW_FLAG_NHANDLER, imgBase, controlPC, fctEntry,
106 &GS_ContextRecord, &hndData, &establisherFrame, NULL);
107 }
108 else
109 #endif
110 {
111 #ifdef __GNUC__
112 #ifdef _WIN64
113 GS_ContextRecord.Rip = (ULONGLONG) __builtin_return_address (0);
114 GS_ContextRecord.Rsp = (ULONGLONG) __builtin_frame_address (0) + 8;
115 #else
116 GS_ContextRecord.Eip = (DWORD) __builtin_return_address (0);
117 GS_ContextRecord.Esp = (DWORD) __builtin_frame_address (0) + 4;
118 #endif
119 #else
120 #ifdef _WIN64
121 GS_ContextRecord.Rip = (ULONGLONG) _ReturnAddress();
122 GS_ContextRecord.Rsp = (ULONGLONG) _AddressOfReturnAddress();
123 #else
124 GS_ContextRecord.Eip = (DWORD) _ReturnAddress();
125 GS_ContextRecord.Esp = (DWORD) _AddressOfReturnAddress();
126 #endif
127 #endif
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
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 }