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