From: Paul Gofman <pgofman@codeweavers.com> --- dlls/ntdll/tests/unwind.c | 46 ++++++++++++++++++++++++++++++++++++++- dlls/ntdll/unwind.c | 10 ++++----- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/dlls/ntdll/tests/unwind.c b/dlls/ntdll/tests/unwind.c index 9dea3f3fe60..77d3d1043b9 100644 --- a/dlls/ntdll/tests/unwind.c +++ b/dlls/ntdll/tests/unwind.c @@ -2959,8 +2959,52 @@ static void call_virtual_unwind_x86( int testnum, const struct unwind_test_x86 * if (pRtlVirtualUnwind2) { - CONTEXT new_context = context; + CONTEXT new_context; + + new_context = context; + status = pRtlVirtualUnwind2( UNW_FLAG_NHANDLER, (ULONG_PTR)code_mem, orig_rip, + test->unwind_info ? &runtime_func : NULL, &new_context, + NULL, NULL, &frame, &ctx_ptr, NULL, NULL, NULL, 0 ); + ok( !status, "got %#lx.\n", status ); + new_context = context; + data = (void *)0xdeadbeef; + status = pRtlVirtualUnwind2( UNW_FLAG_NHANDLER, (ULONG_PTR)code_mem, orig_rip, + test->unwind_info ? &runtime_func : NULL, &new_context, + NULL, &data, &frame, &ctx_ptr, NULL, NULL, NULL, 0 ); + ok( !status, "got %#lx.\n", status ); + ok( data == (void *)0xdeadbeef, "got %p.\n", data ); + + new_context = context; + data = (void *)0xdeadbeef; + status = pRtlVirtualUnwind2( UNW_FLAG_EHANDLER, (ULONG_PTR)code_mem, orig_rip, + test->unwind_info ? &runtime_func : NULL, &new_context, + NULL, &data, &frame, &ctx_ptr, NULL, NULL, NULL, 0 ); + ok( !status, "got %#lx.\n", status ); + if (test->results[i].handler) + ok( *(DWORD *)data == 0x08070605, "got %#lx.\n", *(DWORD *)data ); + else + ok( data == (void *)0xdeadbeef, "got %p.\n", data ); + + new_context = context; + handler = (void *)0xdeadbeef; + status = pRtlVirtualUnwind2( UNW_FLAG_NHANDLER, (ULONG_PTR)code_mem, orig_rip, + test->unwind_info ? &runtime_func : NULL, &new_context, + NULL, NULL, &frame, &ctx_ptr, NULL, NULL, &handler, 0 ); + ok( !status, "got %#lx.\n", status ); + ok( !handler, "got %p.\n", handler ); + + new_context = context; + handler = (void *)0xdeadbeef; + data = (void *)0xdeadbeef; + status = pRtlVirtualUnwind2( UNW_FLAG_NHANDLER, (ULONG_PTR)code_mem, orig_rip, + test->unwind_info ? &runtime_func : NULL, &new_context, + NULL, &data, &frame, &ctx_ptr, NULL, NULL, &handler, 0 ); + ok( !status, "got %#lx.\n", status ); + ok( !handler, "got %p.\n", handler ); + ok( data == (void *)0xdeadbeef, "got %p.\n", data ); + + new_context = context; handler = (void *)0xdeadbeef; data = (void *)0xdeadbeef; status = pRtlVirtualUnwind2( UNW_FLAG_EHANDLER, (ULONG_PTR)code_mem, orig_rip, diff --git a/dlls/ntdll/unwind.c b/dlls/ntdll/unwind.c index ace0510f2ef..124e350edd4 100644 --- a/dlls/ntdll/unwind.c +++ b/dlls/ntdll/unwind.c @@ -2071,8 +2071,8 @@ NTSTATUS WINAPI RtlVirtualUnwind2( ULONG type, ULONG_PTR base, ULONG_PTR pc, { context->Rip = *(ULONG64 *)context->Rsp; context->Rsp += sizeof(ULONG64); - *data = NULL; - *handler_ret = NULL; + if (type) *data = NULL; + if (handler_ret) *handler_ret = NULL; return STATUS_SUCCESS; } @@ -2107,7 +2107,7 @@ NTSTATUS WINAPI RtlVirtualUnwind2( ULONG type, ULONG_PTR base, ULONG_PTR pc, TRACE("inside epilog.\n"); interpret_epilog( (BYTE *)pc, context, ctx_ptr ); *frame_ret = info->frame_reg ? context->Rsp - 8 : frame; - *handler_ret = NULL; + if (handler_ret) *handler_ret = NULL; return STATUS_SUCCESS; } } @@ -2188,12 +2188,12 @@ NTSTATUS WINAPI RtlVirtualUnwind2( ULONG type, ULONG_PTR base, ULONG_PTR pc, context->Rsp += sizeof(ULONG64); } - *handler_ret = NULL; + if (handler_ret) *handler_ret = NULL; if (!(info->flags & type)) return STATUS_SUCCESS; /* no matching handler */ if (prolog_offset != ~0) return STATUS_SUCCESS; /* inside prolog */ - *handler_ret = (PEXCEPTION_ROUTINE)((char *)base + handler_data->handler); + if (handler_ret) *handler_ret = (PEXCEPTION_ROUTINE)((char *)base + handler_data->handler); *data = &handler_data->handler + 1; return STATUS_SUCCESS; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10695