https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d52b70a73e75293f03aa5d5c2d6fe2d6aaaa901c

commit d52b70a73e75293f03aa5d5c2d6fe2d6aaaa901c
Author:     Timo Kreuzer <timo.kreu...@reactos.org>
AuthorDate: Mon Jan 8 19:53:28 2024 +0200
Commit:     Timo Kreuzer <timo.kreu...@reactos.org>
CommitDate: Sat Jan 13 19:39:23 2024 +0200

    [NTDLL_APITEST] Add test for x86 RtlUnwind
---
 modules/rostests/apitests/ntdll/testlist.c         |  4 ++
 modules/rostests/apitests/rtl/CMakeLists.txt       |  4 ++
 modules/rostests/apitests/rtl/i386/RtlUnwind-asm.s | 76 ++++++++++++++++++++++
 modules/rostests/apitests/rtl/i386/RtlUnwind.c     | 58 +++++++++++++++++
 modules/rostests/apitests/rtl/testlist.c           |  4 ++
 5 files changed, 146 insertions(+)

diff --git a/modules/rostests/apitests/ntdll/testlist.c 
b/modules/rostests/apitests/ntdll/testlist.c
index a34b06f12d7..f837fa29f8f 100644
--- a/modules/rostests/apitests/ntdll/testlist.c
+++ b/modules/rostests/apitests/ntdll/testlist.c
@@ -94,6 +94,7 @@ extern void func_RtlRemovePrivileges(void);
 extern void func_RtlUnicodeStringToAnsiString(void);
 extern void func_RtlUnicodeStringToCountedOemString(void);
 extern void func_RtlUnicodeToOemN(void);
+extern void func_RtlUnwind(void);
 extern void func_RtlUpcaseUnicodeStringToCountedOemString(void);
 extern void func_RtlValidateUnicodeString(void);
 extern void func_RtlxUnicodeStringToAnsiSize(void);
@@ -201,6 +202,9 @@ const struct test winetest_testlist[] =
     { "StackOverflow",                  func_StackOverflow },
     { "TimerResolution",                func_TimerResolution },
     { "UserModeException",              func_UserModeException },
+#ifdef _M_IX86
+    { "RtlUnwind",                      func_RtlUnwind },
+#endif
 #ifdef _M_AMD64
     { "RtlCaptureContext",              func_RtlCaptureContext },
 #endif
diff --git a/modules/rostests/apitests/rtl/CMakeLists.txt 
b/modules/rostests/apitests/rtl/CMakeLists.txt
index 13bd9b7a718..49d87415d1a 100644
--- a/modules/rostests/apitests/rtl/CMakeLists.txt
+++ b/modules/rostests/apitests/rtl/CMakeLists.txt
@@ -7,6 +7,10 @@ list(APPEND SOURCE
 if(ARCH STREQUAL "i386")
     list(APPEND SOURCE
         i386/RtlCaptureContext.c
+        i386/RtlUnwind.c
+    )
+    list(APPEND ASM_SOURCE
+        i386/RtlUnwind-asm.s
     )
 elseif(ARCH STREQUAL "amd64")
     list(APPEND ASM_SOURCE
diff --git a/modules/rostests/apitests/rtl/i386/RtlUnwind-asm.s 
b/modules/rostests/apitests/rtl/i386/RtlUnwind-asm.s
new file mode 100644
index 00000000000..f9027ada782
--- /dev/null
+++ b/modules/rostests/apitests/rtl/i386/RtlUnwind-asm.s
@@ -0,0 +1,76 @@
+/*
+ * PROJECT:     ReactOS api tests
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Test helper for x86 RtlUnwind
+ * COPYRIGHT:   Copyright 2024 Timo Kreuzer <timo.kreu...@reactos.org>
+ */
+
+#include <asm.inc>
+#include <ks386.inc>
+
+.code
+
+EXTERN _g_InContext:DWORD
+EXTERN _g_OutContext:DWORD
+EXTERN _RtlUnwind@16:PROC
+
+//
+// VOID
+// WINAPI
+// RtlUnwindWrapper(
+//     _In_ PVOID TargetFrame,
+//     _In_ PVOID TargetIp,
+//     _In_ PEXCEPTION_RECORD ExceptionRecord,
+//     _In_ PVOID ReturnValue);
+//
+PUBLIC _RtlUnwindWrapper@16
+FUNC _RtlUnwindWrapper@16
+
+    push ebp
+    mov ebp, esp
+
+    /* Save non-volatile registers */
+    push ebx
+    push esi
+    push edi
+
+    /* Load registers from the in-context */
+    mov eax, _g_InContext[CONTEXT_EAX]
+    mov ebx, _g_InContext[CONTEXT_EBX]
+    mov ecx, _g_InContext[CONTEXT_ECX]
+    mov edx, _g_InContext[CONTEXT_EDX]
+    mov esi, _g_InContext[CONTEXT_ESI]
+    mov edi, _g_InContext[CONTEXT_EDI]
+
+    /* Call the native function */
+    push dword ptr [ebp + 20] // ReturnValue
+    push dword ptr [ebp + 16] // ExceptionRecord
+    push dword ptr [ebp + 12] // TargetIp
+    push dword ptr [ebp + 8]  // TargetFrame
+    call _RtlUnwind@16
+
+    /* Save registers in the out-context */
+    mov _g_OutContext[CONTEXT_EAX], eax
+    mov _g_OutContext[CONTEXT_EBX], ebx
+    mov _g_OutContext[CONTEXT_ECX], ecx
+    mov _g_OutContext[CONTEXT_EDX], edx
+    mov _g_OutContext[CONTEXT_ESI], esi
+    mov _g_OutContext[CONTEXT_EDI], edi
+    mov word ptr _g_OutContext[CONTEXT_SEGCS], cs
+    mov word ptr _g_OutContext[CONTEXT_SEGDS], ds
+    mov word ptr _g_OutContext[CONTEXT_SEGES], es
+    mov word ptr _g_OutContext[CONTEXT_SEGFS], fs
+
+    /* Restore non-volatile registers */
+    pop edi
+    pop esi
+    pop ebx
+
+    mov esp, ebp
+    pop ebp
+    ret 16
+
+ENDFUNC
+
+
+END
diff --git a/modules/rostests/apitests/rtl/i386/RtlUnwind.c 
b/modules/rostests/apitests/rtl/i386/RtlUnwind.c
new file mode 100644
index 00000000000..958c1318cea
--- /dev/null
+++ b/modules/rostests/apitests/rtl/i386/RtlUnwind.c
@@ -0,0 +1,58 @@
+/*
+ * PROJECT:     ReactOS api tests
+ * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE:     Test for x86 RtlUnwind
+ * COPYRIGHT:   Copyright 2024 Timo Kreuzer <timo.kreu...@reactos.org>
+ */
+
+#include <rtltests.h>
+
+CONTEXT g_InContext;
+CONTEXT g_OutContext;
+
+VOID
+WINAPI
+RtlUnwindWrapper(
+    _In_ PVOID TargetFrame,
+    _In_ PVOID TargetIp,
+    _In_ PEXCEPTION_RECORD ExceptionRecord,
+    _In_ PVOID ReturnValue);
+
+START_TEST(RtlUnwind)
+{
+    BOOL IsWow64;
+
+    RtlZeroMemory(&g_InContext, sizeof(g_InContext));
+    RtlZeroMemory(&g_OutContext, sizeof(g_OutContext));
+
+    PEXCEPTION_REGISTRATION_RECORD ExcptReg = 
(PEXCEPTION_REGISTRATION_RECORD)__readfsdword(0);
+    ok(ExcptReg != NULL, "ExcpReg is NULL\n");
+
+    g_InContext.Eax = 0xabcd0001;
+    g_InContext.Ebx = 0xabcd0002;
+    g_InContext.Ecx = 0xabcd0003;
+    g_InContext.Edx = 0xabcd0004;
+    g_InContext.Esi = 0xabcd0005;
+    g_InContext.Edi = 0xabcd0006;
+    RtlUnwindWrapper(ExcptReg, NULL, NULL, (PVOID)0x12345678);
+    ok_eq_hex(g_OutContext.Eax, 0x12345678ul);
+    ok_eq_hex(g_OutContext.Ebx, 0ul);
+    ok_eq_hex(g_OutContext.Ecx, 0ul);
+    ok_eq_hex(g_OutContext.Edx, 0ul);
+    ok_eq_hex(g_OutContext.Esi, 0ul);
+    ok_eq_hex(g_OutContext.Edi, 0ul);
+    if (IsWow64Process(NtCurrentProcess(), &IsWow64) && IsWow64)
+    {
+        ok_eq_hex(g_OutContext.SegCs, 0x23ul);
+        ok_eq_hex(g_OutContext.SegDs, 0x2bul);
+        ok_eq_hex(g_OutContext.SegEs, 0x2bul);
+        ok_eq_hex(g_OutContext.SegFs, 0x53ul);
+    }
+    else
+    {
+        ok_eq_hex(g_OutContext.SegCs, 0x1bul);
+        ok_eq_hex(g_OutContext.SegDs, 0x23ul);
+        ok_eq_hex(g_OutContext.SegEs, 0x23ul);
+        ok_eq_hex(g_OutContext.SegFs, 0x3bul);
+    }
+}
diff --git a/modules/rostests/apitests/rtl/testlist.c 
b/modules/rostests/apitests/rtl/testlist.c
index 1eeed3b056b..62e2694add8 100644
--- a/modules/rostests/apitests/rtl/testlist.c
+++ b/modules/rostests/apitests/rtl/testlist.c
@@ -5,11 +5,15 @@
 
 extern void func_RtlCaptureContext(void);
 extern void func_RtlIntSafe(void);
+extern void func_RtlUnwind(void);
 
 const struct test winetest_testlist[] =
 {
     { "RtlIntSafe",               func_RtlIntSafe },
 
+#ifdef _M_IX86
+    { "RtlUnwind",                func_RtlUnwind },
+#endif
 #ifdef _M_AMD64
     { "RtlCaptureContext",        func_RtlCaptureContext },
 #endif

Reply via email to