Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/Makefile	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/abs32le/src/debug/stacktrace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/_link.ld.in	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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/include/pm.h
===================================================================
--- kernel/arch/amd64/include/pm.h	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/include/pm.h	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -65,6 +65,5 @@
 #endif /* CONFIG_FB */
 
-#define gdtselector(des)  ((des) << 3)
-#define idtselector(des)  ((des) << 4)
+#define GDT_SELECTOR(des)  ((des) << 3)
 
 #define PL_KERNEL  0
@@ -168,5 +167,4 @@
 
 extern ptr_16_64_t gdtr;
-extern ptr_16_32_t bootstrap_gdtr;
 extern ptr_16_32_t protected_ap_gdtr;
 
Index: kernel/arch/amd64/src/asm.S
===================================================================
--- kernel/arch/amd64/src/asm.S	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/src/asm.S	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -244,5 +244,5 @@
 	 */
 	xorq %rdx, %rdx
-	cmpq $(gdtselector(KTEXT_DES)), ISTATE_OFFSET_CS(%rsp)
+	cmpq $(GDT_SELECTOR(KTEXT_DES)), ISTATE_OFFSET_CS(%rsp)
 	cmovnzq %rdx, %rbp
 
Index: kernel/arch/amd64/src/boot/boot.S
===================================================================
--- kernel/arch/amd64/src/boot/boot.S	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/src/boot/boot.S	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -85,5 +85,5 @@
 	
 	/* Kernel data + stack */
-	movw $gdtselector(KDATA_DES), %cx
+	movw $GDT_SELECTOR(KDATA_DES), %cx
 	movw %cx, %es
 	movw %cx, %ds
@@ -94,9 +94,9 @@
 	 * when _visible_ part of GS does not point to user-mode segment.
 	 */
-	movw $gdtselector(UDATA_DES), %cx
+	movw $GDT_SELECTOR(UDATA_DES), %cx
 	movw %cx, %fs
 	movw %cx, %gs
 	
-	jmpl $gdtselector(KTEXT32_DES), $multiboot_meeting_point
+	jmpl $GDT_SELECTOR(KTEXT32_DES), $multiboot_meeting_point
 	multiboot_meeting_point:
 	
@@ -182,5 +182,5 @@
 	
 	/* At this point we are in compatibility mode */
-	jmpl $gdtselector(KTEXT_DES), $start64
+	jmpl $GDT_SELECTOR(KTEXT_DES), $start64
 
 /** Print string to EGA display (in light red) and halt.
@@ -645,7 +645,6 @@
 .section K_DATA_START, "aw", @progbits
 
-.global bootstrap_gdtr
 bootstrap_gdtr:
-	.word gdtselector(GDT_ITEMS)
+	.word GDT_SELECTOR(GDT_ITEMS)
 	.long KA2PA(gdt)
 
Index: kernel/arch/amd64/src/boot/vesa_ret.inc
===================================================================
--- kernel/arch/amd64/src/boot/vesa_ret.inc	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/src/boot/vesa_ret.inc	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -7,5 +7,5 @@
 	
 	/* Kernel data + stack */
-	movw $gdtselector(KDATA_DES), %cx
+	movw $GDT_SELECTOR(KDATA_DES), %cx
 	movw %cx, %es
 	movw %cx, %ds
@@ -17,7 +17,7 @@
 	 */
 	
-	movw $gdtselector(UDATA_DES), %cx
+	movw $GDT_SELECTOR(UDATA_DES), %cx
 	movw %cx, %fs
 	movw %cx, %gs
 	
-	jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
+	jmpl $GDT_SELECTOR(KTEXT32_DES), $vesa_meeting_point
Index: kernel/arch/amd64/src/ddi/ddi.c
===================================================================
--- kernel/arch/amd64/src/ddi/ddi.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/src/ddi/ddi.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -153,5 +153,5 @@
 	tss_descriptor_t *tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
 	tss_desc->type = AR_TSS;
-	tr_load(gdtselector(TSS_DES));
+	tr_load(GDT_SELECTOR(TSS_DES));
 	
 	/*
Index: kernel/arch/amd64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/amd64/src/debug/stacktrace.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/src/debug/stacktrace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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/amd64/src/pm.c
===================================================================
--- kernel/arch/amd64/src/pm.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/src/pm.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -171,5 +171,5 @@
 
 		d->unused = 0;
-		d->selector = gdtselector(KTEXT_DES);
+		d->selector = GDT_SELECTOR(KTEXT_DES);
 
 		d->present = 1;
@@ -291,5 +291,5 @@
 	 * to its own TSS. We just need to load the TR register.
 	 */
-	tr_load(gdtselector(TSS_DES));
+	tr_load(GDT_SELECTOR(TSS_DES));
 }
 
Index: kernel/arch/amd64/src/smp/ap.S
===================================================================
--- kernel/arch/amd64/src/smp/ap.S	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/src/smp/ap.S	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -61,13 +61,13 @@
 	orl $1, %eax
 	movl %eax, %cr0     # switch to protected mode
-	jmpl $gdtselector(KTEXT32_DES), $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET
+	jmpl $GDT_SELECTOR(KTEXT32_DES), $jump_to_kernel - BOOT_OFFSET + AP_BOOT_OFFSET
 
 jump_to_kernel:
 .code32
-	movw $gdtselector(KDATA_DES), %ax
+	movw $GDT_SELECTOR(KDATA_DES), %ax
 	movw %ax, %ds
 	movw %ax, %es
 	movw %ax, %ss
-	movw $gdtselector(UDATA_DES), %ax
+	movw $GDT_SELECTOR(UDATA_DES), %ax
 	movw %ax, %gs
 	
@@ -94,5 +94,5 @@
 	
 	# At this point we are in compatibility mode
-	jmpl $gdtselector(KTEXT_DES), $start64 - BOOT_OFFSET + AP_BOOT_OFFSET
+	jmpl $GDT_SELECTOR(KTEXT_DES), $start64 - BOOT_OFFSET + AP_BOOT_OFFSET
 
 .code64
Index: kernel/arch/amd64/src/syscall.c
===================================================================
--- kernel/arch/amd64/src/syscall.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/src/syscall.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -58,6 +58,6 @@
 	 */
 	write_msr(AMD_MSR_STAR,
-	    ((uint64_t)(gdtselector(KDATA_DES) | PL_USER) << 48) |
-	    ((uint64_t)(gdtselector(KTEXT_DES) | PL_KERNEL) << 32));
+	    ((uint64_t) (GDT_SELECTOR(KDATA_DES) | PL_USER) << 48) |
+	    ((uint64_t) (GDT_SELECTOR(KTEXT_DES) | PL_KERNEL) << 32));
 	write_msr(AMD_MSR_LSTAR, (uint64_t)syscall_entry);
 	/* Mask RFLAGS on syscall 
Index: kernel/arch/amd64/src/userspace.c
===================================================================
--- kernel/arch/amd64/src/userspace.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/amd64/src/userspace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -65,8 +65,8 @@
 		"xorq %%rdi, %%rdi\n"
 		"iretq\n"
-		:: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER),
+		:: [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
 		   [stack_size] "r" (kernel_uarg->uspace_stack + THREAD_STACK_SIZE),
 		   [ipl] "r" (ipl),
-		   [utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER),
+		   [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
 		   [entry] "r" (kernel_uarg->uspace_entry),
 		   [uarg] "r" (kernel_uarg->uspace_uarg)
Index: kernel/arch/arm32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/arm32/src/debug/stacktrace.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/arm32/src/debug/stacktrace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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/include/bios/bios.h
===================================================================
--- kernel/arch/ia32/include/bios/bios.h	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/include/bios/bios.h	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -38,6 +38,4 @@
 #include <typedefs.h>
 
-#define BIOS_EBDA_PTR  0x40e
-
 extern uintptr_t ebda;
 
Index: kernel/arch/ia32/include/mm/as.h
===================================================================
--- kernel/arch/ia32/include/mm/as.h	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/include/mm/as.h	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32mm	
+/** @addtogroup ia32mm
  * @{
  */
Index: kernel/arch/ia32/include/mm/page.h
===================================================================
--- kernel/arch/ia32/include/mm/page.h	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/include/mm/page.h	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -27,5 +27,5 @@
  */
 
-/** @addtogroup ia32mm	
+/** @addtogroup ia32mm
  * @{
  */
@@ -106,5 +106,5 @@
 
 /* Set PTE flags accessors for each level. */
-#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)	\
+#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
 	set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
 #define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
Index: kernel/arch/ia32/include/pm.h
===================================================================
--- kernel/arch/ia32/include/pm.h	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/include/pm.h	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -58,5 +58,5 @@
 #endif /* CONFIG_FB */
 
-#define gdtselector(des)  ((des) << 3)
+#define GDT_SELECTOR(des)  ((des) << 3)
 
 #define PL_KERNEL  0
@@ -153,5 +153,4 @@
 
 extern ptr_16_32_t gdtr;
-extern ptr_16_32_t bootstrap_gdtr;
 extern ptr_16_32_t protected_ap_gdtr;
 extern tss_t *tss_p;
Index: kernel/arch/ia32/src/asm.S
===================================================================
--- kernel/arch/ia32/src/asm.S	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/asm.S	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -225,5 +225,5 @@
 	 * Switch to kernel selectors.
 	 */
-	movw $(gdtselector(KDATA_DES)), %ax
+	movw $(GDT_SELECTOR(KDATA_DES)), %ax
 	movw %ax, %ds
 	movw %ax, %es
@@ -304,5 +304,5 @@
 	 * Switch to kernel selectors.
 	 */
-	movl $(gdtselector(KDATA_DES)), %eax
+	movl $(GDT_SELECTOR(KDATA_DES)), %eax
 	movl %eax, %ds
 	movl %eax, %es
@@ -407,5 +407,5 @@
 	 * Switch to kernel selectors.
 	 */
-	movl $(gdtselector(KDATA_DES)), %eax
+	movl $(GDT_SELECTOR(KDATA_DES)), %eax
 	movl %eax, %ds
 	movl %eax, %es
@@ -416,5 +416,5 @@
 	 */
 	xorl %eax, %eax
-	cmpl $(gdtselector(KTEXT_DES)), ISTATE_OFFSET_CS(%esp)
+	cmpl $(GDT_SELECTOR(KTEXT_DES)), ISTATE_OFFSET_CS(%esp)
 	cmovnzl %eax, %ebp
 
Index: kernel/arch/ia32/src/bios/bios.c
===================================================================
--- kernel/arch/ia32/src/bios/bios.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/bios/bios.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -36,4 +36,6 @@
 #include <typedefs.h>
 
+#define BIOS_EBDA_PTR  0x40e
+
 uintptr_t ebda = 0;
 
Index: kernel/arch/ia32/src/boot/boot.S
===================================================================
--- kernel/arch/ia32/src/boot/boot.S	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/boot/boot.S	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -78,8 +78,8 @@
 	
 	/* Initialize Global Descriptor Table register */
-	lgdtl KA2PA(bootstrap_gdtr)
+	lgdtl bootstrap_gdtr
 	
 	/* Kernel data + stack */
-	movw $gdtselector(KDATA_DES), %cx
+	movw $GDT_SELECTOR(KDATA_DES), %cx
 	movw %cx, %es
 	movw %cx, %fs
@@ -88,5 +88,5 @@
 	movw %cx, %ss
 	
-	jmpl $gdtselector(KTEXT_DES), $multiboot_meeting_point
+	jmpl $GDT_SELECTOR(KTEXT_DES), $multiboot_meeting_point
 	multiboot_meeting_point:
 	
@@ -514,4 +514,8 @@
 page_directory:
 	.space 4096, 0
+
+bootstrap_gdtr:
+	.word GDT_SELECTOR(GDT_ITEMS)
+	.long KA2PA(gdt)
 
 grub_eax:
Index: kernel/arch/ia32/src/boot/vesa_real.inc
===================================================================
--- kernel/arch/ia32/src/boot/vesa_real.inc	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/boot/vesa_real.inc	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -30,5 +30,5 @@
 .code32
 vesa_init:
-	jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init
+	jmp $GDT_SELECTOR(VESA_INIT_DES), $vesa_init_real - vesa_init
 
 .code16
@@ -335,5 +335,5 @@
 		vesa_leave_real2:
 		
-			ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)
+			ljmpl $GDT_SELECTOR(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)
 	
 	no_mode:
Index: kernel/arch/ia32/src/boot/vesa_ret.inc
===================================================================
--- kernel/arch/ia32/src/boot/vesa_ret.inc	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/boot/vesa_ret.inc	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -7,5 +7,5 @@
 	
 	/* Kernel data + stack */
-	movw $gdtselector(KDATA_DES), %cx
+	movw $GDT_SELECTOR(KDATA_DES), %cx
 	movw %cx, %es
 	movw %cx, %fs
@@ -14,3 +14,3 @@
 	movw %cx, %ss
 	
-	jmpl $gdtselector(KTEXT_DES), $vesa_meeting_point
+	jmpl $GDT_SELECTOR(KTEXT_DES), $vesa_meeting_point
Index: kernel/arch/ia32/src/ddi/ddi.c
===================================================================
--- kernel/arch/ia32/src/ddi/ddi.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/ddi/ddi.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -153,5 +153,5 @@
 	 */
 	gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
-	tr_load(gdtselector(TSS_DES));
+	tr_load(GDT_SELECTOR(TSS_DES));
 	
 	/*
Index: kernel/arch/ia32/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia32/src/debug/stacktrace.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/debug/stacktrace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/mm/frame.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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/ia32/src/pm.c
===================================================================
--- kernel/arch/ia32/src/pm.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/pm.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -75,6 +75,6 @@
 	/* VESA Init descriptor */
 #ifdef CONFIG_FB
-	{ 0xffff, 0, VESA_INIT_SEGMENT>>12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
-#endif	
+	{ 0xffff, 0, VESA_INIT_SEGMENT >> 12, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 0, 0, 0 }
+#endif
 };
 
@@ -86,6 +86,8 @@
 
 /* gdtr is changed by kmp before next CPU is initialized */
-ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((uintptr_t) gdt) };
-ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (uintptr_t) gdt };
+ptr_16_32_t gdtr = {
+	.limit = sizeof(gdt),
+	.base = (uintptr_t) gdt
+};
 
 void gdt_setbase(descriptor_t *d, uintptr_t base)
@@ -128,5 +130,5 @@
 
 		d->unused = 0;
-		d->selector = gdtselector(KTEXT_DES);
+		d->selector = GDT_SELECTOR(KTEXT_DES);
 
 		if (i == VECTOR_SYSCALL) {
@@ -283,5 +285,5 @@
 	 * to its own TSS. We just need to load the TR register.
 	 */
-	tr_load(gdtselector(TSS_DES));
+	tr_load(GDT_SELECTOR(TSS_DES));
 	
 	clean_IOPL_NT_flags();    /* Disable I/O on nonprivileged levels and clear NT flag. */
Index: kernel/arch/ia32/src/proc/scheduler.c
===================================================================
--- kernel/arch/ia32/src/proc/scheduler.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/proc/scheduler.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -67,5 +67,5 @@
 	/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */
 	CPU->arch.tss->esp0 = kstk;
-	CPU->arch.tss->ss0 = gdtselector(KDATA_DES);
+	CPU->arch.tss->ss0 = GDT_SELECTOR(KDATA_DES);
 	
 	/* Set up TLS in GS register */
Index: kernel/arch/ia32/src/syscall.c
===================================================================
--- kernel/arch/ia32/src/syscall.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/syscall.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -45,5 +45,5 @@
 
 	/* set kernel mode CS selector */
-	write_msr(IA32_MSR_SYSENTER_CS, gdtselector(KTEXT_DES));
+	write_msr(IA32_MSR_SYSENTER_CS, GDT_SELECTOR(KTEXT_DES));
 	/* set kernel mode entry point */
 	write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler);
Index: kernel/arch/ia32/src/userspace.c
===================================================================
--- kernel/arch/ia32/src/userspace.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia32/src/userspace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -75,11 +75,11 @@
 		"iret\n"
 		:
-		: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER),
+		: [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
 		  [stack_size] "r" ((uint8_t *) kernel_uarg->uspace_stack + THREAD_STACK_SIZE),
 		  [ipl] "r" (ipl),
-		  [utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER),
+		  [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
 		  [entry] "r" (kernel_uarg->uspace_entry),
 		  [uarg] "r" (kernel_uarg->uspace_uarg),
-		  [tls_des] "r" (gdtselector(TLS_DES))
+		  [tls_des] "r" (GDT_SELECTOR(TLS_DES))
 		: "eax");
 	
Index: kernel/arch/ia64/src/debug/stacktrace.c
===================================================================
--- kernel/arch/ia64/src/debug/stacktrace.c	(revision 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ia64/src/debug/stacktrace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/mips32/include/debugger.h	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/mips32/src/debug/stacktrace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/mips32/src/debug/stacktrace_asm.S	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/mips32/src/debugger.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/ppc32/src/debug/stacktrace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/arch/sparc64/src/debug/stacktrace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/generic/include/macros.h	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/generic/include/stacktrace.h	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/generic/src/debug/stacktrace.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/generic/src/main/main.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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 527298a2333d7b6963d6547e3f3c42f0bea1e8af)
+++ kernel/generic/src/mm/frame.c	(revision df908b30e4b97f72823f6cf1d2178df300bb11d5)
@@ -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);
