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