1/*
2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2002-2008, Axel D��rfler, axeld@pinc-software.de.
4 * Copyright 2012, Alex Smith, alex@alex-smith.me.uk.
5 * Distributed under the terms of the MIT License.
6 *
7 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
8 * Distributed under the terms of the NewOS License.
9 */
10
11
12#include <arch/debug.h>
13
14#include <stdio.h>
15#include <stdlib.h>
16
17#include <ByteOrder.h>
18#include <TypeConstants.h>
19
20#include <cpu.h>
21#include <debug.h>
22#include <debug_heap.h>
23#include <elf.h>
24#include <kernel.h>
25#include <kimage.h>
26#include <thread.h>
27#include <vm/vm.h>
28#include <vm/vm_types.h>
29#include <vm/VMAddressSpace.h>
30#include <vm/VMArea.h>
31
32
33struct stack_frame {
34	stack_frame*	previous;
35	addr_t			return_address;
36};
37
38#define NUM_PREVIOUS_LOCATIONS 32
39
40
41static bool is_kernel_stack_address(Thread* thread, addr_t address);
42
43
44static bool
45already_visited(addr_t* visited, int32* _last, int32* _num, addr_t bp)
46{
47	int32 last = *_last;
48	int32 num = *_num;
49	int32 i;
50
51	for (i = 0; i < num; i++) {
52		if (visited[(NUM_PREVIOUS_LOCATIONS + last - i) % NUM_PREVIOUS_LOCATIONS] == bp)
53			return true;
54	}
55
56	*_last = last = (last + 1) % NUM_PREVIOUS_LOCATIONS;
57	visited[last] = bp;
58
59	if (num < NUM_PREVIOUS_LOCATIONS)
60		*_num = num + 1;
61
62	return false;
63}
64
65
66/*!	Safe to be called only from outside the debugger.
67*/
68static status_t
69get_next_frame_no_debugger(addr_t bp, addr_t* _next, addr_t* _ip,
70	bool onKernelStack, Thread* thread)
71{
72	// TODO: Do this more efficiently in assembly.
73	stack_frame frame;
74	if (onKernelStack
75			&& is_kernel_stack_address(thread, bp + sizeof(frame) - 1)) {
76		memcpy(&frame, (void*)bp, sizeof(frame));
77	} else if (!IS_USER_ADDRESS(bp)
78			|| user_memcpy(&frame, (void*)bp, sizeof(frame)) != B_OK) {
79		return B_BAD_ADDRESS;
80	}
81
82	*_ip = frame.return_address;
83	*_next = (addr_t)frame.previous;
84
85	return B_OK;
86}
87
88
89/*!	Safe to be called only from inside the debugger.
90*/
91static status_t
92get_next_frame_debugger(addr_t bp, addr_t* _next, addr_t* _ip)
93{
94	stack_frame frame;
95	if (debug_memcpy(B_CURRENT_TEAM, &frame, (void*)bp, sizeof(frame)) != B_OK)
96		return B_BAD_ADDRESS;
97
98	*_ip = frame.return_address;
99	*_next = (addr_t)frame.previous;
100
101	return B_OK;
102}
103
104
105static status_t
106lookup_symbol(Thread* thread, addr_t address, addr_t* _baseAddress,
107	const char** _symbolName, const char** _imageName, bool* _exactMatch)
108{
109	status_t status = B_ENTRY_NOT_FOUND;
110
111	if (IS_KERNEL_ADDRESS(address)) {
112		// a kernel symbol
113		status = elf_debug_lookup_symbol_address(address, _baseAddress,
114			_symbolName, _imageName, _exactMatch);
115	} else if (thread != NULL && thread->team != NULL) {
116		// try a lookup using the userland runtime loader structures
117		status = elf_debug_lookup_user_symbol_address(thread->team, address,
118			_baseAddress, _symbolName, _imageName, _exactMatch);
119
120		if (status != B_OK) {
121			// try to locate the image in the images loaded into user space
122			status = image_debug_lookup_user_symbol_address(thread->team,
123				address, _baseAddress, _symbolName, _imageName, _exactMatch);
124		}
125	}
126
127	return status;
128}
129
130
131#ifndef __x86_64__
132
133
134static void
135set_debug_argument_variable(int32 index, uint64 value)
136{
137	char name[8];
138	snprintf(name, sizeof(name), "_arg%ld", index);
139	set_debug_variable(name, value);
140}
141
142
143template<typename Type>
144static Type
145read_function_argument_value(void* argument, bool& _valueKnown)
146{
147	Type value;
148	if (debug_memcpy(B_CURRENT_TEAM, &value, argument, sizeof(Type)) == B_OK) {
149		_valueKnown = true;
150		return value;
151	}
152
153	_valueKnown = false;
154	return 0;
155}
156
157
158static status_t
159print_demangled_call(const char* image, const char* symbol, addr_t args,
160	bool noObjectMethod, bool addDebugVariables)
161{
162	static const size_t kBufferSize = 256;
163	char* buffer = (char*)debug_malloc(kBufferSize);
164	if (buffer == NULL)
165		return B_NO_MEMORY;
166
167	bool isObjectMethod;
168	const char* name = debug_demangle_symbol(symbol, buffer, kBufferSize,
169		&isObjectMethod);
170	if (name == NULL) {
171		debug_free(buffer);
172		return B_ERROR;
173	}
174
175	uint32* arg = (uint32*)args;
176
177	if (noObjectMethod)
178		isObjectMethod = false;
179	if (isObjectMethod) {
180		const char* lastName = strrchr(name, ':') - 1;
181		int namespaceLength = lastName - name;
182
183		uint32 argValue = 0;
184		if (debug_memcpy(B_CURRENT_TEAM, &argValue, arg, 4) == B_OK) {
185			kprintf("<%s> %.*s<\33[32m%#" B_PRIx32 "\33[0m>%s", image,
186				namespaceLength, name, argValue, lastName);
187		} else
188			kprintf("<%s> %.*s<\?\?\?>%s", image, namespaceLength, name, lastName);
189
190		if (addDebugVariables)
191			set_debug_variable("_this", argValue);
192		arg++;
193	} else
194		kprintf("<%s> %s", image, name);
195
196	kprintf("(");
197
198	size_t length;
199	int32 type, i = 0;
200	uint32 cookie = 0;
201	while (debug_get_next_demangled_argument(&cookie, symbol, buffer,
202			kBufferSize, &type, &length) == B_OK) {
203		if (i++ > 0)
204			kprintf(", ");
205
206		// retrieve value and type identifier
207
208		uint64 value;
209		bool valueKnown = false;
210
211		switch (type) {
212			case B_INT64_TYPE:
213				value = read_function_argument_value<int64>(arg, valueKnown);
214				if (valueKnown)
215					kprintf("int64: \33[34m%Ld\33[0m", value);
216				break;
217			case B_INT32_TYPE:
218				value = read_function_argument_value<int32>(arg, valueKnown);
219				if (valueKnown)
220					kprintf("int32: \33[34m%ld\33[0m", (int32)value);
221				break;
222			case B_INT16_TYPE:
223				value = read_function_argument_value<int16>(arg, valueKnown);
224				if (valueKnown)
225					kprintf("int16: \33[34m%d\33[0m", (int16)value);
226				break;
227			case B_INT8_TYPE:
228				value = read_function_argument_value<int8>(arg, valueKnown);
229				if (valueKnown)
230					kprintf("int8: \33[34m%d\33[0m", (int8)value);
231				break;
232			case B_UINT64_TYPE:
233				value = read_function_argument_value<uint64>(arg, valueKnown);
234				if (valueKnown) {
235					kprintf("uint64: \33[34m%#Lx\33[0m", value);
236					if (value < 0x100000)
237						kprintf(" (\33[34m%Lu\33[0m)", value);
238				}
239				break;
240			case B_UINT32_TYPE:
241				value = read_function_argument_value<uint32>(arg, valueKnown);
242				if (valueKnown) {
243					kprintf("uint32: \33[34m%#lx\33[0m", (uint32)value);
244					if (value < 0x100000)
245						kprintf(" (\33[34m%lu\33[0m)", (uint32)value);
246				}
247				break;
248			case B_UINT16_TYPE:
249				value = read_function_argument_value<uint16>(arg, valueKnown);
250				if (valueKnown) {
251					kprintf("uint16: \33[34m%#x\33[0m (\33[34m%u\33[0m)",
252						(uint16)value, (uint16)value);
253				}
254				break;
255			case B_UINT8_TYPE:
256				value = read_function_argument_value<uint8>(arg, valueKnown);
257				if (valueKnown) {
258					kprintf("uint8: \33[34m%#x\33[0m (\33[34m%u\33[0m)",
259						(uint8)value, (uint8)value);
260				}
261				break;
262			case B_BOOL_TYPE:
263				value = read_function_argument_value<uint8>(arg, valueKnown);
264				if (valueKnown)
265					kprintf("\33[34m%s\33[0m", value ? "true" : "false");
266				break;
267			default:
268				if (buffer[0])
269					kprintf("%s: ", buffer);
270
271				if (length == 4) {
272					value = read_function_argument_value<uint32>(arg,
273						valueKnown);
274					if (valueKnown) {
275						if (value == 0
276							&& (type == B_POINTER_TYPE || type == B_REF_TYPE))
277							kprintf("NULL");
278						else
279							kprintf("\33[34m%#lx\33[0m", (uint32)value);
280					}
281					break;
282				}
283
284
285				if (length == 8) {
286					value = read_function_argument_value<uint64>(arg,
287						valueKnown);
288				} else
289					value = (uint64)arg;
290
291				if (valueKnown)
292					kprintf("\33[34m%#Lx\33[0m", value);
293				break;
294		}
295
296		if (!valueKnown)
297			kprintf("???");
298
299		if (valueKnown && type == B_STRING_TYPE) {
300			if (value == 0)
301				kprintf(" \33[31m\"<NULL>\"\33[0m");
302			else if (debug_strlcpy(B_CURRENT_TEAM, buffer, (char*)(addr_t)value,
303					kBufferSize) < B_OK) {
304				kprintf(" \33[31m\"<\?\?\?>\"\33[0m");
305			} else
306				kprintf(" \33[36m\"%s\"\33[0m", buffer);
307		}
308
309		if (addDebugVariables)
310			set_debug_argument_variable(i, value);
311		arg = (uint32*)((uint8*)arg + length);
312	}
313
314	debug_free(buffer);
315
316	kprintf(")");
317	return B_OK;
318}
319
320
321#else	// __x86_64__
322
323
324static status_t
325print_demangled_call(const char* image, const char* symbol, addr_t args,
326	bool noObjectMethod, bool addDebugVariables)
327{
328	// Since x86_64 uses registers rather than the stack for the first 6
329	// arguments we cannot use the same method as x86 to read the function
330	// arguments. Maybe we need DWARF support in the kernel debugger. For now
331	// just print out the function signature without the argument values.
332
333	static const size_t kBufferSize = 256;
334	char* buffer = (char*)debug_malloc(kBufferSize);
335	if (buffer == NULL)
336		return B_NO_MEMORY;
337
338	bool isObjectMethod;
339	const char* name = debug_demangle_symbol(symbol, buffer, kBufferSize,
340		&isObjectMethod);
341	if (name == NULL) {
342		debug_free(buffer);
343		return B_ERROR;
344	}
345
346	kprintf("<%s> %s(", image, name);
347
348	size_t length;
349	int32 type, i = 0;
350	uint32 cookie = 0;
351	while (debug_get_next_demangled_argument(&cookie, symbol, buffer,
352			kBufferSize, &type, &length) == B_OK) {
353		if (i++ > 0)
354			kprintf(", ");
355
356		if (buffer[0])
357			kprintf("%s", buffer);
358		else
359			kprintf("???");
360	}
361
362	debug_free(buffer);
363
364	kprintf(")");
365	return B_OK;
366}
367
368
369#endif	// __x86_64__
370
371
372static void
373print_stack_frame(Thread* thread, addr_t ip, addr_t bp, addr_t nextBp,
374	int32 callIndex, bool demangle)
375{
376	const char* symbol;
377	const char* image;
378	addr_t baseAddress;
379	bool exactMatch;
380	status_t status;
381	addr_t diff;
382
383	diff = nextBp - bp;
384
385	// MSB set = kernel space/user space switch
386	if (diff & ~((addr_t)-1 >> 1))
387		diff = 0;
388
389	status = lookup_symbol(thread, ip, &baseAddress, &symbol, &image,
390		&exactMatch);
391
392	kprintf("%2" B_PRId32 " %0*lx (+%4ld) %0*lx   ", callIndex,
393		B_PRINTF_POINTER_WIDTH, bp, diff, B_PRINTF_POINTER_WIDTH, ip);
394
395	if (status == B_OK) {
396		if (exactMatch && demangle) {
397			status = print_demangled_call(image, symbol,
398				nextBp + sizeof(stack_frame), false, false);
399		}
400
401		if (!exactMatch || !demangle || status != B_OK) {
402			if (symbol != NULL) {
403				kprintf("<%s> %s%s", image, symbol,
404					exactMatch ? "" : " (nearest)");
405			} else
406				kprintf("<%s@%p> <unknown>", image, (void*)baseAddress);
407		}
408
409		kprintf(" + %#04lx\n", ip - baseAddress);
410	} else {
411		VMArea *area = NULL;
412		if (thread != NULL && thread->team != NULL
413			&& thread->team->address_space != NULL) {
414			area = thread->team->address_space->LookupArea(ip);
415		}
416		if (area != NULL) {
417			kprintf("%" B_PRId32 ":%s@%p + %#lx\n", area->id, area->name,
418				(void*)area->Base(), ip - area->Base());
419		} else
420			kprintf("\n");
421	}
422}
423
424
425static void
426print_iframe(iframe* frame)
427{
428	bool isUser = IFRAME_IS_USER(frame);
429
430#ifdef __x86_64__
431	kprintf("%s iframe at %p (end = %p)\n", isUser ? "user" : "kernel", frame,
432		frame + 1);
433
434	kprintf(" rax %#-18lx    rbx %#-18lx    rcx %#lx\n", frame->ax,
435		frame->bx, frame->cx);
436	kprintf(" rdx %#-18lx    rsi %#-18lx    rdi %#lx\n", frame->dx,
437		frame->si, frame->di);
438	kprintf(" rbp %#-18lx     r8 %#-18lx     r9 %#lx\n", frame->bp,
439		frame->r8, frame->r9);
440	kprintf(" r10 %#-18lx    r11 %#-18lx    r12 %#lx\n", frame->r10,
441		frame->r11, frame->r12);
442	kprintf(" r13 %#-18lx    r14 %#-18lx    r15 %#lx\n", frame->r13,
443		frame->r14, frame->r15);
444	kprintf(" rip %#-18lx    rsp %#-18lx rflags %#lx\n", frame->ip,
445		frame->sp, frame->flags);
446#else
447	kprintf("%s iframe at %p (end = %p)\n", isUser ? "user" : "kernel", frame,
448		isUser ? (void*)(frame + 1) : (void*)&frame->user_sp);
449
450	kprintf(" eax %#-10lx    ebx %#-10lx     ecx %#-10lx  edx %#lx\n",
451		frame->ax, frame->bx, frame->cx, frame->dx);
452	kprintf(" esi %#-10lx    edi %#-10lx     ebp %#-10lx  esp %#lx\n",
453		frame->si, frame->di, frame->bp, frame->sp);
454	kprintf(" eip %#-10lx eflags %#-10lx", frame->ip, frame->flags);
455	if (isUser) {
456		// from user space
457		kprintf("user esp %#lx", frame->user_sp);
458	}
459	kprintf("\n");
460#endif
461
462	kprintf(" vector: %#lx, error code: %#lx\n", frame->vector,
463		frame->error_code);
464}
465
466
467static bool
468setup_for_thread(char* arg, Thread** _thread, addr_t* _bp,
469	phys_addr_t* _oldPageDirectory)
470{
471	Thread* thread = NULL;
472
473	if (arg != NULL) {
474		thread_id id = strtoul(arg, NULL, 0);
475		thread = Thread::GetDebug(id);
476		if (thread == NULL) {
477			kprintf("could not find thread %" B_PRId32 "\n", id);
478			return false;
479		}
480
481		if (id != thread_get_current_thread_id()) {
482			// switch to the page directory of the new thread to be
483			// able to follow the stack trace into userland
484			phys_addr_t newPageDirectory = x86_next_page_directory(
485				thread_get_current_thread(), thread);
486
487			if (newPageDirectory != 0) {
488				*_oldPageDirectory = x86_read_cr3();
489				x86_write_cr3(newPageDirectory);
490			}
491
492			if (thread->state == B_THREAD_RUNNING) {
493				// The thread is currently running on another CPU.
494				if (thread->cpu == NULL)
495					return false;
496				arch_debug_registers* registers = debug_get_debug_registers(
497					thread->cpu->cpu_num);
498				if (registers == NULL)
499					return false;
500				*_bp = registers->bp;
501			} else {
502				// Read frame pointer from the thread's stack.
503				*_bp = thread->arch_info.GetFramePointer();
504			}
505		} else
506			thread = NULL;
507	}
508
509	if (thread == NULL) {
510		// if we don't have a thread yet, we want the current one
511		// (ebp has been set by the caller for this case already)
512		thread = thread_get_current_thread();
513	}
514
515	*_thread = thread;
516	return true;
517}
518
519
520static bool
521is_double_fault_stack_address(int32 cpu, addr_t address)
522{
523	size_t size;
524	addr_t bottom = (addr_t)x86_get_double_fault_stack(cpu, &size);
525	return address >= bottom && address < bottom + size;
526}
527
528
529static bool
530is_kernel_stack_address(Thread* thread, addr_t address)
531{
532	// We don't have a thread pointer in the early boot process, but then we are
533	// on the kernel stack for sure.
534	if (thread == NULL)
535		return IS_KERNEL_ADDRESS(address);
536
537	// Also in the early boot process we might have a thread structure, but it
538	// might not have its kernel stack attributes set yet.
539	if (thread->kernel_stack_top == 0)
540		return IS_KERNEL_ADDRESS(address);
541
542	return (address >= thread->kernel_stack_base
543			&& address < thread->kernel_stack_top)
544		|| (thread->cpu != NULL
545			&& is_double_fault_stack_address(thread->cpu->cpu_num, address));
546}
547
548
549static bool
550is_iframe(Thread* thread, addr_t frame)
551{
552	if (!is_kernel_stack_address(thread, frame))
553		return false;
554
555	addr_t previousFrame = *(addr_t*)frame;
556	return ((previousFrame & ~(addr_t)IFRAME_TYPE_MASK) == 0
557		&& previousFrame != 0);
558}
559
560
561static iframe*
562find_previous_iframe(Thread* thread, addr_t frame)
563{
564	// iterate backwards through the stack frames, until we hit an iframe
565	while (is_kernel_stack_address(thread, frame)) {
566		if (is_iframe(thread, frame))
567			return (iframe*)frame;
568
569		frame = *(addr_t*)frame;
570	}
571
572	return NULL;
573}
574
575
576static iframe*
577get_previous_iframe(Thread* thread, iframe* frame)
578{
579	if (frame == NULL)
580		return NULL;
581
582	return find_previous_iframe(thread, frame->bp);
583}
584
585
586static iframe*
587get_current_iframe(Thread* thread)
588{
589	if (thread == thread_get_current_thread())
590		return x86_get_current_iframe();
591
592	// NOTE: This doesn't work, if the thread is running (on another CPU).
593	return find_previous_iframe(thread, thread->arch_info.GetFramePointer());
594}
595
596
597#define CHECK_DEBUG_VARIABLE(_name, _member, _settable) \
598	if (strcmp(variableName, _name) == 0) { \
599		settable = _settable; \
600		return &_member; \
601	}
602
603
604static size_t*
605find_debug_variable(const char* variableName, bool& settable)
606{
607	iframe* frame = get_current_iframe(debug_get_debugged_thread());
608	if (frame == NULL)
609		return NULL;
610
611#ifdef __x86_64__
612	CHECK_DEBUG_VARIABLE("cs", frame->cs, false);
613	CHECK_DEBUG_VARIABLE("ss", frame->ss, false);
614	CHECK_DEBUG_VARIABLE("r15", frame->r15, true);
615	CHECK_DEBUG_VARIABLE("r14", frame->r14, true);
616	CHECK_DEBUG_VARIABLE("r13", frame->r13, true);
617	CHECK_DEBUG_VARIABLE("r12", frame->r12, true);
618	CHECK_DEBUG_VARIABLE("r11", frame->r11, true);
619	CHECK_DEBUG_VARIABLE("r10", frame->r10, true);
620	CHECK_DEBUG_VARIABLE("r9", frame->r9, true);
621	CHECK_DEBUG_VARIABLE("r8", frame->r8, true);
622	CHECK_DEBUG_VARIABLE("rbp", frame->bp, true);
623	CHECK_DEBUG_VARIABLE("rsi", frame->si, true);
624	CHECK_DEBUG_VARIABLE("rdi", frame->di, true);
625	CHECK_DEBUG_VARIABLE("rdx", frame->dx, true);
626	CHECK_DEBUG_VARIABLE("rcx", frame->cx, true);
627	CHECK_DEBUG_VARIABLE("rbx", frame->bx, true);
628	CHECK_DEBUG_VARIABLE("rax", frame->ax, true);
629	CHECK_DEBUG_VARIABLE("rip", frame->ip, true);
630	CHECK_DEBUG_VARIABLE("rflags", frame->flags, true);
631	CHECK_DEBUG_VARIABLE("rsp", frame->sp, true);
632#else
633	CHECK_DEBUG_VARIABLE("gs", frame->gs, false);
634	CHECK_DEBUG_VARIABLE("fs", frame->fs, false);
635	CHECK_DEBUG_VARIABLE("es", frame->es, false);
636	CHECK_DEBUG_VARIABLE("ds", frame->ds, false);
637	CHECK_DEBUG_VARIABLE("cs", frame->cs, false);
638	CHECK_DEBUG_VARIABLE("edi", frame->di, true);
639	CHECK_DEBUG_VARIABLE("esi", frame->si, true);
640	CHECK_DEBUG_VARIABLE("ebp", frame->bp, true);
641	CHECK_DEBUG_VARIABLE("esp", frame->sp, true);
642	CHECK_DEBUG_VARIABLE("ebx", frame->bx, true);
643	CHECK_DEBUG_VARIABLE("edx", frame->dx, true);
644	CHECK_DEBUG_VARIABLE("ecx", frame->cx, true);
645	CHECK_DEBUG_VARIABLE("eax", frame->ax, true);
646	CHECK_DEBUG_VARIABLE("orig_eax", frame->orig_eax, true);
647	CHECK_DEBUG_VARIABLE("orig_edx", frame->orig_edx, true);
648	CHECK_DEBUG_VARIABLE("eip", frame->ip, true);
649	CHECK_DEBUG_VARIABLE("eflags", frame->flags, true);
650
651	if (IFRAME_IS_USER(frame)) {
652		CHECK_DEBUG_VARIABLE("user_esp", frame->user_sp, true);
653		CHECK_DEBUG_VARIABLE("user_ss", frame->user_ss, false);
654	}
655#endif
656
657	return NULL;
658}
659
660
661static int
662stack_trace(int argc, char** argv)
663{
664	static const char* usage = "usage: %s [-d] [ <thread id> ]\n"
665		"Prints a stack trace for the current, respectively the specified\n"
666		"thread.\n"
667		"  -d           -  Disables the demangling of the symbols.\n"
668		"  <thread id>  -  The ID of the thread for which to print the stack\n"
669		"                  trace.\n";
670	bool demangle = true;
671	int32 threadIndex = 1;
672	if (argc > 1 && !strcmp(argv[1], "-d")) {
673		demangle = false;
674		threadIndex++;
675	}
676
677	if (argc > threadIndex + 1
678		|| (argc == 2 && strcmp(argv[1], "--help") == 0)) {
679		kprintf(usage, argv[0]);
680		return 0;
681	}
682
683	addr_t previousLocations[NUM_PREVIOUS_LOCATIONS];
684	Thread* thread = NULL;
685	phys_addr_t oldPageDirectory = 0;
686	addr_t bp = x86_get_stack_frame();
687	int32 num = 0, last = 0;
688
689	if (!setup_for_thread(argc == threadIndex + 1 ? argv[threadIndex] : NULL,
690			&thread, &bp, &oldPageDirectory))
691		return 0;
692
693	DebuggedThreadSetter threadSetter(thread);
694
695	if (thread != NULL) {
696		kprintf("stack trace for thread %" B_PRId32 " \"%s\"\n", thread->id,
697			thread->name);
698
699		kprintf("    kernel stack: %p to %p\n",
700			(void*)thread->kernel_stack_base,
701			(void*)(thread->kernel_stack_top));
702		if (thread->user_stack_base != 0) {
703			kprintf("      user stack: %p to %p\n",
704				(void*)thread->user_stack_base,
705				(void*)(thread->user_stack_base + thread->user_stack_size));
706		}
707	}
708
709	kprintf("%-*s            %-*s   <image>:function + offset\n",
710		B_PRINTF_POINTER_WIDTH, "frame", B_PRINTF_POINTER_WIDTH, "caller");
711
712	bool onKernelStack = true;
713
714	for (int32 callIndex = 0;; callIndex++) {
715		onKernelStack = onKernelStack
716			&& is_kernel_stack_address(thread, bp);
717
718		if (onKernelStack && is_iframe(thread, bp)) {
719			iframe* frame = (iframe*)bp;
720
721			print_iframe(frame);
722			print_stack_frame(thread, frame->ip, bp, frame->bp, callIndex,
723				demangle);
724
725 			bp = frame->bp;
726		} else {
727			addr_t ip, nextBp;
728
729			if (get_next_frame_debugger(bp, &nextBp, &ip) != B_OK) {
730				kprintf("%0*lx -- read fault\n", B_PRINTF_POINTER_WIDTH, bp);
731				break;
732			}
733
734			if (ip == 0 || bp == 0)
735				break;
736
737			print_stack_frame(thread, ip, bp, nextBp, callIndex, demangle);
738			bp = nextBp;
739		}
740
741		if (already_visited(previousLocations, &last, &num, bp)) {
742			kprintf("circular stack frame: %p!\n", (void*)bp);
743			break;
744		}
745		if (bp == 0)
746			break;
747	}
748
749	if (oldPageDirectory != 0) {
750		// switch back to the previous page directory to no cause any troubles
751		x86_write_cr3(oldPageDirectory);
752	}
753
754	return 0;
755}
756
757
758#ifndef __x86_64__
759static void
760print_call(Thread *thread, addr_t eip, addr_t ebp, addr_t nextEbp,
761	int32 argCount)
762{
763	const char *symbol, *image;
764	addr_t baseAddress;
765	bool exactMatch;
766	status_t status;
767	bool demangled = false;
768	int32 *arg = (int32 *)(nextEbp + 8);
769
770	status = lookup_symbol(thread, eip, &baseAddress, &symbol, &image,
771		&exactMatch);
772
773	kprintf("%08lx %08lx   ", ebp, eip);
774
775	if (status == B_OK) {
776		if (symbol != NULL) {
777			if (exactMatch && (argCount == 0 || argCount == -1)) {
778				status = print_demangled_call(image, symbol, (addr_t)arg,
779					argCount == -1, true);
780				if (status == B_OK)
781					demangled = true;
782			}
783			if (!demangled) {
784				kprintf("<%s>:%s%s", image, symbol,
785					exactMatch ? "" : " (nearest)");
786			}
787		} else {
788			kprintf("<%s@%p>:unknown + 0x%04lx", image,
789				(void *)baseAddress, eip - baseAddress);
790		}
791	} else {
792		VMArea *area = NULL;
793		if (thread->team->address_space != NULL)
794			area = thread->team->address_space->LookupArea(eip);
795		if (area != NULL) {
796			kprintf("%ld:%s@%p + %#lx", area->id, area->name,
797				(void *)area->Base(), eip - area->Base());
798		}
799	}
800
801	if (!demangled) {
802		kprintf("(");
803
804		for (int32 i = 0; i < argCount; i++) {
805			if (i > 0)
806				kprintf(", ");
807			kprintf("%#lx", *arg);
808			if (*arg > -0x10000 && *arg < 0x10000)
809				kprintf(" (%ld)", *arg);
810
811			set_debug_argument_variable(i + 1, *(uint32 *)arg);
812			arg++;
813		}
814
815		kprintf(")\n");
816	} else
817		kprintf("\n");
818
819	set_debug_variable("_frame", nextEbp);
820}
821
822
823static int
824show_call(int argc, char **argv)
825{
826	static const char* usage
827		= "usage: %s [ <thread id> ] <call index> [ -<arg count> ]\n"
828		"Prints a function call with parameters of the current, respectively\n"
829		"the specified thread.\n"
830		"  <thread id>   -  The ID of the thread for which to print the call.\n"
831		"  <call index>  -  The index of the call in the stack trace.\n"
832		"  <arg count>   -  The number of call arguments to print (use 'c' to\n"
833		"                   force the C++ demangler to use class methods,\n"
834		"                   use 'd' to disable demangling).\n";
835	if (argc == 2 && strcmp(argv[1], "--help") == 0) {
836		kprintf(usage, argv[0]);
837		return 0;
838	}
839
840	Thread *thread = NULL;
841	phys_addr_t oldPageDirectory = 0;
842	addr_t ebp = x86_get_stack_frame();
843	int32 argCount = 0;
844
845	if (argc >= 2 && argv[argc - 1][0] == '-') {
846		if (argv[argc - 1][1] == 'c')
847			argCount = -1;
848		else if (argv[argc - 1][1] == 'd')
849			argCount = -2;
850		else
851			argCount = strtoul(argv[argc - 1] + 1, NULL, 0);
852
853		if (argCount < -2 || argCount > 16) {
854			kprintf("Invalid argument count \"%ld\".\n", argCount);
855			return 0;
856		}
857		argc--;
858	}
859
860	if (argc < 2 || argc > 3) {
861		kprintf(usage, argv[0]);
862		return 0;
863	}
864
865	if (!setup_for_thread(argc == 3 ? argv[1] : NULL, &thread, &ebp,
866			&oldPageDirectory))
867		return 0;
868
869	DebuggedThreadSetter threadSetter(thread);
870
871	int32 callIndex = strtoul(argv[argc == 3 ? 2 : 1], NULL, 0);
872
873	if (thread != NULL)
874		kprintf("thread %ld, %s\n", thread->id, thread->name);
875
876	bool onKernelStack = true;
877
878	for (int32 index = 0; index <= callIndex; index++) {
879		onKernelStack = onKernelStack
880			&& is_kernel_stack_address(thread, ebp);
881
882		if (onKernelStack && is_iframe(thread, ebp)) {
883			struct iframe *frame = (struct iframe *)ebp;
884
885			if (index == callIndex)
886				print_call(thread, frame->ip, ebp, frame->bp, argCount);
887
888 			ebp = frame->bp;
889		} else {
890			addr_t eip, nextEbp;
891
892			if (get_next_frame_debugger(ebp, &nextEbp, &eip) != B_OK) {
893				kprintf("%08lx -- read fault\n", ebp);
894				break;
895			}
896
897			if (eip == 0 || ebp == 0)
898				break;
899
900			if (index == callIndex)
901				print_call(thread, eip, ebp, nextEbp, argCount);
902
903			ebp = nextEbp;
904		}
905
906		if (ebp == 0)
907			break;
908	}
909
910	if (oldPageDirectory != 0) {
911		// switch back to the previous page directory to not cause any troubles
912		x86_write_cr3(oldPageDirectory);
913	}
914
915	return 0;
916}
917#endif
918
919
920static int
921dump_iframes(int argc, char** argv)
922{
923	static const char* usage = "usage: %s [ <thread id> ]\n"
924		"Prints the iframe stack for the current, respectively the specified\n"
925		"thread.\n"
926		"  <thread id>  -  The ID of the thread for which to print the iframe\n"
927		"                  stack.\n";
928	if (argc == 2 && strcmp(argv[1], "--help") == 0) {
929		kprintf(usage, argv[0]);
930		return 0;
931	}
932
933	Thread* thread = NULL;
934
935	if (argc < 2) {
936		thread = thread_get_current_thread();
937	} else if (argc == 2) {
938		thread_id id = strtoul(argv[1], NULL, 0);
939		thread = Thread::GetDebug(id);
940		if (thread == NULL) {
941			kprintf("could not find thread %" B_PRId32 "\n", id);
942			return 0;
943		}
944	} else if (argc > 2) {
945		kprintf(usage, argv[0]);
946		return 0;
947	}
948
949	if (thread != NULL) {
950		kprintf("iframes for thread %" B_PRId32 " \"%s\"\n", thread->id,
951			thread->name);
952	}
953
954	DebuggedThreadSetter threadSetter(thread);
955
956	iframe* frame = find_previous_iframe(thread, x86_get_stack_frame());
957	while (frame != NULL) {
958		print_iframe(frame);
959		frame = get_previous_iframe(thread, frame);
960	}
961
962	return 0;
963}
964
965
966static bool
967is_calling(Thread* thread, addr_t ip, const char* pattern, addr_t start,
968	addr_t end)
969{
970	if (pattern == NULL)
971		return ip >= start && ip < end;
972
973	if (!IS_KERNEL_ADDRESS(ip))
974		return false;
975
976	const char* symbol;
977	if (lookup_symbol(thread, ip, NULL, &symbol, NULL, NULL) != B_OK)
978		return false;
979
980	return strstr(symbol, pattern);
981}
982
983
984static int
985cmd_in_context(int argc, char** argv)
986{
987	if (argc != 2) {
988		print_debugger_command_usage(argv[0]);
989		return 0;
990	}
991
992	// get the thread ID
993	const char* commandLine = argv[1];
994	char threadIDString[16];
995	if (parse_next_debug_command_argument(&commandLine, threadIDString,
996			sizeof(threadIDString)) != B_OK) {
997		kprintf("Failed to parse thread ID.\n");
998		return 0;
999	}
1000
1001	if (commandLine == NULL) {
1002		print_debugger_command_usage(argv[0]);
1003		return 0;
1004	}
1005
1006	uint64 threadID;
1007	if (!evaluate_debug_expression(threadIDString, &threadID, false))
1008		return 0;
1009
1010	// get the thread
1011	Thread* thread = Thread::GetDebug(threadID);
1012	if (thread == NULL) {
1013		kprintf("Could not find thread with ID \"%s\".\n", threadIDString);
1014		return 0;
1015	}
1016
1017	// switch the page directory, if necessary
1018	phys_addr_t oldPageDirectory = 0;
1019	if (thread != thread_get_current_thread()) {
1020		phys_addr_t newPageDirectory = x86_next_page_directory(
1021			thread_get_current_thread(), thread);
1022
1023		if (newPageDirectory != 0) {
1024			oldPageDirectory = x86_read_cr3();
1025			x86_write_cr3(newPageDirectory);
1026		}
1027	}
1028
1029	// execute the command
1030	{
1031		DebuggedThreadSetter threadSetter(thread);
1032		evaluate_debug_command(commandLine);
1033	}
1034
1035	// reset the page directory
1036	if (oldPageDirectory)
1037		x86_write_cr3(oldPageDirectory);
1038
1039	return 0;
1040}
1041
1042
1043//	#pragma mark -
1044
1045
1046void
1047arch_debug_save_registers(arch_debug_registers* registers)
1048{
1049	// get the caller's frame pointer
1050	stack_frame* frame = (stack_frame*)x86_get_stack_frame();
1051	registers->bp = (addr_t)frame->previous;
1052}
1053
1054
1055void
1056arch_debug_stack_trace(void)
1057{
1058	stack_trace(0, NULL);
1059}
1060
1061
1062bool
1063arch_debug_contains_call(Thread* thread, const char* symbol, addr_t start,
1064	addr_t end)
1065{
1066	DebuggedThreadSetter threadSetter(thread);
1067
1068	addr_t bp;
1069	if (thread == thread_get_current_thread())
1070		bp = x86_get_stack_frame();
1071	else {
1072		if (thread->state == B_THREAD_RUNNING) {
1073			// The thread is currently running on another CPU.
1074			if (thread->cpu == NULL)
1075				return false;
1076			arch_debug_registers* registers = debug_get_debug_registers(
1077				thread->cpu->cpu_num);
1078			if (registers == NULL)
1079				return false;
1080			bp = registers->bp;
1081		} else {
1082			// thread not running
1083			bp = thread->arch_info.GetFramePointer();
1084		}
1085	}
1086
1087	for (;;) {
1088		if (!is_kernel_stack_address(thread, bp))
1089			break;
1090
1091		if (is_iframe(thread, bp)) {
1092			iframe* frame = (iframe*)bp;
1093
1094			if (is_calling(thread, frame->ip, symbol, start, end))
1095				return true;
1096
1097 			bp = frame->bp;
1098		} else {
1099			addr_t ip, nextBp;
1100
1101			if (get_next_frame_no_debugger(bp, &nextBp, &ip, true,
1102					thread) != B_OK
1103				|| ip == 0 || bp == 0)
1104				break;
1105
1106			if (is_calling(thread, ip, symbol, start, end))
1107				return true;
1108
1109			bp = nextBp;
1110		}
1111
1112		if (bp == 0)
1113			break;
1114	}
1115
1116	return false;
1117}
1118
1119
1120void*
1121arch_debug_get_caller(void)
1122{
1123	stack_frame* frame = (stack_frame*)x86_get_stack_frame();
1124	return (void*)frame->previous->return_address;
1125}
1126
1127
1128/*!	Captures a stack trace (the return addresses) of the current thread.
1129	\param returnAddresses The array the return address shall be written to.
1130	\param maxCount The maximum number of return addresses to be captured.
1131	\param skipIframes The number of interrupt frames that shall be skipped. If
1132		greater than 0, \a skipFrames is ignored.
1133	\param skipFrames The number of stack frames that shall be skipped.
1134	\param flags A combination of one or two of the following:
1135		- \c STACK_TRACE_KERNEL: Capture kernel return addresses.
1136		- \c STACK_TRACE_USER: Capture user return addresses.
1137	\return The number of return addresses written to the given array.
1138*/
1139int32
1140arch_debug_get_stack_trace(addr_t* returnAddresses, int32 maxCount,
1141	int32 skipIframes, int32 skipFrames, uint32 flags)
1142{
1143	// Keep skipping normal stack frames until we've skipped the iframes we're
1144	// supposed to skip.
1145	if (skipIframes > 0)
1146		skipFrames = INT_MAX;
1147
1148	Thread* thread = thread_get_current_thread();
1149	int32 count = 0;
1150	addr_t bp = x86_get_stack_frame();
1151	bool onKernelStack = true;
1152
1153	while (bp != 0 && count < maxCount) {
1154		onKernelStack = onKernelStack
1155			&& is_kernel_stack_address(thread, bp);
1156		if (!onKernelStack && (flags & STACK_TRACE_USER) == 0)
1157			break;
1158
1159		addr_t ip;
1160		addr_t nextBp;
1161
1162		if (onKernelStack && is_iframe(thread, bp)) {
1163			iframe* frame = (iframe*)bp;
1164			ip = frame->ip;
1165			nextBp = frame->bp;
1166
1167			if (skipIframes > 0) {
1168				if (--skipIframes == 0)
1169					skipFrames = 0;
1170			}
1171		} else {
1172			if (get_next_frame_no_debugger(bp, &nextBp, &ip,
1173					onKernelStack, thread) != B_OK) {
1174				break;
1175			}
1176		}
1177
1178		if (ip == 0)
1179			break;
1180
1181		if (skipFrames <= 0
1182			&& ((flags & STACK_TRACE_KERNEL) != 0 || onKernelStack)) {
1183			returnAddresses[count++] = ip;
1184		} else
1185			skipFrames--;
1186
1187		bp = nextBp;
1188	}
1189
1190	return count;
1191}
1192
1193
1194/*!	Returns the program counter of the currently debugged (respectively this)
1195	thread where the innermost interrupts happened. \a _isSyscall, if specified,
1196	is set to whether this interrupt frame was created by a syscall. Returns
1197	\c NULL, if there's no such frame or a problem occurred retrieving it;
1198	\a _isSyscall won't be set in this case.
1199*/
1200void*
1201arch_debug_get_interrupt_pc(bool* _isSyscall)
1202{
1203	iframe* frame = get_current_iframe(debug_get_debugged_thread());
1204	if (frame == NULL)
1205		return NULL;
1206
1207	if (_isSyscall != NULL)
1208		*_isSyscall = frame->type == IFRAME_TYPE_SYSCALL;
1209
1210	return (void*)(addr_t)frame->ip;
1211}
1212
1213
1214/*!	Sets the current thread to \c NULL.
1215	Invoked in the kernel debugger only.
1216*/
1217void
1218arch_debug_unset_current_thread(void)
1219{
1220	// Can't just write 0 to the GS base, that will cause the read from %gs:0
1221	// to fault. Instead point it at a NULL pointer, %gs:0 will get this value.
1222	static Thread* unsetThread = NULL;
1223#ifdef __x86_64__
1224	x86_write_msr(IA32_MSR_GS_BASE, (addr_t)&unsetThread);
1225#else
1226	asm volatile("mov %0, %%gs:0" : : "r" (unsetThread) : "memory");
1227#endif
1228}
1229
1230
1231bool
1232arch_is_debug_variable_defined(const char* variableName)
1233{
1234	bool settable;
1235	return find_debug_variable(variableName, settable);
1236}
1237
1238
1239status_t
1240arch_set_debug_variable(const char* variableName, uint64 value)
1241{
1242	bool settable;
1243	size_t* variable = find_debug_variable(variableName, settable);
1244	if (variable == NULL)
1245		return B_ENTRY_NOT_FOUND;
1246
1247	if (!settable)
1248		return B_NOT_ALLOWED;
1249
1250	*variable = (size_t)value;
1251	return B_OK;
1252}
1253
1254
1255status_t
1256arch_get_debug_variable(const char* variableName, uint64* value)
1257{
1258	bool settable;
1259	size_t* variable = find_debug_variable(variableName, settable);
1260	if (variable == NULL)
1261		return B_ENTRY_NOT_FOUND;
1262
1263	*value = *variable;
1264	return B_OK;
1265}
1266
1267
1268struct gdb_register {
1269	int32 type;
1270	uint64 value;
1271};
1272
1273
1274/*!	Writes the contents of the CPU registers at some fixed outer stack frame or
1275	iframe into the given buffer in the format expected by gdb.
1276
1277	This function is called in response to gdb's 'g' command.
1278
1279	\param buffer The buffer to write the registers to.
1280	\param bufferSize The size of \a buffer in bytes.
1281	\return When successful, the number of bytes written to \a buffer, or a
1282		negative error code on error.
1283*/
1284ssize_t
1285arch_debug_gdb_get_registers(char* buffer, size_t bufferSize)
1286{
1287	iframe* frame = get_current_iframe(debug_get_debugged_thread());
1288	if (frame == NULL)
1289		return B_NOT_SUPPORTED;
1290
1291#ifdef __x86_64__
1292	// For x86_64 the register order is:
1293	//
1294	//    rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp,
1295	//    r8, r9, r10, r11, r12, r13, r14, r15,
1296	//    rip, rflags, cs, ss, ds, es, fs, gs
1297	//
1298	// Annoyingly, GDB wants all the registers as 64-bit values, but then
1299	// RFLAGS and the segment registers as 32-bit values, hence the need for
1300	// the type information.
1301	static const int32 kRegisterCount = 24;
1302	gdb_register registers[kRegisterCount] = {
1303		{ B_UINT64_TYPE, frame->ax },  { B_UINT64_TYPE, frame->bx },
1304		{ B_UINT64_TYPE, frame->cx },  { B_UINT64_TYPE, frame->dx },
1305		{ B_UINT64_TYPE, frame->si },  { B_UINT64_TYPE, frame->di },
1306		{ B_UINT64_TYPE, frame->bp },  { B_UINT64_TYPE, frame->sp },
1307		{ B_UINT64_TYPE, frame->r8 },  { B_UINT64_TYPE, frame->r9 },
1308		{ B_UINT64_TYPE, frame->r10 }, { B_UINT64_TYPE, frame->r11 },
1309		{ B_UINT64_TYPE, frame->r12 }, { B_UINT64_TYPE, frame->r13 },
1310		{ B_UINT64_TYPE, frame->r14 }, { B_UINT64_TYPE, frame->r15 },
1311		{ B_UINT64_TYPE, frame->ip },  { B_UINT32_TYPE, frame->flags },
1312		{ B_UINT32_TYPE, frame->cs },  { B_UINT32_TYPE, frame->ss },
1313		{ B_UINT32_TYPE, 0 }, { B_UINT32_TYPE, 0 },
1314		{ B_UINT32_TYPE, 0 }, { B_UINT32_TYPE, 0 },
1315	};
1316#else
1317	// For x86 the register order is:
1318	//
1319	//    eax, ecx, edx, ebx,
1320	//    esp, ebp, esi, edi,
1321	//    eip, eflags,
1322	//    cs, ss, ds, es, fs, gs
1323	//
1324	// Note that even though the segment descriptors are actually 16 bits wide,
1325	// gdb requires them as 32 bit integers.
1326	static const int32 kRegisterCount = 16;
1327	gdb_register registers[kRegisterCount] = {
1328		{ B_UINT32_TYPE, frame->ax }, { B_UINT32_TYPE, frame->cx },
1329		{ B_UINT32_TYPE, frame->dx }, { B_UINT32_TYPE, frame->bx },
1330		{ B_UINT32_TYPE, frame->sp }, { B_UINT32_TYPE, frame->bp },
1331		{ B_UINT32_TYPE, frame->si }, { B_UINT32_TYPE, frame->di },
1332		{ B_UINT32_TYPE, frame->ip }, { B_UINT32_TYPE, frame->flags },
1333		{ B_UINT32_TYPE, frame->cs }, { B_UINT32_TYPE, frame->ds },
1334			// assume ss == ds
1335		{ B_UINT32_TYPE, frame->ds }, { B_UINT32_TYPE, frame->es },
1336		{ B_UINT32_TYPE, frame->fs }, { B_UINT32_TYPE, frame->gs },
1337	};
1338#endif
1339
1340	const char* const bufferStart = buffer;
1341
1342	for (int32 i = 0; i < kRegisterCount; i++) {
1343		// For some reason gdb wants the register dump in *big endian* format.
1344		int result = 0;
1345		switch (registers[i].type) {
1346			case B_UINT64_TYPE:
1347				result = snprintf(buffer, bufferSize, "%016" B_PRIx64,
1348					(uint64)B_HOST_TO_BENDIAN_INT64(registers[i].value));
1349				break;
1350			case B_UINT32_TYPE:
1351				result = snprintf(buffer, bufferSize, "%08" B_PRIx32,
1352					(uint32)B_HOST_TO_BENDIAN_INT32((uint32)registers[i].value));
1353				break;
1354		}
1355		if (result >= (int)bufferSize)
1356			return B_BUFFER_OVERFLOW;
1357
1358		buffer += result;
1359		bufferSize -= result;
1360	}
1361
1362	return buffer - bufferStart;
1363}
1364
1365
1366status_t
1367arch_debug_init(kernel_args* args)
1368{
1369	// at this stage, the debugger command system is alive
1370
1371	add_debugger_command("where", &stack_trace, "Same as \"sc\"");
1372	add_debugger_command("bt", &stack_trace, "Same as \"sc\" (as in gdb)");
1373	add_debugger_command("sc", &stack_trace,
1374		"Stack crawl for current thread (or any other)");
1375	add_debugger_command("iframe", &dump_iframes,
1376		"Dump iframes for the specified thread");
1377#ifndef __x86_64__
1378	add_debugger_command("call", &show_call, "Show call with arguments");
1379#endif
1380	add_debugger_command_etc("in_context", &cmd_in_context,
1381		"Executes a command in the context of a given thread",
1382		"<thread ID> <command> ...\n"
1383		"Executes a command in the context of a given thread.\n",
1384		B_KDEBUG_DONT_PARSE_ARGUMENTS);
1385
1386	return B_NO_ERROR;
1387}
1388
1389