diff --git a/reactos/lib/sdk/crt/startup/mscmain.c b/reactos/lib/sdk/crt/startup/mscmain.c index 4eba46f1ac6..a7f57a47539 100644 --- a/reactos/lib/sdk/crt/startup/mscmain.c +++ b/reactos/lib/sdk/crt/startup/mscmain.c @@ -6,6 +6,18 @@ #include #include +#include +#include +#include +#include + +#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 (); } } diff --git a/reactos/lib/sdk/runtmchk/CMakeLists.txt b/reactos/lib/sdk/runtmchk/CMakeLists.txt index 4b55bc308e1..2cd843096ef 100644 --- a/reactos/lib/sdk/runtmchk/CMakeLists.txt +++ b/reactos/lib/sdk/runtmchk/CMakeLists.txt @@ -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) diff --git a/reactos/lib/sdk/runtmchk/rtcapi.c b/reactos/lib/sdk/runtmchk/rtcapi.c index 1e9bbf5b35b..96631ca53c4 100644 --- a/reactos/lib/sdk/runtmchk/rtcapi.c +++ b/reactos/lib/sdk/runtmchk/rtcapi.c @@ -7,21 +7,76 @@ #include -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; } } + diff --git a/reactos/lib/sdk/runtmchk/rtcuserapi.c b/reactos/lib/sdk/runtmchk/rtcuserapi.c new file mode 100644 index 00000000000..5ae7a9c227d --- /dev/null +++ b/reactos/lib/sdk/runtmchk/rtcuserapi.c @@ -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 + +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; +} +