2014-10-15 22:44:26 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: MSVC runtime check support library
|
|
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
|
|
* PURPOSE: Provides support functions for MSVC runtime checks
|
|
|
|
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
|
|
|
*/
|
2014-10-15 21:54:12 +00:00
|
|
|
|
|
|
|
#include <rtcapi.h>
|
|
|
|
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
#if defined(_M_IX86)
|
|
|
|
#pragma comment(linker, "/alternatename:__CRT_RTC_INITW=__CRT_RTC_INITW0")
|
|
|
|
#elif defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM)
|
|
|
|
#pragma comment(linker, "/alternatename:_CRT_RTC_INITW=_CRT_RTC_INITW0")
|
|
|
|
#else
|
|
|
|
#error Unsupported platform
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int
|
2014-10-15 21:54:12 +00:00
|
|
|
__cdecl
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
_RTC_DefaultErrorFuncW(
|
|
|
|
int errType,
|
|
|
|
const wchar_t *file,
|
|
|
|
int line,
|
|
|
|
const wchar_t *module,
|
|
|
|
const wchar_t *format,
|
|
|
|
...)
|
|
|
|
{
|
|
|
|
/* Simple fallback function */
|
|
|
|
__debugbreak();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
_RTC_error_fnW _RTC_pErrorFuncW = _RTC_DefaultErrorFuncW;
|
|
|
|
|
|
|
|
/*
|
|
|
|
Default CRT RTC init, if we don't link to CRT
|
|
|
|
*/
|
|
|
|
_RTC_error_fnW
|
|
|
|
__cdecl
|
|
|
|
_CRT_RTC_INITW0(
|
|
|
|
void *_Res0,
|
|
|
|
void **_Res1,
|
|
|
|
int _Res2,
|
|
|
|
int _Res3,
|
|
|
|
int _Res4)
|
|
|
|
{
|
|
|
|
return &_RTC_DefaultErrorFuncW;
|
|
|
|
}
|
2014-10-15 21:54:12 +00:00
|
|
|
|
|
|
|
void
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
__cdecl
|
2014-10-15 21:54:12 +00:00
|
|
|
_RTC_InitBase(void)
|
|
|
|
{
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
static char initialized = 0;
|
|
|
|
_RTC_error_fnW errorFunc;
|
|
|
|
|
|
|
|
if (!initialized)
|
|
|
|
{
|
|
|
|
errorFunc = _CRT_RTC_INITW(0, 0, 0, 1, 0);
|
|
|
|
_RTC_SetErrorFuncW(errorFunc);
|
|
|
|
initialized = 1;
|
|
|
|
}
|
2014-10-15 21:54:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
__cdecl
|
2014-10-15 21:54:12 +00:00
|
|
|
_RTC_Shutdown(void)
|
|
|
|
{
|
|
|
|
__debugbreak();
|
|
|
|
}
|
|
|
|
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
void
|
|
|
|
__cdecl
|
|
|
|
_RTC_Initialize(void)
|
|
|
|
{
|
|
|
|
/* Usually this function would walk an array of function pointers and call
|
|
|
|
each of these, like done with global ctors, but since these are currently
|
|
|
|
only _RTC_InitBase, we simply call that function once. */
|
|
|
|
_RTC_InitBase();
|
|
|
|
}
|
|
|
|
|
2014-10-15 21:54:12 +00:00
|
|
|
void
|
|
|
|
__cdecl
|
|
|
|
_RTC_Failure(
|
|
|
|
void* retaddr,
|
|
|
|
int errnum)
|
|
|
|
{
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
_RTC_pErrorFuncW(errnum,
|
|
|
|
L"unknown file",
|
|
|
|
-1,
|
|
|
|
L"unknown module",
|
|
|
|
L"Invalid stack pointer value caught at %p, error %d\n",
|
|
|
|
retaddr,
|
|
|
|
errnum);
|
2014-10-15 21:54:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__cdecl
|
|
|
|
_RTC_UninitUse(
|
|
|
|
const char *_Varname)
|
|
|
|
{
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
_RTC_pErrorFuncW(_RTC_UNINIT_LOCAL_USE,
|
|
|
|
L"unknown file",
|
|
|
|
-1,
|
|
|
|
L"unknown module",
|
|
|
|
L"Use of uninitialized variable %S!\n",
|
|
|
|
_Varname);
|
2014-10-15 21:54:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__fastcall
|
|
|
|
_RTC_CheckStackVars(
|
|
|
|
void *_Esp,
|
|
|
|
_RTC_framedesc *_Fd)
|
|
|
|
{
|
|
|
|
int i, *guard1, *guard2;
|
|
|
|
|
|
|
|
/* Loop all variables in the descriptor */
|
|
|
|
for (i = 0; i < _Fd->varCount; i++)
|
|
|
|
{
|
|
|
|
/* Get the 2 guards below and above the variable */
|
|
|
|
guard1 = (int*)((char*)_Esp + _Fd->variables[i].addr - sizeof(*guard1));
|
|
|
|
guard2 = (int*)((char*)_Esp + _Fd->variables[i].addr +_Fd->variables[i].size);
|
|
|
|
|
|
|
|
/* Check if they contain the guard bytes */
|
2014-10-15 22:44:26 +00:00
|
|
|
if ((*guard1 != 0xCCCCCCCC) || (*guard2 != 0xCCCCCCCC))
|
2014-10-15 21:54:12 +00:00
|
|
|
{
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
_RTC_pErrorFuncW(_RTC_CORRUPT_STACK,
|
|
|
|
L"unknown file",
|
|
|
|
-1,
|
|
|
|
L"unknown module",
|
|
|
|
L"Stack corruption near '%s'\n",
|
|
|
|
_Fd->variables[i].name);
|
2014-10-15 21:54:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__fastcall
|
|
|
|
_RTC_CheckStackVars2(
|
|
|
|
void *_Esp,
|
|
|
|
_RTC_framedesc *_Fd,
|
|
|
|
_RTC_ALLOCA_NODE *_AllocaList)
|
|
|
|
{
|
|
|
|
_RTC_ALLOCA_NODE *current;
|
|
|
|
int *guard;
|
|
|
|
|
|
|
|
/* Process normal variables */
|
|
|
|
_RTC_CheckStackVars(_Esp, _Fd);
|
|
|
|
|
|
|
|
/* Process the alloca list */
|
|
|
|
for (current = _AllocaList; current != 0; current = current->next)
|
|
|
|
{
|
|
|
|
/* Get the upper guard */
|
|
|
|
guard = (int*)((char*)current + current->allocaSize - sizeof(*guard));
|
|
|
|
|
|
|
|
/* Check if all guard locations are still ok */
|
|
|
|
if ((current->guard1 != 0xCCCCCCCC) ||
|
|
|
|
(current->guard2[0] != 0xCCCCCCCC) ||
|
|
|
|
(current->guard2[1] != 0xCCCCCCCC) ||
|
|
|
|
(current->guard2[2] != 0xCCCCCCCC) ||
|
|
|
|
(*guard != 0xCCCCCCCC))
|
|
|
|
{
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
_RTC_pErrorFuncW(_RTC_CORRUPTED_ALLOCA,
|
|
|
|
L"unknown file",
|
|
|
|
-1,
|
|
|
|
L"unknown module",
|
|
|
|
L"Stack corruption in alloca frame\n");
|
2014-10-15 21:54:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
__fastcall
|
|
|
|
_RTC_AllocaHelper(
|
|
|
|
_RTC_ALLOCA_NODE *_PAllocaBase,
|
|
|
|
size_t _CbSize,
|
|
|
|
_RTC_ALLOCA_NODE **_PAllocaInfoList)
|
|
|
|
{
|
|
|
|
unsigned long i;
|
|
|
|
|
|
|
|
/* Check if we got any allocation */
|
|
|
|
if ((_PAllocaBase != 0) &&
|
|
|
|
(_CbSize != 0) &&
|
|
|
|
(_PAllocaInfoList != 0))
|
|
|
|
{
|
|
|
|
/* Mark the whole range */
|
|
|
|
char *guard = (char*)_PAllocaBase;
|
|
|
|
for (i = 0; i < _CbSize; i++)
|
|
|
|
{
|
|
|
|
guard[i] = 0xCC;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize the alloca base frame */
|
|
|
|
_PAllocaBase->allocaSize = _CbSize;
|
|
|
|
|
|
|
|
/* Insert this frame into the alloca list */
|
|
|
|
_PAllocaBase->next = *_PAllocaInfoList;
|
|
|
|
*_PAllocaInfoList = _PAllocaBase;
|
|
|
|
}
|
|
|
|
}
|
[RunTmChk]
- Implement _RTC_GetErrDesc, _RTC_SetErrorFuncW, add stubs for _RTC_NumErrors, _RTC_SetErrorType, _RTC_SetErrorFunc
- Implement _RTC_DefaultErrorFuncW which will be used, when no other error func was set
- Implement _RTC_InitBase, which will be called from _RTC_Initialize, and which in turn calls either _CRT_RTC_INITW, if CRT was linked, or a local _CRT_RTC_INITW0, which in turn will return the error function to use. This allows us to use a custom error function for all modules that link to (MSV)CRT. Only user32 does not really fit into here, since it uses the same startup code but does not link to MSVCRT.
[CRT]
- Call _RTC_Initialize from __main before initializing the global constructors, but fall back to a dummy _RTC_NoInitialize(), when RunTmChk.lib was not linked. Now we properly initialize both our own as well as MS RunTmChk lib.
svn path=/trunk/; revision=64816
2014-10-18 21:22:52 +00:00
|
|
|
|