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

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-07-24 10:39:42 +02:00
parent 1c49905182
commit 2bb668b1da
2 changed files with 54 additions and 15 deletions

View File

@ -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,
"leal -0x2cc(%esp),%esp\n\t" /* sizeof(CONTEXT) */
__ASM_CFI(".cfi_adjust_cfa_offset 0x2cc\n\t")
"pushl %esp\n\t" /* context */
"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) */
"pushl %esp\n\t" /* context */
"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 */

View File

@ -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);
@ -1469,6 +1470,42 @@ static void test_thread_context(void)
#define COMPARE(reg) \
ok( context.reg == expect.reg, "wrong " #reg " %08x/%08x\n", context.reg, expect.reg )
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;
@ -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" );