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.

249 lines
5.1 KiB

  1. /*++
  2. Copyright (c) 1995-2000 Microsoft Corporation
  3. Module Name:
  4. ctrltrns.c
  5. Abstract:
  6. Control Transfer Fragments.
  7. Author:
  8. 10-July-1995 t-orig (Ori Gershony)
  9. Revision History:
  10. 24-Aug-1999 [askhalid] copied from 32-bit wx86 directory and make work for 64bit.
  11. 20-Sept-1999[barrybo] added FRAG2REF(LockCmpXchg8bFrag32, ULONGLONG)
  12. --*/
  13. #include <nt.h>
  14. #include <ntrtl.h>
  15. #include <nturtl.h>
  16. #include <windows.h>
  17. #define _WX86CPUAPI_
  18. #include "wx86nt.h"
  19. #include "wx86cpu.h"
  20. #include "instr.h"
  21. #include "config.h"
  22. #include "cpuassrt.h"
  23. #include "fragp.h"
  24. #include "entrypt.h"
  25. #include "compiler.h"
  26. #include "ctrltrns.h"
  27. #include "threadst.h"
  28. #include "tc.h"
  29. #include "cpunotif.h"
  30. #include "atomic.h"
  31. ASSERTNAME;
  32. VOID
  33. FlushCallstack(
  34. PTHREADSTATE cpu
  35. )
  36. /*++
  37. Routine Description:
  38. Flush the callstack - the Translation Cache is flushing, which
  39. invalidates the callstack.
  40. Arguments:
  41. cpu - per-thread info
  42. Return Value:
  43. .
  44. --*/
  45. {
  46. //
  47. // Mark the callstack as valid.
  48. //
  49. cpu->CSTimestamp = TranslationCacheTimestamp;
  50. memset(cpu->callStack, 0, CSSIZE*sizeof(CALLSTACK));
  51. //
  52. // No need to reset cpu->CSIndex as the stack is actually implemented
  53. // within a circular buffer. It can start at any offset
  54. //
  55. }
  56. // Call
  57. ULONG
  58. CTRL_CallFrag(
  59. PTHREADSTATE cpu, // cpu state pointer
  60. ULONG inteldest,
  61. ULONG intelnext,
  62. ULONG nativenext
  63. )
  64. {
  65. PUSH_LONG(intelnext);
  66. PUSH_CALLSTACK(intelnext, nativenext);
  67. ASSERTPtrInTCOrZero((PVOID)nativenext);
  68. eip = inteldest;
  69. return inteldest;
  70. }
  71. // Call FAR
  72. ULONG
  73. CTRL_CallfFrag(
  74. PTHREADSTATE cpu, // cpu state pointer
  75. PUSHORT pinteldest,
  76. ULONG intelnext,
  77. ULONG nativenext
  78. )
  79. {
  80. USHORT sel;
  81. DWORD offset;
  82. offset = *(UNALIGNED PULONG)(pinteldest);
  83. sel = *(UNALIGNED PUSHORT)(pinteldest+2);
  84. PUSH_LONG(CS);
  85. PUSH_LONG(intelnext);
  86. PUSH_CALLSTACK(intelnext, nativenext);
  87. ASSERTPtrInTCOrZero((PVOID)nativenext);
  88. eip = offset;
  89. CS = sel;
  90. return (ULONG)(ULONGLONG)pinteldest;
  91. }
  92. // IRet
  93. ULONG CTRL_INDIR_IRetFrag(PTHREADSTATE cpu)
  94. {
  95. ULONG intelAddr, nativeAddr;
  96. DWORD CSTemp;
  97. POP_LONG(intelAddr);
  98. POP_LONG(CSTemp);
  99. PopfFrag32(cpu);
  100. eip = intelAddr;
  101. CS = (USHORT)CSTemp;
  102. POP_CALLSTACK(intelAddr,nativeAddr);
  103. ASSERTPtrInTCOrZero((PVOID)nativeAddr);
  104. return nativeAddr;
  105. }
  106. // Now the ret fragments
  107. ULONG CTRL_INDIR_RetnFrag32(PTHREADSTATE cpu)
  108. {
  109. ULONG intelAddr, nativeAddr;
  110. POP_LONG(intelAddr);
  111. eip = intelAddr;
  112. POP_CALLSTACK(intelAddr,nativeAddr);
  113. ASSERTPtrInTCOrZero((PVOID)nativeAddr);
  114. return nativeAddr;
  115. }
  116. ULONG CTRL_INDIR_RetnFrag16(PTHREADSTATE cpu)
  117. {
  118. ULONG intelAddr, nativeAddr;
  119. POP_SHORT(intelAddr);
  120. intelAddr &= 0x0000ffff;
  121. eip = intelAddr;
  122. POP_CALLSTACK(intelAddr,nativeAddr);
  123. ASSERTPtrInTCOrZero((PVOID)nativeAddr);
  124. return nativeAddr;
  125. }
  126. ULONG CTRL_INDIR_RetfFrag32(PTHREADSTATE cpu)
  127. {
  128. ULONG intelAddr, nativeAddr;
  129. ULONG CSTemp;
  130. POP_LONG(intelAddr);
  131. POP_LONG(CSTemp);
  132. eip = intelAddr;
  133. CS = (USHORT)CSTemp;
  134. POP_CALLSTACK(intelAddr,nativeAddr);
  135. ASSERTPtrInTCOrZero((PVOID)nativeAddr);
  136. return nativeAddr;
  137. }
  138. ULONG CTRL_INDIR_RetfFrag16(PTHREADSTATE cpu)
  139. {
  140. ULONG intelAddr, nativeAddr;
  141. ULONG CSTemp;
  142. POP_SHORT(intelAddr);
  143. POP_SHORT(CSTemp);
  144. intelAddr &= 0x0000ffff;
  145. eip = intelAddr;
  146. CS = (USHORT)CSTemp;
  147. POP_CALLSTACK(intelAddr,nativeAddr);
  148. ASSERTPtrInTCOrZero((PVOID)nativeAddr);
  149. return nativeAddr;
  150. }
  151. ULONG CTRL_INDIR_Retn_iFrag32(PTHREADSTATE cpu, ULONG numBytes)
  152. {
  153. ULONG intelAddr, nativeAddr;
  154. intelAddr = *(DWORD *)esp;
  155. eip = intelAddr;
  156. esp += numBytes+4;
  157. POP_CALLSTACK(intelAddr,nativeAddr);
  158. ASSERTPtrInTCOrZero((PVOID)nativeAddr);
  159. return nativeAddr;
  160. }
  161. ULONG CTRL_INDIR_Retn_iFrag16(PTHREADSTATE cpu, ULONG numBytes)
  162. {
  163. ULONG intelAddr, nativeAddr;
  164. intelAddr = *(USHORT *)esp;
  165. eip = intelAddr;
  166. esp += numBytes+2;
  167. POP_CALLSTACK(intelAddr,nativeAddr);
  168. ASSERTPtrInTCOrZero((PVOID)nativeAddr);
  169. return nativeAddr;
  170. }
  171. ULONG CTRL_INDIR_Retf_iFrag32(PTHREADSTATE cpu, ULONG numBytes)
  172. {
  173. ULONG intelAddr, nativeAddr;
  174. USHORT CSTemp;
  175. intelAddr = *(DWORD *)esp;
  176. CSTemp = *(USHORT *)(esp+sizeof(ULONG));
  177. eip = intelAddr;
  178. CS = CSTemp;
  179. esp += numBytes+sizeof(ULONG)+sizeof(ULONG);
  180. POP_CALLSTACK(intelAddr,nativeAddr);
  181. ASSERTPtrInTCOrZero((PVOID)nativeAddr);
  182. return nativeAddr;
  183. }
  184. ULONG CTRL_INDIR_Retf_iFrag16(PTHREADSTATE cpu, ULONG numBytes)
  185. {
  186. ULONG intelAddr, nativeAddr;
  187. USHORT CSTemp;
  188. intelAddr = *(USHORT *)esp;
  189. CSTemp = *(USHORT *)(esp+sizeof(USHORT));
  190. eip = intelAddr;
  191. CS = CSTemp;
  192. esp += numBytes+sizeof(USHORT)+sizeof(USHORT);
  193. POP_CALLSTACK(intelAddr,nativeAddr);
  194. ASSERTPtrInTCOrZero((PVOID)nativeAddr);
  195. return nativeAddr;
  196. }