Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

380 lines
11 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
context.c
Abstract:
This module converts an amd64 context record to an X86 context record
and vice versa.
Author:
13-Dec-2001 Samer Arafeh (samera)
Revision History:
--*/
#define _WOW64CPUAPI_
#ifdef _X86_
#include "amd6432.h"
#else
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntos.h>
#include "wow64.h"
#include "wow64cpu.h"
#include "amd64cpu.h"
#endif
#include "cpup.h"
//
// Legacy FP definitions
//
#define NUMBER_LEGACY_FP_REGISTERS 8
#define FP_LEGACY_REGISTER_SIZE 10
ASSERTNAME;
VOID
Wow64CtxFromAmd64(
IN ULONG X86ContextFlags,
IN PCONTEXT ContextAmd64,
IN OUT PCONTEXT32 ContextX86
)
/*++
Routine Description:
This function builds an x86 context from the native amd64 context.
Arguments:
X86ContextFlags - Specifies which ia32 context to copy
ContextAmd64 - Supplies an the amd64 context buffer that is the source
for the copy into the ia32 context area
ContextX86 - This is an X86 context which will receive the context
information from the amd64 context record passed in above
Return Value:
None.
--*/
{
ULONG FpReg;
//
// Validate context flags
//
if (X86ContextFlags & CONTEXT_AMD64) {
LOGPRINT((ERRORLOG, "Wow64CtxFromAmd64: Request with amd64 context flags (0x%x) FAILED\n", X86ContextFlags));
ASSERT((X86ContextFlags & CONTEXT_AMD64) == 0);
}
if ((X86ContextFlags & CONTEXT32_CONTROL) == CONTEXT32_CONTROL) {
//
// Control registers
//
ContextX86->Ebp = (ULONG) ContextAmd64->Rbp;
ContextX86->SegCs = (KGDT64_R3_CMCODE | RPL_MASK);
ContextX86->Eip = (ULONG) ContextAmd64->Rip;
ContextX86->SegSs = (KGDT64_R3_DATA | RPL_MASK);
ContextX86->Esp = (ULONG) ContextAmd64->Rsp;
ContextX86->EFlags = ContextAmd64->EFlags;
}
if ((X86ContextFlags & CONTEXT32_INTEGER) == CONTEXT32_INTEGER) {
//
// Integer state
//
ContextX86->Edi = (ULONG)ContextAmd64->Rdi;
ContextX86->Esi = (ULONG)ContextAmd64->Rsi;
ContextX86->Ebx = (ULONG)ContextAmd64->Rbx;
ContextX86->Edx = (ULONG)ContextAmd64->Rdx;
ContextX86->Ecx = (ULONG)ContextAmd64->Rcx;
ContextX86->Eax = (ULONG)ContextAmd64->Rax;
}
if ((X86ContextFlags & CONTEXT32_SEGMENTS) == CONTEXT32_SEGMENTS) {
//
// Segment registers...
//
ContextX86->SegGs = (KGDT64_R3_DATA | RPL_MASK);
ContextX86->SegEs = (KGDT64_R3_DATA | RPL_MASK);
ContextX86->SegDs = (KGDT64_R3_DATA | RPL_MASK);
ContextX86->SegFs = (KGDT64_R3_CMTEB | RPL_MASK);
}
if ((X86ContextFlags & CONTEXT32_EXTENDED_REGISTERS) == CONTEXT32_EXTENDED_REGISTERS) {
PFXSAVE_FORMAT_WX86 FxSaveArea = (PFXSAVE_FORMAT_WX86) ContextX86->ExtendedRegisters;
LOGPRINT((TRACELOG, "Wow64CtxFromAmd64: Request to convert extended fp registers\n"));
//
// Initialize the FxSave part of the context.
//
RtlZeroMemory (FxSaveArea,
sizeof (ContextX86->ExtendedRegisters));
//
// Copy over control/status registers
//
FxSaveArea->ControlWord = ContextAmd64->FltSave.ControlWord;
FxSaveArea->StatusWord = ContextAmd64->FltSave.StatusWord;
FxSaveArea->TagWord = ContextAmd64->FltSave.TagWord;
FxSaveArea->ErrorOpcode = ContextAmd64->FltSave.ErrorOpcode;
FxSaveArea->ErrorOffset = ContextAmd64->FltSave.ErrorOffset;
FxSaveArea->ErrorSelector = ContextAmd64->FltSave.ErrorSelector;
FxSaveArea->DataOffset = ContextAmd64->FltSave.DataOffset;
FxSaveArea->DataSelector = ContextAmd64->FltSave.DataSelector;
FxSaveArea->MXCsr = ContextAmd64->MxCsr;
//
// Copy over the legacy FP registers (ST0-ST7)
//
RtlCopyMemory (FxSaveArea->RegisterArea,
ContextAmd64->FltSave.FloatRegisters,
sizeof (FxSaveArea->RegisterArea));
//
// Copy over XMM0 - XMM7
//
RtlCopyMemory (FxSaveArea->Reserved3,
&ContextAmd64->Xmm0,
sizeof (FxSaveArea->Reserved3));
}
if ((X86ContextFlags & CONTEXT32_FLOATING_POINT) == CONTEXT32_FLOATING_POINT) {
LOGPRINT((TRACELOG, "Wow64CtxFromAmd64: Request to convert fp registers\n"));
//
// Floating point (legacy) ST0 - ST7
//
RtlCopyMemory (&ContextX86->FloatSave,
&ContextAmd64->FltSave,
sizeof (ContextX86->FloatSave));
}
if ((X86ContextFlags & CONTEXT32_DEBUG_REGISTERS) == CONTEXT32_DEBUG_REGISTERS) {
LOGPRINT((TRACELOG, "Wow64CtxFromAmd64: Request to convert debug registers\n"));
//
// Debug registers DR0 - DR7
//
if ((ContextAmd64->Dr7 & DR7_ACTIVE) != 0) {
ContextX86->Dr0 = (ULONG)ContextAmd64->Dr0;
ContextX86->Dr1 = (ULONG)ContextAmd64->Dr1;
ContextX86->Dr2 = (ULONG)ContextAmd64->Dr2;
ContextX86->Dr3 = (ULONG)ContextAmd64->Dr3;
ContextX86->Dr6 = (ULONG)ContextAmd64->Dr6;
ContextX86->Dr7 = (ULONG)ContextAmd64->Dr7;
} else {
ContextX86->Dr0 = 0;
ContextX86->Dr1 = 0;
ContextX86->Dr2 = 0;
ContextX86->Dr3 = 0;
ContextX86->Dr6 = 0;
ContextX86->Dr7 = 0;
}
}
ContextX86->ContextFlags = X86ContextFlags;
}
VOID
Wow64CtxToAmd64(
IN ULONG X86ContextFlags,
IN PCONTEXT32 ContextX86,
IN OUT PCONTEXT ContextAmd64
)
/*++
Routine Description:
This function builds a native Amd64 context from an x86 context record.
Arguments:
X86ContextFlags - Specifies which c86 context to copy
ContextX86 - Supplies an the X86 context buffer that is the source
for the copy into the amd64 context area
ContextAmd64 - This is an amd64 context which will receive the context
information from the x86 context record passed in above
Return Value:
None.
--*/
{
BOOLEAN CmMode = (ContextAmd64->SegCs == (KGDT64_R3_CMCODE | RPL_MASK));
//
// Validate context flags
//
if (X86ContextFlags & CONTEXT_AMD64) {
LOGPRINT((ERRORLOG, "Wow64CtxToAmd64: Request with amd64 context flags (0x%x) FAILED\n", X86ContextFlags));
ASSERT((X86ContextFlags & CONTEXT_AMD64) == 0);
}
//
// if we are running in longmode, then only set the registers that won't be changed
// by 64-bit code.
//
if (CmMode != TRUE) {
X86ContextFlags = (X86ContextFlags & ~(CONTEXT32_CONTROL | CONTEXT32_INTEGER | CONTEXT32_SEGMENTS));
X86ContextFlags = (X86ContextFlags | CONTEXT_i386);
}
if ((X86ContextFlags & CONTEXT32_CONTROL) == CONTEXT32_CONTROL) {
LOGPRINT((TRACELOG, "Wow64CtxToAmd64: Request to convert control registers\n"));
//
// Control registers
//
ContextAmd64->SegCs = (KGDT64_R3_CMCODE | RPL_MASK);
ContextAmd64->SegSs = (KGDT64_R3_DATA | RPL_MASK);
ContextAmd64->Rip = ContextX86->Eip;
ContextAmd64->Rbp = ContextX86->Ebp;
ContextAmd64->Rsp = ContextX86->Esp;
ContextAmd64->EFlags = ContextX86->EFlags;
}
if ((X86ContextFlags & CONTEXT32_INTEGER) == CONTEXT32_INTEGER) {
LOGPRINT((TRACELOG, "Wow64CtxToAmd64: Request to convert integer registers\n"));
//
// Integer registers...
//
ContextAmd64->Rdi = ContextX86->Edi;
ContextAmd64->Rsi = ContextX86->Esi;
ContextAmd64->Rbx = ContextX86->Ebx;
ContextAmd64->Rdx = ContextX86->Edx;
ContextAmd64->Rcx = ContextX86->Ecx;
ContextAmd64->Rax = ContextX86->Eax;
}
if ((X86ContextFlags & CONTEXT32_SEGMENTS) == CONTEXT32_SEGMENTS) {
LOGPRINT((TRACELOG, "Wow64CtxToAmd64: Request to convert segment registers\n"));
//
// Segment registers : are never touched, and are used from the native
// context.
//
}
if ((X86ContextFlags & CONTEXT32_EXTENDED_REGISTERS) == CONTEXT32_EXTENDED_REGISTERS) {
PFXSAVE_FORMAT_WX86 FxSaveArea = (PFXSAVE_FORMAT_WX86) ContextX86->ExtendedRegisters;
LOGPRINT((TRACELOG, "Wow64CtxToAmd64: Request to convert extended fp registers\n"));
//
// Control and status registers
//
ContextAmd64->FltSave.ControlWord = FxSaveArea->ControlWord;
ContextAmd64->FltSave.StatusWord = FxSaveArea->StatusWord;
ContextAmd64->FltSave.TagWord = FxSaveArea->TagWord;
ContextAmd64->FltSave.ErrorOpcode = FxSaveArea->ErrorOpcode;
ContextAmd64->FltSave.ErrorOffset = FxSaveArea->ErrorOffset;
ContextAmd64->FltSave.ErrorSelector = (USHORT)FxSaveArea->ErrorSelector;
ContextAmd64->FltSave.DataOffset = FxSaveArea->DataOffset;
ContextAmd64->FltSave.DataSelector = (USHORT)FxSaveArea->DataSelector;
ContextAmd64->MxCsr = FxSaveArea->MXCsr;
//
// Legacy FP registers (ST0-ST7)
//
RtlCopyMemory (ContextAmd64->FltSave.FloatRegisters,
FxSaveArea->RegisterArea,
sizeof (ContextAmd64->FltSave.FloatRegisters));
//
// Extended floating point registers (XMM0-XMM7)
//
RtlCopyMemory (&ContextAmd64->Xmm0,
FxSaveArea->Reserved3,
sizeof (FxSaveArea->Reserved3));
}
if ((X86ContextFlags & CONTEXT32_FLOATING_POINT) == CONTEXT32_FLOATING_POINT) {
LOGPRINT((TRACELOG, "Wow64CtxToAmd64: Request to convert fp registers\n"));
//
// Floating point (legacy) registers (ST0-ST7)
//
RtlCopyMemory (&ContextAmd64->FltSave,
&ContextX86->FloatSave,
sizeof (ContextAmd64->FltSave));
}
if ((X86ContextFlags & CONTEXT32_DEBUG_REGISTERS) == CONTEXT32_DEBUG_REGISTERS) {
//
// Debug registers (Dr0-Dr7)
//
ContextAmd64->Dr0 = ContextX86->Dr0;
ContextAmd64->Dr1 = ContextX86->Dr1;
ContextAmd64->Dr2 = ContextX86->Dr2;
ContextAmd64->Dr3 = ContextX86->Dr3;
ContextAmd64->Dr6 = ContextX86->Dr6;
ContextAmd64->Dr7 = ContextX86->Dr7;
}
}