[RunTmChk]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Wed, 15 Oct 2014 21:54:12 +0000 (21:54 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Wed, 15 Oct 2014 21:54:12 +0000 (21:54 +0000)
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

reactos/lib/sdk/CMakeLists.txt
reactos/lib/sdk/RunTmChk/CMakeLists.txt [new file with mode: 0644]
reactos/lib/sdk/RunTmChk/i386/_RTC_CheckEsp.S [new file with mode: 0644]
reactos/lib/sdk/RunTmChk/rtcapi.c [new file with mode: 0644]

index c89a736..3a1f055 100644 (file)
@@ -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 (file)
index 0000000..2e311e3
--- /dev/null
@@ -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 (file)
index 0000000..a88aa33
--- /dev/null
@@ -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
+
+
diff --git a/reactos/lib/sdk/RunTmChk/rtcapi.c b/reactos/lib/sdk/RunTmChk/rtcapi.c
new file mode 100644 (file)
index 0000000..5f75880
--- /dev/null
@@ -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;
+    }
+}
+