From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/tests/exception.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index cdfa4b026b8..4b31ded98b7 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -2309,6 +2309,22 @@ static void test_virtual_unwind(void) { 0x33, 0x40, FALSE, 0x000, 0x010, { {rsp,0x008}, {-1,-1}}}, };
+ static const struct results broken_results_0[] = + { + /* offset rbp handler rip frame registers */ + { 0x00, 0x40, FALSE, 0x000, 0x000, { {rsp,0x008}, {-1,-1} }}, + { 0x02, 0x40, FALSE, 0x008, 0x000, { {rsp,0x010}, {rbp,0x000}, {-1,-1} }}, + { 0x09, 0x40, FALSE, 0x118, 0x000, { {rsp,0x120}, {rbp,0x110}, {-1,-1} }}, + { 0x0e, 0x40, FALSE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {-1,-1} }}, + { 0x15, 0x40, FALSE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {-1,-1} }}, + { 0x1c, 0x40, TRUE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {rsi,0x138}, {-1,-1}}}, + { 0x1d, 0x40, TRUE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {rsi,0x138}, {-1,-1}}}, + { 0x24, 0x40, TRUE, 0x128, 0x010, { {rsp,0x130}, {rbp,0x120}, {rbx,0x130}, {rsi,0x138}, {-1,-1}}}, + /* On Win11 output frame in epilogue corresponds to context->Rsp - 0x8 when fpreg is set. */ + { 0x2b, 0x40, FALSE, 0x128, 0x128, { {rsp,0x130}, {rbp,0x120}, {-1,-1}}}, + { 0x32, 0x40, FALSE, 0x008, 0x008, { {rsp,0x010}, {rbp,0x000}, {-1,-1}}}, + { 0x33, 0x40, FALSE, 0x000, 0x000, { {rsp,0x008}, {-1,-1}}}, + };
static const BYTE function_1[] = { @@ -2445,7 +2461,7 @@ static void test_virtual_unwind(void)
static const struct unwind_test tests[] = { - { function_0, sizeof(function_0), unwind_info_0, results_0, ARRAY_SIZE(results_0) }, + { function_0, sizeof(function_0), unwind_info_0, results_0, ARRAY_SIZE(results_0), broken_results_0 }, { function_1, sizeof(function_1), unwind_info_1, results_1, ARRAY_SIZE(results_1) }, { function_2, sizeof(function_2), unwind_info_2, results_2, ARRAY_SIZE(results_2) }, { function_2, sizeof(function_2), unwind_info_3, results_3, ARRAY_SIZE(results_3) },
From: Paul Gofman pgofman@codeweavers.com
--- include/winnt.h | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/include/winnt.h b/include/winnt.h index 2e1aac0f477..e78b7026102 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -2269,6 +2269,13 @@ NTSYSAPI PVOID WINAPI RtlVirtualUnwind(DWORD,ULONG_PTR,ULONG_PTR,RUNTIME_FUNCT
#define EXCEPTION_CONTINUABLE 0 #define EXCEPTION_NONCONTINUABLE 0x01 +#define EXCEPTION_UNWINDING 0x2 +#define EXCEPTION_EXIT_UNWIND 0x4 +#define EXCEPTION_STACK_INVALID 0x8 +#define EXCEPTION_NESTED_CALL 0x10 +#define EXCEPTION_TARGET_UNWIND 0x20 +#define EXCEPTION_COLLIDED_UNWIND 0x40 +#define EXCEPTION_SOFTWARE_ORIGINATE 0x80
/* * The exception record used by Win32 to give additional information
From: Paul Gofman pgofman@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55238 --- dlls/ntdll/tests/exception.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 4b31ded98b7..c50dfde753b 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -4947,7 +4947,8 @@ static DWORD nested_exception_handler(EXCEPTION_RECORD *rec, EXCEPTION_REGISTRAT return ExceptionContinueExecution; }
- if (rec->ExceptionCode == 0xdeadbeef && rec->ExceptionFlags == EH_NESTED_CALL) + if (rec->ExceptionCode == 0xdeadbeef && (rec->ExceptionFlags == EH_NESTED_CALL + || rec->ExceptionFlags == (EH_NESTED_CALL | EXCEPTION_SOFTWARE_ORIGINATE))) { ok(!rec->NumberParameters, "Got unexpected rec->NumberParameters %lu.\n", rec->NumberParameters); got_nested_exception = TRUE; @@ -4955,7 +4956,7 @@ static DWORD nested_exception_handler(EXCEPTION_RECORD *rec, EXCEPTION_REGISTRAT return ExceptionContinueSearch; }
- ok(rec->ExceptionCode == 0xdeadbeef && !rec->ExceptionFlags, + ok(rec->ExceptionCode == 0xdeadbeef && (!rec->ExceptionFlags || rec->ExceptionFlags == EXCEPTION_SOFTWARE_ORIGINATE), "Got unexpected exception code %#lx, flags %#lx.\n", rec->ExceptionCode, rec->ExceptionFlags); ok(!rec->NumberParameters, "Got unexpected rec->NumberParameters %lu.\n", rec->NumberParameters); ok(frame == (void *)((BYTE *)nested_exception_initial_frame + 8),
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/tests/exception.c | 83 ++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 22 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index c50dfde753b..58cf8ca8eea 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -9894,6 +9894,20 @@ static void wait_for_thread_next_suspend(HANDLE thread)
#define CONTEXT_NATIVE (CONTEXT_XSTATE & CONTEXT_CONTROL)
+struct context_parameters +{ + ULONG flag; + ULONG supported_flags; + ULONG broken_flags; + ULONG context_length; + ULONG legacy_length; + ULONG context_ex_length; + ULONG align; + ULONG flags_offset; + ULONG xsavearea_offset; + ULONG vector_reg_count; +}; + static void test_extended_context(void) { static BYTE except_code_reset_ymm_state[] = @@ -9915,20 +9929,7 @@ static void test_extended_context(void) 0xc3, /* ret */ };
- static const struct - { - ULONG flag; - ULONG supported_flags; - ULONG broken_flags; - ULONG context_length; - ULONG legacy_length; - ULONG context_ex_length; - ULONG align; - ULONG flags_offset; - ULONG xsavearea_offset; - ULONG vector_reg_count; - } - context_arch[] = + static const struct context_parameters context_arch_old[] = { { 0x00100000, /* CONTEXT_AMD64 */ @@ -9955,6 +9956,36 @@ static void test_extended_context(void) 8, }, }; + + static const struct context_parameters context_arch_new[] = + { + { + 0x00100000, /* CONTEXT_AMD64 */ + 0xf800005f, + 0xf8000000, + 0x4d0, /* sizeof(CONTEXT) */ + 0x4d0, /* sizeof(CONTEXT) */ + 0x20, /* sizeof(CONTEXT_EX) */ + 15, + 0x30, + 0x100, /* offsetof(CONTEXT, FltSave) */ + 16, + }, + { + 0x00010000, /* CONTEXT_X86 */ + 0xf800007f, + 0xf8000000, + 0x2cc, /* sizeof(CONTEXT) */ + 0xcc, /* offsetof(CONTEXT, ExtendedRegisters) */ + 0x20, /* sizeof(CONTEXT_EX) */ + 3, + 0, + 0xcc, /* offsetof(CONTEXT, ExtendedRegisters) */ + 8, + }, + }; + const struct context_parameters *context_arch; + const ULONG64 supported_features = 7, supported_compaction_mask = supported_features | ((ULONG64)1 << 63); ULONG expected_length, expected_length_xstate, context_flags, expected_offset; ULONG64 enabled_features, expected_compaction; @@ -10000,7 +10031,15 @@ static void test_extended_context(void) ok(ret == STATUS_INVALID_PARAMETER && length == 0xdeadbeef, "Got unexpected result ret %#lx, length %#lx.\n", ret, length);
- for (test = 0; test < ARRAY_SIZE(context_arch); ++test) + ret = pRtlGetExtendedContextLength(context_arch_new[0].flag, &length); + ok(!ret, "Got %#lx.\n", ret); + if (length == context_arch_new[0].context_length + context_arch_new[0].context_ex_length + + context_arch_new[0].align) + context_arch = context_arch_new; + else + context_arch = context_arch_old; + + for (test = 0; test < 2; ++test) { expected_length = context_arch[test].context_length + context_arch[test].context_ex_length + context_arch[test].align; @@ -10031,18 +10070,19 @@ static void test_extended_context(void) } else { - ok(ret == STATUS_INVALID_PARAMETER && length == 0xdeadbeef, + ok((ret == STATUS_INVALID_PARAMETER || ret == STATUS_NOT_SUPPORTED) && length == 0xdeadbeef, "Got unexpected result ret %#lx, length %#lx, flags 0x%08lx.\n", ret, length, flags); }
SetLastError(0xdeadbeef); bret = pInitializeContext(NULL, flags, NULL, &length2); ok(!bret && length2 == length && GetLastError() - == (!ret ? ERROR_INSUFFICIENT_BUFFER : ERROR_INVALID_PARAMETER), + == (!ret ? ERROR_INSUFFICIENT_BUFFER + : (ret == STATUS_INVALID_PARAMETER ? ERROR_INVALID_PARAMETER : ERROR_NOT_SUPPORTED)), "Got unexpected bret %#x, length2 %#lx, GetLastError() %lu, flags %#lx.\n", bret, length2, GetLastError(), flags);
- if (GetLastError() == ERROR_INVALID_PARAMETER) + if (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_NOT_SUPPORTED) continue;
SetLastError(0xdeadbeef); @@ -10074,11 +10114,11 @@ static void test_extended_context(void) ok(context_ex->All.Offset == -(int)context_arch[test].context_length, "Got unexpected Offset %ld, flags %#lx.\n", context_ex->All.Offset, flags);
- /* No extra 8 bytes in x64 CONTEXT_EX here. */ + /* No extra 8 bytes in x64 CONTEXT_EX here (before Win11). */ ok(context_ex->All.Length == context_arch[test].context_length + context_arch[1].context_ex_length, "Got unexpected Length %#lx, flags %#lx.\n", context_ex->All.Length, flags);
- ok(context_ex->XState.Offset == 25, + ok(context_ex->XState.Offset == context_arch[1].context_ex_length + 1, "Got unexpected Offset %ld, flags %#lx.\n", context_ex->XState.Offset, flags); ok(!context_ex->XState.Length, "Got unexpected Length %#lx, flags %#lx.\n", context_ex->XState.Length, flags); @@ -10608,8 +10648,7 @@ static void test_extended_context(void) *(void **)(call_func_code_set_ymm0 + call_func_offsets.ymm0_save) = data; memcpy(code_mem, call_func_code_set_ymm0, sizeof(call_func_code_set_ymm0)); xs->CompactionMask = 2; - if (!compaction_enabled) - xs->Mask = 0; + xs->Mask = compaction_enabled ? 2 : 0; context_ex->XState.Length = sizeof(XSTATE);
bret = func();
From: Paul Gofman pgofman@codeweavers.com
--- dlls/ntdll/tests/exception.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 58cf8ca8eea..e469aa33643 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -5134,7 +5134,7 @@ static LONG CALLBACK test_raiseexception_regs_handle(EXCEPTION_POINTERS *excepti ok(rec->NumberParameters == EXCEPTION_MAXIMUM_PARAMETERS, "got %lu.\n", rec->NumberParameters); ok(rec->ExceptionCode == 0xdeadbeaf, "got %#lx.\n", rec->ExceptionCode); ok(!rec->ExceptionRecord, "got %p.\n", rec->ExceptionRecord); - ok(!rec->ExceptionFlags, "got %#lx.\n", rec->ExceptionFlags); + ok(!rec->ExceptionFlags || rec->ExceptionFlags == EXCEPTION_SOFTWARE_ORIGINATE, "got %#lx.\n", rec->ExceptionFlags); for (i = 0; i < rec->NumberParameters; ++i) ok(rec->ExceptionInformation[i] == i, "got %Iu, i %u.\n", rec->ExceptionInformation[i], i); return EXCEPTION_CONTINUE_EXECUTION;