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