[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:
Timo Kreuzer 2014-10-15 21:54:12 +00:00
parent e5e46c1db5
commit 911faa3a6f
4 changed files with 185 additions and 0 deletions

View file

@ -2,6 +2,7 @@
add_subdirectory(comsupp)
if(MSVC)
add_subdirectory(cpprt)
add_subdirectory(RunTmChk)
endif()
add_subdirectory(crt)
add_subdirectory(delayimp)

View 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)

View 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

View 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;
}
}