mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[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
This commit is contained in:
parent
e5e46c1db5
commit
911faa3a6f
4 changed files with 185 additions and 0 deletions
|
@ -2,6 +2,7 @@
|
|||
add_subdirectory(comsupp)
|
||||
if(MSVC)
|
||||
add_subdirectory(cpprt)
|
||||
add_subdirectory(RunTmChk)
|
||||
endif()
|
||||
add_subdirectory(crt)
|
||||
add_subdirectory(delayimp)
|
||||
|
|
15
reactos/lib/sdk/RunTmChk/CMakeLists.txt
Normal file
15
reactos/lib/sdk/RunTmChk/CMakeLists.txt
Normal file
|
@ -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)
|
45
reactos/lib/sdk/RunTmChk/i386/_RTC_CheckEsp.S
Normal file
45
reactos/lib/sdk/RunTmChk/i386/_RTC_CheckEsp.S
Normal file
|
@ -0,0 +1,45 @@
|
|||
|
||||
|
||||
#include <asm.inc>
|
||||
.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
|
||||
|
||||
|
124
reactos/lib/sdk/RunTmChk/rtcapi.c
Normal file
124
reactos/lib/sdk/RunTmChk/rtcapi.c
Normal file
|
@ -0,0 +1,124 @@
|
|||
|
||||
#include <rtcapi.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue