wow64cpu: Implement BTCpuResetToConsistentState().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-12-01 11:23:14 +01:00
parent 39a8701dfd
commit 3af8607430
2 changed files with 76 additions and 2 deletions

View File

@ -41,6 +41,9 @@ struct thunk_32to64
static BYTE DECLSPEC_ALIGN(4096) code_buffer[0x1000]; static BYTE DECLSPEC_ALIGN(4096) code_buffer[0x1000];
static USHORT cs64_sel;
static USHORT ds64_sel;
static USHORT fs32_sel;
BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, void *reserved ) BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, void *reserved )
{ {
@ -48,6 +51,53 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, void *reserved )
return TRUE; return TRUE;
} }
/**********************************************************************
* copy_context_64to32
*
* Copy a 64-bit context corresponding to an exception happening in 32-bit mode
* into the corresponding 32-bit context.
*/
static void copy_context_64to32( I386_CONTEXT *ctx32, DWORD flags, AMD64_CONTEXT *ctx64 )
{
ctx32->ContextFlags = flags;
flags &= ~CONTEXT_i386;
if (flags & CONTEXT_I386_INTEGER)
{
ctx32->Eax = ctx64->Rax;
ctx32->Ebx = ctx64->Rbx;
ctx32->Ecx = ctx64->Rcx;
ctx32->Edx = ctx64->Rdx;
ctx32->Esi = ctx64->Rsi;
ctx32->Edi = ctx64->Rdi;
}
if (flags & CONTEXT_I386_CONTROL)
{
ctx32->Esp = ctx64->Rsp;
ctx32->Ebp = ctx64->Rbp;
ctx32->Eip = ctx64->Rip;
ctx32->EFlags = ctx64->EFlags;
ctx32->SegCs = ctx64->SegCs;
ctx32->SegSs = ds64_sel;
}
if (flags & CONTEXT_I386_SEGMENTS)
{
ctx32->SegDs = ds64_sel;
ctx32->SegEs = ds64_sel;
ctx32->SegFs = fs32_sel;
ctx32->SegGs = ds64_sel;
}
if (flags & CONTEXT_I386_DEBUG_REGISTERS)
{
ctx32->Dr0 = ctx64->Dr0;
ctx32->Dr1 = ctx64->Dr1;
ctx32->Dr2 = ctx64->Dr2;
ctx32->Dr3 = ctx64->Dr3;
ctx32->Dr6 = ctx64->Dr6;
ctx32->Dr7 = ctx64->Dr7;
}
/* FIXME: floating point + xstate */
}
/********************************************************************** /**********************************************************************
* syscall_32to64 * syscall_32to64
@ -141,9 +191,13 @@ NTSTATUS WINAPI BTCpuProcessInit(void)
} }
RtlCaptureContext( &context ); RtlCaptureContext( &context );
cs64_sel = context.SegCs;
ds64_sel = context.SegDs;
fs32_sel = context.SegFs;
thunk->ljmp = 0xea; thunk->ljmp = 0xea;
thunk->addr = PtrToUlong( syscall_32to64 ); thunk->addr = PtrToUlong( syscall_32to64 );
thunk->cs = context.SegCs; thunk->cs = cs64_sel;
NtProtectVirtualMemory( GetCurrentProcess(), (void **)&thunk, &size, PAGE_EXECUTE_READ, &old_prot ); NtProtectVirtualMemory( GetCurrentProcess(), (void **)&thunk, &size, PAGE_EXECUTE_READ, &old_prot );
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -174,3 +228,23 @@ NTSTATUS WINAPI BTCpuSetContext( HANDLE thread, HANDLE process, void *unknown, I
{ {
return NtSetInformationThread( thread, ThreadWow64Context, ctx, sizeof(*ctx) ); return NtSetInformationThread( thread, ThreadWow64Context, ctx, sizeof(*ctx) );
} }
/**********************************************************************
* BTCpuResetToConsistentState (wow64cpu.@)
*/
NTSTATUS WINAPI BTCpuResetToConsistentState( EXCEPTION_POINTERS *ptrs )
{
CONTEXT *context = ptrs->ContextRecord;
I386_CONTEXT wow_context;
copy_context_64to32( &wow_context, CONTEXT_I386_ALL, context );
wow_context.EFlags &= ~(0x100|0x40000);
BTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &wow_context );
/* fixup context to pretend that we jumped to 64-bit mode */
context->Rip = (ULONG64)syscall_32to64;
context->SegCs = cs64_sel;
context->Rsp = context->R14;
return STATUS_SUCCESS;
}

View File

@ -1,7 +1,7 @@
@ stdcall BTCpuGetBopCode() @ stdcall BTCpuGetBopCode()
@ stdcall BTCpuGetContext(long long ptr ptr) @ stdcall BTCpuGetContext(long long ptr ptr)
@ stdcall BTCpuProcessInit() @ stdcall BTCpuProcessInit()
#@ stub BTCpuResetToConsistentState @ stdcall BTCpuResetToConsistentState(ptr)
@ stdcall BTCpuSetContext(long long ptr ptr) @ stdcall BTCpuSetContext(long long ptr ptr)
@ stdcall BTCpuSimulate() @ stdcall BTCpuSimulate()
#@ stub BTCpuTurboThunkControl #@ stub BTCpuTurboThunkControl