Source code of Windows XP (NT5)
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.

275 lines
5.8 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. trapc.c
  5. Abstract:
  6. This module implements the specific exception handlers for EM
  7. exceptions. Called by the BdGenericExceptionHandler.
  8. Author:
  9. Bernard Lint 4-Apr-96
  10. Environment:
  11. Kernel mode only.
  12. Revision History:
  13. --*/
  14. #include "bd.h"
  15. typedef struct _BREAK_INST {
  16. union {
  17. struct {
  18. ULONGLONG qp: 6;
  19. ULONGLONG imm20: 20;
  20. ULONGLONG x: 1;
  21. ULONGLONG x6: 6;
  22. ULONGLONG x3: 3;
  23. ULONGLONG i: 1;
  24. ULONGLONG Op: 4;
  25. ULONGLONG Rsv: 23;
  26. } i_field;
  27. ULONGLONG Ulong64;
  28. } u;
  29. } BREAK_INST;
  30. ULONG
  31. BdExtractImmediate (
  32. IN ULONGLONG Iip,
  33. IN ULONG SlotNumber
  34. )
  35. /*++
  36. Routine Description:
  37. Extract immediate operand from break instruction.
  38. Arguments:
  39. Iip - Bundle address of instruction
  40. SlotNumber - Slot of break instruction within bundle
  41. Return Value:
  42. Value of immediate operand.
  43. --*/
  44. {
  45. PULONGLONG BundleAddress;
  46. ULONGLONG BundleLow;
  47. ULONGLONG BundleHigh;
  48. BREAK_INST BreakInst;
  49. ULONG Imm21;
  50. BundleAddress = (PULONGLONG)Iip;
  51. BundleLow = *BundleAddress;
  52. BundleHigh = *(BundleAddress+1);
  53. //
  54. // Align instruction
  55. //
  56. switch (SlotNumber) {
  57. case 0:
  58. BreakInst.u.Ulong64 = BundleLow >> 5;
  59. break;
  60. case 1:
  61. BreakInst.u.Ulong64 = (BundleLow >> 46) | (BundleHigh << 18);
  62. break;
  63. case 2:
  64. BreakInst.u.Ulong64 = (BundleHigh >> 23);
  65. break;
  66. }
  67. //
  68. // Extract immediate value
  69. //
  70. Imm21 = (ULONG)(BreakInst.u.i_field.i<<20) | (ULONG)(BreakInst.u.i_field.imm20);
  71. return Imm21;
  72. }
  73. BOOLEAN
  74. BdOtherBreakException (
  75. IN PKTRAP_FRAME TrapFrame
  76. )
  77. /*++
  78. Routine Description:
  79. Handler for break exception other than the ones for fast and
  80. normal system calls. This includes debug break points.
  81. Arguments:
  82. TrapFrame - Pointer to the trap frame.
  83. Return Value:
  84. NT status code.
  85. --*/
  86. {
  87. PEXCEPTION_RECORD ExceptionRecord;
  88. ULONG BreakImmediate;
  89. ISR Isr;
  90. BreakImmediate = (ULONG)(TrapFrame->StIIM);
  91. //
  92. // Handle break.b case
  93. //
  94. if (BreakImmediate == 0) {
  95. Isr.ull = TrapFrame->StISR;
  96. BreakImmediate = BdExtractImmediate(TrapFrame->StIIP,
  97. (ULONG)Isr.sb.isr_ei);
  98. TrapFrame->StIIM = BreakImmediate;
  99. }
  100. //
  101. // Initialize exception record
  102. //
  103. ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
  104. ExceptionRecord->ExceptionAddress =
  105. (PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP,
  106. ((TrapFrame->StISR & ISR_EI_MASK) >> ISR_EI));
  107. ExceptionRecord->ExceptionFlags = 0;
  108. ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)NULL;
  109. ExceptionRecord->NumberParameters = 5;
  110. ExceptionRecord->ExceptionInformation[0] = 0;
  111. ExceptionRecord->ExceptionInformation[1] = 0;
  112. ExceptionRecord->ExceptionInformation[2] = 0;
  113. ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
  114. ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
  115. switch (BreakImmediate) {
  116. case KERNEL_BREAKPOINT:
  117. case USER_BREAKPOINT:
  118. case BREAKPOINT_PRINT:
  119. case BREAKPOINT_PROMPT:
  120. case BREAKPOINT_STOP:
  121. case BREAKPOINT_LOAD_SYMBOLS:
  122. case BREAKPOINT_UNLOAD_SYMBOLS:
  123. case BREAKPOINT_BREAKIN:
  124. ExceptionRecord->ExceptionCode = STATUS_BREAKPOINT;
  125. ExceptionRecord->ExceptionInformation[0] = BreakImmediate;
  126. break;
  127. case INTEGER_DIVIDE_BY_ZERO_BREAK:
  128. ExceptionRecord->ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
  129. break;
  130. case INTEGER_OVERFLOW_BREAK:
  131. ExceptionRecord->ExceptionCode = STATUS_INTEGER_OVERFLOW;
  132. break;
  133. case MISALIGNED_DATA_BREAK:
  134. ExceptionRecord->ExceptionCode = STATUS_DATATYPE_MISALIGNMENT;
  135. break;
  136. case RANGE_CHECK_BREAK:
  137. case NULL_POINTER_DEFERENCE_BREAK:
  138. case DECIMAL_OVERFLOW_BREAK:
  139. case DECIMAL_DIVIDE_BY_ZERO_BREAK:
  140. case PACKED_DECIMAL_ERROR_BREAK:
  141. case INVALID_ASCII_DIGIT_BREAK:
  142. case INVALID_DECIMAL_DIGIT_BREAK:
  143. case PARAGRAPH_STACK_OVERFLOW_BREAK:
  144. default:
  145. #if 0
  146. #if DBG
  147. InbvDisplayString ("BdOtherBreakException: Unknown break code.\n");
  148. #endif // DBG
  149. #endif
  150. ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
  151. break;
  152. }
  153. return TRUE;
  154. }
  155. BOOLEAN
  156. BdSingleStep (
  157. IN PKTRAP_FRAME TrapFrame
  158. )
  159. /*++
  160. Routine Description:
  161. Handler for single step trap. An instruction was successfully
  162. executed and the PSR.ss bit is 1.
  163. Arguments:
  164. TrapFrame - Pointer to the trap frame.
  165. Return Value:
  166. None.
  167. Notes:
  168. ISR.ei bits indicate which instruction caused the exception.
  169. ISR.code{3:0} = 1000
  170. --*/
  171. {
  172. PEXCEPTION_RECORD ExceptionRecord;
  173. ULONG IpsrRi;
  174. //
  175. // Initialize the exception record
  176. //
  177. ExceptionRecord = (PEXCEPTION_RECORD)&TrapFrame->ExceptionRecord;
  178. //
  179. // We only want the low order 2 bits so typecast to ULONG
  180. //
  181. IpsrRi = (ULONG)(TrapFrame->StIPSR >> PSR_RI) & 0x3;
  182. ExceptionRecord->ExceptionAddress =
  183. (PVOID) RtlIa64InsertIPSlotNumber(TrapFrame->StIIP, IpsrRi);
  184. ExceptionRecord->ExceptionFlags = 0;
  185. ExceptionRecord->ExceptionRecord = (PEXCEPTION_RECORD)NULL;
  186. ExceptionRecord->NumberParameters = 5;
  187. ExceptionRecord->ExceptionInformation[0] = 0;
  188. ExceptionRecord->ExceptionInformation[1] = 0; // 0 for traps
  189. ExceptionRecord->ExceptionInformation[2] = 0;
  190. ExceptionRecord->ExceptionInformation[3] = TrapFrame->StIIPA;
  191. ExceptionRecord->ExceptionInformation[4] = TrapFrame->StISR;
  192. ExceptionRecord->ExceptionCode = STATUS_SINGLE_STEP;
  193. return TRUE;
  194. }