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

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. context.c
  5. Abstract:
  6. This module converts an amd64 context record to an X86 context record
  7. and vice versa.
  8. Author:
  9. 13-Dec-2001 Samer Arafeh (samera)
  10. Revision History:
  11. --*/
  12. #define _WOW64CPUAPI_
  13. #ifdef _X86_
  14. #include "amd6432.h"
  15. #else
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #include <ntos.h>
  20. #include "wow64.h"
  21. #include "wow64cpu.h"
  22. #include "amd64cpu.h"
  23. #endif
  24. #include "cpup.h"
  25. //
  26. // Legacy FP definitions
  27. //
  28. #define NUMBER_LEGACY_FP_REGISTERS 8
  29. #define FP_LEGACY_REGISTER_SIZE 10
  30. ASSERTNAME;
  31. VOID
  32. Wow64CtxFromAmd64(
  33. IN ULONG X86ContextFlags,
  34. IN PCONTEXT ContextAmd64,
  35. IN OUT PCONTEXT32 ContextX86
  36. )
  37. /*++
  38. Routine Description:
  39. This function builds an x86 context from the native amd64 context.
  40. Arguments:
  41. X86ContextFlags - Specifies which ia32 context to copy
  42. ContextAmd64 - Supplies an the amd64 context buffer that is the source
  43. for the copy into the ia32 context area
  44. ContextX86 - This is an X86 context which will receive the context
  45. information from the amd64 context record passed in above
  46. Return Value:
  47. None.
  48. --*/
  49. {
  50. ULONG FpReg;
  51. //
  52. // Validate context flags
  53. //
  54. if (X86ContextFlags & CONTEXT_AMD64) {
  55. LOGPRINT((ERRORLOG, "Wow64CtxFromAmd64: Request with amd64 context flags (0x%x) FAILED\n", X86ContextFlags));
  56. ASSERT((X86ContextFlags & CONTEXT_AMD64) == 0);
  57. }
  58. if ((X86ContextFlags & CONTEXT32_CONTROL) == CONTEXT32_CONTROL) {
  59. //
  60. // Control registers
  61. //
  62. ContextX86->Ebp = (ULONG) ContextAmd64->Rbp;
  63. ContextX86->SegCs = (KGDT64_R3_CMCODE | RPL_MASK);
  64. ContextX86->Eip = (ULONG) ContextAmd64->Rip;
  65. ContextX86->SegSs = (KGDT64_R3_DATA | RPL_MASK);
  66. ContextX86->Esp = (ULONG) ContextAmd64->Rsp;
  67. ContextX86->EFlags = ContextAmd64->EFlags;
  68. }
  69. if ((X86ContextFlags & CONTEXT32_INTEGER) == CONTEXT32_INTEGER) {
  70. //
  71. // Integer state
  72. //
  73. ContextX86->Edi = (ULONG)ContextAmd64->Rdi;
  74. ContextX86->Esi = (ULONG)ContextAmd64->Rsi;
  75. ContextX86->Ebx = (ULONG)ContextAmd64->Rbx;
  76. ContextX86->Edx = (ULONG)ContextAmd64->Rdx;
  77. ContextX86->Ecx = (ULONG)ContextAmd64->Rcx;
  78. ContextX86->Eax = (ULONG)ContextAmd64->Rax;
  79. }
  80. if ((X86ContextFlags & CONTEXT32_SEGMENTS) == CONTEXT32_SEGMENTS) {
  81. //
  82. // Segment registers...
  83. //
  84. ContextX86->SegGs = (KGDT64_R3_DATA | RPL_MASK);
  85. ContextX86->SegEs = (KGDT64_R3_DATA | RPL_MASK);
  86. ContextX86->SegDs = (KGDT64_R3_DATA | RPL_MASK);
  87. ContextX86->SegFs = (KGDT64_R3_CMTEB | RPL_MASK);
  88. }
  89. if ((X86ContextFlags & CONTEXT32_EXTENDED_REGISTERS) == CONTEXT32_EXTENDED_REGISTERS) {
  90. PFXSAVE_FORMAT_WX86 FxSaveArea = (PFXSAVE_FORMAT_WX86) ContextX86->ExtendedRegisters;
  91. LOGPRINT((TRACELOG, "Wow64CtxFromAmd64: Request to convert extended fp registers\n"));
  92. //
  93. // Initialize the FxSave part of the context.
  94. //
  95. RtlZeroMemory (FxSaveArea,
  96. sizeof (ContextX86->ExtendedRegisters));
  97. //
  98. // Copy over control/status registers
  99. //
  100. FxSaveArea->ControlWord = ContextAmd64->FltSave.ControlWord;
  101. FxSaveArea->StatusWord = ContextAmd64->FltSave.StatusWord;
  102. FxSaveArea->TagWord = ContextAmd64->FltSave.TagWord;
  103. FxSaveArea->ErrorOpcode = ContextAmd64->FltSave.ErrorOpcode;
  104. FxSaveArea->ErrorOffset = ContextAmd64->FltSave.ErrorOffset;
  105. FxSaveArea->ErrorSelector = ContextAmd64->FltSave.ErrorSelector;
  106. FxSaveArea->DataOffset = ContextAmd64->FltSave.DataOffset;
  107. FxSaveArea->DataSelector = ContextAmd64->FltSave.DataSelector;
  108. FxSaveArea->MXCsr = ContextAmd64->MxCsr;
  109. //
  110. // Copy over the legacy FP registers (ST0-ST7)
  111. //
  112. RtlCopyMemory (FxSaveArea->RegisterArea,
  113. ContextAmd64->FltSave.FloatRegisters,
  114. sizeof (FxSaveArea->RegisterArea));
  115. //
  116. // Copy over XMM0 - XMM7
  117. //
  118. RtlCopyMemory (FxSaveArea->Reserved3,
  119. &ContextAmd64->Xmm0,
  120. sizeof (FxSaveArea->Reserved3));
  121. }
  122. if ((X86ContextFlags & CONTEXT32_FLOATING_POINT) == CONTEXT32_FLOATING_POINT) {
  123. LOGPRINT((TRACELOG, "Wow64CtxFromAmd64: Request to convert fp registers\n"));
  124. //
  125. // Floating point (legacy) ST0 - ST7
  126. //
  127. RtlCopyMemory (&ContextX86->FloatSave,
  128. &ContextAmd64->FltSave,
  129. sizeof (ContextX86->FloatSave));
  130. }
  131. if ((X86ContextFlags & CONTEXT32_DEBUG_REGISTERS) == CONTEXT32_DEBUG_REGISTERS) {
  132. LOGPRINT((TRACELOG, "Wow64CtxFromAmd64: Request to convert debug registers\n"));
  133. //
  134. // Debug registers DR0 - DR7
  135. //
  136. if ((ContextAmd64->Dr7 & DR7_ACTIVE) != 0) {
  137. ContextX86->Dr0 = (ULONG)ContextAmd64->Dr0;
  138. ContextX86->Dr1 = (ULONG)ContextAmd64->Dr1;
  139. ContextX86->Dr2 = (ULONG)ContextAmd64->Dr2;
  140. ContextX86->Dr3 = (ULONG)ContextAmd64->Dr3;
  141. ContextX86->Dr6 = (ULONG)ContextAmd64->Dr6;
  142. ContextX86->Dr7 = (ULONG)ContextAmd64->Dr7;
  143. } else {
  144. ContextX86->Dr0 = 0;
  145. ContextX86->Dr1 = 0;
  146. ContextX86->Dr2 = 0;
  147. ContextX86->Dr3 = 0;
  148. ContextX86->Dr6 = 0;
  149. ContextX86->Dr7 = 0;
  150. }
  151. }
  152. ContextX86->ContextFlags = X86ContextFlags;
  153. }
  154. VOID
  155. Wow64CtxToAmd64(
  156. IN ULONG X86ContextFlags,
  157. IN PCONTEXT32 ContextX86,
  158. IN OUT PCONTEXT ContextAmd64
  159. )
  160. /*++
  161. Routine Description:
  162. This function builds a native Amd64 context from an x86 context record.
  163. Arguments:
  164. X86ContextFlags - Specifies which c86 context to copy
  165. ContextX86 - Supplies an the X86 context buffer that is the source
  166. for the copy into the amd64 context area
  167. ContextAmd64 - This is an amd64 context which will receive the context
  168. information from the x86 context record passed in above
  169. Return Value:
  170. None.
  171. --*/
  172. {
  173. BOOLEAN CmMode = (ContextAmd64->SegCs == (KGDT64_R3_CMCODE | RPL_MASK));
  174. //
  175. // Validate context flags
  176. //
  177. if (X86ContextFlags & CONTEXT_AMD64) {
  178. LOGPRINT((ERRORLOG, "Wow64CtxToAmd64: Request with amd64 context flags (0x%x) FAILED\n", X86ContextFlags));
  179. ASSERT((X86ContextFlags & CONTEXT_AMD64) == 0);
  180. }
  181. //
  182. // if we are running in longmode, then only set the registers that won't be changed
  183. // by 64-bit code.
  184. //
  185. if (CmMode != TRUE) {
  186. X86ContextFlags = (X86ContextFlags & ~(CONTEXT32_CONTROL | CONTEXT32_INTEGER | CONTEXT32_SEGMENTS));
  187. X86ContextFlags = (X86ContextFlags | CONTEXT_i386);
  188. }
  189. if ((X86ContextFlags & CONTEXT32_CONTROL) == CONTEXT32_CONTROL) {
  190. LOGPRINT((TRACELOG, "Wow64CtxToAmd64: Request to convert control registers\n"));
  191. //
  192. // Control registers
  193. //
  194. ContextAmd64->SegCs = (KGDT64_R3_CMCODE | RPL_MASK);
  195. ContextAmd64->SegSs = (KGDT64_R3_DATA | RPL_MASK);
  196. ContextAmd64->Rip = ContextX86->Eip;
  197. ContextAmd64->Rbp = ContextX86->Ebp;
  198. ContextAmd64->Rsp = ContextX86->Esp;
  199. ContextAmd64->EFlags = ContextX86->EFlags;
  200. }
  201. if ((X86ContextFlags & CONTEXT32_INTEGER) == CONTEXT32_INTEGER) {
  202. LOGPRINT((TRACELOG, "Wow64CtxToAmd64: Request to convert integer registers\n"));
  203. //
  204. // Integer registers...
  205. //
  206. ContextAmd64->Rdi = ContextX86->Edi;
  207. ContextAmd64->Rsi = ContextX86->Esi;
  208. ContextAmd64->Rbx = ContextX86->Ebx;
  209. ContextAmd64->Rdx = ContextX86->Edx;
  210. ContextAmd64->Rcx = ContextX86->Ecx;
  211. ContextAmd64->Rax = ContextX86->Eax;
  212. }
  213. if ((X86ContextFlags & CONTEXT32_SEGMENTS) == CONTEXT32_SEGMENTS) {
  214. LOGPRINT((TRACELOG, "Wow64CtxToAmd64: Request to convert segment registers\n"));
  215. //
  216. // Segment registers : are never touched, and are used from the native
  217. // context.
  218. //
  219. }
  220. if ((X86ContextFlags & CONTEXT32_EXTENDED_REGISTERS) == CONTEXT32_EXTENDED_REGISTERS) {
  221. PFXSAVE_FORMAT_WX86 FxSaveArea = (PFXSAVE_FORMAT_WX86) ContextX86->ExtendedRegisters;
  222. LOGPRINT((TRACELOG, "Wow64CtxToAmd64: Request to convert extended fp registers\n"));
  223. //
  224. // Control and status registers
  225. //
  226. ContextAmd64->FltSave.ControlWord = FxSaveArea->ControlWord;
  227. ContextAmd64->FltSave.StatusWord = FxSaveArea->StatusWord;
  228. ContextAmd64->FltSave.TagWord = FxSaveArea->TagWord;
  229. ContextAmd64->FltSave.ErrorOpcode = FxSaveArea->ErrorOpcode;
  230. ContextAmd64->FltSave.ErrorOffset = FxSaveArea->ErrorOffset;
  231. ContextAmd64->FltSave.ErrorSelector = (USHORT)FxSaveArea->ErrorSelector;
  232. ContextAmd64->FltSave.DataOffset = FxSaveArea->DataOffset;
  233. ContextAmd64->FltSave.DataSelector = (USHORT)FxSaveArea->DataSelector;
  234. ContextAmd64->MxCsr = FxSaveArea->MXCsr;
  235. //
  236. // Legacy FP registers (ST0-ST7)
  237. //
  238. RtlCopyMemory (ContextAmd64->FltSave.FloatRegisters,
  239. FxSaveArea->RegisterArea,
  240. sizeof (ContextAmd64->FltSave.FloatRegisters));
  241. //
  242. // Extended floating point registers (XMM0-XMM7)
  243. //
  244. RtlCopyMemory (&ContextAmd64->Xmm0,
  245. FxSaveArea->Reserved3,
  246. sizeof (FxSaveArea->Reserved3));
  247. }
  248. if ((X86ContextFlags & CONTEXT32_FLOATING_POINT) == CONTEXT32_FLOATING_POINT) {
  249. LOGPRINT((TRACELOG, "Wow64CtxToAmd64: Request to convert fp registers\n"));
  250. //
  251. // Floating point (legacy) registers (ST0-ST7)
  252. //
  253. RtlCopyMemory (&ContextAmd64->FltSave,
  254. &ContextX86->FloatSave,
  255. sizeof (ContextAmd64->FltSave));
  256. }
  257. if ((X86ContextFlags & CONTEXT32_DEBUG_REGISTERS) == CONTEXT32_DEBUG_REGISTERS) {
  258. //
  259. // Debug registers (Dr0-Dr7)
  260. //
  261. ContextAmd64->Dr0 = ContextX86->Dr0;
  262. ContextAmd64->Dr1 = ContextX86->Dr1;
  263. ContextAmd64->Dr2 = ContextX86->Dr2;
  264. ContextAmd64->Dr3 = ContextX86->Dr3;
  265. ContextAmd64->Dr6 = ContextX86->Dr6;
  266. ContextAmd64->Dr7 = ContextX86->Dr7;
  267. }
  268. }