Sync to trunk head(r38096)
[reactos.git] / reactos / ntoskrnl / kd64 / amd64 / kd-amd64.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/kd64/i386/kdapi-i386.c
5 * PURPOSE: KD64 i386 Support
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* PRIVATE FUNCTIONS *********************************************************/
16
17 VOID
18 NTAPI
19 KdpSetContextState(IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange,
20 IN PCONTEXT Context)
21 {
22 PKPRCB Prcb = KeGetCurrentPrcb();
23
24 /* Copy i386 specific debug registers */
25 WaitStateChange->ControlReport.Dr6 = Prcb->ProcessorState.SpecialRegisters.
26 KernelDr6;
27 WaitStateChange->ControlReport.Dr7 = Prcb->ProcessorState.SpecialRegisters.
28 KernelDr7;
29
30 /* Copy i386 specific segments */
31 WaitStateChange->ControlReport.SegCs = (USHORT)Context->SegCs;
32 WaitStateChange->ControlReport.SegDs = (USHORT)Context->SegDs;
33 WaitStateChange->ControlReport.SegEs = (USHORT)Context->SegEs;
34 WaitStateChange->ControlReport.SegFs = (USHORT)Context->SegFs;
35
36 /* Copy EFlags */
37 WaitStateChange->ControlReport.EFlags = Context->EFlags;
38
39 /* Set Report Flags */
40 WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS;
41 if (WaitStateChange->ControlReport.SegCs == KGDT_64_R0_CODE)
42 {
43 WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_CS;
44 }
45 }
46
47 BOOLEAN
48 NTAPI
49 KdpTrap(IN PKTRAP_FRAME TrapFrame,
50 IN PKEXCEPTION_FRAME ExceptionFrame,
51 IN PEXCEPTION_RECORD ExceptionRecord,
52 IN PCONTEXT ContextRecord,
53 IN KPROCESSOR_MODE PreviousMode,
54 IN BOOLEAN SecondChanceException)
55 {
56 BOOLEAN Unload = FALSE;
57 ULONG64 Rip, Rax;
58 BOOLEAN Status = FALSE;
59
60 /*
61 * Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or
62 * Load/Unload symbols.
63 */
64 if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
65 (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))
66 {
67 /* Save EIP */
68 Rip = ContextRecord->Rip;
69
70 /* Check what kind of operation was requested from us */
71 switch (ExceptionRecord->ExceptionInformation[0])
72 {
73 /* DbgPrint */
74 case BREAKPOINT_PRINT:
75
76 /* Call the worker routine */
77 Rax = KdpPrint(ContextRecord->R8, // ComponentId
78 ContextRecord->R9, // ComponentMask
79 (LPSTR)ExceptionRecord->ExceptionInformation[1], // String
80 (ULONG)ExceptionRecord->ExceptionInformation[2], // Length
81 PreviousMode,
82 TrapFrame,
83 ExceptionFrame,
84 &Status);
85
86 /* Update the return value for the caller */
87 ContextRecord->Rax = Rax;
88 break;
89
90 /* DbgPrompt */
91 case BREAKPOINT_PROMPT:
92
93 /* Call the worker routine */
94 while (TRUE);
95 Rax = 0;
96 Status = TRUE;
97
98 /* Update the return value for the caller */
99 ContextRecord->Rax = Rax;
100 break;
101
102 /* DbgUnloadSymbols */
103 case BREAKPOINT_UNLOAD_SYMBOLS:
104
105 /* Drop into the load case below, with the unload parameter */
106 Unload = TRUE;
107
108 /* DbgLoadSymbols */
109 case BREAKPOINT_LOAD_SYMBOLS:
110
111 /* Call the worker routine */
112 KdpSymbol((PVOID)ExceptionRecord->ExceptionInformation[1],
113 (PVOID)ExceptionRecord->ExceptionInformation[2],
114 Unload,
115 PreviousMode,
116 ContextRecord,
117 TrapFrame,
118 ExceptionFrame);
119 Status = TRUE;
120 break;
121
122 /* DbgCommandString*/
123 case BREAKPOINT_COMMAND_STRING:
124
125 /* Call the worker routine */
126 while (TRUE);
127 Status = TRUE;
128
129 /* Anything else, do nothing */
130 default:
131
132 /* Get out */
133 break;
134 }
135
136 /*
137 * If EIP was not updated, we'll increment it ourselves so execution
138 * continues past the breakpoint.
139 */
140 if (ContextRecord->Rip == Rip) ContextRecord->Rip++;
141 }
142 else
143 {
144 /* Call the worker routine */
145 Status = KdpReport(TrapFrame,
146 ExceptionFrame,
147 ExceptionRecord,
148 ContextRecord,
149 PreviousMode,
150 SecondChanceException);
151 }
152
153 /* Return TRUE or FALSE to caller */
154 return Status;
155 }