xref: /haiku/src/system/kernel/debug/debug.cpp (revision a5bf12376daeded4049521eb17a6cc41192250d9)
1 /*
2  * Copyright 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2002-2010, Axel Dörfler, axeld@pinc-software.de.
4  * Distributed under the terms of the MIT License.
5  *
6  * Copyright 2001, Travis Geiselbrecht. All rights reserved.
7  * Distributed under the terms of the NewOS License.
8  */
9 
10 
11 /*! This file contains the debugger and debug output facilities */
12 
13 
14 #include "blue_screen.h"
15 
16 #include <algorithm>
17 
18 #include <cpu.h>
19 #include <debug.h>
20 #include <debug_heap.h>
21 #include <debug_paranoia.h>
22 #include <driver_settings.h>
23 #include <frame_buffer_console.h>
24 #include <int.h>
25 #include <kernel.h>
26 #include <ksystem_info.h>
27 #include <safemode.h>
28 #include <smp.h>
29 #include <thread.h>
30 #include <tracing.h>
31 #include <vm/vm.h>
32 #include <vm/VMTranslationMap.h>
33 
34 #include <arch/debug_console.h>
35 #include <arch/debug.h>
36 #include <util/AutoLock.h>
37 #include <util/ring_buffer.h>
38 
39 #include <syslog_daemon.h>
40 
41 #include <ctype.h>
42 #include <stdarg.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <syslog.h>
47 
48 #include "debug_builtin_commands.h"
49 #include "debug_commands.h"
50 #include "debug_output_filter.h"
51 #include "debug_variables.h"
52 
53 
54 #if __GNUC__ == 2
55 #	define va_copy(to, from)	__va_copy(to, from)
56 #endif
57 
58 
59 struct debug_memcpy_parameters {
60 	void*		to;
61 	const void*	from;
62 	size_t		size;
63 };
64 
65 struct debug_strlcpy_parameters {
66 	char*		to;
67 	const char*	from;
68 	size_t		size;
69 	size_t		result;
70 };
71 
72 
73 static const char* const kKDLPrompt = "kdebug> ";
74 static const char* const kKDLMessageCommandSeparator = "@!";
75 	// separates panic() message from command list to execute
76 
77 extern "C" int kgets(char* buffer, int length);
78 
79 void call_modules_hook(bool enter);
80 
81 static void syslog_write(const char* text, int32 length, bool notify);
82 
83 static arch_debug_registers sDebugRegisters[B_MAX_CPU_COUNT];
84 
85 static debug_page_fault_info sPageFaultInfo;
86 
87 static bool sSerialDebugEnabled = true;
88 static bool sSyslogOutputEnabled = true;
89 static bool sBlueScreenEnabled = false;
90 	// must always be false on startup
91 static bool sDebugScreenEnabled = false;
92 static bool sSerialInputEnabled = false;
93 static bool sBlueScreenOutput = true;
94 static bool sEmergencyKeysEnabled = true;
95 static spinlock sSpinlock = B_SPINLOCK_INITIALIZER;
96 static int32 sDebuggerOnCPU = -1;
97 
98 static sem_id sSyslogNotify = -1;
99 static struct syslog_message* sSyslogMessage;
100 static struct ring_buffer* sSyslogBuffer;
101 static size_t sSyslogBufferOffset = 0;
102 	// (relative) buffer offset of the yet unsent syslog messages
103 static bool sSyslogDropped = false;
104 static bool sDebugSyslog = false;
105 static size_t sSyslogDebuggerOffset = 0;
106 	// (relative) buffer offset of the kernel debugger messages of the current
107 	// KDL session
108 
109 static const char* sCurrentKernelDebuggerMessagePrefix;
110 static const char* sCurrentKernelDebuggerMessage;
111 static va_list sCurrentKernelDebuggerMessageArgs;
112 
113 #define DEFAULT_SYSLOG_BUFFER_SIZE 65536
114 #define OUTPUT_BUFFER_SIZE 1024
115 static char sOutputBuffer[OUTPUT_BUFFER_SIZE];
116 static char sInterruptOutputBuffer[OUTPUT_BUFFER_SIZE];
117 static char sLastOutputBuffer[OUTPUT_BUFFER_SIZE];
118 static DebugOutputFilter* sDebugOutputFilter = NULL;
119 DefaultDebugOutputFilter gDefaultDebugOutputFilter;
120 static mutex sOutputLock = MUTEX_INITIALIZER("debug output");
121 
122 static void flush_pending_repeats(bool notifySyslog);
123 static void check_pending_repeats(void* data, int iter);
124 
125 static int64 sMessageRepeatFirstTime = 0;
126 static int64 sMessageRepeatLastTime = 0;
127 static int32 sMessageRepeatCount = 0;
128 
129 static debugger_module_info* sDebuggerModules[8];
130 static const uint32 kMaxDebuggerModules = sizeof(sDebuggerModules)
131 	/ sizeof(sDebuggerModules[0]);
132 
133 #define LINE_BUFFER_SIZE 1024
134 #define HISTORY_SIZE 16
135 
136 static char sLineBuffer[HISTORY_SIZE][LINE_BUFFER_SIZE] = { "", };
137 static int32 sCurrentLine = 0;
138 
139 static debugger_demangle_module_info* sDemangleModule;
140 
141 static struct thread* sDebuggedThread;
142 static vint32 sInDebugger = 0;
143 static bool sPreviousDprintfState;
144 static volatile bool sHandOverKDL = false;
145 static vint32 sHandOverKDLToCPU = -1;
146 static bool sCPUTrapped[B_MAX_CPU_COUNT];
147 
148 
149 #define distance(a, b) ((a) < (b) ? (b) - (a) : (a) - (b))
150 
151 
152 // #pragma mark - DebugOutputFilter
153 
154 
155 DebugOutputFilter::DebugOutputFilter()
156 {
157 }
158 
159 
160 DebugOutputFilter::~DebugOutputFilter()
161 {
162 }
163 
164 
165 void
166 DebugOutputFilter::PrintString(const char* string)
167 {
168 }
169 
170 
171 void
172 DebugOutputFilter::Print(const char* format, va_list args)
173 {
174 }
175 
176 
177 void
178 DefaultDebugOutputFilter::PrintString(const char* string)
179 {
180 	size_t length = strlen(string);
181 
182 	if (sSerialDebugEnabled)
183 		arch_debug_serial_puts(string);
184 	if (sSyslogOutputEnabled)
185 		syslog_write(string, length, false);
186 	if (sBlueScreenEnabled || sDebugScreenEnabled)
187 		blue_screen_puts(string);
188 
189 	for (uint32 i = 0; sSerialDebugEnabled && i < kMaxDebuggerModules; i++) {
190 		if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
191 			sDebuggerModules[i]->debugger_puts(string, length);
192 	}
193 }
194 
195 
196 void
197 DefaultDebugOutputFilter::Print(const char* format, va_list args)
198 {
199 	vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE, format, args);
200 	flush_pending_repeats(false);
201 	PrintString(sInterruptOutputBuffer);
202 }
203 
204 
205 // #pragma mark -
206 
207 
208 DebugOutputFilter*
209 set_debug_output_filter(DebugOutputFilter* filter)
210 {
211 	DebugOutputFilter* oldFilter = sDebugOutputFilter;
212 	sDebugOutputFilter = filter;
213 	return oldFilter;
214 }
215 
216 
217 static void
218 kputchar(char c)
219 {
220 	if (sSerialDebugEnabled)
221 		arch_debug_serial_putchar(c);
222 	if (sBlueScreenEnabled || sDebugScreenEnabled)
223 		blue_screen_putchar(c);
224 	for (uint32 i = 0; sSerialDebugEnabled && i < kMaxDebuggerModules; i++)
225 		if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
226 			sDebuggerModules[i]->debugger_puts(&c, sizeof(c));
227 }
228 
229 
230 void
231 kputs(const char* s)
232 {
233 	if (sDebugOutputFilter != NULL)
234 		sDebugOutputFilter->PrintString(s);
235 }
236 
237 
238 void
239 kputs_unfiltered(const char* s)
240 {
241 	gDefaultDebugOutputFilter.PrintString(s);
242 }
243 
244 
245 static void
246 insert_chars_into_line(char* buffer, int32& position, int32& length,
247 	const char* chars, int32 charCount)
248 {
249 	// move the following chars to make room for the ones to insert
250 	if (position < length) {
251 		memmove(buffer + position + charCount, buffer + position,
252 			length - position);
253 	}
254 
255 	// insert chars
256 	memcpy(buffer + position, chars, charCount);
257 	int32 oldPosition = position;
258 	position += charCount;
259 	length += charCount;
260 
261 	// print the new chars (and the following ones)
262 	kprintf("%.*s", (int)(length - oldPosition),
263 		buffer + oldPosition);
264 
265 	// reposition cursor, if necessary
266 	if (position < length)
267 		kprintf("\x1b[%ldD", length - position);
268 }
269 
270 
271 static void
272 insert_char_into_line(char* buffer, int32& position, int32& length, char c)
273 {
274 	insert_chars_into_line(buffer, position, length, &c, 1);
275 }
276 
277 
278 static void
279 remove_char_from_line(char* buffer, int32& position, int32& length)
280 {
281 	if (position == length)
282 		return;
283 
284 	length--;
285 
286 	if (position < length) {
287 		// move the subsequent chars
288 		memmove(buffer + position, buffer + position + 1, length - position);
289 
290 		// print the rest of the line again, if necessary
291 		for (int32 i = position; i < length; i++)
292 			kputchar(buffer[i]);
293 	}
294 
295 	// visually clear the last char
296 	kputchar(' ');
297 
298 	// reposition the cursor
299 	kprintf("\x1b[%ldD", length - position + 1);
300 }
301 
302 
303 class LineEditingHelper {
304 public:
305 	virtual	~LineEditingHelper() {}
306 
307 	virtual	void TabCompletion(char* buffer, int32 capacity, int32& position,
308 		int32& length) = 0;
309 };
310 
311 
312 class CommandLineEditingHelper : public LineEditingHelper {
313 public:
314 	CommandLineEditingHelper()
315 	{
316 	}
317 
318 	virtual	~CommandLineEditingHelper() {}
319 
320 	virtual	void TabCompletion(char* buffer, int32 capacity, int32& position,
321 		int32& length)
322 	{
323 		// find the first space
324 		char tmpChar = buffer[position];
325 		buffer[position] = '\0';
326 		char* firstSpace = strchr(buffer, ' ');
327 		buffer[position] = tmpChar;
328 
329 		bool reprintLine = false;
330 
331 		if (firstSpace != NULL) {
332 			// a complete command -- print its help
333 
334 			// get the command
335 			tmpChar = *firstSpace;
336 			*firstSpace = '\0';
337 			bool ambiguous;
338 			debugger_command* command = find_debugger_command(buffer, true, ambiguous);
339 			*firstSpace = tmpChar;
340 
341 			if (command != NULL) {
342 				kputchar('\n');
343 				print_debugger_command_usage(command->name);
344 			} else {
345 				if (ambiguous)
346 					kprintf("\nambiguous command\n");
347 				else
348 					kprintf("\nno such command\n");
349 			}
350 
351 			reprintLine = true;
352 		} else {
353 			// a partial command -- look for completions
354 
355 			// check for possible completions
356 			int32 count = 0;
357 			int32 longestName = 0;
358 			debugger_command* command = NULL;
359 			int32 longestCommonPrefix = 0;
360 			const char* previousCommandName = NULL;
361 			while ((command = next_debugger_command(command, buffer, position))
362 					!= NULL) {
363 				count++;
364 				int32 nameLength = strlen(command->name);
365 				longestName = max_c(longestName, nameLength);
366 
367 				// updated the length of the longest common prefix of the
368 				// commands
369 				if (count == 1) {
370 					longestCommonPrefix = longestName;
371 				} else {
372 					longestCommonPrefix = min_c(longestCommonPrefix,
373 						nameLength);
374 
375 					for (int32 i = position; i < longestCommonPrefix; i++) {
376 						if (previousCommandName[i] != command->name[i]) {
377 							longestCommonPrefix = i;
378 							break;
379 						}
380 					}
381 				}
382 
383 				previousCommandName = command->name;
384 			}
385 
386 			if (count == 0) {
387 				// no possible completions
388 				kprintf("\nno completions\n");
389 				reprintLine = true;
390 			} else if (count == 1) {
391 				// exactly one completion
392 				command = next_debugger_command(NULL, buffer, position);
393 
394 				// check for sufficient space in the buffer
395 				int32 neededSpace = longestName - position + 1;
396 					// remainder of the name plus one space
397 				// also consider the terminating null char
398 				if (length + neededSpace + 1 >= capacity)
399 					return;
400 
401 				insert_chars_into_line(buffer, position, length,
402 					command->name + position, longestName - position);
403 				insert_char_into_line(buffer, position, length, ' ');
404 			} else if (longestCommonPrefix > position) {
405 				// multiple possible completions with longer common prefix
406 				// -- insert the remainder of the common prefix
407 
408 				// check for sufficient space in the buffer
409 				int32 neededSpace = longestCommonPrefix - position;
410 				// also consider the terminating null char
411 				if (length + neededSpace + 1 >= capacity)
412 					return;
413 
414 				insert_chars_into_line(buffer, position, length,
415 					previousCommandName + position, neededSpace);
416 			} else {
417 				// multiple possible completions without longer common prefix
418 				// -- print them all
419 				kprintf("\n");
420 				reprintLine = true;
421 
422 				int columns = 80 / (longestName + 2);
423 				debugger_command* command = NULL;
424 				int column = 0;
425 				while ((command = next_debugger_command(command, buffer, position))
426 						!= NULL) {
427 					// spacing
428 					if (column > 0 && column % columns == 0)
429 						kputchar('\n');
430 					column++;
431 
432 					kprintf("  %-*s", (int)longestName, command->name);
433 				}
434 				kputchar('\n');
435 			}
436 		}
437 
438 		// reprint the editing line, if necessary
439 		if (reprintLine) {
440 			kprintf("%s%.*s", kKDLPrompt, (int)length, buffer);
441 			if (position < length)
442 				kprintf("\x1b[%ldD", length - position);
443 		}
444 	}
445 };
446 
447 
448 static int
449 read_line(char* buffer, int32 maxLength,
450 	LineEditingHelper* editingHelper = NULL)
451 {
452 	int32 currentHistoryLine = sCurrentLine;
453 	int32 position = 0;
454 	int32 length = 0;
455 	bool done = false;
456 	char c = 0;
457 
458 	while (!done) {
459 		c = kgetc();
460 
461 		switch (c) {
462 			case '\n':
463 			case '\r':
464 				buffer[length++] = '\0';
465 				kputchar('\n');
466 				done = true;
467 				break;
468 			case '\t':
469 			{
470 				if (editingHelper != NULL) {
471 					editingHelper->TabCompletion(buffer, maxLength,
472 						position, length);
473 				}
474 				break;
475 			}
476 			case 8: // backspace
477 				if (position > 0) {
478 					kputs("\x1b[1D"); // move to the left one
479 					position--;
480 					remove_char_from_line(buffer, position, length);
481 				}
482 				break;
483 			case 0x1f & 'K':	// CTRL-K -- clear line after current position
484 				if (position < length) {
485 					// clear chars
486 					for (int32 i = position; i < length; i++)
487 						kputchar(' ');
488 
489 					// reposition cursor
490 					kprintf("\x1b[%ldD", length - position);
491 
492 					length = position;
493 				}
494 				break;
495 			case 0x1f & 'L':	// CTRL-L -- clear screen
496 				if (sBlueScreenOutput) {
497 					// All the following needs to be transparent for the
498 					// serial debug output. I.e. after clearing the screen
499 					// we have to get the on-screen line into the visual state
500 					// it should have.
501 
502 					// clear screen
503 					blue_screen_clear_screen();
504 
505 					// reprint line
506 					buffer[length] = '\0';
507 					blue_screen_puts(kKDLPrompt);
508 					blue_screen_puts(buffer);
509 
510 					// reposition cursor
511 					if (position < length) {
512 						for (int i = length; i > position; i--)
513 							blue_screen_puts("\x1b[1D");
514 					}
515 				}
516 				break;
517 			case 27: // escape sequence
518 				c = kgetc();
519 				if (c != '[') {
520 					// ignore broken escape sequence
521 					break;
522 				}
523 				c = kgetc();
524 				switch (c) {
525 					case 'C': // right arrow
526 						if (position < length) {
527 							kputs("\x1b[1C"); // move to the right one
528 							position++;
529 						}
530 						break;
531 					case 'D': // left arrow
532 						if (position > 0) {
533 							kputs("\x1b[1D"); // move to the left one
534 							position--;
535 						}
536 						break;
537 					case 'A': // up arrow
538 					case 'B': // down arrow
539 					{
540 						int32 historyLine = 0;
541 
542 						if (c == 'A') {
543 							// up arrow
544 							historyLine = currentHistoryLine - 1;
545 							if (historyLine < 0)
546 								historyLine = HISTORY_SIZE - 1;
547 						} else {
548 							// down arrow
549 							if (currentHistoryLine == sCurrentLine)
550 								break;
551 
552 							historyLine = currentHistoryLine + 1;
553 							if (historyLine >= HISTORY_SIZE)
554 								historyLine = 0;
555 						}
556 
557 						// clear the history again if we're in the current line again
558 						// (the buffer we get just is the current line buffer)
559 						if (historyLine == sCurrentLine) {
560 							sLineBuffer[historyLine][0] = '\0';
561 						} else if (sLineBuffer[historyLine][0] == '\0') {
562 							// empty history lines are unused -- so bail out
563 							break;
564 						}
565 
566 						// swap the current line with something from the history
567 						if (position > 0)
568 							kprintf("\x1b[%ldD", position); // move to beginning of line
569 
570 						strcpy(buffer, sLineBuffer[historyLine]);
571 						length = position = strlen(buffer);
572 						kprintf("%s\x1b[K", buffer); // print the line and clear the rest
573 						currentHistoryLine = historyLine;
574 						break;
575 					}
576 					case '5':	// if "5~", it's PAGE UP
577 					case '6':	// if "6~", it's PAGE DOWN
578 					{
579 						if (kgetc() != '~')
580 							break;
581 
582 						// PAGE UP: search backward, PAGE DOWN: forward
583 						int32 searchDirection = (c == '5' ? -1 : 1);
584 
585 						bool found = false;
586 						int32 historyLine = currentHistoryLine;
587 						do {
588 							historyLine = (historyLine + searchDirection
589 								+ HISTORY_SIZE) % HISTORY_SIZE;
590 							if (historyLine == sCurrentLine)
591 								break;
592 
593 							if (strncmp(sLineBuffer[historyLine], buffer,
594 									position) == 0) {
595 								found = true;
596 							}
597 						} while (!found);
598 
599 						// bail out, if we've found nothing or hit an empty
600 						// (i.e. unused) history line
601 						if (!found || strlen(sLineBuffer[historyLine]) == 0)
602 							break;
603 
604 						// found a suitable line -- replace the current buffer
605 						// content with it
606 						strcpy(buffer, sLineBuffer[historyLine]);
607 						length = strlen(buffer);
608 						kprintf("%s\x1b[K", buffer + position);
609 							// print the line and clear the rest
610 						kprintf("\x1b[%ldD", length - position);
611 							// reposition cursor
612 						currentHistoryLine = historyLine;
613 
614 						break;
615 					}
616 					case 'H': // home
617 					{
618 						if (position > 0) {
619 							kprintf("\x1b[%ldD", position);
620 							position = 0;
621 						}
622 						break;
623 					}
624 					case 'F': // end
625 					{
626 						if (position < length) {
627 							kprintf("\x1b[%ldC", length - position);
628 							position = length;
629 						}
630 						break;
631 					}
632 					case '3':	// if "3~", it's DEL
633 					{
634 						if (kgetc() != '~')
635 							break;
636 
637 						if (position < length)
638 							remove_char_from_line(buffer, position, length);
639 
640 						break;
641 					}
642 					default:
643 						break;
644 				}
645 				break;
646 			case '$':
647 			case '+':
648 				if (!sBlueScreenOutput) {
649 					/* HACK ALERT!!!
650 					 *
651 					 * If we get a $ at the beginning of the line
652 					 * we assume we are talking with GDB
653 					 */
654 					if (position == 0) {
655 						strcpy(buffer, "gdb");
656 						position = 4;
657 						done = true;
658 						break;
659 					}
660 				}
661 				/* supposed to fall through */
662 			default:
663 				if (isprint(c))
664 					insert_char_into_line(buffer, position, length, c);
665 				break;
666 		}
667 
668 		if (length >= maxLength - 2) {
669 			buffer[length++] = '\0';
670 			kputchar('\n');
671 			done = true;
672 			break;
673 		}
674 	}
675 
676 	return length;
677 }
678 
679 
680 char
681 kgetc(void)
682 {
683 	if (sSerialInputEnabled)
684 		return arch_debug_serial_getchar();
685 
686 	// give the kernel debugger modules a chance first
687 	for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
688 		if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_getchar) {
689 			int getChar = sDebuggerModules[i]->debugger_getchar();
690 			if (getChar >= 0)
691 				return (char)getChar;
692 		}
693 	}
694 
695 	if (sBlueScreenOutput)
696 		return blue_screen_getchar();
697 
698 	return arch_debug_serial_getchar();
699 }
700 
701 
702 int
703 kgets(char* buffer, int length)
704 {
705 	return read_line(buffer, length);
706 }
707 
708 
709 static void
710 print_kernel_debugger_message()
711 {
712 	if (sCurrentKernelDebuggerMessagePrefix != NULL
713 			|| sCurrentKernelDebuggerMessage != NULL) {
714 		if (sCurrentKernelDebuggerMessagePrefix != NULL)
715 			kprintf("%s", sCurrentKernelDebuggerMessagePrefix);
716 		if (sCurrentKernelDebuggerMessage != NULL
717 				&& sDebugOutputFilter != NULL) {
718 			va_list args;
719 			va_copy(args, sCurrentKernelDebuggerMessageArgs);
720 
721 			if (const char* commandDelimiter = strstr(
722 					sCurrentKernelDebuggerMessage,
723 					kKDLMessageCommandSeparator)) {
724 				// The message string contains a list of commands to be
725 				// executed when entering the kernel debugger. We don't
726 				// want to print those, so we copy the interesting part of
727 				// the format string.
728 				if (commandDelimiter != sCurrentKernelDebuggerMessage) {
729 					size_t length = commandDelimiter
730 						- sCurrentKernelDebuggerMessage;
731 					if (char* format = (char*)debug_malloc(length + 1)) {
732 						memcpy(format, sCurrentKernelDebuggerMessage, length);
733 						format[length] = '\0';
734 						sDebugOutputFilter->Print(format, args);
735 						debug_free(format);
736 					} else {
737 						// allocation failed -- just print everything
738 						sDebugOutputFilter->Print(sCurrentKernelDebuggerMessage,
739 							args);
740 					}
741 				}
742 			} else
743 				sDebugOutputFilter->Print(sCurrentKernelDebuggerMessage, args);
744 
745 			va_end(args);
746 		}
747 
748 		kprintf("\n");
749 	}
750 }
751 
752 
753 static void
754 execute_panic_commands()
755 {
756 	if (sCurrentKernelDebuggerMessage == NULL
757 		|| strstr(sCurrentKernelDebuggerMessage,
758 				kKDLMessageCommandSeparator) == NULL) {
759 		return;
760 	}
761 
762 	// Indeed there are commands to execute.
763 	const size_t kCommandBufferSize = 512;
764 	char* commandBuffer = (char*)debug_malloc(kCommandBufferSize);
765 	if (commandBuffer != NULL) {
766 		va_list tempArgs;
767 		va_copy(tempArgs, sCurrentKernelDebuggerMessageArgs);
768 
769 		if (vsnprintf(commandBuffer, kCommandBufferSize,
770 				sCurrentKernelDebuggerMessage, tempArgs)
771 					< (int)kCommandBufferSize) {
772 			const char* commands = strstr(commandBuffer,
773 				kKDLMessageCommandSeparator);
774 			if (commands != NULL) {
775 				commands += strlen(kKDLMessageCommandSeparator);
776 				kprintf("initial commands: %s\n", commands);
777 				evaluate_debug_command(commands);
778 			}
779 		}
780 
781 		va_end(tempArgs);
782 
783 		debug_free(commandBuffer);
784 	}
785 }
786 
787 
788 static void
789 stack_trace_trampoline(void*)
790 {
791 	arch_debug_stack_trace();
792 }
793 
794 
795 static void
796 kernel_debugger_loop(const char* messagePrefix, const char* message,
797 	va_list args, int32 cpu)
798 {
799 	int32 previousCPU = sDebuggerOnCPU;
800 	sDebuggerOnCPU = cpu;
801 
802 	DebugAllocPool* allocPool = create_debug_alloc_pool();
803 
804 	sCurrentKernelDebuggerMessagePrefix = messagePrefix;
805 	sCurrentKernelDebuggerMessage = message;
806 	if (sCurrentKernelDebuggerMessage != NULL)
807 		va_copy(sCurrentKernelDebuggerMessageArgs, args);
808 
809 	sSyslogDebuggerOffset = sSyslogBuffer != NULL
810 		? ring_buffer_readable(sSyslogBuffer) : 0;
811 
812 	print_kernel_debugger_message();
813 
814 	kprintf("Welcome to Kernel Debugging Land...\n");
815 
816 	// Set a few temporary debug variables and print on which CPU and in which
817 	// thread we are running.
818 	set_debug_variable("_cpu", sDebuggerOnCPU);
819 
820 	struct thread* thread = thread_get_current_thread();
821 	if (thread == NULL) {
822 		kprintf("Running on CPU %ld\n", sDebuggerOnCPU);
823 	} else if (!debug_is_kernel_memory_accessible((addr_t)thread,
824 			sizeof(struct thread), B_KERNEL_READ_AREA)) {
825 		kprintf("Running on CPU %ld\n", sDebuggerOnCPU);
826 		kprintf("Current thread pointer is %p, which is an address we "
827 			"can't read from.\n", thread);
828 		arch_debug_unset_current_thread();
829 	} else {
830 		set_debug_variable("_thread", (uint64)(addr_t)thread);
831 		set_debug_variable("_threadID", thread->id);
832 
833 		kprintf("Thread %ld \"%.64s\" running on CPU %ld\n", thread->id,
834 			thread->name, sDebuggerOnCPU);
835 
836 		if (thread->cpu != gCPU + cpu) {
837 			kprintf("The thread's CPU pointer is %p, but should be %p.\n",
838 				thread->cpu, gCPU + cpu);
839 			arch_debug_unset_current_thread();
840 		} else if (thread->team != NULL) {
841 			if (debug_is_kernel_memory_accessible((addr_t)thread->team,
842 					sizeof(struct team), B_KERNEL_READ_AREA)) {
843 				set_debug_variable("_team", (uint64)(addr_t)thread->team);
844 				set_debug_variable("_teamID", thread->team->id);
845 			} else {
846 				kprintf("The thread's team pointer is %p, which is an "
847 					"address we can't read from.\n", thread->team);
848 				arch_debug_unset_current_thread();
849 			}
850 		}
851 	}
852 
853 	if (!has_debugger_command("help") || message != NULL) {
854 		// No commands yet or we came here via a panic(). Always print a stack
855 		// trace in these cases.
856 		jmp_buf* jumpBuffer = (jmp_buf*)debug_malloc(sizeof(jmp_buf));
857 		if (jumpBuffer != NULL) {
858 			debug_call_with_fault_handler(*jumpBuffer, &stack_trace_trampoline,
859 				NULL);
860 			debug_free(jumpBuffer);
861 		} else
862 			arch_debug_stack_trace();
863 	}
864 
865 	if (has_debugger_command("help")) {
866 		// Commands are registered already -- execute panic() commands. Do that
867 		// with paging disabled, so everything is printed, even if the user
868 		// can't use the keyboard.
869 		bool pagingEnabled = blue_screen_paging_enabled();
870 		blue_screen_set_paging(false);
871 
872 		execute_panic_commands();
873 
874 		blue_screen_set_paging(pagingEnabled);
875 	}
876 
877 	int32 continuableLine = -1;
878 		// Index of the previous command line, if the command returned
879 		// B_KDEBUG_CONT, i.e. asked to be repeatable, -1 otherwise.
880 
881 	for (;;) {
882 		CommandLineEditingHelper editingHelper;
883 		kprintf(kKDLPrompt);
884 		char* line = sLineBuffer[sCurrentLine];
885 		read_line(line, LINE_BUFFER_SIZE, &editingHelper);
886 
887 		// check, if the line is empty or whitespace only
888 		bool whiteSpaceOnly = true;
889 		for (int i = 0 ; line[i] != '\0'; i++) {
890 			if (!isspace(line[i])) {
891 				whiteSpaceOnly = false;
892 				break;
893 			}
894 		}
895 
896 		if (whiteSpaceOnly) {
897 			if (continuableLine < 0)
898 				continue;
899 
900 			// the previous command can be repeated
901 			sCurrentLine = continuableLine;
902 			line = sLineBuffer[sCurrentLine];
903 		}
904 
905 		int rc = evaluate_debug_command(line);
906 
907 		if (rc == B_KDEBUG_QUIT) {
908 			// okay, exit now.
909 			break;
910 		}
911 
912 		// If the command is continuable, remember the current line index.
913 		continuableLine = (rc == B_KDEBUG_CONT ? sCurrentLine : -1);
914 
915 		int previousLine = sCurrentLine - 1;
916 		if (previousLine < 0)
917 			previousLine = HISTORY_SIZE - 1;
918 
919 		// Only use the next slot in the history, if the entries differ
920 		if (strcmp(sLineBuffer[sCurrentLine], sLineBuffer[previousLine])) {
921 			if (++sCurrentLine >= HISTORY_SIZE)
922 				sCurrentLine = 0;
923 		}
924 	}
925 
926 	if (sCurrentKernelDebuggerMessage != NULL)
927 		va_end(sCurrentKernelDebuggerMessageArgs);
928 
929 	delete_debug_alloc_pool(allocPool);
930 
931 	sDebuggerOnCPU = previousCPU;
932 }
933 
934 
935 static void
936 enter_kernel_debugger(int32 cpu)
937 {
938 	while (atomic_add(&sInDebugger, 1) > 0) {
939 		// The debugger is already running, find out where...
940 		if (sDebuggerOnCPU == cpu) {
941 			// We are re-entering the debugger on the same CPU.
942 			break;
943 		}
944 
945 		// Some other CPU must have entered the debugger and tried to halt
946 		// us. Process ICIs to ensure we get the halt request. Then we are
947 		// blocking there until everyone leaves the debugger and we can
948 		// try to enter it again.
949 		atomic_add(&sInDebugger, -1);
950 		smp_intercpu_int_handler(cpu);
951 	}
952 
953 	arch_debug_save_registers(&sDebugRegisters[cpu]);
954 	sPreviousDprintfState = set_dprintf_enabled(true);
955 
956 	if (!gKernelStartup && sDebuggerOnCPU != cpu && smp_get_num_cpus() > 1) {
957 		// First entry on a MP system, send a halt request to all of the other
958 		// CPUs. Should they try to enter the debugger they will be cought in
959 		// the loop above.
960 		smp_send_broadcast_ici_interrupts_disabled(cpu, SMP_MSG_CPU_HALT, 0, 0,
961 			0, NULL, SMP_MSG_FLAG_SYNC);
962 	}
963 
964 	if (sBlueScreenOutput) {
965 		if (blue_screen_enter(false) == B_OK)
966 			sBlueScreenEnabled = true;
967 	}
968 
969 	sDebugOutputFilter = &gDefaultDebugOutputFilter;
970 
971 	sDebuggedThread = NULL;
972 
973 	// sort the commands
974 	sort_debugger_commands();
975 
976 	call_modules_hook(true);
977 }
978 
979 
980 static void
981 exit_kernel_debugger()
982 {
983 	call_modules_hook(false);
984 	set_dprintf_enabled(sPreviousDprintfState);
985 
986 	sDebugOutputFilter = NULL;
987 
988 	sBlueScreenEnabled = false;
989 	if (sDebugScreenEnabled)
990 		blue_screen_enter(true);
991 
992 	atomic_add(&sInDebugger, -1);
993 }
994 
995 
996 static void
997 hand_over_kernel_debugger()
998 {
999 	// Wait until the hand-over is complete.
1000 	// The other CPU gets our sInDebugger reference and will release it when
1001 	// done. Note, that there's a small race condition: the other CPU could
1002 	// hand over to another CPU without us noticing. Since this is only
1003 	// initiated by the user, it is harmless, though.
1004 	sHandOverKDL = true;
1005 	while (sHandOverKDLToCPU >= 0)
1006 		PAUSE();
1007 }
1008 
1009 
1010 static void
1011 kernel_debugger_internal(const char* messagePrefix, const char* message,
1012 	va_list args, int32 cpu)
1013 {
1014 	while (true) {
1015 		if (sHandOverKDLToCPU == cpu) {
1016 			sHandOverKDLToCPU = -1;
1017 			sHandOverKDL = false;
1018 		} else
1019 			enter_kernel_debugger(cpu);
1020 
1021 		kernel_debugger_loop(messagePrefix, message, args, cpu);
1022 
1023 		if (sHandOverKDLToCPU < 0) {
1024 			exit_kernel_debugger();
1025 			break;
1026 		}
1027 
1028 		hand_over_kernel_debugger();
1029 
1030 		debug_trap_cpu_in_kdl(cpu, true);
1031 
1032 		if (sHandOverKDLToCPU != cpu)
1033 			break;
1034 	}
1035 }
1036 
1037 
1038 static int
1039 cmd_dump_kdl_message(int argc, char** argv)
1040 {
1041 	print_kernel_debugger_message();
1042 	return 0;
1043 }
1044 
1045 
1046 static int
1047 cmd_execute_panic_commands(int argc, char** argv)
1048 {
1049 	execute_panic_commands();
1050 	return 0;
1051 }
1052 
1053 
1054 static int
1055 cmd_dump_syslog(int argc, char** argv)
1056 {
1057 	if (!sSyslogOutputEnabled) {
1058 		kprintf("Syslog is not enabled.\n");
1059 		return 0;
1060 	}
1061 
1062 	bool unsentOnly = false;
1063 	bool ignoreKDLOutput = true;
1064 
1065 	int argi = 1;
1066 	for (; argi < argc; argi++) {
1067 		if (strcmp(argv[argi], "-n") == 0)
1068 			unsentOnly = true;
1069 		else if (strcmp(argv[argi], "-k") == 0)
1070 			ignoreKDLOutput = false;
1071 		else
1072 			break;
1073 	}
1074 
1075 	if (argi < argc) {
1076 		print_debugger_command_usage(argv[0]);
1077 		return 0;
1078 	}
1079 
1080 	size_t debuggerOffset = sSyslogDebuggerOffset;
1081 	size_t start = unsentOnly ? sSyslogBufferOffset : 0;
1082 	size_t end = ignoreKDLOutput
1083 		? debuggerOffset : ring_buffer_readable(sSyslogBuffer);
1084 
1085 	// allocate a buffer for processing the syslog output
1086 	size_t bufferSize = 1024;
1087 	char* buffer = (char*)debug_malloc(bufferSize);
1088 	char stackBuffer[64];
1089 	if (buffer == NULL) {
1090 		buffer = stackBuffer;
1091 		bufferSize = sizeof(stackBuffer);
1092 	}
1093 
1094 	// filter the output
1095 	bool newLine = false;
1096 	while (start < end) {
1097 		size_t bytesRead = ring_buffer_peek(sSyslogBuffer, start, buffer,
1098 			std::min(end - start, bufferSize - 1));
1099 		if (bytesRead == 0)
1100 			break;
1101 		start += bytesRead;
1102 
1103 		// remove '\0' and 0xcc
1104 		size_t toPrint = 0;
1105 		for (size_t i = 0; i < bytesRead; i++) {
1106 			if (buffer[i] != '\0' && (uint8)buffer[i] != 0xcc)
1107 				buffer[toPrint++] = buffer[i];
1108 		}
1109 
1110 		if (toPrint > 0) {
1111 			newLine = buffer[toPrint - 1] == '\n';
1112 			buffer[toPrint] = '\0';
1113 			kputs(buffer);
1114 		}
1115 
1116 		if (debuggerOffset > sSyslogDebuggerOffset) {
1117 			// Our output caused older syslog output to be evicted from the
1118 			// syslog buffer. We need to adjust our offsets accordingly. Note,
1119 			// this can still go wrong, if the buffer was already full and more
1120 			// was written to it than we have processed, but we can't help that.
1121 			size_t diff = debuggerOffset - sSyslogDebuggerOffset;
1122 			start -= std::min(start, diff);
1123 			end -= std::min(end, diff);
1124 			debuggerOffset = sSyslogDebuggerOffset;
1125 		}
1126 	}
1127 
1128 	if (!newLine)
1129 		kputs("\n");
1130 
1131 	if (buffer != stackBuffer)
1132 		debug_free(buffer);
1133 
1134 	return 0;
1135 }
1136 
1137 
1138 static int
1139 cmd_serial_input(int argc, char** argv)
1140 {
1141 	sSerialInputEnabled = !sSerialInputEnabled;
1142 	kprintf("Serial input is turned %s now.\n",
1143 		sSerialInputEnabled ? "on" : "off");
1144 	return 0;
1145 }
1146 
1147 
1148 static int
1149 cmd_switch_cpu(int argc, char** argv)
1150 {
1151 	if (argc > 2) {
1152 		print_debugger_command_usage(argv[0]);
1153 		return 0;
1154 	}
1155 
1156 	if (argc == 1) {
1157 		kprintf("running on CPU %ld\n", smp_get_current_cpu());
1158 		return 0;
1159 	}
1160 
1161 	int32 newCPU = parse_expression(argv[1]);
1162 	if (newCPU < 0 || newCPU >= smp_get_num_cpus()) {
1163 		kprintf("invalid CPU index\n");
1164 		return 0;
1165 	}
1166 
1167 	if (newCPU == smp_get_current_cpu()) {
1168 		kprintf("already running on CPU %ld\n", newCPU);
1169 		return 0;
1170 	}
1171 
1172 	sHandOverKDLToCPU = newCPU;
1173 
1174 	return B_KDEBUG_QUIT;
1175 }
1176 
1177 
1178 static status_t
1179 syslog_sender(void* data)
1180 {
1181 	status_t error = B_BAD_PORT_ID;
1182 	port_id port = -1;
1183 	bool bufferPending = false;
1184 	int32 length = 0;
1185 
1186 	while (true) {
1187 		// wait for syslog data to become available
1188 		acquire_sem_etc(sSyslogNotify, 1, B_RELATIVE_TIMEOUT, 5000000);
1189 			// Note: We time out since in some situations output is added to
1190 			// the syslog buffer without being allowed to notify us (e.g. in
1191 			// the kernel debugger).
1192 
1193 		sSyslogMessage->when = real_time_clock();
1194 
1195 		if (error == B_BAD_PORT_ID) {
1196 			// last message couldn't be sent, try to locate the syslog_daemon
1197 			port = find_port(SYSLOG_PORT_NAME);
1198 		}
1199 
1200 		if (port >= B_OK) {
1201 			if (!bufferPending) {
1202 				// we need to have exclusive access to our syslog buffer
1203 				cpu_status state = disable_interrupts();
1204 				acquire_spinlock(&sSpinlock);
1205 
1206 				length = ring_buffer_readable(sSyslogBuffer)
1207 					- sSyslogBufferOffset;
1208 				if (length > (int32)SYSLOG_MAX_MESSAGE_LENGTH)
1209 					length = SYSLOG_MAX_MESSAGE_LENGTH;
1210 
1211 				length = ring_buffer_peek(sSyslogBuffer, sSyslogBufferOffset,
1212 					(uint8*)sSyslogMessage->message, length);
1213 				sSyslogBufferOffset += length;
1214 				if (sSyslogDropped) {
1215 					// Add drop marker - since parts had to be dropped, it's
1216 					// guaranteed that we have enough space in the buffer now.
1217 					ring_buffer_write(sSyslogBuffer, (uint8*)"<DROP>", 6);
1218 					sSyslogDropped = false;
1219 				}
1220 
1221 				release_spinlock(&sSpinlock);
1222 				restore_interrupts(state);
1223 			}
1224 
1225 			if (length == 0) {
1226 				// the buffer we came here for might have been sent already
1227 				bufferPending = false;
1228 				continue;
1229 			}
1230 
1231 			error = write_port_etc(port, SYSLOG_MESSAGE, sSyslogMessage,
1232 				sizeof(struct syslog_message) + length, B_RELATIVE_TIMEOUT, 0);
1233 
1234 			if (error < B_OK) {
1235 				// sending has failed - just wait, maybe it'll work later.
1236 				bufferPending = true;
1237 				continue;
1238 			}
1239 
1240 			if (bufferPending) {
1241 				// we could write the last pending buffer, try to read more
1242 				// from the syslog ring buffer
1243 				release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE);
1244 				bufferPending = false;
1245 			}
1246 		}
1247 	}
1248 
1249 	return 0;
1250 }
1251 
1252 
1253 static void
1254 syslog_write(const char* text, int32 length, bool notify)
1255 {
1256 	if (sSyslogBuffer == NULL)
1257 		return;
1258 
1259 	if (length > sSyslogBuffer->size) {
1260 		text = "<DROP>";
1261 		length = 6;
1262 	}
1263 
1264 	int32 writable = ring_buffer_writable(sSyslogBuffer);
1265 	if (writable < length) {
1266 		// drop old data
1267 		size_t toDrop = length - writable;
1268 		ring_buffer_flush(sSyslogBuffer, toDrop);
1269 
1270 		if (toDrop > sSyslogBufferOffset) {
1271 			sSyslogBufferOffset = 0;
1272 			sSyslogDropped = true;
1273 		} else
1274 			sSyslogBufferOffset -= toDrop;
1275 
1276 		sSyslogDebuggerOffset -= std::min(toDrop, sSyslogDebuggerOffset);
1277 	}
1278 
1279 	ring_buffer_write(sSyslogBuffer, (uint8*)text, length);
1280 
1281 	if (notify)
1282 		release_sem_etc(sSyslogNotify, 1, B_DO_NOT_RESCHEDULE);
1283 }
1284 
1285 
1286 static status_t
1287 syslog_init_post_threads(void)
1288 {
1289 	if (!sSyslogOutputEnabled)
1290 		return B_OK;
1291 
1292 	sSyslogNotify = create_sem(0, "syslog data");
1293 	if (sSyslogNotify >= B_OK) {
1294 		thread_id thread = spawn_kernel_thread(syslog_sender, "syslog sender",
1295 			B_LOW_PRIORITY, NULL);
1296 		if (thread >= B_OK && resume_thread(thread) == B_OK)
1297 			return B_OK;
1298 	}
1299 
1300 	// initializing kernel syslog service failed -- disable it
1301 
1302 	sSyslogOutputEnabled = false;
1303 
1304 	if (sSyslogBuffer != NULL) {
1305 		if (sDebugSyslog)
1306 			delete_area(area_for(sSyslogBuffer));
1307 		else
1308 			delete_ring_buffer(sSyslogBuffer);
1309 
1310 		sSyslogBuffer = NULL;
1311 	}
1312 
1313 	free(sSyslogMessage);
1314 	delete_sem(sSyslogNotify);
1315 
1316 	return B_ERROR;
1317 }
1318 
1319 
1320 static status_t
1321 syslog_init_post_vm(struct kernel_args* args)
1322 {
1323 	status_t status;
1324 	int32 length = 0;
1325 
1326 	if (!sSyslogOutputEnabled) {
1327 		sSyslogBuffer = NULL;
1328 			// Might already have been set in syslog_init(), if the debug syslog
1329 			// was enabled. Just drop it -- we'll never create the area.
1330 		return B_OK;
1331 	}
1332 
1333 	sSyslogMessage = (syslog_message*)malloc(SYSLOG_MESSAGE_BUFFER_SIZE);
1334 	if (sSyslogMessage == NULL) {
1335 		status = B_NO_MEMORY;
1336 		goto err1;
1337 	}
1338 
1339 	if (sSyslogBuffer == NULL) {
1340 		size_t bufferSize = DEFAULT_SYSLOG_BUFFER_SIZE;
1341 		void* handle = load_driver_settings("kernel");
1342 		if (handle != NULL) {
1343 			const char* sizeString = get_driver_parameter(handle,
1344 				"syslog_buffer_size", NULL, NULL);
1345 			if (sizeString != NULL) {
1346 				bufferSize = strtoul(sizeString, NULL, 0);
1347 				if (bufferSize > 262144)
1348 					bufferSize = 262144;
1349 				else if (bufferSize < SYSLOG_MESSAGE_BUFFER_SIZE)
1350 					bufferSize = SYSLOG_MESSAGE_BUFFER_SIZE;
1351 			}
1352 
1353 			unload_driver_settings(handle);
1354 		}
1355 
1356 		sSyslogBuffer = create_ring_buffer(bufferSize);
1357 
1358 		if (sSyslogBuffer == NULL) {
1359 			status = B_NO_MEMORY;
1360 			goto err2;
1361 		}
1362 	} else {
1363 		// create an area for the debug syslog buffer
1364 		void* base = (void*)ROUNDDOWN((addr_t)args->debug_output, B_PAGE_SIZE);
1365 		size_t size = ROUNDUP(args->debug_size, B_PAGE_SIZE);
1366 		area_id area = create_area("syslog debug", &base, B_EXACT_ADDRESS, size,
1367 				B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
1368 		if (area < 0) {
1369 			status = B_NO_MEMORY;
1370 			goto err2;
1371 		}
1372 	}
1373 
1374 	// initialize syslog message
1375 	sSyslogMessage->from = 0;
1376 	sSyslogMessage->options = LOG_KERN;
1377 	sSyslogMessage->priority = LOG_DEBUG;
1378 	sSyslogMessage->ident[0] = '\0';
1379 	//strcpy(sSyslogMessage->ident, "KERNEL");
1380 
1381 	if (args->debug_output != NULL)
1382 		syslog_write((const char*)args->debug_output, args->debug_size, false);
1383 
1384 	char revisionBuffer[64];
1385 	length = snprintf(revisionBuffer, sizeof(revisionBuffer),
1386 		"Welcome to syslog debug output!\nHaiku revision: %lu\n",
1387 		get_haiku_revision());
1388 	syslog_write(revisionBuffer,
1389 		std::min(length, (ssize_t)sizeof(revisionBuffer) - 1), false);
1390 
1391 	add_debugger_command_etc("syslog", &cmd_dump_syslog,
1392 		"Dumps the syslog buffer.",
1393 		"[ \"-n\" ] [ \"-k\" ]\n"
1394 		"Dumps the whole syslog buffer, or, if -k is specified, only "
1395 		"the part that hasn't been sent yet.\n", 0);
1396 
1397 	add_debugger_command("serial_input", &cmd_serial_input,
1398 		"Enable or disable serial input");
1399 
1400 	return B_OK;
1401 
1402 err2:
1403 	free(sSyslogMessage);
1404 err1:
1405 	sSyslogOutputEnabled = false;
1406 	sSyslogBuffer = NULL;
1407 	return status;
1408 }
1409 
1410 
1411 static status_t
1412 syslog_init(struct kernel_args* args)
1413 {
1414 	if (!args->keep_debug_output_buffer || args->debug_output == NULL)
1415 		return B_OK;
1416 
1417 	sSyslogBuffer = create_ring_buffer_etc(args->debug_output, args->debug_size,
1418 		RING_BUFFER_INIT_FROM_BUFFER);
1419 	sDebugSyslog = true;
1420 
1421 	return B_OK;
1422 }
1423 
1424 
1425 static void
1426 debug_memcpy_trampoline(void* _parameters)
1427 {
1428 	debug_memcpy_parameters* parameters = (debug_memcpy_parameters*)_parameters;
1429 	memcpy(parameters->to, parameters->from, parameters->size);
1430 }
1431 
1432 
1433 static void
1434 debug_strlcpy_trampoline(void* _parameters)
1435 {
1436 	debug_strlcpy_parameters* parameters
1437 		= (debug_strlcpy_parameters*)_parameters;
1438 	parameters->result = strlcpy(parameters->to, parameters->from,
1439 		parameters->size);
1440 }
1441 
1442 
1443 void
1444 call_modules_hook(bool enter)
1445 {
1446 	uint32 index = 0;
1447 	while (index < kMaxDebuggerModules && sDebuggerModules[index] != NULL) {
1448 		debugger_module_info* module = sDebuggerModules[index];
1449 
1450 		if (enter && module->enter_debugger != NULL)
1451 			module->enter_debugger();
1452 		else if (!enter && module->exit_debugger != NULL)
1453 			module->exit_debugger();
1454 
1455 		index++;
1456 	}
1457 }
1458 
1459 
1460 //!	Must be called with the sSpinlock held.
1461 static void
1462 debug_output(const char* string, int32 length, bool notifySyslog)
1463 {
1464 	if (length >= OUTPUT_BUFFER_SIZE)
1465 		length = OUTPUT_BUFFER_SIZE - 1;
1466 
1467 	if (length > 1 && string[length - 1] == '\n'
1468 		&& strncmp(string, sLastOutputBuffer, length) == 0) {
1469 		sMessageRepeatCount++;
1470 		sMessageRepeatLastTime = system_time();
1471 		if (sMessageRepeatFirstTime == 0)
1472 			sMessageRepeatFirstTime = sMessageRepeatLastTime;
1473 	} else {
1474 		flush_pending_repeats(notifySyslog);
1475 
1476 		if (sSerialDebugEnabled)
1477 			arch_debug_serial_puts(string);
1478 		if (sSyslogOutputEnabled)
1479 			syslog_write(string, length, notifySyslog);
1480 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1481 			blue_screen_puts(string);
1482 		if (sSerialDebugEnabled) {
1483 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1484 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
1485 					sDebuggerModules[i]->debugger_puts(string, length);
1486 			}
1487 		}
1488 
1489 		memcpy(sLastOutputBuffer, string, length);
1490 		sLastOutputBuffer[length] = 0;
1491 	}
1492 }
1493 
1494 
1495 //!	Must be called with the sSpinlock held.
1496 static void
1497 flush_pending_repeats(bool notifySyslog)
1498 {
1499 	if (sMessageRepeatCount <= 0)
1500 		return;
1501 
1502 	if (sMessageRepeatCount > 1) {
1503 		static char temp[40];
1504 		size_t length = snprintf(temp, sizeof(temp),
1505 			"Last message repeated %ld times.\n", sMessageRepeatCount);
1506 		length = std::min(length, sizeof(temp) - 1);
1507 
1508 		if (sSerialDebugEnabled)
1509 			arch_debug_serial_puts(temp);
1510 		if (sSyslogOutputEnabled)
1511 			syslog_write(temp, length, notifySyslog);
1512 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1513 			blue_screen_puts(temp);
1514 		if (sSerialDebugEnabled) {
1515 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1516 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts)
1517 					sDebuggerModules[i]->debugger_puts(temp, length);
1518 			}
1519 		}
1520 	} else {
1521 		// if we only have one repeat just reprint the last buffer
1522 		size_t length = strlen(sLastOutputBuffer);
1523 
1524 		if (sSerialDebugEnabled)
1525 			arch_debug_serial_puts(sLastOutputBuffer);
1526 		if (sSyslogOutputEnabled)
1527 			syslog_write(sLastOutputBuffer, length, notifySyslog);
1528 		if (sBlueScreenEnabled || sDebugScreenEnabled)
1529 			blue_screen_puts(sLastOutputBuffer);
1530 		if (sSerialDebugEnabled) {
1531 			for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1532 				if (sDebuggerModules[i] && sDebuggerModules[i]->debugger_puts) {
1533 					sDebuggerModules[i]->debugger_puts(sLastOutputBuffer,
1534 						length);
1535 				}
1536 			}
1537 		}
1538 	}
1539 
1540 	sMessageRepeatFirstTime = 0;
1541 	sMessageRepeatCount = 0;
1542 }
1543 
1544 
1545 static void
1546 check_pending_repeats(void* /*data*/, int /*iteration*/)
1547 {
1548 	if (sMessageRepeatCount > 0
1549 		&& (system_time() - sMessageRepeatLastTime > 1000000
1550 			|| system_time() - sMessageRepeatFirstTime > 3000000)) {
1551 		cpu_status state = disable_interrupts();
1552 		acquire_spinlock(&sSpinlock);
1553 
1554 		flush_pending_repeats(true);
1555 
1556 		release_spinlock(&sSpinlock);
1557 		restore_interrupts(state);
1558 	}
1559 }
1560 
1561 
1562 static void
1563 dprintf_args(const char* format, va_list args, bool notifySyslog)
1564 {
1565 	if (are_interrupts_enabled()) {
1566 		MutexLocker locker(sOutputLock);
1567 
1568 		int32 length = vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, format,
1569 			args);
1570 		length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
1571 
1572 		InterruptsSpinLocker _(sSpinlock);
1573 		debug_output(sOutputBuffer, length, notifySyslog);
1574 	} else {
1575 		InterruptsSpinLocker _(sSpinlock);
1576 
1577 		int32 length = vsnprintf(sInterruptOutputBuffer, OUTPUT_BUFFER_SIZE,
1578 			format, args);
1579 		length = std::min(length, (int32)OUTPUT_BUFFER_SIZE - 1);
1580 
1581 		debug_output(sInterruptOutputBuffer, length, notifySyslog);
1582 	}
1583 }
1584 
1585 
1586 // #pragma mark - private kernel API
1587 
1588 
1589 bool
1590 debug_screen_output_enabled(void)
1591 {
1592 	return sDebugScreenEnabled;
1593 }
1594 
1595 
1596 void
1597 debug_stop_screen_debug_output(void)
1598 {
1599 	sDebugScreenEnabled = false;
1600 }
1601 
1602 
1603 bool
1604 debug_debugger_running(void)
1605 {
1606 	return sDebuggerOnCPU != -1;
1607 }
1608 
1609 
1610 void
1611 debug_puts(const char* string, int32 length)
1612 {
1613 	InterruptsSpinLocker _(sSpinlock);
1614 	debug_output(string, length, true);
1615 }
1616 
1617 
1618 void
1619 debug_early_boot_message(const char* string)
1620 {
1621 	arch_debug_serial_early_boot_message(string);
1622 }
1623 
1624 
1625 void
1626 debug_init(kernel_args* args)
1627 {
1628 	new(&gDefaultDebugOutputFilter) DefaultDebugOutputFilter;
1629 
1630 	syslog_init(args);
1631 
1632 	debug_paranoia_init();
1633 	arch_debug_console_init(args);
1634 }
1635 
1636 
1637 void
1638 debug_init_post_vm(kernel_args* args)
1639 {
1640 	add_debugger_command_etc("cpu", &cmd_switch_cpu,
1641 		"Switches to another CPU.",
1642 		"<cpu>\n"
1643 		"Switches to CPU with the index <cpu>.\n", 0);
1644 	add_debugger_command_etc("message", &cmd_dump_kdl_message,
1645 		"Reprint the message printed when entering KDL",
1646 		"\n"
1647 		"Reprints the message printed when entering KDL.\n", 0);
1648 	add_debugger_command_etc("panic_commands", &cmd_execute_panic_commands,
1649 		"Execute commands associated with the panic() that caused "
1650 			"entering KDL",
1651 		"\n"
1652 		"Executes the commands associated with the panic() that caused "
1653 			"entering KDL.\n", 0);
1654 
1655 	debug_builtin_commands_init();
1656 	arch_debug_init(args);
1657 
1658 	debug_heap_init();
1659 	debug_variables_init();
1660 	frame_buffer_console_init(args);
1661 	arch_debug_console_init_settings(args);
1662 	tracing_init();
1663 }
1664 
1665 
1666 void
1667 debug_init_post_settings(struct kernel_args* args)
1668 {
1669 	// get debug settings
1670 
1671 	sSerialDebugEnabled = get_safemode_boolean("serial_debug_output",
1672 		sSerialDebugEnabled);
1673 	sSyslogOutputEnabled = get_safemode_boolean("syslog_debug_output",
1674 		sSyslogOutputEnabled);
1675 	sBlueScreenOutput = get_safemode_boolean("bluescreen", true);
1676 	sEmergencyKeysEnabled = get_safemode_boolean("emergency_keys",
1677 		sEmergencyKeysEnabled);
1678 	sDebugScreenEnabled = get_safemode_boolean("debug_screen", false);
1679 
1680 	if ((sBlueScreenOutput || sDebugScreenEnabled)
1681 		&& blue_screen_init() != B_OK)
1682 		sBlueScreenOutput = sDebugScreenEnabled = false;
1683 
1684 	if (sDebugScreenEnabled)
1685 		blue_screen_enter(true);
1686 
1687 	syslog_init_post_vm(args);
1688 }
1689 
1690 
1691 void
1692 debug_init_post_modules(struct kernel_args* args)
1693 {
1694 	void* cookie;
1695 
1696 	// check for dupped lines every 10/10 second
1697 	register_kernel_daemon(check_pending_repeats, NULL, 10);
1698 
1699 	syslog_init_post_threads();
1700 
1701 	// load kernel debugger addons
1702 
1703 	static const char* kDemanglePrefix = "debugger/demangle/";
1704 
1705 	cookie = open_module_list("debugger");
1706 	uint32 count = 0;
1707 	while (count < kMaxDebuggerModules) {
1708 		char name[B_FILE_NAME_LENGTH];
1709 		size_t nameLength = sizeof(name);
1710 
1711 		if (read_next_module_name(cookie, name, &nameLength) != B_OK)
1712 			break;
1713 
1714 		// get demangle module, if any
1715 		if (!strncmp(name, kDemanglePrefix, strlen(kDemanglePrefix))) {
1716 			if (sDemangleModule == NULL)
1717 				get_module(name, (module_info**)&sDemangleModule);
1718 			continue;
1719 		}
1720 
1721 		if (get_module(name, (module_info**)&sDebuggerModules[count]) == B_OK) {
1722 			dprintf("kernel debugger extension \"%s\": loaded\n", name);
1723 			count++;
1724 		} else
1725 			dprintf("kernel debugger extension \"%s\": failed to load\n", name);
1726 	}
1727 	close_module_list(cookie);
1728 
1729 	frame_buffer_console_init_post_modules(args);
1730 }
1731 
1732 
1733 void
1734 debug_set_page_fault_info(addr_t faultAddress, addr_t pc, uint32 flags)
1735 {
1736 	sPageFaultInfo.fault_address = faultAddress;
1737 	sPageFaultInfo.pc = pc;
1738 	sPageFaultInfo.flags = flags;
1739 }
1740 
1741 
1742 debug_page_fault_info*
1743 debug_get_page_fault_info()
1744 {
1745 	return &sPageFaultInfo;
1746 }
1747 
1748 
1749 void
1750 debug_trap_cpu_in_kdl(int32 cpu, bool returnIfHandedOver)
1751 {
1752 	InterruptsLocker locker;
1753 
1754 	// return, if we've been called recursively (we call
1755 	// smp_intercpu_int_handler() below)
1756 	if (sCPUTrapped[cpu])
1757 		return;
1758 
1759 	arch_debug_save_registers(&sDebugRegisters[cpu]);
1760 
1761 	sCPUTrapped[cpu] = true;
1762 
1763 	while (sInDebugger != 0) {
1764 		if (sHandOverKDL && sHandOverKDLToCPU == cpu) {
1765 			if (returnIfHandedOver)
1766 				break;
1767 
1768 			kernel_debugger_internal(NULL, NULL,
1769 				sCurrentKernelDebuggerMessageArgs, cpu);
1770 		} else
1771 			smp_intercpu_int_handler(cpu);
1772 	}
1773 
1774 	sCPUTrapped[cpu] = false;
1775 }
1776 
1777 
1778 void
1779 debug_double_fault(int32 cpu)
1780 {
1781 	kernel_debugger_internal("Double Fault!", NULL,
1782 		sCurrentKernelDebuggerMessageArgs, cpu);
1783 }
1784 
1785 
1786 bool
1787 debug_emergency_key_pressed(char key)
1788 {
1789 	if (!sEmergencyKeysEnabled)
1790 		return false;
1791 
1792 	if (key == 'd') {
1793 		kernel_debugger("Keyboard Requested Halt.");
1794 		return true;
1795 	}
1796 
1797 	// Broadcast to the kernel debugger modules
1798 
1799 	for (uint32 i = 0; i < kMaxDebuggerModules; i++) {
1800 		if (sDebuggerModules[i] && sDebuggerModules[i]->emergency_key_pressed) {
1801 			if (sDebuggerModules[i]->emergency_key_pressed(key))
1802 				return true;
1803 		}
1804 	}
1805 
1806 	return false;
1807 }
1808 
1809 
1810 /*!	Verifies that the complete given memory range is accessible in the current
1811 	context.
1812 
1813 	Invoked in the kernel debugger only.
1814 
1815 	\param address The start address of the memory range to be checked.
1816 	\param size The size of the memory range to be checked.
1817 	\param protection The area protection for which to check. Valid is a bitwise
1818 		or of one or more of \c B_KERNEL_READ_AREA or \c B_KERNEL_WRITE_AREA.
1819 	\return \c true, if the complete memory range can be accessed in all ways
1820 		specified by \a protection, \c false otherwise.
1821 */
1822 bool
1823 debug_is_kernel_memory_accessible(addr_t address, size_t size,
1824 	uint32 protection)
1825 {
1826 	addr_t endAddress = ROUNDUP(address + size, B_PAGE_SIZE);
1827 	address = ROUNDDOWN(address, B_PAGE_SIZE);
1828 
1829 	if (!IS_KERNEL_ADDRESS(address) || endAddress < address)
1830 		return false;
1831 
1832 	for (; address < endAddress; address += B_PAGE_SIZE) {
1833 		if (!arch_vm_translation_map_is_kernel_page_accessible(address,
1834 				protection)) {
1835 			return false;
1836 		}
1837 	}
1838 
1839 	return true;
1840 }
1841 
1842 
1843 /*!	Calls a function in a setjmp() + fault handler context.
1844 	May only be used in the kernel debugger.
1845 
1846 	\param jumpBuffer Buffer to be used for setjmp()/longjmp().
1847 	\param function The function to be called.
1848 	\param parameter The parameter to be passed to the function to be called.
1849 	\return
1850 		- \c 0, when the function executed without causing a page fault or
1851 		  calling longjmp().
1852 		- \c 1, when the function caused a page fault.
1853 		- Any other value the function passes to longjmp().
1854 */
1855 int
1856 debug_call_with_fault_handler(jmp_buf jumpBuffer, void (*function)(void*),
1857 	void* parameter)
1858 {
1859 	// save current fault handler
1860 	cpu_ent* cpu = gCPU + sDebuggerOnCPU;
1861 	addr_t oldFaultHandler = cpu->fault_handler;
1862 	addr_t oldFaultHandlerStackPointer = cpu->fault_handler_stack_pointer;
1863 
1864 	int result = setjmp(jumpBuffer);
1865 	if (result == 0) {
1866 		arch_debug_call_with_fault_handler(cpu, jumpBuffer, function,
1867 			parameter);
1868 	}
1869 
1870 	// restore old fault handler
1871 	cpu->fault_handler = oldFaultHandler;
1872 	cpu->fault_handler_stack_pointer = oldFaultHandlerStackPointer;
1873 
1874 	return result;
1875 }
1876 
1877 
1878 /*!	Similar to user_memcpy(), but can only be invoked from within the kernel
1879 	debugger (and must not be used outside).
1880 	The supplied \a teamID specifies the address space in which to interpret
1881 	the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(),
1882 	or any valid team ID. If the addresses are both kernel addresses, the
1883 	argument is ignored and the current address space is used.
1884 */
1885 status_t
1886 debug_memcpy(team_id teamID, void* to, const void* from, size_t size)
1887 {
1888 	// don't allow address overflows
1889 	if ((addr_t)from + size < (addr_t)from || (addr_t)to + size < (addr_t)to)
1890 		return B_BAD_ADDRESS;
1891 
1892 	// Try standard memcpy() with fault handler, if the addresses can be
1893 	// interpreted in the current address space.
1894 	if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to))
1895 			|| debug_is_debugged_team(teamID)) {
1896 		debug_memcpy_parameters parameters = {to, from, size};
1897 
1898 		if (debug_call_with_fault_handler(gCPU[sDebuggerOnCPU].fault_jump_buffer,
1899 				&debug_memcpy_trampoline, &parameters) == 0) {
1900 			return B_OK;
1901 		}
1902 	}
1903 
1904 	// Try harder. The pages of the respective memory could be unmapped but
1905 	// still exist in a cache (the page daemon does that with inactive pages).
1906 	while (size > 0) {
1907 		uint8 buffer[32];
1908 		size_t toCopy = std::min(size, sizeof(buffer));
1909 
1910 		// restrict the size so we don't cross page boundaries
1911 		if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy)
1912 			toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE;
1913 		if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy)
1914 			toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE;
1915 
1916 		if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy,
1917 				false) != B_OK
1918 			|| vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true)
1919 				!= B_OK) {
1920 			return B_BAD_ADDRESS;
1921 		}
1922 
1923 		from = (const uint8*)from + toCopy;
1924 		to = (uint8*)to + toCopy;
1925 		size -= toCopy;
1926 	}
1927 
1928 	return B_OK;
1929 }
1930 
1931 
1932 /*!	Similar to user_strlcpy(), but can only be invoked from within the kernel
1933 	debugger (and must not be used outside).
1934 	The supplied \a teamID specifies the address space in which to interpret
1935 	the addresses. It can be \c B_CURRENT_TEAM for debug_get_debugged_thread(),
1936 	or any valid team ID. If the addresses are both kernel addresses, the
1937 	argument is ignored and the current address space is used.
1938 */
1939 ssize_t
1940 debug_strlcpy(team_id teamID, char* to, const char* from, size_t size)
1941 {
1942 	if (from == NULL || (to == NULL && size > 0))
1943 		return B_BAD_ADDRESS;
1944 
1945 	// limit size to avoid address overflows
1946 	size_t maxSize = std::min(size,
1947 		~(addr_t)0 - std::max((addr_t)from, (addr_t)to) + 1);
1948 		// NOTE: Since strlcpy() determines the length of \a from, the source
1949 		// address might still overflow.
1950 
1951 	// Try standard strlcpy() with fault handler, if the addresses can be
1952 	// interpreted in the current address space.
1953 	if ((IS_KERNEL_ADDRESS(from) && IS_KERNEL_ADDRESS(to))
1954 			|| debug_is_debugged_team(teamID)) {
1955 		debug_strlcpy_parameters parameters = {to, from, maxSize};
1956 
1957 		if (debug_call_with_fault_handler(
1958 				gCPU[sDebuggerOnCPU].fault_jump_buffer,
1959 				&debug_strlcpy_trampoline, &parameters) == 0) {
1960 			// If we hit the address overflow boundary, fail.
1961 			if (parameters.result >= maxSize && maxSize < size)
1962 				return B_BAD_ADDRESS;
1963 
1964 			return parameters.result;
1965 		}
1966 	}
1967 
1968 	// Try harder. The pages of the respective memory could be unmapped but
1969 	// still exist in a cache (the page daemon does that with inactive pages).
1970 	size_t totalLength = 0;
1971 	while (maxSize > 0) {
1972 		char buffer[32];
1973 		size_t toCopy = std::min(maxSize, sizeof(buffer));
1974 
1975 		// restrict the size so we don't cross page boundaries
1976 		if (((addr_t)from + toCopy) % B_PAGE_SIZE < toCopy)
1977 			toCopy -= ((addr_t)from + toCopy) % B_PAGE_SIZE;
1978 		if (((addr_t)to + toCopy) % B_PAGE_SIZE < toCopy)
1979 			toCopy -= ((addr_t)to + toCopy) % B_PAGE_SIZE;
1980 
1981 		// copy the next part of the string from the source
1982 		if (vm_debug_copy_page_memory(teamID, (void*)from, buffer, toCopy,
1983 				false) != B_OK) {
1984 			return B_BAD_ADDRESS;
1985 		}
1986 
1987 		// determine the length of the part and whether we've reached the end
1988 		// of the string
1989 		size_t length = strnlen(buffer, toCopy);
1990 		bool endOfString = length < toCopy;
1991 
1992 		from = (const char*)from + toCopy;
1993 		totalLength += length;
1994 		maxSize -= length;
1995 
1996 		if (endOfString) {
1997 			// only copy the actual string, including the terminating null
1998 			toCopy = length + 1;
1999 		}
2000 
2001 		if (size > 0) {
2002 			// We still have space left in the target buffer.
2003 			if (size <= length) {
2004 				// Not enough space for the complete part. Null-terminate it and
2005 				// copy what we can.
2006 				buffer[size - 1] = '\0';
2007 				totalLength += length - size;
2008 				toCopy = size;
2009 			}
2010 
2011 			if (vm_debug_copy_page_memory(teamID, to, buffer, toCopy, true)
2012 					!= B_OK) {
2013 				return B_BAD_ADDRESS;
2014 			}
2015 
2016 			to = (char*)to + toCopy;
2017 			size -= toCopy;
2018 		}
2019 
2020 		if (endOfString)
2021 			return totalLength;
2022 	}
2023 
2024 	return totalLength;
2025 }
2026 
2027 
2028 // #pragma mark - public API
2029 
2030 
2031 uint64
2032 parse_expression(const char* expression)
2033 {
2034 	uint64 result;
2035 	return evaluate_debug_expression(expression, &result, true) ? result : 0;
2036 }
2037 
2038 
2039 void
2040 panic(const char* format, ...)
2041 {
2042 	va_list args;
2043 	va_start(args, format);
2044 
2045 	cpu_status state = disable_interrupts();
2046 
2047 	kernel_debugger_internal("PANIC: ", format, args, smp_get_current_cpu());
2048 
2049 	restore_interrupts(state);
2050 
2051 	va_end(args);
2052 }
2053 
2054 
2055 void
2056 kernel_debugger(const char* message)
2057 {
2058 	cpu_status state = disable_interrupts();
2059 
2060 	kernel_debugger_internal(message, NULL, sCurrentKernelDebuggerMessageArgs,
2061 		smp_get_current_cpu());
2062 
2063 	restore_interrupts(state);
2064 }
2065 
2066 
2067 bool
2068 set_dprintf_enabled(bool newState)
2069 {
2070 	bool oldState = sSerialDebugEnabled;
2071 	sSerialDebugEnabled = newState;
2072 
2073 	return oldState;
2074 }
2075 
2076 
2077 void
2078 dprintf(const char* format, ...)
2079 {
2080 	va_list args;
2081 
2082 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled && !sBlueScreenEnabled)
2083 		return;
2084 
2085 	va_start(args, format);
2086 	dprintf_args(format, args, true);
2087 	va_end(args);
2088 }
2089 
2090 
2091 void
2092 dprintf_no_syslog(const char* format, ...)
2093 {
2094 	va_list args;
2095 
2096 	if (!sSerialDebugEnabled && !sBlueScreenEnabled)
2097 		return;
2098 
2099 	va_start(args, format);
2100 	dprintf_args(format, args, false);
2101 	va_end(args);
2102 }
2103 
2104 
2105 /*!	Similar to dprintf() but thought to be used in the kernel
2106 	debugger only (it doesn't lock).
2107 */
2108 void
2109 kprintf(const char* format, ...)
2110 {
2111 	if (sDebugOutputFilter != NULL) {
2112 		va_list args;
2113 		va_start(args, format);
2114 		sDebugOutputFilter->Print(format, args);
2115 		va_end(args);
2116 	}
2117 }
2118 
2119 
2120 void
2121 kprintf_unfiltered(const char* format, ...)
2122 {
2123 	va_list args;
2124 	va_start(args, format);
2125 	gDefaultDebugOutputFilter.Print(format, args);
2126 	va_end(args);
2127 }
2128 
2129 
2130 const char*
2131 debug_demangle_symbol(const char* symbol, char* buffer, size_t bufferSize,
2132 	bool* _isObjectMethod)
2133 {
2134 	if (sDemangleModule != NULL && sDemangleModule->demangle_symbol != NULL) {
2135 		return sDemangleModule->demangle_symbol(symbol, buffer, bufferSize,
2136 			_isObjectMethod);
2137 	}
2138 
2139 	if (_isObjectMethod != NULL)
2140 		*_isObjectMethod = false;
2141 
2142 	return symbol;
2143 }
2144 
2145 
2146 status_t
2147 debug_get_next_demangled_argument(uint32* _cookie, const char* symbol,
2148 	char* name, size_t nameSize, int32* _type, size_t* _argumentLength)
2149 {
2150 	if (sDemangleModule != NULL && sDemangleModule->get_next_argument != NULL) {
2151 		return sDemangleModule->get_next_argument(_cookie, symbol, name,
2152 			nameSize, _type, _argumentLength);
2153 	}
2154 
2155 	return B_NOT_SUPPORTED;
2156 }
2157 
2158 
2159 struct arch_debug_registers*
2160 debug_get_debug_registers(int32 cpu)
2161 {
2162 	if (cpu < 0 || cpu > smp_get_num_cpus())
2163 		return NULL;
2164 
2165 	return &sDebugRegisters[cpu];
2166 }
2167 
2168 
2169 struct thread*
2170 debug_set_debugged_thread(struct thread* thread)
2171 {
2172 	struct thread* previous = sDebuggedThread;
2173 	sDebuggedThread = thread;
2174 	return previous;
2175 }
2176 
2177 
2178 struct thread*
2179 debug_get_debugged_thread()
2180 {
2181 	return sDebuggedThread != NULL
2182 		? sDebuggedThread : thread_get_current_thread();
2183 }
2184 
2185 
2186 /*!	Returns whether the supplied team ID refers to the same team the currently
2187 	debugged thread (debug_get_debugged_thread()) belongs to.
2188 	Always returns \c true, if \c B_CURRENT_TEAM is given.
2189 */
2190 bool
2191 debug_is_debugged_team(team_id teamID)
2192 {
2193 	if (teamID == B_CURRENT_TEAM)
2194 		return true;
2195 
2196 	struct thread* thread = debug_get_debugged_thread();
2197 	return thread != NULL && thread->team != NULL
2198 		&& thread->team->id == teamID;
2199 }
2200 
2201 
2202 //	#pragma mark -
2203 //	userland syscalls
2204 
2205 
2206 status_t
2207 _user_kernel_debugger(const char *userMessage)
2208 {
2209 	if (geteuid() != 0)
2210 		return B_NOT_ALLOWED;
2211 
2212 	char message[512];
2213 	strcpy(message, "USER: ");
2214 	size_t len = strlen(message);
2215 
2216 	if (userMessage == NULL || !IS_USER_ADDRESS(userMessage)
2217 		|| 	user_strlcpy(message + len, userMessage, sizeof(message) - len)
2218 			< 0) {
2219 		return B_BAD_ADDRESS;
2220 	}
2221 
2222 	kernel_debugger(message);
2223 	return B_OK;
2224 }
2225 
2226 
2227 void
2228 _user_debug_output(const char* userString)
2229 {
2230 	char string[512];
2231 	int32 length;
2232 
2233 	if (!sSerialDebugEnabled && !sSyslogOutputEnabled)
2234 		return;
2235 
2236 	if (!IS_USER_ADDRESS(userString))
2237 		return;
2238 
2239 	do {
2240 		length = user_strlcpy(string, userString, sizeof(string));
2241 		debug_puts(string, length);
2242 		userString += sizeof(string) - 1;
2243 	} while (length >= (ssize_t)sizeof(string));
2244 }
2245 
2246 
2247 void
2248 dump_block(const char* buffer, int size, const char* prefix)
2249 {
2250 	const int DUMPED_BLOCK_SIZE = 16;
2251 	int i;
2252 
2253 	for (i = 0; i < size;) {
2254 		int start = i;
2255 
2256 		dprintf("%s%04x ", prefix, i);
2257 		for (; i < start + DUMPED_BLOCK_SIZE; i++) {
2258 			if (!(i % 4))
2259 				dprintf(" ");
2260 
2261 			if (i >= size)
2262 				dprintf("  ");
2263 			else
2264 				dprintf("%02x", *(unsigned char*)(buffer + i));
2265 		}
2266 		dprintf("  ");
2267 
2268 		for (i = start; i < start + DUMPED_BLOCK_SIZE; i++) {
2269 			if (i < size) {
2270 				char c = buffer[i];
2271 
2272 				if (c < 30)
2273 					dprintf(".");
2274 				else
2275 					dprintf("%c", c);
2276 			} else
2277 				break;
2278 		}
2279 		dprintf("\n");
2280 	}
2281 }
2282