Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v2: fix test failures
dlls/ntdll/tests/exception.c | 58 +++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 18 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 7e849fba1aa..1a63a717d21 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -7562,7 +7562,7 @@ static const unsigned test_extended_context_spoil_data1[8] = {0x10, 0x20, 0x30, static const unsigned test_extended_context_spoil_data2[8] = {0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, 0x85};
static BOOL test_extended_context_modified_state; -static BOOL compaction_enabled; +static BOOL xsaveopt_enabled, compaction_enabled;
static DWORD test_extended_context_handler(EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher) @@ -7603,9 +7603,11 @@ static DWORD test_extended_context_handler(EXCEPTION_RECORD *rec, EXCEPTION_REGI context_ymm_data = (unsigned int *)&xs->YmmContext; ok(!((ULONG_PTR)xs % 64), "Got unexpected xs %p.\n", xs);
- ok((compaction_enabled && (xs->CompactionMask & (expected_compaction_mask | 3)) == expected_compaction_mask) - || (!compaction_enabled && !xs->CompactionMask), "Got unexpected CompactionMask %s, compaction %#x.\n", - wine_dbgstr_longlong(xs->CompactionMask), compaction_enabled); + if (compaction_enabled) + ok((xs->CompactionMask & (expected_compaction_mask | 3)) == expected_compaction_mask, + "Got compaction mask %#I64x.\n", xs->CompactionMask); + else + ok(!xs->CompactionMask, "Got compaction mask %#I64x.\n", xs->CompactionMask);
if (test_extended_context_modified_state) { @@ -7615,9 +7617,13 @@ static DWORD test_extended_context_handler(EXCEPTION_RECORD *rec, EXCEPTION_REGI } else { - ok(!xs->Mask, "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask)); - /* The save area has garbage in this case, the state should be restored to INIT_STATE - * without using these data. */ + ok(xs->Mask == (xsaveopt_enabled ? 0 : 4), "Got unexpected Mask %#I64x.\n", xs->Mask); + /* The save area has garbage if xsaveopt is available, so we can't test + * its contents. */ + + /* Clear the mask; the state should be restored to INIT_STATE without + * using this data. */ + xs->Mask = 0; memcpy(context_ymm_data, test_extended_context_spoil_data1 + 4, sizeof(M128A)); }
@@ -7897,6 +7903,7 @@ static void test_extended_context(void) int regs[4];
__cpuidex(regs, 0xd, 1); + xsaveopt_enabled = regs[0] & 1; compaction_enabled = regs[0] & 2; }
@@ -8547,7 +8554,7 @@ static void test_extended_context(void) "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError()); ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n", context->ContextFlags); - ok(xs->Mask == (compaction_enabled ? 0 : 4), "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask)); + ok(xs->Mask == (compaction_enabled ? 0 : 4), "Got unexpected Mask %#I64x.\n", xs->Mask); ok(xs->CompactionMask == 4, "Got unexpected CompactionMask %s.\n", wine_dbgstr_longlong(xs->CompactionMask)); for (i = 0; i < 4; ++i) @@ -8618,7 +8625,7 @@ static void test_extended_context(void) expected_compaction = compaction_enabled ? ((ULONG64)1 << 63) | 4 : 0;
xs = (XSTATE *)((BYTE *)context_ex + context_ex->XState.Offset); - ok(!xs->Mask, "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask)); + ok(xs->Mask == (xsaveopt_enabled ? 0 : 4), "Got unexpected Mask %#I64x.\n", xs->Mask); ok(xs->CompactionMask == expected_compaction, "Got unexpected CompactionMask %s.\n", wine_dbgstr_longlong(xs->CompactionMask));
@@ -8626,12 +8633,13 @@ static void test_extended_context(void) ok(!data[i], "Got unexpected data %#x, i %u.\n", data[i], i);
for (i = 0; i < 4; ++i) - ok(((ULONG *)&xs->YmmContext)[i] == 0xcccccccc + ok(((ULONG *)&xs->YmmContext)[i] == ((xs->Mask & 4) ? 0 : 0xcccccccc) || broken(((ULONG *)&xs->YmmContext)[i] == test_extended_context_data[i + 4]), "Got unexpected data %#x, i %u.\n", ((ULONG *)&xs->YmmContext)[i], i);
/* Test fault exception context. */ memset(data, 0xff, sizeof(data)); + xs->Mask = 0; test_extended_context_modified_state = FALSE; run_exception_test(test_extended_context_handler, NULL, except_code_reset_ymm_state, ARRAY_SIZE(except_code_reset_ymm_state), PAGE_EXECUTE_READ); @@ -8664,12 +8672,13 @@ static void test_extended_context(void)
bret = GetThreadContext(thread, context); ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError()); - ok(!xs->Mask, "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask)); + todo_wine_if (!xsaveopt_enabled) + ok(xs->Mask == (xsaveopt_enabled ? 0 : 4), "Got unexpected Mask %#I64x.\n", xs->Mask); ok(xs->CompactionMask == expected_compaction, "Got unexpected CompactionMask %s.\n", wine_dbgstr_longlong(xs->CompactionMask)); for (i = 0; i < 16 * 4; ++i) - ok(((ULONG *)&xs->YmmContext)[i] == 0xcccccccc, "Got unexpected value %#x, i %u.\n", - ((ULONG *)&xs->YmmContext)[i], i); + ok(((ULONG *)&xs->YmmContext)[i] == ((xs->Mask & 4) ? 0 : 0xcccccccc), + "Got unexpected value %#x, i %u.\n", ((ULONG *)&xs->YmmContext)[i], i);
pSetXStateFeaturesMask(context, 4); memset(&xs->YmmContext, 0, sizeof(xs->YmmContext)); @@ -8725,11 +8734,24 @@ static void test_extended_context(void) memset(&xs->YmmContext, 0xcc, sizeof(xs->YmmContext)); bret = GetThreadContext(thread, context); ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError()); - ok(!xs->Mask || (sizeof(void *) == 4 && xs->Mask == 4), - "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask)); - for (i = 0; i < 16 * 4; ++i) - ok(((ULONG *)&xs->YmmContext)[i] == (xs->Mask ? (i < 8 * 4 ? 0 : 0x48484848) : 0xcccccccc), - "Got unexpected value %#x, i %u.\n", ((ULONG *)&xs->YmmContext)[i], i); + todo_wine_if (!xsaveopt_enabled && sizeof(void *) != 4) + ok(xs->Mask == (xsaveopt_enabled ? 0 : 4) || (sizeof(void *) == 4 && xs->Mask == 4), + "Got unexpected Mask %#I64x.\n", xs->Mask); + if (xs->Mask == 4) + { + for (i = 0; i < 8 * sizeof(void *); ++i) + ok(((ULONG *)&xs->YmmContext)[i] == 0, + "Got unexpected value %#x, i %u.\n", ((ULONG *)&xs->YmmContext)[i], i); + for (; i < 16 * 4; ++i) + ok(((ULONG *)&xs->YmmContext)[i] == 0x48484848, + "Got unexpected value %#x, i %u.\n", ((ULONG *)&xs->YmmContext)[i], i); + } + else + { + for (i = 0; i < 16 * 4; ++i) + ok(((ULONG *)&xs->YmmContext)[i] == 0xcccccccc, + "Got unexpected value %#x, i %u.\n", ((ULONG *)&xs->YmmContext)[i], i); + }
bret = ResumeThread(thread); ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError());
Follow-up to 94ee27097228ac37f1576565c9f93f6186ff66a3.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/tests/exception.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 1a63a717d21..24f905e86dd 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -4002,7 +4002,6 @@ static void test_thread_context(void) XMM_SAVE_AREA32 FltSave; WORD SegCs, SegDs, SegEs, SegFs, SegGs, SegSs; } expect; - XMM_SAVE_AREA32 broken_fltsave; NTSTATUS (*func_ptr)( void *arg1, void *arg2, struct expected *res, void *func ) = code_mem;
static const BYTE call_func[] = @@ -4164,12 +4163,12 @@ static void test_thread_context(void) COMPARE( SegGs ); COMPARE( SegSs );
- broken_fltsave = context.FltSave; - memset( &broken_fltsave.ErrorOpcode, 0xcc, 0x12 ); + /* AMD CPUs don't save the opcode or data pointer if no exception is + * pending; see the AMD64 Architecture Programmer's Manual Volume 5 s.v. + * FXSAVE */ + memcpy( &expect.FltSave, &context.FltSave, 0x12 );
- ok( !memcmp( &context.FltSave, &expect.FltSave, offsetof( XMM_SAVE_AREA32, XmmRegisters )) || - broken( !memcmp( &broken_fltsave, &expect.FltSave, offsetof( XMM_SAVE_AREA32, XmmRegisters )) ) /* w2008, w8 */, - "wrong FltSave\n" ); + ok( !memcmp( &context.FltSave, &expect.FltSave, offsetof( XMM_SAVE_AREA32, ErrorOffset )), "wrong FltSave\n" ); for (i = 6; i < 16; i++) ok( !memcmp( &context.Xmm0 + i, &expect.FltSave.XmmRegisters[i], sizeof(context.Xmm0) ), "wrong xmm%u\n", i );
The stack handler doesn't return ExceptionContinueExecution if test_stage == 2.
Signed-off-by: Zebediah Figura z.figura12@gmail.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 24f905e86dd..7fa966b0c4e 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -3719,7 +3719,7 @@ static void run_rtlraiseexception_test(DWORD exceptioncode)
todo_wine ok( !rtlraiseexception_handler_called, "Frame handler called\n" ); - todo_wine + todo_wine_if (test_stage != 2) ok( rtlraiseexception_unhandled_handler_called, "UnhandledExceptionFilter wasn't called\n" );
if (have_vectored_api)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- Now that we can use __ASM_GLOBAL_FUNC everywhere, let's stop manually writing out binary code where we don't need to.
The bodies of the functions are changed since we're no longer embedding the parameters directly in the assembly, but rather passing them.
dlls/ntdll/tests/exception.c | 205 ++++++++++------------------------- 1 file changed, 59 insertions(+), 146 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 7fa966b0c4e..8f23677064b 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -30,6 +30,7 @@ #include "winternl.h" #include "ddk/wdm.h" #include "excpt.h" +#include "wine/asm.h" #include "wine/test.h" #include "intrin.h"
@@ -7639,131 +7640,70 @@ done: return ExceptionContinueExecution; }
-struct call_func_offsets -{ - unsigned int func_addr; - unsigned int func_param1; - unsigned int func_param2; - unsigned int ymm0_save; -}; +int __cdecl call_func_set_ymm0( void *arg1, void *arg2, void *func, void *ymm0_save ); +int __cdecl call_func_reset_ymm_state( void *arg1, void *arg2, void *func, void *ymm0_save ); + #ifdef __x86_64__ -static BYTE call_func_code_set_ymm0[] = -{ - 0x55, /* pushq %rbp */ - 0x48, 0xb8, /* mov imm,%rax */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x48, 0xb9, /* mov imm,%rcx */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +__ASM_GLOBAL_FUNC( call_func_set_ymm0, + "pushq %rbx\n\t" + "movq %r9,%rbx\n\t" + "vmovups (%rbx),%ymm0\n\t" + "subq $0x20,%rsp\n\t" + "call *%r8\n\t" + "addq $0x20,%rsp\n\t" + "vmovups %ymm0,(%rbx)\n\t" + "popq %rbx\n\t" + "ret" );
- 0x48, 0xba, /* mov imm,%rdx */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +__ASM_GLOBAL_FUNC( call_func_reset_ymm_state, + "pushq %rbx\n\t" + "movq %r9,%rbx\n\t" + "vzeroupper\n\t" + "xorps %xmm0,%xmm0\n\t" + "subq $0x20,%rsp\n\t" + "call *%r8\n\t" + "addq $0x20,%rsp\n\t" + "vmovups %ymm0,(%rbx)\n\t" + "popq %rbx\n\t" + "ret" );
- 0x48, 0xbd, /* mov imm,%rbp */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0xc5, 0xfc, 0x10, 0x45, 0x00, /* vmovups (%rbp),%ymm0 */ - 0x48, 0x83, 0xec, 0x20, /* sub $0x20,%rsp */ - 0xff, 0xd0, /* call *rax */ - 0x48, 0x83, 0xc4, 0x20, /* add $0x20,%rsp */ - 0xc5, 0xfc, 0x11, 0x45, 0x00, /* vmovups %ymm0,(%rbp) */ - 0x5d, /* popq %rbp */ - 0xc3, /* ret */ -}; -static BYTE call_func_code_reset_ymm_state[] = -{ - 0x55, /* pushq %rbp */ - 0x48, 0xb8, /* mov imm,%rax */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x48, 0xb9, /* mov imm,%rcx */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x48, 0xba, /* mov imm,%rdx */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0x48, 0xbd, /* mov imm,%rbp */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - 0xc5, 0xf8, 0x77, /* vzeroupper */ - 0x0f, 0x57, 0xc0, /* xorps %xmm0,%xmm0 */ - 0x48, 0x83, 0xec, 0x20, /* sub $0x20,%rsp */ - 0xff, 0xd0, /* call *rax */ - 0x48, 0x83, 0xc4, 0x20, /* add $0x20,%rsp */ - 0xc5, 0xfc, 0x11, 0x45, 0x00, /* vmovups %ymm0,(%rbp) */ - 0x5d, /* popq %rbp */ - 0xc3, /* ret */ -}; -static const struct call_func_offsets call_func_offsets = {3, 13, 23, 33}; #else -static BYTE call_func_code_set_ymm0[] = -{ - 0x55, /* pushl %ebp */ - 0xb8, /* mov imm,%eax */ - 0x00, 0x00, 0x00, 0x00,
- 0xb9, /* mov imm,%ecx */ - 0x00, 0x00, 0x00, 0x00, +__ASM_GLOBAL_FUNC( call_func_set_ymm0, + "pushl %ebp\n\t" + "movl %esp,%ebp\n\t" + "movl 20(%ebp),%ecx\n\t" + "vmovups (%ecx),%ymm0\n\t" + "pushl 12(%ebp)\n\t" + "pushl 8(%ebp)\n\t" + "call *16(%ebp)\n\t" + "movl 20(%ebp),%ecx\n\t" + "vmovups %ymm0,(%ecx)\n\t" + "leave\n\t" + "ret" );
- 0xba, /* mov imm,%edx */ - 0x00, 0x00, 0x00, 0x00, +__ASM_GLOBAL_FUNC( call_func_reset_ymm_state, + "pushl %ebp\n\t" + "movl %esp,%ebp\n\t" + "vzeroupper\n\t" + "xorps %xmm0,%xmm0\n\t" + "pushl 12(%ebp)\n\t" + "pushl 8(%ebp)\n\t" + "call *16(%ebp)\n\t" + "movl 20(%ebp),%ecx\n\t" + "vmovups %ymm0,(%ecx)\n\t" + "leave\n\t" + "ret" );
- 0xbd, /* mov imm,%ebp */ - 0x00, 0x00, 0x00, 0x00, - - 0x81, 0xfa, 0xef, 0xbe, 0xad, 0xde, - /* cmpl $0xdeadbeef, %edx */ - 0x74, 0x01, /* je 1f */ - 0x52, /* pushl %edx */ - 0x51, /* 1: pushl %ecx */ - 0xc5, 0xfc, 0x10, 0x45, 0x00, /* vmovups (%ebp),%ymm0 */ - 0xff, 0xd0, /* call *eax */ - 0xc5, 0xfc, 0x11, 0x45, 0x00, /* vmovups %ymm0,(%ebp) */ - 0x5d, /* popl %ebp */ - 0xc3, /* ret */ -}; -static BYTE call_func_code_reset_ymm_state[] = -{ - 0x55, /* pushl %ebp */ - 0xb8, /* mov imm,%eax */ - 0x00, 0x00, 0x00, 0x00, - - 0xb9, /* mov imm,%ecx */ - 0x00, 0x00, 0x00, 0x00, - - 0xba, /* mov imm,%edx */ - 0x00, 0x00, 0x00, 0x00, - - 0xbd, /* mov imm,%ebp */ - 0x00, 0x00, 0x00, 0x00, - - 0x81, 0xfa, 0xef, 0xbe, 0xad, 0xde, - /* cmpl $0xdeadbeef, %edx */ - 0x74, 0x01, /* je 1f */ - 0x52, /* pushl %edx */ - 0x51, /* 1: pushl %ecx */ - 0xc5, 0xf8, 0x77, /* vzeroupper */ - 0x0f, 0x57, 0xc0, /* xorps %xmm0,%xmm0 */ - 0xff, 0xd0, /* call *eax */ - 0xc5, 0xfc, 0x11, 0x45, 0x00, /* vmovups %ymm0,(%ebp) */ - 0x5d, /* popl %ebp */ - 0xc3, /* ret */ -}; -static const struct call_func_offsets call_func_offsets = {2, 7, 12, 17}; #endif
static DWORD WINAPI test_extended_context_thread(void *arg) { - ULONG (WINAPI* func)(void) = code_mem; static unsigned int data[8]; unsigned int i;
- memcpy(code_mem, call_func_code_reset_ymm_state, sizeof(call_func_code_reset_ymm_state)); - *(void **)((BYTE *)code_mem + call_func_offsets.func_addr) = SuspendThread; - *(void **)((BYTE *)code_mem + call_func_offsets.func_param1) = (void *)GetCurrentThread(); - *(void **)((BYTE *)code_mem + call_func_offsets.func_param2) = (void *)0xdeadbeef; - *(void **)((BYTE *)code_mem + call_func_offsets.ymm0_save) = data; - func(); + call_func_reset_ymm_state(GetCurrentThread(), 0, SuspendThread, data);
for (i = 0; i < 4; ++i) ok(!data[i], "Got unexpected data %#x, i %u.\n", data[i], i); @@ -7771,19 +7711,9 @@ static DWORD WINAPI test_extended_context_thread(void *arg) ok(data[i] == 0x48484848, "Got unexpected data %#x, i %u.\n", data[i], i); memset(data, 0x68, sizeof(data));
- memcpy(code_mem, call_func_code_set_ymm0, sizeof(call_func_code_set_ymm0)); - *(void **)((BYTE *)code_mem + call_func_offsets.func_addr) = SuspendThread; - *(void **)((BYTE *)code_mem + call_func_offsets.func_param1) = (void *)GetCurrentThread(); - *(void **)((BYTE *)code_mem + call_func_offsets.func_param2) = (void *)0xdeadbeef; - *(void **)((BYTE *)code_mem + call_func_offsets.ymm0_save) = data; - func(); + call_func_set_ymm0(GetCurrentThread(), 0, SuspendThread, data);
- memcpy(code_mem, call_func_code_reset_ymm_state, sizeof(call_func_code_reset_ymm_state)); - *(void **)((BYTE *)code_mem + call_func_offsets.func_addr) = SuspendThread; - *(void **)((BYTE *)code_mem + call_func_offsets.func_param1) = (void *)GetCurrentThread(); - *(void **)((BYTE *)code_mem + call_func_offsets.func_param2) = (void *)0xdeadbeef; - *(void **)((BYTE *)code_mem + call_func_offsets.ymm0_save) = data; - func(); + call_func_reset_ymm_state(GetCurrentThread(), 0, SuspendThread, data); return 0; }
@@ -7875,7 +7805,6 @@ static void test_extended_context(void) unsigned int i, j, address_offset, test; ULONG ret, ret2, length, length2, align; ULONG flags, flags_fpx, expected_flags; - ULONG (WINAPI* func)(void) = code_mem; CONTEXT_EX *context_ex; CONTEXT *context; unsigned data[8]; @@ -8486,14 +8415,8 @@ static void test_extended_context(void) context_ex = (CONTEXT_EX *)(context + 1); xs = (XSTATE *)((BYTE *)context_ex + context_ex->XState.Offset);
- *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_addr) = RtlCaptureContext; - *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_param1) = context; - *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_param2) = (void *)0xdeadbeef; - *(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)); - memcpy(data, test_extended_context_data, sizeof(data)); - func(); + call_func_set_ymm0(context, 0, RtlCaptureContext, data); ok(context->ContextFlags == (CONTEXT_FULL | CONTEXT_SEGMENTS), "Got unexpected ContextFlags %#x.\n", context->ContextFlags); for (i = 0; i < 8; ++i) @@ -8514,17 +8437,12 @@ static void test_extended_context(void) pSetXStateFeaturesMask(context, ~(ULONG64)0); ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n", context->ContextFlags); - *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_addr) = GetThreadContext; - *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_param1) = (void *)GetCurrentThread(); - *(void **)(call_func_code_set_ymm0 + call_func_offsets.func_param2) = context; - *(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; context_ex->XState.Length = sizeof(XSTATE); - - bret = func(); + bret = call_func_set_ymm0(GetCurrentThread(), context, GetThreadContext, data); ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError());
ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n", @@ -8548,7 +8466,7 @@ static void test_extended_context(void) xs->CompactionMask = 4; xs->Mask = compaction_enabled ? 0 : 4; context_ex->XState.Length = sizeof(XSTATE) + 64; - bret = func(); + bret = call_func_set_ymm0(GetCurrentThread(), context, GetThreadContext, data); ok(!bret && GetLastError() == ERROR_INVALID_PARAMETER, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError()); ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n", @@ -8564,7 +8482,7 @@ static void test_extended_context(void) xs->CompactionMask = 4; xs->Mask = compaction_enabled ? 0 : 4; context_ex->XState.Length = offsetof(XSTATE, YmmContext); - bret = func(); + bret = call_func_set_ymm0(GetCurrentThread(), context, GetThreadContext, data); ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n", context->ContextFlags); ok(!bret && GetLastError() == ERROR_MORE_DATA, @@ -8580,7 +8498,7 @@ static void test_extended_context(void) context_ex->XState.Length = sizeof(XSTATE); xs->CompactionMask = 4; xs->Mask = compaction_enabled ? 0 : 4; - bret = func(); + bret = call_func_set_ymm0(GetCurrentThread(), context, GetThreadContext, data); ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError());
ok(context->ContextFlags == expected_flags, "Got unexpected ContextFlags %#x.\n", @@ -8605,13 +8523,8 @@ static void test_extended_context(void) memset(&xs->YmmContext, 0xcc, sizeof(xs->YmmContext)); ok(bret, "Got unexpected bret %#x.\n", bret); pSetXStateFeaturesMask(context, ~(ULONG64)0); - *(void **)(call_func_code_reset_ymm_state + call_func_offsets.func_addr) = GetThreadContext; - *(void **)(call_func_code_reset_ymm_state + call_func_offsets.func_param1) = (void *)GetCurrentThread(); - *(void **)(call_func_code_reset_ymm_state + call_func_offsets.func_param2) = context; - *(void **)(call_func_code_reset_ymm_state + call_func_offsets.ymm0_save) = data; - memcpy(code_mem, call_func_code_reset_ymm_state, sizeof(call_func_code_reset_ymm_state));
- bret = func(); + bret = call_func_reset_ymm_state(GetCurrentThread(), context, GetThreadContext, data); ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError());
expected_flags = CONTEXT_FULL | CONTEXT_XSTATE | CONTEXT_FLOATING_POINT;
Zebediah Figura z.figura12@gmail.com writes:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
Now that we can use __ASM_GLOBAL_FUNC everywhere, let's stop manually writing out binary code where we don't need to.
I think we want to preserve the ability to build tests with MSVC.
On 6/24/21 3:00 PM, Alexandre Julliard wrote:
Zebediah Figura z.figura12@gmail.com writes:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
Now that we can use __ASM_GLOBAL_FUNC everywhere, let's stop manually writing out binary code where we don't need to.
I think we want to preserve the ability to build tests with MSVC.
Understandable; I'll drop these patches.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ntdll/tests/exception.c | 61 ++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 30 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 8f23677064b..f459bd97741 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -194,6 +194,8 @@ static BOOL is_wow64; static BOOL have_vectored_api; static int test_stage;
+void __cdecl do_breakpoint(void); + #if defined(__i386__) || defined(__x86_64__) static void test_debugger_xstate(HANDLE thread, CONTEXT *ctx, int stage) { @@ -1204,8 +1206,8 @@ static void test_debugger(DWORD cont_status) { ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT, "expected EXCEPTION_BREAKPOINT, got %08x\n", de.u.Exception.ExceptionRecord.ExceptionCode); - ok((char *)ctx.Eip == (char *)code_mem_address + 2, - "expected Eip = %p, got 0x%x\n", (char *)code_mem_address + 2, ctx.Eip); + ok((char *)ctx.Eip == (char *)do_breakpoint + 2, + "expected Eip = %p, got 0x%x\n", (char *)do_breakpoint + 2, ctx.Eip);
if (stage == 10) continuestatus = DBG_EXCEPTION_NOT_HANDLED; } @@ -3885,8 +3887,8 @@ static void test_debugger(DWORD cont_status) { ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT, "expected EXCEPTION_BREAKPOINT, got %08x\n", de.u.Exception.ExceptionRecord.ExceptionCode); - ok((char *)ctx.Rip == (char *)code_mem_address + 2, - "expected Rip = %p, got %p\n", (char *)code_mem_address + 2, (char *)ctx.Rip); + ok((char *)ctx.Rip == (char *)do_breakpoint + 2, + "expected Rip = %p, got %p\n", (char *)do_breakpoint + 2, (char *)ctx.Rip); if (stage == 10) continuestatus = DBG_EXCEPTION_NOT_HANDLED; } else if (stage == 11 || stage == 12 || stage == 13) @@ -6964,6 +6966,19 @@ static void test_ripevent(DWORD numexc) pRtlRemoveVectoredExceptionHandler(vectored_handler); }
+__ASM_GLOBAL_FUNC( do_breakpoint, +#if defined(__i386__) || defined(__x86_64__) + ".byte 0xcd,0x03\n\t" /* force generating a two-byte int $0x3 */ + "ret" +#elif defined(__arm__) + "udf #0xfe\n\t" + "bx lr" +#elif defined(__aarch64__) + "brk #0xf000\n\t" + "ret" +#endif +); + static DWORD breakpoint_exceptions;
static LONG CALLBACK breakpoint_handler(EXCEPTION_POINTERS *ExceptionInfo) @@ -6975,32 +6990,32 @@ static LONG CALLBACK breakpoint_handler(EXCEPTION_POINTERS *ExceptionInfo) rec->ExceptionCode, EXCEPTION_BREAKPOINT);
#ifdef __i386__ - ok(ExceptionInfo->ContextRecord->Eip == (DWORD)code_mem + 1, - "expected Eip = %x, got %x\n", (DWORD)code_mem + 1, ExceptionInfo->ContextRecord->Eip); + ok(ExceptionInfo->ContextRecord->Eip == (DWORD)do_breakpoint + 1, + "expected Eip = %x, got %x\n", (DWORD)do_breakpoint + 1, ExceptionInfo->ContextRecord->Eip); ok(rec->NumberParameters == (is_wow64 ? 1 : 3), "ExceptionParameters is %d instead of %d\n", rec->NumberParameters, is_wow64 ? 1 : 3); ok(rec->ExceptionInformation[0] == 0, "got ExceptionInformation[0] = %lx\n", rec->ExceptionInformation[0]); - ExceptionInfo->ContextRecord->Eip = (DWORD)code_mem + 2; + ExceptionInfo->ContextRecord->Eip = (DWORD)do_breakpoint + 2; #elif defined(__x86_64__) - ok(ExceptionInfo->ContextRecord->Rip == (DWORD_PTR)code_mem + 1, - "expected Rip = %lx, got %lx\n", (DWORD_PTR)code_mem + 1, ExceptionInfo->ContextRecord->Rip); + ok(ExceptionInfo->ContextRecord->Rip == (DWORD_PTR)do_breakpoint + 1, + "expected Rip = %lx, got %lx\n", (DWORD_PTR)do_breakpoint + 1, ExceptionInfo->ContextRecord->Rip); ok(rec->NumberParameters == 1, "ExceptionParameters is %d instead of 1\n", rec->NumberParameters); ok(rec->ExceptionInformation[0] == 0, "got ExceptionInformation[0] = %lx\n", rec->ExceptionInformation[0]); - ExceptionInfo->ContextRecord->Rip = (DWORD_PTR)code_mem + 2; + ExceptionInfo->ContextRecord->Rip = (DWORD_PTR)do_breakpoint + 2; #elif defined(__arm__) - ok(ExceptionInfo->ContextRecord->Pc == (DWORD)code_mem + 1, - "expected pc = %x, got %x\n", (DWORD)code_mem + 1, ExceptionInfo->ContextRecord->Pc); + ok(ExceptionInfo->ContextRecord->Pc == (DWORD)do_breakpoint + 1, + "expected pc = %x, got %x\n", (DWORD)do_breakpoint + 1, ExceptionInfo->ContextRecord->Pc); ok(rec->NumberParameters == 1, "ExceptionParameters is %d instead of 1\n", rec->NumberParameters); ok(rec->ExceptionInformation[0] == 0, "got ExceptionInformation[0] = %lx\n", rec->ExceptionInformation[0]); ExceptionInfo->ContextRecord->Pc += 2; #elif defined(__aarch64__) - ok(ExceptionInfo->ContextRecord->Pc == (DWORD_PTR)code_mem, - "expected pc = %lx, got %lx\n", (DWORD_PTR)code_mem, ExceptionInfo->ContextRecord->Pc); + ok(ExceptionInfo->ContextRecord->Pc == (DWORD_PTR)do_breakpoint, + "expected pc = %lx, got %lx\n", (DWORD_PTR)do_breakpoint, ExceptionInfo->ContextRecord->Pc); ok(rec->NumberParameters == 1, "ExceptionParameters is %d instead of 1\n", rec->NumberParameters); ok(rec->ExceptionInformation[0] == 0, @@ -7012,28 +7027,15 @@ static LONG CALLBACK breakpoint_handler(EXCEPTION_POINTERS *ExceptionInfo) return (rec->ExceptionCode == EXCEPTION_BREAKPOINT) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH; }
-#if defined(__i386__) || defined(__x86_64__) -static const BYTE breakpoint_code[] = { 0xcd, 0x03, 0xc3 }; /* int $0x3; ret */ -#elif defined(__arm__) -static const DWORD breakpoint_code[] = { 0xdefe, 0x4770 }; /* udf #0xfe; bx lr */ -#elif defined(__aarch64__) -static const DWORD breakpoint_code[] = { 0xd43e0000, 0xd65f03c0 }; /* brk #0xf000; ret */ -#endif - static void test_breakpoint(DWORD numexc) { - DWORD (CDECL *func)(void) = code_mem; void *vectored_handler;
- memcpy(code_mem, breakpoint_code, sizeof(breakpoint_code)); -#ifdef __arm__ - func = (void *)((char *)code_mem + 1); /* thumb */ -#endif vectored_handler = pRtlAddVectoredExceptionHandler(TRUE, &breakpoint_handler); ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n");
breakpoint_exceptions = 0; - func(); + do_breakpoint(); ok(breakpoint_exceptions == numexc, "int $0x3 generated %u exceptions, expected %u\n", breakpoint_exceptions, numexc);
@@ -7066,8 +7068,7 @@ static void test_debuggee_xstate(void)
if (!pRtlGetEnabledExtendedFeatures || !pRtlGetEnabledExtendedFeatures(1 << XSTATE_AVX)) { - memcpy(code_mem, breakpoint_code, sizeof(breakpoint_code)); - func(); + do_breakpoint(); return; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=93054
Your paranoid android.
=== w1064v1507 (64 bit report) ===
ntdll: exception.c:4375: Test failed: cs32: ecx 48f20000 / AAEC871948F20000