6d42279d1ab43fcb910c4a8b49b098a79661ca44
[reactos.git] / boot / freeldr / freeldr / arch / i386 / i386bug.c
1
2 #include <freeldr.h>
3
4 #include <debug.h>
5
6 typedef struct _FRAME
7 {
8 struct _FRAME *Next;
9 void *Address;
10 } FRAME;
11
12 static const char *i386ExceptionDescriptionText[] =
13 {
14 "Exception 00: DIVIDE BY ZERO\n\n",
15 "Exception 01: DEBUG EXCEPTION\n\n",
16 "Exception 02: NON-MASKABLE INTERRUPT EXCEPTION\n\n",
17 "Exception 03: BREAKPOINT (INT 3)\n\n",
18 "Exception 04: OVERFLOW\n\n",
19 "Exception 05: BOUND EXCEPTION\n\n",
20 "Exception 06: INVALID OPCODE\n\n",
21 "Exception 07: FPU NOT AVAILABLE\n\n",
22 "Exception 08: DOUBLE FAULT\n\n",
23 "Exception 09: COPROCESSOR SEGMENT OVERRUN\n\n",
24 "Exception 0A: INVALID TSS\n\n",
25 "Exception 0B: SEGMENT NOT PRESENT\n\n",
26 "Exception 0C: STACK EXCEPTION\n\n",
27 "Exception 0D: GENERAL PROTECTION FAULT\n\n",
28 "Exception 0E: PAGE FAULT\n\n",
29 "Exception 0F: Reserved\n\n",
30 "Exception 10: COPROCESSOR ERROR\n\n",
31 "Exception 11: ALIGNMENT CHECK\n\n",
32 "Exception 12: MACHINE CHECK\n\n"
33 };
34
35 #define SCREEN_ATTR 0x1F // Bright white on blue background
36
37 #if 0
38 static void
39 i386PrintChar(char chr, ULONG x, ULONG y)
40 {
41 MachVideoPutChar(chr, SCREEN_ATTR, x, y);
42 }
43 #endif
44
45 /* Used to store the current X and Y position on the screen */
46 ULONG i386_ScreenPosX = 0;
47 ULONG i386_ScreenPosY = 0;
48
49 static void
50 i386PrintText(char *pszText)
51 {
52 char chr;
53 while (1)
54 {
55 chr = *pszText++;
56
57 if (chr == 0) break;
58 if (chr == '\n')
59 {
60 i386_ScreenPosY++;
61 i386_ScreenPosX = 0;
62 continue;
63 }
64
65 MachVideoPutChar(chr, SCREEN_ATTR, i386_ScreenPosX, i386_ScreenPosY);
66 i386_ScreenPosX++;
67 }
68 }
69
70 static void
71 PrintText(const char *format, ...)
72 {
73 va_list argptr;
74 char buffer[256];
75
76 va_start(argptr, format);
77 _vsnprintf(buffer, sizeof(buffer), format, argptr);
78 buffer[sizeof(buffer) - 1] = 0;
79 va_end(argptr);
80 i386PrintText(buffer);
81 }
82
83 static void
84 i386PrintFrames(PKTRAP_FRAME TrapFrame)
85 {
86 FRAME *Frame;
87
88 PrintText("Frames:\n");
89 #ifdef _M_IX86
90 for (Frame = (FRAME*)TrapFrame->Ebp;
91 Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
92 Frame = Frame->Next)
93 #else
94 for (Frame = (FRAME*)TrapFrame->TrapFrame;
95 Frame != 0 && (ULONG_PTR)Frame < STACKADDR;
96 Frame = Frame->Next)
97 #endif
98 {
99 PrintText("%p ", Frame->Address);
100 }
101 }
102
103 void
104 NTAPI
105 i386PrintExceptionText(ULONG TrapIndex, PKTRAP_FRAME TrapFrame, PKSPECIAL_REGISTERS Special)
106 {
107 PUCHAR InstructionPointer;
108
109 MachVideoHideShowTextCursor(FALSE);
110 MachVideoClearScreen(SCREEN_ATTR);
111 i386_ScreenPosX = 0;
112 i386_ScreenPosY = 0;
113
114 PrintText("An error occured in " VERSION "\n"
115 "Report this error to the ReactOS Development mailing list <ros-dev@reactos.org>\n\n"
116 "0x%02lx: %s\n", TrapIndex, i386ExceptionDescriptionText[TrapIndex]);
117 #ifdef _M_IX86
118 PrintText("EAX: %.8lx ESP: %.8lx CR0: %.8lx DR0: %.8lx\n",
119 TrapFrame->Eax, TrapFrame->HardwareEsp, Special->Cr0, TrapFrame->Dr0);
120 PrintText("EBX: %.8lx EBP: %.8lx CR1: ???????? DR1: %.8lx\n",
121 TrapFrame->Ebx, TrapFrame->Ebp, TrapFrame->Dr1);
122 PrintText("ECX: %.8lx ESI: %.8lx CR2: %.8lx DR2: %.8lx\n",
123 TrapFrame->Ecx, TrapFrame->Esi, Special->Cr2, TrapFrame->Dr2);
124 PrintText("EDX: %.8lx EDI: %.8lx CR3: %.8lx DR3: %.8lx\n",
125 TrapFrame->Edx, TrapFrame->Edi, Special->Cr3, TrapFrame->Dr3);
126 PrintText(" DR6: %.8lx\n",
127 TrapFrame->Dr6);
128 PrintText(" DR7: %.8lx\n\n",
129 TrapFrame->Dr7);
130 PrintText("CS: %.4lx EIP: %.8lx\n",
131 TrapFrame->SegCs, TrapFrame->Eip);
132 PrintText("DS: %.4lx ERROR CODE: %.8lx\n",
133 TrapFrame->SegDs, TrapFrame->ErrCode);
134 PrintText("ES: %.4lx EFLAGS: %.8lx\n",
135 TrapFrame->SegEs, TrapFrame->EFlags);
136 PrintText("FS: %.4lx GDTR Base: %.8lx Limit: %.4x\n",
137 TrapFrame->SegFs, Special->Gdtr.Base, Special->Gdtr.Limit);
138 PrintText("GS: %.4lx IDTR Base: %.8lx Limit: %.4x\n",
139 TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit);
140 PrintText("SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n",
141 TrapFrame->HardwareSegSs, Special->Ldtr, Special->Idtr.Limit);
142
143 i386PrintFrames(TrapFrame); // Display frames
144 InstructionPointer = (PUCHAR)TrapFrame->Eip;
145 #else
146 PrintText("RAX: %.8lx R8: %.8lx R12: %.8lx RSI: %.8lx\n",
147 TrapFrame->Rax, TrapFrame->R8, 0, TrapFrame->Rsi);
148 PrintText("RBX: %.8lx R9: %.8lx R13: %.8lx RDI: %.8lx\n",
149 TrapFrame->Rbx, TrapFrame->R9, 0, TrapFrame->Rdi);
150 PrintText("RCX: %.8lx R10: %.8lx R14: %.8lx RBP: %.8lx\n",
151 TrapFrame->Rcx, TrapFrame->R10, 0, TrapFrame->Rbp);
152 PrintText("RDX: %.8lx R11: %.8lx R15: %.8lx RSP: %.8lx\n",
153 TrapFrame->Rdx, TrapFrame->R11, 0, TrapFrame->Rsp);
154
155 PrintText("CS: %.4lx RIP: %.8lx\n",
156 TrapFrame->SegCs, TrapFrame->Rip);
157 PrintText("DS: %.4lx ERROR CODE: %.8lx\n",
158 TrapFrame->SegDs, TrapFrame->ErrorCode);
159 PrintText("ES: %.4lx EFLAGS: %.8lx\n",
160 TrapFrame->SegEs, TrapFrame->EFlags);
161 PrintText("FS: %.4lx GDTR Base: %.8lx Limit: %.4x\n",
162 TrapFrame->SegFs, Special->Gdtr.Base, Special->Gdtr.Limit);
163 PrintText("GS: %.4lx IDTR Base: %.8lx Limit: %.4x\n",
164 TrapFrame->SegGs, Special->Idtr.Base, Special->Idtr.Limit);
165 PrintText("SS: %.4lx LDTR: %.4lx TR: %.4lx\n\n",
166 TrapFrame->SegSs, Special->Ldtr, Special->Idtr.Limit);
167 InstructionPointer = (PUCHAR)TrapFrame->Rip;
168 #endif
169 PrintText("\nInstruction stream: %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x \n",
170 InstructionPointer[0], InstructionPointer[1],
171 InstructionPointer[2], InstructionPointer[3],
172 InstructionPointer[4], InstructionPointer[5],
173 InstructionPointer[6], InstructionPointer[7]);
174 }
175
176 VOID
177 FrLdrBugCheckWithMessage(
178 ULONG BugCode,
179 PCHAR File,
180 ULONG Line,
181 PSTR Format,
182 ...)
183 {
184 CHAR Buffer[1024];
185 va_list argptr;
186
187 MachVideoHideShowTextCursor(FALSE);
188 MachVideoClearScreen(SCREEN_ATTR);
189 i386_ScreenPosX = 0;
190 i386_ScreenPosY = 0;
191
192 PrintText("A problem has been detected and FreeLoader boot has been aborted.\n\n");
193
194 PrintText("%ld: %s\n\n", BugCode, BugCodeStrings[BugCode]);
195
196 if (File)
197 {
198 PrintText("Location: %s:%ld\n\n", File, Line);
199 }
200
201 va_start(argptr, Format);
202 _vsnprintf(Buffer, sizeof(Buffer), Format, argptr);
203 va_end(argptr);
204 Buffer[sizeof(Buffer) - 1] = 0;
205
206 i386PrintText(Buffer);
207
208 _disable();
209 __halt();
210 for (;;);
211 }
212
213 void
214 NTAPI
215 FrLdrBugCheckEx(
216 ULONG BugCode,
217 PCHAR File,
218 ULONG Line)
219 {
220 MachVideoHideShowTextCursor(FALSE);
221 MachVideoClearScreen(SCREEN_ATTR);
222 i386_ScreenPosX = 0;
223 i386_ScreenPosY = 0;
224
225 PrintText("A problem has been detected and FreeLoader boot has been aborted.\n\n");
226
227 PrintText("%ld: %s\n\n", BugCode, BugCodeStrings[BugCode]);
228
229 if (File)
230 {
231 PrintText("Location: %s:%ld\n\n", File, Line);
232 }
233
234 PrintText("Bug Information:\n %p\n %p\n %p\n %p\n %p\n\n",
235 BugCheckInfo[0], BugCheckInfo[1], BugCheckInfo[2], BugCheckInfo[3], BugCheckInfo[4]);
236
237 _disable();
238 __halt();
239 for (;;);
240 }
241
242 void
243 NTAPI
244 FrLdrBugCheck(ULONG BugCode)
245 {
246 FrLdrBugCheckEx(BugCode, 0, 0);
247 }