Index: uspace/lib/c/arch/ppc32/_link.ld.in
===================================================================
--- uspace/lib/c/arch/ppc32/_link.ld.in	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/c/arch/ppc32/_link.ld.in	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -10,4 +10,5 @@
 #endif
 	data PT_LOAD FLAGS(6);
+	debug PT_NOTE;
 }
 
@@ -55,4 +56,17 @@
 	} :data
 	
+#ifdef CONFIG_LINE_DEBUG
+	.comment 0 : { *(.comment); } :debug
+	.debug_abbrev 0 : { *(.debug_abbrev); } :debug
+	.debug_aranges 0 : { *(.debug_aranges); } :debug
+	.debug_info 0 : { *(.debug_info); } :debug
+	.debug_line 0 : { *(.debug_line); } :debug
+	.debug_loc 0 : { *(.debug_loc); } :debug
+	.debug_pubnames 0 : { *(.debug_pubnames); } :debug
+	.debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
+	.debug_ranges 0 : { *(.debug_ranges); } :debug
+	.debug_str 0 : { *(.debug_str); } :debug
+#endif
+	
 	/DISCARD/ : {
 		*(*);
Index: uspace/lib/c/generic/assert.c
===================================================================
--- uspace/lib/c/generic/assert.c	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/c/generic/assert.c	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -33,12 +33,35 @@
 #include <assert.h>
 #include <stdio.h>
+#include <io/klog.h>
 #include <stdlib.h>
+#include <atomic.h>
 #include <stacktrace.h>
+#include <stdint.h>
+
+static atomic_t failed_asserts = {0};
 
 void assert_abort(const char *cond, const char *file, unsigned int line)
 {
+	/*
+	 * Send the message safely to klog. Nested asserts should not occur.
+	 */
+	klog_printf("Assertion failed (%s) in file \"%s\", line %u.\n",
+	    cond, file, line);
+	
+	/*
+	 * Check if this is a nested or parallel assert.
+	 */
+	if (atomic_postinc(&failed_asserts))
+		abort();
+	
+	/*
+	 * Attempt to print the message to standard output and display
+	 * the stack trace. These operations can theoretically trigger nested
+	 * assertions.
+	 */
 	printf("Assertion failed (%s) in file \"%s\", line %u.\n",
 	    cond, file, line);
 	stacktrace_print();
+	
 	abort();
 }
Index: uspace/lib/c/generic/io/klog.c
===================================================================
--- uspace/lib/c/generic/io/klog.c	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/c/generic/io/klog.c	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -38,5 +38,7 @@
 #include <sys/types.h>
 #include <unistd.h>
+#include <errno.h>
 #include <io/klog.h>
+#include <io/printf_core.h>
 
 size_t klog_write(const void *buf, size_t size)
@@ -55,4 +57,67 @@
 }
 
+/** Print formatted text to klog.
+ *
+ * @param fmt Format string
+ *
+ * \see For more details about format string see printf_core.
+ *
+ */
+int klog_printf(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	
+	int ret = klog_vprintf(fmt, args);
+	
+	va_end(args);
+	
+	return ret;
+}
+
+static int klog_vprintf_str_write(const char *str, size_t size, void *data)
+{
+	size_t wr = klog_write(str, size);
+	return str_nlength(str, wr);
+}
+
+static int klog_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
+{
+	size_t offset = 0;
+	size_t chars = 0;
+	
+	while (offset < size) {
+		char buf[STR_BOUNDS(1)];
+		size_t sz = 0;
+		
+		if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK)
+			klog_write(buf, sz);
+		
+		chars++;
+		offset += sizeof(wchar_t);
+	}
+	
+	return chars;
+}
+
+/** Print formatted text to klog.
+ *
+ * @param fmt Format string
+ * @param ap  Format parameters
+ *
+ * \see For more details about format string see printf_core.
+ *
+ */
+int klog_vprintf(const char *fmt, va_list ap)
+{
+	printf_spec_t ps = {
+		klog_vprintf_str_write,
+		klog_vprintf_wstr_write,
+		NULL
+	};
+	
+	return printf_core(fmt, &ps, ap);
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/io/vprintf.c
===================================================================
--- uspace/lib/c/generic/io/vprintf.c	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/c/generic/io/vprintf.c	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -96,7 +96,6 @@
 /** Print formatted text to stdout.
  *
- * @param file Output stream
- * @param fmt  Format string
- * @param ap   Format parameters
+ * @param fmt Format string
+ * @param ap  Format parameters
  *
  * \see For more details about format string see printf_core.
Index: uspace/lib/c/generic/malloc.c
===================================================================
--- uspace/lib/c/generic/malloc.c	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/c/generic/malloc.c	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -65,8 +65,22 @@
 #define BASE_ALIGN  16
 
+/** Heap shrink granularity
+ *
+ * Try not to pump and stress the heap to much
+ * by shrinking and enlarging it too often.
+ * A heap area won't shrunk if it the released
+ * free block is smaller than this constant.
+ *
+ */
+#define SHRINK_GRANULARITY  (64 * PAGE_SIZE)
+
 /** Overhead of each heap block. */
 #define STRUCT_OVERHEAD \
 	(sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
 
+/** Overhead of each area. */
+#define AREA_OVERHEAD(size) \
+	(ALIGN_UP(size + sizeof(heap_area_t), BASE_ALIGN))
+
 /** Calculate real size of a heap block.
  *
@@ -86,6 +100,19 @@
  *
  */
-#define AREA_FIRST_BLOCK(area) \
+#define AREA_FIRST_BLOCK_HEAD(area) \
 	(ALIGN_UP(((uintptr_t) (area)) + sizeof(heap_area_t), BASE_ALIGN))
+
+/** Get last block in heap area.
+ *
+ */
+#define AREA_LAST_BLOCK_FOOT(area) \
+	(((uintptr_t) (area)->end) - sizeof(heap_block_foot_t))
+
+/** Get header in heap block.
+ *
+ */
+#define BLOCK_HEAD(foot) \
+	((heap_block_head_t *) \
+	    (((uintptr_t) (foot)) + sizeof(heap_block_foot_t) - (foot)->size))
 
 /** Get footer in heap block.
@@ -94,5 +121,5 @@
 #define BLOCK_FOOT(head) \
 	((heap_block_foot_t *) \
-	    (((uintptr_t) head) + head->size - sizeof(heap_block_foot_t)))
+	    (((uintptr_t) (head)) + (head)->size - sizeof(heap_block_foot_t)))
 
 /** Heap area.
@@ -115,4 +142,7 @@
 	void *end;
 	
+	/** Previous heap area */
+	struct heap_area *prev;
+	
 	/** Next heap area */
 	struct heap_area *next;
@@ -157,8 +187,24 @@
 
 /** Next heap block to examine (next fit algorithm) */
-static heap_block_head_t *next = NULL;
+static heap_block_head_t *next_fit = NULL;
 
 /** Futex for thread-safe heap manipulation */
 static futex_t malloc_futex = FUTEX_INITIALIZER;
+
+#ifndef NDEBUG
+
+#define malloc_assert(expr) \
+	do { \
+		if (!(expr)) {\
+			futex_up(&malloc_futex); \
+			assert_abort(#expr, __FILE__, __LINE__); \
+		} \
+	} while (0)
+
+#else /* NDEBUG */
+
+#define malloc_assert(expr)
+
+#endif /* NDEBUG */
 
 /** Initialize a heap block
@@ -202,14 +248,16 @@
 	heap_block_head_t *head = (heap_block_head_t *) addr;
 	
-	assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
+	malloc_assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
 	
 	heap_block_foot_t *foot = BLOCK_FOOT(head);
 	
-	assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
-	assert(head->size == foot->size);
+	malloc_assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
+	malloc_assert(head->size == foot->size);
 }
 
 /** Check a heap area structure
  *
+ * Should be called only inside the critical section.
+ *
  * @param addr Address of the heap area.
  *
@@ -219,14 +267,16 @@
 	heap_area_t *area = (heap_area_t *) addr;
 	
-	assert(area->magic == HEAP_AREA_MAGIC);
-	assert(area->start < area->end);
-	assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
-	assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
+	malloc_assert(area->magic == HEAP_AREA_MAGIC);
+	malloc_assert(addr == area->start);
+	malloc_assert(area->start < area->end);
+	malloc_assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
+	malloc_assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
 }
 
 /** Create new heap area
  *
- * @param start Preffered starting address of the new area.
- * @param size  Size of the area.
+ * Should be called only inside the critical section.
+ *
+ * @param size Size of the area.
  *
  */
@@ -248,10 +298,10 @@
 	
 	area->start = astart;
-	area->end = (void *)
-	    ALIGN_DOWN((uintptr_t) astart + asize, BASE_ALIGN);
+	area->end = (void *) ((uintptr_t) astart + asize);
+	area->prev = NULL;
 	area->next = NULL;
 	area->magic = HEAP_AREA_MAGIC;
 	
-	void *block = (void *) AREA_FIRST_BLOCK(area);
+	void *block = (void *) AREA_FIRST_BLOCK_HEAD(area);
 	size_t bsize = (size_t) (area->end - block);
 	
@@ -262,4 +312,5 @@
 		last_heap_area = area;
 	} else {
+		area->prev = last_heap_area;
 		last_heap_area->next = area;
 		last_heap_area = area;
@@ -271,6 +322,10 @@
 /** Try to enlarge a heap area
  *
+ * Should be called only inside the critical section.
+ *
  * @param area Heap area to grow.
- * @param size Gross size of item to allocate (bytes).
+ * @param size Gross size to grow (bytes).
+ *
+ * @return True if successful.
  *
  */
@@ -282,10 +337,8 @@
 	area_check(area);
 	
-	size_t asize = ALIGN_UP((size_t) (area->end - area->start) + size,
-	    PAGE_SIZE);
-	
 	/* New heap area size */
-	void *end = (void *)
-	    ALIGN_DOWN((uintptr_t) area->start + asize, BASE_ALIGN);
+	size_t gross_size = (size_t) (area->end - area->start) + size;
+	size_t asize = ALIGN_UP(gross_size, PAGE_SIZE);
+	void *end = (void *) ((uintptr_t) area->start + asize);
 	
 	/* Check for overflow */
@@ -299,5 +352,7 @@
 	
 	/* Add new free block */
-	block_init(area->end, (size_t) (end - area->end), true, area);
+	size_t net_size = (size_t) (end - area->end);
+	if (net_size > 0)
+		block_init(area->end, net_size, true, area);
 	
 	/* Update heap area parameters */
@@ -309,4 +364,6 @@
 /** Try to enlarge any of the heap areas
  *
+ * Should be called only inside the critical section.
+ *
  * @param size Gross size of item to allocate (bytes).
  *
@@ -318,6 +375,6 @@
 	
 	/* First try to enlarge some existing area */
-	heap_area_t *area;
-	for (area = first_heap_area; area != NULL; area = area->next) {
+	for (heap_area_t *area = first_heap_area; area != NULL;
+	    area = area->next) {
 		if (area_grow(area, size))
 			return true;
@@ -325,15 +382,110 @@
 	
 	/* Eventually try to create a new area */
-	return area_create(AREA_FIRST_BLOCK(size));
-}
-
-/** Try to shrink heap space
- *
+	return area_create(AREA_OVERHEAD(size));
+}
+
+/** Try to shrink heap
+ *
+ * Should be called only inside the critical section.
  * In all cases the next pointer is reset.
  *
- */
-static void heap_shrink(void)
-{
-	next = NULL;
+ * @param area Last modified heap area.
+ *
+ */
+static void heap_shrink(heap_area_t *area)
+{
+	area_check(area);
+	
+	heap_block_foot_t *last_foot =
+	    (heap_block_foot_t *) AREA_LAST_BLOCK_FOOT(area);
+	heap_block_head_t *last_head = BLOCK_HEAD(last_foot);
+	
+	block_check((void *) last_head);
+	malloc_assert(last_head->area == area);
+	
+	if (last_head->free) {
+		/*
+		 * The last block of the heap area is
+		 * unused. The area might be potentially
+		 * shrunk.
+		 */
+		
+		heap_block_head_t *first_head =
+		    (heap_block_head_t *) AREA_FIRST_BLOCK_HEAD(area);
+		
+		block_check((void *) first_head);
+		malloc_assert(first_head->area == area);
+		
+		size_t shrink_size = ALIGN_DOWN(last_head->size, PAGE_SIZE);
+		
+		if (first_head == last_head) {
+			/*
+			 * The entire heap area consists of a single
+			 * free heap block. This means we can get rid
+			 * of it entirely.
+			 */
+			
+			heap_area_t *prev = area->prev;
+			heap_area_t *next = area->next;
+			
+			if (prev != NULL) {
+				area_check(prev);
+				prev->next = next;
+			} else
+				first_heap_area = next;
+			
+			if (next != NULL) {
+				area_check(next);
+				next->prev = prev;
+			} else
+				last_heap_area = prev;
+			
+			as_area_destroy(area->start);
+		} else if (shrink_size >= SHRINK_GRANULARITY) {
+			/*
+			 * Make sure that we always shrink the area
+			 * by a multiple of page size and update
+			 * the block layout accordingly.
+			 */
+			
+			size_t asize = (size_t) (area->end - area->start) - shrink_size;
+			void *end = (void *) ((uintptr_t) area->start + asize);
+			
+			/* Resize the address space area */
+			int ret = as_area_resize(area->start, asize, 0);
+			if (ret != EOK)
+				abort();
+			
+			/* Update heap area parameters */
+			area->end = end;
+			size_t excess = ((size_t) area->end) - ((size_t) last_head);
+			
+			if (excess > 0) {
+				if (excess >= STRUCT_OVERHEAD) {
+					/*
+					 * The previous block cannot be free and there
+					 * is enough free space left in the area to
+					 * create a new free block.
+					 */
+					block_init((void *) last_head, excess, true, area);
+				} else {
+					/*
+					 * The excess is small. Therefore just enlarge
+					 * the previous block.
+					 */
+					heap_block_foot_t *prev_foot = (heap_block_foot_t *)
+					    (((uintptr_t) last_head) - sizeof(heap_block_foot_t));
+					heap_block_head_t *prev_head = BLOCK_HEAD(prev_foot);
+					
+					block_check((void *) prev_head);
+					
+					block_init(prev_head, prev_head->size + excess,
+					    prev_head->free, area);
+				}
+			}
+		}
+	}
+	
+	next_fit = NULL;
 }
 
@@ -362,5 +514,5 @@
 static void split_mark(heap_block_head_t *cur, const size_t size)
 {
-	assert(cur->size >= size);
+	malloc_assert(cur->size >= size);
 	
 	/* See if we should split the block. */
@@ -398,9 +550,8 @@
 {
 	area_check((void *) area);
-	assert((void *) first_block >= (void *) AREA_FIRST_BLOCK(area));
-	assert((void *) first_block < area->end);
-	
-	heap_block_head_t *cur;
-	for (cur = first_block; (void *) cur < area->end;
+	malloc_assert((void *) first_block >= (void *) AREA_FIRST_BLOCK_HEAD(area));
+	malloc_assert((void *) first_block < area->end);
+	
+	for (heap_block_head_t *cur = first_block; (void *) cur < area->end;
 	    cur = (heap_block_head_t *) (((void *) cur) + cur->size)) {
 		block_check(cur);
@@ -425,5 +576,5 @@
 				split_mark(cur, real_size);
 				
-				next = cur;
+				next_fit = cur;
 				return addr;
 			} else {
@@ -436,5 +587,5 @@
 					 * data in (including alignment).
 					 */
-					if ((void *) cur > (void *) AREA_FIRST_BLOCK(area)) {
+					if ((void *) cur > (void *) AREA_FIRST_BLOCK_HEAD(area)) {
 						/*
 						 * There is a block before the current block.
@@ -477,5 +628,5 @@
 						split_mark(next_head, real_size);
 						
-						next = next_head;
+						next_fit = next_head;
 						return aligned;
 					} else {
@@ -496,12 +647,12 @@
 							size_t reduced_size = cur->size - excess;
 							cur = (heap_block_head_t *)
-							    (AREA_FIRST_BLOCK(area) + excess);
+							    (AREA_FIRST_BLOCK_HEAD(area) + excess);
 							
-							block_init((void *) AREA_FIRST_BLOCK(area), excess,
-							    true, area);
+							block_init((void *) AREA_FIRST_BLOCK_HEAD(area),
+							    excess, true, area);
 							block_init(cur, reduced_size, true, area);
 							split_mark(cur, real_size);
 							
-							next = cur;
+							next_fit = cur;
 							return aligned;
 						}
@@ -527,5 +678,5 @@
 static void *malloc_internal(const size_t size, const size_t align)
 {
-	assert(first_heap_area != NULL);
+	malloc_assert(first_heap_area != NULL);
 	
 	if (align == 0)
@@ -541,5 +692,5 @@
 	
 	/* Try the next fit approach */
-	split = next;
+	split = next_fit;
 	
 	if (split != NULL) {
@@ -552,8 +703,8 @@
 	
 	/* Search the entire heap */
-	heap_area_t *area;
-	for (area = first_heap_area; area != NULL; area = area->next) {
+	for (heap_area_t *area = first_heap_area; area != NULL;
+	    area = area->next) {
 		heap_block_head_t *first = (heap_block_head_t *)
-		    AREA_FIRST_BLOCK(area);
+		    AREA_FIRST_BLOCK_HEAD(area);
 		
 		void *addr = malloc_area(area, first, split, real_size,
@@ -652,11 +803,11 @@
 	
 	block_check(head);
-	assert(!head->free);
+	malloc_assert(!head->free);
 	
 	heap_area_t *area = head->area;
 	
 	area_check(area);
-	assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
-	assert((void *) head < area->end);
+	malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
+	malloc_assert((void *) head < area->end);
 	
 	void *ptr = NULL;
@@ -675,5 +826,5 @@
 			block_init((void *) head + real_size,
 			    orig_size - real_size, true, area);
-			heap_shrink();
+			heap_shrink(area);
 		}
 		
@@ -697,5 +848,5 @@
 			
 			ptr = ((void *) head) + sizeof(heap_block_head_t);
-			next = NULL;
+			next_fit = NULL;
 		} else
 			reloc = true;
@@ -729,11 +880,11 @@
 	
 	block_check(head);
-	assert(!head->free);
+	malloc_assert(!head->free);
 	
 	heap_area_t *area = head->area;
 	
 	area_check(area);
-	assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
-	assert((void *) head < area->end);
+	malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
+	malloc_assert((void *) head < area->end);
 	
 	/* Mark the block itself as free. */
@@ -751,5 +902,5 @@
 	
 	/* Look at the previous block. If it is free, merge the two. */
-	if ((void *) head > (void *) AREA_FIRST_BLOCK(area)) {
+	if ((void *) head > (void *) AREA_FIRST_BLOCK_HEAD(area)) {
 		heap_block_foot_t *prev_foot =
 		    (heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t));
@@ -765,9 +916,58 @@
 	}
 	
-	heap_shrink();
+	heap_shrink(area);
 	
 	futex_up(&malloc_futex);
 }
 
+void *heap_check(void)
+{
+	futex_down(&malloc_futex);
+	
+	if (first_heap_area == NULL) {
+		futex_up(&malloc_futex);
+		return (void *) -1;
+	}
+	
+	/* Walk all heap areas */
+	for (heap_area_t *area = first_heap_area; area != NULL;
+	    area = area->next) {
+		
+		/* Check heap area consistency */
+		if ((area->magic != HEAP_AREA_MAGIC) ||
+		    ((void *) area != area->start) ||
+		    (area->start >= area->end) ||
+		    (((uintptr_t) area->start % PAGE_SIZE) != 0) ||
+		    (((uintptr_t) area->end % PAGE_SIZE) != 0)) {
+			futex_up(&malloc_futex);
+			return (void *) area;
+		}
+		
+		/* Walk all heap blocks */
+		for (heap_block_head_t *head = (heap_block_head_t *)
+		    AREA_FIRST_BLOCK_HEAD(area); (void *) head < area->end;
+		    head = (heap_block_head_t *) (((void *) head) + head->size)) {
+			
+			/* Check heap block consistency */
+			if (head->magic != HEAP_BLOCK_HEAD_MAGIC) {
+				futex_up(&malloc_futex);
+				return (void *) head;
+			}
+			
+			heap_block_foot_t *foot = BLOCK_FOOT(head);
+			
+			if ((foot->magic != HEAP_BLOCK_FOOT_MAGIC) ||
+			    (head->size != foot->size)) {
+				futex_up(&malloc_futex);
+				return (void *) foot;
+			}
+		}
+	}
+	
+	futex_up(&malloc_futex);
+	
+	return NULL;
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/thread.c
===================================================================
--- uspace/lib/c/generic/thread.c	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/c/generic/thread.c	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -44,5 +44,5 @@
 
 #ifndef THREAD_INITIAL_STACK_PAGES_NO
-#define THREAD_INITIAL_STACK_PAGES_NO 1
+#define THREAD_INITIAL_STACK_PAGES_NO	2 
 #endif
 
Index: uspace/lib/c/include/adt/list.h
===================================================================
--- uspace/lib/c/include/adt/list.h	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/c/include/adt/list.h	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -49,8 +49,16 @@
  *
  */
-#define LIST_INITIALIZE(name)  link_t name = { \
-	.prev = &name, \
-	.next = &name \
-}
+#define LIST_INITIALIZE(name) \
+	link_t name = { \
+		.prev = &name, \
+		.next = &name \
+	}
+
+#define list_get_instance(link, type, member) \
+	((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
+
+#define list_foreach(list, iterator) \
+	for (link_t *iterator = (list).next; \
+	    iterator != &(list); iterator = iterator->next)
 
 /** Initialize doubly-linked circular list link
@@ -71,11 +79,11 @@
  * Initialize doubly-linked circular list.
  *
- * @param head Pointer to link_t structure representing head of the list.
- *
- */
-static inline void list_initialize(link_t *head)
-{
-	head->prev = head;
-	head->next = head;
+ * @param list Pointer to link_t structure representing the list.
+ *
+ */
+static inline void list_initialize(link_t *list)
+{
+	list->prev = list;
+	list->next = list;
 }
 
@@ -85,13 +93,13 @@
  *
  * @param link Pointer to link_t structure to be added.
- * @param head Pointer to link_t structure representing head of the list.
- *
- */
-static inline void list_prepend(link_t *link, link_t *head)
-{
-	link->next = head->next;
-	link->prev = head;
-	head->next->prev = link;
-	head->next = link;
+ * @param list Pointer to link_t structure representing the list.
+ *
+ */
+static inline void list_prepend(link_t *link, link_t *list)
+{
+	link->next = list->next;
+	link->prev = list;
+	list->next->prev = link;
+	list->next = link;
 }
 
@@ -101,25 +109,29 @@
  *
  * @param link Pointer to link_t structure to be added.
- * @param head Pointer to link_t structure representing head of the list.
- *
- */
-static inline void list_append(link_t *link, link_t *head)
-{
-	link->prev = head->prev;
-	link->next = head;
-	head->prev->next = link;
-	head->prev = link;
-}
-
-/** Insert item before another item in doubly-linked circular list. */
-static inline void list_insert_before(link_t *l, link_t *r)
-{
-	list_append(l, r);
-}
-
-/** Insert item after another item in doubly-linked circular list. */
-static inline void list_insert_after(link_t *r, link_t *l)
-{
-	list_prepend(l, r);
+ * @param list Pointer to link_t structure representing the list.
+ *
+ */
+static inline void list_append(link_t *link, link_t *list)
+{
+	link->prev = list->prev;
+	link->next = list;
+	list->prev->next = link;
+	list->prev = link;
+}
+
+/** Insert item before another item in doubly-linked circular list.
+ *
+ */
+static inline void list_insert_before(link_t *link, link_t *list)
+{
+	list_append(link, list);
+}
+
+/** Insert item after another item in doubly-linked circular list.
+ *
+ */
+static inline void list_insert_after(link_t *link, link_t *list)
+{
+	list_prepend(list, link);
 }
 
@@ -143,10 +155,23 @@
  * Query emptiness of doubly-linked circular list.
  *
- * @param head Pointer to link_t structure representing head of the list.
- *
- */
-static inline int list_empty(link_t *head)
-{
-	return ((head->next == head) ? 1 : 0);
+ * @param list Pointer to link_t structure representing the list.
+ *
+ */
+static inline int list_empty(link_t *list)
+{
+	return (list->next == list);
+}
+
+/** Get head item of a list.
+ *
+ * @param list Pointer to link_t structure representing the list.
+ *
+ * @return Head item of the list.
+ * @return NULL if the list is empty.
+ *
+ */
+static inline link_t *list_head(link_t *list)
+{
+	return ((list->next == list) ? NULL : list->next);
 }
 
@@ -205,10 +230,26 @@
 }
 
-#define list_get_instance(link, type, member) \
-	((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
-
-#define list_foreach(list, iterator) \
-	for (link_t *iterator = (list).next; \
-	    iterator != &(list); iterator = iterator->next)
+/** Get n-th item of a list.
+ *
+ * @param list Pointer to link_t structure representing the list.
+ * @param n    Item number (indexed from zero).
+ *
+ * @return n-th item of the list.
+ * @return NULL if no n-th item found.
+ *
+ */
+static inline link_t *list_nth(link_t *list, unsigned int n)
+{
+	unsigned int cnt = 0;
+	
+	list_foreach(*list, link) {
+		if (cnt == n)
+			return link;
+		
+		cnt++;
+	}
+	
+	return NULL;
+}
 
 extern int list_member(const link_t *, const link_t *);
Index: uspace/lib/c/include/as.h
===================================================================
--- uspace/lib/c/include/as.h	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/c/include/as.h	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -59,5 +59,5 @@
 extern int as_area_destroy(void *);
 extern void *set_maxheapsize(size_t);
-extern void * as_get_mappable_page(size_t);
+extern void *as_get_mappable_page(size_t);
 extern int as_get_physical_mapping(void *, uintptr_t *);
 
Index: uspace/lib/c/include/io/klog.h
===================================================================
--- uspace/lib/c/include/io/klog.h	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/c/include/io/klog.h	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -37,7 +37,10 @@
 
 #include <sys/types.h>
+#include <stdarg.h>
 
 extern size_t klog_write(const void *, size_t);
 extern void klog_update(void);
+extern int klog_printf(const char *, ...);
+extern int klog_vprintf(const char *, va_list);
 
 #endif
Index: uspace/lib/c/include/malloc.h
===================================================================
--- uspace/lib/c/include/malloc.h	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/c/include/malloc.h	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -46,4 +46,5 @@
 extern void *realloc(const void *addr, const size_t size);
 extern void free(const void *addr);
+extern void *heap_check(void);
 
 #endif
Index: uspace/lib/net/il/ip_client.c
===================================================================
--- uspace/lib/net/il/ip_client.c	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/net/il/ip_client.c	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -181,6 +181,6 @@
 	/* Set the header */
 	header = (ip_header_t *) data;
-	header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) +
-	    ipopt_length);
+	SET_IP_HEADER_LENGTH(header,
+	    (IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + ipopt_length)));
 	header->ttl = (ttl ? ttl : IPDEFTTL);
 	header->tos = tos;
@@ -188,5 +188,5 @@
 
 	if (dont_fragment)
-		header->flags = IPFLAG_DONT_FRAGMENT;
+		SET_IP_HEADER_FLAGS(header, IPFLAG_DONT_FRAGMENT);
 
 	return EOK;
@@ -227,5 +227,5 @@
 		*tos = header->tos;
 	if (dont_fragment)
-		*dont_fragment = header->flags & IPFLAG_DONT_FRAGMENT;
+		*dont_fragment = GET_IP_HEADER_FLAGS(header) & IPFLAG_DONT_FRAGMENT;
 	if (ipopt_length) {
 		*ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t);
Index: uspace/lib/net/include/ip_header.h
===================================================================
--- uspace/lib/net/include/ip_header.h	(revision 0dd3e498af91491a8e5cdafa529a40b6d1dfa610)
+++ uspace/lib/net/include/ip_header.h	(revision c9f09755b7b55efc26590633dc8d734d40835ae9)
@@ -64,5 +64,5 @@
  */
 #define IP_FRAGMENT_OFFSET(header) \
-	((((header)->fragment_offset_high << 8) + \
+	(((GET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header) << 8) + \
 	    (header)->fragment_offset_low) * 8U)
 
@@ -83,5 +83,5 @@
  */
 #define IP_HEADER_LENGTH(header) \
-	((header)->header_length * 4U)
+	(GET_IP_HEADER_LENGTH(header) * 4U)
 
 /** Returns the actual IP packet total length.
@@ -143,11 +143,17 @@
  */
 struct ip_header {
-#ifdef ARCH_IS_BIG_ENDIAN
-	uint8_t version : 4;
-	uint8_t header_length : 4;
-#else
-	uint8_t header_length : 4;
-	uint8_t version : 4;
-#endif
+	uint8_t vhl; /* version, header_length */
+
+#define GET_IP_HEADER_VERSION(header) \
+	(((header)->vhl & 0xf0) >> 4)
+#define SET_IP_HEADER_VERSION(header, version) \
+	((header)->vhl = \
+	 ((version & 0x0f) << 4) | ((header)->vhl & 0x0f))
+
+#define GET_IP_HEADER_LENGTH(header) \
+	((header)->vhl & 0x0f)
+#define SET_IP_HEADER_LENGTH(header, length) \
+	((header)->vhl = \
+	 (length & 0x0f) | ((header)->vhl & 0xf0))
 
 	uint8_t tos;
@@ -155,11 +161,17 @@
 	uint16_t identification;
 
-#ifdef ARCH_IS_BIG_ENDIAN
-	uint8_t flags : 3;
-	uint8_t fragment_offset_high : 5;
-#else
-	uint8_t fragment_offset_high : 5;
-	uint8_t flags : 3;
-#endif
+	uint8_t ffoh; /* flags, fragment_offset_high */
+
+#define GET_IP_HEADER_FLAGS(header) \
+	(((header)->ffoh & 0xe0) >> 5)
+#define SET_IP_HEADER_FLAGS(header, flags) \
+	((header)->ffoh = \
+	 ((flags & 0x07) << 5) | ((header)->ffoh & 0x1f))
+
+#define GET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header) \
+	((header)->ffoh & 0x1f)
+#define SET_IP_HEADER_FRAGMENT_OFFSET_HIGH(header, fragment_offset_high) \
+	((header)->ffoh = \
+	 (fragment_offset_high & 0x1f) | ((header)->ffoh & 0xe0))
 
 	uint8_t fragment_offset_low;
@@ -181,11 +193,18 @@
 	uint8_t pointer;
 
-#ifdef ARCH_IS_BIG_ENDIAN
-	uint8_t overflow : 4;
-	uint8_t flags : 4;
-#else
-	uint8_t flags : 4;
-	uint8_t overflow : 4;
-#endif
+	uint8_t of; /* overflow, flags */
+
+#define GET_IP_OPTION_OVERFLOW(option) \
+	(((option)->of & 0xf0) >> 4)
+#define SET_IP_OPTION_OVERFLOW(option, overflow) \
+	((option)->of = \
+	 ((overflow & 0x0f) << 4) | ((option)->of & 0x0f))
+
+#define GET_IP_OPTION_FLAGS(option) \
+	((option)->of & 0x0f)
+#define SET_IP_OPTION_FLAGS(option, flags) \
+	((option)->of = \
+	 (flags & 0x0f) | ((option)->of & 0xf0))
+
 } __attribute__ ((packed));
 
