Alexandre Julliard : ntdll: Get some values from the parent stackframe in RtlCaptureContext.

Alexandre Julliard julliard at winehq.org
Mon Jul 24 15:51:20 CDT 2017


Module: wine
Branch: master
Commit: 2bb668b1da1d39c0e1797f08afe3b2570c08cc48
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2bb668b1da1d39c0e1797f08afe3b2570c08cc48

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Jul 24 10:39:42 2017 +0200

ntdll: Get some values from the parent stackframe in RtlCaptureContext.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/signal_i386.c     | 29 +++++++++++++++--------------
 dlls/ntdll/tests/exception.c | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index 9275ad9..ead1d56 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -1236,15 +1236,16 @@ __ASM_STDCALL_FUNC( RtlCaptureContext, 4,
                     "movl %ebx,0xa4(%eax)\n\t" /* context->Ebx */
                     "movl %edx,0xa8(%eax)\n\t" /* context->Edx */
                     "movl %ecx,0xac(%eax)\n\t" /* context->Ecx */
-                    "movl %ebp,0xb4(%eax)\n\t" /* context->Ebp */
-                    "movl 4(%esp),%edx\n\t"
+                    "movl 0(%ebp),%edx\n\t"
+                    "movl %edx,0xb4(%eax)\n\t" /* context->Ebp */
+                    "movl 4(%ebp),%edx\n\t"
                     "movl %edx,0xb8(%eax)\n\t" /* context->Eip */
                     "movw %cs,0xbc(%eax)\n\t"  /* context->SegCs */
                     "pushfl\n\t"
                     __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                     "popl 0xc0(%eax)\n\t"      /* context->EFlags */
                     __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
-                    "leal 8(%esp),%edx\n\t"
+                    "leal 8(%ebp),%edx\n\t"
                     "movl %edx,0xc4(%eax)\n\t" /* context->Esp */
                     "movw %ss,0xc8(%eax)\n\t"  /* context->SegSs */
                     "popl 0xb0(%eax)\n\t"      /* context->Eax */
@@ -2715,29 +2716,29 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
  *		RtlRaiseException (NTDLL.@)
  */
 __ASM_STDCALL_FUNC( RtlRaiseException, 4,
+                    "pushl %ebp\n\t"
+                    __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+                    __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+                    "movl %esp,%ebp\n\t"
+                    __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
                     "leal -0x2cc(%esp),%esp\n\t"  /* sizeof(CONTEXT) */
-                    __ASM_CFI(".cfi_adjust_cfa_offset 0x2cc\n\t")
                     "pushl %esp\n\t"              /* context */
-                    __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                     "call " __ASM_NAME("RtlCaptureContext") __ASM_STDCALL(4) "\n\t"
-                    __ASM_CFI(".cfi_adjust_cfa_offset -4\n\t")
-                    "movl 0x2cc(%esp),%eax\n\t"   /* return address */
-                    "movl 0x2d0(%esp),%ecx\n\t"   /* rec */
-                    "movl %eax,0xb8(%esp)\n\t"    /* context->Eip */
+                    "movl 4(%ebp),%eax\n\t"       /* return address */
+                    "movl 8(%ebp),%ecx\n\t"       /* rec */
                     "movl %eax,12(%ecx)\n\t"      /* rec->ExceptionAddress */
-                    "leal 0x2d4(%esp),%eax\n\t"
+                    "leal 12(%ebp),%eax\n\t"
                     "movl %eax,0xc4(%esp)\n\t"    /* context->Esp */
                     "movl %esp,%eax\n\t"
                     "pushl $1\n\t"
-                    __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                     "pushl %eax\n\t"
-                    __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                     "pushl %ecx\n\t"
-                    __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
                     "call " __ASM_NAME("NtRaiseException") __ASM_STDCALL(12) "\n\t"
-                    __ASM_CFI(".cfi_adjust_cfa_offset -12\n\t")
                     "pushl %eax\n\t"
                     "call " __ASM_NAME("RtlRaiseStatus") __ASM_STDCALL(4) "\n\t"
+                    "leave\n\t"
+                    __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+                    __ASM_CFI(".cfi_same_value %ebp\n\t")
                     "ret $4" )  /* actually never returns */
 
 
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 14e6da3..6e901e9 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -42,6 +42,7 @@ static NTSTATUS  (WINAPI *pNtGetContextThread)(HANDLE,CONTEXT*);
 static NTSTATUS  (WINAPI *pNtSetContextThread)(HANDLE,CONTEXT*);
 static NTSTATUS  (WINAPI *pRtlRaiseException)(EXCEPTION_RECORD *rec);
 static PVOID     (WINAPI *pRtlUnwind)(PVOID, PVOID, PEXCEPTION_RECORD, PVOID);
+static VOID      (WINAPI *pRtlCaptureContext)(CONTEXT*);
 static PVOID     (WINAPI *pRtlAddVectoredExceptionHandler)(ULONG first, PVECTORED_EXCEPTION_HANDLER func);
 static ULONG     (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID handler);
 static PVOID     (WINAPI *pRtlAddVectoredContinueHandler)(ULONG first, PVECTORED_EXCEPTION_HANDLER func);
@@ -1471,6 +1472,42 @@ static void test_thread_context(void)
 
     memset( &context, 0xcc, sizeof(context) );
     memset( &expect, 0xcc, sizeof(expect) );
+    func_ptr( &expect, pRtlCaptureContext, &context, 0 );
+    trace( "expect: eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x ebp=%08x esp=%08x "
+           "eip=%08x cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x flags=%08x prev=%08x\n",
+           expect.Eax, expect.Ebx, expect.Ecx, expect.Edx, expect.Esi, expect.Edi,
+           expect.Ebp, expect.Esp, expect.Eip, expect.SegCs, expect.SegDs, expect.SegEs,
+           expect.SegFs, expect.SegGs, expect.SegSs, expect.EFlags, expect.prev_frame );
+    trace( "actual: eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x ebp=%08x esp=%08x "
+           "eip=%08x cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x flags=%08x\n",
+           context.Eax, context.Ebx, context.Ecx, context.Edx, context.Esi, context.Edi,
+           context.Ebp, context.Esp, context.Eip, context.SegCs, context.SegDs, context.SegEs,
+           context.SegFs, context.SegGs, context.SegSs, context.EFlags );
+
+    ok( context.ContextFlags == (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) ||
+        broken( context.ContextFlags == 0xcccccccc ),  /* <= vista */
+        "wrong flags %08x\n", context.ContextFlags );
+    COMPARE( Eax );
+    COMPARE( Ebx );
+    COMPARE( Ecx );
+    COMPARE( Edx );
+    COMPARE( Esi );
+    COMPARE( Edi );
+    COMPARE( Eip );
+    COMPARE( SegCs );
+    COMPARE( SegDs );
+    COMPARE( SegEs );
+    COMPARE( SegFs );
+    COMPARE( SegGs );
+    COMPARE( SegSs );
+    COMPARE( EFlags );
+    /* Ebp is from the previous stackframe */
+    ok( context.Ebp == expect.prev_frame, "wrong Ebp %08x/%08x\n", context.Ebp, expect.prev_frame );
+    /* Esp is the value on entry to the previous stackframe */
+    ok( context.Esp == expect.Ebp + 8, "wrong Esp %08x/%08x\n", context.Esp, expect.Ebp + 8 );
+
+    memset( &context, 0xcc, sizeof(context) );
+    memset( &expect, 0xcc, sizeof(expect) );
     context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS;
     status = func_ptr( &expect, pNtGetContextThread, (void *)GetCurrentThread(), &context );
     ok( status == STATUS_SUCCESS, "NtGetContextThread failed %08x\n", status );
@@ -2530,6 +2567,7 @@ START_TEST(exception)
     pNtReadVirtualMemory = (void *)GetProcAddress( hntdll, "NtReadVirtualMemory" );
     pRtlUnwind           = (void *)GetProcAddress( hntdll, "RtlUnwind" );
     pRtlRaiseException   = (void *)GetProcAddress( hntdll, "RtlRaiseException" );
+    pRtlCaptureContext   = (void *)GetProcAddress( hntdll, "RtlCaptureContext" );
     pNtTerminateProcess  = (void *)GetProcAddress( hntdll, "NtTerminateProcess" );
     pRtlAddVectoredExceptionHandler    = (void *)GetProcAddress( hntdll,
                                                                  "RtlAddVectoredExceptionHandler" );




More information about the wine-cvs mailing list