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.

264 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1992-1998 Microsoft Corporation
  3. Module Name:
  4. threadst.h
  5. Abstract:
  6. This module defines the structures and constant for describing a
  7. thread's state.
  8. Author:
  9. Dave Hastings (daveh) creation-date 20-May-1995
  10. Revision History:
  11. --*/
  12. #ifndef _THREADST_H_
  13. #define _THREADST_H_
  14. #define EIPLOGSIZE 32 // keep track of the last N instructions run
  15. #define CSSIZE 512 // Size of call stack (512*8 = 2048 bytes = 1 page)
  16. typedef union _REG32 { // definition of a 32-bit x86 register
  17. struct {
  18. BYTE i1;
  19. BYTE hb;
  20. };
  21. USHORT i2;
  22. ULONG i4;
  23. } REG32;
  24. #if defined(_ALPHA_)
  25. typedef DWORD FPTAG; // bytes are too slow on AXP
  26. #else
  27. typedef BYTE FPTAG;
  28. #endif
  29. typedef struct _FPREG { // definition of an x86 floating-point register
  30. union {
  31. double r64;
  32. DWORD rdw[2];
  33. BYTE rb[8];
  34. };
  35. FPTAG Tag;
  36. FPTAG TagSpecial;
  37. } FPREG, *PFPREG;
  38. //
  39. // CALLSTACK is an optimization for CALL/RET pairs, so that an expensive
  40. // NativeAddressFromEip() call can be avoided when determining the RISC
  41. // address of an x86 return address.
  42. //
  43. typedef struct _callStack {
  44. ULONG intelAddr;
  45. ULONG nativeAddr;
  46. } CALLSTACK, *PCALLSTACK;
  47. // Indices into CPUSTATE.Regs[]. get_reg32() depends on EAX through
  48. // EDI being contiguous and ordered the same as they are in the mod/rm and
  49. // reg instruction encodings (ie. EAX=0,ECX=1,EDX=2,EBX=3,ESP=4,EBP=5,ESI=6,
  50. // EDI=7)
  51. #define GP_EAX 0x00
  52. #define GP_ECX 0x01
  53. #define GP_EDX 0x02
  54. #define GP_EBX 0x03
  55. #define GP_ESP 0x04
  56. #define GP_EBP 0x05
  57. #define GP_ESI 0x06
  58. #define GP_EDI 0x07
  59. // Segment registers. get_segreg() depends on the order.
  60. #define REG_ES 0x08
  61. #define REG_CS 0x09
  62. #define REG_SS 0x0a
  63. #define REG_DS 0x0b
  64. #define REG_FS 0x0c
  65. #define REG_GS 0x0d
  66. // Identifiers for components of registers. get_reg16() depends on the order.
  67. #define GP_AX 0x0e
  68. #define GP_CX 0x0f
  69. #define GP_DX 0x10
  70. #define GP_BX 0x11
  71. #define GP_SP 0x12
  72. #define GP_BP 0x13
  73. #define GP_SI 0x14
  74. #define GP_DI 0x15
  75. // PlaceOperandFragments() depends on GP_AH and beyond, and that no registers
  76. // are past GP_BH.
  77. #define GP_AL 0x16
  78. #define GP_CL 0x17
  79. #define GP_DL 0x18
  80. #define GP_BL 0x19
  81. #define GP_AH 0x1a
  82. #define GP_CH 0x1b
  83. #define GP_DH 0x1c
  84. #define GP_BH 0x1d
  85. #define NO_REG 0xffffffff
  86. typedef struct _CPU_SUSPEND_MSG
  87. {
  88. // Owned by local thread
  89. HANDLE StartSuspendCallEvent;
  90. HANDLE EndSuspendCallEvent;
  91. } CPU_SUSPEND_MSG, *PCPU_SUSPEND_MSG;
  92. // all information related to a particular thread of the CPU belongs here
  93. typedef struct _ThreadState {
  94. //
  95. // General-purpose and segment registers
  96. // accessible as an array of REG32 or by Register Name
  97. // NOTE: the name orders must match the GP_XXX defines for registers
  98. //
  99. union {
  100. REG32 GpRegs[14];
  101. struct _RegisterByName {
  102. REG32 Eax;
  103. REG32 Ecx;
  104. REG32 Edx;
  105. REG32 Ebx;
  106. REG32 Esp;
  107. REG32 Ebp;
  108. REG32 Esi;
  109. REG32 Edi;
  110. REG32 Es;
  111. REG32 Cs;
  112. REG32 Ss;
  113. REG32 Ds;
  114. REG32 Fs;
  115. REG32 Gs;
  116. };
  117. };
  118. REG32 eipReg; // Pointer to start of current instruction (never
  119. // points into the middle of an instruction)
  120. DWORD flag_cf; // 0 = carry
  121. DWORD flag_pf; // 2 = parity
  122. DWORD flag_aux; // 4 = aux carry
  123. DWORD flag_zf; // 6 = zero
  124. DWORD flag_sf; // 7 = sign
  125. DWORD flag_tf; // 8 = trap
  126. DWORD flag_if; // 9 = interrupt enable
  127. DWORD flag_df; // 10 = direction (1 = clear, -1 = set)
  128. DWORD flag_of; // 11 = overflow
  129. DWORD flag_nt; // 14 = nested task
  130. DWORD flag_rf; // 16 = resume flag
  131. DWORD flag_vm; // 17 = virtual mode
  132. DWORD flag_ac; // 18 = alignment check
  133. // Floating-point registers
  134. FPREG FpStack[8];
  135. PFPREG FpST0;
  136. INT FpTop;
  137. INT FpStatusC3;
  138. INT FpStatusC2;
  139. INT FpStatusC1;
  140. INT FpStatusC0;
  141. INT FpStatusSF;
  142. INT FpStatusES; // Error Summary Status
  143. INT FpControlInfinity;
  144. INT FpControlRounding;
  145. INT FpControlPrecision;
  146. DWORD FpStatusExceptions;
  147. DWORD FpControlMask;
  148. DWORD FpEip; // EIP for the current FP instruction
  149. PVOID FpData; // Effective address for current FP instruction
  150. PVOID FpAddTable; // ptr to table of function pointers for FADD
  151. PVOID FpSubTable; // ptr to table of function pointers for FSUB
  152. PVOID FpMulTable; // ptr to table of function pointers for FMUL
  153. PVOID FpDivTable; // ptr to table of function pointers for FDIV
  154. ULONG CpuNotify;
  155. PVOID TraceAddress; // Used by debugger extensions
  156. DWORD fTCUnlocked; // FALSE means TC must be unlocked after exception
  157. // SuspendThread/ResumeThread support
  158. PCPU_SUSPEND_MSG SuspendMsg;
  159. int eipLogIndex; // Index of next entry to write into in the log
  160. DWORD eipLog[EIPLOGSIZE]; // log of last EIPLOGSIZE instructions run
  161. ULONG CSIndex; // Index into the stack (offset of current location)
  162. DWORD CSTimestamp;// Value of TranslationCacheTimestamp corresponding to the callstack cache
  163. CALLSTACK callStack[CSSIZE]; // callstack optimization
  164. int ErrnoVal; // CRT errno value
  165. DWORD flag_id; // 21 = ID (CPUID present if this can be toggled)
  166. } THREADSTATE, *PTHREADSTATE, CPUCONTEXT, *PCPUCONTEXT;
  167. // Bit offsets in cpu->FpControlMask. Same as the x86 bit positions
  168. #define FPCONTROL_IM 1 // Invalid operation
  169. #define FPCONTROL_DM 2 // Denormalized operation
  170. #define FPCONTROL_ZM 4 // Zero divide
  171. #define FPCONTROL_OM 8 // Overflow
  172. #define FPCONTROL_UM 16 // Underflow
  173. #define FPCONTROL_PM 32 // Precision
  174. // This macro allows one to access the cpu state via the local variable cpu
  175. #define DECLARE_CPU \
  176. PCPUCONTEXT cpu=(PCPUCONTEXT)Wow64TlsGetValue(WOW64_TLS_CPURESERVED);
  177. //
  178. // The following macros allow one to push and pop values from the
  179. // call stack
  180. //
  181. #define ISTOPOF_CALLSTACK(iAddr) \
  182. (cpu->callStack[(cpu->CSIndex)].intelAddr == iAddr)
  183. #define PUSH_CALLSTACK(iAddr,nAddr) \
  184. { \
  185. PCALLSTACK pCallStack; \
  186. \
  187. cpu->CSIndex = (cpu->CSIndex+1) % CSSIZE; \
  188. pCallStack = &cpu->callStack[cpu->CSIndex]; \
  189. pCallStack->intelAddr = iAddr; \
  190. pCallStack->nativeAddr = nAddr; \
  191. }
  192. #define POP_CALLSTACK(iAddr,nAddr) \
  193. { \
  194. PCALLSTACK pCallStack; \
  195. extern ULONG TranslationCacheTimestamp; \
  196. \
  197. CPUASSERTMSG( \
  198. (cpu->CSTimestamp == TranslationCacheTimestamp), \
  199. "POP_CALLSTACK: About to return and invalid value\n"\
  200. ); \
  201. \
  202. pCallStack = &cpu->callStack[cpu->CSIndex]; \
  203. if (iAddr == pCallStack->intelAddr) { \
  204. nAddr = pCallStack->nativeAddr; \
  205. } else { \
  206. nAddr = 0; \
  207. } \
  208. cpu->CSIndex = (cpu->CSIndex-1) % CSSIZE; \
  209. }
  210. PCPUCONTEXT GetCpuContext (); //has been implemented in wowproxy
  211. NTSTATUS
  212. CpupSuspendCurrentThread(
  213. VOID);
  214. #endif //_THREADST_H_