Index: HelenOS.config
===================================================================
--- HelenOS.config	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ HelenOS.config	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -498,4 +498,6 @@
 @ "1152x720"
 @ "1152x864"
+@ "1280x720"
+@ "1280x800"
 @ "1280x960"
 @ "1280x1024"
@@ -544,2 +546,4 @@
 ! CONFIG_BAREBONE (n/y)
 
+% Line debugging information
+! [CONFIG_STRIP_BINARIES!=y] CONFIG_LINE_DEBUG (n/y)
Index: boot/Makefile.build
===================================================================
--- boot/Makefile.build	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/Makefile.build	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -61,4 +61,11 @@
 	GCC_CFLAGS += -Werror
 	ICC_CFLAGS += -Werror
+endif
+
+ifeq ($(CONFIG_LINE_DEBUG),y)
+	GCC_CFLAGS += -g
+	ICC_CFLAGS += -g
+	SUNCC_CFLAGS += -g
+	CLANG_CFLAGS += -g
 endif
 
Index: boot/arch/arm32/Makefile.inc
===================================================================
--- boot/arch/arm32/Makefile.inc	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/arch/arm32/Makefile.inc	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -54,4 +54,5 @@
 	$(COMPS_C) \
 	genarch/src/division.c \
+	generic/src/memstr.c \
 	generic/src/printf_core.c \
 	generic/src/vprintf.c \
Index: boot/arch/arm32/src/asm.S
===================================================================
--- boot/arch/arm32/src/asm.S	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/arch/arm32/src/asm.S	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -35,5 +35,4 @@
 .global boot_stack
 .global halt
-.global memcpy
 .global jump_to_kernel
 
@@ -55,63 +54,4 @@
 	b halt
 
-memcpy:
-	add r3, r1, #3
-	bic r3, r3, #3
-	cmp r1, r3
-	stmdb sp!, {r4, r5, lr}
-	mov r5, r0
-	beq 4f
-	
-	1:
-		cmp r2, #0
-		movne ip, #0
-		beq 3f
-	
-	2:
-		ldrb r3, [ip, r1]
-		strb r3, [ip, r0]
-		add ip, ip, #1
-		cmp ip, r2
-		bne 2b
-	
-	3:
-		mov r0, r5
-		ldmia sp!, {r4, r5, pc}
-	
-	4:
-		add r3, r0, #3
-		bic r3, r3, #3
-		cmp r0, r3
-		bne 1b
-		movs r4, r2, lsr #2
-		moveq lr, r4
-		beq 6f
-		mov lr, #0
-		mov ip, lr
-	
-	5:
-		ldr r3, [ip, r1]
-		add lr, lr, #1
-		cmp lr, r4
-		str r3, [ip, r0]
-		add ip, ip, #4
-		bne 5b
-	
-	6:
-		ands r4, r2, #3
-		beq 3b
-		mov r3, lr, lsl #2
-		add r0, r3, r0
-		add ip, r3, r1
-		mov r2, #0
-	
-	7:
-		ldrb r3, [r2, ip]
-		strb r3, [r2, r0]
-		add r2, r2, #1
-		cmp r2, r4
-		bne 7b
-		b 3b
-
 jump_to_kernel:
 	#
Index: boot/arch/ia64/Makefile.inc
===================================================================
--- boot/arch/ia64/Makefile.inc	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/arch/ia64/Makefile.inc	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -49,4 +49,5 @@
 	genarch/src/division.c \
 	generic/src/balloc.c \
+	generic/src/memstr.c \
 	generic/src/printf_core.c \
 	generic/src/vprintf.c \
Index: boot/arch/ia64/src/asm.S
===================================================================
--- boot/arch/ia64/src/asm.S	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/arch/ia64/src/asm.S	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -1,5 +1,5 @@
 #
 # Copyright (c) 2006 Martin Decky
-# Copyright (c) 2006 Jakub Jermar 
+# Copyright (c) 2006 Jakub Jermar
 # All rights reserved.
 #
@@ -39,76 +39,4 @@
 	br halt
 
-memcpy:
-	alloc loc0 = ar.pfs, 3, 1, 0, 0
-
-	adds r14 = 7, in1
-	mov r2 = ar.lc
-	mov r8 = in0 ;;
-	and r14 = -8, r14 ;;
-	cmp.ne p6, p7 = r14, in1
-(p7)	br.cond.dpnt 3f ;;
-0:
-	cmp.ne p6, p7 = 0, in2
-(p7)	br.cond.dpnt 2f ;;
-(p6)	adds r14 = -1, in2
-(p6)	mov r16 = r0
-(p6)	mov r17 = r0 ;;
-(p6)	mov ar.lc = r14
-1:
-	add r14 = r16, in1 
-	add r15 = r16, in0
-	adds r17 = 1, r17 ;;
-	ld1 r14 = [r14]
-	mov r16 = r17 ;;
-	st1 [r15] = r14
-	br.cloop.sptk.few 1b ;;
-2:
-	mov ar.lc = r2
-	mov ar.pfs = loc0
-	br.ret.sptk.many rp
-3:
-	adds r14 = 7, in0 ;;
-	and r14 = -8, r14 ;;
-	cmp.eq p6, p7 = r14, in0
-(p7)	br.cond.dptk 0b
-	shr.u r18 = in2, 3 ;;
-	cmp.ne p6, p7 = 0, r18
-(p7)	br.cond.dpnt 5f	;;
-(p6)	adds r14 = -1, r18
-(p6)	mov r16 = r0
-(p6)	mov r17 = r0 ;;
-(p6)	mov ar.lc = r14
-4:
-	shladd r14 = r16, 3, r0
-	adds r16 = 1, r17 ;;
-	add r15 = in1, r14
-	add r14 = in0, r14
-	mov r17 = r16 ;;
-	ld8 r15 = [r15] ;;
-	st8 [r14] = r15
-	br.cloop.sptk.few 4b
-5:
-	and r15 = 7, in2
-	shladd r14 = r18, 3, r0
-	mov r16 = r0
-	mov r18 = r0 ;;
-	cmp.eq p6, p7 = 0, r15
-	add in0 = r14, in0
-	adds r15 = -1, r15
-	add r17 = r14, in1 
-(p6)	br.cond.dpnt 2b ;;
-	mov ar.lc = r15
-6:
-	add r14 = r16, r17
-	add r15 = r16, in0
-	adds r16 = 1, r18 ;;
-	ld1 r14 = [r14]
-	mov r18 = r16 ;;
-	st1 [r15] = r14
-	br.cloop.sptk.few 6b ;;
-	mov ar.lc = r2
-	mov ar.pfs = loc0
-	br.ret.sptk.many rp
-
 jump_to_kernel:
 	alloc loc0 = ar.pfs, 1, 1, 0, 0
Index: boot/arch/mips32/Makefile.inc
===================================================================
--- boot/arch/mips32/Makefile.inc	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/arch/mips32/Makefile.inc	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -61,4 +61,5 @@
 	genarch/src/division.c \
 	genarch/src/multiplication.c \
+	generic/src/memstr.c \
 	generic/src/printf_core.c \
 	generic/src/vprintf.c \
Index: boot/arch/mips32/src/asm.S
===================================================================
--- boot/arch/mips32/src/asm.S	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/arch/mips32/src/asm.S	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -36,5 +36,4 @@
 .global start
 .global halt
-.global memcpy
 .global jump_to_kernel
 
@@ -127,70 +126,4 @@
 	nop
 
-memcpy:
-	addiu $v0, $a1, 3
-	li $v1, -4
-	and $v0, $v0, $v1
-	beq $a1, $v0, 3f
-	move $t0, $a0
-	move $t2, $a0
-	
-	0:
-		beq $a2, $zero, 2f
-		move $a3, $zero
-	
-	1:
-		addu $v0, $a1, $a3
-		lbu $a0, 0($v0)
-		addu $v1, $t0, $a3
-		addiu $a3, $a3, 1
-		bne $a3, $a2, 1b
-		sb $a0, 0($v1)
-	
-	2:
-		jr $ra
-		move $v0, $t2
-	
-	3:
-		addiu $v0, $a0, 3
-		and $v0, $v0, $v1
-		bne $a0, $v0, 0b
-		srl $t1, $a2, 2
-		
-		beq $t1, $zero, 5f
-		move $a3, $zero
-		
-		move $a3, $zero
-		move $a0, $zero
-	
-	4:
-		addu $v0, $a1, $a0
-		lw $v1, 0($v0)
-		addiu $a3, $a3, 1
-		addu $v0, $t0, $a0
-		sw $v1, 0($v0)
-		bne $a3, $t1, 4b
-		addiu $a0, $a0, 4
-	
-	5:
-		andi $a2, $a2, 0x3
-		beq $a2, $zero, 2b
-		nop
-		
-		sll $v0, $a3, 2
-		addu $t1, $v0, $t0
-		move $a3, $zero
-		addu $t0, $v0, $a1
-	
-	6:
-		addu $v0, $t0, $a3
-		lbu $a0, 0($v0)
-		addu $v1, $t1, $a3
-		addiu $a3, $a3, 1
-		bne $a3, $a2, 6b
-		sb $a0, 0($v1)
-		
-		jr $ra
-		move $v0, $t2
-
 jump_to_kernel:
 	#
Index: boot/arch/ppc32/Makefile.inc
===================================================================
--- boot/arch/ppc32/Makefile.inc	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/arch/ppc32/Makefile.inc	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -56,4 +56,5 @@
 	genarch/src/multiplication.c \
 	generic/src/balloc.c \
+	generic/src/memstr.c \
 	generic/src/printf_core.c \
 	generic/src/vprintf.c \
Index: boot/arch/ppc32/src/asm.S
===================================================================
--- boot/arch/ppc32/src/asm.S	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/arch/ppc32/src/asm.S	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -60,5 +60,4 @@
 .global start
 .global halt
-.global memcpy
 .global jump_to_kernel
 .global real_mode
@@ -78,60 +77,4 @@
 halt:
 	b halt
-
-memcpy:
-	srwi. r7, r5, 3
-	addi r6, r3, -4
-	addi r4, r4, -4
-	beq 2f
-	
-	andi. r0, r6, 3
-	mtctr r7
-	bne 5f
-	
-	1:
-		lwz r7, 4(r4)
-		lwzu r8, 8(r4)
-		stw r7, 4(r6)
-		stwu r8, 8(r6)
-		bdnz 1b
-		
-		andi. r5, r5, 7
-	
-	2:
-		cmplwi 0, r5, 4
-		blt 3f
-		
-		lwzu r0, 4(r4)
-		addi r5, r5, -4
-		stwu r0, 4(r6)
-	
-	3:
-		cmpwi 0, r5, 0
-		beqlr
-		mtctr r5
-		addi r4, r4, 3
-		addi r6, r6, 3
-	
-	4:
-		lbzu r0, 1(r4)
-		stbu r0, 1(r6)
-		bdnz 4b
-		blr
-	
-	5:
-		subfic r0, r0, 4
-		mtctr r0
-	
-	6:
-		lbz r7, 4(r4)
-		addi r4, r4, 1
-		stb r7, 4(r6)
-		addi r6, r6, 1
-		bdnz 6b
-		subf r5, r0, r5
-		rlwinm. r7, r5, 32-3, 3, 31
-		beq 2b
-		mtctr r7
-		b 1b
 
 jump_to_kernel:
Index: boot/arch/sparc64/Makefile.inc
===================================================================
--- boot/arch/sparc64/Makefile.inc	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/arch/sparc64/Makefile.inc	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -54,4 +54,5 @@
 	genarch/src/ofw_tree.c \
 	generic/src/balloc.c \
+	generic/src/memstr.c \
 	generic/src/printf_core.c \
 	generic/src/vprintf.c \
Index: boot/arch/sparc64/src/asm.S
===================================================================
--- boot/arch/sparc64/src/asm.S	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ boot/arch/sparc64/src/asm.S	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -42,5 +42,4 @@
 .global start
 .global halt
-.global memcpy
 .global jump_to_kernel
 
@@ -98,73 +97,4 @@
 	ba %xcc, halt
 	nop
-
-memcpy:
-	! Save dst
-	
-	mov %o0, %o3
-	add %o1, 7, %g1
-	and %g1, -8, %g1
-	cmp %o1, %g1
-	be,pn %xcc, 3f
-	add %o0, 7, %g1
-	mov 0, %g3
-	
-	0:
-		brz,pn %o2, 2f
-		mov 0, %g2
-	
-	1:
-		ldub [%g3 + %o1], %g1
-		add %g2, 1, %g2
-		cmp %o2, %g2
-		stb %g1, [%g3 + %o0]
-		bne,pt %xcc, 1b
-		mov %g2, %g3
-	
-	2:
-		! Exit point
-		
-		jmp %o7 + 8
-		mov %o3, %o0
-	
-	3:
-		and %g1, -8, %g1
-		cmp %o0, %g1
-		bne,pt %xcc, 0b
-		mov 0, %g3
-		srlx %o2, 3, %g4
-		brz,pn %g4, 5f
-		mov 0, %g5
-	
-	4:
-		sllx %g3, 3, %g2
-		add %g5, 1, %g3
-		ldx [%o1 + %g2], %g1
-		mov %g3, %g5
-		cmp %g4, %g3
-		bne,pt %xcc, 4b
-		stx %g1, [%o0 + %g2]
-	
-	5:
-		and %o2, 7, %o2
-		brz,pn %o2, 2b
-		sllx %g4, 3, %g1
-		mov 0, %g2
-		add %g1, %o0, %o0
-		add %g1, %o1, %g4
-		mov 0, %g3
-	
-	6:
-		ldub [%g2 + %g4], %g1
-		stb %g1, [%g2 + %o0]
-		add %g3, 1, %g2
-		cmp %o2, %g2
-		bne,pt %xcc, 6b
-		mov %g2, %g3
-	
-	! Exit point
-	
-	jmp %o7 + 8
-	mov %o3, %o0
 
 jump_to_kernel:
Index: boot/generic/src/memstr.c
===================================================================
--- boot/generic/src/memstr.c	(revision 571addd173f588601486722216ec77880b28e1da)
+++ boot/generic/src/memstr.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <memstr.h>
+#include <typedefs.h>
+
+/** Copy block of memory.
+ *
+ * Copy cnt bytes from src address to dst address.The source and destination
+ * memory areas cannot overlap.
+ *
+ * @param src		Source address to copy from.
+ * @param dst		Destination address to copy to.
+ * @param cnt		Number of bytes to copy.
+ *
+ * @return		Destination address.
+ */
+void *memcpy(void *dst, const void *src, size_t cnt)
+{
+	size_t i;
+
+	for (i = 0; i < cnt; i++)
+		((uint8_t *) dst)[i] = ((uint8_t *) src)[i];
+
+	return dst;
+}
+
+/** @}
+ */
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/Makefile	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -120,4 +120,11 @@
 ifeq ($(CONFIG_LTO),y)
 	GCC_CFLAGS += -flto
+endif
+
+ifeq ($(CONFIG_LINE_DEBUG),y)
+	GCC_CFLAGS += -g
+	ICC_CFLAGS += -g
+	SUNCC_CFLAGS += -g
+	CLANG_CFLAGS += -g
 endif
 
@@ -401,5 +408,9 @@
 
 $(DISASM): $(RAW)
+ifeq ($(CONFIG_LINE_DEBUG),y)
+	$(OBJDUMP) -d -S $< > $@
+else
 	$(OBJDUMP) -d $< > $@
+endif
 
 $(RAW): $(LINK) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(SYMTAB_OBJECTS)
Index: kernel/arch/abs32le/src/debug/stacktrace.c
===================================================================
--- kernel/arch/abs32le/src/debug/stacktrace.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/abs32le/src/debug/stacktrace.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -37,30 +37,30 @@
 #include <typedefs.h>
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return true;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return true;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
 	return true;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return true;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return true;
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
 	return true;
Index: kernel/arch/amd64/_link.ld.in
===================================================================
--- kernel/arch/amd64/_link.ld.in	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/amd64/_link.ld.in	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -53,4 +53,17 @@
 	}
 	
+#ifdef CONFIG_LINE_DEBUG
+	.comment 0 : { *(.comment); }
+	.debug_abbrev 0 : { *(.debug_abbrev); }
+	.debug_aranges 0 : { *(.debug_aranges); }
+	.debug_info 0 : { *(.debug_info); }
+	.debug_line 0 : { *(.debug_line); }
+	.debug_loc 0 : { *(.debug_loc); }
+	.debug_pubnames 0 : { *(.debug_pubnames); }
+	.debug_pubtypes 0 : { *(.debug_pubtypes); }
+	.debug_ranges 0 : { *(.debug_ranges); }
+	.debug_str 0 : { *(.debug_str); }
+#endif
+	
 	/DISCARD/ : {
 		*(*);
Index: kernel/arch/amd64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/amd64/src/debug/stacktrace.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/amd64/src/debug/stacktrace.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -40,12 +40,12 @@
 #define FRAME_OFFSET_RA       1
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	uint64_t *stack = (void *) fp;
+	uint64_t *stack = (void *) ctx->fp;
 	*prev = stack[FRAME_OFFSET_FP_PREV];
 	
@@ -53,7 +53,7 @@
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	uint64_t *stack = (void *) fp;
+	uint64_t *stack = (void *) ctx->fp;
 	*ra = stack[FRAME_OFFSET_RA];
 	
@@ -61,19 +61,19 @@
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return !copy_from_uspace((void *) prev,
-	    (uint64_t *) fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
+	    (uint64_t *) ctx->fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	return !copy_from_uspace((void *) ra, (uint64_t *) fp + FRAME_OFFSET_RA,
-	    sizeof(*ra));
+	return !copy_from_uspace((void *) ra,
+	    (uint64_t *) ctx->fp + FRAME_OFFSET_RA, sizeof(*ra));
 }
 
Index: kernel/arch/arm32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/arm32/src/debug/stacktrace.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/arm32/src/debug/stacktrace.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -40,12 +40,12 @@
 #define FRAME_OFFSET_RA		-1
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	uint32_t *stack = (void *) fp;
+	uint32_t *stack = (void *) ctx->fp;
 
 	*prev = stack[FRAME_OFFSET_FP_PREV];
@@ -53,7 +53,7 @@
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	uint32_t *stack = (void *) fp;
+	uint32_t *stack = (void *) ctx->fp;
 
 	*ra = stack[FRAME_OFFSET_RA];
@@ -61,19 +61,19 @@
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return !copy_from_uspace((void *) prev,
-	    (uint32_t *) fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	return !copy_from_uspace((void *) ra, (uint32_t *) fp + FRAME_OFFSET_RA,
-	    sizeof(*ra));
+	return !copy_from_uspace((void *) ra,
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_RA, sizeof(*ra));
 }
 
Index: kernel/arch/ia32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia32/src/debug/stacktrace.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/ia32/src/debug/stacktrace.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -40,38 +40,38 @@
 #define FRAME_OFFSET_RA		1
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	uint32_t *stack = (void *) fp;
+	uint32_t *stack = (void *) ctx->fp;
 	*prev = stack[FRAME_OFFSET_FP_PREV];
 	return true;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	uint32_t *stack = (void *) fp;
+	uint32_t *stack = (void *) ctx->fp;
 	*ra = stack[FRAME_OFFSET_RA];
 	return true;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return !copy_from_uspace((void *) prev,
-	    (uint32_t *) fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	return !copy_from_uspace((void *) ra, (uint32_t *) fp + FRAME_OFFSET_RA,
-	    sizeof(*ra));
+	return !copy_from_uspace((void *) ra,
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_RA, sizeof(*ra));
 }
 
Index: kernel/arch/ia32/src/mm/frame.c
===================================================================
--- kernel/arch/ia32/src/mm/frame.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/ia32/src/mm/frame.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -131,7 +131,14 @@
 			if (last_frame < ALIGN_UP(new_base + new_size, FRAME_SIZE))
 				last_frame = ALIGN_UP(new_base + new_size, FRAME_SIZE);
-		}
-		
-		if (e820table[i].type == MEMMAP_MEMORY_RESERVED) {
+		} else if ((e820table[i].type == MEMMAP_MEMORY_ACPI) ||
+		    (e820table[i].type == MEMMAP_MEMORY_NVS)) {
+			/* To be safe, make the firmware zone possibly larger */
+			uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE);
+			uint64_t new_size = ALIGN_UP(size + (base - new_base),
+			    FRAME_SIZE);
+			
+			zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0,
+			    ZONE_FIRMWARE);
+		} else {
 			/* To be safe, make the reserved zone possibly larger */
 			uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE);
@@ -141,14 +148,4 @@
 			zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0,
 			    ZONE_RESERVED);
-		}
-		
-		if (e820table[i].type == MEMMAP_MEMORY_ACPI) {
-			/* To be safe, make the firmware zone possibly larger */
-			uint64_t new_base = ALIGN_DOWN(base, FRAME_SIZE);
-			uint64_t new_size = ALIGN_UP(size + (base - new_base),
-			    FRAME_SIZE);
-			
-			zone_create(ADDR2PFN(new_base), SIZE2FRAMES(new_size), 0,
-			    ZONE_FIRMWARE);
 		}
 	}
@@ -203,5 +200,5 @@
 #ifdef CONFIG_SMP
 		/* Reserve AP real mode bootstrap memory */
-		frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH, 
+		frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH,
 		    (hardcoded_unmapped_ktext_size +
 		    hardcoded_unmapped_kdata_size) >> FRAME_WIDTH);
Index: kernel/arch/ia64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia64/src/debug/stacktrace.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/ia64/src/debug/stacktrace.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -37,30 +37,30 @@
 #include <typedefs.h>
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return false;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return false;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
 	return false;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return false;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return false;
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
 	return false;
Index: kernel/arch/mips32/include/debugger.h
===================================================================
--- kernel/arch/mips32/include/debugger.h	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/mips32/include/debugger.h	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -68,4 +68,6 @@
 extern bpinfo_t breakpoints[BKPOINTS_MAX];
 
+extern bool is_jump(unative_t);
+
 extern void debugger_init(void);
 extern void debugger_bpoint(istate_t *);
Index: kernel/arch/mips32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/mips32/src/debug/stacktrace.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/mips32/src/debug/stacktrace.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -36,35 +36,204 @@
 #include <syscall/copy.h>
 #include <typedefs.h>
-
-bool kernel_frame_pointer_validate(uintptr_t fp)
+#include <arch/debugger.h>
+#include <print.h>
+
+#define R0	0U
+#define SP	29U
+#define RA	31U
+
+#define OP_SHIFT	26
+#define RS_SHIFT	21
+#define RT_SHIFT	16
+#define RD_SHIFT	11
+
+#define HINT_SHIFT	6
+#define BASE_SHIFT	RS_SHIFT
+#define IMM_SHIFT	0
+#define OFFSET_SHIFT	IMM_SHIFT
+
+#define RS_MASK		(0x1f << RS_SHIFT)
+#define RT_MASK		(0x1f << RT_SHIFT)
+#define RD_MASK		(0x1f << RD_SHIFT)
+#define HINT_MASK	(0x1f << HINT_SHIFT)
+#define BASE_MASK	RS_MASK
+#define IMM_MASK	(0xffff << IMM_SHIFT)
+#define OFFSET_MASK	IMM_MASK	
+
+#define RS_GET(inst)		(((inst) & RS_MASK) >> RS_SHIFT)
+#define RD_GET(inst)		(((inst) & RD_MASK) >> RD_SHIFT)
+#define IMM_GET(inst)		(int16_t)(((inst) & IMM_MASK) >> IMM_SHIFT)
+#define BASE_GET(inst)		RS_GET(inst)
+#define OFFSET_GET(inst)	IMM_GET(inst)	
+
+#define ADDU_R_SP_R0_TEMPL \
+	((0x0 << OP_SHIFT) | (SP << RS_SHIFT) | (R0 << RT_SHIFT) | 0x21)
+#define ADDU_SP_R_R0_TEMPL \
+	((0x0 << OP_SHIFT) | (SP << RD_SHIFT) | (R0 << RT_SHIFT) | 0x21)
+#define ADDI_SP_SP_IMM_TEMPL \
+	((0x8 << OP_SHIFT) | (SP << RS_SHIFT) | (SP << RT_SHIFT))
+#define ADDIU_SP_SP_IMM_TEMPL \
+	((0x9 << OP_SHIFT) | (SP << RS_SHIFT) | (SP << RT_SHIFT))
+#define JR_RA_TEMPL \
+	((0x0 << OP_SHIFT) | (RA << RS_SHIFT) | (0x0 << HINT_SHIFT) | 0x8)
+#define SW_RA_TEMPL \
+	((0x2b << OP_SHIFT) | (RA << RT_SHIFT))
+
+#define IS_ADDU_R_SP_R0(inst) \
+	(((inst) & ~RD_MASK) == ADDU_R_SP_R0_TEMPL)
+#define IS_ADDU_SP_R_R0(inst) \
+	(((inst) & ~RS_MASK) == ADDU_SP_R_R0_TEMPL)
+#define IS_ADDI_SP_SP_IMM(inst) \
+	(((inst) & ~IMM_MASK) == ADDI_SP_SP_IMM_TEMPL)
+#define IS_ADDIU_SP_SP_IMM(inst) \
+	(((inst) & ~IMM_MASK) == ADDIU_SP_SP_IMM_TEMPL)
+#define IS_JR_RA(inst) \
+	(((inst) & ~HINT_MASK) == JR_RA_TEMPL)
+#define IS_SW_RA(inst) \
+	(((inst) & ~(BASE_MASK | OFFSET_MASK)) == SW_RA_TEMPL)
+
+extern char ktext_start;
+extern char ktext_end;
+
+static bool
+scan(stack_trace_context_t *ctx, uintptr_t *prev_fp, uintptr_t *prev_ra)
+{
+	uint32_t *inst = (void *) ctx->pc;
+	bool has_fp = false;
+	size_t frame_size;
+	unsigned int fp = SP;
+
+	do {
+		inst--;
+#if 0
+		/*
+		 * This is one of the situations in which the theory (ABI) does
+		 * not meet the practice (GCC). GCC simply does not place the
+		 * JR $ra instruction as dictated by the ABI, rendering the
+		 * official stack tracing algorithm somewhat unapplicable.
+		 */
+
+		if (IS_ADDU_R_SP_R0(*inst)) {
+			uint32_t *cur;
+			fp = RD_GET(*inst);
+			/*
+			 * We have a candidate for frame pointer.
+			 */
+			
+			/* Seek to the end of this function. */
+			for (cur = inst + 1; !IS_JR_RA(*cur); cur++)
+				;
+			/* Scan the last basic block */
+			for (cur--; !is_jump(*(cur - 1)); cur--) {
+				if (IS_ADDU_SP_R_R0(*cur) &&
+				    (fp == RS_GET(*cur))) {
+					has_fp = true;
+				}
+			}
+			continue;
+		}
+		
+		if (IS_JR_RA(*inst)) {
+			if (!ctx->istate)
+				return false;
+			/*
+			 * No stack frame has been allocated yet.
+			 * Use the values stored in istate.
+			 */
+			if (prev_fp)
+				*prev_fp = ctx->istate->sp;
+			if (prev_ra)
+				*prev_ra = ctx->istate->ra - 8;
+			ctx->istate = NULL;
+			return true;
+		}
+#endif
+
+	} while ((!IS_ADDIU_SP_SP_IMM(*inst) && !IS_ADDI_SP_SP_IMM(*inst)) ||
+	    (IMM_GET(*inst) >= 0));
+	
+	/*
+	 * We are at the instruction which allocates the space for the current
+	 * stack frame.
+	 */
+	frame_size = -IMM_GET(*inst);
+	if (prev_fp)
+		*prev_fp = ctx->fp + frame_size;
+
+	/*
+	 * Scan the first basic block for the occurrence of
+	 * SW $ra, OFFSET($base).
+	 */
+	for (inst++; !is_jump(*(inst - 1)) && (uintptr_t) inst < ctx->pc;
+	    inst++) {
+		if (IS_SW_RA(*inst)) {
+			unsigned int base = BASE_GET(*inst);
+			int16_t offset = OFFSET_GET(*inst);
+
+			if (base == SP || (has_fp && base == fp)) {
+				uint32_t *addr = (void *) (ctx->fp + offset);
+				
+				if (offset % 4 != 0)
+					return false;
+				/* cannot store below current stack pointer */
+				if (offset < 0)
+					return false;
+				/* too big offsets are suspicious */
+				if (offset > 32 * 4)
+					return false;
+
+				if (prev_ra)
+					*prev_ra = *addr;
+				return true;
+			}
+		}
+	}
+
+	/*
+	 * The first basic block does not save the return address or saves it
+	 * after ctx->pc, which means that the correct value is in istate.
+	 */
+	if (prev_ra) {
+		if (!ctx->istate)
+			return false;
+		*prev_ra = ctx->istate->ra - 8;
+		ctx->istate = NULL;
+	}
+	return true;
+}
+
+
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
+{
+	return !((ctx->fp == 0) || ((ctx->fp % 8) != 0) ||
+	    (ctx->pc % 4 != 0) || (ctx->pc < (uintptr_t) &ktext_start) ||
+	    (ctx->pc >= (uintptr_t) &ktext_end));
+}
+
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
+{
+	return scan(ctx, prev, NULL);
+}
+
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
+{
+	return scan(ctx, NULL, ra);
+}
+
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return false;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return false;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
 	return false;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
-{
-	return false;
-}
-
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
-{
-	return false;
-}
-
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
-{
-	return false;
-}
-
 /** @}
  */
Index: kernel/arch/mips32/src/debug/stacktrace_asm.S
===================================================================
--- kernel/arch/mips32/src/debug/stacktrace_asm.S	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/mips32/src/debug/stacktrace_asm.S	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -37,7 +37,7 @@
 frame_pointer_get:
 	j $ra
-	xor $v0, $v0
+	move $v0, $sp
 
 program_counter_get:
 	j $ra
-	xor $v0, $v0
+	move $v0, $ra
Index: kernel/arch/mips32/src/debugger.c
===================================================================
--- kernel/arch/mips32/src/debugger.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/mips32/src/debugger.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -134,5 +134,5 @@
  *
  */
-static bool is_jump(unative_t instr)
+bool is_jump(unative_t instr)
 {
 	unsigned int i;
Index: kernel/arch/ppc32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ppc32/src/debug/stacktrace.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/ppc32/src/debug/stacktrace.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -40,38 +40,38 @@
 #define FRAME_OFFSET_RA       1
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	uint32_t *stack = (void *) fp;
+	uint32_t *stack = (void *) ctx->fp;
 	*prev = stack[FRAME_OFFSET_FP_PREV];
 	return true;
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	uint32_t *stack = (void *) fp;
+	uint32_t *stack = (void *) ctx->fp;
 	*ra = stack[FRAME_OFFSET_RA];
 	return true;
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return !copy_from_uspace((void *) prev,
-	    (uint32_t *) fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_FP_PREV, sizeof(*prev));
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	return !copy_from_uspace((void *) ra, (uint32_t *) fp + FRAME_OFFSET_RA,
-	    sizeof(*ra));
+	return !copy_from_uspace((void *) ra,
+	    (uint32_t *) ctx->fp + FRAME_OFFSET_RA, sizeof(*ra));
 }
 
Index: kernel/arch/sparc64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/sparc64/src/debug/stacktrace.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/arch/sparc64/src/debug/stacktrace.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -50,5 +50,5 @@
 extern void alloc_window_and_flush(void);
 
-bool kernel_frame_pointer_validate(uintptr_t fp)
+bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	uintptr_t kstack;
@@ -63,12 +63,12 @@
 	kstack -= PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE;
 
-	if (THREAD && (fp == kstack))
+	if (THREAD && (ctx->fp == kstack))
 		return false;
-	return fp != 0;
+	return ctx->fp != 0;
 }
 
-bool kernel_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool kernel_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
-	uint64_t *stack = (void *) fp;
+	uint64_t *stack = (void *) ctx->fp;
 	alloc_window_and_flush();
 	*prev = stack[FRAME_OFFSET_FP_PREV] + STACK_BIAS;
@@ -76,7 +76,7 @@
 }
 
-bool kernel_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool kernel_return_address_get(stack_trace_context_t *ctx, uintptr_t *ra)
 {
-	uint64_t *stack = (void *) fp;
+	uint64_t *stack = (void *) ctx->fp;
 	alloc_window_and_flush();
 	*ra = stack[FRAME_OFFSET_RA];
@@ -84,15 +84,15 @@
 }
 
-bool uspace_frame_pointer_validate(uintptr_t fp)
+bool uspace_stack_trace_context_validate(stack_trace_context_t *ctx)
 {
 	return false;
 }
 
-bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev)
+bool uspace_frame_pointer_prev(stack_trace_context_t *ctx, uintptr_t *prev)
 {
 	return false;
 }
 
-bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra)
+bool uspace_return_address_get(stack_trace_context_t *ctx , uintptr_t *ra)
 {
 	return false;
Index: kernel/generic/include/macros.h
===================================================================
--- kernel/generic/include/macros.h	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/generic/include/macros.h	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -47,12 +47,30 @@
  * @param s2  Start address of the second interval.
  * @param sz2 Size of the second interval.
+ *
  */
-NO_TRACE static inline int overlaps(uintptr_t s1, size_t sz1, uintptr_t s2,
-    size_t sz2)
+NO_TRACE static inline int overlaps(uint64_t s1, uint64_t sz1, uint64_t s2,
+    uint64_t sz2)
 {
-	uintptr_t e1 = s1 + sz1;
-	uintptr_t e2 = s2 + sz2;
+	uint64_t e1 = s1 + sz1;
+	uint64_t e2 = s2 + sz2;
 	
 	return ((s1 < e2) && (s2 < e1));
+}
+
+/** Return true if the second interval is within the first interval.
+ *
+ * @param s1  Start address of the first interval.
+ * @param sz1 Size of the first interval.
+ * @param s2  Start address of the second interval.
+ * @param sz2 Size of the second interval.
+ *
+ */
+NO_TRACE static inline int iswithin(uint64_t s1, uint64_t sz1, uint64_t s2,
+    uint64_t sz2)
+{
+	uint64_t e1 = s1 + sz1;
+	uint64_t e2 = s2 + sz2;
+	
+	return ((s1 <= s2) && (e1 >= e2));
 }
 
@@ -74,5 +92,5 @@
 
 /* Compute overlapping of physical addresses */
-#define PA_overlaps(x, szx, y, szy) \
+#define PA_OVERLAPS(x, szx, y, szy) \
 	overlaps(KA2PA((x)), (szx), KA2PA((y)), (szy))
 
Index: kernel/generic/include/stacktrace.h
===================================================================
--- kernel/generic/include/stacktrace.h	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/generic/include/stacktrace.h	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -42,7 +42,13 @@
 
 typedef struct {
-	bool (* frame_pointer_validate)(uintptr_t);
-	bool (* frame_pointer_prev)(uintptr_t, uintptr_t *);
-	bool (* return_address_get)(uintptr_t, uintptr_t *);
+	uintptr_t fp;
+	uintptr_t pc;
+	struct istate *istate;
+} stack_trace_context_t;
+
+typedef struct {
+	bool (* stack_trace_context_validate)(stack_trace_context_t *);
+	bool (* frame_pointer_prev)(stack_trace_context_t *, uintptr_t *);
+	bool (* return_address_get)(stack_trace_context_t *, uintptr_t *);
 	bool (* symbol_resolve)(uintptr_t, const char **, uintptr_t *);
 } stack_trace_ops_t;
@@ -53,5 +59,5 @@
 extern void stack_trace(void);
 extern void stack_trace_istate(struct istate *);
-extern void stack_trace_fp_pc(stack_trace_ops_t *, uintptr_t, uintptr_t);
+extern void stack_trace_ctx(stack_trace_ops_t *, stack_trace_context_t *);
 
 /*
@@ -61,11 +67,11 @@
 extern uintptr_t program_counter_get(void);
 
-extern bool kernel_frame_pointer_validate(uintptr_t);
-extern bool kernel_frame_pointer_prev(uintptr_t, uintptr_t *);
-extern bool kernel_return_address_get(uintptr_t, uintptr_t *);
+extern bool kernel_stack_trace_context_validate(stack_trace_context_t *);
+extern bool kernel_frame_pointer_prev(stack_trace_context_t *, uintptr_t *);
+extern bool kernel_return_address_get(stack_trace_context_t *, uintptr_t *);
 
-extern bool uspace_frame_pointer_validate(uintptr_t);
-extern bool uspace_frame_pointer_prev(uintptr_t, uintptr_t *);
-extern bool uspace_return_address_get(uintptr_t, uintptr_t *);
+extern bool uspace_stack_trace_context_validate(stack_trace_context_t *);
+extern bool uspace_frame_pointer_prev(stack_trace_context_t *, uintptr_t *);
+extern bool uspace_return_address_get(stack_trace_context_t *, uintptr_t *);
 
 #endif
Index: kernel/generic/src/debug/stacktrace.c
===================================================================
--- kernel/generic/src/debug/stacktrace.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/generic/src/debug/stacktrace.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup genericdebug 
+/** @addtogroup genericdebug
  * @{
  */
@@ -42,24 +42,31 @@
 
 void
-stack_trace_fp_pc(stack_trace_ops_t *ops, uintptr_t fp, uintptr_t pc)
+stack_trace_ctx(stack_trace_ops_t *ops, stack_trace_context_t *ctx)
 {
 	int cnt = 0;
 	const char *symbol;
 	uintptr_t offset;
+	uintptr_t fp;
+	uintptr_t pc;
 	
-	while (cnt++ < STACK_FRAMES_MAX && ops->frame_pointer_validate(fp)) {
+	while (cnt++ < STACK_FRAMES_MAX &&
+	    ops->stack_trace_context_validate(ctx)) {
 		if (ops->symbol_resolve &&
-		    ops->symbol_resolve(pc, &symbol, &offset)) {
+		    ops->symbol_resolve(ctx->pc, &symbol, &offset)) {
 		    	if (offset)
-				printf("%p: %s+%" PRIp "()\n", fp, symbol, offset);
+				printf("%p: %s+%" PRIp "()\n",
+				    ctx->fp, symbol, offset);
 			else
-				printf("%p: %s()\n", fp, symbol);
+				printf("%p: %s()\n",
+				    ctx->fp, symbol);
 		} else {
-			printf("%p: %p()\n", fp, pc);
+			printf("%p: %p()\n", ctx->fp, ctx->pc);
 		}
-		if (!ops->return_address_get(fp, &pc))
+		if (!ops->return_address_get(ctx, &pc))
 			break;
-		if (!ops->frame_pointer_prev(fp, &fp))
+		if (!ops->frame_pointer_prev(ctx, &fp))
 			break;
+		ctx->fp = fp;
+		ctx->pc = pc;
 	}
 }
@@ -67,5 +74,11 @@
 void stack_trace(void)
 {
-	stack_trace_fp_pc(&kst_ops, frame_pointer_get(), program_counter_get());
+	stack_trace_context_t ctx = {
+		.fp = frame_pointer_get(),
+		.pc = program_counter_get(),
+		.istate = NULL
+	};
+
+	stack_trace_ctx(&kst_ops, &ctx);
 
 	/*
@@ -78,13 +91,18 @@
 void stack_trace_istate(istate_t *istate)
 {
+	stack_trace_context_t ctx = {
+		.fp = istate_get_fp(istate),
+		.pc = istate_get_pc(istate),
+		.istate = istate
+	};
+	
 	if (istate_from_uspace(istate))
-		stack_trace_fp_pc(&ust_ops, istate_get_fp(istate),
-		    istate_get_pc(istate));
+		stack_trace_ctx(&ust_ops, &ctx);
 	else
-		stack_trace_fp_pc(&kst_ops, istate_get_fp(istate),
-		    istate_get_pc(istate));
+		stack_trace_ctx(&kst_ops, &ctx);
 }
 
-static bool kernel_symbol_resolve(uintptr_t addr, const char **sp, uintptr_t *op)
+static bool
+kernel_symbol_resolve(uintptr_t addr, const char **sp, uintptr_t *op)
 {
 	return (symtab_name_lookup(addr, sp, op) == 0);
@@ -92,5 +110,5 @@
 
 stack_trace_ops_t kst_ops = {
-	.frame_pointer_validate = kernel_frame_pointer_validate,
+	.stack_trace_context_validate = kernel_stack_trace_context_validate,
 	.frame_pointer_prev = kernel_frame_pointer_prev,
 	.return_address_get = kernel_return_address_get,
@@ -99,5 +117,5 @@
 
 stack_trace_ops_t ust_ops = {
-	.frame_pointer_validate = uspace_frame_pointer_validate,
+	.stack_trace_context_validate = uspace_stack_trace_context_validate,
 	.frame_pointer_prev = uspace_frame_pointer_prev,
 	.return_address_get = uspace_return_address_get,
Index: kernel/generic/src/main/main.c
===================================================================
--- kernel/generic/src/main/main.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/generic/src/main/main.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -147,5 +147,5 @@
 	size_t i;
 	for (i = 0; i < init.cnt; i++) {
-		if (PA_overlaps(config.stack_base, config.stack_size,
+		if (PA_OVERLAPS(config.stack_base, config.stack_size,
 		    init.tasks[i].addr, init.tasks[i].size))
 			config.stack_base = ALIGN_UP(init.tasks[i].addr +
@@ -155,5 +155,5 @@
 	/* Avoid placing stack on top of boot allocations. */
 	if (ballocs.size) {
-		if (PA_overlaps(config.stack_base, config.stack_size,
+		if (PA_OVERLAPS(config.stack_base, config.stack_size,
 		    ballocs.base, ballocs.size))
 			config.stack_base = ALIGN_UP(ballocs.base +
Index: kernel/generic/src/mm/frame.c
===================================================================
--- kernel/generic/src/mm/frame.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ kernel/generic/src/mm/frame.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -121,5 +121,6 @@
  *
  */
-NO_TRACE static size_t zones_insert_zone(pfn_t base, size_t count)
+NO_TRACE static size_t zones_insert_zone(pfn_t base, size_t count,
+    zone_flags_t flags)
 {
 	if (zones.count + 1 == ZONES_MAX) {
@@ -131,10 +132,23 @@
 	for (i = 0; i < zones.count; i++) {
 		/* Check for overlap */
-		if (overlaps(base, count,
-		    zones.info[i].base, zones.info[i].count)) {
-			printf("Zone (%p, %p) overlaps with zone (%p, %p)!\n",
-			    PFN2ADDR(base), PFN2ADDR(base + count),
-			    PFN2ADDR(zones.info[i].base),
-			    PFN2ADDR(zones.info[i].base + zones.info[i].count));
+		if (overlaps(zones.info[i].base, zones.info[i].count,
+		    base, count)) {
+			
+			/*
+			 * If the overlaping zones are of the same type
+			 * and the new zone is completely within the previous
+			 * one, then quietly ignore the new zone.
+			 *
+			 */
+			
+			if ((zones.info[i].flags != flags) ||
+			    (!iswithin(zones.info[i].base, zones.info[i].count,
+			    base, count))) {
+				printf("Zone (%p, %p) overlaps with previous zone (%p, %p)!\n",
+				    PFN2ADDR(base), PFN2ADDR(count),
+				    PFN2ADDR(zones.info[i].base),
+				    PFN2ADDR(zones.info[i].count));
+			}
+			
 			return (size_t) -1;
 		}
@@ -147,6 +161,7 @@
 	for (j = zones.count; j > i; j--) {
 		zones.info[j] = zones.info[j - 1];
-		zones.info[j].buddy_system->data =
-		    (void *) &zones.info[j - 1];
+		if (zones.info[j].buddy_system != NULL)
+			zones.info[j].buddy_system->data =
+			    (void *) &zones.info[j];
 	}
 	
@@ -748,6 +763,7 @@
 	for (i = z2 + 1; i < zones.count; i++) {
 		zones.info[i - 1] = zones.info[i];
-		zones.info[i - 1].buddy_system->data =
-		    (void *) &zones.info[i - 1];
+		if (zones.info[i - 1].buddy_system != NULL)
+			zones.info[i - 1].buddy_system->data =
+			    (void *) &zones.info[i - 1];
 	}
 	
@@ -898,5 +914,5 @@
 		}
 		
-		size_t znum = zones_insert_zone(start, count);
+		size_t znum = zones_insert_zone(start, count, flags);
 		if (znum == (size_t) -1) {
 			irq_spinlock_unlock(&zones.lock, true);
@@ -921,5 +937,5 @@
 	
 	/* Non-available zone */
-	size_t znum = zones_insert_zone(start, count);
+	size_t znum = zones_insert_zone(start, count, flags);
 	if (znum == (size_t) -1) {
 		irq_spinlock_unlock(&zones.lock, true);
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ uspace/Makefile.common	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -172,5 +172,9 @@
 ifneq ($(BINARY),)
 %.disasm: $(BINARY)
+ifeq ($(CONFIG_LINE_DEBUG),y)
+	$(OBJDUMP) -d -S $< > $@
+else
 	$(OBJDUMP) -d $< > $@
+endif
 
 $(BINARY): $(LINKER_SCRIPT) $(OBJECTS) $(LIBS) $(BASE_LIBS)
Index: uspace/app/klog/klog.c
===================================================================
--- uspace/app/klog/klog.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ uspace/app/klog/klog.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -43,11 +43,15 @@
 #include <event.h>
 #include <errno.h>
+#include <str_error.h>
 #include <io/klog.h>
 
-#define NAME  "klog"
+#define NAME       "klog"
+#define LOG_FNAME  "/log/klog"
 
 /* Pointer to klog area */
 static wchar_t *klog;
 static size_t klog_length;
+
+static FILE *log;
 
 static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
@@ -58,6 +62,17 @@
 	size_t i;
 	
-	for (i = klog_len - klog_stored; i < klog_len; i++)
-		putchar(klog[(klog_start + i) % klog_length]);
+	for (i = klog_len - klog_stored; i < klog_len; i++) {
+		wchar_t ch = klog[(klog_start + i) % klog_length];
+		
+		putchar(ch);
+		
+		if (log != NULL)
+			fprintf(log, "%lc", ch);
+	}
+	
+	if (log != NULL) {
+		fflush(log);
+		fsync(fileno(log));
+	}
 }
 
@@ -91,4 +106,14 @@
 	}
 	
+	/*
+	 * Mode "a" would be definitively much better here, but it is
+	 * not well supported by the FAT driver.
+	 *
+	 */
+	log = fopen(LOG_FNAME, "w");
+	if (log == NULL)
+		printf("%s: Unable to create log file %s (%s)\n", NAME, LOG_FNAME,
+		    str_error(errno));
+	
 	async_set_interrupt_received(interrupt_received);
 	klog_update();
Index: uspace/lib/c/generic/io/io.c
===================================================================
--- uspace/lib/c/generic/io/io.c	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ uspace/lib/c/generic/io/io.c	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -757,4 +757,14 @@
 }
 
+int fileno(FILE *stream)
+{
+	if (stream->klog) {
+		errno = EBADF;
+		return -1;
+	}
+	
+	return stream->fd;
+}
+
 int fphone(FILE *stream)
 {
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision 1720cf99a344d8198c24a88d92b1469cab43f376)
+++ uspace/lib/c/include/stdio.h	(revision 571addd173f588601486722216ec77880b28e1da)
@@ -171,4 +171,5 @@
 extern off64_t ftell(FILE *);
 extern int feof(FILE *);
+extern int fileno(FILE *);
 
 extern int fflush(FILE *);
