Hi,
Can someone with ability to run the testsuite on Windows please test the following new 2 testcases under Windows?
They succeed in WINE now, but I wonder if they will work in Windows.
Ciao, Marcus ---
dlls/ntdll/tests/exception.c | 145 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 145 insertions(+), 0 deletions(-)
ef86b7cd65ade45a1e1cd269bff378166d1ad677 diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index 1d00816..20ff896 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -24,6 +24,7 @@ #define _WIN32_WINNT 0x500 /* For NTSTATUS */ #endif
+#include <stdio.h> #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" @@ -281,6 +282,148 @@ static void test_debug_regs(void) ok(ctx.Dr7 == 0x155,"failed to set debugregister 7 to 0x155"); }
+/* test the single step exception behaviour */ +static int gotsinglesteps = 0; +static DWORD single_step_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, + CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) +{ + gotsinglesteps++; + ok (!(context->EFlags & 0x100), "eflags has single stepping bit set\n"); + return ExceptionContinueExecution; +} + +static BYTE single_stepcode[] = { + 0x9c, /* pushf */ + 0x58, /* pop %eax */ + 0x0d,0,1,0,0, /* or $0x100,%eax */ + 0x50, /* push %eax */ + 0x9d, /* popf */ + 0x35,0,1,0,0, /* xor $0x100,%eax */ + 0x50, /* push %eax */ + 0x9d, /* popf */ + 0xc3 +}; + +static void test_single_step(void) +{ + struct { + EXCEPTION_REGISTRATION_RECORD frame; + } exc_frame; + void (*func)(void) = (void *)single_stepcode; + + pNtCurrentTeb = (void *)GetProcAddress( GetModuleHandleA("ntdll.dll"), "NtCurrentTeb" ); + if (!pNtCurrentTeb) { + trace( "NtCurrentTeb not found, skipping tests\n" ); + return; + } + exc_frame.frame.Handler = single_step_handler; + exc_frame.frame.Prev = pNtCurrentTeb()->Tib.ExceptionList; + pNtCurrentTeb()->Tib.ExceptionList = &exc_frame.frame; + func(); + ok(gotsinglesteps == 1, "expected 1 single step exceptions, got %d\n", gotsinglesteps); + pNtCurrentTeb()->Tib.ExceptionList = exc_frame.frame.Prev; +} + +/* Test the alignment check (AC) flag handling. */ +static BYTE align_check_code[] = { + 0x55, /* push %ebp */ + 0x89,0xe5, /* mov %esp,%ebp */ + 0x9c, /* pushf */ + 0x58, /* pop %eax */ + 0x0d,0,0,4,0, /* or $0x40000,%eax */ + 0x50, /* push %eax */ + 0x9d, /* popf */ + 0x8b,0x45,8, /* mov 0x8(%ebp),%eax */ + 0xc7,0x40,1,42,0,0,0, /* movl $42,0x1(%eax) */ + 0x9c, /* pushf */ + 0x58, /* pop %eax */ + 0x35,0,0,4,0, /* xor $0x40000,%eax */ + 0x50, /* push %eax */ + 0x9d, /* popf */ + 0x5d, /* pop %ebp */ + 0xc3, /* ret */ +}; + +static int gotalignfaults = 0; +static DWORD align_check_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, + CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) +{ + ok (!(context->EFlags & 0x40000), "eflags has AC bit set\n"); + gotalignfaults++; + return ExceptionContinueExecution; +} + +/* Not working in Linux now. Causes problems with unrelated functions. + * have to fix them sometime :( + */ +#undef STACK_ALIGN_TEST + +#ifdef STACK_ALIGN_TEST +static BYTE align_check_code2[] = { + 0x55, /* pushl %ebp */ + 0x89,0xe5, /* movl %esp,%ebp */ + 0x9c, /* pushf */ + 0x58, /* pop %eax */ + 0x0d,0,0,4,0, /* or $0x40000,%eax */ + 0x50, /* push %eax */ + 0x9d, /* popf */ + 0x35,0,0,4,0, /* xor $0x40000,%eax */ + 0x83,0xec,2, /* sub $0x2,%esp */ + 0x50, /* push %eax - test fault on stack */ + 0x89,0xec, /* movl %ebp, %esp */ + 0x50, /* push %eax */ + 0x9d, /* popf */ + 0x5d, /* popl %ebp */ + 0xcb /* lret */ +}; + +static DWORD align_check_handler2( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, + CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) +{ + ok (!(context->EFlags & 0x40000), "eflags has AC bit set\n"); + if (context->Esp & 0x2) { + gotalignfaults++; + context->Esp+=2; + } + return ExceptionContinueExecution; +} +#endif + + +static void test_align_faults(void) +{ + int twoints[2]; + struct { + EXCEPTION_REGISTRATION_RECORD frame; + } exc_frame; + void (*func1)(int*) = (void *)align_check_code; +#ifdef STACK_ALIGN_TEST + void (*func2)(void) = (void *)align_check_code2; +#endif + + pNtCurrentTeb = (void *)GetProcAddress( GetModuleHandleA("ntdll.dll"), "NtCurrentTeb" ); + if (!pNtCurrentTeb) { + trace( "NtCurrentTeb not found, skipping tests\n" ); + return; + } + exc_frame.frame.Handler = align_check_handler; + exc_frame.frame.Prev = pNtCurrentTeb()->Tib.ExceptionList; + pNtCurrentTeb()->Tib.ExceptionList = &exc_frame.frame; + + gotalignfaults=0; + func1(twoints); + ok(gotalignfaults == 0, "got %d alignment faults, expected 0\n", gotalignfaults); + +#ifdef STACK_ALIGN_TEST + exc_frame.frame.Handler = align_check_handler2; + gotalignfaults=0; + func2(); + ok(gotalignfaults == 0, "got %d alignment faults, expected 0\n", gotalignfaults); +#endif + + pNtCurrentTeb()->Tib.ExceptionList = exc_frame.frame.Prev; +} + #endif /* __i386__ */
START_TEST(exception) @@ -288,5 +431,7 @@ START_TEST(exception) #ifdef __i386__ test_prot_fault(); test_debug_regs(); + test_single_step(); + test_align_faults(); #endif }