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
}
--
1.2.4