Module: wine Branch: stable Commit: 09d7498d62c05204db2ab048328f4f896d3aa9cb URL: http://source.winehq.org/git/wine.git/?a=commit;h=09d7498d62c05204db2ab04832...
Author: Sebastian Lackner sebastian@fds-team.de Date: Thu Feb 18 10:34:01 2016 +0100
ntdll/tests: Add more tests for calling int $0x2d on x86 and x86_64.
Signed-off-by: Sebastian Lackner sebastian@fds-team.de Signed-off-by: Alexandre Julliard julliard@winehq.org (cherry picked from commit d0b88e7454b72afa5c8317b46ea0d924edff9411) Signed-off-by: Michael Stefaniuc mstefani@winehq.org
---
dlls/ntdll/tests/exception.c | 190 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 93e5ae5..2123b6b 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -945,6 +945,13 @@ static void test_debugger(void) /* here we handle exception */ } } + else if (stage == 7 || stage == 8) + { + ok(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT, + "expected EXCEPTION_BREAKPOINT, got %08x\n", de.u.Exception.ExceptionRecord.ExceptionCode); + + if (stage == 8) continuestatus = DBG_EXCEPTION_NOT_HANDLED; + } else ok(FALSE, "unexpected stage %x\n", stage);
@@ -1339,6 +1346,8 @@ static void test_dpe_exceptions(void)
#elif defined(__x86_64__)
+#define is_wow64 0 + #define UNW_FLAG_NHANDLER 0 #define UNW_FLAG_EHANDLER 1 #define UNW_FLAG_UHANDLER 2 @@ -1824,6 +1833,181 @@ static void test_ripevent(DWORD numexc) pRtlRemoveVectoredExceptionHandler(vectored_handler); }
+static DWORD debug_service_exceptions; + +static LONG CALLBACK debug_service_handler(EXCEPTION_POINTERS *ExceptionInfo) +{ + EXCEPTION_RECORD *rec = ExceptionInfo->ExceptionRecord; + trace("vect. handler %08x addr:%p\n", rec->ExceptionCode, rec->ExceptionAddress); + + ok(rec->ExceptionCode == EXCEPTION_BREAKPOINT, "ExceptionCode is %08x instead of %08x\n", + rec->ExceptionCode, EXCEPTION_BREAKPOINT); + +#ifdef __i386__ + ok(rec->NumberParameters == (is_wow64 ? 1 : 3), + "ExceptionParameters is %d instead of %d\n", rec->NumberParameters, is_wow64 ? 1 : 3); + ok(rec->ExceptionInformation[0] == ExceptionInfo->ContextRecord->Eax, + "expected ExceptionInformation[0] = %x, got %lx\n", + ExceptionInfo->ContextRecord->Eax, rec->ExceptionInformation[0]); + if (!is_wow64) + { + ok(rec->ExceptionInformation[1] == 0x11111111, + "got ExceptionInformation[1] = %lx\n", rec->ExceptionInformation[1]); + ok(rec->ExceptionInformation[2] == 0x22222222, + "got ExceptionInformation[2] = %lx\n", rec->ExceptionInformation[2]); + } +#else + ok(rec->NumberParameters == 1, + "ExceptionParameters is %d instead of 1\n", rec->NumberParameters); + ok(rec->ExceptionInformation[0] == ExceptionInfo->ContextRecord->Rax, + "expected ExceptionInformation[0] = %lx, got %lx\n", + ExceptionInfo->ContextRecord->Rax, rec->ExceptionInformation[0]); +#endif + + debug_service_exceptions++; + return (rec->ExceptionCode == EXCEPTION_BREAKPOINT) ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_CONTINUE_SEARCH; +} + +#ifdef __i386__ + +static const BYTE call_debug_service_code[] = { + 0x53, /* pushl %ebx */ + 0x57, /* pushl %edi */ + 0x8b, 0x44, 0x24, 0x0c, /* movl 12(%esp),%eax */ + 0xb9, 0x11, 0x11, 0x11, 0x11, /* movl $0x11111111,%ecx */ + 0xba, 0x22, 0x22, 0x22, 0x22, /* movl $0x22222222,%edx */ + 0xbb, 0x33, 0x33, 0x33, 0x33, /* movl $0x33333333,%ebx */ + 0xbf, 0x44, 0x44, 0x44, 0x44, /* movl $0x44444444,%edi */ + 0xcd, 0x2d, /* int $0x2d */ + 0xeb, /* jmp $+17 */ + 0x0f, 0x1f, 0x00, /* nop */ + 0x31, 0xc0, /* xorl %eax,%eax */ + 0xeb, 0x0c, /* jmp $+14 */ + 0x90, 0x90, 0x90, 0x90, /* nop */ + 0x90, 0x90, 0x90, 0x90, + 0x90, + 0x31, 0xc0, /* xorl %eax,%eax */ + 0x40, /* incl %eax */ + 0x5f, /* popl %edi */ + 0x5b, /* popl %ebx */ + 0xc3, /* ret */ +}; + +#else + +static const BYTE call_debug_service_code[] = { + 0x53, /* push %rbx */ + 0x57, /* push %rdi */ + 0x48, 0x89, 0xc8, /* movl %rcx,%rax */ + 0x48, 0xb9, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, /* movabs $0x1111111111111111,%rcx */ + 0x48, 0xba, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, /* movabs $0x2222222222222222,%rdx */ + 0x48, 0xbb, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, /* movabs $0x3333333333333333,%rbx */ + 0x48, 0xbf, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, /* movabs $0x4444444444444444,%rdi */ + 0xcd, 0x2d, /* int $0x2d */ + 0xeb, /* jmp $+17 */ + 0x0f, 0x1f, 0x00, /* nop */ + 0x48, 0x31, 0xc0, /* xor %rax,%rax */ + 0xeb, 0x0e, /* jmp $+16 */ + 0x90, 0x90, 0x90, 0x90, /* nop */ + 0x90, 0x90, 0x90, 0x90, + 0x48, 0x31, 0xc0, /* xor %rax,%rax */ + 0x48, 0xff, 0xc0, /* inc %rax */ + 0x5f, /* pop %rdi */ + 0x5b, /* pop %rbx */ + 0xc3, /* ret */ +}; + +#endif + +static void test_debug_service(DWORD numexc) +{ + const BOOL is_win64 = (sizeof(void *) > sizeof(int)); + DWORD (CDECL *func)(DWORD_PTR) = code_mem; + DWORD expected_exc, expected_ret; + void *vectored_handler; + DWORD ret; + + /* code will return 0 if execution resumes immediately after "int $0x2d", otherwise 1 */ + memcpy(code_mem, call_debug_service_code, sizeof(call_debug_service_code)); + + vectored_handler = pRtlAddVectoredExceptionHandler(TRUE, &debug_service_handler); + ok(vectored_handler != 0, "RtlAddVectoredExceptionHandler failed\n"); + + expected_exc = numexc; + expected_ret = (numexc != 0); + + /* BREAKPOINT_BREAK */ + debug_service_exceptions = 0; + ret = func(0); + ok(debug_service_exceptions == expected_exc, + "BREAKPOINT_BREAK generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + todo_wine_if(is_win64) + ok(ret == expected_ret, + "BREAKPOINT_BREAK returned %u, expected %u\n", ret, expected_ret); + + /* BREAKPOINT_PROMPT */ + debug_service_exceptions = 0; + ret = func(2); + ok(debug_service_exceptions == expected_exc, + "BREAKPOINT_PROMPT generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + todo_wine_if(is_win64) + ok(ret == expected_ret, + "BREAKPOINT_PROMPT returned %u, expected %u\n", ret, expected_ret); + + /* invalid debug service */ + debug_service_exceptions = 0; + ret = func(6); + ok(debug_service_exceptions == expected_exc, + "invalid debug service generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + todo_wine_if(is_win64) + ok(ret == expected_ret, + "invalid debug service returned %u, expected %u\n", ret, expected_ret); + + expected_exc = (is_wow64 ? numexc : 0); + expected_ret = (is_wow64 && numexc); + + /* BREAKPOINT_PRINT */ + debug_service_exceptions = 0; + ret = func(1); + ok(debug_service_exceptions == expected_exc, + "BREAKPOINT_PRINT generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret, + "BREAKPOINT_PRINT returned %u, expected %u\n", ret, expected_ret); + + /* BREAKPOINT_LOAD_SYMBOLS */ + debug_service_exceptions = 0; + ret = func(3); + ok(debug_service_exceptions == expected_exc, + "BREAKPOINT_LOAD_SYMBOLS generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret, + "BREAKPOINT_LOAD_SYMBOLS returned %u, expected %u\n", ret, expected_ret); + + /* BREAKPOINT_UNLOAD_SYMBOLS */ + debug_service_exceptions = 0; + ret = func(4); + ok(debug_service_exceptions == expected_exc, + "BREAKPOINT_UNLOAD_SYMBOLS generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret, + "BREAKPOINT_UNLOAD_SYMBOLS returned %u, expected %u\n", ret, expected_ret); + + /* BREAKPOINT_COMMAND_STRING */ + debug_service_exceptions = 0; + ret = func(5); + ok(debug_service_exceptions == expected_exc || broken(debug_service_exceptions == numexc), + "BREAKPOINT_COMMAND_STRING generated %u exceptions, expected %u\n", + debug_service_exceptions, expected_exc); + ok(ret == expected_ret || broken(ret == (numexc != 0)), + "BREAKPOINT_COMMAND_STRING returned %u, expected %u\n", ret, expected_ret); + + pRtlRemoveVectoredExceptionHandler(vectored_handler); +} + static void test_vectored_continue_handler(void) { PVOID handler1, handler2; @@ -1943,6 +2127,10 @@ START_TEST(exception) test_ripevent(0); test_stage = 6; test_ripevent(1); + test_stage = 7; + test_debug_service(0); + test_stage = 8; + test_debug_service(1); } else skip( "RtlRaiseException not found\n" ); @@ -1956,6 +2144,7 @@ START_TEST(exception) test_rtlraiseexception(); test_outputdebugstring(1, FALSE); test_ripevent(1); + test_debug_service(1); test_vectored_continue_handler(); test_debugger(); test_simd_exceptions(); @@ -1975,6 +2164,7 @@ START_TEST(exception)
test_outputdebugstring(1, FALSE); test_ripevent(1); + test_debug_service(1); test_vectored_continue_handler(); test_virtual_unwind();