1 /* 2 * PROJECT: MSVC runtime check support library 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * PURPOSE: Provides support functions for MSVC runtime checks 5 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org) 6 */ 7 8 #include <rtcapi.h> 9 10 #if defined(_M_IX86) 11 #pragma comment(linker, "/alternatename:__CRT_RTC_INITW=__CRT_RTC_INITW0") 12 #elif defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM) 13 #pragma comment(linker, "/alternatename:_CRT_RTC_INITW=_CRT_RTC_INITW0") 14 #else 15 #error Unsupported platform 16 #endif 17 18 // Provide a fallback memset for libraries like kbdrost.dll 19 #if defined(_M_ARM) 20 void* __cdecl memset_fallback(void* src, int val, size_t count) 21 { 22 char *char_src = (char *)src; 23 while(count > 0) 24 { 25 *char_src = val; 26 char_src++; 27 count--; 28 } 29 return src; 30 } 31 #pragma comment(linker, "/alternatename:memset=memset_fallback") 32 #endif 33 34 int 35 __cdecl 36 _RTC_DefaultErrorFuncW( 37 int errType, 38 const wchar_t *file, 39 int line, 40 const wchar_t *module, 41 const wchar_t *format, 42 ...) 43 { 44 /* Simple fallback function */ 45 __debugbreak(); 46 return 0; 47 } 48 49 _RTC_error_fnW _RTC_pErrorFuncW = _RTC_DefaultErrorFuncW; 50 51 /* 52 Default CRT RTC init, if we don't link to CRT 53 */ 54 _RTC_error_fnW 55 __cdecl 56 _CRT_RTC_INITW0( 57 void *_Res0, 58 void **_Res1, 59 int _Res2, 60 int _Res3, 61 int _Res4) 62 { 63 return &_RTC_DefaultErrorFuncW; 64 } 65 66 void 67 __cdecl 68 _RTC_InitBase(void) 69 { 70 static char initialized = 0; 71 _RTC_error_fnW errorFunc; 72 73 if (!initialized) 74 { 75 errorFunc = _CRT_RTC_INITW(0, 0, 0, 1, 0); 76 _RTC_SetErrorFuncW(errorFunc); 77 initialized = 1; 78 } 79 } 80 81 void 82 __cdecl 83 _RTC_Shutdown(void) 84 { 85 __debugbreak(); 86 } 87 88 void 89 __cdecl 90 _RTC_Initialize(void) 91 { 92 /* Usually this function would walk an array of function pointers and call 93 each of these, like done with global ctors, but since these are currently 94 only _RTC_InitBase, we simply call that function once. */ 95 _RTC_InitBase(); 96 } 97 98 void 99 __cdecl 100 _RTC_Failure( 101 void* retaddr, 102 int errnum) 103 { 104 _RTC_pErrorFuncW(errnum, 105 L"unknown file", 106 -1, 107 L"unknown module", 108 L"Invalid stack pointer value caught at %p, error %d\n", 109 retaddr, 110 errnum); 111 } 112 113 void 114 __cdecl 115 _RTC_UninitUse( 116 const char *_Varname) 117 { 118 _RTC_pErrorFuncW(_RTC_UNINIT_LOCAL_USE, 119 L"unknown file", 120 -1, 121 L"unknown module", 122 L"Use of uninitialized variable %S!\n", 123 _Varname); 124 } 125 126 void 127 __fastcall 128 _RTC_CheckStackVars( 129 void *_Esp, 130 _RTC_framedesc *_Fd) 131 { 132 int i, *guard1, *guard2; 133 134 /* Loop all variables in the descriptor */ 135 for (i = 0; i < _Fd->varCount; i++) 136 { 137 /* Get the 2 guards below and above the variable */ 138 guard1 = (int*)((char*)_Esp + _Fd->variables[i].addr - sizeof(*guard1)); 139 guard2 = (int*)((char*)_Esp + _Fd->variables[i].addr +_Fd->variables[i].size); 140 141 /* Check if they contain the guard bytes */ 142 if ((*guard1 != 0xCCCCCCCC) || (*guard2 != 0xCCCCCCCC)) 143 { 144 _RTC_pErrorFuncW(_RTC_CORRUPT_STACK, 145 L"unknown file", 146 -1, 147 L"unknown module", 148 L"Stack corruption near '%s'\n", 149 _Fd->variables[i].name); 150 } 151 } 152 } 153 154 void 155 __fastcall 156 _RTC_CheckStackVars2( 157 void *_Esp, 158 _RTC_framedesc *_Fd, 159 _RTC_ALLOCA_NODE *_AllocaList) 160 { 161 _RTC_ALLOCA_NODE *current; 162 int *guard; 163 164 /* Process normal variables */ 165 _RTC_CheckStackVars(_Esp, _Fd); 166 167 /* Process the alloca list */ 168 for (current = _AllocaList; current != 0; current = current->next) 169 { 170 /* Get the upper guard */ 171 guard = (int*)((char*)current + current->allocaSize - sizeof(*guard)); 172 173 /* Check if all guard locations are still ok */ 174 if ((current->guard1 != 0xCCCCCCCC) || 175 (current->guard2[0] != 0xCCCCCCCC) || 176 (current->guard2[1] != 0xCCCCCCCC) || 177 (current->guard2[2] != 0xCCCCCCCC) || 178 (*guard != 0xCCCCCCCC)) 179 { 180 _RTC_pErrorFuncW(_RTC_CORRUPTED_ALLOCA, 181 L"unknown file", 182 -1, 183 L"unknown module", 184 L"Stack corruption in alloca frame\n"); 185 } 186 } 187 } 188 189 void 190 __fastcall 191 _RTC_AllocaHelper( 192 _RTC_ALLOCA_NODE *_PAllocaBase, 193 size_t _CbSize, 194 _RTC_ALLOCA_NODE **_PAllocaInfoList) 195 { 196 unsigned long i; 197 198 /* Check if we got any allocation */ 199 if ((_PAllocaBase != 0) && 200 (_CbSize != 0) && 201 (_PAllocaInfoList != 0)) 202 { 203 /* Mark the whole range */ 204 char *guard = (char*)_PAllocaBase; 205 for (i = 0; i < _CbSize; i++) 206 { 207 guard[i] = 0xCC; 208 } 209 210 /* Initialize the alloca base frame */ 211 _PAllocaBase->allocaSize = _CbSize; 212 213 /* Insert this frame into the alloca list */ 214 _PAllocaBase->next = *_PAllocaInfoList; 215 *_PAllocaInfoList = _PAllocaBase; 216 } 217 } 218 219