Module: wine Branch: master Commit: 2bb668b1da1d39c0e1797f08afe3b2570c08cc48 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2bb668b1da1d39c0e1797f08af...
Author: Alexandre Julliard julliard@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@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" );