[2/2] kernel32/tests: Port stack commit tests to x86_64.

Sebastian Lackner sebastian at fds-team.de
Fri Apr 15 02:36:54 CDT 2016


Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
---
 dlls/kernel32/tests/virtual.c |  176 +++++++++++++++++++++++-------------------
 1 file changed, 100 insertions(+), 76 deletions(-)

diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c
index 1a8fd6f..a3a44f8 100644
--- a/dlls/kernel32/tests/virtual.c
+++ b/dlls/kernel32/tests/virtual.c
@@ -1806,6 +1806,93 @@ static void test_write_watch(void)
     VirtualFree( base, 0, MEM_RELEASE );
 }
 
+#if defined(__i386__) || defined(__x86_64__)
+
+static DWORD WINAPI stack_commit_func( void *arg )
+{
+    volatile char *p = (char *)&p;
+
+    /* trigger all guard pages, to ensure that the pages are committed */
+    while (p >= (char *)pNtCurrentTeb()->DeallocationStack + 4 * 0x1000)
+    {
+        p[0] |= 0;
+        p -= 0x1000;
+    }
+
+    ok( arg == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", arg );
+    return 42;
+}
+
+static void test_stack_commit(void)
+{
+#ifdef __i386__
+    static const char code_call_on_stack[] = {
+        0x55,                   /* pushl %ebp */
+        0x56,                   /* pushl %esi */
+        0x89, 0xe6,             /* movl %esp,%esi */
+        0x8b, 0x4c, 0x24, 0x0c, /* movl 12(%esp),%ecx - func */
+        0x8b, 0x54, 0x24, 0x10, /* movl 16(%esp),%edx - arg */
+        0x8b, 0x44, 0x24, 0x14, /* movl 20(%esp),%eax - stack */
+        0x83, 0xe0, 0xf0,       /* andl $~15,%eax */
+        0x83, 0xe8, 0x0c,       /* subl $12,%eax */
+        0x89, 0xc4,             /* movl %eax,%esp */
+        0x52,                   /* pushl %edx */
+        0x31, 0xed,             /* xorl %ebp,%ebp */
+        0xff, 0xd1,             /* call *%ecx */
+        0x89, 0xf4,             /* movl %esi,%esp */
+        0x5e,                   /* popl %esi */
+        0x5d,                   /* popl %ebp */
+        0xc2, 0x0c, 0x00 };     /* ret $12 */
+#else
+    static const char code_call_on_stack[] = {
+        0x55,                   /* pushq %rbp */
+        0x48, 0x89, 0xe5,       /* movq %rsp,%rbp */
+                                /* %rcx - func, %rdx - arg, %r8 - stack */
+        0x48, 0x87, 0xca,       /* xchgq %rcx,%rdx */
+        0x49, 0x83, 0xe0, 0xf0, /* andq $~15,%r8 */
+        0x49, 0x83, 0xe8, 0x20, /* subq $0x20,%r8 */
+        0x4c, 0x89, 0xc4,       /* movq %r8,%rsp */
+        0xff, 0xd2,             /* callq *%rdx */
+        0x48, 0x89, 0xec,       /* movq %rbp,%rsp */
+        0x5d,                   /* popq %rbp */
+        0xc3 };                 /* ret */
+#endif
+    DWORD (WINAPI *call_on_stack)( DWORD (WINAPI *func)(void *), void *arg, void *stack );
+    void *old_stack, *old_stack_base, *old_stack_limit;
+    void *new_stack, *new_stack_base;
+    DWORD result;
+
+    call_on_stack = VirtualAlloc( 0, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+    ok( call_on_stack != NULL, "VirtualAlloc failed %u\n", GetLastError() );
+    memcpy( call_on_stack, code_call_on_stack, sizeof(code_call_on_stack) );
+
+    /* allocate a new stack, only the first guard page is committed */
+    new_stack = VirtualAlloc( 0, 0x400000, MEM_RESERVE, PAGE_READWRITE );
+    ok( new_stack != NULL, "VirtualAlloc failed %u\n", GetLastError() );
+    new_stack_base = (char *)new_stack + 0x400000;
+    VirtualAlloc( (char *)new_stack_base - 0x1000, 0x1000, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD );
+
+    old_stack       = pNtCurrentTeb()->DeallocationStack;
+    old_stack_base  = pNtCurrentTeb()->Tib.StackBase;
+    old_stack_limit = pNtCurrentTeb()->Tib.StackLimit;
+
+    pNtCurrentTeb()->DeallocationStack  = new_stack;
+    pNtCurrentTeb()->Tib.StackBase      = new_stack_base;
+    pNtCurrentTeb()->Tib.StackLimit     = new_stack_base;
+
+    result = call_on_stack( stack_commit_func, (void *)0xdeadbeef, new_stack_base );
+
+    pNtCurrentTeb()->DeallocationStack  = old_stack;
+    pNtCurrentTeb()->Tib.StackBase      = old_stack_base;
+    pNtCurrentTeb()->Tib.StackLimit     = old_stack_limit;
+
+    ok( result == 42, "expected 42, got %u\n", result );
+
+    VirtualFree( new_stack, 0, MEM_RELEASE );
+    VirtualFree( call_on_stack, 0, MEM_RELEASE );
+}
+
+#endif  /* defined(__i386__) || defined(__x86_64__) */
 #ifdef __i386__
 
 static LONG num_guard_page_calls;
@@ -2057,81 +2144,6 @@ static void test_guard_page(void)
     VirtualFree( base, 0, MEM_RELEASE );
 }
 
-static DWORD WINAPI stack_commit_func( void *arg )
-{
-    volatile char *p = (char *)&p;
-
-    /* trigger all guard pages, to ensure that the pages are committed */
-    while (p >= (char *)pNtCurrentTeb()->DeallocationStack + 3 * 0x1000)
-    {
-        p[0] |= 0;
-        p -= 0x1000;
-    }
-
-    ok( arg == (void *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", arg );
-    return 42;
-}
-
-static void test_stack_commit(void)
-{
-    static const char code_call_on_stack[] = {
-        0x55,                   /* pushl %ebp */
-        0x56,                   /* pushl %esi */
-        0x89, 0xe6,             /* movl %esp,%esi */
-        0x8b, 0x4c, 0x24, 0x0c, /* movl 12(%esp),%ecx - func */
-        0x8b, 0x54, 0x24, 0x10, /* movl 16(%esp),%edx - arg */
-        0x8b, 0x44, 0x24, 0x14, /* movl 20(%esp),%eax - stack */
-        0x83, 0xe0, 0xf0,       /* andl $~15,%eax */
-        0x83, 0xe8, 0x0c,       /* subl $12,%eax */
-        0x89, 0xc4,             /* movl %eax,%esp */
-        0x52,                   /* pushl %edx */
-        0x31, 0xed,             /* xorl %ebp,%ebp */
-        0xff, 0xd1,             /* call *%ecx */
-        0x89, 0xf4,             /* movl %esi,%esp */
-        0x5e,                   /* popl %esi */
-        0x5d,                   /* popl %ebp */
-        0xc2, 0x0c, 0x00 };     /* ret $12 */
-
-    DWORD (WINAPI *call_on_stack)( DWORD (WINAPI *func)(void *), void *arg, void *stack );
-    void *old_stack, *old_stack_base, *old_stack_limit;
-    void *new_stack, *new_stack_base;
-    DWORD result;
-
-    if (!pNtCurrentTeb)
-    {
-        win_skip( "NtCurrentTeb not supported\n" );
-        return;
-    }
-
-    call_on_stack = VirtualAlloc( 0, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
-    ok( call_on_stack != NULL, "VirtualAlloc failed %u\n", GetLastError() );
-    memcpy( call_on_stack, code_call_on_stack, sizeof(code_call_on_stack) );
-
-    /* allocate a new stack, only the first guard page is committed */
-    new_stack = VirtualAlloc( 0, 0x400000, MEM_RESERVE, PAGE_READWRITE );
-    ok( new_stack != NULL, "VirtualAlloc failed %u\n", GetLastError() );
-    new_stack_base = (char *)new_stack + 0x400000;
-    VirtualAlloc( (char *)new_stack_base - 0x1000, 0x1000, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD );
-
-    old_stack       = pNtCurrentTeb()->DeallocationStack;
-    old_stack_base  = pNtCurrentTeb()->Tib.StackBase;
-    old_stack_limit = pNtCurrentTeb()->Tib.StackLimit;
-
-    pNtCurrentTeb()->DeallocationStack  = new_stack;
-    pNtCurrentTeb()->Tib.StackBase      = new_stack_base;
-    pNtCurrentTeb()->Tib.StackLimit     = new_stack_base;
-
-    result = call_on_stack( stack_commit_func, (void *)0xdeadbeef, new_stack_base );
-    ok( result == 42, "expected 42, got %u\n", result );
-
-    pNtCurrentTeb()->DeallocationStack  = old_stack;
-    pNtCurrentTeb()->Tib.StackBase      = old_stack_base;
-    pNtCurrentTeb()->Tib.StackLimit     = old_stack_limit;
-
-    VirtualFree( new_stack, 0, MEM_RELEASE );
-    VirtualFree( call_on_stack, 0, MEM_RELEASE );
-}
-
 static LONG num_execute_fault_calls;
 
 static DWORD execute_fault_seh_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
@@ -3771,6 +3783,10 @@ static void test_shared_memory_ro(BOOL is_child, DWORD child_access)
 
 START_TEST(virtual)
 {
+#ifdef __x86_64__
+    static const char code_current_teb[] = {
+        0x65, 0x48, 0x8b, 0x04, 0x25, 0x30, 0x00, 0x00, 0x00, 0xc3 };
+#endif
     int argc;
     char **argv;
     argc = winetest_get_mainargs( &argv );
@@ -3826,6 +3842,12 @@ START_TEST(virtual)
     pNtAllocateVirtualMemory = (void *)GetProcAddress( hntdll, "NtAllocateVirtualMemory" );
     pNtFreeVirtualMemory = (void *)GetProcAddress( hntdll, "NtFreeVirtualMemory" );
 
+#ifdef __x86_64__
+    pNtCurrentTeb = VirtualAlloc( 0, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+    ok( pNtCurrentTeb != NULL, "VirtualAlloc failed %u\n", GetLastError() );
+    memcpy( pNtCurrentTeb, code_current_teb, sizeof(code_current_teb) );
+#endif
+
     test_shared_memory(FALSE);
     test_shared_memory_ro(FALSE, FILE_MAP_READ|FILE_MAP_WRITE);
     test_shared_memory_ro(FALSE, FILE_MAP_COPY);
@@ -3844,9 +3866,11 @@ START_TEST(virtual)
     test_IsBadWritePtr();
     test_IsBadCodePtr();
     test_write_watch();
+#if defined(__i386__) || defined(__x86_64__)
+    test_stack_commit();
+#endif
 #ifdef __i386__
     test_guard_page();
-    test_stack_commit();
     /* The following tests should be executed as a last step, and in exactly this
      * order, since ATL thunk emulation cannot be enabled anymore on Windows. */
     test_atl_thunk_emulation( MEM_EXECUTE_OPTION_ENABLE );
-- 
2.7.1



More information about the wine-patches mailing list