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)
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")
15 #error Unsupported platform
20 _RTC_DefaultErrorFuncW(
24 const wchar_t *module
,
25 const wchar_t *format
,
28 /* Simple fallback function */
33 _RTC_error_fnW _RTC_pErrorFuncW
= _RTC_DefaultErrorFuncW
;
36 Default CRT RTC init, if we don't link to CRT
47 return &_RTC_DefaultErrorFuncW
;
54 static char initialized
= 0;
55 _RTC_error_fnW errorFunc
;
59 errorFunc
= _CRT_RTC_INITW(0, 0, 0, 1, 0);
60 _RTC_SetErrorFuncW(errorFunc
);
76 /* Usually this function would walk an array of function pointers and call
77 each of these, like done with global ctors, but since these are currently
78 only _RTC_InitBase, we simply call that function once. */
88 _RTC_pErrorFuncW(errnum
,
92 L
"Invalid stack pointer value caught at %p, error %d\n",
100 const char *_Varname
)
102 _RTC_pErrorFuncW(_RTC_UNINIT_LOCAL_USE
,
106 L
"Use of uninitialized variable %S!\n",
116 int i
, *guard1
, *guard2
;
118 /* Loop all variables in the descriptor */
119 for (i
= 0; i
< _Fd
->varCount
; i
++)
121 /* Get the 2 guards below and above the variable */
122 guard1
= (int*)((char*)_Esp
+ _Fd
->variables
[i
].addr
- sizeof(*guard1
));
123 guard2
= (int*)((char*)_Esp
+ _Fd
->variables
[i
].addr
+_Fd
->variables
[i
].size
);
125 /* Check if they contain the guard bytes */
126 if ((*guard1
!= 0xCCCCCCCC) || (*guard2
!= 0xCCCCCCCC))
128 _RTC_pErrorFuncW(_RTC_CORRUPT_STACK
,
132 L
"Stack corruption near '%s'\n",
133 _Fd
->variables
[i
].name
);
140 _RTC_CheckStackVars2(
143 _RTC_ALLOCA_NODE
*_AllocaList
)
145 _RTC_ALLOCA_NODE
*current
;
148 /* Process normal variables */
149 _RTC_CheckStackVars(_Esp
, _Fd
);
151 /* Process the alloca list */
152 for (current
= _AllocaList
; current
!= 0; current
= current
->next
)
154 /* Get the upper guard */
155 guard
= (int*)((char*)current
+ current
->allocaSize
- sizeof(*guard
));
157 /* Check if all guard locations are still ok */
158 if ((current
->guard1
!= 0xCCCCCCCC) ||
159 (current
->guard2
[0] != 0xCCCCCCCC) ||
160 (current
->guard2
[1] != 0xCCCCCCCC) ||
161 (current
->guard2
[2] != 0xCCCCCCCC) ||
162 (*guard
!= 0xCCCCCCCC))
164 _RTC_pErrorFuncW(_RTC_CORRUPTED_ALLOCA
,
168 L
"Stack corruption in alloca frame\n");
176 _RTC_ALLOCA_NODE
*_PAllocaBase
,
178 _RTC_ALLOCA_NODE
**_PAllocaInfoList
)
182 /* Check if we got any allocation */
183 if ((_PAllocaBase
!= 0) &&
185 (_PAllocaInfoList
!= 0))
187 /* Mark the whole range */
188 char *guard
= (char*)_PAllocaBase
;
189 for (i
= 0; i
< _CbSize
; i
++)
194 /* Initialize the alloca base frame */
195 _PAllocaBase
->allocaSize
= _CbSize
;
197 /* Insert this frame into the alloca list */
198 _PAllocaBase
->next
= *_PAllocaInfoList
;
199 *_PAllocaInfoList
= _PAllocaBase
;