From: Timo Kreuzer Date: Wed, 15 Oct 2014 21:54:12 +0000 (+0000) Subject: [RunTmChk] X-Git-Tag: backups/tcpip_revolution@71025~478 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=911faa3a6f63af77f4febdac510e342d2d0b4867 [RunTmChk] Implement a simple version of RunTmChk.lib for MSVC runtime check support, which can also be used in kernel mode. This one is good enough to compile ntoskrnl with it. svn path=/trunk/; revision=64756 --- diff --git a/reactos/lib/sdk/CMakeLists.txt b/reactos/lib/sdk/CMakeLists.txt index c89a7365e72..3a1f0550a5b 100644 --- a/reactos/lib/sdk/CMakeLists.txt +++ b/reactos/lib/sdk/CMakeLists.txt @@ -2,6 +2,7 @@ add_subdirectory(comsupp) if(MSVC) add_subdirectory(cpprt) + add_subdirectory(RunTmChk) endif() add_subdirectory(crt) add_subdirectory(delayimp) diff --git a/reactos/lib/sdk/RunTmChk/CMakeLists.txt b/reactos/lib/sdk/RunTmChk/CMakeLists.txt new file mode 100644 index 00000000000..2e311e3a675 --- /dev/null +++ b/reactos/lib/sdk/RunTmChk/CMakeLists.txt @@ -0,0 +1,15 @@ + +list(APPEND SOURCE + rtcapi.c +) + +if(ARCH STREQUAL "i386") + list(APPEND ASM_SOURCE + i386/_RTC_CheckEsp.S +) +endif() + +add_asm_files(RunTmChk_asm ${ASM_SOURCE}) +add_library(RunTmChk ${SOURCE} ${RunTmChk_asm}) + +add_dependencies(RunTmChk asm) diff --git a/reactos/lib/sdk/RunTmChk/i386/_RTC_CheckEsp.S b/reactos/lib/sdk/RunTmChk/i386/_RTC_CheckEsp.S new file mode 100644 index 00000000000..a88aa333829 --- /dev/null +++ b/reactos/lib/sdk/RunTmChk/i386/_RTC_CheckEsp.S @@ -0,0 +1,45 @@ + + +#include +.code + +EXTERN __RTC_Failure:PROC + +/* + + This function is invoked like this: + + mov esi, esp + // Do the actual function call + cmp esp, esi + call __RTC_CheckEsp + + http://stackoverflow.com/questions/3914750/hows-rtc-checkesp-implemented +*/ +PUBLIC __RTC_CheckEsp +__RTC_CheckEsp: + + /* We check if the zero flag is set, and if it is, everything is fine + and we return to the caller */ + je __RTC_CheckEsp_return + + push ebp + mov ebp, esp + pusha + + // void _RTC_Failure(void* retaddr, int errnum); + push 0 // errnum + push dword ptr [esp + 4] // retaddr + call __RTC_Failure + add esp, 8 + int 3 + + popa + pop ebp + +__RTC_CheckEsp_return: + ret + +END + + diff --git a/reactos/lib/sdk/RunTmChk/rtcapi.c b/reactos/lib/sdk/RunTmChk/rtcapi.c new file mode 100644 index 00000000000..5f75880320d --- /dev/null +++ b/reactos/lib/sdk/RunTmChk/rtcapi.c @@ -0,0 +1,124 @@ + +#include + +unsigned long +__cdecl +DbgPrint( + const char *fmt, ...); + +void +_RTC_InitBase(void) +{ + __debugbreak(); +} + +void +_RTC_Shutdown(void) +{ + __debugbreak(); +} + +void +__cdecl +_RTC_Failure( + void* retaddr, + int errnum) +{ + DbgPrint("Invalid stack pointer value caught at %p, error %d\n", retaddr, errnum); + __debugbreak(); +} + +void +__cdecl +_RTC_UninitUse( + const char *_Varname) +{ + DbgPrint("Use of uninitialized variable %s!\n", _Varname); + __debugbreak(); +} + +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 */ + if ((*guard1 != 0xCCCCCCCC) || (*guard1 != 0xCCCCCCCC)) + { + DbgPrint("Stack corruption near '%s'\n", _Fd->variables[i].name); + __debugbreak(); + } + } +} + +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)) + { + __debugbreak(); + } + } +} + +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; + } +} +