/*++ Copyright (c) 1995-2000 Microsoft Corporation Module Name: ctrltrns.c Abstract: Control Transfer Fragments. Author: 10-July-1995 t-orig (Ori Gershony) Revision History: 24-Aug-1999 [askhalid] copied from 32-bit wx86 directory and make work for 64bit. 20-Sept-1999[barrybo] added FRAG2REF(LockCmpXchg8bFrag32, ULONGLONG) --*/ #include #include #include #include #define _WX86CPUAPI_ #include "wx86nt.h" #include "wx86cpu.h" #include "instr.h" #include "config.h" #include "cpuassrt.h" #include "fragp.h" #include "entrypt.h" #include "compiler.h" #include "ctrltrns.h" #include "threadst.h" #include "tc.h" #include "cpunotif.h" #include "atomic.h" ASSERTNAME; VOID FlushCallstack( PTHREADSTATE cpu ) /*++ Routine Description: Flush the callstack - the Translation Cache is flushing, which invalidates the callstack. Arguments: cpu - per-thread info Return Value: . --*/ { // // Mark the callstack as valid. // cpu->CSTimestamp = TranslationCacheTimestamp; memset(cpu->callStack, 0, CSSIZE*sizeof(CALLSTACK)); // // No need to reset cpu->CSIndex as the stack is actually implemented // within a circular buffer. It can start at any offset // } // Call ULONG CTRL_CallFrag( PTHREADSTATE cpu, // cpu state pointer ULONG inteldest, ULONG intelnext, ULONG nativenext ) { PUSH_LONG(intelnext); PUSH_CALLSTACK(intelnext, nativenext); ASSERTPtrInTCOrZero((PVOID)nativenext); eip = inteldest; return inteldest; } // Call FAR ULONG CTRL_CallfFrag( PTHREADSTATE cpu, // cpu state pointer PUSHORT pinteldest, ULONG intelnext, ULONG nativenext ) { USHORT sel; DWORD offset; offset = *(UNALIGNED PULONG)(pinteldest); sel = *(UNALIGNED PUSHORT)(pinteldest+2); PUSH_LONG(CS); PUSH_LONG(intelnext); PUSH_CALLSTACK(intelnext, nativenext); ASSERTPtrInTCOrZero((PVOID)nativenext); eip = offset; CS = sel; return (ULONG)(ULONGLONG)pinteldest; } // IRet ULONG CTRL_INDIR_IRetFrag(PTHREADSTATE cpu) { ULONG intelAddr, nativeAddr; DWORD CSTemp; POP_LONG(intelAddr); POP_LONG(CSTemp); PopfFrag32(cpu); eip = intelAddr; CS = (USHORT)CSTemp; POP_CALLSTACK(intelAddr,nativeAddr); ASSERTPtrInTCOrZero((PVOID)nativeAddr); return nativeAddr; } // Now the ret fragments ULONG CTRL_INDIR_RetnFrag32(PTHREADSTATE cpu) { ULONG intelAddr, nativeAddr; POP_LONG(intelAddr); eip = intelAddr; POP_CALLSTACK(intelAddr,nativeAddr); ASSERTPtrInTCOrZero((PVOID)nativeAddr); return nativeAddr; } ULONG CTRL_INDIR_RetnFrag16(PTHREADSTATE cpu) { ULONG intelAddr, nativeAddr; POP_SHORT(intelAddr); intelAddr &= 0x0000ffff; eip = intelAddr; POP_CALLSTACK(intelAddr,nativeAddr); ASSERTPtrInTCOrZero((PVOID)nativeAddr); return nativeAddr; } ULONG CTRL_INDIR_RetfFrag32(PTHREADSTATE cpu) { ULONG intelAddr, nativeAddr; ULONG CSTemp; POP_LONG(intelAddr); POP_LONG(CSTemp); eip = intelAddr; CS = (USHORT)CSTemp; POP_CALLSTACK(intelAddr,nativeAddr); ASSERTPtrInTCOrZero((PVOID)nativeAddr); return nativeAddr; } ULONG CTRL_INDIR_RetfFrag16(PTHREADSTATE cpu) { ULONG intelAddr, nativeAddr; ULONG CSTemp; POP_SHORT(intelAddr); POP_SHORT(CSTemp); intelAddr &= 0x0000ffff; eip = intelAddr; CS = (USHORT)CSTemp; POP_CALLSTACK(intelAddr,nativeAddr); ASSERTPtrInTCOrZero((PVOID)nativeAddr); return nativeAddr; } ULONG CTRL_INDIR_Retn_iFrag32(PTHREADSTATE cpu, ULONG numBytes) { ULONG intelAddr, nativeAddr; intelAddr = *(DWORD *)esp; eip = intelAddr; esp += numBytes+4; POP_CALLSTACK(intelAddr,nativeAddr); ASSERTPtrInTCOrZero((PVOID)nativeAddr); return nativeAddr; } ULONG CTRL_INDIR_Retn_iFrag16(PTHREADSTATE cpu, ULONG numBytes) { ULONG intelAddr, nativeAddr; intelAddr = *(USHORT *)esp; eip = intelAddr; esp += numBytes+2; POP_CALLSTACK(intelAddr,nativeAddr); ASSERTPtrInTCOrZero((PVOID)nativeAddr); return nativeAddr; } ULONG CTRL_INDIR_Retf_iFrag32(PTHREADSTATE cpu, ULONG numBytes) { ULONG intelAddr, nativeAddr; USHORT CSTemp; intelAddr = *(DWORD *)esp; CSTemp = *(USHORT *)(esp+sizeof(ULONG)); eip = intelAddr; CS = CSTemp; esp += numBytes+sizeof(ULONG)+sizeof(ULONG); POP_CALLSTACK(intelAddr,nativeAddr); ASSERTPtrInTCOrZero((PVOID)nativeAddr); return nativeAddr; } ULONG CTRL_INDIR_Retf_iFrag16(PTHREADSTATE cpu, ULONG numBytes) { ULONG intelAddr, nativeAddr; USHORT CSTemp; intelAddr = *(USHORT *)esp; CSTemp = *(USHORT *)(esp+sizeof(USHORT)); eip = intelAddr; CS = CSTemp; esp += numBytes+sizeof(USHORT)+sizeof(USHORT); POP_CALLSTACK(intelAddr,nativeAddr); ASSERTPtrInTCOrZero((PVOID)nativeAddr); return nativeAddr; }