1 /**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 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
27 typedef LONG NTSTATUS; /* same as in ntdef.h / winternl.h */
28
29 #define UNW_FLAG_NHANDLER 0x0
30
31 typedef union
32 {
33 unsigned __int64 ft_scalar;
34 FILETIME ft_struct;
35 } FT;
36
37 static EXCEPTION_RECORD GS_ExceptionRecord;
38 static CONTEXT GS_ContextRecord;
39
40 static const EXCEPTION_POINTERS GS_ExceptionPointers = {
41 &GS_ExceptionRecord,&GS_ContextRecord
42 };
43
44 DECLSPEC_SELECTANY UINT_PTR __security_cookie = DEFAULT_SECURITY_COOKIE;
45 DECLSPEC_SELECTANY UINT_PTR __security_cookie_complement = ~(DEFAULT_SECURITY_COOKIE);
46
47 void __cdecl __security_init_cookie (void);
48
49 void __cdecl
__security_init_cookie(void)50 __security_init_cookie (void)
51 {
52 UINT_PTR cookie;
53 FT systime = { 0, };
54 LARGE_INTEGER perfctr;
55
56 if (__security_cookie != DEFAULT_SECURITY_COOKIE)
57 {
58 __security_cookie_complement = ~__security_cookie;
59 return;
60 }
61
62 GetSystemTimeAsFileTime (&systime.ft_struct);
63 #ifdef _WIN64
64 cookie = systime.ft_scalar;
65 #else
66 cookie = systime.ft_struct.dwLowDateTime;
67 cookie ^= systime.ft_struct.dwHighDateTime;
68 #endif
69
70 cookie ^= GetCurrentProcessId ();
71 cookie ^= GetCurrentThreadId ();
72 cookie ^= GetTickCount ();
73
74 QueryPerformanceCounter (&perfctr);
75 #ifdef _WIN64
76 cookie ^= perfctr.QuadPart;
77 #else
78 cookie ^= perfctr.LowPart;
79 cookie ^= perfctr.HighPart;
80 #endif
81
82 #ifdef _WIN64
83 cookie &= 0x0000ffffffffffffll;
84 #endif
85
86 if (cookie == DEFAULT_SECURITY_COOKIE)
87 cookie = DEFAULT_SECURITY_COOKIE + 1;
88 __security_cookie = cookie;
89 __security_cookie_complement = ~cookie;
90 }
91
92
93 #if defined(__GNUC__) /* wrap msvc intrinsics onto gcc builtins */
94 #undef _ReturnAddress
95 #undef _AddressOfReturnAddress
96 #define _ReturnAddress() __builtin_return_address(0)
97 #define _AddressOfReturnAddress() __builtin_frame_address (0)
98 #endif /* __GNUC__ */
99
100 __declspec(noreturn) void __cdecl __report_gsfailure (ULONG_PTR);
101
102 #define UNUSED_PARAM(x) { x = x; }
103 __declspec(noreturn) void __cdecl
__report_gsfailure(ULONG_PTR StackCookie)104 __report_gsfailure (ULONG_PTR StackCookie)
105 {
106 volatile UINT_PTR cookie[2] __MINGW_ATTRIB_UNUSED;
107 #if defined(_WIN64) && !defined(__aarch64__)
108 ULONG64 controlPC, imgBase, establisherFrame;
109 PRUNTIME_FUNCTION fctEntry;
110 PVOID hndData;
111
112 RtlCaptureContext (&GS_ContextRecord);
113 controlPC = GS_ContextRecord.Rip;
114 fctEntry = RtlLookupFunctionEntry (controlPC, &imgBase, NULL);
115 if (fctEntry != NULL)
116 {
117 RtlVirtualUnwind (UNW_FLAG_NHANDLER, imgBase, controlPC, fctEntry,
118 &GS_ContextRecord, &hndData, &establisherFrame, NULL);
119 }
120 else
121 #endif /* _WIN64 */
122 {
123 #if defined(__x86_64__) || defined(_AMD64_)
124 GS_ContextRecord.Rip = (ULONGLONG) _ReturnAddress();
125 GS_ContextRecord.Rsp = (ULONGLONG) _AddressOfReturnAddress() + 8;
126 #elif defined(__i386__) || defined(_X86_)
127 GS_ContextRecord.Eip = (DWORD) _ReturnAddress();
128 GS_ContextRecord.Esp = (DWORD) _AddressOfReturnAddress() + 4;
129 #elif defined(__arm__) || defined(_ARM_)
130 GS_ContextRecord.Pc = (DWORD) _ReturnAddress();
131 GS_ContextRecord.Sp = (DWORD) _AddressOfReturnAddress() + 4;
132 #endif /* _WIN64 */
133 }
134
135 #if defined(__x86_64__) || defined(_AMD64_)
136 GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Rip;
137 GS_ContextRecord.Rcx = StackCookie;
138 #elif defined(__i386__) || defined(_X86_)
139 GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Eip;
140 GS_ContextRecord.Ecx = StackCookie;
141 #elif defined(__arm__) || defined(_ARM_)
142 GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Pc;
143 UNUSED_PARAM(StackCookie);
144 #endif /* _WIN64 */
145 GS_ExceptionRecord.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
146 GS_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
147 cookie[0] = __security_cookie;
148 cookie[1] = __security_cookie_complement;
149 SetUnhandledExceptionFilter (NULL);
150 UnhandledExceptionFilter ((EXCEPTION_POINTERS *) &GS_ExceptionPointers);
151 TerminateProcess (GetCurrentProcess (), STATUS_STACK_BUFFER_OVERRUN);
152 abort();
153 }
154
155