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