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.

170 lines
4.2 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. decoder.c
  5. Abstract:
  6. Public Decoder APIs and helper functions use in decoding instructions
  7. Author:
  8. 27-Jun-1995 BarryBo
  9. Revision History:
  10. 24-Aug-1999 [askhalid] copied from 32-bit wx86 directory and make work for 64bit.
  11. --*/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <windows.h>
  16. #include <stdio.h>
  17. #include "cpuassrt.h"
  18. #include "threadst.h"
  19. #include "instr.h"
  20. #include "decoder.h"
  21. #include "decoderp.h"
  22. ASSERTNAME;
  23. ULONG
  24. DecoderExceptionFilter(
  25. PINSTRUCTION Instruction,
  26. struct _EXCEPTION_POINTERS *ExInfo
  27. )
  28. /*++
  29. Routine Description:
  30. Handles any exception thrown while decoding an instruction. Creates
  31. an OP_Fault instruction with operand2 being the exception code and
  32. operand1 being the address where the exception occurred.
  33. Arguments:
  34. Instruction - Structure to be filled in with the decoding
  35. ExInfo - Information about the exception.
  36. Return Value:
  37. ULONG - always EXCEPTION_EXECUTE_HANDLER.
  38. --*/
  39. {
  40. Instruction->Operation = OP_Fault;
  41. Instruction->Operand1.Type = OPND_IMM;
  42. Instruction->Operand2.Immed = (ULONG)(ULONGLONG)ExInfo->ExceptionRecord->ExceptionAddress;
  43. Instruction->Operand2.Type = OPND_IMM;
  44. Instruction->Operand1.Immed = ExInfo->ExceptionRecord->ExceptionCode;
  45. Instruction->Size = 1;
  46. return EXCEPTION_EXECUTE_HANDLER;
  47. }
  48. VOID
  49. DecodeInstruction(
  50. DWORD InstructionAddress,
  51. PINSTRUCTION Instruction
  52. )
  53. /*++
  54. Routine Description:
  55. Decodes a single Intel instruction beginning at InstructionAddress, filling
  56. in the INSTRUCTION structure.
  57. Arguments:
  58. InstructionAddress - Address of first byte of the Intel Instruction
  59. Instruction - Structure to be filled in with the decoding
  60. Return Value:
  61. None - always succeeds.
  62. --*/
  63. {
  64. DECODERSTATE DecoderState;
  65. //
  66. // Initialize the Instruction structure. Instruction structures are
  67. // zero-filled by the analysis phase, so only non-zero fields need
  68. // to be filled in here.
  69. //
  70. Instruction->Size = 1;
  71. Instruction->Operand1.Reg = NO_REG;
  72. Instruction->Operand1.IndexReg = NO_REG;
  73. Instruction->Operand2.Reg = NO_REG;
  74. Instruction->Operand2.IndexReg = NO_REG;
  75. Instruction->Operand3.Reg = NO_REG;
  76. Instruction->Operand3.IndexReg = NO_REG;
  77. Instruction->IntelAddress = InstructionAddress;
  78. // Initialize the decoder state info
  79. DecoderState.InstructionAddress = InstructionAddress;
  80. DecoderState.RepPrefix = PREFIX_NONE;
  81. DecoderState.AdrPrefix = FALSE;
  82. DecoderState.OperationOverride = OP_MAX;
  83. try {
  84. // Decode the instruction, filling in the Instruction structure
  85. (Dispatch32[GET_BYTE(InstructionAddress)])(&DecoderState, Instruction);
  86. } except(DecoderExceptionFilter(Instruction, GetExceptionInformation())) {
  87. }
  88. // Handle illegal instructions
  89. if (DecoderState.OperationOverride != OP_MAX) {
  90. Instruction->Size = 1;
  91. Instruction->Operation = DecoderState.OperationOverride;
  92. Instruction->Operand1.Type = OPND_NONE;
  93. Instruction->Operand2.Type = OPND_NONE;
  94. }
  95. // If Operand2 is filled-in, then Operand1 must also be filled in.
  96. CPUASSERT(Instruction->Operand2.Type == OPND_NONE ||
  97. Instruction->Operand1.Type != OPND_NONE);
  98. }
  99. void get_segreg(PDECODERSTATE State, POPERAND op)
  100. {
  101. BYTE Reg = ((*(PBYTE)(eipTemp+1)) >> 3) & 0x07;
  102. op->Type = OPND_REGVALUE;
  103. op->Reg = REG_ES + Reg;
  104. if (Reg > 5) {
  105. BAD_INSTR;
  106. }
  107. }
  108. int scaled_index(PBYTE pmodrm, POPERAND op)
  109. {
  110. BYTE sib = *(pmodrm+1);
  111. INT IndexReg = GP_EAX + (sib >> 3) & 0x07;
  112. BYTE base = GP_EAX + sib & 0x07;
  113. op->Type = OPND_ADDRREF;
  114. op->Scale = sib >> 6;
  115. if (IndexReg != GP_ESP) {
  116. op->IndexReg = IndexReg;
  117. } // else op->IndexReg = NO_REG, which is the default value
  118. if (base == GP_EBP && ((*pmodrm) >> 6) == 0) {
  119. op->Immed = GET_LONG(pmodrm+2);
  120. return 5; // account for sib+DWORD
  121. }
  122. op->Reg = base;
  123. return 1; // account for sib
  124. }