[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
This commit is contained in:
Timo Kreuzer 2014-10-18 21:22:52 +00:00
parent 91dd4cbea0
commit 400a2c65cf
4 changed files with 222 additions and 14 deletions

View file

@ -6,6 +6,18 @@
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <rtcapi.h>
#include <assert.h>
#if defined(_M_IX86)
#pragma comment(linker, "/alternatename:__RTC_Initialize=__RTC_NoInitialize")
#elif defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM)
#pragma comment(linker, "/alternatename:_RTC_Initialize=_RTC_NoInitialize")
#else
#error Unsupported platform
#endif
void _pei386_runtime_relocator(void)
{
@ -36,16 +48,39 @@ _CRT_INIT0(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
return TRUE;
}
void Catch_RTC_Failure(int errType, const wchar_t *file, int line,
const wchar_t *module, const wchar_t *format, ...)
int
__cdecl
Catch_RTC_Failure(
int errType,
const wchar_t *file,
int line,
const wchar_t *module,
const wchar_t *format,
...)
{
/* FIXME: better failure routine */
__debugbreak();
return 0;
}
void* __cdecl _CRT_RTC_INITW(void *res0, void **res1, int res2, int res3, int res4)
extern
void
__cdecl
_RTC_NoInitialize(void)
{
return &Catch_RTC_Failure;
/* Do nothing, if RunTmChk.lib is not pulled in */
}
_RTC_error_fnW
__cdecl
_CRT_RTC_INITW(
void *_Res0,
void **_Res1,
int _Res2,
int _Res3,
int _Res4)
{
return &Catch_RTC_Failure;
}
static int initialized = 0;
@ -56,6 +91,9 @@ __main(void)
if (!initialized)
{
initialized = 1;
_RTC_Initialize();
__do_global_ctors ();
}
}

View file

@ -1,5 +1,8 @@
list(APPEND SOURCE rtcapi.c)
list(APPEND SOURCE
rtcapi.c
rtcuserapi.c
)
if(ARCH STREQUAL "i386")
list(APPEND ASM_SOURCE i386/_RTC_CheckEsp.S)

View file

@ -7,21 +7,76 @@
#include <rtcapi.h>
unsigned long
#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
__cdecl
DbgPrint(
const char *fmt, ...);
_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;
}
void
__cdecl
_RTC_InitBase(void)
{
static char initialized = 0;
_RTC_error_fnW errorFunc;
if (!initialized)
{
errorFunc = _CRT_RTC_INITW(0, 0, 0, 1, 0);
_RTC_SetErrorFuncW(errorFunc);
initialized = 1;
}
}
void
__cdecl
_RTC_Shutdown(void)
{
__debugbreak();
}
void
_RTC_Shutdown(void)
__cdecl
_RTC_Initialize(void)
{
__debugbreak();
/* 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();
}
void
@ -30,7 +85,13 @@ _RTC_Failure(
void* retaddr,
int errnum)
{
__debugbreak();
_RTC_pErrorFuncW(errnum,
L"unknown file",
-1,
L"unknown module",
L"Invalid stack pointer value caught at %p, error %d\n",
retaddr,
errnum);
}
void
@ -38,7 +99,12 @@ __cdecl
_RTC_UninitUse(
const char *_Varname)
{
__debugbreak();
_RTC_pErrorFuncW(_RTC_UNINIT_LOCAL_USE,
L"unknown file",
-1,
L"unknown module",
L"Use of uninitialized variable %S!\n",
_Varname);
}
void
@ -59,7 +125,12 @@ _RTC_CheckStackVars(
/* Check if they contain the guard bytes */
if ((*guard1 != 0xCCCCCCCC) || (*guard2 != 0xCCCCCCCC))
{
__debugbreak();
_RTC_pErrorFuncW(_RTC_CORRUPT_STACK,
L"unknown file",
-1,
L"unknown module",
L"Stack corruption near '%s'\n",
_Fd->variables[i].name);
}
}
}
@ -90,7 +161,11 @@ _RTC_CheckStackVars2(
(current->guard2[2] != 0xCCCCCCCC) ||
(*guard != 0xCCCCCCCC))
{
__debugbreak();
_RTC_pErrorFuncW(_RTC_CORRUPTED_ALLOCA,
L"unknown file",
-1,
L"unknown module",
L"Stack corruption in alloca frame\n");
}
}
}
@ -124,3 +199,4 @@ _RTC_AllocaHelper(
*_PAllocaInfoList = _PAllocaBase;
}
}

View file

@ -0,0 +1,91 @@
/*
* 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)
*/
#include <rtcapi.h>
extern _RTC_error_fnW _RTC_pErrorFuncW;
int
__cdecl
_RTC_DefaultErrorFuncW(
int errType,
const wchar_t *file,
int line,
const wchar_t *module,
const wchar_t *format,
...);
static
char*
_RTC_ErrorDescription[] =
{
"The stack pointer was wrong after returning from a function call.", /* _RTC_CHKSTK */
"Data was lost when a type was converted to a smaller type.", /* _RTC_CVRT_LOSS_INFO */
"The stack near a local variable was corrupted.", /* _RTC_CORRUPT_STACK */
"An uninitialized local variable was used.", /* _RTC_UNINIT_LOCAL_USE */
"The stack around an alloca was corrupted.", /* _RTC_CORRUPTED_ALLOCA */
};
int
__cdecl
_RTC_NumErrors(void)
{
/* Not supported yet */
__debugbreak();
return 0;
}
const char *
__cdecl
_RTC_GetErrDesc(
_RTC_ErrorNumber _Errnum)
{
if (_Errnum < (sizeof(_RTC_ErrorDescription) / sizeof(_RTC_ErrorDescription[0])))
{
return _RTC_ErrorDescription[_Errnum];
}
return "Invalid/Unknown error.";
}
int
__cdecl
_RTC_SetErrorType(
_RTC_ErrorNumber _Errnum,
int _ErrType)
{
/* Not supported yet */
__debugbreak();
return 0;
}
_RTC_error_fn
__cdecl
_RTC_SetErrorFunc(
_RTC_error_fn new_fn)
{
/* Not supported yet */
__debugbreak();
return 0;
}
_RTC_error_fnW
__cdecl
_RTC_SetErrorFuncW(_RTC_error_fnW new_fn)
{
_RTC_error_fnW old_fn;
/* Get the current error func */
old_fn = _RTC_pErrorFuncW;
/* Set the new function or reset when 0 was passed */
_RTC_pErrorFuncW = new_fn ? new_fn : _RTC_DefaultErrorFuncW;
/* Return the old error func, or 0, if none was set */
return old_fn != _RTC_DefaultErrorFuncW ? old_fn : 0;
}