Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,5 +38,4 @@
 	app/bithenge \
 	app/blkdump \
-	app/bnchmark \
 	app/contacts \
 	app/corecfg \
@@ -51,4 +50,5 @@
 	app/getterm \
 	app/gunzip \
+	app/hbench \
 	app/init \
 	app/inet \
@@ -58,4 +58,5 @@
 	app/loc \
 	app/logset \
+	app/lprint \
 	app/mixerctl \
 	app/mkfat \
@@ -66,5 +67,5 @@
 	app/netecho \
 	app/nterm \
-	app/perf \
+	app/pci \
 	app/redir \
 	app/sbi \
@@ -151,4 +152,5 @@
 	drv/block/ddisk \
 	drv/block/usbmast \
+	drv/block/virtio-blk \
 	drv/bus/adb/cuda_adb \
 	drv/bus/isa \
@@ -166,4 +168,6 @@
 	drv/char/msim-con \
 	drv/char/ns8250 \
+	drv/char/pc-lpt \
+	drv/char/pl011 \
 	drv/char/pl050 \
 	drv/char/ski-con \
@@ -178,4 +182,5 @@
 	drv/hid/xtkbd \
 	drv/intctl/apic \
+	drv/intctl/gicv2 \
 	drv/intctl/i8259 \
 	drv/intctl/icp-ic \
@@ -188,4 +193,5 @@
 	drv/nic/virtio-net \
 	drv/platform/amdm37x \
+	drv/platform/arm64virt \
 	drv/platform/icp \
 	drv/platform/mac \
@@ -274,4 +280,5 @@
 
 export: $(BUILDS)
+	mkdir -p $(EXPORT_DIR)
 	$(MAKE) -r -C lib/posix export EXPORT_DIR=$(EXPORT_DIR)
 
Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -120,6 +120,14 @@
 		STATIC_BUILD = y
 	else
-		ifeq ($(CONFIG_USE_SHARED_LIBS),y)
-			STATIC_BUILD = n
+		ifeq ($(CONFIG_BUILD_SHARED_LIBS),y)
+			ifeq ($(CONFIG_USE_SHARED_LIBS),y)
+				STATIC_BUILD = n
+			else
+				ifeq ($(LIBRARY),)
+					STATIC_BUILD = y
+				else
+					STATIC_BUILD = n
+				endif
+			endif
 		else
 			STATIC_BUILD = y
@@ -300,4 +308,8 @@
 LIBARGS := $(addprefix -L$(USPACE_PREFIX)/lib/, $(LIBS)) $(addprefix -l, $(LIBS))
 
+ifneq ($(LIBRARY),libc)
+	LIBTAGS := $(LIBC_PREFIX)/tag $(LIBTAGS)
+endif
+
 .PHONY: all all-test clean fasterclean depend
 
@@ -369,5 +381,5 @@
 	$(AR) rc $@ $(LOBJECTS)
 
-$(SLIBRARY): $(LIBRARY).la
+$(SLIBRARY): $(LIBRARY).la $(LIBTAGS)
 	$(CC) $(CFLAGS) $(LIB_LDFLAGS) $(EXTRA_LDFLAGS) -Wl,-Map,$@.map -o $@ -Wl,--whole-archive $(LIBRARY).la -Wl,--no-whole-archive $(LIBARGS) $(BASE_LIBS)
 
Index: uspace/app/bdsh/Makefile
===================================================================
--- uspace/app/bdsh/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,4 +34,6 @@
 
 SOURCES = \
+	cmds/modules/module_aliases.c \
+	cmds/modules/modules.c \
 	cmds/modules/help/help.c \
 	cmds/modules/mkdir/mkdir.c \
@@ -51,4 +53,6 @@
 	cmds/modules/kcon/kcon.c \
 	cmds/modules/cmp/cmp.c \
+	cmds/builtins/builtin_aliases.c \
+	cmds/builtins/builtins.c \
 	cmds/builtins/batch/batch.c \
 	cmds/builtins/exit/exit.c \
Index: uspace/app/bdsh/cmds/builtins/builtin_aliases.c
===================================================================
--- uspace/app/bdsh/cmds/builtins/builtin_aliases.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/bdsh/cmds/builtins/builtin_aliases.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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.
+ */
+
+#ifndef BUILTIN_ALIASES_H
+#define BUILTIN_ALIASES_H
+
+#include <stdlib.h>
+#include "builtin_aliases.h"
+
+/* See modules/module_aliases.h for an explanation of this file */
+
+char *builtin_aliases[] = {
+	NULL, NULL
+};
+
+#endif
Index: uspace/app/bdsh/cmds/builtins/builtin_aliases.h
===================================================================
--- uspace/app/bdsh/cmds/builtins/builtin_aliases.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/builtins/builtin_aliases.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,10 +1,34 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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.
+ */
+
 #ifndef BUILTIN_ALIASES_H
 #define BUILTIN_ALIASES_H
 
-/* See modules/module_aliases.h for an explanation of this file */
-
-char *builtin_aliases[] = {
-	NULL, NULL
-};
+extern char *builtin_aliases[];
 
 #endif
Index: uspace/app/bdsh/cmds/builtins/builtins.c
===================================================================
--- uspace/app/bdsh/cmds/builtins/builtins.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/bdsh/cmds/builtins/builtins.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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 <stdlib.h>
+#include "builtins.h"
+
+#include "batch/entry.h"
+#include "cd/entry.h"
+#include "exit/entry.h"
+
+builtin_t builtins[] = {
+#include "batch/batch_def.inc"
+#include "cd/cd_def.inc"
+#include "exit/exit_def.inc"
+	{ NULL, NULL, NULL, NULL, 0 }
+};
Index: uspace/app/bdsh/cmds/builtins/builtins.h
===================================================================
--- uspace/app/bdsh/cmds/builtins/builtins.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/builtins/builtins.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,17 +1,36 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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.
+ */
+
 #ifndef BUILTINS_H
 #define BUILTINS_H
 
-#include "config.h"
+#include "../cmds.h"
 
-#include "batch/entry.h"
-#include "cd/entry.h"
-#include "exit/entry.h"
-
-builtin_t builtins[] = {
-#include "batch/batch_def.inc"
-#include "cd/cd_def.inc"
-#include "exit/exit_def.inc"
-	{ NULL, NULL, NULL, NULL, 0 }
-};
+extern builtin_t builtins[];
 
 #endif
Index: uspace/app/bdsh/cmds/mknewcmd
===================================================================
--- uspace/app/bdsh/cmds/mknewcmd	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/mknewcmd	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -213,5 +213,5 @@
 	printf " to include your new command.\n"
 	[ -n "$CMDALIAS" ] &&  {
-		printf "\nYou should also modify %ss/%s_aliases.h and " \
+		printf "\nYou should also modify %ss/%s_aliases.c and " \
 			"${CMDTYPE}" "${CMDTYPE}"
 		printf "add %s as an alias for %s\n" \
Index: uspace/app/bdsh/cmds/modules/ls/ls.c
===================================================================
--- uspace/app/bdsh/cmds/modules/ls/ls.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/modules/ls/ls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -267,5 +267,5 @@
 
 	/* Populate the directory list. */
-	if (ls.recursive) {
+	if (ls.recursive && nbdirs > 0) {
 		tmp = (struct dir_elem_t *) realloc(*dir_list_ptr,
 		    nbdirs * sizeof(struct dir_elem_t));
Index: uspace/app/bdsh/cmds/modules/module_aliases.c
===================================================================
--- uspace/app/bdsh/cmds/modules/module_aliases.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/bdsh/cmds/modules/module_aliases.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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 <stdlib.h>
+#include "module_aliases.h"
+
+/*
+ * Modules that declare multiple names for themselves but use the
+ * same entry functions are aliases. This array helps to determine if
+ * a module is an alias, as such it can be invoked differently.
+ * format is alias , real_name
+ */
+
+/*
+ * So far, this is only used in the help display but could be used to
+ * handle a module differently even prior to reaching its entry code.
+ * For instance, 'exit' could behave differently than 'quit', prior to
+ * the entry point being reached.
+ */
+
+const char *mod_aliases[] = {
+	"ren", "mv",
+	"umount", "unmount",
+	NULL, NULL
+};
Index: uspace/app/bdsh/cmds/modules/module_aliases.h
===================================================================
--- uspace/app/bdsh/cmds/modules/module_aliases.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/modules/module_aliases.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,23 +30,5 @@
 #define MODULE_ALIASES_H
 
-/*
- * Modules that declare multiple names for themselves but use the
- * same entry functions are aliases. This array helps to determine if
- * a module is an alias, as such it can be invoked differently.
- * format is alias , real_name
- */
-
-/*
- * So far, this is only used in the help display but could be used to
- * handle a module differently even prior to reaching its entry code.
- * For instance, 'exit' could behave differently than 'quit', prior to
- * the entry point being reached.
- */
-
-const char *mod_aliases[] = {
-	"ren", "mv",
-	"umount", "unmount",
-	NULL, NULL
-};
+extern const char *mod_aliases[];
 
 #endif
Index: uspace/app/bdsh/cmds/modules/modules.c
===================================================================
--- uspace/app/bdsh/cmds/modules/modules.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/bdsh/cmds/modules/modules.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2008 Tim Post
+ * 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.
+ */
+
+/*
+ * Each built in function has two files, one being an entry.h file which
+ * prototypes the run/help entry functions, the other being a .def file
+ * which fills the modules[] array according to the cmd_t structure
+ * defined in cmds.h.
+ *
+ * To add or remove a module, just make a new directory in cmds/modules
+ * for it and copy the 'show' example for basics, then include it here.
+ * (or reverse the process to remove one)
+ *
+ * NOTE: See module_ aliases.h as well, this is where aliases (commands that
+ * share an entry point with others) are indexed
+ */
+
+#include "config.h"
+#include "modules.h"
+
+/* Prototypes for each module's entry (help/exec) points */
+
+#include "help/entry.h"
+#include "mkdir/entry.h"
+#include "mkfile/entry.h"
+#include "rm/entry.h"
+#include "cat/entry.h"
+#include "touch/entry.h"
+#include "ls/entry.h"
+#include "pwd/entry.h"
+#include "sleep/entry.h"
+#include "cp/entry.h"
+#include "mv/entry.h"
+#include "mount/entry.h"
+#include "unmount/entry.h"
+#include "kcon/entry.h"
+#include "printf/entry.h"
+#include "echo/entry.h"
+#include "cmp/entry.h"
+
+/*
+ * Each .def function fills the module_t struct with the individual name, entry
+ * point, help entry point, etc. You can use config.h to control what modules
+ * are loaded based on what libraries exist on the system.
+ */
+
+module_t modules[] = {
+#include "help/help_def.inc"
+#include "mkdir/mkdir_def.inc"
+#include "mkfile/mkfile_def.inc"
+#include "rm/rm_def.inc"
+#include "cat/cat_def.inc"
+#include "touch/touch_def.inc"
+#include "ls/ls_def.inc"
+#include "pwd/pwd_def.inc"
+#include "sleep/sleep_def.inc"
+#include "cp/cp_def.inc"
+#include "mv/mv_def.inc"
+#include "mount/mount_def.inc"
+#include "unmount/unmount_def.inc"
+#include "kcon/kcon_def.inc"
+#include "printf/printf_def.inc"
+#include "echo/echo_def.inc"
+#include "cmp/cmp_def.inc"
+
+	{ NULL, NULL, NULL, NULL }
+};
Index: uspace/app/bdsh/cmds/modules/modules.h
===================================================================
--- uspace/app/bdsh/cmds/modules/modules.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/modules/modules.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,67 +30,8 @@
 #define MODULES_H
 
-/*
- * Each built in function has two files, one being an entry.h file which
- * prototypes the run/help entry functions, the other being a .def file
- * which fills the modules[] array according to the cmd_t structure
- * defined in cmds.h.
- *
- * To add or remove a module, just make a new directory in cmds/modules
- * for it and copy the 'show' example for basics, then include it here.
- * (or reverse the process to remove one)
- *
- * NOTE: See module_ aliases.h as well, this is where aliases (commands that
- * share an entry point with others) are indexed
- */
+#include "../cmds.h"
+#include "modules.h"
 
-#include "config.h"
-
-/* Prototypes for each module's entry (help/exec) points */
-
-#include "help/entry.h"
-#include "mkdir/entry.h"
-#include "mkfile/entry.h"
-#include "rm/entry.h"
-#include "cat/entry.h"
-#include "touch/entry.h"
-#include "ls/entry.h"
-#include "pwd/entry.h"
-#include "sleep/entry.h"
-#include "cp/entry.h"
-#include "mv/entry.h"
-#include "mount/entry.h"
-#include "unmount/entry.h"
-#include "kcon/entry.h"
-#include "printf/entry.h"
-#include "echo/entry.h"
-#include "cmp/entry.h"
-
-/*
- * Each .def function fills the module_t struct with the individual name, entry
- * point, help entry point, etc. You can use config.h to control what modules
- * are loaded based on what libraries exist on the system.
- */
-
-module_t modules[] = {
-#include "help/help_def.inc"
-#include "mkdir/mkdir_def.inc"
-#include "mkfile/mkfile_def.inc"
-#include "rm/rm_def.inc"
-#include "cat/cat_def.inc"
-#include "touch/touch_def.inc"
-#include "ls/ls_def.inc"
-#include "pwd/pwd_def.inc"
-#include "sleep/sleep_def.inc"
-#include "cp/cp_def.inc"
-#include "mv/mv_def.inc"
-#include "mount/mount_def.inc"
-#include "unmount/unmount_def.inc"
-#include "kcon/kcon_def.inc"
-#include "printf/printf_def.inc"
-#include "echo/echo_def.inc"
-#include "cmp/cmp_def.inc"
-
-	{ NULL, NULL, NULL, NULL }
-};
+extern module_t modules[];
 
 #endif
Index: uspace/app/bdsh/cmds/modules/sleep/sleep.c
===================================================================
--- uspace/app/bdsh/cmds/modules/sleep/sleep.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/cmds/modules/sleep/sleep.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#include <async.h>
 #include <errno.h>
+#include <fibril.h>
 #include <stdio.h>
 #include <stdlib.h>
Index: uspace/app/bdsh/compl.c
===================================================================
--- uspace/app/bdsh/compl.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/compl.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,4 +40,5 @@
 #include "exec.h"
 #include "tok.h"
+#include "util.h"
 
 static errno_t compl_init(wchar_t *text, size_t pos, size_t *cstart, void **state);
@@ -209,6 +210,4 @@
 		}
 		*cstart += rpath_sep + 1 - prefix;
-		free(prefix);
-		prefix = NULL;
 
 		cs->path_list = malloc(sizeof(char *) * 2);
@@ -217,5 +216,22 @@
 			goto error;
 		}
-		cs->path_list[0] = dirname;
+
+		if (!is_path(prefix) && cs->is_command) {
+			cs->path_list[0] = malloc(sizeof(char) * PATH_MAX);
+			if (cs->path_list[0] == NULL) {
+				retval = ENOMEM;
+				goto error;
+			}
+
+			int ret = snprintf(cs->path_list[0], PATH_MAX, "%s/%s", search_dir[0], dirname);
+			if (ret < 0 || ret >= PATH_MAX) {
+				retval = ENOMEM;
+				goto error;
+			}
+		} else {
+			cs->path_list[0] = dirname;
+		}
+
+		free(prefix);
 		cs->path_list[1] = NULL;
 		/*
Index: uspace/app/bdsh/exec.c
===================================================================
--- uspace/app/bdsh/exec.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/exec.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,8 +47,5 @@
 #include "errors.h"
 
-/* FIXME: Just have find_command() return an allocated string */
-static char *found;
-
-static char *find_command(char *);
+static errno_t find_command(char *, char **);
 static int try_access(const char *);
 
@@ -68,30 +65,48 @@
 }
 
-/** Returns the full path of "cmd" if cmd is found
+/** Returns EOK if no internal failure or else ENOMEM
  *
- * else just hand back cmd as it was presented
+ * When the parameter `cmd` can be found then the absolute path will be set in `found`.
+ * Or else `found` will be NULL.
+ * `found` will be newly allocated and must be freed by the caller
  */
-static char *find_command(char *cmd)
+static errno_t find_command(char *cmd, char **found)
 {
-	size_t i;
+	/* The user has specified a full or relative path, just give it back. */
+	if (is_path(cmd)) {
+		if (-1 != try_access(cmd)) {
+			*found = str_dup(cmd);
+			return EOK;
+		}
 
-	found = (char *)malloc(PATH_MAX);
+		*found = NULL;
+		return EOK;
+	}
 
-	/* The user has specified a full or relative path, just give it back. */
-	if (-1 != try_access(cmd)) {
-		return (char *) cmd;
+	*found = (char *)malloc(PATH_MAX);
+	if (*found == NULL) {
+		return ENOMEM;
 	}
 
 	/* We now have n places to look for the command */
+	size_t i;
+	size_t cmd_length = str_length(cmd);
 	for (i = 0; search_dir[i] != NULL; i++) {
-		memset(found, 0, PATH_MAX);
-		snprintf(found, PATH_MAX, "%s/%s", search_dir[i], cmd);
-		if (-1 != try_access(found)) {
-			return (char *) found;
+		if (str_length(search_dir[i]) + cmd_length + 2 > PATH_MAX) {
+			free(*found);
+			return ENOMEM;
+		}
+
+		memset(*found, 0, PATH_MAX);
+		snprintf(*found, PATH_MAX, "%s/%s", search_dir[i], cmd);
+		if (-1 != try_access(*found)) {
+			return EOK;
 		}
 	}
+	free(*found);
+	*found = NULL;
 
-	/* We didn't find it, just give it back as-is. */
-	return (char *) cmd;
+	/* We didn't find it, return NULL */
+	return EOK;
 }
 
@@ -107,6 +122,14 @@
 	FILE *files[3];
 
-	tmp = str_dup(find_command(cmd));
-	free(found);
+	rc = find_command(cmd, &tmp);
+	if (rc != EOK) {
+		cli_error(CL_ENOMEM, "%s: failure executing find_command()", progname);
+		return 1;
+	}
+
+	if (tmp == NULL) {
+		cli_error(CL_EEXEC, "%s: Command not found '%s'", progname, cmd);
+		return 1;
+	}
 
 	files[0] = io->stdin;
Index: uspace/app/bdsh/util.c
===================================================================
--- uspace/app/bdsh/util.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/util.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -74,2 +74,15 @@
 	return 0;
 }
+
+/*
+ * Returns true if the string is a relative or an absolute path
+ */
+bool is_path(const char *cmd)
+{
+
+	bool ret = str_lcmp(cmd, "/", 1) == 0;
+	ret = ret || str_lcmp(cmd, "./", 2) == 0;
+	ret = ret || str_lcmp(cmd, "../", 3) == 0;
+
+	return ret;
+}
Index: uspace/app/bdsh/util.h
===================================================================
--- uspace/app/bdsh/util.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/bdsh/util.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,8 +31,10 @@
 
 #include "scli.h"
+#include <stdbool.h>
 
 /* Utility functions */
 extern unsigned int cli_count_args(char **);
 extern unsigned int cli_set_prompt(cliuser_t *usr);
+extern bool is_path(const char *cmd);
 
 #endif
Index: uspace/app/bnchmark/Makefile
===================================================================
--- uspace/app/bnchmark/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#
-# Copyright (c) 2011 Martin Sucha
-# 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.
-#
-
-USPACE_PREFIX = ../..
-BINARY = bnchmark
-
-SOURCES = \
-	bnchmark.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/bnchmark/bnchmark.c
===================================================================
--- uspace/app/bnchmark/bnchmark.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,213 +1,0 @@
-/*
- * Copyright (c) 2011 Martin Sucha
- * 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.
- */
-
-/** @addtogroup bnchmark
- * @{
- */
-
-/**
- * @file	bnchmark.c
- * This program measures time for various actions and writes the results
- * to a file.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <str_error.h>
-#include <mem.h>
-#include <loc.h>
-#include <byteorder.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <time.h>
-#include <dirent.h>
-#include <str.h>
-
-#define NAME	"bnchmark"
-#define BUFSIZE 8096
-#define MBYTE (1024*1024)
-
-typedef errno_t (*measure_func_t)(void *);
-
-static void syntax_print(void);
-
-static errno_t measure(measure_func_t fn, void *data, msec_t *result)
-{
-	struct timespec start_time;
-	getuptime(&start_time);
-
-	errno_t rc = fn(data);
-	if (rc != EOK) {
-		fprintf(stderr, "measured function failed\n");
-		return rc;
-	}
-
-	struct timespec final_time;
-	getuptime(&final_time);
-
-	/* Calculate time difference in milliseconds */
-	*result = NSEC2USEC(ts_sub_diff(&final_time, &start_time));
-	return EOK;
-}
-
-static errno_t sequential_read_file(void *data)
-{
-	char *path = (char *) data;
-	char *buf = malloc(BUFSIZE);
-
-	if (buf == NULL)
-		return ENOMEM;
-
-	FILE *file = fopen(path, "r");
-	if (file == NULL) {
-		fprintf(stderr, "Failed opening file: %s\n", path);
-		free(buf);
-		return EIO;
-	}
-
-	while (!feof(file)) {
-		fread(buf, 1, BUFSIZE, file);
-		if (ferror(file)) {
-			fprintf(stderr, "Failed reading file\n");
-			fclose(file);
-			free(buf);
-			return EIO;
-		}
-	}
-
-	fclose(file);
-	free(buf);
-	return EOK;
-}
-
-static errno_t sequential_read_dir(void *data)
-{
-	char *path = (char *) data;
-
-	DIR *dir = opendir(path);
-	if (dir == NULL) {
-		fprintf(stderr, "Failed opening directory: %s\n", path);
-		return EIO;
-	}
-
-	struct dirent *dp;
-
-	while ((dp = readdir(dir))) {
-		/* Do nothing */
-	}
-
-	closedir(dir);
-	return EOK;
-}
-
-int main(int argc, char **argv)
-{
-	errno_t rc;
-	msec_t milliseconds_taken = 0;
-	char *path = NULL;
-	measure_func_t fn = NULL;
-	int iteration;
-	int iterations;
-	char *log_str = NULL;
-	char *test_type = NULL;
-	char *endptr;
-
-	if (argc < 5) {
-		fprintf(stderr, NAME ": Error, argument missing.\n");
-		syntax_print();
-		return 1;
-	}
-
-	if (argc > 5) {
-		fprintf(stderr, NAME ": Error, too many arguments.\n");
-		syntax_print();
-		return 1;
-	}
-
-	// Skip program name
-	--argc;
-	++argv;
-
-	iterations = strtol(*argv, &endptr, 10);
-	if (*endptr != '\0') {
-		printf(NAME ": Error, invalid argument (iterations).\n");
-		syntax_print();
-		return 1;
-	}
-
-	--argc;
-	++argv;
-	test_type = *argv;
-
-	--argc;
-	++argv;
-	log_str = *argv;
-
-	--argc;
-	++argv;
-	path = *argv;
-
-	if (str_cmp(test_type, "sequential-file-read") == 0) {
-		fn = sequential_read_file;
-	} else if (str_cmp(test_type, "sequential-dir-read") == 0) {
-		fn = sequential_read_dir;
-	} else {
-		fprintf(stderr, "Error, unknown test type\n");
-		syntax_print();
-		return 1;
-	}
-
-	for (iteration = 0; iteration < iterations; iteration++) {
-		rc = measure(fn, path, &milliseconds_taken);
-		if (rc != EOK) {
-			fprintf(stderr, "Error: %s\n", str_error(rc));
-			return 1;
-		}
-
-		printf("%s;%s;%s;%lld;ms\n", test_type, path, log_str, milliseconds_taken);
-	}
-
-	return 0;
-}
-
-static void syntax_print(void)
-{
-	fprintf(stderr, "syntax: " NAME " <iterations> <test type> <log-str> <path>\n");
-	fprintf(stderr, "  <iterations>    number of times to run a given test\n");
-	fprintf(stderr, "  <test-type>     one of:\n");
-	fprintf(stderr, "                    sequential-file-read\n");
-	fprintf(stderr, "                    sequential-dir-read\n");
-	fprintf(stderr, "  <log-str>       a string to attach to results\n");
-	fprintf(stderr, "  <path>          file/directory to use for testing\n");
-}
-
-/**
- * @}
- */
Index: uspace/app/bnchmark/doc/doxygroups.h
===================================================================
--- uspace/app/bnchmark/doc/doxygroups.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,4 +1,0 @@
-/** @addtogroup bnchmark bnchmark
- * @brief Benchmarking application
- * @ingroup apps
- */
Index: uspace/app/contacts/contacts.c
===================================================================
--- uspace/app/contacts/contacts.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/contacts/contacts.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -526,5 +526,5 @@
 {
 	errno_t rc;
-	contacts_t *contacts;
+	contacts_t *contacts = NULL;
 
 	rc = contacts_open("contacts.sif", &contacts);
Index: uspace/app/df/df.c
===================================================================
--- uspace/app/df/df.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/df/df.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -70,5 +70,5 @@
 
 	/* Parse command-line options */
-	while ((optres = getopt(argc, argv, ":ubh")) != -1) {
+	while ((optres = getopt(argc, argv, "ubh")) != -1) {
 		switch (optres) {
 		case 'h':
@@ -78,10 +78,4 @@
 		case 'b':
 			display_blocks = true;
-			break;
-
-		case ':':
-			fprintf(stderr, "Option -%c requires an operand\n",
-			    optopt);
-			errflg++;
 			break;
 
Index: uspace/app/dltest/dltest.c
===================================================================
--- uspace/app/dltest/dltest.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/dltest/dltest.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -91,4 +91,30 @@
 }
 
+/** Test calling function that calls a function that returns a constant */
+static bool test_dlfcn_dl_get_constant_via_call(void)
+{
+	int (*p_dl_get_constant)(void);
+	int val;
+
+	printf("Call dlsym/dl_get_constant_via_call...\n");
+
+	p_dl_get_constant = dlsym(handle, "dl_get_constant_via_call");
+	if (p_dl_get_constant == NULL) {
+		printf("FAILED\n");
+		return false;
+	}
+
+	val = p_dl_get_constant();
+
+	printf("Got %d, expected %d... ", val, dl_constant);
+	if (val != dl_constant) {
+		printf("FAILED\n");
+		return false;
+	}
+
+	printf("Passed\n");
+	return true;
+}
+
 /** Test calling a function that returns contents of a private initialized
  * variable.
@@ -564,4 +590,23 @@
 }
 
+/** Test directly calling function that calls a function that returns a constant */
+static bool test_lnk_dl_get_constant_via_call(void)
+{
+	int val;
+
+	printf("Call linked dl_get_constant_via_call...\n");
+
+	val = dl_get_constant_via_call();
+
+	printf("Got %d, expected %d... ", val, dl_constant);
+	if (val != dl_constant) {
+		printf("FAILED\n");
+		return false;
+	}
+
+	printf("Passed\n");
+	return true;
+}
+
 /** Test dircetly calling a function that returns contents of a private
  * initialized variable.
@@ -853,4 +898,7 @@
 		return 1;
 
+	if (!test_dlfcn_dl_get_constant_via_call())
+		return 1;
+
 	if (!test_dlfcn_dl_get_private_var())
 		return 1;
@@ -905,4 +953,7 @@
 {
 	if (!test_lnk_dl_get_constant())
+		return 1;
+
+	if (!test_lnk_dl_get_constant_via_call())
 		return 1;
 
Index: uspace/app/hbench/Makefile
===================================================================
--- uspace/app/hbench/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2018 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.
+#
+
+USPACE_PREFIX = ../..
+
+LIBS = math
+
+BINARY = hbench
+
+SOURCES = \
+	benchlist.c \
+	csv.c \
+	env.c \
+	main.c \
+	utils.c \
+	fs/dirread.c \
+	fs/fileread.c \
+	ipc/ns_ping.c \
+	ipc/ping_pong.c \
+	malloc/malloc1.c \
+	malloc/malloc2.c \
+	synch/fibril_mutex.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/hbench/benchlist.c
===================================================================
--- uspace/app/hbench/benchlist.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/benchlist.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * Copyright (c) 2018 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdlib.h>
+#include "hbench.h"
+
+benchmark_t *benchmarks[] = {
+	&benchmark_dir_read,
+	&benchmark_fibril_mutex,
+	&benchmark_file_read,
+	&benchmark_malloc1,
+	&benchmark_malloc2,
+	&benchmark_ns_ping,
+	&benchmark_ping_pong
+};
+
+size_t benchmark_count = sizeof(benchmarks) / sizeof(benchmarks[0]);
+
+/** @}
+ */
Index: uspace/app/hbench/csv.c
===================================================================
--- uspace/app/hbench/csv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/csv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2019 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "hbench.h"
+
+static FILE *csv_output = NULL;
+
+/** Open CSV benchmark report.
+ *
+ * @param filename Filename where to store the CSV.
+ * @return Whether it was possible to open the file.
+ */
+errno_t csv_report_open(const char *filename)
+{
+	csv_output = fopen(filename, "w");
+	if (csv_output == NULL) {
+		return errno;
+	}
+
+	fprintf(csv_output, "benchmark,run,size,duration_nanos\n");
+
+	return EOK;
+}
+
+/** Add one entry to the report.
+ *
+ * When csv_report_open() was not called or failed, the function does
+ * nothing.
+ *
+ * @param run Performance data of the entry.
+ * @param run_index Run index, use negative values for warm-up.
+ * @param bench Benchmark information.
+ * @param workload_size Workload size.
+ */
+void csv_report_add_entry(bench_run_t *run, int run_index,
+    benchmark_t *bench, uint64_t workload_size)
+{
+	if (csv_output == NULL) {
+		return;
+	}
+
+	fprintf(csv_output, "%s,%d,%" PRIu64 ",%lld\n",
+	    bench->name, run_index, workload_size,
+	    (long long) stopwatch_get_nanos(&run->stopwatch));
+}
+
+/** Close CSV report.
+ *
+ * When csv_report_open() was not called or failed, the function does
+ * nothing.
+ */
+void csv_report_close(void)
+{
+	if (csv_output != NULL) {
+		fclose(csv_output);
+	}
+}
+
+/** @}
+ */
Index: uspace/app/hbench/doc/doxygroups.h
===================================================================
--- uspace/app/hbench/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,44 @@
+/** @addtogroup hbench hbench
+ * @brief User space benchmarks
+ * @ingroup apps
+ *
+ * @details
+ *
+ * To add a new benchmark, you need to implement the actual benchmarking
+ * code and register it.
+ *
+ * Registration is done by adding
+ * <code>extern benchmark_t bench_YOUR_NAME</code> reference to benchlist.h
+ * and by adding it to the array in benchlist.c.
+ *
+ * The actual benchmark should reside in a separate file (see malloc/malloc1.c
+ * for example) and has to (at least) declare one function (the actual
+ * benchmark) and fill-in the benchmark_t structure.
+ *
+ * Fill-in the name of the benchmark, its description and a reference to the
+ * benchmark function to the benchmark_t.
+ *
+ * The benchmarking function has to accept trhee arguments:
+ *  @li bench_env_t: benchmark environment configuration
+ *  @li bench_run_t: call bench_run_start and bench_run_stop around the
+ *      actual benchmarking code
+ *  @li uint64_t: size of the workload - typically number of inner loops in
+ *      your benchmark (used to self-calibrate benchmark size)
+ *
+ * Typically, the structure of the function is following:
+ * @code{c}
+ * static bool runnerconst bench_env_t const *envbench_run_t *run, uint64_t size)
+ * {
+ * 	bench_run_start(run);
+ * 	for (uint64_t i = 0; i < size; i++) {
+ * 		// measured action
+ * 		if (something_fails) {
+ * 		    return bench_run_fail(run, "oops: %s (%d)", str_error(rc), rc);
+ * 		}
+ * 	}
+ * 	bench_run_stop(run);
+ *
+ * 	return true;
+ * }
+ * @endcode
+ */
Index: uspace/app/hbench/env.c
===================================================================
--- uspace/app/hbench/env.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/env.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2019 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <str.h>
+#include "hbench.h"
+
+typedef struct {
+	ht_link_t link;
+
+	char *key;
+	char *value;
+} param_t;
+
+static size_t param_hash(const ht_link_t *item)
+{
+	param_t *param = hash_table_get_inst(item, param_t, link);
+	return str_size(param->key);
+}
+
+static size_t param_key_hash(const void *key)
+{
+	const char *key_str = key;
+	return str_size(key_str);
+}
+
+static bool param_key_equal(const void *key, const ht_link_t *item)
+{
+	param_t *param = hash_table_get_inst(item, param_t, link);
+	const char *key_str = key;
+
+	return str_cmp(param->key, key_str) == 0;
+}
+
+static bool param_equal(const ht_link_t *link_a, const ht_link_t *link_b)
+{
+	param_t *a = hash_table_get_inst(link_a, param_t, link);
+	param_t *b = hash_table_get_inst(link_b, param_t, link);
+
+	return str_cmp(a->key, b->key) == 0;
+}
+
+static void param_remove(ht_link_t *item)
+{
+	param_t *param = hash_table_get_inst(item, param_t, link);
+	free(param->key);
+	free(param->value);
+}
+
+static hash_table_ops_t param_hash_table_ops = {
+	.hash = param_hash,
+	.key_hash = param_key_hash,
+	.key_equal = param_key_equal,
+	.equal = param_equal,
+	.remove_callback = param_remove
+};
+
+errno_t bench_env_init(bench_env_t *env)
+{
+	bool ok = hash_table_create(&env->parameters, 0, 0, &param_hash_table_ops);
+	if (!ok) {
+		return ENOMEM;
+	}
+
+	env->run_count = DEFAULT_RUN_COUNT;
+	env->minimal_run_duration_nanos = MSEC2NSEC(DEFAULT_MIN_RUN_DURATION_SEC);
+
+	return EOK;
+}
+
+void bench_env_cleanup(bench_env_t *env)
+{
+	hash_table_destroy(&env->parameters);
+}
+
+errno_t bench_env_param_set(bench_env_t *env, const char *key, const char *value)
+{
+	param_t *param = malloc(sizeof(param_t));
+	if (param == NULL) {
+		return ENOMEM;
+	}
+
+	param->key = str_dup(key);
+	param->value = str_dup(value);
+
+	if ((param->key == NULL) || (param->value == NULL)) {
+		free(param->key);
+		free(param->value);
+		free(param);
+
+		return ENOMEM;
+	}
+
+	hash_table_insert(&env->parameters, &param->link);
+
+	return EOK;
+}
+
+const char *bench_env_param_get(bench_env_t *env, const char *key, const char *default_value)
+{
+	ht_link_t *item = hash_table_find(&env->parameters, (char *) key);
+
+	if (item == NULL) {
+		return default_value;
+	}
+
+	param_t *param = hash_table_get_inst(item, param_t, link);
+	return param->value;
+}
+
+/** @}
+ */
Index: uspace/app/hbench/fs/dirread.c
===================================================================
--- uspace/app/hbench/fs/dirread.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/fs/dirread.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * Copyright (c) 2019 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+
+#include <dirent.h>
+#include <str_error.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "../hbench.h"
+
+/** Execute directory listing benchmark.
+ *
+ * Note that while this benchmark tries to measure speed of direct
+ * read, it rather measures speed of FS cache as it is highly probable
+ * that the corresponding blocks would be cached after first run.
+ */
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t size)
+{
+	const char *path = bench_env_param_get(env, "dirname", "/");
+
+	bench_run_start(run);
+	for (uint64_t i = 0; i < size; i++) {
+		DIR *dir = opendir(path);
+		if (dir == NULL) {
+			return bench_run_fail(run, "failed to open %s for reading: %s",
+			    path, str_error(errno));
+		}
+
+		struct dirent *dp;
+		while ((dp = readdir(dir))) {
+			/* Do nothing */
+		}
+
+		closedir(dir);
+	}
+	bench_run_stop(run);
+
+	return true;
+}
+
+benchmark_t benchmark_dir_read = {
+	.name = "dir_read",
+	.desc = "Read contents of a directory (use 'dirname' param to alter the default).",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/**
+ * @}
+ */
Index: uspace/app/hbench/fs/fileread.c
===================================================================
--- uspace/app/hbench/fs/fileread.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/fs/fileread.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2011 Martin Sucha
+ * Copyright (c) 2019 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+
+#include <str_error.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "../hbench.h"
+
+#define BUFFER_SIZE 4096
+
+/** Execute file reading benchmark.
+ *
+ * Note that while this benchmark tries to measure speed of file reading,
+ * it rather measures speed of FS cache as it is highly probable that the
+ * corresponding blocks would be cached after first run.
+ */
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t size)
+{
+	const char *path = bench_env_param_get(env, "filename", "/data/web/helenos.png");
+
+	char *buf = malloc(BUFFER_SIZE);
+	if (buf == NULL) {
+		return bench_run_fail(run, "failed to allocate %dB buffer", BUFFER_SIZE);
+	}
+
+	bool ret = true;
+
+	FILE *file = fopen(path, "r");
+	if (file == NULL) {
+		bench_run_fail(run, "failed to open %s for reading: %s",
+		    path, str_error(errno));
+		ret = false;
+		goto leave_free_buf;
+	}
+
+	bench_run_start(run);
+	for (uint64_t i = 0; i < size; i++) {
+		int rc = fseek(file, 0, SEEK_SET);
+		if (rc != 0) {
+			bench_run_fail(run, "failed to rewind %s: %s",
+			    path, str_error(errno));
+			ret = false;
+			goto leave_close;
+		}
+		while (!feof(file)) {
+			fread(buf, 1, BUFFER_SIZE, file);
+			if (ferror(file)) {
+				bench_run_fail(run, "failed to read from %s: %s",
+				    path, str_error(errno));
+				ret = false;
+				goto leave_close;
+			}
+		}
+	}
+	bench_run_stop(run);
+
+leave_close:
+	fclose(file);
+
+leave_free_buf:
+	free(buf);
+
+	return ret;
+}
+
+benchmark_t benchmark_file_read = {
+	.name = "file_read",
+	.desc = "Sequentially read contents of a file (use 'filename' param to alter the default).",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/**
+ * @}
+ */
Index: uspace/app/hbench/hbench.h
===================================================================
--- uspace/app/hbench/hbench.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/hbench.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * Copyright (c) 2019 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+/** @file
+ */
+
+#ifndef HBENCH_H_
+#define HBENCH_H_
+
+#include <adt/hash_table.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <perf.h>
+
+#define DEFAULT_RUN_COUNT 10
+#define DEFAULT_MIN_RUN_DURATION_SEC 10
+
+/** Single run information.
+ *
+ * Used to store both performance information (now, only wall-clock
+ * time) as well as information about error.
+ *
+ * Use proper access functions when modifying data inside this structure.
+ *
+ * Eventually, we could collection of hardware counters etc. without
+ * modifying signatures of any existing benchmark.
+ */
+typedef struct {
+	stopwatch_t stopwatch;
+	char *error_message;
+	size_t error_message_buffer_size;
+} bench_run_t;
+
+/** Benchmark environment configuration.
+ *
+ * Benchmarking code (runners) should use access functions to read
+ * data from this structure (now only bench_env_param_get).
+ *
+ * Harness can access it directly.
+ */
+typedef struct {
+	hash_table_t parameters;
+	size_t run_count;
+	nsec_t minimal_run_duration_nanos;
+} bench_env_t;
+
+/** Actual benchmark runner.
+ *
+ * The first argument describes the environment, second is used to store
+ * information about the run (performance data or error message) and
+ * third describes workload size (number of iterations).
+ */
+typedef bool (*benchmark_entry_t)(bench_env_t *, bench_run_t *, uint64_t);
+
+/** Setup and teardown callback type.
+ *
+ * Unlike in benchmark_entry_t, we do not need to pass in number of
+ * iterations to execute (note that we use bench_run_t only to simplify
+ * creation of error messages).
+ */
+typedef bool (*benchmark_helper_t)(bench_env_t *, bench_run_t *);
+
+typedef struct {
+	const char *name;
+	const char *desc;
+	benchmark_entry_t entry;
+	benchmark_helper_t setup;
+	benchmark_helper_t teardown;
+} benchmark_t;
+
+extern void bench_run_init(bench_run_t *, char *, size_t);
+extern bool bench_run_fail(bench_run_t *, const char *, ...);
+
+/*
+ * We keep the following two functions inline to ensure that we start
+ * measurement as close to the surrounding code as possible. Note that
+ * this inlining is done at least on the level of individual wrappers
+ * (this one and the one provided by stopwatch_t) to pass the control
+ * as fast as possible to the actual timer used.
+ */
+
+static inline void bench_run_start(bench_run_t *run)
+{
+	stopwatch_start(&run->stopwatch);
+}
+
+static inline void bench_run_stop(bench_run_t *run)
+{
+	stopwatch_stop(&run->stopwatch);
+}
+
+extern errno_t csv_report_open(const char *);
+extern void csv_report_add_entry(bench_run_t *, int, benchmark_t *, uint64_t);
+extern void csv_report_close(void);
+
+extern errno_t bench_env_init(bench_env_t *);
+extern errno_t bench_env_param_set(bench_env_t *, const char *, const char *);
+extern const char *bench_env_param_get(bench_env_t *, const char *, const char *);
+extern void bench_env_cleanup(bench_env_t *);
+
+extern benchmark_t *benchmarks[];
+extern size_t benchmark_count;
+
+/* Put your benchmark descriptors here (and also to benchlist.c). */
+extern benchmark_t benchmark_dir_read;
+extern benchmark_t benchmark_fibril_mutex;
+extern benchmark_t benchmark_file_read;
+extern benchmark_t benchmark_malloc1;
+extern benchmark_t benchmark_malloc2;
+extern benchmark_t benchmark_ns_ping;
+extern benchmark_t benchmark_ping_pong;
+
+#endif
+
+/** @}
+ */
Index: uspace/app/hbench/ipc/ns_ping.c
===================================================================
--- uspace/app/hbench/ipc/ns_ping.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/ipc/ns_ping.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+
+#include <stdio.h>
+#include <ns.h>
+#include <async.h>
+#include <errno.h>
+#include <str_error.h>
+#include "../hbench.h"
+
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t niter)
+{
+	bench_run_start(run);
+
+	for (uint64_t count = 0; count < niter; count++) {
+		errno_t rc = ns_ping();
+
+		if (rc != EOK) {
+			return bench_run_fail(run, "failed sending ping message: %s (%d)",
+			    str_error(rc), rc);
+		}
+	}
+
+	bench_run_stop(run);
+
+	return true;
+}
+
+benchmark_t benchmark_ns_ping = {
+	.name = "ns_ping",
+	.desc = "Name service IPC ping-pong benchmark",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/** @}
+ */
Index: uspace/app/hbench/ipc/ping_pong.c
===================================================================
--- uspace/app/hbench/ipc/ping_pong.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/ipc/ping_pong.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2009 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+
+#include <stdio.h>
+#include <ipc_test.h>
+#include <async.h>
+#include <errno.h>
+#include <str_error.h>
+#include "../hbench.h"
+
+static ipc_test_t *test = NULL;
+
+static bool setup(bench_env_t *env, bench_run_t *run)
+{
+	errno_t rc = ipc_test_create(&test);
+	if (rc != EOK) {
+		return bench_run_fail(run,
+		    "failed contacting IPC test server (have you run /srv/test/ipc-test?): %s (%d)",
+		    str_error(rc), rc);
+	}
+
+	return true;
+}
+
+static bool teardown(bench_env_t *env, bench_run_t *run)
+{
+	ipc_test_destroy(test);
+	return true;
+}
+
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t niter)
+{
+	bench_run_start(run);
+
+	for (uint64_t count = 0; count < niter; count++) {
+		errno_t rc = ipc_test_ping(test);
+
+		if (rc != EOK) {
+			return bench_run_fail(run, "failed sending ping message: %s (%d)",
+			    str_error(rc), rc);
+		}
+	}
+
+	bench_run_stop(run);
+
+	return true;
+}
+
+benchmark_t benchmark_ping_pong = {
+	.name = "ping_pong",
+	.desc = "IPC ping-pong benchmark",
+	.entry = &runner,
+	.setup = &setup,
+	.teardown = &teardown
+};
+
+/** @}
+ */
Index: uspace/app/hbench/main.c
===================================================================
--- uspace/app/hbench/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2018 Jiri Svoboda
+ * Copyright (c) 2018 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <assert.h>
+#include <getopt.h>
+#include <math.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <str.h>
+#include <time.h>
+#include <errno.h>
+#include <str_error.h>
+#include <perf.h>
+#include <types/casting.h>
+#include "hbench.h"
+
+#define MAX_ERROR_STR_LENGTH 1024
+
+static void short_report(bench_run_t *info, int run_index,
+    benchmark_t *bench, uint64_t workload_size)
+{
+	csv_report_add_entry(info, run_index, bench, workload_size);
+
+	usec_t duration_usec = NSEC2USEC(stopwatch_get_nanos(&info->stopwatch));
+
+	printf("Completed %" PRIu64 " operations in %llu us",
+	    workload_size, duration_usec);
+	if (duration_usec > 0) {
+		double nanos = stopwatch_get_nanos(&info->stopwatch);
+		double thruput = (double) workload_size / (nanos / 1000000000.0l);
+		printf(", %.0f ops/s.\n", thruput);
+	} else {
+		printf(".\n");
+	}
+}
+
+/** Estimate square root value.
+ *
+ * @param value The value to compute square root of.
+ * @param precision Required precision (e.g. 0.00001).
+ *
+ * @details
+ *
+ * This is a temporary solution until we have proper sqrt() implementation
+ * in libmath.
+ *
+ * The algorithm uses Babylonian method [1].
+ *
+ * [1] https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
+ */
+static double estimate_square_root(double value, double precision)
+{
+	double estimate = 1.;
+	double prev_estimate = estimate + 10 * precision;
+
+	while (fabs(estimate - prev_estimate) > precision) {
+		prev_estimate = estimate;
+		estimate = (prev_estimate + value / prev_estimate) / 2.;
+	}
+
+	return estimate;
+}
+
+/** Compute available statistics from given stopwatches.
+ *
+ * We compute normal mean for average duration of the workload and geometric
+ * mean for average thruput. Note that geometric mean is necessary to compute
+ * average throughput correctly - consider the following example:
+ *  - we run always 60 operations,
+ *  - first run executes in 30 s (i.e. 2 ops/s)
+ *  - and second one in 10 s (6 ops/s).
+ * Then, naively, average throughput would be (2+6)/2 = 4 [ops/s]. However, we
+ * actually executed 60 + 60 ops in 30 + 10 seconds. So the actual average
+ * throughput is 3 ops/s (which is exactly what geometric mean means).
+ *
+ */
+static void compute_stats(bench_run_t *runs, size_t run_count,
+    uint64_t workload_size, double precision, double *out_duration_avg,
+    double *out_duration_sigma, double *out_thruput_avg)
+{
+	double inv_thruput_sum = 0.0;
+	double nanos_sum = 0.0;
+	double nanos_sum2 = 0.0;
+
+	for (size_t i = 0; i < run_count; i++) {
+		double nanos = stopwatch_get_nanos(&runs[i].stopwatch);
+		double thruput = (double) workload_size / nanos;
+
+		inv_thruput_sum += 1.0 / thruput;
+		nanos_sum += nanos;
+		nanos_sum2 += nanos * nanos;
+	}
+	*out_duration_avg = nanos_sum / run_count;
+	double sigma2 = (nanos_sum2 - nanos_sum * (*out_duration_avg)) /
+	    ((double) run_count - 1);
+	// FIXME: implement sqrt properly
+	if (run_count > 1) {
+		*out_duration_sigma = estimate_square_root(sigma2, precision);
+	} else {
+		*out_duration_sigma = NAN;
+	}
+	*out_thruput_avg = 1.0 / (inv_thruput_sum / run_count);
+}
+
+static void summary_stats(bench_run_t *runs, size_t run_count,
+    benchmark_t *bench, uint64_t workload_size)
+{
+	double duration_avg, duration_sigma, thruput_avg;
+	compute_stats(runs, run_count, workload_size, 0.001,
+	    &duration_avg, &duration_sigma, &thruput_avg);
+
+	printf("Average: %" PRIu64 " ops in %.0f us (sd %.0f us); "
+	    "%.0f ops/s; Samples: %zu\n",
+	    workload_size, duration_avg / 1000.0, duration_sigma / 1000.0,
+	    thruput_avg * 1000000000.0, run_count);
+}
+
+static bool run_benchmark(bench_env_t *env, benchmark_t *bench)
+{
+	printf("Warm up and determine workload size...\n");
+
+	/*
+	 * We share this buffer across all runs as we know that it is
+	 * used only on failure (and we abort after first error).
+	 */
+	char *error_msg = malloc(MAX_ERROR_STR_LENGTH + 1);
+	if (error_msg == NULL) {
+		printf("Out of memory!\n");
+		return false;
+	}
+	str_cpy(error_msg, MAX_ERROR_STR_LENGTH, "");
+
+	bench_run_t helper_run;
+	bench_run_init(&helper_run, error_msg, MAX_ERROR_STR_LENGTH);
+
+	bool ret = true;
+
+	if (bench->setup != NULL) {
+		ret = bench->setup(env, &helper_run);
+		if (!ret) {
+			goto leave_error;
+		}
+	}
+
+	/*
+	 * Find workload size that is big enough to last few seconds.
+	 * We also check that uint64_t is big enough.
+	 */
+	uint64_t workload_size = 0;
+	for (size_t bits = 0; bits <= 64; bits++) {
+		if (bits == 64) {
+			str_cpy(error_msg, MAX_ERROR_STR_LENGTH, "Workload too small even for 1 << 63");
+			goto leave_error;
+		}
+		workload_size = ((uint64_t) 1) << bits;
+
+		bench_run_t run;
+		bench_run_init(&run, error_msg, MAX_ERROR_STR_LENGTH);
+
+		bool ok = bench->entry(env, &run, workload_size);
+		if (!ok) {
+			goto leave_error;
+		}
+		short_report(&run, -1, bench, workload_size);
+
+		nsec_t duration = stopwatch_get_nanos(&run.stopwatch);
+		if (duration > env->minimal_run_duration_nanos) {
+			break;
+		}
+	}
+
+	printf("Workload size set to %" PRIu64 ", measuring %zu samples.\n",
+	    workload_size, env->run_count);
+
+	bench_run_t *runs = calloc(env->run_count, sizeof(bench_run_t));
+	if (runs == NULL) {
+		snprintf(error_msg, MAX_ERROR_STR_LENGTH, "failed allocating memory");
+		goto leave_error;
+	}
+	for (size_t i = 0; i < env->run_count; i++) {
+		bench_run_init(&runs[i], error_msg, MAX_ERROR_STR_LENGTH);
+
+		bool ok = bench->entry(env, &runs[i], workload_size);
+		if (!ok) {
+			free(runs);
+			goto leave_error;
+		}
+		short_report(&runs[i], i, bench, workload_size);
+	}
+
+	summary_stats(runs, env->run_count, bench, workload_size);
+	printf("\nBenchmark completed\n");
+
+	free(runs);
+
+	goto leave;
+
+leave_error:
+	printf("Error: %s\n", error_msg);
+	ret = false;
+
+leave:
+	if (bench->teardown != NULL) {
+		bool ok = bench->teardown(env, &helper_run);
+		if (!ok) {
+			printf("Error: %s\n", error_msg);
+			ret = false;
+		}
+	}
+
+	free(error_msg);
+
+	return ret;
+}
+
+static int run_benchmarks(bench_env_t *env)
+{
+	unsigned int count_ok = 0;
+	unsigned int count_fail = 0;
+
+	char *failed_names = NULL;
+
+	printf("\n*** Running all benchmarks ***\n\n");
+
+	for (size_t it = 0; it < benchmark_count; it++) {
+		printf("%s (%s)\n", benchmarks[it]->name, benchmarks[it]->desc);
+		if (run_benchmark(env, benchmarks[it])) {
+			count_ok++;
+			continue;
+		}
+
+		if (!failed_names) {
+			failed_names = str_dup(benchmarks[it]->name);
+		} else {
+			char *f = NULL;
+			asprintf(&f, "%s, %s", failed_names, benchmarks[it]->name);
+			if (!f) {
+				printf("Out of memory.\n");
+				abort();
+			}
+			free(failed_names);
+			failed_names = f;
+		}
+		count_fail++;
+	}
+
+	printf("\nCompleted, %u benchmarks run, %u succeeded.\n",
+	    count_ok + count_fail, count_ok);
+	if (failed_names)
+		printf("Failed benchmarks: %s\n", failed_names);
+
+	return count_fail;
+}
+
+static void list_benchmarks(void)
+{
+	size_t len = 0;
+	for (size_t i = 0; i < benchmark_count; i++) {
+		size_t len_now = str_length(benchmarks[i]->name);
+		if (len_now > len)
+			len = len_now;
+	}
+
+	assert(can_cast_size_t_to_int(len) && "benchmark name length overflow");
+
+	for (size_t i = 0; i < benchmark_count; i++)
+		printf("  %-*s %s\n", (int) len, benchmarks[i]->name, benchmarks[i]->desc);
+
+	printf("  %-*s Run all benchmarks\n", (int) len, "*");
+}
+
+static void print_usage(const char *progname)
+{
+	printf("Usage: %s [options] <benchmark>\n", progname);
+	printf("-h, --help                 "
+	    "Print this help and exit\n");
+	printf("-d, --duration MILLIS      "
+	    "Set minimal run duration (milliseconds)\n");
+	printf("-n, --count N              "
+	    "Set number of measured runs\n");
+	printf("-o, --output filename.csv  "
+	    "Store machine-readable data in filename.csv\n");
+	printf("-p, --param KEY=VALUE      "
+	    "Additional parameters for the benchmark\n");
+	printf("<benchmark> is one of the following:\n");
+	list_benchmarks();
+}
+
+static void handle_param_arg(bench_env_t *env, char *arg)
+{
+	char *value = NULL;
+	char *key = str_tok(arg, "=", &value);
+	bench_env_param_set(env, key, value);
+}
+
+int main(int argc, char *argv[])
+{
+	bench_env_t bench_env;
+	errno_t rc = bench_env_init(&bench_env);
+	if (rc != EOK) {
+		fprintf(stderr, "Failed to initialize internal params structure: %s\n",
+		    str_error(rc));
+		return -5;
+	}
+
+	const char *short_options = "ho:p:n:d:";
+	struct option long_options[] = {
+		{ "duration", required_argument, NULL, 'd' },
+		{ "help", optional_argument, NULL, 'h' },
+		{ "count", required_argument, NULL, 'n' },
+		{ "output", required_argument, NULL, 'o' },
+		{ "param", required_argument, NULL, 'p' },
+		{ 0, 0, NULL, 0 }
+	};
+
+	char *csv_output_filename = NULL;
+
+	int opt = 0;
+	while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) > 0) {
+		switch (opt) {
+		case 'd':
+			errno = EOK;
+			bench_env.minimal_run_duration_nanos = MSEC2NSEC(atoll(optarg));
+			if ((errno != EOK) || (bench_env.minimal_run_duration_nanos <= 0)) {
+				fprintf(stderr, "Invalid -d argument.\n");
+				return -3;
+			}
+			break;
+		case 'h':
+			print_usage(*argv);
+			return 0;
+		case 'n':
+			errno = EOK;
+			bench_env.run_count = (nsec_t) atoll(optarg);
+			if ((errno != EOK) || (bench_env.run_count <= 0)) {
+				fprintf(stderr, "Invalid -n argument.\n");
+				return -3;
+			}
+			break;
+		case 'o':
+			csv_output_filename = optarg;
+			break;
+		case 'p':
+			handle_param_arg(&bench_env, optarg);
+			break;
+		case -1:
+		default:
+			break;
+		}
+	}
+
+	if (optind + 1 != argc) {
+		print_usage(*argv);
+		fprintf(stderr, "Error: specify one benchmark to run or * for all.\n");
+		return -3;
+	}
+
+	const char *benchmark = argv[optind];
+
+	if (csv_output_filename != NULL) {
+		errno_t rc = csv_report_open(csv_output_filename);
+		if (rc != EOK) {
+			fprintf(stderr, "Failed to open CSV report '%s': %s\n",
+			    csv_output_filename, str_error(rc));
+			return -4;
+		}
+	}
+
+	int exit_code = 0;
+
+	if (str_cmp(benchmark, "*") == 0) {
+		exit_code = run_benchmarks(&bench_env);
+	} else {
+		bool benchmark_exists = false;
+		for (size_t i = 0; i < benchmark_count; i++) {
+			if (str_cmp(benchmark, benchmarks[i]->name) == 0) {
+				benchmark_exists = true;
+				exit_code = run_benchmark(&bench_env, benchmarks[i]) ? 0 : -1;
+				break;
+			}
+		}
+		if (!benchmark_exists) {
+			printf("Unknown benchmark \"%s\"\n", benchmark);
+			exit_code = -2;
+		}
+	}
+
+	csv_report_close();
+	bench_env_cleanup(&bench_env);
+
+	return exit_code;
+}
+
+/** @}
+ */
Index: uspace/app/hbench/malloc/malloc1.c
===================================================================
--- uspace/app/hbench/malloc/malloc1.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/malloc/malloc1.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "../hbench.h"
+
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t size)
+{
+	bench_run_start(run);
+	for (uint64_t i = 0; i < size; i++) {
+		void *p = malloc(1);
+		if (p == NULL) {
+			return bench_run_fail(run,
+			    "failed to allocate 1B in run %" PRIu64 " (out of %" PRIu64 ")",
+			    i, size);
+		}
+		free(p);
+	}
+	bench_run_stop(run);
+
+	return true;
+}
+
+benchmark_t benchmark_malloc1 = {
+	.name = "malloc1",
+	.desc = "User-space memory allocator benchmark, repeatedly allocate one block",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/** @}
+ */
Index: uspace/app/hbench/malloc/malloc2.c
===================================================================
--- uspace/app/hbench/malloc/malloc2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/malloc/malloc2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "../hbench.h"
+
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t niter)
+{
+	bench_run_start(run);
+
+	void **p = malloc(niter * sizeof(void *));
+	if (p == NULL) {
+		return bench_run_fail(run, "failed to allocate backend array (%" PRIu64 "B)",
+		    niter * sizeof(void *));
+	}
+
+	for (uint64_t count = 0; count < niter; count++) {
+		p[count] = malloc(1);
+		if (p[count] == NULL) {
+			for (uint64_t j = 0; j < count; j++) {
+				free(p[j]);
+			}
+			free(p);
+			return bench_run_fail(run,
+			    "failed to allocate 1B in run %" PRIu64 " (out of %" PRIu64 ")",
+			    count, niter);
+		}
+	}
+
+	for (uint64_t count = 0; count < niter; count++)
+		free(p[count]);
+
+	free(p);
+
+	bench_run_stop(run);
+
+	return true;
+}
+
+benchmark_t benchmark_malloc2 = {
+	.name = "malloc2",
+	.desc = "User-space memory allocator benchmark, allocate many small blocks",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/** @}
+ */
Index: uspace/app/hbench/synch/fibril_mutex.c
===================================================================
--- uspace/app/hbench/synch/fibril_mutex.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/synch/fibril_mutex.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2019 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+
+#include <fibril_synch.h>
+#include <stdatomic.h>
+#include "../hbench.h"
+
+/*
+ * Simple benchmark for fibril mutexes. There are two fibrils that compete
+ * over the same mutex as that is the simplest scenario.
+ */
+
+typedef struct {
+	fibril_mutex_t mutex;
+	uint64_t counter;
+	atomic_bool done;
+} shared_t;
+
+static errno_t competitor(void *arg)
+{
+	shared_t *shared = arg;
+	fibril_detach(fibril_get_id());
+
+	while (true) {
+		fibril_mutex_lock(&shared->mutex);
+		uint64_t local = shared->counter;
+		fibril_mutex_unlock(&shared->mutex);
+		if (local == 0) {
+			break;
+		}
+	}
+
+	atomic_store(&shared->done, true);
+
+	return EOK;
+}
+
+static bool runner(bench_env_t *env, bench_run_t *run, uint64_t size)
+{
+	shared_t shared;
+	fibril_mutex_initialize(&shared.mutex);
+	shared.counter = size;
+	atomic_store(&shared.done, false);
+
+	fid_t other = fibril_create(competitor, &shared);
+	fibril_add_ready(other);
+
+	bench_run_start(run);
+	for (uint64_t i = 0; i < size; i++) {
+		fibril_mutex_lock(&shared.mutex);
+		shared.counter--;
+		fibril_mutex_unlock(&shared.mutex);
+	}
+	bench_run_stop(run);
+
+	while (!atomic_load(&shared.done)) {
+		fibril_yield();
+	}
+
+	return true;
+}
+
+benchmark_t benchmark_fibril_mutex = {
+	.name = "fibril_mutex",
+	.desc = "Speed of mutex lock/unlock operations",
+	.entry = &runner,
+	.setup = NULL,
+	.teardown = NULL
+};
+
+/** @}
+ */
Index: uspace/app/hbench/utils.c
===================================================================
--- uspace/app/hbench/utils.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/hbench/utils.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup hbench
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "hbench.h"
+
+/** Initialize bench run structure.
+ *
+ * @param run Structure to intialize.
+ * @param error_buffer Pre-allocated memory to use for error messages.
+ * @param error_buffer_size Size of error_buffer.
+ */
+void bench_run_init(bench_run_t *run, char *error_buffer, size_t error_buffer_size)
+{
+	stopwatch_init(&run->stopwatch);
+	run->error_message = error_buffer;
+	run->error_message_buffer_size = error_buffer_size;
+}
+
+/** Format error message on benchmark failure.
+ *
+ * This function always returns false so it can be easily used in benchmark
+ * runners as
+ *
+ * @code
+ * if (error) {
+ *     return bench_run_fail(run, "we failed");
+ * }
+ * @endcode
+ *
+ * @param run Current benchmark run.
+ * @param fmt printf-style message followed by extra arguments.
+ * @retval false Always.
+ */
+bool bench_run_fail(bench_run_t *run, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	vsnprintf(run->error_message, run->error_message_buffer_size, fmt, args);
+	va_end(args);
+
+	return false;
+}
+
+/** @}
+ */
Index: uspace/app/init/untar.c
===================================================================
--- uspace/app/init/untar.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/init/untar.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,5 +45,5 @@
 typedef struct {
 	const char *dev;
-	
+
 	service_id_t sid;
 	aoff64_t offset;
Index: uspace/app/kio/kio.c
===================================================================
--- uspace/app/kio/kio.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/kio/kio.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -164,7 +164,7 @@
 	fibril_mutex_lock(&mtx);
 
-	size_t kio_start = (size_t) IPC_GET_ARG1(*call);
-	size_t kio_len = (size_t) IPC_GET_ARG2(*call);
-	size_t kio_stored = (size_t) IPC_GET_ARG3(*call);
+	size_t kio_start = (size_t) ipc_get_arg1(call);
+	size_t kio_len = (size_t) ipc_get_arg2(call);
+	size_t kio_stored = (size_t) ipc_get_arg3(call);
 
 	size_t offset = (kio_start + kio_len - kio_stored) % kio_length;
Index: uspace/app/lprint/Makefile
===================================================================
--- uspace/app/lprint/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/lprint/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2018 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = lprint
+
+SOURCES = \
+	lprint.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/lprint/doc/doxygroups.h
===================================================================
--- uspace/app/lprint/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/lprint/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,4 @@
+/** @addtogroup lprint lprint
+ * @brief Print on a printer
+ * @ingroup apps
+ */
Index: uspace/app/lprint/lprint.c
===================================================================
--- uspace/app/lprint/lprint.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/lprint/lprint.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/** @addtogroup lprint
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Print on a printer
+ *
+ */
+
+#include <errno.h>
+#include <io/chardev.h>
+#include <loc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str.h>
+
+#define NAME	"lprint"
+
+#define BUF_SIZE 1024
+
+static void syntax_print(void);
+
+/** Get default printer port.
+ *
+ * @param sid Place to store service ID of the printer port
+ * @return EOK on success or error code
+ */
+static errno_t lprint_get_def_printer_port(service_id_t *sid)
+{
+	category_id_t cid;
+	service_id_t *sids;
+	size_t nsids;
+	errno_t rc;
+
+	rc = loc_category_get_id("printer-port", &cid, 0);
+	if (rc != EOK)
+		return EIO;
+
+	rc = loc_category_get_svcs(cid, &sids, &nsids);
+	if (rc != EOK)
+		return EIO;
+
+	if (nsids < 1) {
+		free(sids);
+		return EIO;
+	}
+
+	*sid = sids[0];
+	free(sids);
+	return EOK;
+}
+
+/** Print a message.
+ *
+ * @param chardev Character device
+ * @param argc Number of arguments
+ * @param argv Arguments - strings to print
+ *
+ * @return EOK on success or error code
+ */
+static errno_t lprint_msg(chardev_t *chardev, int argc, char *argv[])
+{
+	const char *msg;
+	size_t nbytes;
+	const char *sep;
+	errno_t rc;
+
+	while (argc > 0) {
+		msg = *argv;
+		--argc;
+		++argv;
+
+		rc = chardev_write(chardev, msg, str_size(msg), &nbytes);
+		if (rc != EOK) {
+			printf(NAME ": Failed sending data.\n");
+			return EIO;
+		}
+
+		sep = argc > 0 ? " " : "\n";
+
+		rc = chardev_write(chardev, sep, str_size(sep), &nbytes);
+		if (rc != EOK) {
+			printf(NAME ": Failed sending data.\n");
+			return EIO;
+		}
+	}
+
+	return EOK;
+}
+
+/** Print a file.
+ *
+ * @param chardev Character device
+ * @param fname File name
+ *
+ * @return EOK on success or error code
+ */
+static errno_t lprint_file(chardev_t *chardev, const char *fname)
+{
+	void *buf;
+	size_t nread, nwritten;
+	FILE *f = NULL;
+	errno_t rc;
+
+	buf = malloc(BUF_SIZE);
+	if (buf == NULL) {
+		printf(NAME ": Out of memory.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	f = fopen(fname, "rb");
+	if (f == NULL) {
+		printf(NAME ": Cannot open '%s'.\n", fname);
+		rc = EIO;
+		goto error;
+	}
+
+	while (true) {
+		nread = fread(buf, 1, BUF_SIZE, f);
+		if (ferror(f)) {
+			printf(NAME ": Error reading file.\n");
+			rc = EIO;
+			goto error;
+		}
+
+		if (nread == 0)
+			break;
+
+		rc = chardev_write(chardev, buf, nread, &nwritten);
+		if (rc != EOK) {
+			printf(NAME ": Failed sending data.\n");
+			rc = EIO;
+			goto error;
+		}
+
+	}
+
+	fclose(f);
+	return EOK;
+error:
+	if (buf != NULL)
+		free(buf);
+	if (f != NULL)
+		fclose(f);
+	return rc;
+}
+
+int main(int argc, char **argv)
+{
+	chardev_t *chardev;
+	errno_t rc;
+	async_sess_t *sess;
+	service_id_t sid;
+	const char *svc_name = NULL;
+	bool msg_mode = false;
+
+	if (argc < 2) {
+		printf(NAME ": Error, argument missing.\n");
+		syntax_print();
+		return 1;
+	}
+
+	--argc;
+	++argv;
+
+	while (*argv != NULL && *argv[0] == '-') {
+		if (str_cmp(*argv, "-d") == 0) {
+			--argc;
+			++argv;
+
+			if (*argv == NULL) {
+				printf(NAME ": Error, argument missing.\n");
+				syntax_print();
+				return 1;
+			}
+
+			svc_name = *argv;
+			--argc;
+			++argv;
+			continue;
+		}
+
+		if (str_cmp(*argv, "-m") == 0) {
+			msg_mode = true;
+			--argc;
+			++argv;
+			continue;
+		}
+
+		if (str_cmp(*argv, "--help") == 0) {
+			--argc;
+			++argv;
+
+			if (*argv != NULL) {
+				printf(NAME ": Error, unexpected argument.\n");
+				syntax_print();
+				return 1;
+			}
+
+			syntax_print();
+			return 0;
+		}
+
+		printf(NAME ": Error, invalid argument.\n");
+		syntax_print();
+		return 1;
+	}
+
+	if (argc < 1) {
+		printf(NAME ": Error, argument missing.\n");
+		syntax_print();
+		return 1;
+	}
+
+	if (!msg_mode && argc > 1) {
+		printf(NAME ": Error, too many arguments.\n");
+		syntax_print();
+		return 1;
+	}
+
+	if (svc_name != NULL) {
+		rc = loc_service_get_id(svc_name, &sid, 0);
+		if (rc != EOK) {
+			printf(NAME ": Failed resolving printer port service "
+			    "'%s'.\n", svc_name);
+			return 1;
+		}
+	} else {
+		rc = lprint_get_def_printer_port(&sid);
+		if (rc != EOK) {
+			printf(NAME ": No printer found.\n");
+			return 1;
+		}
+	}
+
+	sess = loc_service_connect(sid, INTERFACE_DDF, 0);
+	if (sess == NULL) {
+		printf(NAME ": Failed connecting printer port service.\n");
+		return 1;
+	}
+
+	rc = chardev_open(sess, &chardev);
+	if (rc != EOK) {
+		async_hangup(sess);
+		printf(NAME ": Failed opening printer port device.\n");
+		return 1;
+	}
+
+	if (msg_mode) {
+		rc = lprint_msg(chardev, argc, argv);
+		if (rc != EOK) {
+			chardev_close(chardev);
+			return 1;
+		}
+	} else {
+		rc = lprint_file(chardev, argv[0]);
+		if (rc != EOK) {
+			chardev_close(chardev);
+			return 1;
+		}
+	}
+
+	chardev_close(chardev);
+	return 0;
+}
+
+/** Print syntax help. */
+static void syntax_print(void)
+{
+	printf("syntax:\n"
+	    "\tlprint [<options>] <file>\n"
+	    "\tlprint [<options>] -m <message...>\n"
+	    "options:\n"
+	    "\t-d <device>Print to the specified device\n");
+}
+
+/**
+ * @}
+ */
Index: uspace/app/mkbd/main.c
===================================================================
--- uspace/app/mkbd/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/mkbd/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,5 @@
 #include <stdlib.h>
 #include <errno.h>
+#include <fibril.h>
 #include <str_error.h>
 #include <stdbool.h>
Index: uspace/app/mkext4/mkext4.c
===================================================================
--- uspace/app/mkext4/mkext4.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/mkext4/mkext4.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -56,4 +56,5 @@
 	aoff64_t nblocks;
 	const char *label = "";
+	unsigned int bsize = 4096;
 
 	cfg.version = ext4_def_fs_version;
@@ -68,5 +69,5 @@
 	++argv;
 
-	while (*argv[0] == '-') {
+	while (*argv && *argv[0] == '-') {
 		if (str_cmp(*argv, "--size") == 0) {
 			--argc;
@@ -87,4 +88,26 @@
 			--argc;
 			++argv;
+			continue;
+		}
+
+		if (str_cmp(*argv, "--bsize") == 0) {
+			--argc;
+			++argv;
+			if (*argv == NULL) {
+				printf(NAME ": Error, argument missing.\n");
+				syntax_print();
+				return 1;
+			}
+
+			bsize = strtol(*argv, &endptr, 10);
+			if (*endptr != '\0') {
+				printf(NAME ": Error, invalid argument.\n");
+				syntax_print();
+				return 1;
+			}
+
+			--argc;
+			++argv;
+			continue;
 		}
 
@@ -107,4 +130,5 @@
 			--argc;
 			++argv;
+			continue;
 		}
 
@@ -122,4 +146,10 @@
 			--argc;
 			++argv;
+			continue;
+		}
+
+		if (str_cmp(*argv, "--help") == 0) {
+			syntax_print();
+			return 0;
 		}
 
@@ -128,4 +158,8 @@
 			++argv;
 			break;
+		} else {
+			printf(NAME ": Invalid argument: %s\n", *argv);
+			syntax_print();
+			return 1;
 		}
 	}
@@ -147,4 +181,5 @@
 
 	cfg.volume_name = label;
+	cfg.bsize = bsize;
 	(void) nblocks;
 
@@ -166,5 +201,6 @@
 	    "\t--size <sectors> Filesystem size, overrides device size\n"
 	    "\t--label <label>  Volume label\n"
-	    "\t--type <fstype>  Filesystem type (ext2, ext2old)\n");
+	    "\t--type <fstype>  Filesystem type (ext2, ext2old)\n"
+	    "\t--bsize <bytes>  Filesystem block size in bytes (default = 4096)\n");
 }
 
Index: uspace/app/modplay/modplay.c
===================================================================
--- uspace/app/modplay/modplay.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/modplay/modplay.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,5 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <str.h>
 #include <str_error.h>
 #include <trackmod.h>
@@ -67,4 +68,11 @@
 }
 
+static void print_syntax(void)
+{
+	printf("syntax: modplay [<options>] <filename.mod>\n");
+	printf("options:\n");
+	printf("\t-t <target>\tOutput to specified audio target.\n");
+}
+
 int main(int argc, char *argv[])
 {
@@ -78,8 +86,33 @@
 	void *buffer;
 	size_t buffer_size;
+	const char *target = HOUND_DEFAULT_TARGET;
 	errno_t rc;
 
-	if (argc != 2) {
-		printf("syntax: modplay <filename.mod>\n");
+	++argv;
+	--argc;
+
+	while (argc > 0 && (*argv)[0] == '-') {
+		if (str_cmp(*argv, "-t") == 0) {
+			++argv;
+			--argc;
+
+			if (argc < 1) {
+				printf("Option '-t' requires an argument.\n");
+				print_syntax();
+				return 1;
+			}
+
+			target = *argv++;
+			--argc;
+			continue;
+		}
+
+		printf("Invalid option '%s'\n", *argv);
+		print_syntax();
+		return 1;
+	}
+
+	if (argc != 1) {
+		print_syntax();
 		return 1;
 	}
@@ -87,7 +120,7 @@
 	con = console_init(stdin, stdout);
 
-	rc = trackmod_module_load(argv[1], &mod);
+	rc = trackmod_module_load(argv[0], &mod);
 	if (rc != EOK) {
-		printf("Error loading %s.\n", argv[1]);
+		printf("Error loading %s.\n", argv[0]);
 		return 1;
 	}
@@ -114,7 +147,18 @@
 	}
 
-	rc = hound_context_connect_target(hound, HOUND_DEFAULT_TARGET);
+	rc = hound_context_connect_target(hound, target);
 	if (rc != EOK) {
-		printf("Error connecting default audio target: %s.\n", str_error(rc));
+		printf("Error connecting audio target '%s': %s.\n",
+		    target, str_error(rc));
+
+		char **names = NULL;
+		size_t count = 0;
+		rc = hound_context_get_available_targets(hound, &names, &count);
+		if (rc == EOK) {
+			printf("Available targets:\n");
+			for (size_t i = 0; i < count; i++)
+				printf(" - %s\n", names[i]);
+		}
+
 		return 1;
 	}
Index: uspace/app/pci/Makefile
===================================================================
--- uspace/app/pci/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/pci/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2019 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.
+#
+
+USPACE_PREFIX = ../..
+BINARY = pci
+
+SOURCES = \
+	pci.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/pci/doc/doxygroups.h
===================================================================
--- uspace/app/pci/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/pci/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,4 @@
+/** @addtogroup pci pci
+ * @brief Tool for listing PCI devices
+ * @ingroup apps
+ */
Index: uspace/app/pci/pci.c
===================================================================
--- uspace/app/pci/pci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/app/pci/pci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup pci
+ * @{
+ */
+
+/**
+ * @file
+ * @brief Tool for listing PCI devices.
+ */
+
+#include <devman.h>
+#include <errno.h>
+#include <io/table.h>
+#include <loc.h>
+#include <pci.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <str.h>
+
+#define NAME	"mkext4"
+
+#define MAX_NAME_LENGTH 1024
+
+static void syntax_print(void);
+static errno_t pci_list(void);
+static errno_t pci_list_bridge(const char *);
+static errno_t pci_list_bridge_id(service_id_t);
+
+int main(int argc, char **argv)
+{
+	errno_t rc;
+	const char *bridge = NULL;
+
+	--argc;
+	++argv;
+
+	while (argc > 0 && argv[0][0] == '-') {
+		if (str_cmp(argv[0], "--bridge") == 0) {
+			--argc;
+			++argv;
+			if (argc < 1) {
+				printf("Option argument missing.\n");
+				return 1;
+			}
+
+			bridge = argv[0];
+			--argc;
+			++argv;
+		} else {
+			syntax_print();
+			return 1;
+		}
+	}
+
+	if (argc != 0) {
+		syntax_print();
+		return 1;
+	}
+
+	if (bridge != NULL)
+		rc = pci_list_bridge(bridge);
+	else
+		rc = pci_list();
+
+	if (rc != EOK)
+		return 1;
+
+	return 0;
+}
+
+static void syntax_print(void)
+{
+	printf("syntax: pci [<options>]\n");
+	printf("options:\n"
+	    "\t--bridge <svc-name> Only devices under host bridge <svc-name>\n");
+}
+
+/** List PCI devices. */
+static errno_t pci_list(void)
+{
+	errno_t rc;
+	category_id_t pci_cat_id;
+	service_id_t *svc_ids = NULL;
+	size_t svc_cnt;
+	size_t i;
+
+	rc = loc_category_get_id("pci", &pci_cat_id, 0);
+	if (rc != EOK) {
+		printf("Error getting 'pci' category ID.\n");
+		goto error;
+	}
+
+	rc = loc_category_get_svcs(pci_cat_id, &svc_ids, &svc_cnt);
+	if (rc != EOK) {
+		printf("Error getting list of PCI services.\n");
+		goto error;
+	}
+
+	for (i = 0; i < svc_cnt; i++) {
+		if (i > 0)
+			putchar('\n');
+
+		rc = pci_list_bridge_id(svc_ids[i]);
+		if (rc != EOK)
+			goto error;
+	}
+
+	free(svc_ids);
+	return EOK;
+error:
+	if (svc_ids != NULL)
+		free(svc_ids);
+	return rc;
+}
+
+/** List PCI devices under a host bridge specified by name.
+ *
+ * @param svc_name PCI service name
+ * @return EOK on success or an error code
+ */
+static errno_t pci_list_bridge(const char *svc_name)
+{
+	errno_t rc;
+	service_id_t svc_id;
+
+	rc = loc_service_get_id(svc_name, &svc_id, 0);
+	if (rc != EOK) {
+		printf("Error looking up host bridge '%s'.\n", svc_name);
+		return rc;
+	}
+
+	return pci_list_bridge_id(svc_id);
+}
+
+/** List PCI devices under a host bridge specified by ID.
+ *
+ * @param svc_id PCI service ID
+ * @return EOK on success or an error code
+ */
+static errno_t pci_list_bridge_id(service_id_t svc_id)
+{
+	errno_t rc;
+	devman_handle_t *dev_ids = NULL;
+	size_t dev_cnt;
+	pci_dev_info_t dev_info;
+	size_t i;
+	pci_t *pci = NULL;
+	char *svc_name = NULL;
+	char *drv_name = NULL;
+	table_t *table = NULL;
+
+	drv_name = malloc(MAX_NAME_LENGTH);
+	if (drv_name == NULL) {
+		printf("Out of memory.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = table_create(&table);
+	if (rc != EOK) {
+		printf("Out of memory.\n");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	table_header_row(table);
+	table_printf(table, "Address\t" "Type\t" "Driver\n");
+
+	rc = loc_service_get_name(svc_id, &svc_name);
+	if (rc != EOK) {
+		printf("Error getting service name.\n");
+		goto error;
+	}
+
+	rc = pci_open(svc_id, &pci);
+	if (rc != EOK) {
+		printf("Error opening PCI service '%s'.\n", svc_name);
+		goto error;
+	}
+
+	rc = pci_get_devices(pci, &dev_ids, &dev_cnt);
+	if (rc != EOK) {
+		printf("Error getting PCI device list.\n");
+		goto error;
+	}
+
+	for (i = 0; i < dev_cnt; i++) {
+		rc = pci_dev_get_info(pci, dev_ids[i], &dev_info);
+		if (rc != EOK) {
+			printf("Error getting PCI device info.\n");
+			goto error;
+		}
+
+		rc = devman_fun_get_driver_name(dev_info.dev_handle,
+		    drv_name, MAX_NAME_LENGTH);
+		if (rc != EOK && rc != EINVAL) {
+			printf("Error getting driver name.\n");
+			goto error;
+		}
+
+		if (rc == EINVAL)
+			drv_name[0] = '\0';
+
+		table_printf(table, "%02x.%02x.%x\t" "%04x:%04x\t"
+		    "%s\n", dev_info.bus_num, dev_info.dev_num,
+		    dev_info.fn_num, dev_info.vendor_id,
+		    dev_info.device_id, drv_name);
+	}
+
+	printf("Device listing for host bridge %s:\n\n", svc_name);
+	rc = table_print_out(table, stdout);
+	if (rc != EOK) {
+		printf("Error printing table.\n");
+		goto error;
+	}
+
+	table_destroy(table);
+	table = NULL;
+	free(dev_ids);
+	dev_ids = NULL;
+	pci_close(pci);
+	pci = NULL;
+	free(svc_name);
+	svc_name = NULL;
+
+	free(drv_name);
+	return EOK;
+error:
+	if (drv_name != NULL)
+		free(drv_name);
+	if (table != NULL)
+		table_destroy(table);
+	if (pci != NULL)
+		pci_close(pci);
+	if (svc_name != NULL)
+		free(svc_name);
+	if (dev_ids != NULL)
+		free(dev_ids);
+	return rc;
+}
+
+/**
+ * @}
+ */
Index: uspace/app/perf/Makefile
===================================================================
--- uspace/app/perf/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,42 +1,0 @@
-#
-# Copyright (c) 2018 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.
-#
-
-USPACE_PREFIX = ../..
-
-LIBS = math
-
-BINARY = perf
-
-SOURCES = \
-	perf.c \
-	ipc/ns_ping.c \
-	ipc/ping_pong.c \
-	malloc/malloc1.c \
-	malloc/malloc2.c
-
-include $(USPACE_PREFIX)/Makefile.common
Index: uspace/app/perf/doc/doxygroups.h
===================================================================
--- uspace/app/perf/doc/doxygroups.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,4 +1,0 @@
-/** @addtogroup perf perf
- * @brief User space performance measuring tool
- * @ingroup apps
- */
Index: uspace/app/perf/ipc/ns_ping.c
===================================================================
--- uspace/app/perf/ipc/ns_ping.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,134 +1,0 @@
-/*
- * Copyright (c) 2018 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 <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <ns.h>
-#include <async.h>
-#include <errno.h>
-#include "../perf.h"
-
-#define MIN_DURATION_SECS  10
-#define NUM_SAMPLES 10
-
-static errno_t ping_pong_measure(uint64_t niter, uint64_t *rduration)
-{
-	struct timespec start;
-	uint64_t count;
-
-	getuptime(&start);
-
-	for (count = 0; count < niter; count++) {
-		errno_t retval = ns_ping();
-
-		if (retval != EOK) {
-			printf("Error sending ping message.\n");
-			return EIO;
-		}
-	}
-
-	struct timespec now;
-	getuptime(&now);
-
-	*rduration = ts_sub_diff(&now, &start) / 1000;
-	return EOK;
-}
-
-static void ping_pong_report(uint64_t niter, uint64_t duration)
-{
-	printf("Completed %" PRIu64 " round trips in %" PRIu64 " us",
-	    niter, duration);
-
-	if (duration > 0) {
-		printf(", %" PRIu64 " rt/s.\n", niter * 1000 * 1000 / duration);
-	} else {
-		printf(".\n");
-	}
-}
-
-const char *bench_ns_ping(void)
-{
-	errno_t rc;
-	uint64_t duration;
-	uint64_t dsmp[NUM_SAMPLES];
-
-	printf("Warm up and determine work size...\n");
-
-	struct timespec start;
-	getuptime(&start);
-
-	uint64_t niter = 1;
-
-	while (true) {
-		rc = ping_pong_measure(niter, &duration);
-		if (rc != EOK)
-			return "Failed.";
-
-		ping_pong_report(niter, duration);
-
-		if (duration >= MIN_DURATION_SECS * 1000000)
-			break;
-
-		niter *= 2;
-	}
-
-	printf("Measure %d samples...\n", NUM_SAMPLES);
-
-	int i;
-
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		rc = ping_pong_measure(niter, &dsmp[i]);
-		if (rc != EOK)
-			return "Failed.";
-
-		ping_pong_report(niter, dsmp[i]);
-	}
-
-	double sum = 0.0;
-
-	for (i = 0; i < NUM_SAMPLES; i++)
-		sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
-
-	double avg = sum / NUM_SAMPLES;
-
-	double qd = 0.0;
-	double d;
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
-		qd += d * d;
-	}
-
-	double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
-
-	printf("Average: %.0f rt/s Std.dev^2: %.0f rt/s Samples: %d\n",
-	    avg, stddev, NUM_SAMPLES);
-
-	return NULL;
-}
Index: uspace/app/perf/ipc/ns_ping.def
===================================================================
--- uspace/app/perf/ipc/ns_ping.def	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,5 +1,0 @@
-{
-	"ns_ping",
-	"Name service IPC ping-pong benchmark",
-	&bench_ns_ping
-},
Index: uspace/app/perf/ipc/ping_pong.c
===================================================================
--- uspace/app/perf/ipc/ping_pong.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,149 +1,0 @@
-/*
- * Copyright (c) 2009 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 <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <ipc_test.h>
-#include <async.h>
-#include <errno.h>
-#include "../perf.h"
-
-#define MIN_DURATION_SECS  10
-#define NUM_SAMPLES 10
-
-static errno_t ping_pong_measure(ipc_test_t *test, uint64_t niter,
-    uint64_t *rduration)
-{
-	struct timespec start;
-	uint64_t count;
-
-	getuptime(&start);
-
-	for (count = 0; count < niter; count++) {
-		errno_t retval = ipc_test_ping(test);
-
-		if (retval != EOK) {
-			printf("Error sending ping message.\n");
-			return EIO;
-		}
-	}
-
-	struct timespec now;
-	getuptime(&now);
-
-	*rduration = ts_sub_diff(&now, &start) / 1000;
-	return EOK;
-}
-
-static void ping_pong_report(uint64_t niter, uint64_t duration)
-{
-	printf("Completed %" PRIu64 " round trips in %" PRIu64 " us",
-	    niter, duration);
-
-	if (duration > 0) {
-		printf(", %" PRIu64 " rt/s.\n", niter * 1000 * 1000 / duration);
-	} else {
-		printf(".\n");
-	}
-}
-
-const char *bench_ping_pong(void)
-{
-	errno_t rc;
-	uint64_t duration;
-	uint64_t dsmp[NUM_SAMPLES];
-	ipc_test_t *test;
-	const char *msg;
-
-	rc = ipc_test_create(&test);
-	if (rc != EOK)
-		return "Failed contacting IPC test server.";
-
-	printf("Warm up and determine work size...\n");
-
-	struct timespec start;
-	getuptime(&start);
-
-	uint64_t niter = 1;
-
-	while (true) {
-		rc = ping_pong_measure(test, niter, &duration);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		ping_pong_report(niter, duration);
-
-		if (duration >= MIN_DURATION_SECS * 1000000)
-			break;
-
-		niter *= 2;
-	}
-
-	printf("Measure %d samples...\n", NUM_SAMPLES);
-
-	int i;
-
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		rc = ping_pong_measure(test, niter, &dsmp[i]);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		ping_pong_report(niter, dsmp[i]);
-	}
-
-	double sum = 0.0;
-
-	for (i = 0; i < NUM_SAMPLES; i++)
-		sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
-
-	double avg = sum / NUM_SAMPLES;
-
-	double qd = 0.0;
-	double d;
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
-		qd += d * d;
-	}
-
-	double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
-
-	printf("Average: %.0f rt/s Std.dev^2: %.0f rt/s Samples: %d\n",
-	    avg, stddev, NUM_SAMPLES);
-
-	ipc_test_destroy(test);
-	return NULL;
-error:
-	ipc_test_destroy(test);
-	return msg;
-}
Index: uspace/app/perf/ipc/ping_pong.def
===================================================================
--- uspace/app/perf/ipc/ping_pong.def	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,5 +1,0 @@
-{
-	"ping_pong",
-	"IPC ping-pong benchmark",
-	&bench_ping_pong
-},
Index: uspace/app/perf/malloc/malloc1.c
===================================================================
--- uspace/app/perf/malloc/malloc1.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,138 +1,0 @@
-/*
- * Copyright (c) 2018 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 <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <errno.h>
-#include "../perf.h"
-
-#define MIN_DURATION_SECS  10
-#define NUM_SAMPLES 10
-
-static errno_t malloc1_measure(uint64_t niter, uint64_t *rduration)
-{
-	struct timespec start;
-	uint64_t count;
-	void *p;
-
-	getuptime(&start);
-
-	for (count = 0; count < niter; count++) {
-		p = malloc(1);
-		if (p == NULL)
-			return ENOMEM;
-		free(p);
-	}
-
-	struct timespec now;
-	getuptime(&now);
-
-	*rduration = ts_sub_diff(&now, &start) / 1000;
-	return EOK;
-}
-
-static void malloc1_report(uint64_t niter, uint64_t duration)
-{
-	printf("Completed %" PRIu64 " allocations and deallocations in %" PRIu64 " us",
-	    niter, duration);
-
-	if (duration > 0) {
-		printf(", %" PRIu64 " cycles/s.\n", niter * 1000 * 1000 / duration);
-	} else {
-		printf(".\n");
-	}
-}
-
-const char *bench_malloc1(void)
-{
-	errno_t rc;
-	uint64_t duration;
-	uint64_t dsmp[NUM_SAMPLES];
-	const char *msg;
-
-	printf("Warm up and determine work size...\n");
-
-	struct timespec start;
-	getuptime(&start);
-
-	uint64_t niter = 1;
-
-	while (true) {
-		rc = malloc1_measure(niter, &duration);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		malloc1_report(niter, duration);
-
-		if (duration >= MIN_DURATION_SECS * 1000000)
-			break;
-
-		niter *= 2;
-	}
-
-	printf("Measure %d samples...\n", NUM_SAMPLES);
-
-	int i;
-
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		rc = malloc1_measure(niter, &dsmp[i]);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		malloc1_report(niter, dsmp[i]);
-	}
-
-	double sum = 0.0;
-
-	for (i = 0; i < NUM_SAMPLES; i++)
-		sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
-
-	double avg = sum / NUM_SAMPLES;
-
-	double qd = 0.0;
-	double d;
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
-		qd += d * d;
-	}
-
-	double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
-
-	printf("Average: %.0f cycles/s Std.dev^2: %.0f cycles/s Samples: %d\n",
-	    avg, stddev, NUM_SAMPLES);
-
-	return NULL;
-error:
-	return msg;
-}
Index: uspace/app/perf/malloc/malloc1.def
===================================================================
--- uspace/app/perf/malloc/malloc1.def	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,5 +1,0 @@
-{
-	"malloc1",
-	"User-space memory allocator benchmark, repeatedly allocate one block",
-	&bench_malloc1
-},
Index: uspace/app/perf/malloc/malloc2.c
===================================================================
--- uspace/app/perf/malloc/malloc2.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,146 +1,0 @@
-/*
- * Copyright (c) 2018 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 <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <errno.h>
-#include "../perf.h"
-
-#define MIN_DURATION_SECS  10
-#define NUM_SAMPLES 10
-
-static errno_t malloc2_measure(uint64_t niter, uint64_t *rduration)
-{
-	struct timespec start;
-	uint64_t count;
-	void **p;
-
-	getuptime(&start);
-
-	p = malloc(niter * sizeof(void *));
-	if (p == NULL)
-		return ENOMEM;
-
-	for (count = 0; count < niter; count++) {
-		p[count] = malloc(1);
-		if (p[count] == NULL)
-			return ENOMEM;
-	}
-
-	for (count = 0; count < niter; count++)
-		free(p[count]);
-
-	free(p);
-
-	struct timespec now;
-	getuptime(&now);
-
-	*rduration = ts_sub_diff(&now, &start) / 1000;
-	return EOK;
-}
-
-static void malloc2_report(uint64_t niter, uint64_t duration)
-{
-	printf("Completed %" PRIu64 " allocations and deallocations in %" PRIu64 " us",
-	    niter, duration);
-
-	if (duration > 0) {
-		printf(", %" PRIu64 " cycles/s.\n", niter * 1000 * 1000 / duration);
-	} else {
-		printf(".\n");
-	}
-}
-
-const char *bench_malloc2(void)
-{
-	errno_t rc;
-	uint64_t duration;
-	uint64_t dsmp[NUM_SAMPLES];
-	const char *msg;
-
-	printf("Warm up and determine work size...\n");
-
-	struct timespec start;
-	getuptime(&start);
-
-	uint64_t niter = 1;
-
-	while (true) {
-		rc = malloc2_measure(niter, &duration);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		malloc2_report(niter, duration);
-
-		if (duration >= MIN_DURATION_SECS * 1000000)
-			break;
-
-		niter *= 2;
-	}
-
-	printf("Measure %d samples...\n", NUM_SAMPLES);
-
-	int i;
-
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		rc = malloc2_measure(niter, &dsmp[i]);
-		if (rc != EOK) {
-			msg = "Failed.";
-			goto error;
-		}
-
-		malloc2_report(niter, dsmp[i]);
-	}
-
-	double sum = 0.0;
-
-	for (i = 0; i < NUM_SAMPLES; i++)
-		sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
-
-	double avg = sum / NUM_SAMPLES;
-
-	double qd = 0.0;
-	double d;
-	for (i = 0; i < NUM_SAMPLES; i++) {
-		d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
-		qd += d * d;
-	}
-
-	double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
-
-	printf("Average: %.0f cycles/s Std.dev^2: %.0f cycles/s Samples: %d\n",
-	    avg, stddev, NUM_SAMPLES);
-
-	return NULL;
-error:
-	return msg;
-}
Index: uspace/app/perf/malloc/malloc2.def
===================================================================
--- uspace/app/perf/malloc/malloc2.def	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,5 +1,0 @@
-{
-	"malloc2",
-	"User-space memory allocator benchmark, allocate many small blocks",
-	&bench_malloc2
-},
Index: uspace/app/perf/perf.c
===================================================================
--- uspace/app/perf/perf.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,149 +1,0 @@
-/*
- * Copyright (c) 2018 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.
- */
-
-/** @addtogroup perf
- * @{
- */
-/**
- * @file
- */
-
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <str.h>
-#include "perf.h"
-
-benchmark_t benchmarks[] = {
-#include "ipc/ns_ping.def"
-#include "ipc/ping_pong.def"
-#include "malloc/malloc1.def"
-#include "malloc/malloc2.def"
-	{ NULL, NULL, NULL }
-};
-
-static bool run_benchmark(benchmark_t *bench)
-{
-	/* Execute the benchmarl */
-	const char *ret = bench->entry();
-
-	if (ret == NULL) {
-		printf("\nBenchmark completed\n");
-		return true;
-	}
-
-	printf("\n%s\n", ret);
-	return false;
-}
-
-static int run_benchmarks(void)
-{
-	benchmark_t *bench;
-	unsigned int i = 0;
-	unsigned int n = 0;
-
-	char *failed_names = NULL;
-
-	printf("\n*** Running all benchmarks ***\n\n");
-
-	for (bench = benchmarks; bench->name != NULL; bench++) {
-		printf("%s (%s)\n", bench->name, bench->desc);
-		if (run_benchmark(bench)) {
-			i++;
-			continue;
-		}
-
-		if (!failed_names) {
-			failed_names = str_dup(bench->name);
-		} else {
-			char *f = NULL;
-			asprintf(&f, "%s, %s", failed_names, bench->name);
-			if (!f) {
-				printf("Out of memory.\n");
-				abort();
-			}
-			free(failed_names);
-			failed_names = f;
-		}
-		n++;
-	}
-
-	printf("\nCompleted, %u benchmarks run, %u succeeded.\n", i + n, i);
-	if (failed_names)
-		printf("Failed benchmarks: %s\n", failed_names);
-
-	return n;
-}
-
-static void list_benchmarks(void)
-{
-	size_t len = 0;
-	benchmark_t *bench;
-	for (bench = benchmarks; bench->name != NULL; bench++) {
-		if (str_length(bench->name) > len)
-			len = str_length(bench->name);
-	}
-
-	unsigned int _len = (unsigned int) len;
-	if ((_len != len) || (((int) _len) < 0)) {
-		printf("Command length overflow\n");
-		return;
-	}
-
-	for (bench = benchmarks; bench->name != NULL; bench++)
-		printf("%-*s %s\n", _len, bench->name, bench->desc);
-
-	printf("%-*s Run all benchmarks\n", _len, "*");
-}
-
-int main(int argc, char *argv[])
-{
-	if (argc < 2) {
-		printf("Usage:\n\n");
-		printf("%s <benchmark>\n\n", argv[0]);
-		list_benchmarks();
-		return 0;
-	}
-
-	if (str_cmp(argv[1], "*") == 0) {
-		return run_benchmarks();
-	}
-
-	benchmark_t *bench;
-	for (bench = benchmarks; bench->name != NULL; bench++) {
-		if (str_cmp(argv[1], bench->name) == 0) {
-			return (run_benchmark(bench) ? 0 : -1);
-		}
-	}
-
-	printf("Unknown benchmark \"%s\"\n", argv[1]);
-	return -2;
-}
-
-/** @}
- */
Index: uspace/app/perf/perf.h
===================================================================
--- uspace/app/perf/perf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,58 +1,0 @@
-/*
- * Copyright (c) 2018 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.
- */
-
-/** @addtogroup perf
- * @{
- */
-/** @file
- */
-
-#ifndef PERF_H_
-#define PERF_H_
-
-#include <stdbool.h>
-
-typedef const char *(*benchmark_entry_t)(void);
-
-typedef struct {
-	const char *name;
-	const char *desc;
-	benchmark_entry_t entry;
-} benchmark_t;
-
-extern const char *bench_malloc1(void);
-extern const char *bench_malloc2(void);
-extern const char *bench_ns_ping(void);
-extern const char *bench_ping_pong(void);
-
-extern benchmark_t benchmarks[];
-
-#endif
-
-/** @}
- */
Index: uspace/app/sbi/src/bigint.c
===================================================================
--- uspace/app/sbi/src/bigint.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/sbi/src/bigint.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -379,5 +379,5 @@
 	printf("Convert bigint to string.\n");
 #endif
-	static_assert(BIGINT_BASE >= 10);
+	static_assert(BIGINT_BASE >= 10, "");
 
 	/* Compute number of characters. */
Index: uspace/app/sportdmp/sportdmp.c
===================================================================
--- uspace/app/sportdmp/sportdmp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/sportdmp/sportdmp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -146,5 +146,6 @@
 
 	while (true) {
-		rc = chardev_read(chardev, buf, BUF_SIZE, &nread);
+		rc = chardev_read(chardev, buf, BUF_SIZE, &nread,
+		    chardev_f_none);
 		for (size_t i = 0; i < nread; i++) {
 			printf("%02hhx ", buf[i]);
Index: uspace/app/sysinst/rdimg.c
===================================================================
--- uspace/app/sysinst/rdimg.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/sysinst/rdimg.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,4 +34,5 @@
 
 #include <errno.h>
+#include <fibril.h>
 #include <stdio.h>
 #include <stdlib.h>
Index: uspace/app/sysinst/sysinst.c
===================================================================
--- uspace/app/sysinst/sysinst.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/sysinst/sysinst.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,5 +62,5 @@
  * in Grub notation).
  */
-#define DEFAULT_DEV "devices/\\hw\\pci0\\00:01.0\\ata-c1\\d0"
+#define DEFAULT_DEV "devices/\\hw\\sys\\00:01.0\\ata-c1\\d0"
 //#define DEFAULT_DEV "devices/\\hw\\pci0\\00:01.2\\uhci_rh\\usb01_a1\\mass-storage0\\l0"
 /** Volume label for the new file system */
Index: uspace/app/taskdump/symtab.c
===================================================================
--- uspace/app/taskdump/symtab.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/taskdump/symtab.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -215,5 +215,5 @@
 			continue;
 
-		stype = ELF_ST_TYPE(st->sym[i].st_info);
+		stype = elf_st_type(st->sym[i].st_info);
 		if (stype != STT_OBJECT && stype != STT_FUNC)
 			continue;
@@ -257,5 +257,5 @@
 			continue;
 
-		stype = ELF_ST_TYPE(st->sym[i].st_info);
+		stype = elf_st_type(st->sym[i].st_info);
 		if (stype != STT_OBJECT && stype != STT_FUNC &&
 		    stype != STT_NOTYPE) {
Index: uspace/app/tester/chardev/chardev1.c
===================================================================
--- uspace/app/tester/chardev/chardev1.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/tester/chardev/chardev1.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jiri Svoboda
+ * Copyright (c) 2019 Jiri Svoboda
  * All rights reserved.
  *
@@ -76,5 +76,6 @@
 	TPRINTF("Sent %zu bytes\n", nbytes);
 
-	rc = chardev_read(chardev, small_buffer, SMALL_BUFFER_SIZE, &nbytes);
+	rc = chardev_read(chardev, small_buffer, SMALL_BUFFER_SIZE, &nbytes,
+	    chardev_f_none);
 	if (rc != EOK) {
 		chardev_close(chardev);
@@ -128,5 +129,6 @@
 	TPRINTF("Sent %zu bytes\n", nbytes);
 
-	rc = chardev_read(chardev, large_buffer, LARGE_BUFFER_SIZE, &nbytes);
+	rc = chardev_read(chardev, large_buffer, LARGE_BUFFER_SIZE, &nbytes,
+	    chardev_f_none);
 	if (rc != EOK) {
 		chardev_close(chardev);
@@ -181,5 +183,6 @@
 	    str_error_name(rc));
 
-	rc = chardev_read(chardev, small_buffer, SMALL_BUFFER_SIZE, &nbytes);
+	rc = chardev_read(chardev, small_buffer, SMALL_BUFFER_SIZE, &nbytes,
+	    chardev_f_none);
 	if (rc != EIO || nbytes != 1) {
 		chardev_close(chardev);
Index: uspace/app/tester/hw/serial/serial1.c
===================================================================
--- uspace/app/tester/hw/serial/serial1.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/tester/hw/serial/serial1.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -136,5 +136,6 @@
 	while (total < cnt) {
 
-		rc = chardev_read(chardev, buf, cnt - total, &nread);
+		rc = chardev_read(chardev, buf, cnt - total, &nread,
+		    chardev_f_none);
 		if (rc != EOK) {
 			(void) serial_set_comm_props(serial, old_baud,
Index: uspace/app/tester/stdio/logger2.c
===================================================================
--- uspace/app/tester/stdio/logger2.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/tester/stdio/logger2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,6 +30,6 @@
 #include <stdlib.h>
 #include <errno.h>
+#include <fibril.h>
 #include <io/log.h>
-#include <async.h>
 #include "../tester.h"
 
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/tester/tester.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,4 +35,5 @@
  */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stddef.h>
@@ -40,4 +41,5 @@
 #include <str.h>
 #include <io/log.h>
+#include <types/casting.h>
 #include "tester.h"
 
@@ -144,15 +146,11 @@
 	}
 
-	unsigned int _len = (unsigned int) len;
-	if ((_len != len) || (((int) _len) < 0)) {
-		printf("Command length overflow\n");
-		return;
-	}
+	assert(can_cast_size_t_to_int(len) && "test name length overflow");
 
 	for (test = tests; test->name != NULL; test++)
-		printf("%-*s %s%s\n", _len, test->name, test->desc,
+		printf("%-*s %s%s\n", (int) len, test->name, test->desc,
 		    (test->safe ? "" : " (unsafe)"));
 
-	printf("%-*s Run all safe tests\n", _len, "*");
+	printf("%-*s Run all safe tests\n", (int) len, "*");
 }
 
Index: uspace/app/trace/ipcp.c
===================================================================
--- uspace/app/trace/ipcp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/trace/ipcp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -72,8 +72,8 @@
 proto_t	*proto_unknown;		/**< Protocol with no known methods. */
 
-static size_t pending_call_key_hash(void *key)
-{
-	cap_call_handle_t *chandle = (cap_call_handle_t *) key;
-	return CAP_HANDLE_RAW(*chandle);
+static size_t pending_call_key_hash(const void *key)
+{
+	const cap_call_handle_t *chandle = key;
+	return cap_handle_raw(*chandle);
 }
 
@@ -81,10 +81,10 @@
 {
 	pending_call_t *hs = hash_table_get_inst(item, pending_call_t, link);
-	return CAP_HANDLE_RAW(hs->call_handle);
-}
-
-static bool pending_call_key_equal(void *key, const ht_link_t *item)
-{
-	cap_call_handle_t *chandle = (cap_call_handle_t *) key;
+	return cap_handle_raw(hs->call_handle);
+}
+
+static bool pending_call_key_equal(const void *key, const ht_link_t *item)
+{
+	const cap_call_handle_t *chandle = key;
 	pending_call_t *hs = hash_table_get_inst(item, pending_call_t, link);
 
@@ -104,16 +104,16 @@
 	// XXX: there is no longer a limit on the number of phones as phones are
 	// now handled using capabilities
-	if (CAP_HANDLE_RAW(phone) < 0 || CAP_HANDLE_RAW(phone) >= MAX_PHONE)
+	if (cap_handle_raw(phone) < 0 || cap_handle_raw(phone) >= MAX_PHONE)
 		return;
-	connections[CAP_HANDLE_RAW(phone)].server = server;
-	connections[CAP_HANDLE_RAW(phone)].proto = proto;
-	have_conn[CAP_HANDLE_RAW(phone)] = 1;
+	connections[cap_handle_raw(phone)].server = server;
+	connections[cap_handle_raw(phone)].proto = proto;
+	have_conn[cap_handle_raw(phone)] = 1;
 }
 
 void ipcp_connection_clear(cap_phone_handle_t phone)
 {
-	have_conn[CAP_HANDLE_RAW(phone)] = 0;
-	connections[CAP_HANDLE_RAW(phone)].server = 0;
-	connections[CAP_HANDLE_RAW(phone)].proto = NULL;
+	have_conn[cap_handle_raw(phone)] = 0;
+	connections[cap_handle_raw(phone)].server = 0;
+	connections[cap_handle_raw(phone)].proto = NULL;
 }
 
@@ -184,6 +184,6 @@
 	int i;
 
-	if (have_conn[CAP_HANDLE_RAW(phandle)])
-		proto = connections[CAP_HANDLE_RAW(phandle)].proto;
+	if (have_conn[cap_handle_raw(phandle)])
+		proto = connections[cap_handle_raw(phandle)].proto;
 	else
 		proto = NULL;
@@ -194,5 +194,5 @@
 		printf("Call handle: %p, phone: %p, proto: %s, method: ",
 		    chandle, phandle, (proto ? proto->name : "n/a"));
-		ipc_m_print(proto, IPC_GET_IMETHOD(*call));
+		ipc_m_print(proto, ipc_get_imethod(call));
 		printf(" args: (%" PRIun ", %" PRIun ", %" PRIun ", "
 		    "%" PRIun ", %" PRIun ")\n",
@@ -203,5 +203,5 @@
 
 		if (proto != NULL) {
-			oper = proto_get_oper(proto, IPC_GET_IMETHOD(*call));
+			oper = proto_get_oper(proto, ipc_get_imethod(call));
 		} else {
 			oper = NULL;
@@ -262,6 +262,6 @@
 
 	phone = pcall->phone_handle;
-	method = IPC_GET_IMETHOD(pcall->question);
-	retval = IPC_GET_RETVAL(*answer);
+	method = ipc_get_imethod(&pcall->question);
+	retval = ipc_get_retval(answer);
 
 	resp = answer->args;
@@ -270,7 +270,7 @@
 		printf("Response to %p: retval=%s, args = (%" PRIun ", "
 		    "%" PRIun ", %" PRIun ", %" PRIun ", %" PRIun ")\n",
-		    call_handle, str_error_name(retval), IPC_GET_ARG1(*answer),
-		    IPC_GET_ARG2(*answer), IPC_GET_ARG3(*answer),
-		    IPC_GET_ARG4(*answer), IPC_GET_ARG5(*answer));
+		    call_handle, str_error_name(retval), ipc_get_arg1(answer),
+		    ipc_get_arg2(answer), ipc_get_arg3(answer),
+		    ipc_get_arg4(answer), ipc_get_arg5(answer));
 	}
 
@@ -305,10 +305,10 @@
 	    (retval == 0)) {
 		/* Connected to a service (through NS) */
-		service = IPC_GET_ARG2(pcall->question);
+		service = ipc_get_arg2(&pcall->question);
 		proto = proto_get_by_srv(service);
 		if (proto == NULL)
 			proto = proto_unknown;
 
-		cphone = (cap_phone_handle_t) IPC_GET_ARG5(*answer);
+		cphone = (cap_phone_handle_t) ipc_get_arg5(answer);
 		if ((display_mask & DM_SYSTEM) != 0) {
 			printf("Registering connection (phone %p, protocol: %s)\n", cphone,
Index: uspace/app/trace/proto.c
===================================================================
--- uspace/app/trace/proto.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/trace/proto.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -57,7 +57,8 @@
 /* Hash table operations. */
 
-static size_t srv_proto_key_hash(void *key)
-{
-	return *(int *)key;
+static size_t srv_proto_key_hash(const void *key)
+{
+	const int *n = key;
+	return *n;
 }
 
@@ -68,8 +69,9 @@
 }
 
-static bool srv_proto_key_equal(void *key, const ht_link_t *item)
-{
+static bool srv_proto_key_equal(const void *key, const ht_link_t *item)
+{
+	const int *n = key;
 	srv_proto_t *sp = hash_table_get_inst(item, srv_proto_t, link);
-	return sp->srv == *(int *)key;
+	return sp->srv == *n;
 }
 
@@ -82,7 +84,8 @@
 };
 
-static size_t method_oper_key_hash(void *key)
-{
-	return *(int *)key;
+static size_t method_oper_key_hash(const void *key)
+{
+	const int *n = key;
+	return *n;
 }
 
@@ -93,8 +96,9 @@
 }
 
-static bool method_oper_key_equal(void *key, const ht_link_t *item)
-{
+static bool method_oper_key_equal(const void *key, const ht_link_t *item)
+{
+	const int *n = key;
 	method_oper_t *mo = hash_table_get_inst(item, method_oper_t, link);
-	return mo->method == *(int *)key;
+	return mo->method == *n;
 }
 
Index: uspace/app/trace/trace.c
===================================================================
--- uspace/app/trace/trace.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/trace/trace.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -302,10 +302,10 @@
 	phandle = (cap_phone_handle_t) sc_args[0];
 
-	IPC_SET_IMETHOD(call, sc_args[1]);
-	IPC_SET_ARG1(call, sc_args[2]);
-	IPC_SET_ARG2(call, sc_args[3]);
-	IPC_SET_ARG3(call, sc_args[4]);
-	IPC_SET_ARG4(call, sc_args[5]);
-	IPC_SET_ARG5(call, 0);
+	ipc_set_imethod(&call, sc_args[1]);
+	ipc_set_arg1(&call, sc_args[2]);
+	ipc_set_arg2(&call, sc_args[3]);
+	ipc_set_arg3(&call, sc_args[4]);
+	ipc_set_arg4(&call, sc_args[5]);
+	ipc_set_arg5(&call, 0);
 
 	ipcp_call_out(phandle, &call, 0);
Index: uspace/app/wavplay/dplay.c
===================================================================
--- uspace/app/wavplay/dplay.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/wavplay/dplay.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -103,8 +103,8 @@
 		async_get_call(&call);
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case PCM_EVENT_PLAYBACK_STARTED:
 		case PCM_EVENT_FRAMES_PLAYED:
-			printf("%" PRIun " frames: ", IPC_GET_ARG1(call));
+			printf("%" PRIun " frames: ", ipc_get_arg1(&call));
 			async_answer_0(&call, EOK);
 			break;
@@ -118,5 +118,5 @@
 			return;
 		default:
-			printf("Unknown event %" PRIun ".\n", IPC_GET_IMETHOD(call));
+			printf("Unknown event %" PRIun ".\n", ipc_get_imethod(&call));
 			async_answer_0(&call, ENOTSUP);
 			continue;
Index: uspace/app/wavplay/drec.c
===================================================================
--- uspace/app/wavplay/drec.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/wavplay/drec.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,4 +36,5 @@
 #include <assert.h>
 #include <errno.h>
+#include <fibril.h>
 #include <str_error.h>
 #include <audio_pcm_iface.h>
@@ -88,6 +89,6 @@
  * Writes recorded data.
  *
- * @param icall Poitner to IPC call structure.
- * @param arg   Argument. Poitner to recording helper structure.
+ * @param icall Pointer to IPC call structure.
+ * @param arg   Argument. Pointer to recording helper structure.
  *
  */
@@ -102,5 +103,5 @@
 		async_get_call(&call);
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case PCM_EVENT_CAPTURE_TERMINATED:
 			printf("Recording terminated\n");
@@ -108,8 +109,8 @@
 			break;
 		case PCM_EVENT_FRAMES_CAPTURED:
-			printf("%" PRIun " frames\n", IPC_GET_ARG1(call));
+			printf("%" PRIun " frames\n", ipc_get_arg1(&call));
 			break;
 		default:
-			printf("Unknown event %" PRIun ".\n", IPC_GET_IMETHOD(call));
+			printf("Unknown event %" PRIun ".\n", ipc_get_imethod(&call));
 			async_answer_0(&call, ENOTSUP);
 			continue;
Index: uspace/app/wavplay/main.c
===================================================================
--- uspace/app/wavplay/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/app/wavplay/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -119,5 +119,5 @@
  * @return Error code
  */
-static errno_t hplay(const char *filename)
+static errno_t hplay(const char *filename, const char *target)
 {
 	printf("Hound playback: %s\n", filename);
@@ -158,8 +158,18 @@
 	}
 
-	ret = hound_context_connect_target(hound, HOUND_DEFAULT_TARGET);
+	ret = hound_context_connect_target(hound, target);
 	if (ret != EOK) {
-		printf("Failed to connect to default target: %s\n",
+		printf("Failed to connect to target '%s': %s\n", target,
 		    str_error(ret));
+
+		char **names = NULL;
+		size_t count = 0;
+		ret = hound_context_get_available_targets(hound, &names, &count);
+		if (ret == EOK) {
+			printf("Available targets:\n");
+			for (size_t i = 0; i < count; i++)
+				printf(" - %s\n", names[i]);
+		}
+
 		hound_context_destroy(hound);
 		fclose(source);
@@ -215,4 +225,5 @@
 	{ "parallel", no_argument, 0, 'p' },
 	{ "record", no_argument, 0, 'r' },
+	{ "target", required_argument, 0, 't' },
 	{ "help", no_argument, 0, 'h' },
 	{ 0, 0, 0, 0 }
@@ -230,6 +241,7 @@
 	printf("\t -r, --record\t Start recording instead of playback. "
 	    "(Not implemented)\n");
-	printf("\t -d, --device\t Use specified device instead of the sound "
-	    "service. Use location path or a special device `default'\n");
+	printf("\t -d, --device\t Direct output to specified device instead of "
+	    "the sound service. Use location path or a special device `default'\n");
+	printf("\t -t, --target\t Output to the specified audio target.\n");
 	printf("\t -p, --parallel\t Play given files in parallel instead of "
 	    "sequentially (does not work with -d).\n");
@@ -239,4 +251,5 @@
 {
 	const char *device = "default";
+	const char *target = HOUND_DEFAULT_TARGET;
 	int idx = 0;
 	bool direct = false, record = false, parallel = false;
@@ -246,5 +259,5 @@
 	/* Parse command line options */
 	while (ret != -1) {
-		ret = getopt_long(argc, argv, "d:prh", opts, &idx);
+		ret = getopt_long(argc, argv, "d:prt:h", opts, &idx);
 		switch (ret) {
 		case 'd':
@@ -257,4 +270,7 @@
 		case 'p':
 			parallel = true;
+			break;
+		case 't':
+			target = optarg;
 			break;
 		case 'h':
@@ -334,5 +350,5 @@
 				fibril_add_ready(fid);
 			} else {
-				hplay(file);
+				hplay(file, target);
 			}
 		}
Index: uspace/doc/main_page.h
===================================================================
--- uspace/doc/main_page.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,12 +1,0 @@
-/**
- * @mainpage HelenOS Operating System Source Code Reference
- *
- * HelenOS is a portable microkernel-based multiserver operating system designed and implemented from scratch. It decomposes key operating system functionality such as file systems, networking, device drivers and graphical user interface into a collection of fine-grained user space components that interact with each other via message passing. A failure or crash of one component does not directly harm others. HelenOS is therefore flexible, modular, extensible, fault tolerant and easy to understand.
- *
- * HelenOS does not aim to be a clone of any existing operating system and trades compatibility with legacy APIs for cleaner design. Most of HelenOS components have been made to order specifically for HelenOS so that its essential parts can stay free of adaptation layers, glue code, franken-components and the maintenance burden incurred by them.
- *
- * HelenOS runs on seven different processor architectures and machines ranging from embedded ARM devices and single-board computers through multicore 32-bit and 64-bit desktop PCs to 64-bit Itanium and SPARC rack-mount servers.
- *
- * HelenOS is open source, free software. Its source code is available under the BSD license. Some third-party components are licensed under GPL.
- *
- */
Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -151,4 +151,5 @@
 {
 	ddf_fun_t *fun_pcm = NULL;
+	bool bound = false;
 	hda_t *hda = NULL;
 	hw_res_list_parsed_t res;
@@ -299,9 +300,17 @@
 	}
 
-	ddf_fun_add_to_category(fun_pcm, "audio-pcm");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun_pcm, "audio-pcm");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function to audio-pcm category.");
+		goto error;
+	}
 
 	hw_res_list_parsed_clean(&res);
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun_pcm);
 	if (fun_pcm != NULL)
 		ddf_fun_destroy(fun_pcm);
@@ -376,5 +385,5 @@
 	hda_ctl_interrupt(hda->ctl);
 
-	if (IPC_GET_ARG3(*icall) != 0) {
+	if (ipc_get_arg3(icall) != 0) {
 		/* Buffer completed */
 		hda_lock(hda);
Index: uspace/drv/audio/hdaudio/hdaudio.ma
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.ma	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/audio/hdaudio/hdaudio.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 10 pci/ven=1002&dev=4383
+10 pci/ven=8086&dev=160c
 10 pci/ven=8086&dev=1e20
 10 pci/ven=8086&dev=2668
@@ -5,2 +6,3 @@
 10 pci/ven=8086&dev=1c20
 10 pci/ven=8086&dev=293e
+10 pci/ven=8086&dev=9ca0
Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/block/ahci/ahci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -816,5 +816,5 @@
  *
  * @param sata     SATA device structure.
- * @param phys     Physical addres of buffer with sector data.
+ * @param phys     Physical address of buffer with sector data.
  * @param blocknum Block number to write.
  *
@@ -897,6 +897,6 @@
 {
 	ahci_dev_t *ahci = dev_ahci_dev(dev);
-	unsigned int port = IPC_GET_ARG1(*icall);
-	ahci_port_is_t pxis = IPC_GET_ARG2(*icall);
+	unsigned int port = ipc_get_arg1(icall);
+	ahci_port_is_t pxis = ipc_get_arg2(icall);
 
 	if (port >= AHCI_MAX_PORTS)
Index: uspace/drv/block/ata_bd/main.c
===================================================================
--- uspace/drv/block/ata_bd/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/block/ata_bd/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -162,4 +162,5 @@
 	ddf_fun_t *fun = NULL;
 	ata_fun_t *afun = NULL;
+	bool bound = false;
 
 	fun_name = ata_fun_name(disk);
@@ -202,5 +203,12 @@
 	}
 
-	ddf_fun_add_to_category(fun, "disk");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "disk");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function %s to "
+		    "category 'disk': %s", fun_name, str_error(rc));
+		goto error;
+	}
 
 	free(fun_name);
@@ -208,4 +216,6 @@
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
Index: uspace/drv/block/ddisk/ddisk.c
===================================================================
--- uspace/drv/block/ddisk/ddisk.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/block/ddisk/ddisk.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -179,5 +179,5 @@
 {
 	ddf_msg(LVL_DEBUG, "ddisk_irq_handler(), status=%" PRIx32,
-	    (uint32_t) IPC_GET_ARG1(*icall));
+	    (uint32_t) ipc_get_arg1(icall));
 
 	ddisk_t *ddisk = (ddisk_t *) ddf_dev_data_get(dev);
@@ -319,4 +319,5 @@
 	errno_t rc;
 	ddf_fun_t *fun = NULL;
+	bool bound = false;
 
 	fun = ddf_fun_create(ddisk->dev, fun_exposed, DDISK_FUN_NAME);
@@ -337,9 +338,18 @@
 	}
 
-	ddf_fun_add_to_category(fun, "disk");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "disk");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function %s to category "
+		    "'disk': %s.\n", DDISK_FUN_NAME, str_error(rc));
+		goto error;
+	}
 	ddisk->fun = fun;
 
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
Index: uspace/drv/block/usbmast/main.c
===================================================================
--- uspace/drv/block/usbmast/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/block/usbmast/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -223,4 +223,5 @@
 	ddf_fun_t *fun = NULL;
 	usbmast_fun_t *mfun = NULL;
+	bool bound = false;
 
 	if (asprintf(&fun_name, "l%u", lun) < 0) {
@@ -299,5 +300,12 @@
 	}
 
-	ddf_fun_add_to_category(fun, "disk");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "disk");
+	if (rc != EOK) {
+		usb_log_error("Failed to add function %s to category 'disk': %s.",
+		    fun_name, str_error(rc));
+		goto error;
+	}
 
 	free(fun_name);
@@ -308,4 +316,6 @@
 	/* Error cleanup */
 error:
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
Index: uspace/drv/block/virtio-blk/Makefile
===================================================================
--- uspace/drv/block/virtio-blk/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/block/virtio-blk/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2019 Jakub Jermar
+# 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = drv scsi virtio
+BINARY = virtio-blk
+
+SOURCES = \
+	virtio-blk.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/block/virtio-blk/virtio-blk.c
===================================================================
--- uspace/drv/block/virtio-blk/virtio-blk.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/block/virtio-blk/virtio-blk.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2019 Jakub Jermar
+ * 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 "virtio-blk.h"
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include <as.h>
+#include <ddf/driver.h>
+#include <ddf/interrupt.h>
+#include <ddf/log.h>
+#include <pci_dev_iface.h>
+#include <fibril_synch.h>
+
+#include <bd_srv.h>
+
+#include <virtio-pci.h>
+
+#define NAME	"virtio-blk"
+
+#define VIRTIO_BLK_NUM_QUEUES	1
+
+#define RQ_QUEUE	0
+
+/*
+ * VIRTIO_BLK requests need at least two descriptors so that device-read-only
+ * buffers are separated from device-writable buffers. For convenience, we
+ * always use three descriptors for the request header, buffer and footer.
+ * We therefore organize the virtque so that first RQ_BUFFERS descriptors are
+ * used for request headers, the following RQ_BUFFERS descriptors are used
+ * for in/out buffers and the last RQ_BUFFERS descriptors are used for request
+ * footers.
+ */
+#define REQ_HEADER_DESC(descno)	(0 * RQ_BUFFERS + (descno))
+#define REQ_BUFFER_DESC(descno)	(1 * RQ_BUFFERS + (descno))
+#define REQ_FOOTER_DESC(descno)	(2 * RQ_BUFFERS + (descno))
+
+static errno_t virtio_blk_dev_add(ddf_dev_t *dev);
+
+static driver_ops_t virtio_blk_driver_ops = {
+	.dev_add = virtio_blk_dev_add
+};
+
+static driver_t virtio_blk_driver = {
+	.name = NAME,
+	.driver_ops = &virtio_blk_driver_ops
+};
+
+static void virtio_blk_irq_handler(ipc_call_t *icall, ddf_dev_t *dev)
+{
+	virtio_blk_t *virtio_blk = (virtio_blk_t *) ddf_dev_data_get(dev);
+	virtio_dev_t *vdev = &virtio_blk->virtio_dev;
+
+	uint16_t descno;
+	uint32_t len;
+
+	while (virtio_virtq_consume_used(vdev, RQ_QUEUE, &descno, &len)) {
+		assert(descno < RQ_BUFFERS);
+		fibril_mutex_lock(&virtio_blk->completion_lock[descno]);
+		fibril_condvar_signal(&virtio_blk->completion_cv[descno]);
+		fibril_mutex_unlock(&virtio_blk->completion_lock[descno]);
+	}
+}
+
+static errno_t virtio_blk_register_interrupt(ddf_dev_t *dev)
+{
+	virtio_blk_t *virtio_blk = (virtio_blk_t *) ddf_dev_data_get(dev);
+	virtio_dev_t *vdev = &virtio_blk->virtio_dev;
+
+	async_sess_t *parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_t res;
+	hw_res_list_parsed_init(&res);
+
+	hw_res_list_parsed_init(&res);
+	errno_t rc = hw_res_get_list_parsed(parent_sess, &res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (res.irqs.count < 1) {
+		hw_res_list_parsed_clean(&res);
+		return EINVAL;
+	}
+
+	virtio_blk->irq = res.irqs.irqs[0];
+	hw_res_list_parsed_clean(&res);
+
+	irq_pio_range_t pio_ranges[] = {
+		{
+			.base = vdev->isr_phys,
+			.size = sizeof(vdev->isr_phys),
+		}
+	};
+
+	irq_cmd_t irq_commands[] = {
+		{
+			.cmd = CMD_PIO_READ_8,
+			.addr = (void *) vdev->isr_phys,
+			.dstarg = 2
+		},
+		{
+			.cmd = CMD_PREDICATE,
+			.value = 1,
+			.srcarg = 2
+		},
+		{
+			.cmd = CMD_ACCEPT
+		}
+	};
+
+	irq_code_t irq_code = {
+		.rangecount = sizeof(pio_ranges) / sizeof(irq_pio_range_t),
+		.ranges = pio_ranges,
+		.cmdcount = sizeof(irq_commands) / sizeof(irq_cmd_t),
+		.cmds = irq_commands
+	};
+
+	return register_interrupt_handler(dev, virtio_blk->irq,
+	    virtio_blk_irq_handler, &irq_code, &virtio_blk->irq_handle);
+}
+
+static errno_t virtio_blk_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
+{
+	return EOK;
+}
+
+static errno_t virtio_blk_bd_close(bd_srv_t *bd)
+{
+	return EOK;
+}
+
+static errno_t virtio_blk_rw_block(virtio_blk_t *virtio_blk, bool read,
+    aoff64_t ba, void *buf)
+{
+	virtio_dev_t *vdev = &virtio_blk->virtio_dev;
+
+	/*
+	 * Allocate a descriptor.
+	 *
+	 * The allocated descno will determine the header descriptor
+	 * (REQ_HEADER_DESC), the buffer descriptor (REQ_BUFFER_DESC) and the
+	 * footer (REQ_FOOTER_DESC) descriptor.
+	 */
+	fibril_mutex_lock(&virtio_blk->free_lock);
+	uint16_t descno = virtio_alloc_desc(vdev, RQ_QUEUE,
+	    &virtio_blk->rq_free_head);
+	while (descno == (uint16_t) -1U) {
+		fibril_condvar_wait(&virtio_blk->free_cv,
+		    &virtio_blk->free_lock);
+		descno = virtio_alloc_desc(vdev, RQ_QUEUE,
+		    &virtio_blk->rq_free_head);
+	}
+	fibril_mutex_unlock(&virtio_blk->free_lock);
+
+	assert(descno < RQ_BUFFERS);
+
+	/* Setup the request header */
+	virtio_blk_req_header_t *req_header =
+	    (virtio_blk_req_header_t *) virtio_blk->rq_header[descno];
+	memset(req_header, 0, sizeof(virtio_blk_req_header_t));
+	pio_write_le32(&req_header->type,
+	    read ? VIRTIO_BLK_T_IN : VIRTIO_BLK_T_OUT);
+	pio_write_le64(&req_header->sector, ba);
+
+	/* Copy write data to the request. */
+	if (!read)
+		memcpy(virtio_blk->rq_buf[descno], buf, VIRTIO_BLK_BLOCK_SIZE);
+
+	fibril_mutex_lock(&virtio_blk->completion_lock[descno]);
+
+	/*
+	 * Set the descriptors, chain them in the virtqueue and notify the
+	 * device.
+	 */
+	virtio_virtq_desc_set(vdev, RQ_QUEUE, REQ_HEADER_DESC(descno),
+	    virtio_blk->rq_header_p[descno], sizeof(virtio_blk_req_header_t),
+	    VIRTQ_DESC_F_NEXT, REQ_BUFFER_DESC(descno));
+	virtio_virtq_desc_set(vdev, RQ_QUEUE, REQ_BUFFER_DESC(descno),
+	    virtio_blk->rq_buf_p[descno], VIRTIO_BLK_BLOCK_SIZE,
+	    VIRTQ_DESC_F_NEXT | (read ? VIRTQ_DESC_F_WRITE : 0),
+	    REQ_FOOTER_DESC(descno));
+	virtio_virtq_desc_set(vdev, RQ_QUEUE, REQ_FOOTER_DESC(descno),
+	    virtio_blk->rq_footer_p[descno], sizeof(virtio_blk_req_footer_t),
+	    VIRTQ_DESC_F_WRITE, 0);
+	virtio_virtq_produce_available(vdev, RQ_QUEUE, descno);
+
+	/*
+	 * Wait for the completion of the request.
+	 */
+	fibril_condvar_wait(&virtio_blk->completion_cv[descno],
+	    &virtio_blk->completion_lock[descno]);
+	fibril_mutex_unlock(&virtio_blk->completion_lock[descno]);
+
+	errno_t rc;
+	virtio_blk_req_footer_t *footer =
+	    (virtio_blk_req_footer_t *) virtio_blk->rq_footer[descno];
+	switch (footer->status) {
+	case VIRTIO_BLK_S_OK:
+		rc = EOK;
+		break;
+	case VIRTIO_BLK_S_IOERR:
+		rc = EIO;
+		break;
+	case VIRTIO_BLK_S_UNSUPP:
+		rc = ENOTSUP;
+		break;
+	default:
+		ddf_msg(LVL_DEBUG, "device returned unknown status=%d\n",
+		    (int) footer->status);
+		rc = EIO;
+		break;
+	}
+
+	/* Copy read data from the request */
+	if (rc == EOK && read)
+		memcpy(buf, virtio_blk->rq_buf[descno], VIRTIO_BLK_BLOCK_SIZE);
+
+	/* Free the descriptor and buffer */
+	fibril_mutex_lock(&virtio_blk->free_lock);
+	virtio_free_desc(vdev, RQ_QUEUE, &virtio_blk->rq_free_head, descno);
+	fibril_condvar_signal(&virtio_blk->free_cv);
+	fibril_mutex_unlock(&virtio_blk->free_lock);
+
+	return rc;
+}
+
+static errno_t virtio_blk_bd_rw_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
+    void *buf, size_t size, bool read)
+{
+	virtio_blk_t *virtio_blk = (virtio_blk_t *) bd->srvs->sarg;
+	aoff64_t i;
+	errno_t rc;
+
+	if (size != cnt * VIRTIO_BLK_BLOCK_SIZE)
+		return EINVAL;
+
+	for (i = 0; i < cnt; i++) {
+		rc = virtio_blk_rw_block(virtio_blk, read, ba + i,
+		    buf + i * VIRTIO_BLK_BLOCK_SIZE);
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
+}
+
+static errno_t virtio_blk_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
+    void *buf, size_t size)
+{
+	return virtio_blk_bd_rw_blocks(bd, ba, cnt, buf, size, true);
+}
+
+static errno_t virtio_blk_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
+    const void *buf, size_t size)
+{
+	return virtio_blk_bd_rw_blocks(bd, ba, cnt, (void *) buf, size, false);
+}
+
+static errno_t virtio_blk_bd_get_block_size(bd_srv_t *bd, size_t *size)
+{
+	*size = VIRTIO_BLK_BLOCK_SIZE;
+	return EOK;
+}
+
+static errno_t virtio_blk_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *nb)
+{
+	virtio_blk_t *virtio_blk = (virtio_blk_t *) bd->srvs->sarg;
+	virtio_blk_cfg_t *blkcfg = virtio_blk->virtio_dev.device_cfg;
+	*nb = pio_read_le64(&blkcfg->capacity);
+	return EOK;
+}
+
+bd_ops_t virtio_blk_bd_ops = {
+	.open = virtio_blk_bd_open,
+	.close = virtio_blk_bd_close,
+	.read_blocks = virtio_blk_bd_read_blocks,
+	.write_blocks = virtio_blk_bd_write_blocks,
+	.get_block_size = virtio_blk_bd_get_block_size,
+	.get_num_blocks = virtio_blk_bd_get_num_blocks,
+};
+
+static errno_t virtio_blk_initialize(ddf_dev_t *dev)
+{
+	virtio_blk_t *virtio_blk = ddf_dev_data_alloc(dev,
+	    sizeof(virtio_blk_t));
+	if (!virtio_blk)
+		return ENOMEM;
+
+	fibril_mutex_initialize(&virtio_blk->free_lock);
+	fibril_condvar_initialize(&virtio_blk->free_cv);
+
+	for (unsigned i = 0; i < RQ_BUFFERS; i++) {
+		fibril_mutex_initialize(&virtio_blk->completion_lock[i]);
+		fibril_condvar_initialize(&virtio_blk->completion_cv[i]);
+	}
+
+	bd_srvs_init(&virtio_blk->bds);
+	virtio_blk->bds.ops = &virtio_blk_bd_ops;
+	virtio_blk->bds.sarg = virtio_blk;
+
+	errno_t rc = virtio_pci_dev_initialize(dev, &virtio_blk->virtio_dev);
+	if (rc != EOK)
+		return rc;
+
+	virtio_dev_t *vdev = &virtio_blk->virtio_dev;
+	virtio_pci_common_cfg_t *cfg = virtio_blk->virtio_dev.common_cfg;
+
+	/*
+	 * Register IRQ
+	 */
+	rc = virtio_blk_register_interrupt(dev);
+	if (rc != EOK)
+		goto fail;
+
+	/* Reset the device and negotiate the feature bits */
+	rc = virtio_device_setup_start(vdev, 0);
+	if (rc != EOK)
+		goto fail;
+
+	/* Perform device-specific setup */
+
+	/*
+	 * Discover and configure the virtqueue
+	 */
+	uint16_t num_queues = pio_read_le16(&cfg->num_queues);
+	if (num_queues != VIRTIO_BLK_NUM_QUEUES) {
+		ddf_msg(LVL_NOTE, "Unsupported number of virtqueues: %u",
+		    num_queues);
+		rc = ELIMIT;
+		goto fail;
+	}
+
+	vdev->queues = calloc(sizeof(virtq_t), num_queues);
+	if (!vdev->queues) {
+		rc = ENOMEM;
+		goto fail;
+	}
+
+	/* For each in/out request we need 3 descriptors */
+	rc = virtio_virtq_setup(vdev, RQ_QUEUE, 3 * RQ_BUFFERS);
+	if (rc != EOK)
+		goto fail;
+
+	/*
+	 * Setup DMA buffers
+	 */
+	rc = virtio_setup_dma_bufs(RQ_BUFFERS, sizeof(virtio_blk_req_header_t),
+	    true, virtio_blk->rq_header, virtio_blk->rq_header_p);
+	if (rc != EOK)
+		goto fail;
+	rc = virtio_setup_dma_bufs(RQ_BUFFERS, VIRTIO_BLK_BLOCK_SIZE,
+	    true, virtio_blk->rq_buf, virtio_blk->rq_buf_p);
+	if (rc != EOK)
+		goto fail;
+	rc = virtio_setup_dma_bufs(RQ_BUFFERS, sizeof(virtio_blk_req_footer_t),
+	    false, virtio_blk->rq_footer, virtio_blk->rq_footer_p);
+	if (rc != EOK)
+		goto fail;
+
+	/*
+	 * Put all request descriptors on a free list. Because of the
+	 * correspondence between the request, buffer and footer descriptors,
+	 * we only need to manage allocations for one set: the request header
+	 * descriptors.
+	 */
+	virtio_create_desc_free_list(vdev, RQ_QUEUE, RQ_BUFFERS,
+	    &virtio_blk->rq_free_head);
+
+	/*
+	 * Enable IRQ
+	 */
+	rc = hw_res_enable_interrupt(ddf_dev_parent_sess_get(dev),
+	    virtio_blk->irq);
+	if (rc != EOK) {
+		ddf_msg(LVL_NOTE, "Failed to enable interrupt");
+		goto fail;
+	}
+
+	ddf_msg(LVL_NOTE, "Registered IRQ %d", virtio_blk->irq);
+
+	/* Go live */
+	virtio_device_setup_finalize(vdev);
+
+	return EOK;
+
+fail:
+	virtio_teardown_dma_bufs(virtio_blk->rq_header);
+	virtio_teardown_dma_bufs(virtio_blk->rq_buf);
+	virtio_teardown_dma_bufs(virtio_blk->rq_footer);
+
+	virtio_device_setup_fail(vdev);
+	virtio_pci_dev_cleanup(vdev);
+	return rc;
+}
+
+static void virtio_blk_uninitialize(ddf_dev_t *dev)
+{
+	virtio_blk_t *virtio_blk = (virtio_blk_t *) ddf_dev_data_get(dev);
+
+	virtio_teardown_dma_bufs(virtio_blk->rq_header);
+	virtio_teardown_dma_bufs(virtio_blk->rq_buf);
+	virtio_teardown_dma_bufs(virtio_blk->rq_footer);
+
+	virtio_device_setup_fail(&virtio_blk->virtio_dev);
+	virtio_pci_dev_cleanup(&virtio_blk->virtio_dev);
+}
+
+static void virtio_blk_bd_connection(ipc_call_t *icall, void *arg)
+{
+	virtio_blk_t *virtio_blk;
+	ddf_fun_t *fun = (ddf_fun_t *) arg;
+
+	virtio_blk = (virtio_blk_t *) ddf_dev_data_get(ddf_fun_get_dev(fun));
+	bd_conn(icall, &virtio_blk->bds);
+}
+
+static errno_t virtio_blk_dev_add(ddf_dev_t *dev)
+{
+	ddf_msg(LVL_NOTE, "%s %s (handle = %zu)", __func__,
+	    ddf_dev_get_name(dev), ddf_dev_get_handle(dev));
+
+	errno_t rc = virtio_blk_initialize(dev);
+	if (rc != EOK)
+		return rc;
+
+	ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "port0");
+	if (fun == NULL) {
+		rc = ENOMEM;
+		goto uninitialize;
+	}
+
+	ddf_fun_set_conn_handler(fun, virtio_blk_bd_connection);
+
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding device function");
+		goto destroy;
+	}
+
+	rc = ddf_fun_add_to_category(fun, "disk");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function to category");
+		goto unbind;
+	}
+
+	ddf_msg(LVL_NOTE, "The %s device has been successfully initialized.",
+	    ddf_dev_get_name(dev));
+
+	return EOK;
+
+unbind:
+	ddf_fun_unbind(fun);
+destroy:
+	ddf_fun_destroy(fun);
+uninitialize:
+	virtio_blk_uninitialize(dev);
+	return rc;
+}
+
+int main(void)
+{
+	printf("%s: HelenOS virtio-blk driver\n", NAME);
+
+	(void) ddf_log_init(NAME);
+	return ddf_driver_main(&virtio_blk_driver);
+}
Index: uspace/drv/block/virtio-blk/virtio-blk.h
===================================================================
--- uspace/drv/block/virtio-blk/virtio-blk.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/block/virtio-blk/virtio-blk.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2019 Jakub Jermar
+ * 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.
+ */
+
+#ifndef _VIRTIO_BLK_H_
+#define _VIRTIO_BLK_H_
+
+#include <virtio-pci.h>
+#include <bd_srv.h>
+#include <abi/cap.h>
+
+#include <fibril_synch.h>
+
+#define VIRTIO_BLK_BLOCK_SIZE	512
+
+/* Operation types. */
+#define VIRTIO_BLK_T_IN		0
+#define VIRTIO_BLK_T_OUT	1
+
+/* Status codes returned by the device. */
+#define VIRTIO_BLK_S_OK		0
+#define VIRTIO_BLK_S_IOERR	1
+#define VIRTIO_BLK_S_UNSUPP	2
+
+#define RQ_BUFFERS	32
+
+/** Device is read-only. */
+#define VIRTIO_BLK_F_RO		(1U << 5)
+
+typedef struct {
+	uint32_t type;
+	uint32_t reserved;
+	uint64_t sector;
+} virtio_blk_req_header_t;
+
+typedef struct {
+	uint8_t status;
+} virtio_blk_req_footer_t;
+
+typedef struct {
+	uint64_t capacity;
+} virtio_blk_cfg_t;
+
+typedef struct {
+	virtio_dev_t virtio_dev;
+
+	void *rq_header[RQ_BUFFERS];
+	uintptr_t rq_header_p[RQ_BUFFERS];
+
+	void *rq_buf[RQ_BUFFERS];
+	uintptr_t rq_buf_p[RQ_BUFFERS];
+
+	void *rq_footer[RQ_BUFFERS];
+	uintptr_t rq_footer_p[RQ_BUFFERS];
+
+	uint16_t rq_free_head;
+
+	int irq;
+	cap_irq_handle_t irq_handle;
+
+	bd_srvs_t bds;
+
+	fibril_mutex_t free_lock;
+	fibril_condvar_t free_cv;
+
+	fibril_mutex_t completion_lock[RQ_BUFFERS];
+	fibril_condvar_t completion_cv[RQ_BUFFERS];
+} virtio_blk_t;
+
+#endif
Index: uspace/drv/block/virtio-blk/virtio-blk.ma
===================================================================
--- uspace/drv/block/virtio-blk/virtio-blk.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/block/virtio-blk/virtio-blk.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,2 @@
+10 pci/ven=1af4&dev=1001
+10 pci/ven=1af4&dev=1042
Index: uspace/drv/bus/adb/cuda_adb/cuda_adb.c
===================================================================
--- uspace/drv/bus/adb/cuda_adb/cuda_adb.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/adb/cuda_adb/cuda_adb.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -208,5 +208,5 @@
 	while (true) {
 		async_get_call(&call);
-		method = IPC_GET_IMETHOD(call);
+		method = ipc_get_imethod(&call);
 
 		if (!method) {
@@ -273,4 +273,7 @@
 
 	fibril_mutex_lock(&cuda->dev_lock);
+
+	/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
+	pio_write_8(&cuda->regs->ifr, SR_INT);
 
 	switch (cuda->xstate) {
@@ -293,7 +296,4 @@
 	}
 
-	/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
-	pio_write_8(&cuda->regs->ifr, SR_INT);
-
 	fibril_mutex_unlock(&cuda->dev_lock);
 
Index: uspace/drv/bus/adb/cuda_adb/cuda_hw.h
===================================================================
--- uspace/drv/bus/adb/cuda_adb/cuda_hw.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/adb/cuda_adb/cuda_hw.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,53 +37,55 @@
 #define CUDA_HW_H_
 
+#include <ddi.h>
+
 #include <stdint.h>
 
 typedef struct cuda_regs {
-	uint8_t b;
+	ioport8_t b;
 	uint8_t pad0[0x1ff];
 
-	uint8_t a;
+	ioport8_t a;
 	uint8_t pad1[0x1ff];
 
-	uint8_t dirb;
+	ioport8_t dirb;
 	uint8_t pad2[0x1ff];
 
-	uint8_t dira;
+	ioport8_t dira;
 	uint8_t pad3[0x1ff];
 
-	uint8_t t1cl;
+	ioport8_t t1cl;
 	uint8_t pad4[0x1ff];
 
-	uint8_t t1ch;
+	ioport8_t t1ch;
 	uint8_t pad5[0x1ff];
 
-	uint8_t t1ll;
+	ioport8_t t1ll;
 	uint8_t pad6[0x1ff];
 
-	uint8_t t1lh;
+	ioport8_t t1lh;
 	uint8_t pad7[0x1ff];
 
-	uint8_t t2cl;
+	ioport8_t t2cl;
 	uint8_t pad8[0x1ff];
 
-	uint8_t t2ch;
+	ioport8_t t2ch;
 	uint8_t pad9[0x1ff];
 
-	uint8_t sr;
+	ioport8_t sr;
 	uint8_t pad10[0x1ff];
 
-	uint8_t acr;
+	ioport8_t acr;
 	uint8_t pad11[0x1ff];
 
-	uint8_t pcr;
+	ioport8_t pcr;
 	uint8_t pad12[0x1ff];
 
-	uint8_t ifr;
+	ioport8_t ifr;
 	uint8_t pad13[0x1ff];
 
-	uint8_t ier;
+	ioport8_t ier;
 	uint8_t pad14[0x1ff];
 
-	uint8_t anh;
+	ioport8_t anh;
 	uint8_t pad15[0x1ff];
 } cuda_regs_t;
Index: uspace/drv/bus/isa/i8237.c
===================================================================
--- uspace/drv/bus/isa/i8237.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/isa/i8237.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -188,5 +188,5 @@
 } dma_controller_t;
 
-static fibril_mutex_t guard = FIBRIL_MUTEX_INITIALIZER(guard);
+static FIBRIL_MUTEX_INITIALIZE(guard);
 
 /** Standard i8237 DMA controller.
Index: uspace/drv/bus/isa/isa.c
===================================================================
--- uspace/drv/bus/isa/isa.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/isa/isa.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -465,5 +465,5 @@
 		resources[count].res.mem_range.address += isa->pio_win.mem.base;
 		resources[count].res.mem_range.size = len;
-		resources[count].res.mem_range.relative = true;
+		resources[count].res.mem_range.relative = false;
 		resources[count].res.mem_range.endianness = LITTLE_ENDIAN;
 
Index: uspace/drv/bus/isa/isa.dev
===================================================================
--- uspace/drv/bus/isa/isa.dev	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/isa/isa.dev	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -17,4 +17,14 @@
 	irq 3
 	io_range 2f8 8
+
+lpt1:
+	match 100 isa/lpt
+	io_range 378 8
+	irq 7
+
+lpt2:
+	match 100 isa/lpt
+	io_range 278 8
+	irq 5
 
 i8042:
Index: uspace/drv/bus/pci/pciintel/Makefile
===================================================================
--- uspace/drv/bus/pci/pciintel/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/pci/pciintel/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,4 +32,5 @@
 
 SOURCES = \
+	ctl.c \
 	pci.c
 
Index: uspace/drv/bus/pci/pciintel/ctl.c
===================================================================
--- uspace/drv/bus/pci/pciintel/ctl.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/bus/pci/pciintel/ctl.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/**
+ * @addtogroup pciintel
+ * @{
+ */
+
+/** @file
+ */
+
+#include <async.h>
+#include <ddf/log.h>
+#include <ipc/pci.h>
+#include <macros.h>
+#include <types/pci.h>
+#include "ctl.h"
+#include "pci.h"
+
+static void pci_ctl_get_devices_srv(pci_bus_t *, ipc_call_t *);
+static void pci_ctl_dev_get_info_srv(pci_bus_t *, ipc_call_t *);
+static errno_t pci_ctl_get_devices(pci_bus_t *, devman_handle_t *, size_t,
+    size_t *);
+static errno_t pci_ctl_dev_get_info(pci_fun_t *, pci_dev_info_t *);
+
+/** Handle control service connection */
+void pci_ctl_connection(ipc_call_t *icall, void *arg)
+{
+	ipc_call_t call;
+	pci_bus_t *bus;
+
+	/*
+	 * Answer the first IPC_M_CONNECT_ME_TO call.
+	 */
+	async_accept_0(icall);
+
+	bus = pci_bus(ddf_fun_get_dev((ddf_fun_t *) arg));
+
+	while (true) {
+		async_get_call(&call);
+
+		if (!ipc_get_imethod(&call))
+			break;
+
+		switch (ipc_get_imethod(&call)) {
+		case PCI_GET_DEVICES:
+			pci_ctl_get_devices_srv(bus, &call);
+			break;
+		case PCI_DEV_GET_INFO:
+			pci_ctl_dev_get_info_srv(bus, &call);
+			break;
+		default:
+			async_answer_0(&call, EINVAL);
+			break;
+		}
+	}
+}
+
+/** Handle request to get list of PCI devices.
+ *
+ * @param bus PCI bus
+ * @param call Async request
+ */
+static void pci_ctl_get_devices_srv(pci_bus_t *bus, ipc_call_t *icall)
+{
+	ipc_call_t call;
+	size_t size;
+	size_t act_size;
+	devman_handle_t *buf;
+	errno_t rc;
+
+	if (!async_data_read_receive(&call, &size)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	if ((size % sizeof(devman_handle_t)) != 0) {
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	buf = malloc(max(1, size));
+	if (buf == NULL) {
+		async_answer_0(&call, ENOMEM);
+		async_answer_0(icall, ENOMEM);
+		return;
+	}
+
+	rc = pci_ctl_get_devices(bus, buf, size, &act_size);
+	if (rc != EOK) {
+		free(buf);
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	errno_t retval = async_data_read_finalize(&call, buf, size);
+
+	free(buf);
+	async_answer_1(icall, retval, act_size);
+}
+
+/** Handle request to get PCI device information.
+ *
+ * @param bus PCI bus
+ * @param call Async request
+ */
+static void pci_ctl_dev_get_info_srv(pci_bus_t *bus, ipc_call_t *icall)
+{
+	devman_handle_t dev_handle;
+	pci_fun_t *fun;
+	pci_dev_info_t info;
+	errno_t rc;
+
+	dev_handle = ipc_get_arg1(icall);
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "pci_dev_get_info_srv(%zu)",
+	    dev_handle);
+	fun = pci_fun_first(bus);
+	while (fun != NULL) {
+		if (ddf_fun_get_handle(fun->fnode) == dev_handle)
+			break;
+
+		fun = pci_fun_next(fun);
+	}
+
+	if (fun == NULL) {
+		log_msg(LOG_DEFAULT, LVL_DEBUG, "pci_dev_get_info_srv: "
+		    "device %zu not found", dev_handle);
+		async_answer_0(icall, ENOENT);
+		return;
+	}
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "pci_dev_get_info_srv: "
+	    "vol_volume_get_info");
+	rc = pci_ctl_dev_get_info(fun, &info);
+	if (rc != EOK) {
+		async_answer_0(icall, EIO);
+		return;
+	}
+
+	ipc_call_t call;
+	size_t size;
+	if (!async_data_read_receive(&call, &size)) {
+		async_answer_0(&call, EREFUSED);
+		async_answer_0(icall, EREFUSED);
+		return;
+	}
+
+	if (size != sizeof(pci_dev_info_t)) {
+		async_answer_0(&call, EINVAL);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	rc = async_data_read_finalize(&call, &info,
+	    min(size, sizeof(info)));
+	if (rc != EOK) {
+		async_answer_0(&call, rc);
+		async_answer_0(icall, rc);
+		return;
+	}
+
+	async_answer_0(icall, EOK);
+}
+
+/** Get list of PCI devices.
+ *
+ * @param bus PCI bus
+ * @param call Async request
+ */
+static errno_t pci_ctl_get_devices(pci_bus_t *bus, devman_handle_t *id_buf,
+    size_t size, size_t *act_size)
+{
+	pci_fun_t *fun;
+	size_t cnt;
+
+	ddf_msg(LVL_NOTE, "pci_ctl_get_devices(%p, %p, %zu, %p)\n",
+	    bus, id_buf, size, act_size);
+
+	fun = pci_fun_first(bus);
+	cnt = 0;
+	while (fun != NULL) {
+		if (sizeof(devman_handle_t) * cnt < size)
+			id_buf[cnt] = ddf_fun_get_handle(fun->fnode);
+		++cnt;
+		fun = pci_fun_next(fun);
+	}
+
+	*act_size = sizeof(devman_handle_t) * cnt;
+	return EOK;
+}
+
+/** Get PCI device information.
+ *
+ * @param fun PCI function
+ * @param info Place to store information
+ *
+ * @return EOK on success or an error code
+ */
+static errno_t pci_ctl_dev_get_info(pci_fun_t *fun, pci_dev_info_t *info)
+{
+	info->dev_handle = ddf_fun_get_handle(fun->fnode);
+	info->bus_num = fun->bus;
+	info->dev_num = fun->dev;
+	info->fn_num = fun->fn;
+	info->vendor_id = fun->vendor_id;
+	info->device_id = fun->device_id;
+	return EOK;
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/pci/pciintel/ctl.h
===================================================================
--- uspace/drv/bus/pci/pciintel/ctl.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/bus/pci/pciintel/ctl.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup pciintel
+ * @{
+ */
+/** @file
+ */
+
+#ifndef CTL_H_
+#define CTL_H_
+
+#include <async.h>
+
+extern void pci_ctl_connection(ipc_call_t *icall, void *arg);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/drv/bus/pci/pciintel/pci.c
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/pci/pciintel/pci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,5 +1,5 @@
 /*
+ * Copyright (c) 2019 Jiri Svoboda
  * Copyright (c) 2010 Lenka Trochtova
- * Copyright (c) 2018 Jiri Svoboda
  * All rights reserved.
  *
@@ -58,5 +58,7 @@
 #include <pci_dev_iface.h>
 
+#include "ctl.h"
 #include "pci.h"
+#include "pci_regs.h"
 
 #define NAME "pciintel"
@@ -73,10 +75,8 @@
 
 /** Obtain PCI bus soft-state from DDF device node */
-#if 0
-static pci_bus_t *pci_bus(ddf_dev_t *dnode)
+pci_bus_t *pci_bus(ddf_dev_t *dnode)
 {
 	return ddf_dev_data_get(dnode);
 }
-#endif
 
 /** Obtain PCI bus soft-state from function soft-state */
@@ -448,4 +448,36 @@
 
 	/* TODO add subsys ids, but those exist only in header type 0 */
+}
+
+/** Get first PCI function.
+ *
+ * @param bus PCI bus
+ * @return First PCI function on @a bus or @c NULL if there is none
+ */
+pci_fun_t *pci_fun_first(pci_bus_t *bus)
+{
+	link_t *link;
+
+	link = list_first(&bus->funs);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, pci_fun_t, lfuns);
+}
+
+/** Get next PCI function.
+ *
+ * @param cur Current function
+ * @return Next PCI function on the same bus or @c NULL if there is none
+ */
+pci_fun_t *pci_fun_next(pci_fun_t *cur)
+{
+	link_t *link;
+
+	link = list_next(&cur->lfuns, &cur->busptr->funs);
+	if (link == NULL)
+		return NULL;
+
+	return list_get_instance(link, pci_fun_t, lfuns);
 }
 
@@ -691,4 +723,6 @@
 				continue;
 			}
+
+			list_append(&fun->lfuns, &bus->funs);
 		}
 	}
@@ -718,4 +752,6 @@
 		goto fail;
 	}
+
+	list_initialize(&bus->funs);
 	fibril_mutex_initialize(&bus->conf_mutex);
 
@@ -802,4 +838,6 @@
 	}
 
+	ddf_fun_set_conn_handler(ctl, pci_ctl_connection);
+
 	/* Enumerate functions. */
 	ddf_msg(LVL_DEBUG, "Enumerating the bus");
@@ -816,4 +854,11 @@
 	}
 
+	rc = ddf_fun_add_to_category(ctl, "pci");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding control function to category "
+		    "'pci'.");
+		goto fail;
+	}
+
 	hw_res_clean_resource_list(&hw_resources);
 
Index: uspace/drv/bus/pci/pciintel/pci.h
===================================================================
--- uspace/drv/bus/pci/pciintel/pci.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/pci/pciintel/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,6 +37,8 @@
 #define PCI_H_
 
+#include <adt/list.h>
+#include <ddi.h>
 #include <ddf/driver.h>
-#include "pci_regs.h"
+#include <fibril_synch.h>
 
 #define PCI_MAX_HW_RES 10
@@ -50,4 +52,6 @@
 	pio_window_t pio_win;
 	fibril_mutex_t conf_mutex;
+	/** List of functions (of pci_fun_t) */
+	list_t funs;
 } pci_bus_t;
 
@@ -55,4 +59,6 @@
 	pci_bus_t *busptr;
 	ddf_fun_t *fnode;
+	/** Link to @c busptr->funs */
+	link_t lfuns;
 
 	int bus;
@@ -71,5 +77,9 @@
 } pci_fun_t;
 
+extern pci_bus_t *pci_bus(ddf_dev_t *);
+
 extern void pci_fun_create_match_ids(pci_fun_t *);
+extern pci_fun_t *pci_fun_first(pci_bus_t *);
+extern pci_fun_t *pci_fun_next(pci_fun_t *);
 
 extern uint8_t pci_conf_read_8(pci_fun_t *, int);
Index: uspace/drv/bus/usb/ehci/hw_struct/iso_transfer_descriptor.h
===================================================================
--- uspace/drv/bus/usb/ehci/hw_struct/iso_transfer_descriptor.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/ehci/hw_struct/iso_transfer_descriptor.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -56,6 +56,6 @@
 #define ITD_TRANSACTION_STATUS_BABBLE_FLAG   (1 << 29)
 #define ITD_TRANSACTION_STATUS_TRANS_ERROR_FLAG  (1 << 28)
-#define ITD_TRANSACTION_LENGHT_MASK    0xfff
-#define ITD_TRANSACTION_LENGHT_SHIFT   16
+#define ITD_TRANSACTION_LENGTH_MASK    0xfff
+#define ITD_TRANSACTION_LENGTH_SHIFT   16
 #define ITD_TRANSACTION_IOC_FLAG       (1 << 15)
 #define ITD_TRANSACTION_PG_MASK        0x3
Index: uspace/drv/bus/usb/ehci/hw_struct/transfer_descriptor.h
===================================================================
--- uspace/drv/bus/usb/ehci/hw_struct/transfer_descriptor.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/ehci/hw_struct/transfer_descriptor.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -88,5 +88,5 @@
 #define TD_BUFFER_POINTER_OFFSET_MASK    0xfff
 
-static_assert(sizeof(td_t) % 32 == 0);
+static_assert(sizeof(td_t) % 32 == 0, "");
 
 static inline bool td_active(const td_t *td)
Index: uspace/drv/bus/usb/ohci/hc.c
===================================================================
--- uspace/drv/bus/usb/ohci/hc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/ohci/hc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -514,5 +514,5 @@
 
 	/* Enable interrupts */
-	if (CAP_HANDLE_VALID(instance->base.irq_handle)) {
+	if (cap_handle_valid(instance->base.irq_handle)) {
 		OHCI_WR(instance->registers->interrupt_enable,
 		    OHCI_USED_INTERRUPTS);
Index: uspace/drv/bus/usb/ohci/hw_struct/hcca.h
===================================================================
--- uspace/drv/bus/usb/ohci/hw_struct/hcca.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/ohci/hw_struct/hcca.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -61,5 +61,5 @@
 } hcca_t;
 
-static_assert(sizeof(hcca_t) == 256);
+static_assert(sizeof(hcca_t) == 256, "");
 
 /** Allocate properly aligned structure.
Index: uspace/drv/bus/usb/ohci/ohci_regs.h
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_regs.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/ohci/ohci_regs.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -153,5 +153,5 @@
  * ohci_regs_t.control
  */
- 
+
 /* Control-bulk service ratio */
 #define C_CBSR_1_1  (0x0)
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -295,5 +295,5 @@
 	pio_write_32(&registers->flbaseadd, pa);
 
-	if (CAP_HANDLE_VALID(instance->base.irq_handle)) {
+	if (cap_handle_valid(instance->base.irq_handle)) {
 		/* Enable all interrupts, but resume interrupt */
 		pio_write_16(&instance->registers->usbintr,
Index: uspace/drv/bus/usb/uhci/uhci_batch.c
===================================================================
--- uspace/drv/bus/usb/uhci/uhci_batch.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/uhci/uhci_batch.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -96,5 +96,5 @@
 int uhci_transfer_batch_prepare(uhci_transfer_batch_t *uhci_batch)
 {
-	static_assert((sizeof(td_t) % 16) == 0);
+	static_assert((sizeof(td_t) % 16) == 0, "");
 
 	usb_transfer_batch_t *usb_batch = &uhci_batch->base;
Index: uspace/drv/bus/usb/vhc/conndev.c
===================================================================
--- uspace/drv/bus/usb/vhc/conndev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/vhc/conndev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -83,5 +83,5 @@
 		return;
 
-	size_t len = IPC_GET_ARG2(data_request_call);
+	size_t len = ipc_get_arg2(&data_request_call);
 	plugged_device_name[len] = 0;
 }
Index: uspace/drv/bus/usb/xhci/hc.c
===================================================================
--- uspace/drv/bus/usb/xhci/hc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/xhci/hc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -494,5 +494,5 @@
 	XHCI_REG_WR(intr0, XHCI_INTR_ERSTBA, erstba_phys);
 
-	if (CAP_HANDLE_VALID(hc->base.irq_handle)) {
+	if (cap_handle_valid(hc->base.irq_handle)) {
 		XHCI_REG_SET(intr0, XHCI_INTR_IE, 1);
 		XHCI_REG_SET(hc->op_regs, XHCI_OP_INTE, 1);
Index: uspace/drv/bus/usb/xhci/hw_struct/common.h
===================================================================
--- uspace/drv/bus/usb/xhci/hw_struct/common.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/xhci/hw_struct/common.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,4 +45,5 @@
 #include <ddi.h>
 #include <errno.h>
+#include <fibril.h>
 
 #define host2xhci(size, val) host2uint##size##_t_le((val))
Index: uspace/drv/bus/usb/xhci/trb_ring.c
===================================================================
--- uspace/drv/bus/usb/xhci/trb_ring.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/bus/usb/xhci/trb_ring.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -53,5 +53,5 @@
 } __attribute__((aligned(PAGE_SIZE)));
 
-static_assert(sizeof(trb_segment_t) == PAGE_SIZE);
+static_assert(sizeof(trb_segment_t) == PAGE_SIZE, "");
 
 /**
Index: uspace/drv/char/i8042/i8042.c
===================================================================
--- uspace/drv/char/i8042/i8042.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/i8042/i8042.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -67,5 +67,6 @@
 
 static void i8042_char_conn(ipc_call_t *, void *);
-static errno_t i8042_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t i8042_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t i8042_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -131,6 +132,6 @@
 	errno_t rc;
 
-	const uint8_t status = IPC_GET_ARG1(*call);
-	const uint8_t data = IPC_GET_ARG2(*call);
+	const uint8_t status = ipc_get_arg1(call);
+	const uint8_t data = ipc_get_arg2(call);
 
 	i8042_port_t *port = (status & i8042_AUX_DATA) ?
@@ -385,5 +386,5 @@
  */
 static errno_t i8042_read(chardev_srv_t *srv, void *dest, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg;
@@ -394,5 +395,6 @@
 	fibril_mutex_lock(&port->buf_lock);
 
-	while (circ_buf_nused(&port->cbuf) == 0)
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    circ_buf_nused(&port->cbuf) == 0)
 		fibril_condvar_wait(&port->buf_cv, &port->buf_lock);
 
Index: uspace/drv/char/msim-con/msim-con.c
===================================================================
--- uspace/drv/char/msim-con/msim-con.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/msim-con/msim-con.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,5 +43,6 @@
 static void msim_con_connection(ipc_call_t *, void *);
 
-static errno_t msim_con_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t msim_con_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t msim_con_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -70,5 +71,5 @@
 	fibril_mutex_lock(&con->buf_lock);
 
-	c = IPC_GET_ARG2(*call);
+	c = ipc_get_arg2(call);
 	rc = circ_buf_push(&con->cbuf, &c);
 	if (rc != EOK)
@@ -85,4 +86,5 @@
 	irq_cmd_t *msim_cmds = NULL;
 	errno_t rc;
+	bool bound = false;
 
 	circ_buf_init(&con->cbuf, con->buf, msim_con_buf_size, 1);
@@ -143,10 +145,19 @@
 	}
 
-	ddf_fun_add_to_category(fun, "console");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "console");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding function 'a' to category "
+		    "'console'.");
+		goto error;
+	}
 
 	return EOK;
 error:
-	if (CAP_HANDLE_VALID(con->irq_handle))
+	if (cap_handle_valid(con->irq_handle))
 		async_irq_unsubscribe(con->irq_handle);
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
@@ -175,5 +186,5 @@
 /** Read from msim console device */
 static errno_t msim_con_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	msim_con_t *con = (msim_con_t *) srv->srvs->sarg;
@@ -184,5 +195,6 @@
 	fibril_mutex_lock(&con->buf_lock);
 
-	while (circ_buf_nused(&con->cbuf) == 0)
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    circ_buf_nused(&con->cbuf) == 0)
 		fibril_condvar_wait(&con->buf_cv, &con->buf_lock);
 
Index: uspace/drv/char/ns8250/ns8250.c
===================================================================
--- uspace/drv/char/ns8250/ns8250.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/ns8250/ns8250.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -246,8 +246,11 @@
  * @param count		The number of bytes to be read.
  * @param nread		Place to store number of bytes actually read
+ * @param flags		@c chardev_f_nonblock not to block waiting for data
+ *			even if no data is available
  *
  * @return		EOK on success or non-zero error code
  */
-static errno_t ns8250_read(chardev_srv_t *srv, void *buf, size_t count, size_t *nread)
+static errno_t ns8250_read(chardev_srv_t *srv, void *buf, size_t count, size_t *nread,
+    chardev_flags_t flags)
 {
 	ns8250_t *ns = srv_ns8250(srv);
@@ -261,5 +264,6 @@
 
 	fibril_mutex_lock(&ns->mutex);
-	while (buf_is_empty(&ns->input_buffer))
+	while ((flags & chardev_f_none) == 0 &&
+	    buf_is_empty(&ns->input_buffer))
 		fibril_condvar_wait(&ns->input_buffer_available, &ns->mutex);
 	while (!buf_is_empty(&ns->input_buffer) && pos < count) {
@@ -829,4 +833,5 @@
 	bool need_cleanup = false;
 	bool need_unreg_intr_handler = false;
+	bool bound = false;
 	errno_t rc;
 
@@ -909,7 +914,12 @@
 	}
 
+	bound = true;
 	ns->fun = fun;
 
-	ddf_fun_add_to_category(fun, "serial");
+	rc = ddf_fun_add_to_category(fun, "serial");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding function to category 'serial'.");
+		goto fail;
+	}
 
 	ddf_msg(LVL_NOTE, "Device %s successfully initialized.",
@@ -918,4 +928,6 @@
 	return EOK;
 fail:
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
@@ -1068,5 +1080,5 @@
 {
 	ns8250_t *ns8250 = srv_ns8250(srv);
-	sysarg_t method = IPC_GET_IMETHOD(*call);
+	sysarg_t method = ipc_get_imethod(call);
 	errno_t ret;
 	unsigned int baud_rate, parity, word_length, stop_bits;
@@ -1081,8 +1093,8 @@
 
 	case SERIAL_SET_COM_PROPS:
-		baud_rate = IPC_GET_ARG1(*call);
-		parity = IPC_GET_ARG2(*call);
-		word_length = IPC_GET_ARG3(*call);
-		stop_bits = IPC_GET_ARG4(*call);
+		baud_rate = ipc_get_arg1(call);
+		parity = ipc_get_arg2(call);
+		word_length = ipc_get_arg3(call);
+		stop_bits = ipc_get_arg4(call);
 		ret = ns8250_set_props(ns8250->dev, baud_rate, parity, word_length,
 		    stop_bits);
Index: uspace/drv/char/pc-lpt/Makefile
===================================================================
--- uspace/drv/char/pc-lpt/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2018 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = drv
+BINARY = pc-lpt
+
+SOURCES = \
+	main.c \
+	pc-lpt.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/char/pc-lpt/doc/doxygroups.h
===================================================================
--- uspace/drv/char/pc-lpt/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,4 @@
+/** @addtogroup uspace_drv_pc_lpt pc-lpt
+ * @brief PC parallel port driver
+ * @ingroup drvs
+ */
Index: uspace/drv/char/pc-lpt/main.c
===================================================================
--- uspace/drv/char/pc-lpt/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/** @addtogroup uspace_drv_pc_lpt
+ * @{
+ */
+/** @file PC parallel port driver
+ */
+
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <device/hw_res_parsed.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "pc-lpt.h"
+
+#define NAME  "pc-lpt"
+
+static errno_t pc_lpt_dev_add(ddf_dev_t *dev);
+static errno_t pc_lpt_dev_remove(ddf_dev_t *dev);
+static errno_t pc_lpt_dev_gone(ddf_dev_t *dev);
+static errno_t pc_lpt_fun_online(ddf_fun_t *fun);
+static errno_t pc_lpt_fun_offline(ddf_fun_t *fun);
+
+static driver_ops_t driver_ops = {
+	.dev_add = pc_lpt_dev_add,
+	.dev_remove = pc_lpt_dev_remove,
+	.dev_gone = pc_lpt_dev_gone,
+	.fun_online = pc_lpt_fun_online,
+	.fun_offline = pc_lpt_fun_offline
+};
+
+static driver_t pc_lpt_driver = {
+	.name = NAME,
+	.driver_ops = &driver_ops
+};
+
+static errno_t pc_lpt_get_res(ddf_dev_t *dev, pc_lpt_res_t *res)
+{
+	async_sess_t *parent_sess;
+	hw_res_list_parsed_t hw_res;
+	errno_t rc;
+
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_init(&hw_res);
+	rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (hw_res.io_ranges.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->base = RNGABS(hw_res.io_ranges.ranges[0]);
+
+	if (hw_res.irqs.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->irq = hw_res.irqs.irqs[0];
+
+	return EOK;
+error:
+	hw_res_list_parsed_clean(&hw_res);
+	return rc;
+}
+
+static errno_t pc_lpt_dev_add(ddf_dev_t *dev)
+{
+	pc_lpt_t *pc_lpt;
+	pc_lpt_res_t res;
+	errno_t rc;
+
+	ddf_msg(LVL_DEBUG, "pc_lpt_dev_add(%p)", dev);
+
+	pc_lpt = ddf_dev_data_alloc(dev, sizeof(pc_lpt_t));
+	if (pc_lpt == NULL) {
+		ddf_msg(LVL_ERROR, "Failed allocating soft state.");
+		return ENOMEM;
+	}
+
+	pc_lpt->dev = dev;
+
+	rc = pc_lpt_get_res(dev, &res);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed getting hardware resource list.");
+		return EIO;
+	}
+
+	return pc_lpt_add(pc_lpt, &res);
+}
+
+static errno_t pc_lpt_dev_remove(ddf_dev_t *dev)
+{
+	pc_lpt_t *pc_lpt = (pc_lpt_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "pc_lpt_dev_remove(%p)", dev);
+
+	return pc_lpt_remove(pc_lpt);
+}
+
+static errno_t pc_lpt_dev_gone(ddf_dev_t *dev)
+{
+	pc_lpt_t *pc_lpt = (pc_lpt_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "pc_lpt_dev_gone(%p)", dev);
+
+	return pc_lpt_gone(pc_lpt);
+}
+
+static errno_t pc_lpt_fun_online(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "pc_lpt_fun_online()");
+	return ddf_fun_online(fun);
+}
+
+static errno_t pc_lpt_fun_offline(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "pc_lpt_fun_offline()");
+	return ddf_fun_offline(fun);
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": PC parallel port driver\n");
+	ddf_log_init(NAME);
+	return ddf_driver_main(&pc_lpt_driver);
+}
+
+/** @}
+ */
Index: uspace/drv/char/pc-lpt/pc-lpt.c
===================================================================
--- uspace/drv/char/pc-lpt/pc-lpt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/pc-lpt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/** @file
+ * @brief PC parallel port driver.
+ */
+
+#include <async.h>
+#include <bitops.h>
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <ddi.h>
+#include <errno.h>
+#include <fibril_synch.h>
+#include <io/chardev_srv.h>
+
+#include "pc-lpt.h"
+#include "pc-lpt_hw.h"
+
+static void pc_lpt_connection(ipc_call_t *, void *);
+
+static errno_t pc_lpt_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
+static errno_t pc_lpt_write(chardev_srv_t *, const void *, size_t, size_t *);
+
+static chardev_ops_t pc_lpt_chardev_ops = {
+	.read = pc_lpt_read,
+	.write = pc_lpt_write
+};
+
+static irq_cmd_t pc_lpt_cmds_proto[] = {
+	{
+		.cmd = CMD_DECLINE
+	}
+};
+
+/** PC LPT IRQ handler.
+ *
+ * Note that while the standard PC parallel port supports IRQ, it seems
+ * drivers tend to avoid using them (for a reason?) These IRQs tend
+ * to be used by other HW as well (Sound Blaster) so caution is in order.
+ * Also not sure, if/how the IRQ needs to be cleared.
+ *
+ * Currently we don't enable IRQ and don't handle it in any way.
+ */
+static void pc_lpt_irq_handler(ipc_call_t *call, void *arg)
+{
+	pc_lpt_t *lpt = (pc_lpt_t *) arg;
+
+	(void) lpt;
+}
+
+/** Add pc-lpt device. */
+errno_t pc_lpt_add(pc_lpt_t *lpt, pc_lpt_res_t *res)
+{
+	ddf_fun_t *fun = NULL;
+	bool bound = false;
+	irq_cmd_t *pc_lpt_cmds = NULL;
+	uint8_t control;
+	uint8_t r;
+	errno_t rc;
+
+	lpt->irq_handle = CAP_NIL;
+	fibril_mutex_initialize(&lpt->hw_lock);
+
+	pc_lpt_cmds = malloc(sizeof(pc_lpt_cmds_proto));
+	if (pc_lpt_cmds == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	lpt->res = *res;
+
+	fun = ddf_fun_create(lpt->dev, fun_exposed, "a");
+	if (fun == NULL) {
+		ddf_msg(LVL_ERROR, "Error creating function 'a'.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = pio_enable((void *)res->base, sizeof(pc_lpt_regs_t),
+	    (void **) &lpt->regs);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error enabling I/O");
+		goto error;
+	}
+
+	ddf_fun_set_conn_handler(fun, pc_lpt_connection);
+
+	lpt->irq_range[0].base = res->base;
+	lpt->irq_range[0].size = 1;
+
+	memcpy(pc_lpt_cmds, pc_lpt_cmds_proto, sizeof(pc_lpt_cmds_proto));
+	pc_lpt_cmds[0].addr = (void *) res->base;
+
+	lpt->irq_code.rangecount = 1;
+	lpt->irq_code.ranges = lpt->irq_range;
+	lpt->irq_code.cmdcount = sizeof(pc_lpt_cmds_proto) / sizeof(irq_cmd_t);
+	lpt->irq_code.cmds = pc_lpt_cmds;
+
+	rc = async_irq_subscribe(res->irq, pc_lpt_irq_handler, lpt,
+	    &lpt->irq_code, &lpt->irq_handle);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error registering IRQ code.");
+		goto error;
+	}
+
+	control = BIT_V(uint8_t, ctl_select) | BIT_V(uint8_t, ctl_ninit);
+	pio_write_8(&lpt->regs->control, control);
+	r = pio_read_8(&lpt->regs->control);
+	if ((r & 0xf) != control) {
+		/* Device not present */
+		rc = EIO;
+		goto error;
+	}
+
+	control |= BIT_V(uint8_t, ctl_autofd);
+	pio_write_8(&lpt->regs->control, control);
+	r = pio_read_8(&lpt->regs->control);
+	if ((r & 0xf) != control) {
+		/* Device not present */
+		rc = EIO;
+		goto error;
+	}
+
+	control &= ~BIT_V(uint8_t, ctl_autofd);
+	pio_write_8(&lpt->regs->control, control);
+
+	chardev_srvs_init(&lpt->cds);
+	lpt->cds.ops = &pc_lpt_chardev_ops;
+	lpt->cds.sarg = lpt;
+
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error binding function 'a'.");
+		goto error;
+	}
+
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "printer-port");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding function 'a' to category "
+		    "'printer-port'.");
+		goto error;
+	}
+
+	return EOK;
+error:
+	if (cap_handle_valid(lpt->irq_handle))
+		async_irq_unsubscribe(lpt->irq_handle);
+	if (bound)
+		ddf_fun_unbind(fun);
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	free(pc_lpt_cmds);
+
+	return rc;
+}
+
+/** Remove pc-lpt device */
+errno_t pc_lpt_remove(pc_lpt_t *lpt)
+{
+	return ENOTSUP;
+}
+
+/** Pc-lpt device gone */
+errno_t pc_lpt_gone(pc_lpt_t *lpt)
+{
+	return ENOTSUP;
+}
+
+/** Write a single byte to the parallel port.
+ *
+ * @param lpt Parallel port (locked)
+ * @param ch Byte
+ */
+static void pc_lpt_putchar(pc_lpt_t *lpt, uint8_t ch)
+{
+	uint8_t status;
+	uint8_t control;
+
+	assert(fibril_mutex_is_locked(&lpt->hw_lock));
+
+	/* Write data */
+	pio_write_8(&lpt->regs->data, ch);
+
+	/* Wait for S7/nbusy to become 1 */
+	do {
+		status = pio_read_8(&lpt->regs->status);
+		// FIXME Need to time out with an error after a while
+	} while ((status & BIT_V(uint8_t, sts_nbusy)) == 0);
+
+	control = pio_read_8(&lpt->regs->control);
+	pio_write_8(&lpt->regs->control, control | BIT_V(uint8_t, ctl_strobe));
+	fibril_usleep(5);
+	pio_write_8(&lpt->regs->control, control & ~BIT_V(uint8_t, ctl_strobe));
+}
+
+/** Read from pc-lpt device */
+static errno_t pc_lpt_read(chardev_srv_t *srv, void *buf, size_t size,
+    size_t *nread, chardev_flags_t flags)
+{
+	pc_lpt_t *lpt = (pc_lpt_t *) srv->srvs->sarg;
+	(void) lpt;
+	return ENOTSUP;
+}
+
+/** Write to pc-lpt device */
+static errno_t pc_lpt_write(chardev_srv_t *srv, const void *data, size_t size,
+    size_t *nwr)
+{
+	pc_lpt_t *lpt = (pc_lpt_t *) srv->srvs->sarg;
+	size_t i;
+	uint8_t *dp = (uint8_t *) data;
+
+	fibril_mutex_lock(&lpt->hw_lock);
+
+	for (i = 0; i < size; i++)
+		pc_lpt_putchar(lpt, dp[i]);
+
+	fibril_mutex_unlock(&lpt->hw_lock);
+
+	*nwr = size;
+	return EOK;
+}
+
+/** Character device connection handler. */
+static void pc_lpt_connection(ipc_call_t *icall, void *arg)
+{
+	pc_lpt_t *lpt = (pc_lpt_t *) ddf_dev_data_get(
+	    ddf_fun_get_dev((ddf_fun_t *) arg));
+
+	chardev_conn(icall, &lpt->cds);
+}
+
+/** @}
+ */
Index: uspace/drv/char/pc-lpt/pc-lpt.h
===================================================================
--- uspace/drv/char/pc-lpt/pc-lpt.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/pc-lpt.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/** @addtogroup uspace_drv_pc_lpt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef PC_LPT_H
+#define PC_LPT_H
+
+#include <async.h>
+#include <ddf/driver.h>
+#include <ddi.h>
+#include <fibril_synch.h>
+#include <io/chardev_srv.h>
+#include <stdint.h>
+
+#include "pc-lpt_hw.h"
+
+/** PC parallel port resources */
+typedef struct {
+	uintptr_t base;
+	int irq;
+} pc_lpt_res_t;
+
+/** PC parallel port */
+typedef struct {
+	/** DDF device */
+	ddf_dev_t *dev;
+	/** Character device service structure */
+	chardev_srvs_t cds;
+	/** Hardware resources */
+	pc_lpt_res_t res;
+	/** PIO range */
+	irq_pio_range_t irq_range[1];
+	/** IRQ code */
+	irq_code_t irq_code;
+	/** Hardware access lock */
+	fibril_mutex_t hw_lock;
+	/** Hardware registers */
+	pc_lpt_regs_t *regs;
+	/** IRQ handle */
+	cap_irq_handle_t irq_handle;
+} pc_lpt_t;
+
+extern errno_t pc_lpt_add(pc_lpt_t *, pc_lpt_res_t *);
+extern errno_t pc_lpt_remove(pc_lpt_t *);
+extern errno_t pc_lpt_gone(pc_lpt_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/char/pc-lpt/pc-lpt.ma
===================================================================
--- uspace/drv/char/pc-lpt/pc-lpt.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/pc-lpt.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+10 isa/lpt
Index: uspace/drv/char/pc-lpt/pc-lpt_hw.h
===================================================================
--- uspace/drv/char/pc-lpt/pc-lpt_hw.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pc-lpt/pc-lpt_hw.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/** @addtogroup uspace_drv_pc_lpt
+ * @{
+ */
+/** @file
+ */
+
+#ifndef PC_LPT_HW_H
+#define PC_LPT_HW_H
+
+#include <ddi.h>
+
+/** PC parallel port registers */
+typedef struct {
+	/** Data out register */
+	ioport8_t data;
+	/** Status register */
+	ioport8_t status;
+	/** Control register */
+	ioport8_t control;
+} pc_lpt_regs_t;
+
+/** Printer control register bits */
+typedef enum {
+	/** Strobe */
+	ctl_strobe = 0,
+	/** Auto linefeed */
+	ctl_autofd = 1,
+	/** -Init */
+	ctl_ninit = 2,
+	/** Select */
+	ctl_select = 3,
+	/** IRQ Enable */
+	ctl_irq_enable = 4
+} pc_lpt_ctl_bits_t;
+
+/** Printer status register bits */
+typedef enum {
+	/** -Error */
+	sts_nerror = 3,
+	/** Select */
+	sts_select = 4,
+	/** Init */
+	sts_paper_end = 5,
+	/** -Ack */
+	sts_nack = 6,
+	/** -Busy */
+	sts_nbusy = 7
+} pc_lpt_sts_bits_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/char/pl011/Makefile
===================================================================
--- uspace/drv/char/pl011/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pl011/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2016 Petr Pavlu
+# 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = drv
+BINARY = pl011
+
+SOURCES = \
+	main.c \
+	pl011.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/char/pl011/main.c
===================================================================
--- uspace/drv/char/pl011/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pl011/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup uspace_drv_pl011
+ * @{
+ */
+/** @file ARM PrimeCell PL011 UART driver.
+ */
+
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <device/hw_res_parsed.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "pl011.h"
+
+#define NAME  "pl011"
+
+static errno_t pl011_dev_add(ddf_dev_t *dev);
+static errno_t pl011_dev_remove(ddf_dev_t *dev);
+static errno_t pl011_dev_gone(ddf_dev_t *dev);
+static errno_t pl011_fun_online(ddf_fun_t *fun);
+static errno_t pl011_fun_offline(ddf_fun_t *fun);
+
+static driver_ops_t driver_ops = {
+	.dev_add = pl011_dev_add,
+	.dev_remove = pl011_dev_remove,
+	.dev_gone = pl011_dev_gone,
+	.fun_online = pl011_fun_online,
+	.fun_offline = pl011_fun_offline
+};
+
+static driver_t pl011_driver = {
+	.name = NAME,
+	.driver_ops = &driver_ops
+};
+
+static errno_t pl011_get_res(ddf_dev_t *dev, pl011_res_t *res)
+{
+	async_sess_t *parent_sess;
+	hw_res_list_parsed_t hw_res;
+	errno_t rc;
+
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_init(&hw_res);
+	rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (hw_res.mem_ranges.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->base = RNGABS(hw_res.mem_ranges.ranges[0]);
+
+	if (hw_res.irqs.count != 1) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->irq = hw_res.irqs.irqs[0];
+
+	return EOK;
+error:
+	hw_res_list_parsed_clean(&hw_res);
+	return rc;
+}
+
+static errno_t pl011_dev_add(ddf_dev_t *dev)
+{
+	pl011_t *pl011;
+	pl011_res_t res;
+	errno_t rc;
+
+	ddf_msg(LVL_DEBUG, "pl011_dev_add(%p)", dev);
+
+	pl011 = ddf_dev_data_alloc(dev, sizeof(pl011_t));
+	if (pl011 == NULL) {
+		ddf_msg(LVL_ERROR, "Failed allocating soft state.");
+		return ENOMEM;
+	}
+
+	pl011->dev = dev;
+
+	rc = pl011_get_res(dev, &res);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed getting hardware resource list.");
+		return EIO;
+	}
+
+	return pl011_add(pl011, &res);
+}
+
+static errno_t pl011_dev_remove(ddf_dev_t *dev)
+{
+	pl011_t *pl011 = (pl011_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "pl011_dev_remove(%p)", dev);
+
+	return pl011_remove(pl011);
+}
+
+static errno_t pl011_dev_gone(ddf_dev_t *dev)
+{
+	pl011_t *pl011 = (pl011_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "pl011_dev_gone(%p)", dev);
+
+	return pl011_gone(pl011);
+}
+
+static errno_t pl011_fun_online(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "pl011_fun_online()");
+	return ddf_fun_online(fun);
+}
+
+static errno_t pl011_fun_offline(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "pl011_fun_offline()");
+	return ddf_fun_offline(fun);
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": PL011 serial device driver\n");
+	ddf_log_init(NAME);
+	return ddf_driver_main(&pl011_driver);
+}
+
+/** @}
+ */
Index: uspace/drv/char/pl011/pl011.c
===================================================================
--- uspace/drv/char/pl011/pl011.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pl011/pl011.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ * 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.
+ */
+
+/** @file ARM PrimeCell PL011 UART driver.
+ */
+
+#include <async.h>
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <ddi.h>
+#include <errno.h>
+#include <io/chardev_srv.h>
+#include <macros.h>
+
+#include "pl011.h"
+
+/** PL011 register map. */
+typedef struct {
+	/** UART data register. */
+	ioport32_t data;
+	union {
+		/** Receive status register (same values that are in upper bits
+		 * of data register).
+		 */
+		const ioport32_t status;
+		/** Error clear register (writing anything clears all errors).
+		 */
+		ioport32_t error_clear;
+	};
+	/** Reserved. */
+	PADD32(4);
+	/** Flag register. */
+	const ioport32_t flag;
+	/** Transmit FIFO full. */
+#define PL011_UART_FLAG_TXFF_FLAG  (1 << 5)
+
+	/** Reserved. */
+	PADD32(1);
+	/** IrDA low-power counter register. */
+	ioport32_t irda_low_power;
+	/** Integer baud rate register. */
+	ioport32_t int_baud_divisor;
+	/** Fractional baud rate register. */
+	ioport32_t fract_baud_divisor;
+	/** Line control register. */
+	ioport32_t line_control_high;
+	/** Control register. */
+	ioport32_t control;
+	/** Interrupt FIFO level select register. */
+	ioport32_t interrupt_fifo;
+	/** Interrupt mask set/clear register. */
+	ioport32_t interrupt_mask;
+	/** Raw interrupt status register (pending interrupts before applying
+	 * the mask).
+	 */
+	const ioport32_t raw_interrupt_status;
+	/** Masked interrupt status register (pending interrupts after applying
+	 * the mask).
+	 */
+	const ioport32_t masked_interrupt_status;
+	/** Interrupt clear register (write 1s to clear pending interrupts). */
+	ioport32_t interrupt_clear;
+
+	/** Interrupt indicating a change in the nUARTRI modem status. */
+#define PL011_UART_INTERRUPT_RIM_FLAG   (1 << 0)
+	/** Interrupt indicating a change in the nUARTCTS modem status. */
+#define PL011_UART_INTERRUPT_CTSM_FLAG  (1 << 1)
+	/** Interrupt indicating a change in the nUARTDCD modem status. */
+#define PL011_UART_INTERRUPT_DCDM_FLAG  (1 << 2)
+	/** Interrupt indicating a change in the nUARTDSR modem status. */
+#define PL011_UART_INTERRUPT_DSRM_FLAG  (1 << 3)
+	/** The receive interrupt. */
+#define PL011_UART_INTERRUPT_RX_FLAG    (1 << 4)
+	/** The transmit interrupt. */
+#define PL011_UART_INTERRUPT_TX_FLAG    (1 << 5)
+	/** The receive timeout interrupt.  */
+#define PL011_UART_INTERRUPT_RT_FLAG    (1 << 6)
+	/** Interrupt indicating an overrun error. */
+#define PL011_UART_INTERRUPT_FE_FLAG    (1 << 7)
+	/** Interrupt indicating a break in the reception. */
+#define PL011_UART_INTERRUPT_PE_FLAG    (1 << 8)
+	/** Interrupt indicating a parity error in the received character. */
+#define PL011_UART_INTERRUPT_BE_FLAG    (1 << 9)
+	/** Interrupt indicating a framing error in the received character. */
+#define PL011_UART_INTERRUPT_OE_FLAG    (1 << 10)
+	/** All interrupt mask. */
+#define PL011_UART_INTERRUPT_ALL        0x3ff
+
+	/** DMA control register. */
+	ioport32_t dma_control;
+	/** Reserved. */
+	PADD32(13);
+	/** Reserved for test purposes. */
+	PADD32(4);
+	/** Reserved. */
+	PADD32(976);
+	/** Reserved for future ID expansion. */
+	PADD32(4);
+	/** UARTPeriphID0 register. */
+	const ioport32_t periph_id0;
+	/** UARTPeriphID1 register. */
+	const ioport32_t periph_id1;
+	/** UARTPeriphID2 register. */
+	const ioport32_t periph_id2;
+	/** UARTPeriphID3 register. */
+	const ioport32_t periph_id3;
+	/** UARTPCellID0 register. */
+	const ioport32_t cell_id0;
+	/** UARTPCellID1 register. */
+	const ioport32_t cell_id1;
+	/** UARTPCellID2 register. */
+	const ioport32_t cell_id2;
+	/** UARTPCellID3 register. */
+	const ioport32_t cell_id3;
+} pl011_uart_regs_t;
+
+static void pl011_connection(ipc_call_t *, void *);
+
+static errno_t pl011_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
+static errno_t pl011_write(chardev_srv_t *, const void *, size_t, size_t *);
+
+static chardev_ops_t pl011_chardev_ops = {
+	.read = pl011_read,
+	.write = pl011_write
+};
+
+/** Address range accessed by the PL011 interrupt pseudo-code. */
+static const irq_pio_range_t pl011_ranges_proto[] = {
+	{
+		.base = 0,
+		.size = sizeof(pl011_uart_regs_t)
+	}
+};
+
+/** PL011 interrupt pseudo-code instructions. */
+static const irq_cmd_t pl011_cmds_proto[] = {
+	{
+		/* Read masked_interrupt_status. */
+		.cmd = CMD_PIO_READ_32,
+		.addr = NULL,
+		.dstarg = 1
+	},
+	{
+		.cmd = CMD_AND,
+		.value = PL011_UART_INTERRUPT_RX_FLAG |
+		    PL011_UART_INTERRUPT_RT_FLAG,
+		.srcarg = 1,
+		.dstarg = 3
+	},
+	{
+		.cmd = CMD_PREDICATE,
+		.value = 1,
+		.srcarg = 3
+	},
+	{
+		/* Read data. */
+		.cmd = CMD_PIO_READ_32,
+		.addr = NULL,
+		.dstarg = 2
+	},
+	{
+		.cmd = CMD_ACCEPT
+	}
+};
+
+/** Process an interrupt from a PL011 device. */
+static void pl011_irq_handler(ipc_call_t *call, void *arg)
+{
+	pl011_t *pl011 = (pl011_t *) arg;
+	uint32_t intrs = ipc_get_arg1(call);
+	uint8_t c = ipc_get_arg2(call);
+	errno_t rc;
+
+	if ((intrs & (PL011_UART_INTERRUPT_RX_FLAG |
+	    PL011_UART_INTERRUPT_RT_FLAG)) == 0) {
+		/* TODO */
+		return;
+	}
+
+	fibril_mutex_lock(&pl011->buf_lock);
+
+	rc = circ_buf_push(&pl011->cbuf, &c);
+	if (rc != EOK)
+		ddf_msg(LVL_ERROR, "Buffer overrun");
+
+	fibril_mutex_unlock(&pl011->buf_lock);
+	fibril_condvar_broadcast(&pl011->buf_cv);
+}
+
+/** Add a PL011 device. */
+errno_t pl011_add(pl011_t *pl011, pl011_res_t *res)
+{
+	ddf_fun_t *fun = NULL;
+	irq_pio_range_t *pl011_ranges = NULL;
+	irq_cmd_t *pl011_cmds = NULL;
+	errno_t rc;
+
+	circ_buf_init(&pl011->cbuf, pl011->buf, pl011_buf_size, 1);
+	fibril_mutex_initialize(&pl011->buf_lock);
+	fibril_condvar_initialize(&pl011->buf_cv);
+
+	pl011->irq_handle = CAP_NIL;
+
+	pl011_ranges = malloc(sizeof(pl011_ranges_proto));
+	if (pl011_ranges == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+	pl011_cmds = malloc(sizeof(pl011_cmds_proto));
+	if (pl011_cmds == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	pl011->res = *res;
+
+	fun = ddf_fun_create(pl011->dev, fun_exposed, "a");
+	if (fun == NULL) {
+		ddf_msg(LVL_ERROR, "Error creating function 'a'.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	rc = pio_enable(
+	    (void *) res->base, sizeof(pl011_uart_regs_t), &pl011->regs);
+	if (rc != EOK)
+		goto error;
+
+	ddf_fun_set_conn_handler(fun, pl011_connection);
+
+	memcpy(pl011_ranges, pl011_ranges_proto, sizeof(pl011_ranges_proto));
+	memcpy(pl011_cmds, pl011_cmds_proto, sizeof(pl011_cmds_proto));
+	pl011_ranges[0].base = res->base;
+	pl011_uart_regs_t *regsphys = (pl011_uart_regs_t *) res->base;
+	pl011_cmds[0].addr = (void *) &regsphys->masked_interrupt_status;
+	pl011_cmds[3].addr = (void *) &regsphys->data;
+
+	pl011->irq_code.rangecount =
+	    sizeof(pl011_ranges_proto) / sizeof(irq_pio_range_t);
+	pl011->irq_code.ranges = pl011_ranges;
+	pl011->irq_code.cmdcount = sizeof(pl011_cmds_proto) / sizeof(irq_cmd_t);
+	pl011->irq_code.cmds = pl011_cmds;
+
+	rc = async_irq_subscribe(res->irq, pl011_irq_handler, pl011,
+	    &pl011->irq_code, &pl011->irq_handle);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error registering IRQ code.");
+		goto error;
+	}
+
+	chardev_srvs_init(&pl011->cds);
+	pl011->cds.ops = &pl011_chardev_ops;
+	pl011->cds.sarg = pl011;
+
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error binding function 'a'.");
+		goto error;
+	}
+
+	ddf_fun_add_to_category(fun, "console");
+
+	return EOK;
+error:
+	if (cap_handle_valid(pl011->irq_handle))
+		async_irq_unsubscribe(pl011->irq_handle);
+	if (fun != NULL)
+		ddf_fun_destroy(fun);
+	free(pl011_ranges);
+	free(pl011_cmds);
+
+	return rc;
+}
+
+/** Remove a PL011 device. */
+errno_t pl011_remove(pl011_t *pl011)
+{
+	return ENOTSUP;
+}
+
+/** A PL011 device gone. */
+errno_t pl011_gone(pl011_t *pl011)
+{
+	return ENOTSUP;
+}
+
+/** Send a character to a PL011 device.
+ *
+ * @param c Character to be printed.
+ */
+static void pl011_putchar(pl011_t *pl011, uint8_t ch)
+{
+	pl011_uart_regs_t *regs = (pl011_uart_regs_t *) pl011->regs;
+
+	/* Wait for space to become available in the TX FIFO. */
+	while (pio_read_32(&regs->flag) & PL011_UART_FLAG_TXFF_FLAG)
+		;
+
+	pio_write_32(&regs->data, ch);
+}
+
+/** Read from a PL011 device. */
+static errno_t pl011_read(chardev_srv_t *srv, void *buf, size_t size,
+    size_t *nread, chardev_flags_t flags)
+{
+	pl011_t *pl011 = (pl011_t *) srv->srvs->sarg;
+	size_t p;
+	uint8_t *bp = (uint8_t *) buf;
+	errno_t rc;
+
+	fibril_mutex_lock(&pl011->buf_lock);
+
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    circ_buf_nused(&pl011->cbuf) == 0)
+		fibril_condvar_wait(&pl011->buf_cv, &pl011->buf_lock);
+
+	p = 0;
+	while (p < size) {
+		rc = circ_buf_pop(&pl011->cbuf, &bp[p]);
+		if (rc != EOK)
+			break;
+		++p;
+	}
+
+	fibril_mutex_unlock(&pl011->buf_lock);
+
+	*nread = p;
+	return EOK;
+}
+
+/** Write to a PL011 device. */
+static errno_t pl011_write(chardev_srv_t *srv, const void *data, size_t size,
+    size_t *nwr)
+{
+	pl011_t *pl011 = (pl011_t *) srv->srvs->sarg;
+	size_t i;
+	uint8_t *dp = (uint8_t *) data;
+
+	for (i = 0; i < size; i++)
+		pl011_putchar(pl011, dp[i]);
+
+	*nwr = size;
+	return EOK;
+}
+
+/** Character device connection handler. */
+static void pl011_connection(ipc_call_t *icall, void *arg)
+{
+	pl011_t *pl011 = (pl011_t *) ddf_dev_data_get(
+	    ddf_fun_get_dev((ddf_fun_t *) arg));
+
+	chardev_conn(icall, &pl011->cds);
+}
+
+/** @}
+ */
Index: uspace/drv/char/pl011/pl011.h
===================================================================
--- uspace/drv/char/pl011/pl011.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pl011/pl011.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup uspace_drv_pl011
+ * @{
+ */
+/** @file
+ */
+
+#ifndef PL011_CON_H
+#define PL011_CON_H
+
+#include <adt/circ_buf.h>
+#include <async.h>
+#include <ddf/driver.h>
+#include <ddi.h>
+#include <fibril_synch.h>
+#include <io/chardev_srv.h>
+#include <loc.h>
+#include <stdint.h>
+
+enum {
+	pl011_buf_size = 64
+};
+
+/** PL011 device resources. */
+typedef struct {
+	uintptr_t base;
+	int irq;
+} pl011_res_t;
+
+/** PL011 device. */
+typedef struct {
+	ddf_dev_t *dev;
+	chardev_srvs_t cds;
+	pl011_res_t res;
+	irq_code_t irq_code;
+	circ_buf_t cbuf;
+	uint8_t buf[pl011_buf_size];
+	fibril_mutex_t buf_lock;
+	fibril_condvar_t buf_cv;
+	void *regs;
+	cap_irq_handle_t irq_handle;
+} pl011_t;
+
+extern errno_t pl011_add(pl011_t *, pl011_res_t *);
+extern errno_t pl011_remove(pl011_t *);
+extern errno_t pl011_gone(pl011_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/char/pl011/pl011.ma
===================================================================
--- uspace/drv/char/pl011/pl011.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/char/pl011/pl011.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+10 arm/pl011
Index: uspace/drv/char/pl050/pl050.c
===================================================================
--- uspace/drv/char/pl050/pl050.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/pl050/pl050.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -59,5 +59,6 @@
 static errno_t pl050_fun_offline(ddf_fun_t *);
 static void pl050_char_conn(ipc_call_t *, void *);
-static errno_t pl050_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t pl050_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t pl050_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -156,5 +157,5 @@
 	}
 
-	pl050->buffer[pl050->buf_wp] = IPC_GET_ARG2(*call);
+	pl050->buffer[pl050->buf_wp] = ipc_get_arg2(call);
 	pl050->buf_wp = nidx;
 	fibril_condvar_broadcast(&pl050->buf_cv);
@@ -242,5 +243,5 @@
 
 static errno_t pl050_read(chardev_srv_t *srv, void *buffer, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	pl050_t *pl050 = (pl050_t *)srv->srvs->sarg;
@@ -252,5 +253,6 @@
 	left = size;
 	while (left > 0) {
-		while (left == size && pl050->buf_rp == pl050->buf_wp)
+		while ((flags & chardev_f_nonblock) == 0 &&
+		    left == size && pl050->buf_rp == pl050->buf_wp)
 			fibril_condvar_wait(&pl050->buf_cv, &pl050->buf_lock);
 		if (pl050->buf_rp == pl050->buf_wp)
Index: uspace/drv/char/ski-con/ski-con.c
===================================================================
--- uspace/drv/char/ski-con/ski-con.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/ski-con/ski-con.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -55,5 +55,6 @@
 static void ski_con_connection(ipc_call_t *, void *);
 
-static errno_t ski_con_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t ski_con_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t ski_con_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -112,7 +113,12 @@
 	}
 
-	ddf_fun_add_to_category(fun, "console");
-
 	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "console");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding function 'a' to category "
+		    "'console'.");
+		goto error;
+	}
 
 	fid = fibril_create(ski_con_fibril, con);
@@ -255,5 +261,5 @@
 /** Read from Ski console device */
 static errno_t ski_con_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	ski_con_t *con = (ski_con_t *) srv->srvs->sarg;
@@ -264,5 +270,6 @@
 	fibril_mutex_lock(&con->buf_lock);
 
-	while (circ_buf_nused(&con->cbuf) == 0)
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    circ_buf_nused(&con->cbuf) == 0)
 		fibril_condvar_wait(&con->buf_cv, &con->buf_lock);
 
Index: uspace/drv/char/sun4v-con/sun4v-con.c
===================================================================
--- uspace/drv/char/sun4v-con/sun4v-con.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/char/sun4v-con/sun4v-con.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -46,5 +46,6 @@
 #define POLL_INTERVAL  10000
 
-static errno_t sun4v_con_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t sun4v_con_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t sun4v_con_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -74,4 +75,5 @@
 	ddf_fun_t *fun = NULL;
 	errno_t rc;
+	bool bound = false;
 
 	con->res = *res;
@@ -113,5 +115,12 @@
 	}
 
-	ddf_fun_add_to_category(fun, "console");
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, "console");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding function 'a' to category "
+		    "'console'.");
+		goto error;
+	}
 
 	return EOK;
@@ -123,4 +132,7 @@
 		physmem_unmap((void *) con->output_buffer);
 
+	if (bound)
+		ddf_fun_unbind(fun);
+
 	if (fun != NULL)
 		ddf_fun_destroy(fun);
@@ -143,5 +155,5 @@
 /** Read from Sun4v console device */
 static errno_t sun4v_con_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	sun4v_con_t *con = (sun4v_con_t *) srv->srvs->sarg;
@@ -150,5 +162,6 @@
 	char c;
 
-	while (con->input_buffer->read_ptr == con->input_buffer->write_ptr)
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    con->input_buffer->read_ptr == con->input_buffer->write_ptr)
 		fibril_usleep(POLL_INTERVAL);
 
Index: uspace/drv/fb/amdm37x_dispc/main.c
===================================================================
--- uspace/drv/fb/amdm37x_dispc/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/fb/amdm37x_dispc/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,5 +60,5 @@
 	ddf_fun_t *fun = ddf_fun_create(dev, fun_exposed, "viz");
 	if (!fun) {
-		ddf_log_error("Failed to create visualizer function\n");
+		ddf_log_error("Failed to create visualizer function.");
 		return ENOMEM;
 	}
@@ -66,5 +66,5 @@
 	visualizer_t *vis = ddf_fun_data_alloc(fun, sizeof(visualizer_t));
 	if (!vis) {
-		ddf_log_error("Failed to allocate visualizer structure\n");
+		ddf_log_error("Failed to allocate visualizer structure.");
 		ddf_fun_destroy(fun);
 		return ENOMEM;
@@ -79,27 +79,36 @@
 	    ddf_dev_data_alloc(dev, sizeof(amdm37x_dispc_t));
 	if (!dispc) {
-		ddf_log_error("Failed to allocate dispc structure\n");
+		ddf_log_error("Failed to allocate dispc structure.");
 		ddf_fun_destroy(fun);
 		return ENOMEM;
 	}
 
-	errno_t ret = amdm37x_dispc_init(dispc, vis);
-	if (ret != EOK) {
-		ddf_log_error("Failed to init dispc: %s\n", str_error(ret));
+	errno_t rc = amdm37x_dispc_init(dispc, vis);
+	if (rc != EOK) {
+		ddf_log_error("Failed to init dispc: %s.", str_error(rc));
 		ddf_fun_destroy(fun);
-		return ret;
+		return rc;
 	}
 
 	/* Bind function */
-	ret = ddf_fun_bind(fun);
-	if (ret != EOK) {
-		ddf_log_error("Failed to bind function: %s\n", str_error(ret));
+	rc = ddf_fun_bind(fun);
+	if (rc != EOK) {
+		ddf_log_error("Failed to bind function: %s.", str_error(rc));
 		amdm37x_dispc_fini(dispc);
 		ddf_fun_destroy(fun);
-		return ret;
+		return rc;
 	}
-	ddf_fun_add_to_category(fun, "visualizer");
 
-	ddf_log_note("Added device `%s'\n", ddf_dev_get_name(dev));
+	rc = ddf_fun_add_to_category(fun, "visualizer");
+	if (rc != EOK) {
+		ddf_log_error("Failed to add function: %s to visualizer "
+		    "category.", str_error(rc));
+		amdm37x_dispc_fini(dispc);
+		ddf_fun_unbind(fun);
+		ddf_fun_destroy(fun);
+		return rc;
+	}
+
+	ddf_log_note("Added device `%s'", ddf_dev_get_name(dev));
 	return EOK;
 }
Index: uspace/drv/fb/kfb/port.c
===================================================================
--- uspace/drv/fb/kfb/port.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/fb/kfb/port.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -348,5 +348,12 @@
 
 	vs->reg_svc_handle = ddf_fun_get_handle(fun_vs);
-	ddf_fun_add_to_category(fun_vs, "visualizer");
+	rc = ddf_fun_add_to_category(fun_vs, "visualizer");
+	if (rc != EOK) {
+		list_remove(&pixel_mode.link);
+		ddf_fun_unbind(fun_vs);
+		ddf_fun_destroy(fun_vs);
+		as_area_destroy(kfb.addr);
+		return rc;
+	}
 
 	return EOK;
Index: uspace/drv/hid/adb-kbd/adb-kbd.c
===================================================================
--- uspace/drv/hid/adb-kbd/adb-kbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/adb-kbd/adb-kbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -141,12 +141,12 @@
 		errno_t retval = EOK;
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case ADB_REG_NOTIF:
-			adb_kbd_reg0_data(kbd, IPC_GET_ARG1(call));
+			adb_kbd_reg0_data(kbd, ipc_get_arg1(&call));
 			break;
 		default:
@@ -205,5 +205,5 @@
 	while (true) {
 		async_get_call(&call);
-		method = IPC_GET_IMETHOD(call);
+		method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/drv/hid/adb-mouse/adb-mouse.c
===================================================================
--- uspace/drv/hid/adb-mouse/adb-mouse.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/adb-mouse/adb-mouse.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -99,12 +99,12 @@
 		errno_t retval = EOK;
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* TODO: Handle hangup */
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case ADB_REG_NOTIF:
-			adb_mouse_data(mouse, IPC_GET_ARG1(call));
+			adb_mouse_data(mouse, ipc_get_arg1(&call));
 			break;
 		default:
@@ -215,5 +215,5 @@
 	while (true) {
 		async_get_call(&call);
-		method = IPC_GET_IMETHOD(call);
+		method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/drv/hid/atkbd/atkbd.c
===================================================================
--- uspace/drv/hid/atkbd/atkbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/atkbd/atkbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -211,5 +211,5 @@
 	while (true) {
 		uint8_t code = 0;
-		rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+		rc = chardev_read(kbd->chardev, &code, 1, &nwr, chardev_f_none);
 		if (rc != EOK)
 			return EIO;
@@ -222,9 +222,11 @@
 			map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
 		} else if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -232,5 +234,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -238,5 +241,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -244,5 +248,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -250,5 +255,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -256,5 +262,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -262,5 +269,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -277,5 +285,6 @@
 		if (code == KBD_SCANCODE_KEY_RELEASE) {
 			type = KEY_RELEASE;
-			rc = chardev_read(kbd->chardev, &code, 1, &nwr);
+			rc = chardev_read(kbd->chardev, &code, 1, &nwr,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -301,5 +310,5 @@
 static void default_connection_handler(ddf_fun_t *fun, ipc_call_t *icall)
 {
-	const sysarg_t method = IPC_GET_IMETHOD(*icall);
+	const sysarg_t method = ipc_get_imethod(icall);
 	at_kbd_t *kbd = ddf_dev_data_get(ddf_fun_get_dev(fun));
 	async_sess_t *sess;
@@ -418,5 +427,6 @@
 		return EIO;
 	}
-	rc = chardev_read(kbd->chardev, &code, 1, &bytes);
+	rc = chardev_read(kbd->chardev, &code, 1, &bytes,
+	    chardev_f_none);
 	if (rc != EOK || code != AT_KBD_ACK) {
 		ddf_msg(LVL_ERROR, "Failed to confirm keyboard enable: %hhx.",
Index: uspace/drv/hid/ps2mouse/ps2mouse.c
===================================================================
--- uspace/drv/hid/ps2mouse/ps2mouse.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/ps2mouse/ps2mouse.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -49,4 +49,5 @@
 #define PS2_MOUSE_SET_SAMPLE_RATE   0xf3
 #define PS2_MOUSE_ENABLE_DATA_REPORT   0xf4
+#define PS2_MOUSE_DISABLE_DATA_REPORT   0xf5
 #define PS2_MOUSE_ACK   0xfa
 
@@ -77,5 +78,6 @@
 	uint8_t data = 0; \
 	size_t nread; \
-	const errno_t rc = chardev_read((mouse)->chardev, &data, 1, &nread); \
+	const errno_t rc = chardev_read((mouse)->chardev, &data, 1, &nread, \
+	    chardev_f_none); \
 	if (rc != EOK) { \
 		ddf_msg(LVL_ERROR, "Failed reading byte: %s", str_error_name(rc));\
@@ -164,4 +166,26 @@
 	}
 
+	/* Disable mouse data reporting. */
+	uint8_t report = PS2_MOUSE_ENABLE_DATA_REPORT;
+	size_t nwr;
+	rc = chardev_write(mouse->chardev, &report, 1, &nwr);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed to enable data reporting.");
+		rc = EIO;
+		goto error;
+	}
+
+	/* Drain input buffer */
+	size_t nread;
+	uint8_t b;
+	do {
+		rc = chardev_read(mouse->chardev, &b, 1, &nread, chardev_f_nonblock);
+		if (rc != EOK) {
+			ddf_msg(LVL_ERROR, "Failed to drain input buffer.\n");
+			rc = EIO;
+			goto error;
+		}
+	} while (nread > 0);
+
 	/* Probe IntelliMouse extensions. */
 	errno_t (*polling_f)(void *) = polling_ps2;
@@ -174,6 +198,5 @@
 
 	/* Enable mouse data reporting. */
-	uint8_t report = PS2_MOUSE_ENABLE_DATA_REPORT;
-	size_t nwr;
+	report = PS2_MOUSE_ENABLE_DATA_REPORT;
 	rc = chardev_write(mouse->chardev, &report, 1, &nwr);
 	if (rc != EOK) {
@@ -183,6 +206,5 @@
 	}
 
-	size_t nread;
-	rc = chardev_read(mouse->chardev, &report, 1, &nread);
+	rc = chardev_read(mouse->chardev, &report, 1, &nread, chardev_f_none);
 	if (rc != EOK || report != PS2_MOUSE_ACK) {
 		ddf_msg(LVL_ERROR, "Failed to confirm data reporting: %hhx.",
@@ -232,5 +254,5 @@
 	while (pos < psize) {
 		rc = chardev_read(mouse->chardev, pbuf + pos, psize - pos,
-		    &nread);
+		    &nread, chardev_f_none);
 		if (rc != EOK) {
 			ddf_msg(LVL_WARN, "Error reading packet.");
@@ -407,5 +429,5 @@
 void default_connection_handler(ddf_fun_t *fun, ipc_call_t *icall)
 {
-	const sysarg_t method = IPC_GET_IMETHOD(*icall);
+	const sysarg_t method = ipc_get_imethod(icall);
 	ps2_mouse_t *mouse = ddf_dev_data_get(ddf_fun_get_dev(fun));
 	async_sess_t *sess;
Index: uspace/drv/hid/usbhid/kbd/kbddev.c
===================================================================
--- uspace/drv/hid/usbhid/kbd/kbddev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/usbhid/kbd/kbddev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -159,5 +159,5 @@
 static void default_connection_handler(ddf_fun_t *fun, ipc_call_t *icall)
 {
-	const sysarg_t method = IPC_GET_IMETHOD(*icall);
+	const sysarg_t method = ipc_get_imethod(icall);
 	usb_kbd_t *kbd_dev = ddf_fun_data_get(fun);
 	async_sess_t *sess;
@@ -165,5 +165,5 @@
 	switch (method) {
 	case KBDEV_SET_IND:
-		kbd_dev->mods = IPC_GET_ARG1(*icall);
+		kbd_dev->mods = ipc_get_arg1(icall);
 		usb_kbd_set_led(kbd_dev->hid_dev, kbd_dev);
 		async_answer_0(icall, EOK);
Index: uspace/drv/hid/xtkbd/xtkbd.c
===================================================================
--- uspace/drv/hid/xtkbd/xtkbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/hid/xtkbd/xtkbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -216,5 +216,5 @@
 
 		uint8_t code = 0;
-		rc = chardev_read(kbd->chardev, &code, 1, &nread);
+		rc = chardev_read(kbd->chardev, &code, 1, &nread, chardev_f_none);
 		if (rc != EOK)
 			return EIO;
@@ -229,5 +229,6 @@
 			map_size = sizeof(scanmap_e0) / sizeof(unsigned int);
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -236,5 +237,6 @@
 
 			if (code == 0x2a) {  /* Print Screen */
-				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				rc = chardev_read(kbd->chardev, &code, 1, &nread,
+				    chardev_f_none);
 				if (rc != EOK)
 					return EIO;
@@ -243,5 +245,6 @@
 					continue;
 
-				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				rc = chardev_read(kbd->chardev, &code, 1, &nread,
+				    chardev_f_none);
 				if (rc != EOK)
 					return EIO;
@@ -254,5 +257,6 @@
 
 			if (code == 0x46) {  /* Break */
-				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				rc = chardev_read(kbd->chardev, &code, 1, &nread,
+				    chardev_f_none);
 				if (rc != EOK)
 					return EIO;
@@ -261,5 +265,6 @@
 					continue;
 
-				rc = chardev_read(kbd->chardev, &code, 1, &nread);
+				rc = chardev_read(kbd->chardev, &code, 1, &nread,
+				    chardev_f_none);
 				if (rc != EOK)
 					return EIO;
@@ -274,5 +279,6 @@
 		/* Extended special set */
 		if (code == KBD_SCANCODE_SET_EXTENDED_SPECIAL) {
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -281,5 +287,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -288,5 +295,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -295,5 +303,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -302,5 +311,6 @@
 				continue;
 
-			rc = chardev_read(kbd->chardev, &code, 1, &nread);
+			rc = chardev_read(kbd->chardev, &code, 1, &nread,
+			    chardev_f_none);
 			if (rc != EOK)
 				return EIO;
@@ -334,5 +344,5 @@
 static void default_connection_handler(ddf_fun_t *fun, ipc_call_t *icall)
 {
-	const sysarg_t method = IPC_GET_IMETHOD(*icall);
+	const sysarg_t method = ipc_get_imethod(icall);
 	xt_kbd_t *kbd = ddf_dev_data_get(ddf_fun_get_dev(fun));
 	unsigned mods;
@@ -345,5 +355,5 @@
 		 * assume AT keyboard with Scan Code Set 1.
 		 */
-		mods = IPC_GET_ARG1(*icall);
+		mods = ipc_get_arg1(icall);
 		const uint8_t status = 0 |
 		    ((mods & KM_CAPS_LOCK) ? LI_CAPS : 0) |
Index: uspace/drv/intctl/apic/apic.c
===================================================================
--- uspace/drv/intctl/apic/apic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/intctl/apic/apic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -179,5 +179,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* The other side has hung up. */
 			async_answer_0(&call, EOK);
@@ -185,8 +185,8 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IRC_ENABLE_INTERRUPT:
 			async_answer_0(&call, apic_enable_irq(apic,
-			    IPC_GET_ARG1(call)));
+			    ipc_get_arg1(&call)));
 			break;
 		case IRC_DISABLE_INTERRUPT:
@@ -212,4 +212,5 @@
 	void *regs;
 	errno_t rc;
+	bool bound = false;
 
 	if ((sysinfo_get_value("apic", &have_apic) != EOK) || (!have_apic)) {
@@ -241,4 +242,6 @@
 	}
 
+	bound = true;
+
 	rc = ddf_fun_add_to_category(fun_a, "irc");
 	if (rc != EOK)
@@ -247,4 +250,6 @@
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun_a);
 	if (fun_a != NULL)
 		ddf_fun_destroy(fun_a);
Index: uspace/drv/intctl/gicv2/Makefile
===================================================================
--- uspace/drv/intctl/gicv2/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/intctl/gicv2/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2016 Petr Pavlu
+# 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = drv
+BINARY = gicv2
+
+SOURCES = \
+	gicv2.c \
+	main.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/intctl/gicv2/gicv2.c
===================================================================
--- uspace/drv/intctl/gicv2/gicv2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/intctl/gicv2/gicv2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup uspace_drv_gicv2
+ * @{
+ */
+
+/** @file
+ */
+
+#include <async.h>
+#include <bitops.h>
+#include <ddi.h>
+#include <ddf/log.h>
+#include <errno.h>
+#include <macros.h>
+#include <str_error.h>
+#include <ipc/irc.h>
+#include <stdint.h>
+
+#include "gicv2.h"
+
+/** GICv2 distributor register map. */
+typedef struct {
+	/** Distributor control register. */
+	ioport32_t ctlr;
+#define GICV2D_CTLR_ENABLE_FLAG  0x1
+
+	/** Interrupt controller type register. */
+	const ioport32_t typer;
+#define GICV2D_TYPER_IT_LINES_NUMBER_SHIFT  0
+#define GICV2D_TYPER_IT_LINES_NUMBER_MASK \
+	(0x1f << GICV2D_TYPER_IT_LINES_NUMBER_SHIFT)
+
+	/** Distributor implementer identification register. */
+	const ioport32_t iidr;
+	/** Reserved. */
+	PADD32(5);
+	/** Implementation defined registers. */
+	ioport32_t impl[8];
+	/** Reserved. */
+	PADD32(16);
+	/** Interrupt group registers. */
+	ioport32_t igroupr[32];
+	/** Interrupt set-enable registers. */
+	ioport32_t isenabler[32];
+	/** Interrupt clear-enable registers. */
+	ioport32_t icenabler[32];
+	/** Interrupt set-pending registers. */
+	ioport32_t ispendr[32];
+	/** Interrupt clear-pending registers. */
+	ioport32_t icpendr[32];
+	/** GICv2 interrupt set-active registers. */
+	ioport32_t isactiver[32];
+	/** Interrupt clear-active registers. */
+	ioport32_t icactiver[32];
+	/** Interrupt priority registers. */
+	ioport32_t ipriorityr[255];
+	/** Reserved. */
+	PADD32(1);
+	/** Interrupt processor target registers. First 8 words are read-only.
+	 */
+	ioport32_t itargetsr[255];
+	/** Reserved. */
+	PADD32(1);
+	/** Interrupt configuration registers. */
+	ioport32_t icfgr[64];
+	/** Implementation defined registers. */
+	ioport32_t impl2[64];
+	/** Non-secure access control registers. */
+	ioport32_t nsacr[64];
+	/** Software generated interrupt register. */
+	ioport32_t sgir;
+	/** Reserved. */
+	PADD32(3);
+	/** SGI clear-pending registers. */
+	ioport32_t cpendsgir[4];
+	/** SGI set-pending registers. */
+	ioport32_t spendsgir[4];
+	/** Reserved. */
+	PADD32(40);
+	/** Implementation defined identification registers. */
+	const ioport32_t impl3[12];
+} gicv2_distr_regs_t;
+
+/* GICv2 CPU interface register map. */
+typedef struct {
+	/** CPU interface control register. */
+	ioport32_t ctlr;
+#define GICV2C_CTLR_ENABLE_FLAG  0x1
+
+	/** Interrupt priority mask register. */
+	ioport32_t pmr;
+	/** Binary point register. */
+	ioport32_t bpr;
+	/** Interrupt acknowledge register. */
+	const ioport32_t iar;
+#define GICV2C_IAR_INTERRUPT_ID_SHIFT  0
+#define GICV2C_IAR_INTERRUPT_ID_MASK \
+	(0x3ff << GICV2C_IAR_INTERRUPT_ID_SHIFT)
+#define GICV2C_IAR_CPUID_SHIFT  10
+#define GICV2C_IAR_CPUID_MASK \
+	(0x7 << GICV2C_IAR_CPUID_SHIFT)
+
+	/** End of interrupt register. */
+	ioport32_t eoir;
+	/** Running priority register. */
+	const ioport32_t rpr;
+	/** Highest priority pending interrupt register. */
+	const ioport32_t hppir;
+	/** Aliased binary point register. */
+	ioport32_t abpr;
+	/** Aliased interrupt acknowledge register. */
+	const ioport32_t aiar;
+	/** Aliased end of interrupt register. */
+	ioport32_t aeoir;
+	/** Aliased highest priority pending interrupt register. */
+	const ioport32_t ahppir;
+	/** Reserved. */
+	PADD32(5);
+	/** Implementation defined registers. */
+	ioport32_t impl[36];
+	/** Active priorities registers. */
+	ioport32_t apr[4];
+	/** Non-secure active priorities registers. */
+	ioport32_t nsapr[4];
+	/** Reserved. */
+	PADD32(3);
+	/** CPU interface identification register. */
+	const ioport32_t iidr;
+	/** Unallocated. */
+	PADD32(960);
+	/** Deactivate interrupt register. */
+	ioport32_t dir;
+} gicv2_cpui_regs_t;
+
+static errno_t gicv2_enable_irq(gicv2_t *gicv2, sysarg_t irq)
+{
+	if (irq > gicv2->max_irq)
+		return EINVAL;
+
+	ddf_msg(LVL_NOTE, "Enable interrupt '%" PRIun "'.", irq);
+
+	gicv2_distr_regs_t *distr = (gicv2_distr_regs_t *) gicv2->distr;
+	pio_write_32(&distr->isenabler[irq / 32], BIT_V(uint32_t, irq % 32));
+	return EOK;
+}
+
+/** Client connection handler.
+ *
+ * @param icall Call data of the request that opened the connection.
+ * @param arg   Local argument.
+ */
+static void gicv2_connection(ipc_call_t *icall, void *arg)
+{
+	ipc_call_t call;
+	gicv2_t *gicv2;
+
+	/*
+	 * Answer the first IPC_M_CONNECT_ME_TO call.
+	 */
+	async_answer_0(icall, EOK);
+
+	gicv2 = (gicv2_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
+
+	while (true) {
+		async_get_call(&call);
+
+		if (!ipc_get_imethod(&call)) {
+			/* The other side has hung up. */
+			async_answer_0(&call, EOK);
+			return;
+		}
+
+		switch (ipc_get_imethod(&call)) {
+		case IRC_ENABLE_INTERRUPT:
+			async_answer_0(&call,
+			    gicv2_enable_irq(gicv2, ipc_get_arg1(&call)));
+			break;
+		case IRC_DISABLE_INTERRUPT:
+			/* XXX TODO */
+			async_answer_0(&call, EOK);
+			break;
+		case IRC_CLEAR_INTERRUPT:
+			/* Noop */
+			async_answer_0(&call, EOK);
+			break;
+		default:
+			async_answer_0(&call, EINVAL);
+			break;
+		}
+	}
+}
+
+/** Add a GICv2 device. */
+errno_t gicv2_add(gicv2_t *gicv2, gicv2_res_t *res)
+{
+	ddf_fun_t *fun_a = NULL;
+	errno_t rc;
+
+	rc = pio_enable((void *) res->distr_base, sizeof(gicv2_distr_regs_t),
+	    &gicv2->distr);
+	if (rc != EOK) {
+		ddf_msg(
+		    LVL_ERROR, "Error enabling PIO for distributor registers.");
+		goto error;
+	}
+
+	rc = pio_enable(
+	    (void *) res->cpui_base, sizeof(gicv2_cpui_regs_t), &gicv2->cpui);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR,
+		    "Error enabling PIO for CPU interface registers.");
+		goto error;
+	}
+
+	fun_a = ddf_fun_create(gicv2->dev, fun_exposed, "a");
+	if (fun_a == NULL) {
+		ddf_msg(LVL_ERROR, "Failed creating function 'a'.");
+		rc = ENOMEM;
+		goto error;
+	}
+
+	ddf_fun_set_conn_handler(fun_a, gicv2_connection);
+
+	rc = ddf_fun_bind(fun_a);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function 'a': %s",
+		    str_error(rc));
+		goto error;
+	}
+
+	rc = ddf_fun_add_to_category(fun_a, "irc");
+	if (rc != EOK)
+		goto error;
+
+	/* Get maximum number of interrupts. */
+	gicv2_distr_regs_t *distr = (gicv2_distr_regs_t *) gicv2->distr;
+	uint32_t typer = pio_read_32(&distr->typer);
+	gicv2->max_irq = (((typer & GICV2D_TYPER_IT_LINES_NUMBER_MASK) >>
+	    GICV2D_TYPER_IT_LINES_NUMBER_SHIFT) + 1) * 32;
+
+	return EOK;
+error:
+	if (fun_a != NULL)
+		ddf_fun_destroy(fun_a);
+	return rc;
+}
+
+/** Remove a GICv2 device. */
+errno_t gicv2_remove(gicv2_t *gicv2)
+{
+	return ENOTSUP;
+}
+
+/** A GICv2 device gone. */
+errno_t gicv2_gone(gicv2_t *gicv2)
+{
+	return ENOTSUP;
+}
+
+/** @}
+ */
Index: uspace/drv/intctl/gicv2/gicv2.h
===================================================================
--- uspace/drv/intctl/gicv2/gicv2.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/intctl/gicv2/gicv2.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup uspace_drv_gicv2
+ * @{
+ */
+/** @file
+ */
+
+#ifndef GICV2_H_
+#define GICV2_H_
+
+#include <ddf/driver.h>
+#include <loc.h>
+#include <stdint.h>
+
+typedef struct {
+	uintptr_t distr_base;
+	uintptr_t cpui_base;
+} gicv2_res_t;
+
+/** GICv2 interrupt controller. */
+typedef struct {
+	ddf_dev_t *dev;
+	void *distr;
+	void *cpui;
+	unsigned max_irq;
+} gicv2_t;
+
+extern errno_t gicv2_add(gicv2_t *, gicv2_res_t *);
+extern errno_t gicv2_remove(gicv2_t *);
+extern errno_t gicv2_gone(gicv2_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/drv/intctl/gicv2/gicv2.ma
===================================================================
--- uspace/drv/intctl/gicv2/gicv2.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/intctl/gicv2/gicv2.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+10 arm/gicv2
Index: uspace/drv/intctl/gicv2/main.c
===================================================================
--- uspace/drv/intctl/gicv2/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/intctl/gicv2/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2018 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup uspace_drv_gicv2
+ * @{
+ */
+/** @file GICv2 driver.
+ * @brief ARM Generic Interrupt Controller, Architecture version 2.0.
+ *
+ * This IRQ controller is present on the QEMU virt platform for ARM.
+ */
+
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <device/hw_res_parsed.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "gicv2.h"
+
+#define NAME  "gicv2"
+
+static errno_t gicv2_dev_add(ddf_dev_t *dev);
+static errno_t gicv2_dev_remove(ddf_dev_t *dev);
+static errno_t gicv2_dev_gone(ddf_dev_t *dev);
+static errno_t gicv2_fun_online(ddf_fun_t *fun);
+static errno_t gicv2_fun_offline(ddf_fun_t *fun);
+
+static driver_ops_t driver_ops = {
+	.dev_add = gicv2_dev_add,
+	.dev_remove = gicv2_dev_remove,
+	.dev_gone = gicv2_dev_gone,
+	.fun_online = gicv2_fun_online,
+	.fun_offline = gicv2_fun_offline
+};
+
+static driver_t gicv2_driver = {
+	.name = NAME,
+	.driver_ops = &driver_ops
+};
+
+static errno_t gicv2_get_res(ddf_dev_t *dev, gicv2_res_t *res)
+{
+	async_sess_t *parent_sess;
+	hw_res_list_parsed_t hw_res;
+	errno_t rc;
+
+	parent_sess = ddf_dev_parent_sess_get(dev);
+	if (parent_sess == NULL)
+		return ENOMEM;
+
+	hw_res_list_parsed_init(&hw_res);
+	rc = hw_res_get_list_parsed(parent_sess, &hw_res, 0);
+	if (rc != EOK)
+		return rc;
+
+	if (hw_res.mem_ranges.count != 2) {
+		rc = EINVAL;
+		goto error;
+	}
+
+	res->distr_base = RNGABS(hw_res.mem_ranges.ranges[0]);
+	res->cpui_base = RNGABS(hw_res.mem_ranges.ranges[1]);
+
+	return EOK;
+error:
+	hw_res_list_parsed_clean(&hw_res);
+	return rc;
+}
+
+static errno_t gicv2_dev_add(ddf_dev_t *dev)
+{
+	gicv2_t *gicv2;
+	gicv2_res_t gicv2_res;
+	errno_t rc;
+
+	ddf_msg(LVL_DEBUG, "gicv2_dev_add(%p)", dev);
+	gicv2 = ddf_dev_data_alloc(dev, sizeof(gicv2_t));
+	if (gicv2 == NULL) {
+		ddf_msg(LVL_ERROR, "Failed allocating soft state.");
+		return ENOMEM;
+	}
+
+	gicv2->dev = dev;
+
+	rc = gicv2_get_res(dev, &gicv2_res);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed getting hardware resource list.\n");
+		return EIO;
+	}
+
+	return gicv2_add(gicv2, &gicv2_res);
+}
+
+static errno_t gicv2_dev_remove(ddf_dev_t *dev)
+{
+	gicv2_t *gicv2 = (gicv2_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "gicv2_dev_remove(%p)", dev);
+
+	return gicv2_remove(gicv2);
+}
+
+static errno_t gicv2_dev_gone(ddf_dev_t *dev)
+{
+	gicv2_t *gicv2 = (gicv2_t *)ddf_dev_data_get(dev);
+
+	ddf_msg(LVL_DEBUG, "gicv2_dev_gone(%p)", dev);
+
+	return gicv2_gone(gicv2);
+}
+
+static errno_t gicv2_fun_online(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "gicv2_fun_online()");
+	return ddf_fun_online(fun);
+}
+
+static errno_t gicv2_fun_offline(ddf_fun_t *fun)
+{
+	ddf_msg(LVL_DEBUG, "gicv2_fun_offline()");
+	return ddf_fun_offline(fun);
+}
+
+int main(int argc, char *argv[])
+{
+	printf(NAME ": GICv2 interrupt controller driver\n");
+	ddf_log_init(NAME);
+	return ddf_driver_main(&gicv2_driver);
+}
+
+/** @}
+ */
Index: uspace/drv/intctl/i8259/i8259.c
===================================================================
--- uspace/drv/intctl/i8259/i8259.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/intctl/i8259/i8259.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -108,5 +108,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* The other side has hung up. */
 			async_answer_0(&call, EOK);
@@ -114,8 +114,8 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IRC_ENABLE_INTERRUPT:
 			async_answer_0(&call, pic_enable_irq(i8259,
-			    IPC_GET_ARG1(call)));
+			    ipc_get_arg1(&call)));
 			break;
 		case IRC_DISABLE_INTERRUPT:
@@ -142,4 +142,5 @@
 	ddf_fun_t *fun_a = NULL;
 	errno_t rc;
+	bool bound = false;
 
 	if ((sysinfo_get_value("i8259", &have_i8259) != EOK) || (!have_i8259)) {
@@ -174,4 +175,6 @@
 	}
 
+	bound = true;
+
 	rc = ddf_fun_add_to_category(fun_a, "irc");
 	if (rc != EOK)
@@ -180,4 +183,6 @@
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun_a);
 	if (fun_a != NULL)
 		ddf_fun_destroy(fun_a);
Index: uspace/drv/intctl/icp-ic/icp-ic.c
===================================================================
--- uspace/drv/intctl/icp-ic/icp-ic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/intctl/icp-ic/icp-ic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -84,5 +84,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* The other side has hung up. */
 			async_answer_0(&call, EOK);
@@ -90,8 +90,8 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IRC_ENABLE_INTERRUPT:
 			async_answer_0(&call,
-			    icpic_enable_irq(icpic, IPC_GET_ARG1(call)));
+			    icpic_enable_irq(icpic, ipc_get_arg1(&call)));
 			break;
 		case IRC_DISABLE_INTERRUPT:
@@ -116,4 +116,5 @@
 	void *regs;
 	errno_t rc;
+	bool bound = false;
 
 	rc = pio_enable((void *)res->base, sizeof(icpic_regs_t), &regs);
@@ -146,4 +147,6 @@
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun_a);
 	if (fun_a != NULL)
 		ddf_fun_destroy(fun_a);
Index: uspace/drv/intctl/obio/obio.c
===================================================================
--- uspace/drv/intctl/obio/obio.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/intctl/obio/obio.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -90,7 +90,7 @@
 		async_get_call(&call);
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IRC_ENABLE_INTERRUPT:
-			inr = IPC_GET_ARG1(call);
+			inr = ipc_get_arg1(&call);
 			pio_set_64(&obio->regs[OBIO_IMR(inr & INO_MASK)],
 			    1UL << 31, 0);
@@ -102,5 +102,5 @@
 			break;
 		case IRC_CLEAR_INTERRUPT:
-			inr = IPC_GET_ARG1(call);
+			inr = ipc_get_arg1(&call);
 			pio_write_64(&obio->regs[OBIO_CIR(inr & INO_MASK)], 0);
 			async_answer_0(&call, EOK);
@@ -118,4 +118,5 @@
 	ddf_fun_t *fun_a = NULL;
 	errno_t rc;
+	bool bound = false;
 
 	rc = pio_enable((void *)res->base, OBIO_SIZE, (void **) &obio->regs);
@@ -149,4 +150,6 @@
 	return EOK;
 error:
+	if (bound)
+		ddf_fun_unbind(fun_a);
 	if (fun_a != NULL)
 		ddf_fun_destroy(fun_a);
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/e1k/e1k.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1244,5 +1244,5 @@
     ddf_dev_t *dev)
 {
-	uint32_t icr = (uint32_t) IPC_GET_ARG2(*icall);
+	uint32_t icr = (uint32_t) ipc_get_arg2(icall);
 	nic_t *nic = NIC_DATA_DEV(dev);
 	e1000_t *e1000 = DRIVER_DATA_NIC(nic);
Index: uspace/drv/nic/ne2k/ne2k.c
===================================================================
--- uspace/drv/nic/ne2k/ne2k.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/ne2k/ne2k.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -52,5 +52,5 @@
  *
  */
-#define IRQ_GET_ISR(call)  ((int) IPC_GET_ARG2(call))
+#define IRQ_GET_ISR(call)  ((int) ipc_get_arg2(&call))
 
 /** Return the TSR from the interrupt call.
@@ -59,5 +59,5 @@
  *
  */
-#define IRQ_GET_TSR(call)  ((int) IPC_GET_ARG3(call))
+#define IRQ_GET_TSR(call)  ((int) ipc_get_arg3(&call))
 
 #define DRIVER_DATA(dev) ((nic_t *) ddf_dev_data_get(dev))
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/rtl8139/driver.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -827,5 +827,5 @@
 	assert(icall);
 
-	uint16_t isr = (uint16_t) IPC_GET_ARG2(*icall);
+	uint16_t isr = (uint16_t) ipc_get_arg2(icall);
 	nic_t *nic_data = nic_get_from_ddf_dev(dev);
 	rtl8139_t *rtl8139 = nic_get_specific(nic_data);
Index: uspace/drv/nic/rtl8139/driver.h
===================================================================
--- uspace/drv/nic/rtl8139/driver.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/rtl8139/driver.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -107,5 +107,5 @@
 	void *tx_buff_virt;
 
-	/** Virtual adresses of the Tx buffers */
+	/** Virtual addresses of the Tx buffers */
 	void *tx_buff[TX_BUFF_COUNT];
 
Index: uspace/drv/nic/rtl8169/driver.c
===================================================================
--- uspace/drv/nic/rtl8169/driver.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/rtl8169/driver.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1038,5 +1038,5 @@
 	assert(icall);
 
-	uint16_t isr = (uint16_t) IPC_GET_ARG2(*icall) & INT_KNOWN;
+	uint16_t isr = (uint16_t) ipc_get_arg2(icall) & INT_KNOWN;
 	nic_t *nic_data = nic_get_from_ddf_dev(dev);
 	rtl8169_t *rtl8169 = nic_get_specific(nic_data);
Index: uspace/drv/nic/virtio-net/virtio-net.c
===================================================================
--- uspace/drv/nic/virtio-net/virtio-net.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/virtio-net/virtio-net.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -211,4 +211,5 @@
 		ddf_msg(LVL_NOTE, "Unsupported number of virtqueues: %u",
 		    num_queues);
+		rc = ELIMIT;
 		goto fail;
 	}
@@ -342,8 +343,9 @@
 	assert(descno < TX_BUFFERS);
 
-	/* Setup the packed header */
+	/* Setup the packet header */
 	virtio_net_hdr_t *hdr = (virtio_net_hdr_t *) virtio_net->tx_buf[descno];
 	memset(hdr, 0, sizeof(virtio_net_hdr_t));
 	hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+	hdr->num_buffers = 0;
 
 	/* Copy packet data into the buffer just past the header */
@@ -403,5 +405,5 @@
 	if (fun == NULL) {
 		rc = ENOMEM;
-		goto error;
+		goto uninitialize;
 	}
 	nic_t *nic = ddf_dev_data_get(dev);
@@ -417,5 +419,5 @@
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed binding device function");
-		goto uninitialize;
+		goto destroy;
 	}
 
@@ -433,7 +435,8 @@
 unbind:
 	ddf_fun_unbind(fun);
+destroy:
+	ddf_fun_destroy(fun);
 uninitialize:
 	virtio_net_uninitialize(dev);
-error:
 	return rc;
 }
Index: uspace/drv/nic/virtio-net/virtio-net.h
===================================================================
--- uspace/drv/nic/virtio-net/virtio-net.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/nic/virtio-net/virtio-net.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -55,9 +55,5 @@
 	uint16_t csum_start;
 	uint16_t csum_offset;
-
-	// XXX: QEMU uses the legacy layout for some reason
-#if 0
 	uint16_t num_buffers;
-#endif
 } virtio_net_hdr_t;
 
Index: uspace/drv/platform/arm64virt/Makefile
===================================================================
--- uspace/drv/platform/arm64virt/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/platform/arm64virt/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2016 Petr Pavlu
+# 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.
+#
+
+USPACE_PREFIX = ../../..
+LIBS = drv
+BINARY = arm64virt
+
+SOURCES = \
+	arm64virt.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/drv/platform/arm64virt/arm64virt.c
===================================================================
--- uspace/drv/platform/arm64virt/arm64virt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/platform/arm64virt/arm64virt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2016 Petr Pavlu
+ * 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.
+ */
+
+/**
+ * @addtogroup arm64virt
+ * @{
+ */
+
+/** @file
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <ddf/driver.h>
+#include <ddf/log.h>
+#include <ops/hw_res.h>
+#include <ops/pio_window.h>
+
+#define NAME  "arm64virt"
+
+enum {
+	arm64virt_ic_distr_membase = 0x08000000,
+	arm64virt_ic_distr_memsize = 0x00001000,
+	arm64virt_ic_cpui_membase = 0x08010000,
+	arm64virt_ic_cpui_memsize = 0x00001004,
+	arm64virt_uart_irq = 33,
+	arm64virt_uart_membase = 0x09000000,
+	arm64virt_uart_memsize = 0x00001000
+};
+
+typedef struct arm64virt_fun {
+	hw_resource_list_t hw_resources;
+} arm64virt_fun_t;
+
+static errno_t arm64virt_dev_add(ddf_dev_t *);
+
+static driver_ops_t arm64virt_ops = {
+	.dev_add = &arm64virt_dev_add
+};
+
+static driver_t arm64virt_driver = {
+	.name = NAME,
+	.driver_ops = &arm64virt_ops
+};
+
+static hw_resource_t arm64virt_ic_res[] = {
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = arm64virt_ic_distr_membase,
+			.size = arm64virt_ic_distr_memsize,
+			.relative = false,
+			.endianness = LITTLE_ENDIAN
+		}
+	},
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = arm64virt_ic_cpui_membase,
+			.size = arm64virt_ic_cpui_memsize,
+			.relative = false,
+			.endianness = LITTLE_ENDIAN
+		}
+	}
+};
+
+static hw_resource_t arm64virt_uart_res[] = {
+	{
+		.type = MEM_RANGE,
+		.res.mem_range = {
+			.address = arm64virt_uart_membase,
+			.size = arm64virt_uart_memsize,
+			.relative = false,
+			.endianness = LITTLE_ENDIAN
+		}
+	},
+	{
+		.type = INTERRUPT,
+		.res.interrupt = {
+			.irq = arm64virt_uart_irq
+		}
+	}
+};
+
+static pio_window_t arm64virt_pio_window = {
+	.mem = {
+		.base = 0,
+		.size = -1
+	}
+};
+
+static arm64virt_fun_t arm64virt_ic_fun_proto = {
+	.hw_resources = {
+		sizeof(arm64virt_ic_res) / sizeof(arm64virt_ic_res[0]),
+		arm64virt_ic_res
+	},
+};
+
+static arm64virt_fun_t arm64virt_uart_fun_proto = {
+	.hw_resources = {
+		sizeof(arm64virt_uart_res) / sizeof(arm64virt_uart_res[0]),
+		arm64virt_uart_res
+	},
+};
+
+/** Obtain function soft-state from DDF function node. */
+static arm64virt_fun_t *arm64virt_fun(ddf_fun_t *fnode)
+{
+	return ddf_fun_data_get(fnode);
+}
+
+static hw_resource_list_t *arm64virt_get_resources(ddf_fun_t *fnode)
+{
+	arm64virt_fun_t *fun = arm64virt_fun(fnode);
+
+	assert(fun != NULL);
+	return &fun->hw_resources;
+}
+
+static errno_t arm64virt_enable_interrupt(ddf_fun_t *fun, int irq)
+{
+	/* TODO */
+	return false;
+}
+
+static pio_window_t *arm64virt_get_pio_window(ddf_fun_t *fnode)
+{
+	return &arm64virt_pio_window;
+}
+
+static hw_res_ops_t arm64virt_hw_res_ops = {
+	.get_resource_list = &arm64virt_get_resources,
+	.enable_interrupt = &arm64virt_enable_interrupt,
+};
+
+static pio_window_ops_t arm64virt_pio_window_ops = {
+	.get_pio_window = &arm64virt_get_pio_window
+};
+
+static ddf_dev_ops_t arm64virt_fun_ops = {
+	.interfaces = {
+		[HW_RES_DEV_IFACE] = &arm64virt_hw_res_ops,
+		[PIO_WINDOW_DEV_IFACE] = &arm64virt_pio_window_ops
+	}
+};
+
+static errno_t arm64virt_add_fun(ddf_dev_t *dev, const char *name,
+    const char *str_match_id, arm64virt_fun_t *fun_proto)
+{
+	ddf_msg(LVL_NOTE, "Adding function '%s'.", name);
+
+	ddf_fun_t *fnode = NULL;
+	errno_t rc;
+
+	/* Create new device. */
+	fnode = ddf_fun_create(dev, fun_inner, name);
+	if (fnode == NULL) {
+		ddf_msg(LVL_ERROR, "Error creating function '%s'.", name);
+		rc = ENOMEM;
+		goto error;
+	}
+
+	arm64virt_fun_t *fun = ddf_fun_data_alloc(fnode,
+	    sizeof(arm64virt_fun_t));
+	*fun = *fun_proto;
+
+	/* Add match ID. */
+	rc = ddf_fun_add_match_id(fnode, str_match_id, 100);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Error adding match ID to function '%s'.",
+		    name);
+		goto error;
+	}
+
+	/* Set provided operations to the device. */
+	ddf_fun_set_ops(fnode, &arm64virt_fun_ops);
+
+	/* Register function. */
+	rc = ddf_fun_bind(fnode);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed binding function '%s'.", name);
+		goto error;
+	}
+
+	return EOK;
+
+error:
+	if (fnode != NULL)
+		ddf_fun_destroy(fnode);
+
+	return rc;
+}
+
+static errno_t arm64virt_add_functions(ddf_dev_t *dev)
+{
+	errno_t rc;
+
+	rc = arm64virt_add_fun(dev, "intctl", "arm/gicv2",
+	    &arm64virt_ic_fun_proto);
+	if (rc != EOK)
+		return rc;
+
+	rc = arm64virt_add_fun(dev, "uart", "arm/pl011",
+	    &arm64virt_uart_fun_proto);
+	if (rc != EOK)
+		return rc;
+
+	return EOK;
+}
+
+/** Add device. */
+static errno_t arm64virt_dev_add(ddf_dev_t *dev)
+{
+	ddf_msg(LVL_NOTE, "arm64virt_dev_add(), device=%s.",
+	    ddf_dev_get_name(dev));
+
+	/* Register functions. */
+	if (arm64virt_add_functions(dev))
+		ddf_msg(LVL_ERROR, "Failed to add functions for ARM64 QEMU "
+		    "virt platform.");
+
+	return EOK;
+}
+
+int main(int argc, char *argv[])
+{
+	errno_t rc;
+
+	printf(NAME ": HelenOS ARM64 QEMU virt platform driver\n");
+
+	rc = ddf_log_init(NAME);
+	if (rc != EOK) {
+		printf(NAME ": Failed connecting logging service.");
+		return 1;
+	}
+
+	return ddf_driver_main(&arm64virt_driver);
+}
+
+/**
+ * @}
+ */
Index: uspace/drv/platform/arm64virt/arm64virt.ma
===================================================================
--- uspace/drv/platform/arm64virt/arm64virt.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/drv/platform/arm64virt/arm64virt.ma	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+10 platform/arm64virt
Index: uspace/drv/test/test1/test1.c
===================================================================
--- uspace/drv/test/test1/test1.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/test/test1/test1.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -176,5 +176,12 @@
 	}
 
-	ddf_fun_add_to_category(fun_a, "virtual");
+	rc = ddf_fun_add_to_category(fun_a, "virtual");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding function 'a' to category "
+		    "'virtual'.");
+		ddf_fun_unbind(fun_a);
+		ddf_fun_destroy(fun_a);
+		goto error;
+	}
 
 	if (str_cmp(dev_name, "test1") == 0) {
Index: uspace/drv/test/test2/test2.c
===================================================================
--- uspace/drv/test/test2/test2.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/test/test2/test2.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,7 +31,7 @@
 
 #include <assert.h>
-#include <async.h>
 #include <stdio.h>
 #include <errno.h>
+#include <fibril.h>
 #include <str.h>
 #include <str_error.h>
@@ -140,9 +140,18 @@
 	rc = ddf_fun_bind(fun_a);
 	if (rc != EOK) {
+		ddf_fun_destroy(fun_a);
 		ddf_msg(LVL_ERROR, "Failed binding function 'a'.");
 		return rc;
 	}
 
-	ddf_fun_add_to_category(fun_a, "virtual");
+	rc = ddf_fun_add_to_category(fun_a, "virtual");
+	if (rc != EOK) {
+		ddf_fun_unbind(fun_a);
+		ddf_fun_destroy(fun_a);
+		ddf_msg(LVL_ERROR, "Failed adding function 'a' to category "
+		    "'virtual'.");
+		return rc;
+	}
+
 	test2->fun_a = fun_a;
 
Index: uspace/drv/test/test3/test3.c
===================================================================
--- uspace/drv/test/test3/test3.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/test/test3/test3.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -70,4 +70,5 @@
 	errno_t rc;
 	char *fun_name = NULL;
+	bool bound = false;
 
 	if (asprintf(&fun_name, "%s%zu", base_name, index) < 0) {
@@ -91,5 +92,12 @@
 	}
 
-	ddf_fun_add_to_category(fun, class_name);
+	bound = true;
+
+	rc = ddf_fun_add_to_category(fun, class_name);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed addning function %s to category %s: "
+		    "%s", fun_name, class_name, str_error(rc));
+		goto leave;
+	}
 
 	ddf_msg(LVL_NOTE, "Registered exposed function `%s'.", fun_name);
@@ -98,4 +106,6 @@
 	free(fun_name);
 
+	if (bound)
+		ddf_fun_unbind(fun);
 	if ((rc != EOK) && (fun != NULL)) {
 		ddf_fun_destroy(fun);
Index: uspace/drv/time/cmos-rtc/cmos-rtc.c
===================================================================
--- uspace/drv/time/cmos-rtc/cmos-rtc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/drv/time/cmos-rtc/cmos-rtc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -588,4 +588,5 @@
 	errno_t rc;
 	bool need_cleanup = false;
+	bool bound = false;
 
 	ddf_msg(LVL_DEBUG, "rtc_dev_add %s (handle = %d)",
@@ -624,7 +625,12 @@
 	}
 
+	bound = true;
 	rtc->fun = fun;
 
-	ddf_fun_add_to_category(fun, "clock");
+	rc = ddf_fun_add_to_category(fun, "clock");
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed adding service to clock category.");
+		goto error;
+	}
 
 	ddf_msg(LVL_NOTE, "Device %s successfully initialized",
@@ -634,4 +640,6 @@
 
 error:
+	if (bound)
+		ddf_fun_unbind(fun);
 	if (fun)
 		ddf_fun_destroy(fun);
@@ -754,6 +762,8 @@
 
 	rc = ddf_fun_online(fun);
-	if (rc == EOK)
-		ddf_fun_add_to_category(fun, "clock");
+	if (rc == EOK) {
+		// XXX This should be probably handled by the framework
+		rc = ddf_fun_add_to_category(fun, "clock");
+	}
 
 	return rc;
Index: uspace/lib/block/block.c
===================================================================
--- uspace/lib/block/block.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/block/block.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -241,7 +241,7 @@
 }
 
-static size_t cache_key_hash(void *key)
-{
-	aoff64_t *lba = (aoff64_t *)key;
+static size_t cache_key_hash(const void *key)
+{
+	const aoff64_t *lba = key;
 	return *lba;
 }
@@ -253,7 +253,7 @@
 }
 
-static bool cache_key_equal(void *key, const ht_link_t *item)
-{
-	aoff64_t *lba = (aoff64_t *)key;
+static bool cache_key_equal(const void *key, const ht_link_t *item)
+{
+	const aoff64_t *lba = key;
 	block_t *b = hash_table_get_inst(item, block_t, hash_link);
 	return b->lba == *lba;
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,5 +34,5 @@
 
 EXTRA_OUTPUT = $(START_FILES)
-EXTRA_CFLAGS += -fno-builtin
+EXTRA_CFLAGS += -fno-builtin -D_LIBC_SOURCE
 LIBRARY = libc
 SOVERSION = 0.0
@@ -53,4 +53,5 @@
 	generic/context.c \
 	generic/corecfg.c \
+	generic/ctype.c \
 	generic/devman.c \
 	generic/device/hw_res.c \
@@ -165,4 +166,5 @@
 	generic/assert.c \
 	generic/bsearch.c \
+	generic/pci.c \
 	generic/pio_trace.c \
 	generic/qsort.c \
@@ -188,18 +190,28 @@
 TEST_SOURCES = \
 	test/adt/circ_buf.c \
+	test/adt/odict.c \
+	test/cap.c \
+	test/casting.c \
+	test/double_to_str.c \
 	test/fibril/timer.c \
+	test/getopt.c \
+	test/gsort.c \
+	test/ieee_double.c \
+	test/imath.c \
+	test/inttypes.c \
+	test/io/table.c \
 	test/main.c \
 	test/mem.c \
-	test/inttypes.c \
-	test/io/table.c \
-	test/stdio/scanf.c \
-	test/odict.c \
+	test/perf.c \
 	test/perm.c \
 	test/qsort.c \
 	test/sprintf.c \
+	test/stdio/scanf.c \
 	test/stdio.c \
 	test/stdlib.c \
 	test/str.c \
-	test/string.c
+	test/string.c \
+	test/strtol.c \
+	test/uuid.c
 
 include $(USPACE_PREFIX)/Makefile.common
Index: uspace/lib/c/arch/abs32le/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_CONFIG_H_
-#define LIBC_abs32le_CONFIG_H_
+#ifndef _LIBC_abs32le_CONFIG_H_
+#define _LIBC_abs32le_CONFIG_H_
 
 #define PAGE_WIDTH  12
Index: uspace/lib/c/arch/abs32le/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,6 +30,6 @@
  */
 
-#ifndef LIBC_abs32le_DDI_H_
-#define LIBC_abs32le_DDI_H_
+#ifndef _LIBC_abs32le_DDI_H_
+#define _LIBC_abs32le_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_ELF_LINUX_H_
-#define LIBC_abs32le_ELF_LINUX_H_
+#ifndef _LIBC_abs32le_ELF_LINUX_H_
+#define _LIBC_abs32le_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_FADDR_H_
-#define LIBC_abs32le_FADDR_H_
+#ifndef _LIBC_abs32le_FADDR_H_
+#define _LIBC_abs32le_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_FIBRIL_H_
-#define LIBC_abs32le_FIBRIL_H_
+#ifndef _LIBC_abs32le_FIBRIL_H_
+#define _LIBC_abs32le_FIBRIL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_abs32le_FIBRIL_CONTEXT_H_
-#define LIBC_abs32le_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_abs32le_FIBRIL_CONTEXT_H_
+#define _LIBC_abs32le_FIBRIL_CONTEXT_H_
 
 #include <stdint.h>
@@ -36,10 +36,10 @@
  * need to be preserved across function calls.
  */
-typedef struct context {
+typedef struct __context {
 	uintptr_t sp;
 	uintptr_t fp;
 	uintptr_t pc;
 	uintptr_t tls;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/abs32le/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_abs32le_SYSCALL_H_
-#define LIBC_abs32le_SYSCALL_H_
+#ifndef _LIBC_abs32le_SYSCALL_H_
+#define _LIBC_abs32le_SYSCALL_H_
 
 #include <abi/syscall.h>
Index: uspace/lib/c/arch/abs32le/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_THREAD_H_
-#define LIBC_abs32le_THREAD_H_
+#ifndef _LIBC_abs32le_THREAD_H_
+#define _LIBC_abs32le_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/abs32le/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/abs32le/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_abs32le_TLS_H_
-#define LIBC_abs32le_TLS_H_
+#ifndef _LIBC_abs32le_TLS_H_
+#define _LIBC_abs32le_TLS_H_
 
 #define CONFIG_TLS_VARIANT_2
Index: uspace/lib/c/arch/abs32le/src/fibril.c
===================================================================
--- uspace/lib/c/arch/abs32le/src/fibril.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/abs32le/src/fibril.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,10 +33,10 @@
 #include <stdbool.h>
 
-int __setjmp(context_t *ctx)
+int __context_save(__context_t *ctx)
 {
 	return 0;
 }
 
-void __longjmp(context_t *ctx, int val)
+void __context_restore(__context_t *ctx, int val)
 {
 	while (true)
Index: uspace/lib/c/arch/amd64/Makefile.common
===================================================================
--- uspace/lib/c/arch/amd64/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -28,5 +28,5 @@
 
 # TODO: We need to implement DWARF unwinding and get rid of this flag.
-COMMON_CFLAGS += -fno-omit-frame-pointer
+COMMON_CFLAGS += -fno-omit-frame-pointer -Wl,-z,max-page-size=0x1000
 
 # XXX: This architecture requires unoptimized TLS pointer access,
Index: uspace/lib/c/arch/amd64/Makefile.inc
===================================================================
--- uspace/lib/c/arch/amd64/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,5 +34,7 @@
 	arch/$(UARCH)/src/tls.c \
 	arch/$(UARCH)/src/stacktrace.c \
-	arch/$(UARCH)/src/stacktrace_asm.S
+	arch/$(UARCH)/src/stacktrace_asm.S \
+	arch/$(UARCH)/src/rtld/dynamic.c \
+	arch/$(UARCH)/src/rtld/reloc.c
 
 ARCH_AUTOCHECK_HEADERS = \
Index: uspace/lib/c/arch/amd64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_CONFIG_H_
-#define LIBC_amd64_CONFIG_H_
+#ifndef _LIBC_amd64_CONFIG_H_
+#define _LIBC_amd64_CONFIG_H_
 
 #define PAGE_WIDTH	12
Index: uspace/lib/c/arch/amd64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_ELF_LINUX_H_
-#define LIBC_amd64_ELF_LINUX_H_
+#ifndef _LIBC_amd64_ELF_LINUX_H_
+#define _LIBC_amd64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/amd64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_FADDR_H_
-#define LIBC_amd64_FADDR_H_
+#ifndef _LIBC_amd64_FADDR_H_
+#define _LIBC_amd64_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/amd64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_FIBRIL_H_
-#define LIBC_amd64_FIBRIL_H_
+#ifndef _LIBC_amd64_FIBRIL_H_
+#define _LIBC_amd64_FIBRIL_H_
 
 #include <libarch/fibril_context.h>
Index: uspace/lib/c/arch/amd64/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,17 +27,17 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP   0x00
-#define CONTEXT_OFFSET_PC   0x08
-#define CONTEXT_OFFSET_RBX  0x10
-#define CONTEXT_OFFSET_RBP  0x18
-#define CONTEXT_OFFSET_R12  0x20
-#define CONTEXT_OFFSET_R13  0x28
-#define CONTEXT_OFFSET_R14  0x30
-#define CONTEXT_OFFSET_R15  0x38
-#define CONTEXT_OFFSET_TLS  0x40
-#define CONTEXT_SIZE        0x48
+#define __CONTEXT_OFFSET_SP   0x00
+#define __CONTEXT_OFFSET_PC   0x08
+#define __CONTEXT_OFFSET_RBX  0x10
+#define __CONTEXT_OFFSET_RBP  0x18
+#define __CONTEXT_OFFSET_R12  0x20
+#define __CONTEXT_OFFSET_R13  0x28
+#define __CONTEXT_OFFSET_R14  0x30
+#define __CONTEXT_OFFSET_R15  0x38
+#define __CONTEXT_OFFSET_TLS  0x40
+#define __CONTEXT_SIZE        0x48
 
 #ifndef __ASSEMBLER__
@@ -45,5 +45,5 @@
 #include <stdint.h>
 
-typedef struct context {
+typedef struct __context {
 	/*
 	 * We include only registers that must be preserved
@@ -59,5 +59,5 @@
 	uint64_t r15;
 	uint64_t tls;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/amd64/include/libarch/rtld/dynamic.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/amd64/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016 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.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_amd64_RTLD_DYNAMIC_H_
+#define _LIBC_amd64_RTLD_DYNAMIC_H_
+
+typedef struct {
+	/* Empty. */
+} dyn_info_arch_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/amd64/include/libarch/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/amd64/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 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.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+/** @file amd64 dynamic relocation types
+ */
+
+#ifndef _LIBC_amd64_RTLD_ELF_DYN_H_
+#define _LIBC_amd64_RTLD_ELF_DYN_H_
+
+#define R_X86_64_64		1
+#define R_X86_64_PC32		2
+#define R_X86_64_COPY		5
+#define R_X86_64_GLOB_DAT	6
+#define R_X86_64_JUMP_SLOT	7
+#define R_X86_64_RELATIVE	8
+
+#define R_X86_64_DTPMOD64	16
+#define R_X86_64_DTPOFF64	17
+#define R_X86_64_TPOFF64	18
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/amd64/include/libarch/rtld/module.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/amd64/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_amd64_RTLD_MODULE_H_
+#define _LIBC_amd64_RTLD_MODULE_H_
+
+#include <elf/elf_mod.h>
+
+/** ELF module load flags */
+#define RTLD_MODULE_LDF 0
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/amd64/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/stackarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/stackarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STACKARG_H_
-#define LIBC_STACKARG_H_
+#ifndef _LIBC_STACKARG_H_
+#define _LIBC_STACKARG_H_
 
 #endif
Index: uspace/lib/c/arch/amd64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_amd64_SYSCALL_H_
-#define LIBC_amd64_SYSCALL_H_
+#ifndef _LIBC_amd64_SYSCALL_H_
+#define _LIBC_amd64_SYSCALL_H_
 
 #define LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/arch/amd64/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_THREAD_H_
-#define LIBC_amd64_THREAD_H_
+#ifndef _LIBC_amd64_THREAD_H_
+#define _LIBC_amd64_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/amd64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/amd64/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_amd64_TLS_H_
-#define LIBC_amd64_TLS_H_
+#ifndef _LIBC_amd64_TLS_H_
+#define _LIBC_amd64_TLS_H_
 
 #define CONFIG_TLS_VARIANT_2
@@ -45,4 +45,6 @@
 	void *self;
 	void *fibril_data;
+	void **dtv;
+	void *pad;
 } tcb_t;
 
Index: uspace/lib/c/arch/amd64/src/entry.S
===================================================================
--- uspace/lib/c/arch/amd64/src/entry.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/src/entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,3 +47,3 @@
 	# %rdi was deliberately chosen as the first argument is also in %rdi
 	# Pass PCB pointer to __c_start (no operation)
-	call __c_start
+	call FUNCTION_REF(__c_start)
Index: uspace/lib/c/arch/amd64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/amd64/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,24 +37,24 @@
 # pointed by the 1st argument. Returns 0 in RAX.
 #
-FUNCTION_BEGIN(__setjmp)
+FUNCTION_BEGIN(__context_save)
 	movq (%rsp), %rdx     # the caller's return %eip
 
 	# in %rdi is passed 1st argument
-	movq %rdx, CONTEXT_OFFSET_PC(%rdi)
-	movq %rsp, CONTEXT_OFFSET_SP(%rdi)
+	movq %rdx, __CONTEXT_OFFSET_PC(%rdi)
+	movq %rsp, __CONTEXT_OFFSET_SP(%rdi)
 
-	movq %rbx, CONTEXT_OFFSET_RBX(%rdi)
-	movq %rbp, CONTEXT_OFFSET_RBP(%rdi)
-	movq %r12, CONTEXT_OFFSET_R12(%rdi)
-	movq %r13, CONTEXT_OFFSET_R13(%rdi)
-	movq %r14, CONTEXT_OFFSET_R14(%rdi)
-	movq %r15, CONTEXT_OFFSET_R15(%rdi)
+	movq %rbx, __CONTEXT_OFFSET_RBX(%rdi)
+	movq %rbp, __CONTEXT_OFFSET_RBP(%rdi)
+	movq %r12, __CONTEXT_OFFSET_R12(%rdi)
+	movq %r13, __CONTEXT_OFFSET_R13(%rdi)
+	movq %r14, __CONTEXT_OFFSET_R14(%rdi)
+	movq %r15, __CONTEXT_OFFSET_R15(%rdi)
 
 	movq %fs:0, %rax
-	movq %rax, CONTEXT_OFFSET_TLS(%rdi)
+	movq %rax, __CONTEXT_OFFSET_TLS(%rdi)
 
-	xorq %rax, %rax                      # __setjmp returns 0
+	xorq %rax, %rax                      # __context_save returns 0
 	ret
-FUNCTION_END(__setjmp)
+FUNCTION_END(__context_save)
 
 ## Restore current CPU context
@@ -63,23 +63,23 @@
 # pointed by the 1st argument. Returns second argument in RAX.
 #
-FUNCTION_BEGIN(__longjmp)
-	movq CONTEXT_OFFSET_R15(%rdi), %r15
-	movq CONTEXT_OFFSET_R14(%rdi), %r14
-	movq CONTEXT_OFFSET_R13(%rdi), %r13
-	movq CONTEXT_OFFSET_R12(%rdi), %r12
-	movq CONTEXT_OFFSET_RBP(%rdi), %rbp
-	movq CONTEXT_OFFSET_RBX(%rdi), %rbx
+FUNCTION_BEGIN(__context_restore)
+	movq __CONTEXT_OFFSET_R15(%rdi), %r15
+	movq __CONTEXT_OFFSET_R14(%rdi), %r14
+	movq __CONTEXT_OFFSET_R13(%rdi), %r13
+	movq __CONTEXT_OFFSET_R12(%rdi), %r12
+	movq __CONTEXT_OFFSET_RBP(%rdi), %rbp
+	movq __CONTEXT_OFFSET_RBX(%rdi), %rbx
 
-	movq CONTEXT_OFFSET_SP(%rdi), %rsp   # ctx->sp -> %rsp
+	movq __CONTEXT_OFFSET_SP(%rdi), %rsp   # ctx->sp -> %rsp
 
-	movq CONTEXT_OFFSET_PC(%rdi), %rdx
+	movq __CONTEXT_OFFSET_PC(%rdi), %rdx
 
 	movq %rdx,(%rsp)
 
-	movq CONTEXT_OFFSET_TLS(%rdi), %rdi
+	movq __CONTEXT_OFFSET_TLS(%rdi), %rdi
 	movq %rdi, %fs:0
 
-	movq %rsi, %rax                      # __longjmp returns second argument
+	movq %rsi, %rax                      # __context_restore returns second argument
 	ret
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
 
Index: uspace/lib/c/arch/amd64/src/rtld/dynamic.c
===================================================================
--- uspace/lib/c/arch/amd64/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/amd64/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 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.
+ */
+
+/** @addtogroup libcamd64
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtld/elf_dyn.h>
+#include <rtld/dynamic.h>
+
+void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
+{
+	(void) dp;
+	(void) bias;
+	(void) info;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/amd64/src/rtld/reloc.c
===================================================================
--- uspace/lib/c/arch/amd64/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/amd64/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2016 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.
+ */
+
+/** @addtogroup libcamd64
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <mem.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <libarch/rtld/elf_dyn.h>
+#include <rtld/symbol.h>
+#include <rtld/rtld.h>
+#include <rtld/rtld_debug.h>
+#include <rtld/rtld_arch.h>
+
+void module_process_pre_arch(module_t *m)
+{
+	/* Unused */
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with implicit addends.
+ */
+void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size)
+{
+
+	DPRINTF("rel table address: 0x%zx, size: %zd\n", (uintptr_t)rt, rt_size);
+	/* Unused */
+	(void)m;
+	(void)rt;
+	(void)rt_size;
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with explicit addends.
+ */
+void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size)
+{
+	unsigned i;
+
+	size_t rt_entries;
+	size_t r_offset;
+	size_t r_addend;
+	elf_xword r_info;
+	unsigned rel_type;
+	elf_word sym_idx;
+	uintptr_t sym_addr;
+
+	elf_symbol_t *sym_table;
+	elf_symbol_t *sym;
+	uintptr_t *r_ptr;
+	uint32_t *r_ptr32;
+	uintptr_t sym_size;
+	char *str_tab;
+
+	elf_symbol_t *sym_def;
+	module_t *dest;
+
+	DPRINTF("parse relocation table\n");
+
+	sym_table = m->dyn.sym_tab;
+	rt_entries = rt_size / sizeof(elf_rela_t);
+	str_tab = m->dyn.str_tab;
+
+	DPRINTF("rel table address: 0x%zx, entries: %zd\n", (uintptr_t)rt, rt_entries);
+
+	for (i = 0; i < rt_entries; ++i) {
+#if 0
+		DPRINTF("symbol %d: ", i);
+#endif
+		r_offset = rt[i].r_offset;
+		r_info = rt[i].r_info;
+		r_addend = rt[i].r_addend;
+
+		sym_idx = ELF64_R_SYM(r_info);
+		sym = &sym_table[sym_idx];
+
+#if 0
+		DPRINTF("name '%s', value 0x%x, size 0x%x\n",
+		    str_tab + sym->st_name,
+		    sym->st_value,
+		    sym->st_size);
+#endif
+		rel_type = ELF64_R_TYPE(r_info);
+		r_ptr = (uintptr_t *)(r_offset + m->bias);
+		r_ptr32 = (uint32_t *)r_ptr;
+
+		if (sym->st_name != 0) {
+			DPRINTF("rel_type: %x, rel_offset: 0x%zx\n", rel_type, r_offset);
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_none, &dest);
+			DPRINTF("dest name: '%s'\n", dest->dyn.soname);
+			DPRINTF("dest bias: 0x%zx\n", dest->bias);
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+				DPRINTF("symbol definition found, value=0x%zx addr=0x%zx\n", sym_def->st_value, sym_addr);
+			} else {
+				printf("Definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+		} else {
+			sym_addr = 0;
+			sym_def = NULL;
+
+			/*
+			 * DTPMOD with null st_name should return the index
+			 * of the current module.
+			 */
+			dest = m;
+		}
+
+		switch (rel_type) {
+		case R_X86_64_64:
+			DPRINTF("fixup R_X86_64_64 (S+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr + r_addend);
+			*r_ptr = sym_addr + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_PC32:
+			DPRINTF("fixup R_X86_64_PC32 (S+A-P)\n");
+			DPRINTF("(32)*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr + r_addend - (uintptr_t) r_ptr);
+			*r_ptr32 = sym_addr + r_addend - (uintptr_t) r_ptr;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_COPY:
+			/*
+			 * Copy symbol data from shared object to specified
+			 * location. Need to find the 'source', i.e. the
+			 * other instance of the object than the one in the
+			 * executable program.
+			 */
+			DPRINTF("fixup R_X86_64_COPY (s)\n");
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			sym_size = sym->st_size;
+			if (sym_size != sym_def->st_size) {
+				printf("Warning: Mismatched symbol sizes.\n");
+				/* Take the lower value. */
+				if (sym_size > sym_def->st_size)
+					sym_size = sym_def->st_size;
+			}
+
+			memcpy(r_ptr, (const void *)sym_addr, sym_size);
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_GLOB_DAT:
+		case R_X86_64_JUMP_SLOT:
+			DPRINTF("fixup R_X86_64_GLOB_DAT/JUMP_SLOT (S)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr);
+			*r_ptr = sym_addr;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_RELATIVE:
+			DPRINTF("fixup R_X86_64_RELATIVE (B+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, m->bias + r_addend);
+			*r_ptr = m->bias + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_DTPMOD64:
+			DPRINTF("fixup R_X86_64_DTPMOD64\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, (size_t)dest->id);
+			*r_ptr = dest->id;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_DTPOFF64:
+			DPRINTF("fixup R_X86_64_DTPOFF64\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_def->st_value);
+			*r_ptr = sym_def->st_value;
+			DPRINTF("OK\n");
+			break;
+
+		case R_X86_64_TPOFF64:
+			DPRINTF("fixup R_X86_64_TPOFF64\n");
+			*r_ptr = sym_def->st_value + dest->tpoff;
+			break;
+
+		default:
+			printf("Error: Unknown relocation type %d\n",
+			    rel_type);
+			exit(1);
+		}
+
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/amd64/src/thread_entry.S
===================================================================
--- uspace/lib/c/arch/amd64/src/thread_entry.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/src/thread_entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -46,4 +46,4 @@
 	#
 	movq %rax, %rdi
-	call __thread_main
+	call FUNCTION_REF(__thread_main)
 SYMBOL_END(__thread_entry)
Index: uspace/lib/c/arch/amd64/src/tls.c
===================================================================
--- uspace/lib/c/arch/amd64/src/tls.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/amd64/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,8 @@
 #include <stddef.h>
 
+#ifdef CONFIG_RTLD
+#include <rtld/rtld.h>
+#endif
+
 tcb_t *tls_alloc_arch(size_t size, size_t align)
 {
@@ -48,4 +52,32 @@
 }
 
+/*
+ * Rtld TLS support
+ */
+
+typedef struct {
+	unsigned long int ti_module;
+	unsigned long int ti_offset;
+} tls_index;
+
+void __attribute__((__regparm__(1)))
+    *__tls_get_addr(tls_index *ti);
+
+void __attribute__((__regparm__(1)))
+    *__tls_get_addr(tls_index *ti)
+{
+	uint8_t *tls;
+
+#ifdef CONFIG_RTLD
+	if (runtime_env != NULL) {
+		return rtld_tls_get_addr(runtime_env, __tcb_get(),
+		    ti->ti_module, ti->ti_offset);
+	}
+#endif
+	/* Get address of static TLS block */
+	tls = tls_get();
+	return tls + ti->ti_offset;
+}
+
 /** @}
  */
Index: uspace/lib/c/arch/arm32/Makefile.common
===================================================================
--- uspace/lib/c/arch/arm32/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -29,5 +29,5 @@
 
 COMMON_CFLAGS += -ffixed-r9 -mtp=soft -fno-omit-frame-pointer -mapcs-frame \
-	-mcpu=$(subst _,-,$(PROCESSOR))
+	-mcpu=$(subst _,-,$(PROCESSOR)) -Wl,-z,max-page-size=0x1000
 
 LDFLAGS += -Wl,--gc-sections
Index: uspace/lib/c/arch/arm32/Makefile.inc
===================================================================
--- uspace/lib/c/arch/arm32/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,3 +37,5 @@
 	arch/$(UARCH)/src/eabi.S \
 	arch/$(UARCH)/src/stacktrace.c \
-	arch/$(UARCH)/src/stacktrace_asm.S
+	arch/$(UARCH)/src/stacktrace_asm.S \
+	arch/$(UARCH)/src/rtld/dynamic.c \
+	arch/$(UARCH)/src/rtld/reloc.c
Index: uspace/lib/c/arch/arm32/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_CONFIG_H_
-#define LIBC_arm32_CONFIG_H_
+#ifndef _LIBC_arm32_CONFIG_H_
+#define _LIBC_arm32_CONFIG_H_
 
 #define PAGE_WIDTH	12
Index: uspace/lib/c/arch/arm32/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_arm32_DDI_H_
-#define LIBC_arm32_DDI_H_
+#ifndef _LIBC_arm32_DDI_H_
+#define _LIBC_arm32_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/arm32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_arm32_ELF_LINUX_H_
-#define LIBC_arm32_ELF_LINUX_H_
+#ifndef _LIBC_arm32_ELF_LINUX_H_
+#define _LIBC_arm32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/arm32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_FADDR_H_
-#define LIBC_arm32_FADDR_H_
+#ifndef _LIBC_arm32_FADDR_H_
+#define _LIBC_arm32_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/arm32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_FIBRIL_H_
-#define LIBC_arm32_FIBRIL_H_
+#ifndef _LIBC_arm32_FIBRIL_H_
+#define _LIBC_arm32_FIBRIL_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/arm32/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
 #include <stdint.h>
@@ -41,5 +41,5 @@
 // XXX: This struct must match the assembly code in src/fibril.S
 
-typedef struct context {
+typedef struct __context {
 	uintptr_t sp;
 	uintptr_t pc;
@@ -54,5 +54,5 @@
 	/* r11 */
 	uint32_t fp;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/arm32/include/libarch/rtld/dynamic.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm32/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_arm32_RTLD_DYNAMIC_H_
+#define _LIBC_arm32_RTLD_DYNAMIC_H_
+
+typedef struct {
+	/* Empty. */
+} dyn_info_arch_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm32/include/libarch/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm32/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_arm32_RTLD_ELF_DYN_H_
+#define _LIBC_arm32_RTLD_ELF_DYN_H_
+
+/*
+ * arm32 dynamic relocation types
+ */
+
+#define R_ARM_ABS32         2
+#define R_ARM_TLS_DTPMOD32 17
+#define R_ARM_TLS_DTPOFF32 18
+#define R_ARM_TLS_TPOFF32  19
+#define R_ARM_COPY         20
+#define R_ARM_GLOB_DAT     21
+#define R_ARM_JUMP_SLOT    22
+#define R_ARM_RELATIVE     23
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm32/include/libarch/rtld/module.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_arm32_RTLD_MODULE_H_
+#define _LIBC_arm32_RTLD_MODULE_H_
+
+#include <elf/elf_mod.h>
+
+/** ELF module load flags */
+#define RTLD_MODULE_LDF 0
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm32/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/stackarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/stackarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_STACKARG_H_
-#define LIBC_arm32_STACKARG_H_
+#ifndef _LIBC_arm32_STACKARG_H_
+#define _LIBC_arm32_STACKARG_H_
 
 #endif
Index: uspace/lib/c/arch/arm32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_SYSCALL_H_
-#define LIBC_arm32_SYSCALL_H_
+#ifndef _LIBC_arm32_SYSCALL_H_
+#define _LIBC_arm32_SYSCALL_H_
 
 #define LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/arch/arm32/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_THREAD_H_
-#define LIBC_arm32_THREAD_H_
+#ifndef _LIBC_arm32_THREAD_H_
+#define _LIBC_arm32_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/arm32/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/arm32/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_arm32_TLS_H_
-#define LIBC_arm32_TLS_H_
+#ifndef _LIBC_arm32_TLS_H_
+#define _LIBC_arm32_TLS_H_
 
 #include <stdint.h>
@@ -49,4 +49,6 @@
  */
 typedef struct {
+	void **dtv;
+	void *pad;
 	/** Fibril data. */
 	void *fibril_data;
Index: uspace/lib/c/arch/arm32/src/atomic.c
===================================================================
--- uspace/lib/c/arch/arm32/src/atomic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/src/atomic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,5 +35,5 @@
 #include <stdbool.h>
 
-extern volatile unsigned *ras_page;
+volatile unsigned *ras_page;
 
 bool __atomic_compare_exchange_4(volatile unsigned *mem, unsigned *expected, unsigned desired, bool weak, int success, int failure)
Index: uspace/lib/c/arch/arm32/src/entry.S
===================================================================
--- uspace/lib/c/arch/arm32/src/entry.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/src/entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -56,5 +56,2 @@
 
 .data
-
-SYMBOL(ras_page)
-	.long 0
Index: uspace/lib/c/arch/arm32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/arm32/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,5 +31,5 @@
 .text
 
-FUNCTION_BEGIN(__setjmp)
+FUNCTION_BEGIN(__context_save)
 	stmia r0!, {sp, lr}
 	stmia r0!, {r4-r11}
@@ -38,7 +38,7 @@
 	mov r0, #0
 	mov pc, lr
-FUNCTION_END(__setjmp)
+FUNCTION_END(__context_save)
 
-FUNCTION_BEGIN(__longjmp)
+FUNCTION_BEGIN(__context_restore)
 	ldmia r0!, {sp, lr}
 	ldmia r0!, {r4-r11}
@@ -47,4 +47,4 @@
 	mov r0, r1
 	mov pc, lr
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
 
Index: uspace/lib/c/arch/arm32/src/rtld/dynamic.c
===================================================================
--- uspace/lib/c/arch/arm32/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm32/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libcarm32
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtld/elf_dyn.h>
+#include <rtld/dynamic.h>
+
+void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
+{
+	(void) dp;
+	(void) bias;
+	(void) info;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm32/src/rtld/reloc.c
===================================================================
--- uspace/lib/c/arch/arm32/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm32/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libcarm32
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <bitops.h>
+#include <smc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <str.h>
+
+#include <libarch/rtld/elf_dyn.h>
+#include <rtld/symbol.h>
+#include <rtld/rtld.h>
+#include <rtld/rtld_debug.h>
+#include <rtld/rtld_arch.h>
+
+void module_process_pre_arch(module_t *m)
+{
+	/* Unused */
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table.
+ */
+void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size)
+{
+	unsigned i;
+
+	size_t rt_entries;
+	size_t r_offset;
+	elf_word r_info;
+	unsigned rel_type;
+	elf_word sym_idx;
+	uint32_t sym_addr;
+
+	elf_symbol_t *sym_table;
+	elf_symbol_t *sym;
+	uint32_t *r_ptr;
+	uint32_t sym_size;
+	char *str_tab;
+
+	elf_symbol_t *sym_def;
+	module_t *dest;
+
+	DPRINTF("parse relocation table\n");
+
+	sym_table = m->dyn.sym_tab;
+	rt_entries = rt_size / sizeof(elf_rel_t);
+	str_tab = m->dyn.str_tab;
+
+	DPRINTF("address: 0x%" PRIxPTR ", entries: %zd\n", (uintptr_t)rt, rt_entries);
+
+	for (i = 0; i < rt_entries; ++i) {
+#if 0
+		DPRINTF("symbol %d: ", i);
+#endif
+		r_offset = rt[i].r_offset;
+		r_info = rt[i].r_info;
+
+		sym_idx = ELF32_R_SYM(r_info);
+		sym = &sym_table[sym_idx];
+
+#if 0
+		DPRINTF("name '%s', value 0x%x, size 0x%x\n",
+		    str_tab + sym->st_name, sym->st_value, sym->st_size);
+#endif
+		rel_type = ELF32_R_TYPE(r_info);
+		r_ptr = (uint32_t *)(r_offset + m->bias);
+
+		if (sym->st_name != 0) {
+#if 0
+			DPRINTF("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset);
+#endif
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_none, &dest);
+			DPRINTF("dest name: '%s'\n", dest->dyn.soname);
+			DPRINTF("dest bias: 0x%x\n", dest->bias);
+			if (sym_def) {
+				sym_addr = (uint32_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+#if 0
+				DPRINTF("symbol definition found, addr=0x%x\n", sym_addr);
+#endif
+			} else {
+				printf("Definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+		} else {
+			sym_addr = 0;
+			sym_def = NULL;
+			dest = m;
+		}
+
+		switch (rel_type) {
+		case R_ARM_ABS32:
+			DPRINTF("ignore R_ARM_ABS32\n");
+			/*
+			 * Not sure why we get these static relocations, but
+			 * attempting to process them will crash the
+			 * loader. If we ignore them, everything
+			 * seems to work.
+			 */
+			break;
+
+		case R_ARM_TLS_DTPMOD32:
+			DPRINTF("fixup R_ARM_TLS_DTPMOD32\n");
+			*r_ptr = dest->id;
+			break;
+
+		case R_ARM_TLS_DTPOFF32:
+			DPRINTF("fixup R_ARM_TLS_DTPOFF32\n");
+			*r_ptr = sym_def->st_value;
+			break;
+
+		case R_ARM_TLS_TPOFF32:
+			DPRINTF("fixup R_ARM_TLS_TPOFF\n");
+			if (sym_def != NULL)
+				*r_ptr = sym_def->st_value + dest->tpoff;
+			else
+				*r_ptr = m->tpoff;
+			break;
+
+		case R_ARM_COPY:
+			/*
+			 * Copy symbol data from shared object to specified
+			 * location. Need to find the 'source', i.e. the
+			 * other instance of the object than the one in the
+			 * executable program.
+			 */
+			DPRINTF("fixup R_ARM_COPY (s)\n");
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uint32_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			sym_size = sym->st_size;
+			if (sym_size != sym_def->st_size) {
+				printf("Warning: Mismatched symbol sizes.\n");
+				/* Take the lower value. */
+				if (sym_size > sym_def->st_size)
+					sym_size = sym_def->st_size;
+			}
+
+			memcpy(r_ptr, (const void *)sym_addr, sym_size);
+			break;
+
+		case R_ARM_GLOB_DAT:
+		case R_ARM_JUMP_SLOT:
+			DPRINTF("fixup R_ARM_GLOB_DAT/JUMP_SLOT (S)\n");
+			*r_ptr = sym_addr;
+			break;
+
+		case R_ARM_RELATIVE:
+			DPRINTF("fixup R_ARM_RELATIVE (B)\n");
+			*r_ptr += dest->bias;
+			break;
+
+		default:
+			printf("Error: Unknown relocation type %d\n",
+			    rel_type);
+			exit(1);
+		}
+	}
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with explicit addends.
+ */
+void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size)
+{
+	(void) m;
+	(void) rt;
+	(void) rt_size;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm32/src/syscall.c
===================================================================
--- uspace/lib/c/arch/arm32/src/syscall.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/src/syscall.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -70,4 +70,10 @@
 	      "r" (__arm_reg_r5),
 	      "r" (__arm_reg_r6)
+	    :
+	      /*
+	       * Clobber memory too as some arguments might be
+	       * actually pointers.
+	       */
+	      "memory"
 	);
 
Index: uspace/lib/c/arch/arm32/src/tls.c
===================================================================
--- uspace/lib/c/arch/arm32/src/tls.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/arm32/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2019 Jiri Svoboda
  * Copyright (c) 2007 Pavel Jancik
  * All rights reserved.
@@ -38,4 +39,8 @@
 #include <stddef.h>
 
+#ifdef CONFIG_RTLD
+#include <rtld/rtld.h>
+#endif
+
 tcb_t *tls_alloc_arch(size_t size, size_t align)
 {
@@ -48,4 +53,32 @@
 }
 
+/*
+ * Rtld TLS support
+ */
+
+typedef struct {
+	unsigned long int ti_module;
+	unsigned long int ti_offset;
+} tls_index;
+
+int __tls_debug = 0;
+
+void *__tls_get_addr(tls_index *ti);
+
+void *__tls_get_addr(tls_index *ti)
+{
+	uint8_t *tls;
+
+#ifdef CONFIG_RTLD
+	if (runtime_env != NULL) {
+		return rtld_tls_get_addr(runtime_env, __tcb_get(),
+		    ti->ti_module, ti->ti_offset);
+	}
+#endif
+	/* Get address of static TLS block */
+	tls = tls_get();
+	return tls + ti->ti_offset;
+}
+
 /** @}
  */
Index: uspace/lib/c/arch/arm64/Makefile.common
===================================================================
--- uspace/lib/c/arch/arm64/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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.
+#
+
+COMMON_CFLAGS += -fno-omit-frame-pointer
+
+LDFLAGS += -Wl,--gc-sections
+
+ENDIANESS = LE
+
+BFD_NAME = elf64-littleaarch64
+BFD_ARCH = aarch64
Index: uspace/lib/c/arch/arm64/Makefile.inc
===================================================================
--- uspace/lib/c/arch/arm64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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.
+#
+
+ARCH_SOURCES = \
+	arch/$(UARCH)/src/entryjmp.S \
+	arch/$(UARCH)/src/fibril.S \
+	arch/$(UARCH)/src/stacktrace.c \
+	arch/$(UARCH)/src/stacktrace_asm.S \
+	arch/$(UARCH)/src/syscall.c \
+	arch/$(UARCH)/src/tls.c \
+	arch/$(UARCH)/src/thread_entry.S
+
+ARCH_AUTOCHECK_HEADERS = \
+	arch/$(UARCH)/include/libarch/fibril_context.h
Index: uspace/lib/c/arch/arm64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ * @{
+ */
+/** @file
+ * @brief Configuration constants.
+ */
+
+#ifndef _LIBC_arm64_CONFIG_H_
+#define _LIBC_arm64_CONFIG_H_
+
+#define PAGE_WIDTH  12
+#define PAGE_SIZE   (1 << PAGE_WIDTH)
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ * @{
+ */
+/** @file
+ * @brief
+ */
+
+#ifndef _LIBC_arm64_DDI_H_
+#define _LIBC_arm64_DDI_H_
+
+#include <ddi.h>
+
+static inline void arch_pio_write_8(ioport8_t *port, uint8_t v)
+{
+	*port = v;
+}
+
+static inline void arch_pio_write_16(ioport16_t *port, uint16_t v)
+{
+	*port = v;
+}
+
+static inline void arch_pio_write_32(ioport32_t *port, uint32_t v)
+{
+	*port = v;
+}
+
+static inline void arch_pio_write_64(ioport64_t *port, uint64_t v)
+{
+	*port = v;
+}
+
+static inline uint8_t arch_pio_read_8(const ioport8_t *port)
+{
+	return *port;
+}
+
+static inline uint16_t arch_pio_read_16(const ioport16_t *port)
+{
+	return *port;
+}
+
+static inline uint32_t arch_pio_read_32(const ioport32_t *port)
+{
+	return *port;
+}
+
+static inline uint64_t arch_pio_read_64(const ioport64_t *port)
+{
+	return *port;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ * @{
+ */
+/** @file Definitions needed to write core files in Linux-ELF format.
+ */
+
+#ifndef _LIBC_arm64_ELF_LINUX_H_
+#define _LIBC_arm64_ELF_LINUX_H_
+
+#include <libarch/istate.h>
+#include <stdint.h>
+
+/** Linux kernel struct pt_regs structure.
+ *
+ * We need this to save register state to a core file in Linux format
+ * (readable by GDB configured for Linux target).
+ */
+typedef struct {
+	uint64_t x0;
+	uint64_t x1;
+	uint64_t x2;
+	uint64_t x3;
+	uint64_t x4;
+	uint64_t x5;
+	uint64_t x6;
+	uint64_t x7;
+	uint64_t x8;
+	uint64_t x9;
+	uint64_t x10;
+	uint64_t x11;
+	uint64_t x12;
+	uint64_t x13;
+	uint64_t x14;
+	uint64_t x15;
+	uint64_t x16;
+	uint64_t x17;
+	uint64_t x18;
+	uint64_t x19;
+	uint64_t x20;
+	uint64_t x21;
+	uint64_t x22;
+	uint64_t x23;
+	uint64_t x24;
+	uint64_t x25;
+	uint64_t x26;
+	uint64_t x27;
+	uint64_t x28;
+	uint64_t x29;
+	uint64_t x30;
+
+	uint64_t sp;
+	uint64_t pc;
+	uint64_t pstate;
+
+	uint64_t orig_x0;
+	uint64_t syscallno;
+} elf_regs_t;
+
+/** Convert istate_t to elf_regs_t. */
+static inline void istate_to_elf_regs(istate_t *istate, elf_regs_t *elf_regs)
+{
+	elf_regs->x0 = istate->x0;
+	elf_regs->x1 = istate->x1;
+	elf_regs->x2 = istate->x2;
+	elf_regs->x3 = istate->x3;
+	elf_regs->x4 = istate->x4;
+	elf_regs->x5 = istate->x5;
+	elf_regs->x6 = istate->x6;
+	elf_regs->x7 = istate->x7;
+	elf_regs->x8 = istate->x8;
+	elf_regs->x9 = istate->x9;
+	elf_regs->x10 = istate->x10;
+	elf_regs->x11 = istate->x11;
+	elf_regs->x12 = istate->x12;
+	elf_regs->x13 = istate->x13;
+	elf_regs->x14 = istate->x14;
+	elf_regs->x15 = istate->x15;
+	elf_regs->x16 = istate->x16;
+	elf_regs->x17 = istate->x17;
+	elf_regs->x18 = istate->x18;
+	elf_regs->x19 = istate->x19;
+	elf_regs->x20 = istate->x20;
+	elf_regs->x21 = istate->x21;
+	elf_regs->x22 = istate->x22;
+	elf_regs->x23 = istate->x23;
+	elf_regs->x24 = istate->x24;
+	elf_regs->x25 = istate->x25;
+	elf_regs->x26 = istate->x26;
+	elf_regs->x27 = istate->x27;
+	elf_regs->x28 = istate->x28;
+	elf_regs->x29 = istate->x29;
+	elf_regs->x30 = istate->x30;
+
+	elf_regs->sp = istate->sp;
+	elf_regs->pc = istate->pc;
+	elf_regs->pstate = istate->spsr;
+
+	elf_regs->orig_x0 = 0;
+	elf_regs->syscallno = 0;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ * @{
+ */
+/** @file
+ * @brief Function address conversion.
+ */
+
+#ifndef _LIBC_arm64_FADDR_H_
+#define _LIBC_arm64_FADDR_H_
+
+#include <types/common.h>
+
+/** Calculate absolute address of function referenced by fptr pointer.
+ *
+ * @param f Function pointer.
+ */
+#define FADDR(f)  ((uintptr_t) (f))
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ * @{
+ */
+/** @file
+ * @brief Fibrils related declarations.
+ */
+
+#ifndef _LIBC_arm64_FIBRIL_H_
+#define _LIBC_arm64_FIBRIL_H_
+
+#include <types/common.h>
+#include <align.h>
+#include <libarch/fibril_context.h>
+
+/** Size of a stack item. */
+#define STACK_ITEM_SIZE	 8
+
+/** Required stack alignment. */
+#define STACK_ALIGNMENT	 16
+
+#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
+
+/** Sets data to the context.
+ *
+ * @param c Context (#context_t).
+ * @param _pc Program counter.
+ * @param stack Stack address.
+ * @param size Stack size.
+ * @param ptls Pointer to the TCB.
+ */
+#define context_set(c, _pc, stack, size, ptls) \
+	do { \
+		(c)->pc = (uint64_t) (_pc); \
+		(c)->sp = ((uint64_t) (stack)) + (size) - SP_DELTA; \
+		(c)->tls = ((uint64_t) (ptls)) + ARCH_TP_OFFSET; \
+		/* Set frame pointer too. */ \
+		(c)->x29 = 0; \
+	} while (0)
+
+static inline uintptr_t _context_get_fp(context_t *ctx)
+{
+	return ctx->x29;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
+
+#define __CONTEXT_OFFSET_SP     0x00
+#define __CONTEXT_OFFSET_PC     0x08
+#define __CONTEXT_OFFSET_X19    0x10
+#define __CONTEXT_OFFSET_X20    0x18
+#define __CONTEXT_OFFSET_X21    0x20
+#define __CONTEXT_OFFSET_X22    0x28
+#define __CONTEXT_OFFSET_X23    0x30
+#define __CONTEXT_OFFSET_X24    0x38
+#define __CONTEXT_OFFSET_X25    0x40
+#define __CONTEXT_OFFSET_X26    0x48
+#define __CONTEXT_OFFSET_X27    0x50
+#define __CONTEXT_OFFSET_X28    0x58
+#define __CONTEXT_OFFSET_X29    0x60
+#define __CONTEXT_OFFSET_TLS    0x68
+#define __CONTEXT_OFFSET_VREGS  0x70
+#define __CONTEXT_SIZE          0xb0
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+typedef struct __context {
+	uint64_t sp;
+	uint64_t pc;
+	uint64_t x19;
+	uint64_t x20;
+	uint64_t x21;
+	uint64_t x22;
+	uint64_t x23;
+	uint64_t x24;
+	uint64_t x25;
+	uint64_t x26;
+	uint64_t x27;
+	uint64_t x28;
+	uint64_t x29;
+	uint64_t tls;
+	/* v8-v15, low 64 bits only. */
+	uint64_t vregs[8];
+} __context_t;
+
+#endif
+#endif
Index: uspace/lib/c/arch/arm64/include/libarch/istate.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/istate.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/arm64/include/arch/istate.h
Index: uspace/lib/c/arch/arm64/include/libarch/istate_struct.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/istate_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/istate_struct.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/arm64/include/arch/istate_struct.h
Index: uspace/lib/c/arch/arm64/include/libarch/regutils.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/regutils.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/regutils.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,1 @@
+../../../../../../../kernel/arch/arm64/include/arch/regutils.h
Index: uspace/lib/c/arch/arm64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ * @{
+ */
+/** @file
+ * @brief
+ */
+
+#ifndef _LIBC_arm64_SYSCALL_H_
+#define _LIBC_arm64_SYSCALL_H_
+
+#define LIBARCH_SYSCALL_GENERIC
+
+#include <syscall.h>
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_arm64_THREAD_H_
+#define _LIBC_arm64_THREAD_H_
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/arm64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ * @{
+ */
+/** @file
+ * @brief Thread-local storage.
+ */
+
+#ifndef _LIBC_arm64_TLS_H_
+#define _LIBC_arm64_TLS_H_
+
+#define CONFIG_TLS_VARIANT_1
+
+/** Offsets for accessing thread-local variables are shifted 16 bytes higher. */
+#define ARCH_TP_OFFSET  (sizeof(tcb_t) - 16)
+
+/** TCB (Thread Control Block) struct.
+ *
+ * TLS starts just after this struct.
+ */
+typedef struct {
+	/** Fibril data. */
+	void *fibril_data;
+} tcb_t;
+
+static inline void __tcb_raw_set(void *tls)
+{
+	asm volatile ("msr tpidr_el0, %[tls]" : : [tls] "r" (tls));
+}
+
+static inline void *__tcb_raw_get(void)
+{
+	void *retval;
+	asm volatile ("mrs %[tls], tpidr_el0" : [tls] "=r" (retval));
+	return retval;
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/src/entry.S
===================================================================
--- uspace/lib/c/arch/arm64/src/entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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 <abi/asmtool.h>
+
+.text
+
+.org 0
+
+## User-space task entry point
+#
+# x0 contains the PCB pointer
+#
+SYMBOL(_start)
+	#
+	# Create the first stack frame.
+	#
+	mov x29, #0
+	stp x29, x30, [sp, #-16]!
+	mov x29, sp
+
+	# Pass pcb_ptr to __c_start as the first argument (in x0)
+	bl __c_start
Index: uspace/lib/c/arch/arm64/src/entryjmp.S
===================================================================
--- uspace/lib/c/arch/arm64/src/entryjmp.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/entryjmp.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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 <abi/asmtool.h>
+
+## void entry_point_jmp(void *entry_point, void *pcb);
+#
+# x0	contains entry_point
+# x1	contains pcb
+#
+# Jump to program entry point
+SYMBOL(entry_point_jmp)
+	# Pass PCB in x0 to the entry point and jump to it.
+	mov x2, x0
+	mov x0, x1
+	br x2
Index: uspace/lib/c/arch/arm64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/arm64/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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 <abi/asmtool.h>
+#include <libarch/fibril_context.h>
+
+.text
+
+/* Static checks for the context_t save/load. */
+#if __CONTEXT_OFFSET_SP + 8 != __CONTEXT_OFFSET_PC
+#error sp and pc are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X19 + 8 != __CONTEXT_OFFSET_X20
+#error x19 and x20 are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X21 + 8 != __CONTEXT_OFFSET_X22
+#error x21 and x22 are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X23 + 8 != __CONTEXT_OFFSET_X24
+#error x23 and x24 are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X25 + 8 != __CONTEXT_OFFSET_X26
+#error x25 and x26 are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X27 + 8 != __CONTEXT_OFFSET_X28
+#error x27 and x28 are not successive in context_t
+#endif
+#if __CONTEXT_OFFSET_X29 + 8 != __CONTEXT_OFFSET_TLS
+#error x29 and tls are not successive in context_t
+#endif
+
+FUNCTION_BEGIN(__context_save)
+	/* Save callee-saved registers into context_t pointed by x0. */
+	mov x1, sp
+	stp x1, x30, [x0, #__CONTEXT_OFFSET_SP]
+	stp x19, x20, [x0, #__CONTEXT_OFFSET_X19]
+	stp x21, x22, [x0, #__CONTEXT_OFFSET_X21]
+	stp x23, x24, [x0, #__CONTEXT_OFFSET_X23]
+	stp x25, x26, [x0, #__CONTEXT_OFFSET_X25]
+	stp x27, x28, [x0, #__CONTEXT_OFFSET_X27]
+	/* Save the last general-purpose register and TLS. */
+	mrs x1, tpidr_el0
+	stp x29, x1, [x0, #__CONTEXT_OFFSET_X29]
+	/* Save low 64 bits of v8-v15. */
+	stp d8, d9, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 0]
+	stp d10, d11, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 2]
+	stp d12, d13, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 4]
+	stp d14, d15, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 6]
+
+	/* Return 0. */
+	mov x0, #0
+	ret
+FUNCTION_END(__context_save)
+
+FUNCTION_BEGIN(__context_restore)
+	/* Restore callee-saved registers from context_t pointed by x0. */
+	ldp x2, x30, [x0, #__CONTEXT_OFFSET_SP]
+	mov sp, x2
+	ldp x19, x20, [x0, #__CONTEXT_OFFSET_X19]
+	ldp x21, x22, [x0, #__CONTEXT_OFFSET_X21]
+	ldp x23, x24, [x0, #__CONTEXT_OFFSET_X23]
+	ldp x25, x26, [x0, #__CONTEXT_OFFSET_X25]
+	ldp x27, x28, [x0, #__CONTEXT_OFFSET_X27]
+	/* Restore the last general-purpose register and TLS. */
+	ldp x29, x2, [x0, #__CONTEXT_OFFSET_X29]
+	msr tpidr_el0, x2
+	/* Restore low 64 bits of v8-v15. */
+	ldp d8, d9, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 0]
+	ldp d10, d11, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 2]
+	ldp d12, d13, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 4]
+	ldp d14, d15, [x0, #__CONTEXT_OFFSET_VREGS + 8 * 6]
+
+	/* Return the second argument. */
+	mov x0, x1
+	ret
+FUNCTION_END(__context_restore)
Index: uspace/lib/c/arch/arm64/src/stacktrace.c
===================================================================
--- uspace/lib/c/arch/arm64/src/stacktrace.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/stacktrace.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ * @{
+ */
+/** @file
+ * @brief
+ */
+
+#include <stacktrace.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#define FRAME_OFFSET_FP_PREV  0
+#define FRAME_OFFSET_RA       8
+
+bool stacktrace_fp_valid(stacktrace_t *st __attribute__((unused)),
+    uintptr_t fp)
+{
+	return fp != 0;
+}
+
+errno_t stacktrace_fp_prev(stacktrace_t *st, uintptr_t fp, uintptr_t *prev)
+{
+	return (*st->ops->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_FP_PREV,
+	    prev);
+}
+
+errno_t stacktrace_ra_get(stacktrace_t *st, uintptr_t fp, uintptr_t *ra)
+{
+	return (*st->ops->read_uintptr)(st->op_arg, fp + FRAME_OFFSET_RA, ra);
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/src/stacktrace_asm.S
===================================================================
--- uspace/lib/c/arch/arm64/src/stacktrace_asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/stacktrace_asm.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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 <abi/asmtool.h>
+
+.text
+
+FUNCTION_BEGIN(stacktrace_prepare)
+	ret
+FUNCTION_END(stacktrace_prepare)
+
+FUNCTION_BEGIN(stacktrace_fp_get)
+	mov x0, x29
+	ret
+FUNCTION_END(stacktrace_fp_get)
+
+FUNCTION_BEGIN(stacktrace_pc_get)
+	mov x0, x30
+	ret
+FUNCTION_END(stacktrace_pc_get)
Index: uspace/lib/c/arch/arm64/src/syscall.c
===================================================================
--- uspace/lib/c/arch/arm64/src/syscall.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/syscall.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ * @{
+ */
+/** @file
+ * @brief Syscall routine.
+ */
+
+#include <libc.h>
+
+/** Syscall routine.
+ *
+ * Stores p1-p6, id to r0-r6 registers and calls <code>svc</code> instruction.
+ * Returned value is read from r0 register.
+ *
+ * @param p1 Parameter 1.
+ * @param p2 Parameter 2.
+ * @param p3 Parameter 3.
+ * @param p4 Parameter 4.
+ * @param p5 Parameter 5.
+ * @param p6 Parameter 6.
+ * @param id Number of syscall.
+ *
+ * @return Syscall return value.
+ */
+sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2, const sysarg_t p3,
+    const sysarg_t p4, const sysarg_t p5, const sysarg_t p6,
+    const syscall_t id)
+{
+	register sysarg_t __arm_reg_x0 asm("x0") = p1;
+	register sysarg_t __arm_reg_x1 asm("x1") = p2;
+	register sysarg_t __arm_reg_x2 asm("x2") = p3;
+	register sysarg_t __arm_reg_x3 asm("x3") = p4;
+	register sysarg_t __arm_reg_x4 asm("x4") = p5;
+	register sysarg_t __arm_reg_x5 asm("x5") = p6;
+	register sysarg_t __arm_reg_x6 asm("x6") = id;
+
+	asm volatile (
+	    "svc #0"
+	    : "=r" (__arm_reg_x0)
+	    : "r" (__arm_reg_x0),
+	      "r" (__arm_reg_x1),
+	      "r" (__arm_reg_x2),
+	      "r" (__arm_reg_x3),
+	      "r" (__arm_reg_x4),
+	      "r" (__arm_reg_x5),
+	      "r" (__arm_reg_x6)
+	    :
+	      /*
+	       * Clobber memory too as some arguments might be actually
+	       * pointers.
+	       */
+	      "memory"
+	);
+
+	return __arm_reg_x0;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/arm64/src/thread_entry.S
===================================================================
--- uspace/lib/c/arch/arm64/src/thread_entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/thread_entry.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2015 Petr Pavlu
+# 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 <abi/asmtool.h>
+
+.text
+
+## User-space thread entry point for all but the first thread.
+#
+#
+SYMBOL(__thread_entry)
+	#
+	# Create the first stack frame.
+	#
+	mov x29, #0
+	stp x29, x30, [sp, #-16]!
+	mov x29, sp
+
+	b __thread_main
Index: uspace/lib/c/arch/arm64/src/tls.c
===================================================================
--- uspace/lib/c/arch/arm64/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/arm64/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 Petr Pavlu
+ * 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.
+ */
+
+/** @addtogroup libcarm64
+ */
+/** @file
+ * @brief Thread-local storage.
+ */
+
+#include <tls.h>
+#include <stddef.h>
+
+tcb_t *tls_alloc_arch(size_t size, size_t align)
+{
+	return tls_alloc_variant_1(size, align);
+}
+
+void tls_free_arch(tcb_t *tcb, size_t size, size_t align)
+{
+	tls_free_variant_1(tcb, size, align);
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/ia32/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_CONFIG_H_
-#define LIBC_ia32_CONFIG_H_
+#ifndef _LIBC_ia32_CONFIG_H_
+#define _LIBC_ia32_CONFIG_H_
 
 #define PAGE_WIDTH  12
Index: uspace/lib/c/arch/ia32/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_ia32_DDI_H_
-#define LIBC_ia32_DDI_H_
+#ifndef _LIBC_ia32_DDI_H_
+#define _LIBC_ia32_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/ia32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_ELF_LINUX_H_
-#define LIBC_ia32_ELF_LINUX_H_
+#ifndef _LIBC_ia32_ELF_LINUX_H_
+#define _LIBC_ia32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/ia32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_FADDR_H_
-#define LIBC_ia32_FADDR_H_
+#ifndef _LIBC_ia32_FADDR_H_
+#define _LIBC_ia32_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/ia32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_FIBRIL_H_
-#define LIBC_ia32_FIBRIL_H_
+#ifndef _LIBC_ia32_FIBRIL_H_
+#define _LIBC_ia32_FIBRIL_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/ia32/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,15 +27,15 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP   0x00
-#define CONTEXT_OFFSET_PC   0x04
-#define CONTEXT_OFFSET_EBX  0x08
-#define CONTEXT_OFFSET_ESI  0x0c
-#define CONTEXT_OFFSET_EDI  0x10
-#define CONTEXT_OFFSET_EBP  0x14
-#define CONTEXT_OFFSET_TLS  0x18
-#define CONTEXT_SIZE        0x1c
+#define __CONTEXT_OFFSET_SP   0x00
+#define __CONTEXT_OFFSET_PC   0x04
+#define __CONTEXT_OFFSET_EBX  0x08
+#define __CONTEXT_OFFSET_ESI  0x0c
+#define __CONTEXT_OFFSET_EDI  0x10
+#define __CONTEXT_OFFSET_EBP  0x14
+#define __CONTEXT_OFFSET_TLS  0x18
+#define __CONTEXT_SIZE        0x1c
 
 #ifndef __ASSEMBLER__
@@ -44,5 +44,5 @@
 
 /* We include only registers that must be preserved during function call. */
-typedef struct context {
+typedef struct __context {
 	uint32_t sp;
 	uint32_t pc;
@@ -52,5 +52,5 @@
 	uint32_t ebp;
 	uint32_t tls;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/ia32/include/libarch/rtld/dynamic.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/rtld/dynamic.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_RTLD_DYNAMIC_H_
-#define LIBC_ia32_RTLD_DYNAMIC_H_
+#ifndef _LIBC_ia32_RTLD_DYNAMIC_H_
+#define _LIBC_ia32_RTLD_DYNAMIC_H_
 
 typedef struct {
Index: uspace/lib/c/arch/ia32/include/libarch/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/rtld/elf_dyn.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_RTLD_ELF_DYN_H_
-#define LIBC_ia32_RTLD_ELF_DYN_H_
+#ifndef _LIBC_ia32_RTLD_ELF_DYN_H_
+#define _LIBC_ia32_RTLD_ELF_DYN_H_
 
 /*
Index: uspace/lib/c/arch/ia32/include/libarch/rtld/module.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ia32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_ia32_RTLD_MODULE_H_
+#define _LIBC_ia32_RTLD_MODULE_H_
+
+#include <elf/elf_mod.h>
+
+/** ELF module load flags.
+ *
+ * Keep code segment read-write
+ */
+#define RTLD_MODULE_LDF ELDF_RW
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/ia32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_ia32_SYSCALL_H_
-#define LIBC_ia32_SYSCALL_H_
+#ifndef _LIBC_ia32_SYSCALL_H_
+#define _LIBC_ia32_SYSCALL_H_
 
 #include <abi/syscall.h>
Index: uspace/lib/c/arch/ia32/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_THREAD_H_
-#define LIBC_ia32_THREAD_H_
+#ifndef _LIBC_ia32_THREAD_H_
+#define _LIBC_ia32_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/ia32/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/ia32/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia32_TLS_H_
-#define LIBC_ia32_TLS_H_
+#ifndef _LIBC_ia32_TLS_H_
+#define _LIBC_ia32_TLS_H_
 
 #define CONFIG_TLS_VARIANT_2
Index: uspace/lib/c/arch/ia32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/ia32/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia32/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,23 +37,23 @@
 # pointed by the 1st argument. Returns 0 in EAX.
 #
-FUNCTION_BEGIN(__setjmp)
+FUNCTION_BEGIN(__context_save)
 	movl 0(%esp), %eax  # the caller's return %eip
 	movl 4(%esp), %edx  # address of the context variable to save context to
 
 	# save registers to the context structure
-	movl %esp, CONTEXT_OFFSET_SP(%edx)	# %esp -> ctx->sp
-	movl %eax, CONTEXT_OFFSET_PC(%edx)	# %eip -> ctx->pc
-	movl %ebx, CONTEXT_OFFSET_EBX(%edx)	# %ebx -> ctx->ebx
-	movl %esi, CONTEXT_OFFSET_ESI(%edx)	# %esi -> ctx->esi
-	movl %edi, CONTEXT_OFFSET_EDI(%edx)	# %edi -> ctx->edi
-	movl %ebp, CONTEXT_OFFSET_EBP(%edx)	# %ebp -> ctx->ebp
+	movl %esp, __CONTEXT_OFFSET_SP(%edx)	# %esp -> ctx->sp
+	movl %eax, __CONTEXT_OFFSET_PC(%edx)	# %eip -> ctx->pc
+	movl %ebx, __CONTEXT_OFFSET_EBX(%edx)	# %ebx -> ctx->ebx
+	movl %esi, __CONTEXT_OFFSET_ESI(%edx)	# %esi -> ctx->esi
+	movl %edi, __CONTEXT_OFFSET_EDI(%edx)	# %edi -> ctx->edi
+	movl %ebp, __CONTEXT_OFFSET_EBP(%edx)	# %ebp -> ctx->ebp
 
 	# save TLS
 	movl %gs:0, %eax
-	movl %eax, CONTEXT_OFFSET_TLS(%edx)	# tls -> ctx->tls
+	movl %eax, __CONTEXT_OFFSET_TLS(%edx)	# tls -> ctx->tls
 
-	xorl %eax, %eax		# __setjmp returns 0
+	xorl %eax, %eax		# __context_save returns 0
 	ret
-FUNCTION_END(__setjmp)
+FUNCTION_END(__context_save)
 
 ## Restore saved CPU context
@@ -62,24 +62,24 @@
 # pointed by the 1st argument. Returns second argument in EAX.
 #
-FUNCTION_BEGIN(__longjmp)
+FUNCTION_BEGIN(__context_restore)
 	movl 4(%esp), %eax  # address of the context variable to restore context from
 	movl 8(%esp), %ecx  # return value
 
 	# restore registers from the context structure
-	movl CONTEXT_OFFSET_SP(%eax),%esp	# ctx->sp -> %esp
-	movl CONTEXT_OFFSET_PC(%eax),%edx	# ctx->pc -> \pc
-	movl CONTEXT_OFFSET_EBX(%eax),%ebx	# ctx->ebx -> %ebx
-	movl CONTEXT_OFFSET_ESI(%eax),%esi	# ctx->esi -> %esi
-	movl CONTEXT_OFFSET_EDI(%eax),%edi	# ctx->edi -> %edi
-	movl CONTEXT_OFFSET_EBP(%eax),%ebp	# ctx->ebp -> %ebp
+	movl __CONTEXT_OFFSET_SP(%eax),%esp	# ctx->sp -> %esp
+	movl __CONTEXT_OFFSET_PC(%eax),%edx	# ctx->pc -> \pc
+	movl __CONTEXT_OFFSET_EBX(%eax),%ebx	# ctx->ebx -> %ebx
+	movl __CONTEXT_OFFSET_ESI(%eax),%esi	# ctx->esi -> %esi
+	movl __CONTEXT_OFFSET_EDI(%eax),%edi	# ctx->edi -> %edi
+	movl __CONTEXT_OFFSET_EBP(%eax),%ebp	# ctx->ebp -> %ebp
 
 	movl %edx, 0(%esp)  # ctx->pc -> saver's return %eip
 
 	# set thread local storage
-	movl CONTEXT_OFFSET_TLS(%eax), %edx	# Set arg1 to TLS addr
+	movl __CONTEXT_OFFSET_TLS(%eax), %edx	# Set arg1 to TLS addr
 	movl %edx, %gs:0
 
 	movl %ecx, %eax
 	ret
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
 
Index: uspace/lib/c/arch/ia64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_CONFIG_H_
-#define LIBC_ia64_CONFIG_H_
+#ifndef _LIBC_ia64_CONFIG_H_
+#define _LIBC_ia64_CONFIG_H_
 
 #define PAGE_WIDTH	14
Index: uspace/lib/c/arch/ia64/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_DDI_H_
-#define LIBC_ia64_DDI_H_
+#ifndef _LIBC_ia64_DDI_H_
+#define _LIBC_ia64_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/ia64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_ELF_LINUX_H_
-#define LIBC_ia64_ELF_LINUX_H_
+#ifndef _LIBC_ia64_ELF_LINUX_H_
+#define _LIBC_ia64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/ia64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_FADDR_H_
-#define LIBC_ia64_FADDR_H_
+#ifndef _LIBC_ia64_FADDR_H_
+#define _LIBC_ia64_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/ia64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_FIBRIL_H_
-#define LIBC_ia64_FIBRIL_H_
+#ifndef _LIBC_ia64_FIBRIL_H_
+#define _LIBC_ia64_FIBRIL_H_
 
 #include <stdint.h>
@@ -43,5 +43,5 @@
 
 /*
- * __setjmp() and __longjmp() are both leaf procedures.
+ * __context_save() and __context_restore() are both leaf procedures.
  * No need to allocate scratch area.
  */
Index: uspace/lib/c/arch/ia64/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,49 +27,49 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_AR_PFS          0x000
-#define CONTEXT_OFFSET_AR_UNAT_CALLER  0x008
-#define CONTEXT_OFFSET_AR_UNAT_CALLEE  0x010
-#define CONTEXT_OFFSET_AR_RSC          0x018
-#define CONTEXT_OFFSET_BSP             0x020
-#define CONTEXT_OFFSET_AR_RNAT         0x028
-#define CONTEXT_OFFSET_AR_LC           0x030
-#define CONTEXT_OFFSET_R1              0x038
-#define CONTEXT_OFFSET_R4              0x040
-#define CONTEXT_OFFSET_R5              0x048
-#define CONTEXT_OFFSET_R6              0x050
-#define CONTEXT_OFFSET_R7              0x058
-#define CONTEXT_OFFSET_SP              0x060
-#define CONTEXT_OFFSET_TP              0x068
-#define CONTEXT_OFFSET_PC              0x070
-#define CONTEXT_OFFSET_B1              0x078
-#define CONTEXT_OFFSET_B2              0x080
-#define CONTEXT_OFFSET_B3              0x088
-#define CONTEXT_OFFSET_B4              0x090
-#define CONTEXT_OFFSET_B5              0x098
-#define CONTEXT_OFFSET_PR              0x0a0
-#define CONTEXT_OFFSET_F2              0x0b0
-#define CONTEXT_OFFSET_F3              0x0c0
-#define CONTEXT_OFFSET_F4              0x0d0
-#define CONTEXT_OFFSET_F5              0x0e0
-#define CONTEXT_OFFSET_F16             0x0f0
-#define CONTEXT_OFFSET_F17             0x100
-#define CONTEXT_OFFSET_F18             0x110
-#define CONTEXT_OFFSET_F19             0x120
-#define CONTEXT_OFFSET_F20             0x130
-#define CONTEXT_OFFSET_F21             0x140
-#define CONTEXT_OFFSET_F22             0x150
-#define CONTEXT_OFFSET_F23             0x160
-#define CONTEXT_OFFSET_F24             0x170
-#define CONTEXT_OFFSET_F25             0x180
-#define CONTEXT_OFFSET_F26             0x190
-#define CONTEXT_OFFSET_F27             0x1a0
-#define CONTEXT_OFFSET_F28             0x1b0
-#define CONTEXT_OFFSET_F29             0x1c0
-#define CONTEXT_OFFSET_F30             0x1d0
-#define CONTEXT_OFFSET_F31             0x1e0
-#define CONTEXT_SIZE                   0x1f0
+#define __CONTEXT_OFFSET_AR_PFS          0x000
+#define __CONTEXT_OFFSET_AR_UNAT_CALLER  0x008
+#define __CONTEXT_OFFSET_AR_UNAT_CALLEE  0x010
+#define __CONTEXT_OFFSET_AR_RSC          0x018
+#define __CONTEXT_OFFSET_BSP             0x020
+#define __CONTEXT_OFFSET_AR_RNAT         0x028
+#define __CONTEXT_OFFSET_AR_LC           0x030
+#define __CONTEXT_OFFSET_R1              0x038
+#define __CONTEXT_OFFSET_R4              0x040
+#define __CONTEXT_OFFSET_R5              0x048
+#define __CONTEXT_OFFSET_R6              0x050
+#define __CONTEXT_OFFSET_R7              0x058
+#define __CONTEXT_OFFSET_SP              0x060
+#define __CONTEXT_OFFSET_TP              0x068
+#define __CONTEXT_OFFSET_PC              0x070
+#define __CONTEXT_OFFSET_B1              0x078
+#define __CONTEXT_OFFSET_B2              0x080
+#define __CONTEXT_OFFSET_B3              0x088
+#define __CONTEXT_OFFSET_B4              0x090
+#define __CONTEXT_OFFSET_B5              0x098
+#define __CONTEXT_OFFSET_PR              0x0a0
+#define __CONTEXT_OFFSET_F2              0x0b0
+#define __CONTEXT_OFFSET_F3              0x0c0
+#define __CONTEXT_OFFSET_F4              0x0d0
+#define __CONTEXT_OFFSET_F5              0x0e0
+#define __CONTEXT_OFFSET_F16             0x0f0
+#define __CONTEXT_OFFSET_F17             0x100
+#define __CONTEXT_OFFSET_F18             0x110
+#define __CONTEXT_OFFSET_F19             0x120
+#define __CONTEXT_OFFSET_F20             0x130
+#define __CONTEXT_OFFSET_F21             0x140
+#define __CONTEXT_OFFSET_F22             0x150
+#define __CONTEXT_OFFSET_F23             0x160
+#define __CONTEXT_OFFSET_F24             0x170
+#define __CONTEXT_OFFSET_F25             0x180
+#define __CONTEXT_OFFSET_F26             0x190
+#define __CONTEXT_OFFSET_F27             0x1a0
+#define __CONTEXT_OFFSET_F28             0x1b0
+#define __CONTEXT_OFFSET_F29             0x1c0
+#define __CONTEXT_OFFSET_F30             0x1d0
+#define __CONTEXT_OFFSET_F31             0x1e0
+#define __CONTEXT_SIZE                   0x1f0
 
 #ifndef __ASSEMBLER__
@@ -79,5 +79,5 @@
 
 // Only save registers that must be preserved across function calls.
-typedef struct context {
+typedef struct __context {
 	// Application registers.
 	uint64_t ar_pfs;
@@ -132,5 +132,5 @@
 	uint128_t f30;
 	uint128_t f31;
-} context_t;
+} __context_t;
 
 #endif  /* __ASSEMBLER__ */
Index: uspace/lib/c/arch/ia64/include/libarch/stack.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/stack.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/stack.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_STACK_H_
-#define LIBC_ia64_STACK_H_
+#ifndef _LIBC_ia64_STACK_H_
+#define _LIBC_ia64_STACK_H_
 
 #define STACK_ITEM_SIZE			8
Index: uspace/lib/c/arch/ia64/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/stackarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/stackarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STACKARG_H_
-#define LIBC_STACKARG_H_
+#ifndef _LIBC_STACKARG_H_
+#define _LIBC_STACKARG_H_
 
 #endif
Index: uspace/lib/c/arch/ia64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_ia64_SYSCALL_H_
-#define LIBC_ia64_SYSCALL_H_
+#ifndef _LIBC_ia64_SYSCALL_H_
+#define _LIBC_ia64_SYSCALL_H_
 
 #define LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/arch/ia64/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_THREAD_H_
-#define LIBC_ia64_THREAD_H_
+#ifndef _LIBC_ia64_THREAD_H_
+#define _LIBC_ia64_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/ia64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/ia64/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ia64_TLS_H_
-#define LIBC_ia64_TLS_H_
+#ifndef _LIBC_ia64_TLS_H_
+#define _LIBC_ia64_TLS_H_
 
 #define CONFIG_TLS_VARIANT_1
Index: uspace/lib/c/arch/ia64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/ia64/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ia64/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,5 +32,5 @@
 .text
 
-FUNCTION_BEGIN(__setjmp)
+FUNCTION_BEGIN(__context_save)
 	alloc loc0 = ar.pfs, 1, 49, 0, 0
 	mov loc1 = ar.unat ;;
@@ -58,50 +58,50 @@
 	mov loc6 = ar.lc
 
-	add loc8 = CONTEXT_OFFSET_AR_PFS, in0
-	add loc9 = CONTEXT_OFFSET_AR_UNAT_CALLER, in0
-	add loc10 = CONTEXT_OFFSET_AR_UNAT_CALLEE, in0
-	add loc11 = CONTEXT_OFFSET_AR_RSC, in0
-	add loc12 = CONTEXT_OFFSET_BSP, in0
-	add loc13 = CONTEXT_OFFSET_AR_RNAT, in0
-	add loc14 = CONTEXT_OFFSET_AR_LC, in0
-
-	add loc15 = CONTEXT_OFFSET_R1, in0
-	add loc16 = CONTEXT_OFFSET_R4, in0
-	add loc17 = CONTEXT_OFFSET_R5, in0
-	add loc18 = CONTEXT_OFFSET_R6, in0
-	add loc19 = CONTEXT_OFFSET_R7, in0
-	add loc20 = CONTEXT_OFFSET_SP, in0
-	add loc21 = CONTEXT_OFFSET_TP, in0
-
-	add loc22 = CONTEXT_OFFSET_PC, in0
-	add loc23 = CONTEXT_OFFSET_B1, in0
-	add loc24 = CONTEXT_OFFSET_B2, in0
-	add loc25 = CONTEXT_OFFSET_B3, in0
-	add loc26 = CONTEXT_OFFSET_B4, in0
-	add loc27 = CONTEXT_OFFSET_B5, in0
-
-	add loc28 = CONTEXT_OFFSET_PR, in0
-
-	add loc29 = CONTEXT_OFFSET_F2, in0
-	add loc30 = CONTEXT_OFFSET_F3, in0
-	add loc31 = CONTEXT_OFFSET_F4, in0
-	add loc32 = CONTEXT_OFFSET_F5, in0
-
-	add loc33 = CONTEXT_OFFSET_F16, in0
-	add loc34 = CONTEXT_OFFSET_F17, in0
-	add loc35 = CONTEXT_OFFSET_F18, in0
-	add loc36 = CONTEXT_OFFSET_F19, in0
-	add loc37 = CONTEXT_OFFSET_F20, in0
-	add loc38 = CONTEXT_OFFSET_F21, in0
-	add loc39 = CONTEXT_OFFSET_F22, in0
-	add loc40 = CONTEXT_OFFSET_F23, in0
-	add loc41 = CONTEXT_OFFSET_F24, in0
-	add loc42 = CONTEXT_OFFSET_F25, in0
-	add loc43 = CONTEXT_OFFSET_F26, in0
-	add loc44 = CONTEXT_OFFSET_F27, in0
-	add loc45 = CONTEXT_OFFSET_F28, in0
-	add loc46 = CONTEXT_OFFSET_F29, in0
-	add loc47 = CONTEXT_OFFSET_F30, in0
-	add loc48 = CONTEXT_OFFSET_F31, in0 ;;
+	add loc8 = __CONTEXT_OFFSET_AR_PFS, in0
+	add loc9 = __CONTEXT_OFFSET_AR_UNAT_CALLER, in0
+	add loc10 = __CONTEXT_OFFSET_AR_UNAT_CALLEE, in0
+	add loc11 = __CONTEXT_OFFSET_AR_RSC, in0
+	add loc12 = __CONTEXT_OFFSET_BSP, in0
+	add loc13 = __CONTEXT_OFFSET_AR_RNAT, in0
+	add loc14 = __CONTEXT_OFFSET_AR_LC, in0
+
+	add loc15 = __CONTEXT_OFFSET_R1, in0
+	add loc16 = __CONTEXT_OFFSET_R4, in0
+	add loc17 = __CONTEXT_OFFSET_R5, in0
+	add loc18 = __CONTEXT_OFFSET_R6, in0
+	add loc19 = __CONTEXT_OFFSET_R7, in0
+	add loc20 = __CONTEXT_OFFSET_SP, in0
+	add loc21 = __CONTEXT_OFFSET_TP, in0
+
+	add loc22 = __CONTEXT_OFFSET_PC, in0
+	add loc23 = __CONTEXT_OFFSET_B1, in0
+	add loc24 = __CONTEXT_OFFSET_B2, in0
+	add loc25 = __CONTEXT_OFFSET_B3, in0
+	add loc26 = __CONTEXT_OFFSET_B4, in0
+	add loc27 = __CONTEXT_OFFSET_B5, in0
+
+	add loc28 = __CONTEXT_OFFSET_PR, in0
+
+	add loc29 = __CONTEXT_OFFSET_F2, in0
+	add loc30 = __CONTEXT_OFFSET_F3, in0
+	add loc31 = __CONTEXT_OFFSET_F4, in0
+	add loc32 = __CONTEXT_OFFSET_F5, in0
+
+	add loc33 = __CONTEXT_OFFSET_F16, in0
+	add loc34 = __CONTEXT_OFFSET_F17, in0
+	add loc35 = __CONTEXT_OFFSET_F18, in0
+	add loc36 = __CONTEXT_OFFSET_F19, in0
+	add loc37 = __CONTEXT_OFFSET_F20, in0
+	add loc38 = __CONTEXT_OFFSET_F21, in0
+	add loc39 = __CONTEXT_OFFSET_F22, in0
+	add loc40 = __CONTEXT_OFFSET_F23, in0
+	add loc41 = __CONTEXT_OFFSET_F24, in0
+	add loc42 = __CONTEXT_OFFSET_F25, in0
+	add loc43 = __CONTEXT_OFFSET_F26, in0
+	add loc44 = __CONTEXT_OFFSET_F27, in0
+	add loc45 = __CONTEXT_OFFSET_F28, in0
+	add loc46 = __CONTEXT_OFFSET_F29, in0
+	add loc47 = __CONTEXT_OFFSET_F30, in0
+	add loc48 = __CONTEXT_OFFSET_F31, in0 ;;
 
 	/*
@@ -178,57 +178,57 @@
 	mov ar.unat = loc1
 
-	mov r8 = 0 	/* __setjmp returns 0 */
+	mov r8 = 0 	/* __context_save returns 0 */
 	br.ret.sptk.many b0
-FUNCTION_END(__setjmp)
-
-FUNCTION_BEGIN(__longjmp)
+FUNCTION_END(__context_save)
+
+FUNCTION_BEGIN(__context_restore)
 	alloc loc0 = ar.pfs, 2, 50, 0, 0 ;;
 
-	add loc9 = CONTEXT_OFFSET_AR_PFS, in0
-	add loc10 = CONTEXT_OFFSET_AR_UNAT_CALLER, in0
-	add loc11 = CONTEXT_OFFSET_AR_UNAT_CALLEE, in0
-	add loc12 = CONTEXT_OFFSET_AR_RSC, in0
-	add loc13 = CONTEXT_OFFSET_BSP, in0
-	add loc14 = CONTEXT_OFFSET_AR_RNAT, in0
-	add loc15 = CONTEXT_OFFSET_AR_LC, in0
-
-	add loc16 = CONTEXT_OFFSET_R1, in0
-	add loc17 = CONTEXT_OFFSET_R4, in0
-	add loc18 = CONTEXT_OFFSET_R5, in0
-	add loc19 = CONTEXT_OFFSET_R6, in0
-	add loc20 = CONTEXT_OFFSET_R7, in0
-	add loc21 = CONTEXT_OFFSET_SP, in0
-	add loc22 = CONTEXT_OFFSET_TP, in0
-
-	add loc23 = CONTEXT_OFFSET_PC, in0
-	add loc24 = CONTEXT_OFFSET_B1, in0
-	add loc25 = CONTEXT_OFFSET_B2, in0
-	add loc26 = CONTEXT_OFFSET_B3, in0
-	add loc27 = CONTEXT_OFFSET_B4, in0
-	add loc28 = CONTEXT_OFFSET_B5, in0
-
-	add loc29 = CONTEXT_OFFSET_PR, in0
-
-	add loc30 = CONTEXT_OFFSET_F2, in0
-	add loc31 = CONTEXT_OFFSET_F3, in0
-	add loc32 = CONTEXT_OFFSET_F4, in0
-	add loc33 = CONTEXT_OFFSET_F5, in0
-
-	add loc34 = CONTEXT_OFFSET_F16, in0
-	add loc35 = CONTEXT_OFFSET_F17, in0
-	add loc36 = CONTEXT_OFFSET_F18, in0
-	add loc37 = CONTEXT_OFFSET_F19, in0
-	add loc38 = CONTEXT_OFFSET_F20, in0
-	add loc39 = CONTEXT_OFFSET_F21, in0
-	add loc40 = CONTEXT_OFFSET_F22, in0
-	add loc41 = CONTEXT_OFFSET_F23, in0
-	add loc42 = CONTEXT_OFFSET_F24, in0
-	add loc43 = CONTEXT_OFFSET_F25, in0
-	add loc44 = CONTEXT_OFFSET_F26, in0
-	add loc45 = CONTEXT_OFFSET_F27, in0
-	add loc46 = CONTEXT_OFFSET_F28, in0
-	add loc47 = CONTEXT_OFFSET_F29, in0
-	add loc48 = CONTEXT_OFFSET_F30, in0
-	add loc49 = CONTEXT_OFFSET_F31, in0 ;;
+	add loc9 = __CONTEXT_OFFSET_AR_PFS, in0
+	add loc10 = __CONTEXT_OFFSET_AR_UNAT_CALLER, in0
+	add loc11 = __CONTEXT_OFFSET_AR_UNAT_CALLEE, in0
+	add loc12 = __CONTEXT_OFFSET_AR_RSC, in0
+	add loc13 = __CONTEXT_OFFSET_BSP, in0
+	add loc14 = __CONTEXT_OFFSET_AR_RNAT, in0
+	add loc15 = __CONTEXT_OFFSET_AR_LC, in0
+
+	add loc16 = __CONTEXT_OFFSET_R1, in0
+	add loc17 = __CONTEXT_OFFSET_R4, in0
+	add loc18 = __CONTEXT_OFFSET_R5, in0
+	add loc19 = __CONTEXT_OFFSET_R6, in0
+	add loc20 = __CONTEXT_OFFSET_R7, in0
+	add loc21 = __CONTEXT_OFFSET_SP, in0
+	add loc22 = __CONTEXT_OFFSET_TP, in0
+
+	add loc23 = __CONTEXT_OFFSET_PC, in0
+	add loc24 = __CONTEXT_OFFSET_B1, in0
+	add loc25 = __CONTEXT_OFFSET_B2, in0
+	add loc26 = __CONTEXT_OFFSET_B3, in0
+	add loc27 = __CONTEXT_OFFSET_B4, in0
+	add loc28 = __CONTEXT_OFFSET_B5, in0
+
+	add loc29 = __CONTEXT_OFFSET_PR, in0
+
+	add loc30 = __CONTEXT_OFFSET_F2, in0
+	add loc31 = __CONTEXT_OFFSET_F3, in0
+	add loc32 = __CONTEXT_OFFSET_F4, in0
+	add loc33 = __CONTEXT_OFFSET_F5, in0
+
+	add loc34 = __CONTEXT_OFFSET_F16, in0
+	add loc35 = __CONTEXT_OFFSET_F17, in0
+	add loc36 = __CONTEXT_OFFSET_F18, in0
+	add loc37 = __CONTEXT_OFFSET_F19, in0
+	add loc38 = __CONTEXT_OFFSET_F20, in0
+	add loc39 = __CONTEXT_OFFSET_F21, in0
+	add loc40 = __CONTEXT_OFFSET_F22, in0
+	add loc41 = __CONTEXT_OFFSET_F23, in0
+	add loc42 = __CONTEXT_OFFSET_F24, in0
+	add loc43 = __CONTEXT_OFFSET_F25, in0
+	add loc44 = __CONTEXT_OFFSET_F26, in0
+	add loc45 = __CONTEXT_OFFSET_F27, in0
+	add loc46 = __CONTEXT_OFFSET_F28, in0
+	add loc47 = __CONTEXT_OFFSET_F29, in0
+	add loc48 = __CONTEXT_OFFSET_F30, in0
+	add loc49 = __CONTEXT_OFFSET_F31, in0 ;;
 
 	ld8 loc0 = [loc9]	/* load ar.pfs */
@@ -335,5 +335,5 @@
 	mov ar.unat = loc1
 
-	mov r8 = in1			/* __longjmp returns second argument */
+	mov r8 = in1			/* __context_restore returns second argument */
 	br.ret.sptk.many b0
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
Index: uspace/lib/c/arch/mips32/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_mips32_CONFIG_H_
-#define LIBC_mips32_CONFIG_H_
+#ifndef _LIBC_mips32_CONFIG_H_
+#define _LIBC_mips32_CONFIG_H_
 
 #define PAGE_WIDTH  14
Index: uspace/lib/c/arch/mips32/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_mips32_DDI_H_
-#define LIBC_mips32_DDI_H_
+#ifndef _LIBC_mips32_DDI_H_
+#define _LIBC_mips32_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/mips32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_mips32_ELF_LINUX_H_
-#define LIBC_mips32_ELF_LINUX_H_
+#ifndef _LIBC_mips32_ELF_LINUX_H_
+#define _LIBC_mips32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/mips32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_mips32_FADDR_H_
-#define LIBC_mips32_FADDR_H_
+#ifndef _LIBC_mips32_FADDR_H_
+#define _LIBC_mips32_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/mips32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_mips32_FIBRIL_H_
-#define LIBC_mips32_FIBRIL_H_
+#ifndef _LIBC_mips32_FIBRIL_H_
+#define _LIBC_mips32_FIBRIL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/mips32/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,32 +27,32 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP   0x00
-#define CONTEXT_OFFSET_PC   0x04
-#define CONTEXT_OFFSET_S0   0x08
-#define CONTEXT_OFFSET_S1   0x0c
-#define CONTEXT_OFFSET_S2   0x10
-#define CONTEXT_OFFSET_S3   0x14
-#define CONTEXT_OFFSET_S4   0x18
-#define CONTEXT_OFFSET_S5   0x1c
-#define CONTEXT_OFFSET_S6   0x20
-#define CONTEXT_OFFSET_S7   0x24
-#define CONTEXT_OFFSET_S8   0x28
-#define CONTEXT_OFFSET_GP   0x2c
-#define CONTEXT_OFFSET_TLS  0x30
-#define CONTEXT_OFFSET_F20  0x34
-#define CONTEXT_OFFSET_F21  0x38
-#define CONTEXT_OFFSET_F22  0x3c
-#define CONTEXT_OFFSET_F23  0x40
-#define CONTEXT_OFFSET_F24  0x44
-#define CONTEXT_OFFSET_F25  0x48
-#define CONTEXT_OFFSET_F26  0x4c
-#define CONTEXT_OFFSET_F27  0x50
-#define CONTEXT_OFFSET_F28  0x54
-#define CONTEXT_OFFSET_F29  0x58
-#define CONTEXT_OFFSET_F30  0x5c
-#define CONTEXT_SIZE        0x60
+#define __CONTEXT_OFFSET_SP   0x00
+#define __CONTEXT_OFFSET_PC   0x04
+#define __CONTEXT_OFFSET_S0   0x08
+#define __CONTEXT_OFFSET_S1   0x0c
+#define __CONTEXT_OFFSET_S2   0x10
+#define __CONTEXT_OFFSET_S3   0x14
+#define __CONTEXT_OFFSET_S4   0x18
+#define __CONTEXT_OFFSET_S5   0x1c
+#define __CONTEXT_OFFSET_S6   0x20
+#define __CONTEXT_OFFSET_S7   0x24
+#define __CONTEXT_OFFSET_S8   0x28
+#define __CONTEXT_OFFSET_GP   0x2c
+#define __CONTEXT_OFFSET_TLS  0x30
+#define __CONTEXT_OFFSET_F20  0x34
+#define __CONTEXT_OFFSET_F21  0x38
+#define __CONTEXT_OFFSET_F22  0x3c
+#define __CONTEXT_OFFSET_F23  0x40
+#define __CONTEXT_OFFSET_F24  0x44
+#define __CONTEXT_OFFSET_F25  0x48
+#define __CONTEXT_OFFSET_F26  0x4c
+#define __CONTEXT_OFFSET_F27  0x50
+#define __CONTEXT_OFFSET_F28  0x54
+#define __CONTEXT_OFFSET_F29  0x58
+#define __CONTEXT_OFFSET_F30  0x5c
+#define __CONTEXT_SIZE        0x60
 
 #ifndef __ASSEMBLER__
@@ -61,5 +61,5 @@
 #include <stdint.h>
 
-typedef struct context {
+typedef struct __context {
 	uint32_t sp;
 	uint32_t pc;
@@ -87,5 +87,5 @@
 	uint32_t f29;
 	uint32_t f30;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/mips32/include/libarch/stack.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/stack.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/stack.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_mips32_STACK_H_
-#define LIBC_mips32_STACK_H_
+#ifndef _LIBC_mips32_STACK_H_
+#define _LIBC_mips32_STACK_H_
 
 #define STACK_ITEM_SIZE  4
Index: uspace/lib/c/arch/mips32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_mips32_SYSCALL_H_
-#define LIBC_mips32_SYSCALL_H_
+#ifndef _LIBC_mips32_SYSCALL_H_
+#define _LIBC_mips32_SYSCALL_H_
 
 #define LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/arch/mips32/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_mips32_THREAD_H_
-#define LIBC_mips32_THREAD_H_
+#ifndef _LIBC_mips32_THREAD_H_
+#define _LIBC_mips32_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/mips32/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/mips32/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,6 +36,6 @@
 /* TLS for MIPS is described in http://www.linux-mips.org/wiki/NPTL */
 
-#ifndef LIBC_mips32_TLS_H_
-#define LIBC_mips32_TLS_H_
+#ifndef _LIBC_mips32_TLS_H_
+#define _LIBC_mips32_TLS_H_
 
 /*
Index: uspace/lib/c/arch/mips32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/mips32/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,111 +35,111 @@
 #include <libarch/fibril_context.h>
 
-FUNCTION_BEGIN(__setjmp)
-	sw $s0, CONTEXT_OFFSET_S0($a0)
-	sw $s1, CONTEXT_OFFSET_S1($a0)
-	sw $s2, CONTEXT_OFFSET_S2($a0)
-	sw $s3, CONTEXT_OFFSET_S3($a0)
-	sw $s4, CONTEXT_OFFSET_S4($a0)
-	sw $s5, CONTEXT_OFFSET_S5($a0)
-	sw $s6, CONTEXT_OFFSET_S6($a0)
-	sw $s7, CONTEXT_OFFSET_S7($a0)
-	sw $s8, CONTEXT_OFFSET_S8($a0)
-	sw $gp, CONTEXT_OFFSET_GP($a0)
+FUNCTION_BEGIN(__context_save)
+	sw $s0, __CONTEXT_OFFSET_S0($a0)
+	sw $s1, __CONTEXT_OFFSET_S1($a0)
+	sw $s2, __CONTEXT_OFFSET_S2($a0)
+	sw $s3, __CONTEXT_OFFSET_S3($a0)
+	sw $s4, __CONTEXT_OFFSET_S4($a0)
+	sw $s5, __CONTEXT_OFFSET_S5($a0)
+	sw $s6, __CONTEXT_OFFSET_S6($a0)
+	sw $s7, __CONTEXT_OFFSET_S7($a0)
+	sw $s8, __CONTEXT_OFFSET_S8($a0)
+	sw $gp, __CONTEXT_OFFSET_GP($a0)
 
-	sw $k1, CONTEXT_OFFSET_TLS($a0)
+	sw $k1, __CONTEXT_OFFSET_TLS($a0)
 
 #ifdef CONFIG_FPU
 	mfc1 $t0, $20
-	sw $t0, CONTEXT_OFFSET_F20($a0)
+	sw $t0, __CONTEXT_OFFSET_F20($a0)
 
 	mfc1 $t0, $21
-	sw $t0, CONTEXT_OFFSET_F21($a0)
+	sw $t0, __CONTEXT_OFFSET_F21($a0)
 
 	mfc1 $t0, $22
-	sw $t0, CONTEXT_OFFSET_F22($a0)
+	sw $t0, __CONTEXT_OFFSET_F22($a0)
 
 	mfc1 $t0, $23
-	sw $t0, CONTEXT_OFFSET_F23($a0)
+	sw $t0, __CONTEXT_OFFSET_F23($a0)
 
 	mfc1 $t0, $24
-	sw $t0, CONTEXT_OFFSET_F24($a0)
+	sw $t0, __CONTEXT_OFFSET_F24($a0)
 
 	mfc1 $t0, $25
-	sw $t0, CONTEXT_OFFSET_F25($a0)
+	sw $t0, __CONTEXT_OFFSET_F25($a0)
 
 	mfc1 $t0, $26
-	sw $t0, CONTEXT_OFFSET_F26($a0)
+	sw $t0, __CONTEXT_OFFSET_F26($a0)
 
 	mfc1 $t0, $27
-	sw $t0, CONTEXT_OFFSET_F27($a0)
+	sw $t0, __CONTEXT_OFFSET_F27($a0)
 
 	mfc1 $t0, $28
-	sw $t0, CONTEXT_OFFSET_F28($a0)
+	sw $t0, __CONTEXT_OFFSET_F28($a0)
 
 	mfc1 $t0, $29
-	sw $t0, CONTEXT_OFFSET_F29($a0)
+	sw $t0, __CONTEXT_OFFSET_F29($a0)
 
 	mfc1 $t0, $30
-	sw $t0, CONTEXT_OFFSET_F30($a0)
+	sw $t0, __CONTEXT_OFFSET_F30($a0)
 #endif /* CONFIG_FPU */
 
-	sw $ra, CONTEXT_OFFSET_PC($a0)
-	sw $sp, CONTEXT_OFFSET_SP($a0)
+	sw $ra, __CONTEXT_OFFSET_PC($a0)
+	sw $sp, __CONTEXT_OFFSET_SP($a0)
 
-	# __setjmp returns 0
+	# __context_save returns 0
 	j $ra
 	li $v0, 0
-FUNCTION_END(__setjmp)
+FUNCTION_END(__context_save)
 
-FUNCTION_BEGIN(__longjmp)
-	lw $s0, CONTEXT_OFFSET_S0($a0)
-	lw $s1, CONTEXT_OFFSET_S1($a0)
-	lw $s2, CONTEXT_OFFSET_S2($a0)
-	lw $s3, CONTEXT_OFFSET_S3($a0)
-	lw $s4, CONTEXT_OFFSET_S4($a0)
-	lw $s5, CONTEXT_OFFSET_S5($a0)
-	lw $s6, CONTEXT_OFFSET_S6($a0)
-	lw $s7, CONTEXT_OFFSET_S7($a0)
-	lw $s8, CONTEXT_OFFSET_S8($a0)
-	lw $gp, CONTEXT_OFFSET_GP($a0)
-	lw $k1, CONTEXT_OFFSET_TLS($a0)
+FUNCTION_BEGIN(__context_restore)
+	lw $s0, __CONTEXT_OFFSET_S0($a0)
+	lw $s1, __CONTEXT_OFFSET_S1($a0)
+	lw $s2, __CONTEXT_OFFSET_S2($a0)
+	lw $s3, __CONTEXT_OFFSET_S3($a0)
+	lw $s4, __CONTEXT_OFFSET_S4($a0)
+	lw $s5, __CONTEXT_OFFSET_S5($a0)
+	lw $s6, __CONTEXT_OFFSET_S6($a0)
+	lw $s7, __CONTEXT_OFFSET_S7($a0)
+	lw $s8, __CONTEXT_OFFSET_S8($a0)
+	lw $gp, __CONTEXT_OFFSET_GP($a0)
+	lw $k1, __CONTEXT_OFFSET_TLS($a0)
 
 #ifdef CONFIG_FPU
-	lw $t0, CONTEXT_OFFSET_F20($a0)
+	lw $t0, __CONTEXT_OFFSET_F20($a0)
 	mtc1 $t0, $20
 
-	lw $t0, CONTEXT_OFFSET_F21($a0)
+	lw $t0, __CONTEXT_OFFSET_F21($a0)
 	mtc1 $t0, $21
 
-	lw $t0, CONTEXT_OFFSET_F22($a0)
+	lw $t0, __CONTEXT_OFFSET_F22($a0)
 	mtc1 $t0, $22
 
-	lw $t0, CONTEXT_OFFSET_F23($a0)
+	lw $t0, __CONTEXT_OFFSET_F23($a0)
 	mtc1 $t0, $23
 
-	lw $t0, CONTEXT_OFFSET_F24($a0)
+	lw $t0, __CONTEXT_OFFSET_F24($a0)
 	mtc1 $t0, $24
 
-	lw $t0, CONTEXT_OFFSET_F25($a0)
+	lw $t0, __CONTEXT_OFFSET_F25($a0)
 	mtc1 $t0, $25
 
-	lw $t0, CONTEXT_OFFSET_F26($a0)
+	lw $t0, __CONTEXT_OFFSET_F26($a0)
 	mtc1 $t0, $26
 
-	lw $t0, CONTEXT_OFFSET_F27($a0)
+	lw $t0, __CONTEXT_OFFSET_F27($a0)
 	mtc1 $t0, $27
 
-	lw $t0, CONTEXT_OFFSET_F28($a0)
+	lw $t0, __CONTEXT_OFFSET_F28($a0)
 	mtc1 $t0, $28
 
-	lw $t0, CONTEXT_OFFSET_F29($a0)
+	lw $t0, __CONTEXT_OFFSET_F29($a0)
 	mtc1 $t0, $29
 
-	lw $t0, CONTEXT_OFFSET_F30($a0)
+	lw $t0, __CONTEXT_OFFSET_F30($a0)
 	mtc1 $t0, $30
 #endif /* CONFIG_FPU */
 
-	lw $ra, CONTEXT_OFFSET_PC($a0)
-	lw $sp, CONTEXT_OFFSET_SP($a0)
+	lw $ra, __CONTEXT_OFFSET_PC($a0)
+	lw $sp, __CONTEXT_OFFSET_SP($a0)
 
 	# Just for the jump into first function,
@@ -147,6 +147,6 @@
 	move $t9, $ra
 
-	# __longjmp returns second argument
+	# __context_restore returns second argument
 	j $ra
 	move $v0, $a1
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
Index: uspace/lib/c/arch/mips32/src/syscall.c
===================================================================
--- uspace/lib/c/arch/mips32/src/syscall.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/mips32/src/syscall.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -57,9 +57,15 @@
 	      "r" (__mips_reg_t1),
 	      "r" (__mips_reg_v0)
+	    :
 	      /*
 	       * We are a function call, although C
 	       * does not know it.
 	       */
-	    : "%ra"
+	      "%ra",
+	      /*
+	       * Clobber memory too as some arguments might be
+	       * actually pointers.
+	       */
+	      "memory"
 	);
 
Index: uspace/lib/c/arch/ppc32/Makefile.common
===================================================================
--- uspace/lib/c/arch/ppc32/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,5 +33,5 @@
 endif
 
-COMMON_CFLAGS += -mcpu=powerpc -m$(FLOATS)-float -m32
+COMMON_CFLAGS += -mcpu=powerpc -m$(FLOATS)-float -m32 -Wl,-z,max-page-size=0x1000
 AFLAGS += -a32
 LDFLAGS += -Wl,--gc-sections
Index: uspace/lib/c/arch/ppc32/Makefile.inc
===================================================================
--- uspace/lib/c/arch/ppc32/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,5 +34,7 @@
 	arch/$(UARCH)/src/tls.c \
 	arch/$(UARCH)/src/stacktrace.c \
-	arch/$(UARCH)/src/stacktrace_asm.S
+	arch/$(UARCH)/src/stacktrace_asm.S \
+	arch/$(UARCH)/src/rtld/dynamic.c \
+	arch/$(UARCH)/src/rtld/reloc.c
 
 ARCH_AUTOCHECK_HEADERS = \
Index: uspace/lib/c/arch/ppc32/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_CONFIG_H_
-#define LIBC_ppc32_CONFIG_H_
+#ifndef _LIBC_ppc32_CONFIG_H_
+#define _LIBC_ppc32_CONFIG_H_
 
 #define PAGE_WIDTH	12
Index: uspace/lib/c/arch/ppc32/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_ppc32_DDI_H_
-#define LIBC_ppc32_DDI_H_
+#ifndef _LIBC_ppc32_DDI_H_
+#define _LIBC_ppc32_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/ppc32/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_ELF_LINUX_H_
-#define LIBC_ppc32_ELF_LINUX_H_
+#ifndef _LIBC_ppc32_ELF_LINUX_H_
+#define _LIBC_ppc32_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/ppc32/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_FADDR_H_
-#define LIBC_ppc32_FADDR_H_
+#ifndef _LIBC_ppc32_FADDR_H_
+#define _LIBC_ppc32_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/ppc32/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_FIBRIL_H_
-#define LIBC_ppc32_FIBRIL_H_
+#ifndef _LIBC_ppc32_FIBRIL_H_
+#define _LIBC_ppc32_FIBRIL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/ppc32/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,31 +27,31 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP   0x00
-#define CONTEXT_OFFSET_PC   0x04
-#define CONTEXT_OFFSET_TLS  0x08
-#define CONTEXT_OFFSET_R13  0x0c
-#define CONTEXT_OFFSET_R14  0x10
-#define CONTEXT_OFFSET_R15  0x14
-#define CONTEXT_OFFSET_R16  0x18
-#define CONTEXT_OFFSET_R17  0x1c
-#define CONTEXT_OFFSET_R18  0x20
-#define CONTEXT_OFFSET_R19  0x24
-#define CONTEXT_OFFSET_R20  0x28
-#define CONTEXT_OFFSET_R21  0x2c
-#define CONTEXT_OFFSET_R22  0x30
-#define CONTEXT_OFFSET_R23  0x34
-#define CONTEXT_OFFSET_R24  0x38
-#define CONTEXT_OFFSET_R25  0x3c
-#define CONTEXT_OFFSET_R26  0x40
-#define CONTEXT_OFFSET_R27  0x44
-#define CONTEXT_OFFSET_R28  0x48
-#define CONTEXT_OFFSET_R29  0x4c
-#define CONTEXT_OFFSET_R30  0x50
-#define CONTEXT_OFFSET_R31  0x54
-#define CONTEXT_OFFSET_CR   0x58
-#define CONTEXT_SIZE        0x5c
+#define __CONTEXT_OFFSET_SP   0x00
+#define __CONTEXT_OFFSET_PC   0x04
+#define __CONTEXT_OFFSET_TLS  0x08
+#define __CONTEXT_OFFSET_R13  0x0c
+#define __CONTEXT_OFFSET_R14  0x10
+#define __CONTEXT_OFFSET_R15  0x14
+#define __CONTEXT_OFFSET_R16  0x18
+#define __CONTEXT_OFFSET_R17  0x1c
+#define __CONTEXT_OFFSET_R18  0x20
+#define __CONTEXT_OFFSET_R19  0x24
+#define __CONTEXT_OFFSET_R20  0x28
+#define __CONTEXT_OFFSET_R21  0x2c
+#define __CONTEXT_OFFSET_R22  0x30
+#define __CONTEXT_OFFSET_R23  0x34
+#define __CONTEXT_OFFSET_R24  0x38
+#define __CONTEXT_OFFSET_R25  0x3c
+#define __CONTEXT_OFFSET_R26  0x40
+#define __CONTEXT_OFFSET_R27  0x44
+#define __CONTEXT_OFFSET_R28  0x48
+#define __CONTEXT_OFFSET_R29  0x4c
+#define __CONTEXT_OFFSET_R30  0x50
+#define __CONTEXT_OFFSET_R31  0x54
+#define __CONTEXT_OFFSET_CR   0x58
+#define __CONTEXT_SIZE        0x5c
 
 #ifndef __ASSEMBLER__
@@ -60,5 +60,5 @@
 #include <stdint.h>
 
-typedef struct context {
+typedef struct __context {
 	uint32_t sp;
 	uint32_t pc;
@@ -84,5 +84,5 @@
 	uint32_t r31;
 	uint32_t cr;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/ppc32/include/libarch/regname.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/regname.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/regname.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_REGNAME_H_
-#define LIBC_ppc32_REGNAME_H_
+#ifndef _LIBC_ppc32_REGNAME_H_
+#define _LIBC_ppc32_REGNAME_H_
 
 /* Condition Register Bit Fields */
Index: uspace/lib/c/arch/ppc32/include/libarch/rtld/dynamic.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ppc32/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_ppc32_RTLD_DYNAMIC_H_
+#define _LIBC_ppc32_RTLD_DYNAMIC_H_
+
+typedef struct {
+	/* Empty. */
+} dyn_info_arch_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/ppc32/include/libarch/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ppc32/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_ppc32_RTLD_ELF_DYN_H_
+#define _LIBC_ppc32_RTLD_ELF_DYN_H_
+
+/*
+ * ppc32 dynamic relocation types
+ */
+
+#define R_PPC_ADDR32   1
+#define R_PPC_REL24    10
+#define R_PPC_COPY     19
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+
+#define R_PPC_DTPMOD32 68
+#define R_PPC_DTPREL32 78
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/ppc32/include/libarch/rtld/module.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ppc32/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_ppc32_RTLD_MODULE_H_
+#define _LIBC_ppc32_RTLD_MODULE_H_
+
+#include <elf/elf_mod.h>
+
+/** ELF module load flags */
+#define RTLD_MODULE_LDF 0
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/ppc32/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/stackarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/stackarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STACKARG_H_
-#define LIBC_STACKARG_H_
+#ifndef _LIBC_STACKARG_H_
+#define _LIBC_STACKARG_H_
 
 #endif
Index: uspace/lib/c/arch/ppc32/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_ppc32_SYSCALL_H_
-#define LIBC_ppc32_SYSCALL_H_
+#ifndef _LIBC_ppc32_SYSCALL_H_
+#define _LIBC_ppc32_SYSCALL_H_
 
 #define LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/arch/ppc32/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_THREAD_H_
-#define LIBC_ppc32_THREAD_H_
+#ifndef _LIBC_ppc32_THREAD_H_
+#define _LIBC_ppc32_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/ppc32/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/ppc32/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ppc32_TLS_H_
-#define LIBC_ppc32_TLS_H_
+#ifndef _LIBC_ppc32_TLS_H_
+#define _LIBC_ppc32_TLS_H_
 
 #define CONFIG_TLS_VARIANT_1
@@ -43,4 +43,6 @@
 
 typedef struct {
+	void **dtv;
+	void *pad;
 	void *fibril_data;
 } tcb_t;
Index: uspace/lib/c/arch/ppc32/src/fibril.S
===================================================================
--- uspace/lib/c/arch/ppc32/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,69 +33,69 @@
 #include <libarch/fibril_context.h>
 
-FUNCTION_BEGIN(__setjmp)
-	stw sp, CONTEXT_OFFSET_SP(r3)
-	stw r2, CONTEXT_OFFSET_TLS(r3)
-	stw r13, CONTEXT_OFFSET_R13(r3)
-	stw r14, CONTEXT_OFFSET_R14(r3)
-	stw r15, CONTEXT_OFFSET_R15(r3)
-	stw r16, CONTEXT_OFFSET_R16(r3)
-	stw r17, CONTEXT_OFFSET_R17(r3)
-	stw r18, CONTEXT_OFFSET_R18(r3)
-	stw r19, CONTEXT_OFFSET_R19(r3)
-	stw r20, CONTEXT_OFFSET_R20(r3)
-	stw r21, CONTEXT_OFFSET_R21(r3)
-	stw r22, CONTEXT_OFFSET_R22(r3)
-	stw r23, CONTEXT_OFFSET_R23(r3)
-	stw r24, CONTEXT_OFFSET_R24(r3)
-	stw r25, CONTEXT_OFFSET_R25(r3)
-	stw r26, CONTEXT_OFFSET_R26(r3)
-	stw r27, CONTEXT_OFFSET_R27(r3)
-	stw r28, CONTEXT_OFFSET_R28(r3)
-	stw r29, CONTEXT_OFFSET_R29(r3)
-	stw r30, CONTEXT_OFFSET_R30(r3)
-	stw r31, CONTEXT_OFFSET_R31(r3)
+FUNCTION_BEGIN(__context_save)
+	stw sp, __CONTEXT_OFFSET_SP(r3)
+	stw r2, __CONTEXT_OFFSET_TLS(r3)
+	stw r13, __CONTEXT_OFFSET_R13(r3)
+	stw r14, __CONTEXT_OFFSET_R14(r3)
+	stw r15, __CONTEXT_OFFSET_R15(r3)
+	stw r16, __CONTEXT_OFFSET_R16(r3)
+	stw r17, __CONTEXT_OFFSET_R17(r3)
+	stw r18, __CONTEXT_OFFSET_R18(r3)
+	stw r19, __CONTEXT_OFFSET_R19(r3)
+	stw r20, __CONTEXT_OFFSET_R20(r3)
+	stw r21, __CONTEXT_OFFSET_R21(r3)
+	stw r22, __CONTEXT_OFFSET_R22(r3)
+	stw r23, __CONTEXT_OFFSET_R23(r3)
+	stw r24, __CONTEXT_OFFSET_R24(r3)
+	stw r25, __CONTEXT_OFFSET_R25(r3)
+	stw r26, __CONTEXT_OFFSET_R26(r3)
+	stw r27, __CONTEXT_OFFSET_R27(r3)
+	stw r28, __CONTEXT_OFFSET_R28(r3)
+	stw r29, __CONTEXT_OFFSET_R29(r3)
+	stw r30, __CONTEXT_OFFSET_R30(r3)
+	stw r31, __CONTEXT_OFFSET_R31(r3)
 
 	mflr r4
-	stw r4, CONTEXT_OFFSET_PC(r3)
+	stw r4, __CONTEXT_OFFSET_PC(r3)
 
 	mfcr r4
-	stw r4, CONTEXT_OFFSET_CR(r3)
+	stw r4, __CONTEXT_OFFSET_CR(r3)
 
-	# __setjmp returns 0
+	# __context_save returns 0
 	li r3, 0
 	blr
-FUNCTION_END(__setjmp)
+FUNCTION_END(__context_save)
 
-FUNCTION_BEGIN(__longjmp)
-	lwz sp, CONTEXT_OFFSET_SP(r3)
-	lwz r2, CONTEXT_OFFSET_TLS(r3)
-	lwz r13, CONTEXT_OFFSET_R13(r3)
-	lwz r14, CONTEXT_OFFSET_R14(r3)
-	lwz r15, CONTEXT_OFFSET_R15(r3)
-	lwz r16, CONTEXT_OFFSET_R16(r3)
-	lwz r17, CONTEXT_OFFSET_R17(r3)
-	lwz r18, CONTEXT_OFFSET_R18(r3)
-	lwz r19, CONTEXT_OFFSET_R19(r3)
-	lwz r20, CONTEXT_OFFSET_R20(r3)
-	lwz r21, CONTEXT_OFFSET_R21(r3)
-	lwz r22, CONTEXT_OFFSET_R22(r3)
-	lwz r23, CONTEXT_OFFSET_R23(r3)
-	lwz r24, CONTEXT_OFFSET_R24(r3)
-	lwz r25, CONTEXT_OFFSET_R25(r3)
-	lwz r26, CONTEXT_OFFSET_R26(r3)
-	lwz r27, CONTEXT_OFFSET_R27(r3)
-	lwz r28, CONTEXT_OFFSET_R28(r3)
-	lwz r29, CONTEXT_OFFSET_R29(r3)
-	lwz r30, CONTEXT_OFFSET_R30(r3)
-	lwz r31, CONTEXT_OFFSET_R31(r3)
+FUNCTION_BEGIN(__context_restore)
+	lwz sp, __CONTEXT_OFFSET_SP(r3)
+	lwz r2, __CONTEXT_OFFSET_TLS(r3)
+	lwz r13, __CONTEXT_OFFSET_R13(r3)
+	lwz r14, __CONTEXT_OFFSET_R14(r3)
+	lwz r15, __CONTEXT_OFFSET_R15(r3)
+	lwz r16, __CONTEXT_OFFSET_R16(r3)
+	lwz r17, __CONTEXT_OFFSET_R17(r3)
+	lwz r18, __CONTEXT_OFFSET_R18(r3)
+	lwz r19, __CONTEXT_OFFSET_R19(r3)
+	lwz r20, __CONTEXT_OFFSET_R20(r3)
+	lwz r21, __CONTEXT_OFFSET_R21(r3)
+	lwz r22, __CONTEXT_OFFSET_R22(r3)
+	lwz r23, __CONTEXT_OFFSET_R23(r3)
+	lwz r24, __CONTEXT_OFFSET_R24(r3)
+	lwz r25, __CONTEXT_OFFSET_R25(r3)
+	lwz r26, __CONTEXT_OFFSET_R26(r3)
+	lwz r27, __CONTEXT_OFFSET_R27(r3)
+	lwz r28, __CONTEXT_OFFSET_R28(r3)
+	lwz r29, __CONTEXT_OFFSET_R29(r3)
+	lwz r30, __CONTEXT_OFFSET_R30(r3)
+	lwz r31, __CONTEXT_OFFSET_R31(r3)
 
-	lwz r5, CONTEXT_OFFSET_CR(r3)
+	lwz r5, __CONTEXT_OFFSET_CR(r3)
 	mtcr r5
 
-	lwz r5, CONTEXT_OFFSET_PC(r3)
+	lwz r5, __CONTEXT_OFFSET_PC(r3)
 	mtlr r5
 
-	# __longjmp returns second argument
+	# __context_restore returns second argument
 	mr r3, r4
 	blr
-FUNCTION_END(__longjmp)
+FUNCTION_END(__context_restore)
Index: uspace/lib/c/arch/ppc32/src/rtld/dynamic.c
===================================================================
--- uspace/lib/c/arch/ppc32/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ppc32/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libcppc32
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtld/elf_dyn.h>
+#include <rtld/dynamic.h>
+
+void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
+{
+	(void) dp;
+	(void) bias;
+	(void) info;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/ppc32/src/rtld/reloc.c
===================================================================
--- uspace/lib/c/arch/ppc32/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/ppc32/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libcppc32
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <bitops.h>
+#include <smc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <str.h>
+
+#include <libarch/rtld/elf_dyn.h>
+#include <rtld/symbol.h>
+#include <rtld/rtld.h>
+#include <rtld/rtld_debug.h>
+#include <rtld/rtld_arch.h>
+
+static void plt_farcall_init(uint32_t *plt, uint32_t *);
+static void plt_entry_init(uint32_t *, uint32_t *, uint32_t *, uintptr_t);
+static uint32_t *plt_entry_ptr(uint32_t *, size_t);
+static size_t plt_entry_index(size_t);
+static uint16_t addr_ha(uint32_t);
+static uint16_t addr_l(uint32_t);
+
+void module_process_pre_arch(module_t *m)
+{
+	/* Unused */
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table.
+ */
+void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size)
+{
+	/* Unused */
+	(void)m;
+	(void)rt;
+	(void)rt_size;
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with explicit addends.
+ */
+void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size)
+{
+	unsigned i;
+
+	size_t rt_entries;
+	size_t r_offset;
+	size_t r_addend;
+	elf_xword r_info;
+	unsigned rel_type;
+	elf_word sym_idx;
+	uintptr_t sym_addr;
+
+	elf_symbol_t *sym_table;
+	elf_symbol_t *sym;
+	uintptr_t *r_ptr;
+	uintptr_t sym_size;
+	char *str_tab;
+
+	elf_symbol_t *sym_def;
+	module_t *dest;
+	uint32_t *plt;
+	uint32_t *plt_datawords;
+	size_t jmp_slots;
+
+	DPRINTF("Count jump slots.\n");
+
+	rt_entries = rt_size / sizeof(elf_rela_t);
+
+	jmp_slots = 0;
+	for (i = 0; i < rt_entries; ++i) {
+		r_info = rt[i].r_info;
+		rel_type = ELF32_R_TYPE(r_info);
+
+		if (rel_type == R_PPC_JMP_SLOT)
+			++jmp_slots;
+	}
+
+	DPRINTF("Init farcall section\n");
+
+	plt = (uint32_t *)m->dyn.plt_got;
+
+	/* Table with addresses starts just after last PLT entry */
+	plt_datawords = plt_entry_ptr(plt, jmp_slots);
+
+	/* Init farcall section with reference to datawords table */
+	plt_farcall_init(plt, plt_datawords);
+
+	DPRINTF("parse relocation table\n");
+
+	sym_table = m->dyn.sym_tab;
+	str_tab = m->dyn.str_tab;
+
+	DPRINTF("rel table address: 0x%zx, entries: %zd\n", (uintptr_t)rt, rt_entries);
+
+	for (i = 0; i < rt_entries; ++i) {
+#if 0
+		DPRINTF("symbol %d: ", i);
+#endif
+		r_offset = rt[i].r_offset;
+		r_info = rt[i].r_info;
+		r_addend = rt[i].r_addend;
+
+		sym_idx = ELF32_R_SYM(r_info);
+		sym = &sym_table[sym_idx];
+
+#if 0
+		DPRINTF("name '%s', value 0x%x, size 0x%x\n",
+		    str_tab + sym->st_name,
+		    sym->st_value,
+		    sym->st_size);
+#endif
+		rel_type = ELF32_R_TYPE(r_info);
+		r_ptr = (uintptr_t *)(r_offset + m->bias);
+
+		if (sym->st_name != 0) {
+			DPRINTF("rel_type: %x, rel_offset: 0x%zx\n", rel_type, r_offset);
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_none, &dest);
+			DPRINTF("dest name: '%s'\n", dest->dyn.soname);
+			DPRINTF("dest bias: 0x%zx\n", dest->bias);
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+				DPRINTF("symbol definition found, value=0x%zx addr=0x%zx\n", sym_def->st_value, sym_addr);
+			} else {
+				printf("Definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+		} else {
+			sym_addr = 0;
+			sym_def = NULL;
+
+			/*
+			 * DTPMOD with null st_name should return the index
+			 * of the current module.
+			 */
+			dest = m;
+		}
+
+		switch (rel_type) {
+		case R_PPC_ADDR32:
+			DPRINTF("fixup R_PPC_ADDR32 (S+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr);
+			*r_ptr = sym_addr + r_addend;
+			DPRINTF("OK\n");
+			break;
+		case R_PPC_REL24:
+			DPRINTF("fixup R_PPC_REL24 ((S+A-P) >> 2)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr,
+			    (sym_addr + r_addend - (uintptr_t)r_ptr) >> 2);
+			*r_ptr = (sym_addr + r_addend - (uintptr_t)r_ptr) >> 2;
+			DPRINTF("OK\n");
+			break;
+		case R_PPC_COPY:
+			/*
+			 * Copy symbol data from shared object to specified
+			 * location. Need to find the 'source', i.e. the
+			 * other instance of the object than the one in the
+			 * executable program.
+			 */
+			DPRINTF("fixup R_PPC_COPY (s)\n");
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			sym_size = sym->st_size;
+			if (sym_size != sym_def->st_size) {
+#if 0
+				printf("Warning: Mismatched symbol sizes.\n");
+#endif
+				/* Take the lower value. */
+				if (sym_size > sym_def->st_size)
+					sym_size = sym_def->st_size;
+			}
+
+			memcpy(r_ptr, (const void *)sym_addr, sym_size);
+			DPRINTF("OK\n");
+			break;
+
+		case R_PPC_JMP_SLOT:
+			DPRINTF("fixup R_PPC_JMP_SLOT (S)\n");
+			DPRINTF("r_offset=0x%zx r_addend=0x%zx\n",
+			    r_offset, r_addend);
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			DPRINTF("sym_addr = 0x%zx\n", sym_addr);
+			DPRINTF("r_offset=0x%zx\n", r_offset);
+
+			/*
+			 * Fill PLT entry with jump to symbol address.
+			 */
+			plt_entry_init(plt, (uint32_t *)r_ptr, plt_datawords,
+			    sym_addr);
+
+			DPRINTF("OK\n");
+			break;
+
+		case R_PPC_RELATIVE:
+			DPRINTF("fixup R_PPC_RELATIVE (B+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, m->bias + r_addend);
+			*r_ptr = m->bias + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_PPC_DTPMOD32:
+			DPRINTF("fixup R_PPC_DTPMOD32\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, (size_t)dest->id);
+			*r_ptr = dest->id;
+			DPRINTF("OK\n");
+			break;
+
+		case R_PPC_DTPREL32:
+			DPRINTF("fixup R_PPC_DTPREL32\n"); /* XXXXX */
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_def->st_value);
+			*r_ptr = sym_def->st_value + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		default:
+			printf("Error: Unknown relocation type %d\n",
+			    rel_type);
+			exit(1);
+		}
+
+	}
+}
+
+/** Init PLT farcall section. */
+static void plt_farcall_init(uint32_t *plt, uint32_t *plt_datawords)
+{
+	uint16_t hi;
+	uint16_t lo;
+	int i;
+
+	hi = addr_ha((uintptr_t)plt_datawords);
+	lo = addr_l((uintptr_t)plt_datawords);
+
+	plt[0] = 0x3d6b0000 | hi; /* addis %r11,% r11,. plt_datawords@ha */
+	plt[1] = 0x816b0000 | lo; /* lwz %r11, .plt_datawords@l(%r11) */
+	plt[2] = 0x7d6903a6;      /* mtctr %r11 */
+	plt[3] = 0x4e800420;      /* bctr */
+	plt[4] = 0x60000000;      /* nop */
+	plt[5] = 0x60000000;      /* nop */
+
+	smc_coherence(plt, 4 * 6);
+
+	for (i = 0; i < 6; i++)
+		DPRINTF("%p: farcall[%d] = %08zx\n", &plt[i], i, plt[i]);
+}
+
+/** Fill in PLT entry.
+ *
+ * Fill a PLT entry with PowerPC instructions to set table index and
+ * jump to the farcall section. Fill table entry with target address.
+ *
+ * @param plt Pointer to PLT
+ * @param plte Pointer to PLT entry to fill in
+ * @param datawords Address table
+ * @param ta Target address of the jump
+ */
+static void plt_entry_init(uint32_t *plt, uint32_t *plte, uint32_t *datawords,
+    uintptr_t ta)
+{
+	size_t index;
+	size_t woffset;
+	uint16_t i4index;
+	uint32_t btgt;
+
+	DPRINTF("plt_entry_init(plt=%p, plte=%p, datawords=%p, ta=0z%zx\n",
+	    plt, plte, datawords, ta);
+
+	/* Entry offset in words */
+	woffset = plte - plt;
+
+	/* Entry index */
+	index = plt_entry_index(woffset);
+
+	/* This only works for the first 2048 entries */
+	assert(index * 4 < 0x8000);
+	i4index = 4 * index;
+
+	/* Relative branch offset */
+	btgt = ((uint8_t *)plt - (uint8_t *)&plte[1]) & 0x03ffffff;
+
+	/* Write target address to table */
+	datawords[index] = ta;
+	DPRINTF("%p: datawords[%zu] = %08x\n", &datawords[index], index, ta);
+
+	plte[0] = 0x39600000 | i4index; /* li %r11, 4 * index */
+	plte[1] = 0x48000000 | btgt;    /* b .plt_farcall */
+
+	DPRINTF("%p: plte[0] = %08zx\n", &plte[0], plte[0]);
+	DPRINTF("%p: plte[1] = %08zx\n", &plte[1], plte[1]);
+
+	smc_coherence(plte, 4 * 2);
+}
+
+/** Determine PLT entry address.
+ *
+ * @param plt Start of PLT
+ * @param index PLT entry index
+ * @return Pointer to PLT entry
+ */
+static uint32_t *plt_entry_ptr(uint32_t *plt, size_t index)
+{
+	if (index < 8192)
+		return plt + 18 + 2 * index;
+	else
+		return plt + 18 + 2 * 8192 + 4 * (index - 8192);
+}
+
+/** Determine index of PLT entry from its word offset.
+ *
+ * @param woffset Offset of PLT entry in words
+ * @return PLT entry index
+ */
+static size_t plt_entry_index(size_t woffset)
+{
+	assert(woffset >= 18);
+	woffset -= 18;
+
+	if (woffset < 2 * 8192) {
+		assert((woffset & 0x1) == 0);
+		return woffset / 2;
+	} else {
+		assert((woffset & 0x3) == 0);
+		return (woffset - 2 * 8192) / 4;
+	}
+}
+
+/** Determine high bits of address.
+ *
+ * The lower bits are determined by @c addr_l function. The lower bits
+ * are considered to be a 16-bit signed integer.
+ *
+ * @param addr Address
+ * @return Higher bits of address
+ */
+static uint16_t addr_ha(uint32_t addr)
+{
+	int32_t la;
+
+	/* The lower part of the address is a signed 16-bit integer */
+	la = (int16_t)(addr & 0xffff);
+
+	/* Compute higher bits while compensating for the sign extension */
+	return (addr - la) >> 16;
+}
+
+/** Determine lower bits of address.
+ *
+ * The lower bits are considered to be 16-bit signed integer/immediate
+ * operand by the ISA, but we return them here as unsigned unmber so
+ * it can be easily incorporated into an instruction opcode.
+ *
+ * @param addr Address
+ * @return Lower bits of address cast as unsigned 16-bit integer
+ */
+static uint16_t addr_l(uint32_t addr)
+{
+	return (uint16_t) (addr & 0x0000ffff);
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/ppc32/src/syscall.c
===================================================================
--- uspace/lib/c/arch/ppc32/src/syscall.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/src/syscall.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -58,4 +58,10 @@
 	      "r" (__ppc32_reg_r8),
 	      "r" (__ppc32_reg_r9)
+	    :
+	      /*
+	       * Clobber memory too as some arguments might be
+	       * actually pointers.
+	       */
+	      "memory"
 	);
 
Index: uspace/lib/c/arch/ppc32/src/tls.c
===================================================================
--- uspace/lib/c/arch/ppc32/src/tls.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/ppc32/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2019 Jiri Svoboda
  * Copyright (c) 2006 Ondrej Palkovsky
  * All rights reserved.
@@ -36,4 +37,8 @@
 #include <stddef.h>
 
+#ifdef CONFIG_RTLD
+#include <rtld/rtld.h>
+#endif
+
 tcb_t *tls_alloc_arch(size_t size, size_t align)
 {
@@ -46,4 +51,32 @@
 }
 
+/*
+ * Rtld TLS support
+ */
+
+typedef struct {
+	unsigned long int ti_module;
+	unsigned long int ti_offset;
+} tls_index;
+
+int __tls_debug = 0;
+
+void *__tls_get_addr(tls_index *ti);
+
+void *__tls_get_addr(tls_index *ti)
+{
+	uint8_t *tls;
+
+#ifdef CONFIG_RTLD
+	if (runtime_env != NULL) {
+		return rtld_tls_get_addr(runtime_env, __tcb_get(),
+		    ti->ti_module, ti->ti_offset) + 0x8000;
+	}
+#endif
+	/* Get address of static TLS block */
+	tls = tls_get();
+	return tls + ti->ti_offset + 0x8000;
+}
+
 /** @}
  */
Index: uspace/lib/c/arch/riscv64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_CONFIG_H_
-#define LIBC_riscv64_CONFIG_H_
+#ifndef _LIBC_riscv64_CONFIG_H_
+#define _LIBC_riscv64_CONFIG_H_
 
 #define PAGE_WIDTH  12
Index: uspace/lib/c/arch/riscv64/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,6 +30,6 @@
  */
 
-#ifndef LIBC_riscv64_DDI_H_
-#define LIBC_riscv64_DDI_H_
+#ifndef _LIBC_riscv64_DDI_H_
+#define _LIBC_riscv64_DDI_H_
 
 #include <ddi.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_ELF_LINUX_H_
-#define LIBC_riscv64_ELF_LINUX_H_
+#ifndef _LIBC_riscv64_ELF_LINUX_H_
+#define _LIBC_riscv64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_FADDR_H_
-#define LIBC_riscv64_FADDR_H_
+#ifndef _LIBC_riscv64_FADDR_H_
+#define _LIBC_riscv64_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_FIBRIL_H_
-#define LIBC_riscv64_FIBRIL_H_
+#ifndef _LIBC_riscv64_FIBRIL_H_
+#define _LIBC_riscv64_FIBRIL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,41 +27,41 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP   0x00
-#define CONTEXT_OFFSET_PC   0x08
-#define CONTEXT_OFFSET_ZERO 0x10
-#define CONTEXT_OFFSET_RA   0x18
-#define CONTEXT_OFFSET_X3   0x20
-#define CONTEXT_OFFSET_X4   0x28
-#define CONTEXT_OFFSET_X5   0x30
-#define CONTEXT_OFFSET_X6   0x38
-#define CONTEXT_OFFSET_X7   0x40
-#define CONTEXT_OFFSET_X8   0x48
-#define CONTEXT_OFFSET_X9   0x50
-#define CONTEXT_OFFSET_X10  0x58
-#define CONTEXT_OFFSET_X11  0x60
-#define CONTEXT_OFFSET_X12  0x68
-#define CONTEXT_OFFSET_X13  0x70
-#define CONTEXT_OFFSET_X14  0x78
-#define CONTEXT_OFFSET_X15  0x80
-#define CONTEXT_OFFSET_X16  0x88
-#define CONTEXT_OFFSET_X17  0x90
-#define CONTEXT_OFFSET_X18  0x98
-#define CONTEXT_OFFSET_X19  0xa0
-#define CONTEXT_OFFSET_X20  0xa8
-#define CONTEXT_OFFSET_X21  0xb0
-#define CONTEXT_OFFSET_X22  0xb8
-#define CONTEXT_OFFSET_X23  0xc0
-#define CONTEXT_OFFSET_X24  0xc8
-#define CONTEXT_OFFSET_X25  0xd0
-#define CONTEXT_OFFSET_X26  0xd8
-#define CONTEXT_OFFSET_X27  0xe0
-#define CONTEXT_OFFSET_X28  0xe8
-#define CONTEXT_OFFSET_X29  0xf0
-#define CONTEXT_OFFSET_X30  0xf8
-#define CONTEXT_OFFSET_X31  0x100
-#define CONTEXT_SIZE        0x108
+#define __CONTEXT_OFFSET_SP   0x00
+#define __CONTEXT_OFFSET_PC   0x08
+#define __CONTEXT_OFFSET_ZERO 0x10
+#define __CONTEXT_OFFSET_RA   0x18
+#define __CONTEXT_OFFSET_X3   0x20
+#define __CONTEXT_OFFSET_X4   0x28
+#define __CONTEXT_OFFSET_X5   0x30
+#define __CONTEXT_OFFSET_X6   0x38
+#define __CONTEXT_OFFSET_X7   0x40
+#define __CONTEXT_OFFSET_X8   0x48
+#define __CONTEXT_OFFSET_X9   0x50
+#define __CONTEXT_OFFSET_X10  0x58
+#define __CONTEXT_OFFSET_X11  0x60
+#define __CONTEXT_OFFSET_X12  0x68
+#define __CONTEXT_OFFSET_X13  0x70
+#define __CONTEXT_OFFSET_X14  0x78
+#define __CONTEXT_OFFSET_X15  0x80
+#define __CONTEXT_OFFSET_X16  0x88
+#define __CONTEXT_OFFSET_X17  0x90
+#define __CONTEXT_OFFSET_X18  0x98
+#define __CONTEXT_OFFSET_X19  0xa0
+#define __CONTEXT_OFFSET_X20  0xa8
+#define __CONTEXT_OFFSET_X21  0xb0
+#define __CONTEXT_OFFSET_X22  0xb8
+#define __CONTEXT_OFFSET_X23  0xc0
+#define __CONTEXT_OFFSET_X24  0xc8
+#define __CONTEXT_OFFSET_X25  0xd0
+#define __CONTEXT_OFFSET_X26  0xd8
+#define __CONTEXT_OFFSET_X27  0xe0
+#define __CONTEXT_OFFSET_X28  0xe8
+#define __CONTEXT_OFFSET_X29  0xf0
+#define __CONTEXT_OFFSET_X30  0xf8
+#define __CONTEXT_OFFSET_X31  0x100
+#define __CONTEXT_SIZE        0x108
 
 #ifndef __ASSEMBLER__
@@ -75,5 +75,5 @@
  */
 
-typedef struct context {
+typedef struct __context {
 	uint64_t sp;
 	uint64_t pc;
@@ -109,5 +109,5 @@
 	uint64_t x30;
 	uint64_t x31;
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/riscv64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_riscv64_SYSCALL_H_
-#define LIBC_riscv64_SYSCALL_H_
+#ifndef _LIBC_riscv64_SYSCALL_H_
+#define _LIBC_riscv64_SYSCALL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/riscv64/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_THREAD_H_
-#define LIBC_riscv64_THREAD_H_
+#ifndef _LIBC_riscv64_THREAD_H_
+#define _LIBC_riscv64_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/riscv64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/riscv64/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_riscv64_TLS_H_
-#define LIBC_riscv64_TLS_H_
+#ifndef _LIBC_riscv64_TLS_H_
+#define _LIBC_riscv64_TLS_H_
 
 #define CONFIG_TLS_VARIANT_2
Index: uspace/lib/c/arch/riscv64/src/fibril.c
===================================================================
--- uspace/lib/c/arch/riscv64/src/fibril.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/riscv64/src/fibril.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,10 +33,10 @@
 #include <stdbool.h>
 
-int __setjmp(context_t *ctx)
+int __context_save(__context_t *ctx)
 {
 	return 0;
 }
 
-void __longjmp(context_t *ctx, int ret)
+void __context_restore(__context_t *ctx, int ret)
 {
 	while (true)
Index: uspace/lib/c/arch/sparc64/Makefile.common
===================================================================
--- uspace/lib/c/arch/sparc64/Makefile.common	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/Makefile.common	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -52,3 +52,6 @@
 ifeq ($(PROCESSOR),sun4v)
 	DEFS += -DSUN4V
+	COMMON_CFLAGS += -Wl,-z,max-page-size=0x2000
+else
+	COMMON_CFLAGS += -Wl,-z,max-page-size=0x4000
 endif
Index: uspace/lib/c/arch/sparc64/Makefile.inc
===================================================================
--- uspace/lib/c/arch/sparc64/Makefile.inc	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/Makefile.inc	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,5 +33,7 @@
 	arch/$(UARCH)/src/tls.c \
 	arch/$(UARCH)/src/stacktrace.c \
-	arch/$(UARCH)/src/stacktrace_asm.S
+	arch/$(UARCH)/src/stacktrace_asm.S \
+	arch/$(UARCH)/src/rtld/dynamic.c \
+	arch/$(UARCH)/src/rtld/reloc.c
 
 ARCH_AUTOCHECK_HEADERS = \
Index: uspace/lib/c/arch/sparc64/include/libarch/config.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_CONFIG_H_
-#define LIBC_sparc64_CONFIG_H_
+#ifndef _LIBC_sparc64_CONFIG_H_
+#define _LIBC_sparc64_CONFIG_H_
 
 #if defined (SUN4U)
Index: uspace/lib/c/arch/sparc64/include/libarch/ddi.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_sparc64_DDI_H_
-#define LIBC_sparc64_DDI_H_
+#ifndef _LIBC_sparc64_DDI_H_
+#define _LIBC_sparc64_DDI_H_
 
 #include <barrier.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/elf_linux.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_ELF_LINUX_H_
-#define LIBC_sparc64_ELF_LINUX_H_
+#ifndef _LIBC_sparc64_ELF_LINUX_H_
+#define _LIBC_sparc64_ELF_LINUX_H_
 
 #include <libarch/istate.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/faddr.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/faddr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/faddr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_FADDR_H_
-#define LIBC_sparc64_FADDR_H_
+#ifndef _LIBC_sparc64_FADDR_H_
+#define _LIBC_sparc64_FADDR_H_
 
 #include <types/common.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/fibril.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_FIBRIL_H_
-#define LIBC_sparc64_FIBRIL_H_
+#ifndef _LIBC_sparc64_FIBRIL_H_
+#define _LIBC_sparc64_FIBRIL_H_
 
 #include <libarch/stack.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/fibril_context.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/fibril_context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/fibril_context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,27 +27,27 @@
  */
 
-#ifndef LIBC_ARCH_FIBRIL_CONTEXT_H_
-#define LIBC_ARCH_FIBRIL_CONTEXT_H_
+#ifndef _LIBC_ARCH_FIBRIL_CONTEXT_H_
+#define _LIBC_ARCH_FIBRIL_CONTEXT_H_
 
-#define CONTEXT_OFFSET_SP  0x00
-#define CONTEXT_OFFSET_PC  0x08
-#define CONTEXT_OFFSET_I0  0x10
-#define CONTEXT_OFFSET_I1  0x18
-#define CONTEXT_OFFSET_I2  0x20
-#define CONTEXT_OFFSET_I3  0x28
-#define CONTEXT_OFFSET_I4  0x30
-#define CONTEXT_OFFSET_I5  0x38
-#define CONTEXT_OFFSET_FP  0x40
-#define CONTEXT_OFFSET_I7  0x48
-#define CONTEXT_OFFSET_L0  0x50
-#define CONTEXT_OFFSET_L1  0x58
-#define CONTEXT_OFFSET_L2  0x60
-#define CONTEXT_OFFSET_L3  0x68
-#define CONTEXT_OFFSET_L4  0x70
-#define CONTEXT_OFFSET_L5  0x78
-#define CONTEXT_OFFSET_L6  0x80
-#define CONTEXT_OFFSET_L7  0x88
-#define CONTEXT_OFFSET_TP  0x90
-#define CONTEXT_SIZE       0x98
+#define __CONTEXT_OFFSET_SP  0x00
+#define __CONTEXT_OFFSET_PC  0x08
+#define __CONTEXT_OFFSET_I0  0x10
+#define __CONTEXT_OFFSET_I1  0x18
+#define __CONTEXT_OFFSET_I2  0x20
+#define __CONTEXT_OFFSET_I3  0x28
+#define __CONTEXT_OFFSET_I4  0x30
+#define __CONTEXT_OFFSET_I5  0x38
+#define __CONTEXT_OFFSET_FP  0x40
+#define __CONTEXT_OFFSET_I7  0x48
+#define __CONTEXT_OFFSET_L0  0x50
+#define __CONTEXT_OFFSET_L1  0x58
+#define __CONTEXT_OFFSET_L2  0x60
+#define __CONTEXT_OFFSET_L3  0x68
+#define __CONTEXT_OFFSET_L4  0x70
+#define __CONTEXT_OFFSET_L5  0x78
+#define __CONTEXT_OFFSET_L6  0x80
+#define __CONTEXT_OFFSET_L7  0x88
+#define __CONTEXT_OFFSET_TP  0x90
+#define __CONTEXT_SIZE       0x98
 
 #ifndef __ASSEMBLER__
@@ -56,5 +56,5 @@
 #include <stdint.h>
 
-typedef struct context {
+typedef struct __context {
 	uintptr_t sp;  // %o6
 	uintptr_t pc;  // %o7
@@ -76,5 +76,5 @@
 	uint64_t l7;
 	uint64_t tp;  // %g7
-} context_t;
+} __context_t;
 
 #endif
Index: uspace/lib/c/arch/sparc64/include/libarch/rtld/dynamic.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/sparc64/include/libarch/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_sparc64_RTLD_DYNAMIC_H_
+#define _LIBC_sparc64_RTLD_DYNAMIC_H_
+
+typedef struct {
+	/* Empty. */
+} dyn_info_arch_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc64/include/libarch/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/sparc64/include/libarch/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup generic
+ * @{
+ */
+/** @file sparc64 dynamic relocation types
+ */
+
+#ifndef _LIBC_sparc64_RTLD_ELF_DYN_H_
+#define _LIBC_sparc64_RTLD_ELF_DYN_H_
+
+#define R_SPARC_COPY		19
+#define R_SPARC_GLOB_DAT	20
+#define R_SPARC_JMP_SLOT	21
+#define R_SPARC_RELATIVE	22
+#define R_SPARC_64		32
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF64	79
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc64/include/libarch/rtld/module.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/sparc64/include/libarch/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_sparc64_RTLD_MODULE_H_
+#define _LIBC_sparc64_RTLD_MODULE_H_
+
+#include <elf/elf_mod.h>
+
+/** ELF module load flags */
+#define RTLD_MODULE_LDF 0
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc64/include/libarch/stack.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/stack.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/stack.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_STACK_H_
-#define LIBC_sparc64_STACK_H_
+#ifndef _LIBC_sparc64_STACK_H_
+#define _LIBC_sparc64_STACK_H_
 
 #define STACK_ITEM_SIZE			8
Index: uspace/lib/c/arch/sparc64/include/libarch/stackarg.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/stackarg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/stackarg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_STACKARG_H_
-#define LIBC_sparc64_STACKARG_H_
+#ifndef _LIBC_sparc64_STACKARG_H_
+#define _LIBC_sparc64_STACKARG_H_
 
 #endif
Index: uspace/lib/c/arch/sparc64/include/libarch/syscall.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_sparc64_SYSCALL_H_
-#define LIBC_sparc64_SYSCALL_H_
+#ifndef _LIBC_sparc64_SYSCALL_H_
+#define _LIBC_sparc64_SYSCALL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/arch/sparc64/include/libarch/thread.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,6 +32,6 @@
  */
 
-#ifndef LIBC_sparc64_THREAD_H_
-#define LIBC_sparc64_THREAD_H_
+#ifndef _LIBC_sparc64_THREAD_H_
+#define _LIBC_sparc64_THREAD_H_
 
 #endif
Index: uspace/lib/c/arch/sparc64/include/libarch/tls.h
===================================================================
--- uspace/lib/c/arch/sparc64/include/libarch/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/include/libarch/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,6 +36,6 @@
  */
 
-#ifndef LIBC_sparc64_TLS_H_
-#define LIBC_sparc64_TLS_H_
+#ifndef _LIBC_sparc64_TLS_H_
+#define _LIBC_sparc64_TLS_H_
 
 #define CONFIG_TLS_VARIANT_2
@@ -46,4 +46,6 @@
 	void *self;
 	void *fibril_data;
+	void **dtv;
+	void *pad;
 } tcb_t;
 
Index: uspace/lib/c/arch/sparc64/src/fibril.S
===================================================================
--- uspace/lib/c/arch/sparc64/src/fibril.S	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/src/fibril.S	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,33 +32,33 @@
 .text
 
-FUNCTION_BEGIN(__setjmp)
+FUNCTION_BEGIN(__context_save)
 	#
 	# We rely on the kernel to flush our active register windows to memory
 	# should a thread switch occur.
 	#
-	stx %sp, [%o0 + CONTEXT_OFFSET_SP]
-	stx %o7, [%o0 + CONTEXT_OFFSET_PC]
-	stx %i0, [%o0 + CONTEXT_OFFSET_I0]
-	stx %i1, [%o0 + CONTEXT_OFFSET_I1]
-	stx %i2, [%o0 + CONTEXT_OFFSET_I2]
-	stx %i3, [%o0 + CONTEXT_OFFSET_I3]
-	stx %i4, [%o0 + CONTEXT_OFFSET_I4]
-	stx %i5, [%o0 + CONTEXT_OFFSET_I5]
-	stx %fp, [%o0 + CONTEXT_OFFSET_FP]
-	stx %i7, [%o0 + CONTEXT_OFFSET_I7]
-	stx %l0, [%o0 + CONTEXT_OFFSET_L0]
-	stx %l1, [%o0 + CONTEXT_OFFSET_L1]
-	stx %l2, [%o0 + CONTEXT_OFFSET_L2]
-	stx %l3, [%o0 + CONTEXT_OFFSET_L3]
-	stx %l4, [%o0 + CONTEXT_OFFSET_L4]
-	stx %l5, [%o0 + CONTEXT_OFFSET_L5]
-	stx %l6, [%o0 + CONTEXT_OFFSET_L6]
-	stx %l7, [%o0 + CONTEXT_OFFSET_L7]
-	stx %g7, [%o0 + CONTEXT_OFFSET_TP]
+	stx %sp, [%o0 + __CONTEXT_OFFSET_SP]
+	stx %o7, [%o0 + __CONTEXT_OFFSET_PC]
+	stx %i0, [%o0 + __CONTEXT_OFFSET_I0]
+	stx %i1, [%o0 + __CONTEXT_OFFSET_I1]
+	stx %i2, [%o0 + __CONTEXT_OFFSET_I2]
+	stx %i3, [%o0 + __CONTEXT_OFFSET_I3]
+	stx %i4, [%o0 + __CONTEXT_OFFSET_I4]
+	stx %i5, [%o0 + __CONTEXT_OFFSET_I5]
+	stx %fp, [%o0 + __CONTEXT_OFFSET_FP]
+	stx %i7, [%o0 + __CONTEXT_OFFSET_I7]
+	stx %l0, [%o0 + __CONTEXT_OFFSET_L0]
+	stx %l1, [%o0 + __CONTEXT_OFFSET_L1]
+	stx %l2, [%o0 + __CONTEXT_OFFSET_L2]
+	stx %l3, [%o0 + __CONTEXT_OFFSET_L3]
+	stx %l4, [%o0 + __CONTEXT_OFFSET_L4]
+	stx %l5, [%o0 + __CONTEXT_OFFSET_L5]
+	stx %l6, [%o0 + __CONTEXT_OFFSET_L6]
+	stx %l7, [%o0 + __CONTEXT_OFFSET_L7]
+	stx %g7, [%o0 + __CONTEXT_OFFSET_TP]
 	retl
-	mov 0, %o0		! __setjmp returns 0
-FUNCTION_END(__setjmp)
+	mov 0, %o0		! __context_save returns 0
+FUNCTION_END(__context_save)
 
-FUNCTION_BEGIN(__longjmp)
+FUNCTION_BEGIN(__context_restore)
 	#
 	# Flush all active windows.
@@ -69,24 +69,24 @@
 	flushw
 
-	ldx [%o0 + CONTEXT_OFFSET_SP], %sp
-	ldx [%o0 + CONTEXT_OFFSET_PC], %o7
-	ldx [%o0 + CONTEXT_OFFSET_I0], %i0
-	ldx [%o0 + CONTEXT_OFFSET_I1], %i1
-	ldx [%o0 + CONTEXT_OFFSET_I2], %i2
-	ldx [%o0 + CONTEXT_OFFSET_I3], %i3
-	ldx [%o0 + CONTEXT_OFFSET_I4], %i4
-	ldx [%o0 + CONTEXT_OFFSET_I5], %i5
-	ldx [%o0 + CONTEXT_OFFSET_FP], %fp
-	ldx [%o0 + CONTEXT_OFFSET_I7], %i7
-	ldx [%o0 + CONTEXT_OFFSET_L0], %l0
-	ldx [%o0 + CONTEXT_OFFSET_L1], %l1
-	ldx [%o0 + CONTEXT_OFFSET_L2], %l2
-	ldx [%o0 + CONTEXT_OFFSET_L3], %l3
-	ldx [%o0 + CONTEXT_OFFSET_L4], %l4
-	ldx [%o0 + CONTEXT_OFFSET_L5], %l5
-	ldx [%o0 + CONTEXT_OFFSET_L6], %l6
-	ldx [%o0 + CONTEXT_OFFSET_L7], %l7
-	ldx [%o0 + CONTEXT_OFFSET_TP], %g7
+	ldx [%o0 + __CONTEXT_OFFSET_SP], %sp
+	ldx [%o0 + __CONTEXT_OFFSET_PC], %o7
+	ldx [%o0 + __CONTEXT_OFFSET_I0], %i0
+	ldx [%o0 + __CONTEXT_OFFSET_I1], %i1
+	ldx [%o0 + __CONTEXT_OFFSET_I2], %i2
+	ldx [%o0 + __CONTEXT_OFFSET_I3], %i3
+	ldx [%o0 + __CONTEXT_OFFSET_I4], %i4
+	ldx [%o0 + __CONTEXT_OFFSET_I5], %i5
+	ldx [%o0 + __CONTEXT_OFFSET_FP], %fp
+	ldx [%o0 + __CONTEXT_OFFSET_I7], %i7
+	ldx [%o0 + __CONTEXT_OFFSET_L0], %l0
+	ldx [%o0 + __CONTEXT_OFFSET_L1], %l1
+	ldx [%o0 + __CONTEXT_OFFSET_L2], %l2
+	ldx [%o0 + __CONTEXT_OFFSET_L3], %l3
+	ldx [%o0 + __CONTEXT_OFFSET_L4], %l4
+	ldx [%o0 + __CONTEXT_OFFSET_L5], %l5
+	ldx [%o0 + __CONTEXT_OFFSET_L6], %l6
+	ldx [%o0 + __CONTEXT_OFFSET_L7], %l7
+	ldx [%o0 + __CONTEXT_OFFSET_TP], %g7
 	retl
-	mov %o1, %o0	! __longjmp returns second argument
-FUNCTION_END(__longjmp)
+	mov %o1, %o0	! __context_restore returns second argument
+FUNCTION_END(__context_restore)
Index: uspace/lib/c/arch/sparc64/src/rtld/dynamic.c
===================================================================
--- uspace/lib/c/arch/sparc64/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/sparc64/src/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libcsparc64
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtld/elf_dyn.h>
+#include <rtld/dynamic.h>
+
+void dyn_parse_arch(elf_dyn_t *dp, size_t bias, dyn_info_t *info)
+{
+	(void) dp;
+	(void) bias;
+	(void) info;
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc64/src/rtld/reloc.c
===================================================================
--- uspace/lib/c/arch/sparc64/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/arch/sparc64/src/rtld/reloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libcsparc64
+ * @brief
+ * @{
+ */
+/**
+ * @file
+ */
+
+#include <bitops.h>
+#include <mem.h>
+#include <smc.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <libarch/rtld/elf_dyn.h>
+#include <rtld/symbol.h>
+#include <rtld/rtld.h>
+#include <rtld/rtld_debug.h>
+#include <rtld/rtld_arch.h>
+
+static void fill_plt_entry_generic(uint32_t *, uintptr_t);
+
+void module_process_pre_arch(module_t *m)
+{
+	/* Unused */
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with implicit addends.
+ */
+void rel_table_process(module_t *m, elf_rel_t *rt, size_t rt_size)
+{
+
+	DPRINTF("rel table address: 0x%zx, size: %zd\n", (uintptr_t)rt, rt_size);
+	/* Unused */
+	(void)m;
+	(void)rt;
+	(void)rt_size;
+}
+
+/**
+ * Process (fixup) all relocations in a relocation table with explicit addends.
+ */
+void rela_table_process(module_t *m, elf_rela_t *rt, size_t rt_size)
+{
+	unsigned i;
+
+	size_t rt_entries;
+	size_t r_offset;
+	size_t r_addend;
+	elf_xword r_info;
+	unsigned rel_type;
+	elf_word sym_idx;
+	uintptr_t sym_addr;
+
+	elf_symbol_t *sym_table;
+	elf_symbol_t *sym;
+	uintptr_t *r_ptr;
+	uintptr_t sym_size;
+	char *str_tab;
+
+	elf_symbol_t *sym_def;
+	module_t *dest;
+	uint32_t *plt;
+
+	DPRINTF("parse relocation table\n");
+
+	sym_table = m->dyn.sym_tab;
+	rt_entries = rt_size / sizeof(elf_rela_t);
+	str_tab = m->dyn.str_tab;
+
+	plt = (uint32_t *)m->dyn.plt_got;
+
+	DPRINTF("rel table address: 0x%zx, entries: %zd\n", (uintptr_t)rt, rt_entries);
+
+	for (i = 0; i < rt_entries; ++i) {
+#if 0
+		DPRINTF("symbol %d: ", i);
+#endif
+		r_offset = rt[i].r_offset;
+		r_info = rt[i].r_info;
+		r_addend = rt[i].r_addend;
+
+		sym_idx = ELF64_R_SYM(r_info);
+		sym = &sym_table[sym_idx];
+
+#if 0
+		DPRINTF("name '%s', value 0x%x, size 0x%x\n",
+		    str_tab + sym->st_name,
+		    sym->st_value,
+		    sym->st_size);
+#endif
+		rel_type = ELF64_R_TYPE(r_info);
+		r_ptr = (uintptr_t *)(r_offset + m->bias);
+
+		if (sym->st_name != 0) {
+			DPRINTF("rel_type: %x, rel_offset: 0x%zx\n", rel_type, r_offset);
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_none, &dest);
+			DPRINTF("dest name: '%s'\n", dest->dyn.soname);
+			DPRINTF("dest bias: 0x%zx\n", dest->bias);
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+				DPRINTF("symbol definition found, value=0x%zx addr=0x%zx\n", sym_def->st_value, sym_addr);
+			} else {
+				printf("Definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+		} else {
+			sym_addr = 0;
+			sym_def = NULL;
+
+			/*
+			 * DTPMOD with null st_name should return the index
+			 * of the current module.
+			 */
+			dest = m;
+		}
+
+		switch (rel_type) {
+		case R_SPARC_COPY:
+			/*
+			 * Copy symbol data from shared object to specified
+			 * location. Need to find the 'source', i.e. the
+			 * other instance of the object than the one in the
+			 * executable program.
+			 */
+			DPRINTF("fixup R_SPARC_COPY (s)\n");
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			sym_size = sym->st_size;
+			if (sym_size != sym_def->st_size) {
+				printf("Warning: Mismatched symbol sizes.\n");
+				/* Take the lower value. */
+				if (sym_size > sym_def->st_size)
+					sym_size = sym_def->st_size;
+			}
+
+			memcpy(r_ptr, (const void *)sym_addr, sym_size);
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_GLOB_DAT:
+			DPRINTF("fixup R_SPARC_GLOB_DAT (S+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr);
+			*r_ptr = sym_addr + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_JMP_SLOT:
+			DPRINTF("fixup R_SPARC_JMP_SLOT (S)\n");
+			DPRINTF("r_offset=0x%zx r_addend=0x%zx\n",
+			    r_offset, r_addend);
+
+			sym_def = symbol_def_find(str_tab + sym->st_name,
+			    m, ssf_noexec, &dest);
+
+			if (sym_def) {
+				sym_addr = (uintptr_t)
+				    symbol_get_addr(sym_def, dest, NULL);
+			} else {
+				printf("Source definition of '%s' not found.\n",
+				    str_tab + sym->st_name);
+				continue;
+			}
+
+			DPRINTF("sym_addr = 0x%zx\n", sym_addr);
+			DPRINTF("r_offset=0x%zx\n", r_offset);
+
+			/*
+			 * Fill PLT entry with jump to symbol address.
+			 * r_ptr points to the PLT entry, sym_addr contains
+			 * address of the symbol.
+			 *
+			 * XXX This only works for the first 32768 entries.
+			 * If there are more, the layout is more complex.
+			 */
+			assert((uint32_t *)r_ptr - plt < 32768 * 8);
+			fill_plt_entry_generic((uint32_t *)r_ptr, sym_addr);
+			smc_coherence(r_ptr, 32);
+
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_RELATIVE:
+			DPRINTF("fixup R_SPARC_RELATIVE (B+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, m->bias + r_addend);
+			*r_ptr = m->bias + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_64:
+			DPRINTF("fixup R_SPARC_64 (S+A)\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_addr);
+			*r_ptr = sym_addr + r_addend;
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_TLS_DTPMOD64:
+			DPRINTF("fixup R_SPARC_TLS_DTPMOD64\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, (size_t)dest->id);
+			*r_ptr = dest->id;
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_TLS_DTPOFF64:
+			DPRINTF("fixup R_SPARC_TLS_DTPOFF64\n");
+			DPRINTF("*0x%zx = 0x%zx\n", (uintptr_t)r_ptr, sym_def->st_value);
+			*r_ptr = sym_def->st_value;
+			DPRINTF("OK\n");
+			break;
+
+		case R_SPARC_TLS_TPOFF64:
+			DPRINTF("fixup R_SPARC_TLS_TPOFF64\n");
+			*r_ptr = sym_def->st_value + dest->tpoff;
+			break;
+
+		default:
+			printf("Error: Unknown relocation type %d\n",
+			    rel_type);
+			exit(1);
+		}
+
+	}
+}
+
+/** Fill in generic PLT entry.
+ *
+ * Fill a PLT entry with SPARC instructions to jump to the specified
+ * address.
+ *
+ * @param plte Pointer to PLT entry to fill in
+ * @param ta Target address of the jump
+ */
+static void fill_plt_entry_generic(uint32_t *plte, uintptr_t ta)
+{
+	uint32_t hh, lm, hm, lo;
+
+	hh = BIT_RANGE_EXTRACT(uintptr_t, 63, 42, ta);
+	hm = BIT_RANGE_EXTRACT(uintptr_t, 41, 32, ta);
+	lm = BIT_RANGE_EXTRACT(uintptr_t, 31, 10, ta);
+	lo = BIT_RANGE_EXTRACT(uintptr_t, 9, 0, ta);
+
+	plte[0] = 0x01000000;      /* nop */
+	plte[1] = 0x03000000 | hh; /* sethi %hh(target), %g1 */
+	plte[2] = 0x0b000000 | lm; /* sethi %lm(target), %g5 */
+	plte[3] = 0x82106000 | hm; /* or %g1, %hm(target), %g1 */
+	plte[4] = 0x83287020;      /* sllx %g1, 32, %g1 */
+	plte[5] = 0x8a104005;      /* or %g1, %g5, %g5 */
+	plte[6] = 0x81c16000 | lo; /* jmpl %g5+lo(target),%g0 */
+	plte[7] = 0x01000000;      /* nop */
+
+	DPRINTF("Fill PTL entry at %p (target=0x%zx)\n",
+	    plte, ta);
+	for (unsigned i = 0; i < 8; i++) {
+		DPRINTF(" - [%d] = 0x%08x\n", i, plte[i]);
+	}
+}
+
+/** @}
+ */
Index: uspace/lib/c/arch/sparc64/src/tls.c
===================================================================
--- uspace/lib/c/arch/sparc64/src/tls.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/arch/sparc64/src/tls.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,8 @@
 #include <stddef.h>
 
+#ifdef CONFIG_RTLD
+#include <rtld/rtld.h>
+#endif
+
 tcb_t *tls_alloc_arch(size_t size, size_t align)
 {
@@ -48,4 +52,30 @@
 }
 
+/*
+ * Rtld TLS support
+ */
+
+typedef struct {
+	unsigned long int ti_module;
+	unsigned long int ti_offset;
+} tls_index;
+
+void *__tls_get_addr(tls_index *ti);
+
+void *__tls_get_addr(tls_index *ti)
+{
+	uint8_t *tls;
+
+#ifdef CONFIG_RTLD
+	if (runtime_env != NULL) {
+		return rtld_tls_get_addr(runtime_env, __tcb_get(),
+		    ti->ti_module, ti->ti_offset);
+	}
+#endif
+	/* Get address of static TLS block */
+	tls = tls_get();
+	return tls + ti->ti_offset;
+}
+
 /** @}
  */
Index: uspace/lib/c/doc/doxygroups.h
===================================================================
--- uspace/lib/c/doc/doxygroups.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/doc/doxygroups.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -17,4 +17,9 @@
 /**
  * @addtogroup libcarm32 arm32
+ * @ingroup libc
+ */
+
+/**
+ * @addtogroup libcarm64 arm64
  * @ingroup libc
  */
Index: uspace/lib/c/generic/adt/hash_table.c
===================================================================
--- uspace/lib/c/generic/adt/hash_table.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/adt/hash_table.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -245,5 +245,5 @@
  *
  */
-ht_link_t *hash_table_find(const hash_table_t *h, void *key)
+ht_link_t *hash_table_find(const hash_table_t *h, const void *key)
 {
 	assert(h && h->bucket);
@@ -303,9 +303,8 @@
  * @param key  Array of keys that will be compared against items of
  *             the hash table.
- * @param keys Number of keys in the 'key' array.
  *
  * @return Returns the number of removed items.
  */
-size_t hash_table_remove(hash_table_t *h, void *key)
+size_t hash_table_remove(hash_table_t *h, const void *key)
 {
 	assert(h && h->bucket);
Index: uspace/lib/c/generic/as.c
===================================================================
--- uspace/lib/c/generic/as.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/as.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -126,5 +126,5 @@
  *
  * @param      virt Virtual address to find mapping for.
- * @param[out] phys Physical adress.
+ * @param[out] phys Physical address.
  *
  * @return EOK on no error.
Index: uspace/lib/c/generic/async/client.c
===================================================================
--- uspace/lib/c/generic/async/client.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/async/client.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -95,10 +95,10 @@
  */
 
-#define LIBC_ASYNC_C_
+#define _LIBC_ASYNC_C_
 #include <ipc/ipc.h>
 #include <async.h>
 #include "../private/async.h"
 #include "../private/ns.h"
-#undef LIBC_ASYNC_C_
+#undef _LIBC_ASYNC_C_
 
 #include <ipc/irq.h>
@@ -216,5 +216,5 @@
 	fibril_rmutex_lock(&message_mutex);
 
-	msg->retval = IPC_GET_RETVAL(*data);
+	msg->retval = ipc_get_retval(data);
 
 	/* Copy data inside lock, just in case the call was detached */
@@ -249,5 +249,5 @@
  *
  */
-aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+static aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
 {
@@ -289,5 +289,5 @@
  *
  */
-aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+static aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     ipc_call_t *dataptr)
@@ -310,4 +310,41 @@
 
 	return (aid_t) msg;
+}
+
+aid_t async_send_0(async_exch_t *exch, sysarg_t imethod, ipc_call_t *dataptr)
+{
+	return async_send_fast(exch, imethod, 0, 0, 0, 0, dataptr);
+}
+
+aid_t async_send_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    ipc_call_t *dataptr)
+{
+	return async_send_fast(exch, imethod, arg1, 0, 0, 0, dataptr);
+}
+
+aid_t async_send_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, ipc_call_t *dataptr)
+{
+	return async_send_fast(exch, imethod, arg1, arg2, 0, 0, dataptr);
+}
+
+aid_t async_send_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, ipc_call_t *dataptr)
+{
+	return async_send_fast(exch, imethod, arg1, arg2, arg3, 0, dataptr);
+}
+
+aid_t async_send_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
+{
+	return async_send_fast(exch, imethod, arg1, arg2, arg3, arg4, dataptr);
+}
+
+aid_t async_send_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
+    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
+    ipc_call_t *dataptr)
+{
+	return async_send_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5,
+	    dataptr);
 }
 
@@ -434,7 +471,7 @@
  *
  */
-errno_t async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
-    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
-    sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+static errno_t async_req_fast(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
+    sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
 {
 	if (exch == NULL)
@@ -449,17 +486,17 @@
 
 	if (r1)
-		*r1 = IPC_GET_ARG1(result);
+		*r1 = ipc_get_arg1(&result);
 
 	if (r2)
-		*r2 = IPC_GET_ARG2(result);
+		*r2 = ipc_get_arg2(&result);
 
 	if (r3)
-		*r3 = IPC_GET_ARG3(result);
+		*r3 = ipc_get_arg3(&result);
 
 	if (r4)
-		*r4 = IPC_GET_ARG4(result);
+		*r4 = ipc_get_arg4(&result);
 
 	if (r5)
-		*r5 = IPC_GET_ARG5(result);
+		*r5 = ipc_get_arg5(&result);
 
 	return rc;
@@ -486,7 +523,7 @@
  *
  */
-errno_t async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1,
-    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1,
-    sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+static errno_t async_req_slow(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
+    sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
 {
 	if (exch == NULL)
@@ -501,19 +538,199 @@
 
 	if (r1)
-		*r1 = IPC_GET_ARG1(result);
+		*r1 = ipc_get_arg1(&result);
 
 	if (r2)
-		*r2 = IPC_GET_ARG2(result);
+		*r2 = ipc_get_arg2(&result);
 
 	if (r3)
-		*r3 = IPC_GET_ARG3(result);
+		*r3 = ipc_get_arg3(&result);
 
 	if (r4)
-		*r4 = IPC_GET_ARG4(result);
+		*r4 = ipc_get_arg4(&result);
 
 	if (r5)
-		*r5 = IPC_GET_ARG5(result);
+		*r5 = ipc_get_arg5(&result);
 
 	return rc;
+}
+
+errno_t async_req_0_0(async_exch_t *exch, sysarg_t imethod)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_0_1(async_exch_t *exch, sysarg_t imethod, sysarg_t *r1)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_0_2(async_exch_t *exch, sysarg_t imethod, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_0_3(async_exch_t *exch, sysarg_t imethod, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_0_4(async_exch_t *exch, sysarg_t imethod, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_0_5(async_exch_t *exch, sysarg_t imethod, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_fast(exch, imethod, 0, 0, 0, 0, r1, r2, r3, r4, r5);
+}
+
+errno_t async_req_1_0(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_1_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t *r1)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_1_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_1_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_1_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_1_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_fast(exch, imethod, arg1, 0, 0, 0, r1, r2, r3, r4, r5);
+}
+
+errno_t async_req_2_0(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_2_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t *r1)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_2_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_2_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_2_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_2_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, 0, 0, r1, r2, r3, r4, r5);
+}
+
+errno_t async_req_3_0(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_3_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t *r1)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_3_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_3_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_3_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_3_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, 0, r1, r2, r3, r4, r5);
+}
+
+errno_t async_req_4_0(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_4_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_4_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_4_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_4_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_4_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_fast(exch, imethod, arg1, arg2, arg3, arg4, r1, r2, r3, r4, r5);
+}
+
+errno_t async_req_5_0(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, NULL, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_5_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, r1, NULL, NULL, NULL, NULL);
+}
+
+errno_t async_req_5_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, sysarg_t *r2)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, r1, r2, NULL, NULL, NULL);
+}
+
+errno_t async_req_5_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, r1, r2, r3, NULL, NULL);
+}
+
+errno_t async_req_5_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, r1, r2, r3, r4, NULL);
+}
+
+errno_t async_req_5_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5)
+{
+	return async_req_slow(exch, imethod, arg1, arg2, arg3, arg4, arg5, r1, r2, r3, r4, r5);
 }
 
@@ -588,5 +805,5 @@
 		return rc;
 
-	*out_phone = (cap_phone_handle_t) IPC_GET_ARG5(result);
+	*out_phone = (cap_phone_handle_t) ipc_get_arg5(&result);
 	return EOK;
 }
@@ -926,6 +1143,6 @@
  *
  */
-errno_t async_share_in_start(async_exch_t *exch, size_t size, sysarg_t arg,
-    unsigned int *flags, void **dst)
+static errno_t async_share_in_start(async_exch_t *exch, size_t size,
+    sysarg_t arg, unsigned int *flags, void **dst)
 {
 	if (exch == NULL)
@@ -945,4 +1162,27 @@
 }
 
+errno_t async_share_in_start_0_0(async_exch_t *exch, size_t size, void **dst)
+{
+	return async_share_in_start(exch, size, 0, NULL, dst);
+}
+
+errno_t async_share_in_start_0_1(async_exch_t *exch, size_t size,
+    unsigned int *flags, void **dst)
+{
+	return async_share_in_start(exch, size, 0, flags, dst);
+}
+
+errno_t async_share_in_start_1_0(async_exch_t *exch, size_t size, sysarg_t arg,
+    void **dst)
+{
+	return async_share_in_start(exch, size, arg, NULL, dst);
+}
+
+errno_t async_share_in_start_1_1(async_exch_t *exch, size_t size, sysarg_t arg,
+    unsigned int *flags, void **dst)
+{
+	return async_share_in_start(exch, size, arg, flags, dst);
+}
+
 /** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
  *
@@ -1020,5 +1260,5 @@
 {
 	return async_req_5_0(exch, IPC_M_STATE_CHANGE_AUTHORIZE,
-	    arg1, arg2, arg3, 0, CAP_HANDLE_RAW(other_exch->phone));
+	    arg1, arg2, arg3, 0, cap_handle_raw(other_exch->phone));
 }
 
Index: uspace/lib/c/generic/async/ports.c
===================================================================
--- uspace/lib/c/generic/async/ports.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/async/ports.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,9 +27,9 @@
  */
 
-#define LIBC_ASYNC_C_
+#define _LIBC_ASYNC_C_
 #include <ipc/ipc.h>
 #include <async.h>
 #include "../private/async.h"
-#undef LIBC_ASYNC_C_
+#undef _LIBC_ASYNC_C_
 
 #include <ipc/irq.h>
@@ -103,8 +103,8 @@
 static hash_table_t interface_hash_table;
 
-static size_t interface_key_hash(void *key)
-{
-	iface_t iface = *(iface_t *) key;
-	return iface;
+static size_t interface_key_hash(const void *key)
+{
+	const iface_t *iface = key;
+	return *iface;
 }
 
@@ -115,9 +115,9 @@
 }
 
-static bool interface_key_equal(void *key, const ht_link_t *item)
-{
-	iface_t iface = *(iface_t *) key;
+static bool interface_key_equal(const void *key, const ht_link_t *item)
+{
+	const iface_t *iface = key;
 	interface_t *interface = hash_table_get_inst(item, interface_t, link);
-	return iface == interface->iface;
+	return *iface == interface->iface;
 }
 
@@ -131,8 +131,8 @@
 };
 
-static size_t port_key_hash(void *key)
-{
-	port_id_t port_id = *(port_id_t *) key;
-	return port_id;
+static size_t port_key_hash(const void *key)
+{
+	const port_id_t *port_id = key;
+	return *port_id;
 }
 
@@ -143,9 +143,9 @@
 }
 
-static bool port_key_equal(void *key, const ht_link_t *item)
-{
-	port_id_t port_id = *(port_id_t *) key;
+static bool port_key_equal(const void *key, const ht_link_t *item)
+{
+	const port_id_t *port_id = key;
 	port_t *port = hash_table_get_inst(item, port_t, link);
-	return port_id == port->id;
+	return *port_id == port->id;
 }
 
Index: uspace/lib/c/generic/async/server.c
===================================================================
--- uspace/lib/c/generic/async/server.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/async/server.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -96,9 +96,9 @@
  */
 
-#define LIBC_ASYNC_C_
+#define _LIBC_ASYNC_C_
 #include <ipc/ipc.h>
 #include <async.h>
 #include "../private/async.h"
-#undef LIBC_ASYNC_C_
+#undef _LIBC_ASYNC_C_
 
 #include <ipc/irq.h>
@@ -231,8 +231,8 @@
 static sysarg_t notification_avail = 0;
 
-static size_t client_key_hash(void *key)
-{
-	task_id_t in_task_id = *(task_id_t *) key;
-	return in_task_id;
+static size_t client_key_hash(const void *key)
+{
+	const task_id_t *in_task_id = key;
+	return *in_task_id;
 }
 
@@ -243,9 +243,9 @@
 }
 
-static bool client_key_equal(void *key, const ht_link_t *item)
-{
-	task_id_t in_task_id = *(task_id_t *) key;
+static bool client_key_equal(const void *key, const ht_link_t *item)
+{
+	const task_id_t *in_task_id = key;
 	client_t *client = hash_table_get_inst(item, client_t, link);
-	return in_task_id == client->in_task_id;
+	return *in_task_id == client->in_task_id;
 }
 
@@ -490,8 +490,8 @@
 }
 
-static size_t notification_key_hash(void *key)
-{
-	sysarg_t id = *(sysarg_t *) key;
-	return id;
+static size_t notification_key_hash(const void *key)
+{
+	const sysarg_t *id = key;
+	return *id;
 }
 
@@ -503,10 +503,10 @@
 }
 
-static bool notification_key_equal(void *key, const ht_link_t *item)
-{
-	sysarg_t id = *(sysarg_t *) key;
+static bool notification_key_equal(const void *key, const ht_link_t *item)
+{
+	const sysarg_t *id = key;
 	notification_t *notification =
 	    hash_table_get_inst(item, notification_t, htlink);
-	return id == notification->imethod;
+	return *id == notification->imethod;
 }
 
@@ -546,5 +546,5 @@
 	errno_t rc = mpsc_send(conn->msg_channel, call);
 
-	if (IPC_GET_IMETHOD(*call) == IPC_M_PHONE_HUNGUP) {
+	if (ipc_get_imethod(call) == IPC_M_PHONE_HUNGUP) {
 		/* Close the channel, but let the connection fibril answer. */
 		mpsc_close(conn->msg_channel);
@@ -656,6 +656,6 @@
 	}
 
-	ht_link_t *link = hash_table_find(&notification_hash_table,
-	    &IPC_GET_IMETHOD(*call));
+	sysarg_t imethod = ipc_get_imethod(call);
+	ht_link_t *link = hash_table_find(&notification_hash_table, &imethod);
 	if (!link) {
 		/* Invalid notification. */
@@ -871,7 +871,14 @@
 
 		memset(call, 0, sizeof(ipc_call_t));
+		ipc_set_imethod(call, IPC_M_PHONE_HUNGUP);
+		call->cap_handle = CAP_NIL;
 	}
 
 	return true;
+}
+
+bool async_get_call(ipc_call_t *call)
+{
+	return async_get_call_timeout(call, 0);
 }
 
@@ -937,5 +944,5 @@
 
 	/* New connection */
-	if (IPC_GET_IMETHOD(*call) == IPC_M_CONNECT_ME_TO) {
+	if (ipc_get_imethod(call) == IPC_M_CONNECT_ME_TO) {
 		connection_t *conn = calloc(1, sizeof(*conn));
 		if (!conn) {
@@ -944,5 +951,5 @@
 		}
 
-		iface_t iface = (iface_t) IPC_GET_ARG1(*call);
+		iface_t iface = (iface_t) ipc_get_arg1(call);
 
 		// TODO: Currently ignores all ports but the first one.
@@ -1001,5 +1008,5 @@
 
 /** Add one manager to manager list. */
-fid_t async_create_manager(void)
+static fid_t async_create_manager(void)
 {
 	fid_t fid = fibril_create_generic(async_manager_fibril, NULL, PAGE_SIZE);
@@ -1094,5 +1101,5 @@
 }
 
-errno_t async_forward_fast(ipc_call_t *call, async_exch_t *exch,
+static errno_t async_forward_fast(ipc_call_t *call, async_exch_t *exch,
     sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode)
 {
@@ -1110,5 +1117,5 @@
 }
 
-errno_t async_forward_slow(ipc_call_t *call, async_exch_t *exch,
+static errno_t async_forward_slow(ipc_call_t *call, async_exch_t *exch,
     sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     sysarg_t arg4, sysarg_t arg5, unsigned int mode)
@@ -1125,4 +1132,45 @@
 	return ipc_forward_slow(chandle, exch->phone, imethod, arg1, arg2, arg3,
 	    arg4, arg5, mode);
+}
+
+errno_t async_forward_0(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    unsigned int mode)
+{
+	return async_forward_fast(call, exch, imethod, 0, 0, mode);
+}
+
+errno_t async_forward_1(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, unsigned int mode)
+{
+	return async_forward_fast(call, exch, imethod, arg1, 0, mode);
+}
+
+errno_t async_forward_2(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
+{
+	return async_forward_fast(call, exch, imethod, arg1, arg2, mode);
+}
+
+errno_t async_forward_3(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, unsigned int mode)
+{
+	return async_forward_slow(call, exch, imethod, arg1, arg2, arg3, 0, 0,
+	    mode);
+}
+
+errno_t async_forward_4(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
+    unsigned int mode)
+{
+	return async_forward_slow(call, exch, imethod, arg1, arg2, arg3, arg4,
+	    0, mode);
+}
+
+errno_t async_forward_5(ipc_call_t *call, async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
+    unsigned int mode)
+{
+	return async_forward_slow(call, exch, imethod, arg1, arg2, arg3, arg4,
+	    arg5, mode);
 }
 
@@ -1173,8 +1221,8 @@
 	async_get_call(call);
 
-	if (IPC_GET_IMETHOD(*call) != IPC_M_SHARE_IN)
+	if (ipc_get_imethod(call) != IPC_M_SHARE_IN)
 		return false;
 
-	*size = (size_t) IPC_GET_ARG1(*call);
+	*size = (size_t) ipc_get_arg1(call);
 	return true;
 }
@@ -1228,9 +1276,9 @@
 	async_get_call(call);
 
-	if (IPC_GET_IMETHOD(*call) != IPC_M_SHARE_OUT)
+	if (ipc_get_imethod(call) != IPC_M_SHARE_OUT)
 		return false;
 
-	*size = (size_t) IPC_GET_ARG2(*call);
-	*flags = (unsigned int) IPC_GET_ARG3(*call);
+	*size = (size_t) ipc_get_arg2(call);
+	*flags = (unsigned int) ipc_get_arg3(call);
 	return true;
 }
@@ -1281,9 +1329,9 @@
 	async_get_call(call);
 
-	if (IPC_GET_IMETHOD(*call) != IPC_M_DATA_READ)
+	if (ipc_get_imethod(call) != IPC_M_DATA_READ)
 		return false;
 
 	if (size)
-		*size = (size_t) IPC_GET_ARG2(*call);
+		*size = (size_t) ipc_get_arg2(call);
 
 	return true;
@@ -1318,5 +1366,5 @@
  *
  */
-errno_t async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod,
+static errno_t async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod,
     sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
     ipc_call_t *dataptr)
@@ -1331,5 +1379,5 @@
 	}
 
-	aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
+	aid_t msg = async_send_4(exch, imethod, arg1, arg2, arg3, arg4,
 	    dataptr);
 	if (msg == 0) {
@@ -1352,4 +1400,72 @@
 }
 
+errno_t async_data_read_forward_0_0(async_exch_t *exch, sysarg_t imethod)
+{
+	return async_data_read_forward_fast(exch, imethod, 0, 0, 0, 0, NULL);
+}
+
+errno_t async_data_read_forward_1_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, 0, 0, 0, NULL);
+}
+
+errno_t async_data_read_forward_2_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, 0,
+	    0, NULL);
+}
+
+errno_t async_data_read_forward_3_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    0, NULL);
+}
+
+errno_t async_data_read_forward_4_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    arg4, NULL);
+}
+
+errno_t async_data_read_forward_0_1(async_exch_t *exch, sysarg_t imethod,
+    ipc_call_t *dataptr)
+{
+	return async_data_read_forward_fast(exch, imethod, 0, 0, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_read_forward_1_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, ipc_call_t *dataptr)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, 0, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_read_forward_2_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, ipc_call_t *dataptr)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_read_forward_3_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, ipc_call_t *dataptr)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    0, dataptr);
+}
+
+errno_t async_data_read_forward_4_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
+    ipc_call_t *dataptr)
+{
+	return async_data_read_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    arg4, dataptr);
+}
+
 /** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework.
  *
@@ -1372,9 +1488,9 @@
 	async_get_call(call);
 
-	if (IPC_GET_IMETHOD(*call) != IPC_M_DATA_WRITE)
+	if (ipc_get_imethod(call) != IPC_M_DATA_WRITE)
 		return false;
 
 	if (size)
-		*size = (size_t) IPC_GET_ARG2(*call);
+		*size = (size_t) ipc_get_arg2(call);
 
 	return true;
@@ -1495,7 +1611,7 @@
  *
  */
-errno_t async_data_write_forward_fast(async_exch_t *exch, sysarg_t imethod,
-    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
-    ipc_call_t *dataptr)
+static errno_t async_data_write_forward_fast(async_exch_t *exch,
+    sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
+    sysarg_t arg4, ipc_call_t *dataptr)
 {
 	if (exch == NULL)
@@ -1508,5 +1624,5 @@
 	}
 
-	aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4,
+	aid_t msg = async_send_4(exch, imethod, arg1, arg2, arg3, arg4,
 	    dataptr);
 	if (msg == 0) {
@@ -1529,4 +1645,74 @@
 }
 
+errno_t async_data_write_forward_0_0(async_exch_t *exch, sysarg_t imethod)
+{
+	return async_data_write_forward_fast(exch, imethod, 0, 0, 0,
+	    0, NULL);
+}
+
+errno_t async_data_write_forward_1_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, 0, 0,
+	    0, NULL);
+}
+
+errno_t async_data_write_forward_2_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, 0,
+	    0, NULL);
+}
+
+errno_t async_data_write_forward_3_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    0, NULL);
+}
+
+errno_t async_data_write_forward_4_0(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    arg4, NULL);
+}
+
+errno_t async_data_write_forward_0_1(async_exch_t *exch, sysarg_t imethod,
+    ipc_call_t *dataptr)
+{
+	return async_data_write_forward_fast(exch, imethod, 0, 0, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_write_forward_1_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, ipc_call_t *dataptr)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, 0, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_write_forward_2_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, ipc_call_t *dataptr)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, 0,
+	    0, dataptr);
+}
+
+errno_t async_data_write_forward_3_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, ipc_call_t *dataptr)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    0, dataptr);
+}
+
+errno_t async_data_write_forward_4_1(async_exch_t *exch, sysarg_t imethod,
+    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4,
+    ipc_call_t *dataptr)
+{
+	return async_data_write_forward_fast(exch, imethod, arg1, arg2, arg3,
+	    arg4, dataptr);
+}
+
 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
  *
@@ -1546,8 +1732,8 @@
 	async_get_call(&call);
 
-	cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(call);
-
-	if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) ||
-	    !CAP_HANDLE_VALID((phandle))) {
+	cap_phone_handle_t phandle = (cap_handle_t) ipc_get_arg5(&call);
+
+	if ((ipc_get_imethod(&call) != IPC_M_CONNECT_TO_ME) ||
+	    !cap_handle_valid((phandle))) {
 		async_answer_0(&call, EINVAL);
 		return NULL;
@@ -1590,8 +1776,8 @@
 async_sess_t *async_callback_receive_start(exch_mgmt_t mgmt, ipc_call_t *call)
 {
-	cap_phone_handle_t phandle = (cap_handle_t) IPC_GET_ARG5(*call);
-
-	if ((IPC_GET_IMETHOD(*call) != IPC_M_CONNECT_TO_ME) ||
-	    !CAP_HANDLE_VALID((phandle)))
+	cap_phone_handle_t phandle = (cap_handle_t) ipc_get_arg5(call);
+
+	if ((ipc_get_imethod(call) != IPC_M_CONNECT_TO_ME) ||
+	    !cap_handle_valid((phandle)))
 		return NULL;
 
@@ -1617,5 +1803,5 @@
 	async_get_call(call);
 
-	if (IPC_GET_IMETHOD(*call) != IPC_M_STATE_CHANGE_AUTHORIZE)
+	if (ipc_get_imethod(call) != IPC_M_STATE_CHANGE_AUTHORIZE)
 		return false;
 
@@ -1627,5 +1813,5 @@
 	assert(call);
 
-	return async_answer_1(call, EOK, CAP_HANDLE_RAW(other_exch->phone));
+	return async_answer_1(call, EOK, cap_handle_raw(other_exch->phone));
 }
 
Index: uspace/lib/c/generic/bd.c
===================================================================
--- uspace/lib/c/generic/bd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/bd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -206,10 +206,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		default:
 			async_answer_0(&call, ENOTSUP);
Index: uspace/lib/c/generic/bd_srv.c
===================================================================
--- uspace/lib/c/generic/bd_srv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/bd_srv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -51,6 +51,6 @@
 	errno_t rc;
 
-	ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
-	cnt = IPC_GET_ARG3(*call);
+	ba = MERGE_LOUP32(ipc_get_arg1(call), ipc_get_arg2(call));
+	cnt = ipc_get_arg3(call);
 
 	ipc_call_t rcall;
@@ -95,5 +95,5 @@
 	errno_t rc;
 
-	session = IPC_GET_ARG1(*call);
+	session = ipc_get_arg1(call);
 
 	ipc_call_t rcall;
@@ -137,6 +137,6 @@
 	errno_t rc;
 
-	ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
-	cnt = IPC_GET_ARG3(*call);
+	ba = MERGE_LOUP32(ipc_get_arg1(call), ipc_get_arg2(call));
+	cnt = ipc_get_arg3(call);
 
 	if (srv->srvs->ops->sync_cache == NULL) {
@@ -157,6 +157,6 @@
 	errno_t rc;
 
-	ba = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
-	cnt = IPC_GET_ARG3(*call);
+	ba = MERGE_LOUP32(ipc_get_arg1(call), ipc_get_arg2(call));
+	cnt = ipc_get_arg3(call);
 
 	rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
@@ -247,5 +247,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/lib/c/generic/context.c
===================================================================
--- uspace/lib/c/generic/context.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/context.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,11 +43,11 @@
 void context_swap(context_t *self, context_t *other)
 {
-	if (!__setjmp(self))
-		__longjmp(other, 1);
+	if (!__context_save(self))
+		__context_restore(other, 1);
 }
 
 void context_create(context_t *context, const context_create_t *arg)
 {
-	__setjmp(context);
+	__context_save(context);
 	context_set(context, FADDR(arg->fn), arg->stack_base,
 	    arg->stack_size, arg->tls);
Index: uspace/lib/c/generic/ctype.c
===================================================================
--- uspace/lib/c/generic/ctype.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/generic/ctype.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#include <ctype.h>
+
+int islower(int c)
+{
+	return ((c >= 'a') && (c <= 'z'));
+}
+
+int isupper(int c)
+{
+	return ((c >= 'A') && (c <= 'Z'));
+}
+
+int isalpha(int c)
+{
+	return (islower(c) || isupper(c));
+}
+
+int isdigit(int c)
+{
+	return ((c >= '0') && (c <= '9'));
+}
+
+int isalnum(int c)
+{
+	return (isalpha(c) || isdigit(c));
+}
+
+int isblank(int c)
+{
+	return c == ' ' || c == '\t';
+}
+
+int iscntrl(int c)
+{
+	return (c >= 0 && c < 0x20) || c == 0x7E;
+}
+
+int isprint(int c)
+{
+	return c >= 0 && c < 0x80 && !iscntrl(c);
+}
+
+int isgraph(int c)
+{
+	return isprint(c) && c != ' ';
+}
+
+int isspace(int c)
+{
+	switch (c) {
+	case ' ':
+	case '\n':
+	case '\t':
+	case '\f':
+	case '\r':
+	case '\v':
+		return 1;
+		break;
+	default:
+		return 0;
+	}
+}
+
+int ispunct(int c)
+{
+	return !isspace(c) && !isalnum(c) && isprint(c);
+}
+
+int isxdigit(int c)
+{
+	return isdigit(c) ||
+	    (c >= 'a' && c <= 'f') ||
+	    (c >= 'A' && c <= 'F');
+}
+
+int tolower(int c)
+{
+	if (isupper(c))
+		return (c + ('a' - 'A'));
+	else
+		return c;
+}
+
+int toupper(int c)
+{
+	if (islower(c))
+		return (c + ('A' - 'a'));
+	else
+		return c;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/devman.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -255,5 +255,5 @@
 	if (retval == EOK) {
 		if (funh != NULL)
-			*funh = (int) IPC_GET_ARG1(answer);
+			*funh = (int) ipc_get_arg1(&answer);
 	} else {
 		if (funh != NULL)
@@ -394,5 +394,5 @@
 
 	if (handle != NULL)
-		*handle = (devman_handle_t) IPC_GET_ARG1(answer);
+		*handle = (devman_handle_t) ipc_get_arg1(&answer);
 
 	return retval;
@@ -429,6 +429,6 @@
 
 	if (r1 != NULL)
-		*r1 = IPC_GET_ARG1(answer);
-	act_size = IPC_GET_ARG2(dreply);
+		*r1 = ipc_get_arg1(&answer);
+	act_size = ipc_get_arg2(&dreply);
 	assert(act_size <= buf_size - 1);
 	buf[act_size] = '\0';
@@ -517,5 +517,5 @@
 	}
 
-	*act_size = IPC_GET_ARG1(answer);
+	*act_size = ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -663,5 +663,5 @@
 
 	if (handle != NULL)
-		*handle = (devman_handle_t) IPC_GET_ARG1(answer);
+		*handle = (devman_handle_t) ipc_get_arg1(&answer);
 
 	return retval;
Index: uspace/lib/c/generic/dirent.c
===================================================================
--- uspace/lib/c/generic/dirent.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/dirent.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,11 @@
 #include <errno.h>
 #include <assert.h>
+#include <string.h>
+
+struct __dirstream {
+	int fd;
+	struct dirent res;
+	aoff64_t pos;
+};
 
 /** Open directory.
@@ -86,10 +93,12 @@
 	ssize_t len = 0;
 
-	rc = vfs_read_short(dirp->fd, dirp->pos, &dirp->res.d_name[0],
-	    NAME_MAX + 1, &len);
+	rc = vfs_read_short(dirp->fd, dirp->pos, dirp->res.d_name,
+	    sizeof(dirp->res.d_name), &len);
 	if (rc != EOK) {
 		errno = rc;
 		return NULL;
 	}
+
+	assert(strnlen(dirp->res.d_name, sizeof(dirp->res.d_name)) < sizeof(dirp->res.d_name));
 
 	dirp->pos += len;
Index: uspace/lib/c/generic/dlfcn.c
===================================================================
--- uspace/lib/c/generic/dlfcn.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/dlfcn.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,4 +35,5 @@
  */
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -53,5 +54,12 @@
 	if (m == NULL) {
 		m = module_load(runtime_env, path, mlf_local);
-		module_load_deps(m, mlf_local);
+		if (m == NULL) {
+			return NULL;
+		}
+
+		if (module_load_deps(m, mlf_local) != EOK) {
+			return NULL;
+		}
+
 		/* Now relocate. */
 		module_process_relocs(m);
Index: uspace/lib/c/generic/dnsr.c
===================================================================
--- uspace/lib/c/generic/dnsr.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/dnsr.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -125,5 +125,5 @@
 	}
 
-	size_t act_size = IPC_GET_ARG2(answer_cname);
+	size_t act_size = ipc_get_arg2(&answer_cname);
 	assert(act_size <= DNSR_NAME_MAX_SIZE);
 
Index: uspace/lib/c/generic/double_to_str.c
===================================================================
--- uspace/lib/c/generic/double_to_str.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/double_to_str.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -503,5 +503,5 @@
 {
 	/* The whole computation assumes 64bit significand. */
-	static_assert(sizeof(ieee_val.pos_val.significand) == sizeof(uint64_t));
+	static_assert(sizeof(ieee_val.pos_val.significand) == sizeof(uint64_t), "");
 
 	if (ieee_val.is_special) {
@@ -754,5 +754,5 @@
 {
 	/* The whole computation assumes 64bit significand. */
-	static_assert(sizeof(ieee_val.pos_val.significand) == sizeof(uint64_t));
+	static_assert(sizeof(ieee_val.pos_val.significand) == sizeof(uint64_t), "");
 
 	if (ieee_val.is_special) {
Index: uspace/lib/c/generic/elf/elf_load.c
===================================================================
--- uspace/lib/c/generic/elf/elf_load.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/elf/elf_load.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -53,15 +53,15 @@
  * @param file File handle
  * @param info Place to store ELF program information
- * @return EE_OK on success or an EE_x error code
+ * @return EOK on success or an error code
  */
-int elf_load(int file, elf_info_t *info)
+errno_t elf_load(int file, elf_info_t *info)
 {
 #ifdef CONFIG_RTLD
 	rtld_t *env;
 #endif
-	int rc;
+	errno_t rc;
 
 	rc = elf_load_file(file, 0, &info->finfo);
-	if (rc != EE_OK) {
+	if (rc != EOK) {
 		DPRINTF("Failed to load executable '%s'.\n", file_name);
 		return rc;
@@ -72,5 +72,5 @@
 		DPRINTF("Binary is statically linked.\n");
 		info->env = NULL;
-		return EE_OK;
+		return EOK;
 	}
 
@@ -79,20 +79,8 @@
 	DPRINTF("- prog dynamic: %p\n", info->finfo.dynamic);
 
-	errno_t rc2 = rtld_prog_process(&info->finfo, &env);
-	switch (rc2) {
-	case EOK:
-		rc = EE_OK;
-		break;
-	case ENOMEM:
-		rc = EE_MEMORY;
-		break;
-	default:
-		DPRINTF("Unexpected error code from rtld_prog_process(): %s\n", str_error_name(rc2));
-		rc = EE_INVALID;
-	}
-
+	rc = rtld_prog_process(&info->finfo, &env);
 	info->env = env;
 #else
-	rc = EE_UNSUPPORTED;
+	rc = ENOTSUP;
 #endif
 	return rc;
Index: uspace/lib/c/generic/elf/elf_mod.c
===================================================================
--- uspace/lib/c/generic/elf/elf_mod.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/elf/elf_mod.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -64,17 +64,7 @@
 #define DPRINTF(...)
 
-static const char *error_codes[] = {
-	"no error",
-	"invalid image",
-	"address space error",
-	"incompatible image",
-	"unsupported image type",
-	"irrecoverable error",
-	"file io error"
-};
-
-static unsigned int elf_load_module(elf_ld_t *elf);
-static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
-static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
+static errno_t elf_load_module(elf_ld_t *elf);
+static errno_t segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
+static errno_t load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
 
 /** Load ELF binary from a file.
@@ -90,8 +80,8 @@
  *                  extracted from the binary.
  *
- * @return EE_OK on success or EE_xx error code.
- *
- */
-int elf_load_file(int file, eld_flags_t flags, elf_finfo_t *info)
+ * @return EOK on success or an error code.
+ *
+ */
+errno_t elf_load_file(int file, eld_flags_t flags, elf_finfo_t *info)
 {
 	elf_ld_t elf;
@@ -103,5 +93,5 @@
 	}
 	if (rc != EOK) {
-		return EE_IO;
+		return rc;
 	}
 
@@ -110,20 +100,20 @@
 	elf.flags = flags;
 
-	int ret = elf_load_module(&elf);
+	rc = elf_load_module(&elf);
 
 	vfs_put(ofile);
-	return ret;
-}
-
-int elf_load_file_name(const char *path, eld_flags_t flags, elf_finfo_t *info)
+	return rc;
+}
+
+errno_t elf_load_file_name(const char *path, eld_flags_t flags, elf_finfo_t *info)
 {
 	int file;
 	errno_t rc = vfs_lookup(path, 0, &file);
 	if (rc == EOK) {
-		int ret = elf_load_file(file, flags, info);
+		rc = elf_load_file(file, flags, info);
 		vfs_put(file);
-		return ret;
+		return rc;
 	} else {
-		return EE_IO;
+		return EIO;
 	}
 }
@@ -136,7 +126,7 @@
  *
  * @param elf		Pointer to loader state buffer.
- * @return EE_OK on success or EE_xx error code.
- */
-static unsigned int elf_load_module(elf_ld_t *elf)
+ * @return EOK on success or an error code.
+ */
+static errno_t elf_load_module(elf_ld_t *elf)
 {
 	elf_header_t header_buf;
@@ -144,5 +134,5 @@
 	aoff64_t pos = 0;
 	size_t nr;
-	int i, ret;
+	int i;
 	errno_t rc;
 
@@ -150,5 +140,5 @@
 	if (rc != EOK || nr != sizeof(elf_header_t)) {
 		DPRINTF("Read error.\n");
-		return EE_IO;
+		return EIO;
 	}
 
@@ -159,5 +149,5 @@
 	    header->e_ident[EI_MAG3] != ELFMAG3) {
 		DPRINTF("Invalid header.\n");
-		return EE_INVALID;
+		return EINVAL;
 	}
 
@@ -169,5 +159,5 @@
 	    header->e_ident[EI_CLASS] != ELF_CLASS) {
 		DPRINTF("Incompatible data/version/class.\n");
-		return EE_INCOMPATIBLE;
+		return EINVAL;
 	}
 
@@ -175,5 +165,5 @@
 		DPRINTF("e_phentsize: %u != %zu\n", header->e_phentsize,
 		    sizeof(elf_segment_header_t));
-		return EE_INCOMPATIBLE;
+		return EINVAL;
 	}
 
@@ -181,10 +171,10 @@
 	if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
 		DPRINTF("Object type %d is not supported\n", header->e_type);
-		return EE_UNSUPPORTED;
+		return ENOTSUP;
 	}
 
 	if (header->e_phoff == 0) {
 		DPRINTF("Program header table is not present!\n");
-		return EE_UNSUPPORTED;
+		return ENOTSUP;
 	}
 
@@ -203,5 +193,5 @@
 	if (phdr_len > sizeof(phdr)) {
 		DPRINTF("more than %d program headers\n", phdr_cap);
-		return EE_UNSUPPORTED;
+		return ENOTSUP;
 	}
 
@@ -210,5 +200,5 @@
 	if (rc != EOK || nr != phdr_len) {
 		DPRINTF("Read error.\n");
-		return EE_IO;
+		return EIO;
 	}
 
@@ -231,5 +221,5 @@
 	if (base_offset != 0) {
 		DPRINTF("ELF headers not present in the text segment.\n");
-		return EE_INVALID;
+		return EINVAL;
 	}
 
@@ -240,5 +230,5 @@
 		if (module_base != 0) {
 			DPRINTF("Unexpected shared object format.\n");
-			return EE_INVALID;
+			return EINVAL;
 		}
 
@@ -258,5 +248,5 @@
 		if (area == AS_MAP_FAILED) {
 			DPRINTF("Can't find suitable memory area.\n");
-			return EE_MEMORY;
+			return ENOMEM;
 		}
 
@@ -270,7 +260,7 @@
 			continue;
 
-		ret = load_segment(elf, &phdr[i]);
-		if (ret != EE_OK)
-			return ret;
+		rc = load_segment(elf, &phdr[i]);
+		if (rc != EOK)
+			return rc;
 	}
 
@@ -292,7 +282,7 @@
 			continue;
 
-		ret = segment_header(elf, &phdr[i]);
-		if (ret != EE_OK)
-			return ret;
+		rc = segment_header(elf, &phdr[i]);
+		if (rc != EOK)
+			return rc;
 	}
 
@@ -302,18 +292,5 @@
 	DPRINTF("Done.\n");
 
-	return EE_OK;
-}
-
-/** Print error message according to error code.
- *
- * @param rc Return code returned by elf_load().
- *
- * @return NULL terminated description of error.
- */
-const char *elf_error(unsigned int rc)
-{
-	assert(rc < sizeof(error_codes) / sizeof(char *));
-
-	return error_codes[rc];
+	return EOK;
 }
 
@@ -338,7 +315,7 @@
  * @param entry	Segment header.
  *
- * @return EE_OK on success, error code otherwise.
- */
-static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
+ * @return EOK on success, error code otherwise.
+ */
+static errno_t segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
 {
 	switch (entry->p_type) {
@@ -358,9 +335,9 @@
 		if (entry->p_filesz == 0) {
 			DPRINTF("Zero-sized ELF interp string.\n");
-			return EE_INVALID;
+			return EINVAL;
 		}
 		if (elf->info->interp[entry->p_filesz - 1] != '\0') {
 			DPRINTF("Unterminated ELF interp string.\n");
-			return EE_INVALID;
+			return EINVAL;
 		}
 		DPRINTF("interpreter: \"%s\"\n", elf->info->interp);
@@ -389,8 +366,8 @@
 	default:
 		DPRINTF("Segment p_type %d unknown.\n", entry->p_type);
-		return EE_UNSUPPORTED;
-		break;
-	}
-	return EE_OK;
+		return ENOTSUP;
+		break;
+	}
+	return EOK;
 }
 
@@ -400,7 +377,7 @@
  * @param entry Program header entry describing segment to be loaded.
  *
- * @return EE_OK on success, error code otherwise.
- */
-int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
+ * @return EOK on success, error code otherwise.
+ */
+errno_t load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
 {
 	void *a;
@@ -420,6 +397,11 @@
 	seg_ptr = (void *) seg_addr;
 
-	DPRINTF("Load segment at addr %p, size 0x%zx\n", (void *) seg_addr,
-	    entry->p_memsz);
+	DPRINTF("Load segment v_addr=0x%zx at addr %p, size 0x%zx, flags %c%c%c\n",
+	    entry->p_vaddr,
+	    (void *) seg_addr,
+	    entry->p_memsz,
+	    (entry->p_flags & PF_R) ? 'r' : '-',
+	    (entry->p_flags & PF_W) ? 'w' : '-',
+	    (entry->p_flags & PF_X) ? 'x' : '-');
 
 	if (entry->p_align > 1) {
@@ -427,8 +409,8 @@
 		    (seg_addr % entry->p_align)) {
 			DPRINTF("Align check 1 failed offset%%align=0x%zx, "
-			    "vaddr%%align=0x%zx\n",
+			    "vaddr%%align=0x%zx align=0x%zx\n",
 			    entry->p_offset % entry->p_align,
-			    seg_addr % entry->p_align);
-			return EE_INVALID;
+			    seg_addr % entry->p_align, entry->p_align);
+			return EINVAL;
 		}
 	}
@@ -461,5 +443,5 @@
 		DPRINTF("memory mapping failed (%p, %zu)\n",
 		    (void *) (base + bias), mem_sz);
-		return EE_MEMORY;
+		return ENOMEM;
 	}
 
@@ -474,5 +456,5 @@
 	if (rc != EOK || nr != entry->p_filesz) {
 		DPRINTF("read error\n");
-		return EE_IO;
+		return EIO;
 	}
 
@@ -482,10 +464,12 @@
 	 */
 	if ((elf->flags & ELDF_RW) != 0)
-		return EE_OK;
-
-	rc = as_area_change_flags(seg_ptr, flags);
+		return EOK;
+
+	DPRINTF("as_area_change_flags(%p, %x)\n",
+	    (uint8_t *) base + bias, flags);
+	rc = as_area_change_flags((uint8_t *) base + bias, flags);
 	if (rc != EOK) {
 		DPRINTF("Failed to set memory area flags.\n");
-		return EE_MEMORY;
+		return ENOMEM;
 	}
 
@@ -493,8 +477,8 @@
 		/* Enforce SMC coherence for the segment */
 		if (smc_coherence(seg_ptr, entry->p_filesz))
-			return EE_MEMORY;
-	}
-
-	return EE_OK;
+			return ENOMEM;
+	}
+
+	return EOK;
 }
 
Index: uspace/lib/c/generic/gsort.c
===================================================================
--- uspace/lib/c/generic/gsort.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/gsort.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,8 +33,7 @@
 /**
  * @file
- * @brief Sorting functions.
+ * @brief Gnome Sort.
  *
- * This files contains functions implementing several sorting
- * algorithms (e.g. quick sort and gnome sort).
+ * This file contains an implementation of gnome sort
  *
  */
@@ -80,5 +79,5 @@
 		if ((i != 0) &&
 		    (cmp(INDEX(data, i, elem_size),
-		    INDEX(data, i - 1, elem_size), arg) == -1)) {
+		    INDEX(data, i - 1, elem_size), arg) < 0)) {
 			memcpy(slot, INDEX(data, i, elem_size), elem_size);
 			memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size),
Index: uspace/lib/c/generic/ieee_double.c
===================================================================
--- uspace/lib/c/generic/ieee_double.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/ieee_double.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,5 +45,5 @@
 	const int exponent_bias = 1075;
 
-	static_assert(sizeof(val) == sizeof(uint64_t));
+	static_assert(sizeof(val) == sizeof(uint64_t), "");
 
 	union {
Index: uspace/lib/c/generic/imath.c
===================================================================
--- uspace/lib/c/generic/imath.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/imath.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,5 +50,5 @@
 errno_t ipow10_u64(unsigned exp, uint64_t *res)
 {
-	unsigned a;
+	uint64_t a;
 	uint64_t r;
 
Index: uspace/lib/c/generic/inet.c
===================================================================
--- uspace/lib/c/generic/inet.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/inet.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -180,6 +180,6 @@
 	inet_dgram_t dgram;
 
-	dgram.tos = IPC_GET_ARG1(*icall);
-	dgram.iplink = IPC_GET_ARG2(*icall);
+	dgram.tos = ipc_get_arg1(icall);
+	dgram.iplink = ipc_get_arg2(icall);
 
 	ipc_call_t call;
@@ -240,10 +240,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case INET_EV_RECV:
 			inet_ev_recv(&call);
Index: uspace/lib/c/generic/inet/tcp.c
===================================================================
--- uspace/lib/c/generic/inet/tcp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/inet/tcp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -232,5 +232,5 @@
 		goto error;
 
-	conn_id = IPC_GET_ARG1(answer);
+	conn_id = ipc_get_arg1(&answer);
 
 	rc = tcp_conn_new(tcp, conn_id, cb, arg, rconn);
@@ -348,5 +348,5 @@
 
 	lst->tcp = tcp;
-	lst->id = IPC_GET_ARG1(answer);
+	lst->id = ipc_get_arg1(&answer);
 	lst->lcb = lcb;
 	lst->lcb_arg = larg;
@@ -569,5 +569,5 @@
 	}
 
-	*nrecv = IPC_GET_ARG1(answer);
+	*nrecv = ipc_get_arg1(&answer);
 	fibril_mutex_unlock(&conn->lock);
 	return EOK;
@@ -626,5 +626,5 @@
 	}
 
-	*nrecv = IPC_GET_ARG1(answer);
+	*nrecv = ipc_get_arg1(&answer);
 	fibril_mutex_unlock(&conn->lock);
 	return EOK;
@@ -643,5 +643,5 @@
 	errno_t rc;
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	rc = tcp_conn_get(tcp, conn_id, &conn);
@@ -671,5 +671,5 @@
 	errno_t rc;
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	rc = tcp_conn_get(tcp, conn_id, &conn);
@@ -699,5 +699,5 @@
 	errno_t rc;
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	rc = tcp_conn_get(tcp, conn_id, &conn);
@@ -727,5 +727,5 @@
 	errno_t rc;
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	rc = tcp_conn_get(tcp, conn_id, &conn);
@@ -771,6 +771,6 @@
 	errno_t rc;
 
-	lst_id = IPC_GET_ARG1(*icall);
-	conn_id = IPC_GET_ARG2(*icall);
+	lst_id = ipc_get_arg1(icall);
+	conn_id = ipc_get_arg2(icall);
 
 	rc = tcp_listener_get(tcp, lst_id, &lst);
@@ -821,5 +821,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* Hangup*/
 			async_answer_0(&call, EOK);
@@ -827,5 +827,5 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case TCP_EV_CONNECTED:
 			tcp_ev_connected(tcp, &call);
Index: uspace/lib/c/generic/inet/udp.c
===================================================================
--- uspace/lib/c/generic/inet/udp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/inet/udp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -190,5 +190,5 @@
 
 	assoc->udp = udp;
-	assoc->id = IPC_GET_ARG1(answer);
+	assoc->id = ipc_get_arg1(&answer);
 	assoc->cb = cb;
 	assoc->cb_arg = arg;
@@ -404,6 +404,6 @@
 
 	rmsg->udp = udp;
-	rmsg->assoc_id = IPC_GET_ARG1(answer);
-	rmsg->size = IPC_GET_ARG2(answer);
+	rmsg->assoc_id = ipc_get_arg1(&answer);
+	rmsg->size = ipc_get_arg2(&answer);
 	rmsg->remote_ep = ep;
 	return EOK;
@@ -498,5 +498,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			/* Hangup */
 			async_answer_0(&call, EOK);
@@ -504,5 +504,5 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case UDP_EV_DATA:
 			udp_ev_data(udp, &call);
Index: uspace/lib/c/generic/inetcfg.c
===================================================================
--- uspace/lib/c/generic/inetcfg.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/inetcfg.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,5 +62,5 @@
 	}
 
-	*act_size = IPC_GET_ARG1(answer);
+	*act_size = ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -161,5 +161,5 @@
 	async_wait_for(req, &retval);
 
-	*addr_id = IPC_GET_ARG1(answer);
+	*addr_id = ipc_get_arg1(&answer);
 
 	return retval;
@@ -217,10 +217,10 @@
 		return retval;
 
-	size_t act_size = IPC_GET_ARG2(answer_name);
+	size_t act_size = ipc_get_arg2(&answer_name);
 	assert(act_size <= LOC_NAME_MAXLEN);
 
 	name_buf[act_size] = '\0';
 
-	ainfo->ilink = IPC_GET_ARG1(answer);
+	ainfo->ilink = ipc_get_arg1(&answer);
 	ainfo->name = str_dup(name_buf);
 
@@ -244,5 +244,5 @@
 
 	async_wait_for(req, &retval);
-	*addr_id = IPC_GET_ARG1(answer);
+	*addr_id = ipc_get_arg1(&answer);
 
 	return retval;
@@ -305,10 +305,10 @@
 		return retval;
 
-	act_size = IPC_GET_ARG2(dreply);
+	act_size = ipc_get_arg2(&dreply);
 	assert(act_size <= LOC_NAME_MAXLEN);
 	name_buf[act_size] = '\0';
 
 	linfo->name = str_dup(name_buf);
-	linfo->def_mtu = IPC_GET_ARG1(answer);
+	linfo->def_mtu = ipc_get_arg1(&answer);
 
 	return EOK;
@@ -359,5 +359,5 @@
 	async_wait_for(req, &retval);
 
-	*sroute_id = IPC_GET_ARG1(answer);
+	*sroute_id = ipc_get_arg1(&answer);
 
 	return retval;
@@ -428,5 +428,5 @@
 		return retval;
 
-	size_t act_size = IPC_GET_ARG2(answer_name);
+	size_t act_size = ipc_get_arg2(&answer_name);
 	assert(act_size <= LOC_NAME_MAXLEN);
 
@@ -454,5 +454,5 @@
 
 	async_wait_for(req, &retval);
-	*sroute_id = IPC_GET_ARG1(answer);
+	*sroute_id = ipc_get_arg1(&answer);
 
 	return retval;
Index: uspace/lib/c/generic/inetping.c
===================================================================
--- uspace/lib/c/generic/inetping.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/inetping.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -154,5 +154,5 @@
 	inetping_sdu_t sdu;
 
-	sdu.seq_no = IPC_GET_ARG1(*icall);
+	sdu.seq_no = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -213,10 +213,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case INETPING_EV_RECV:
 			inetping_ev_recv(&call);
Index: uspace/lib/c/generic/io/asprintf.c
===================================================================
--- uspace/lib/c/generic/io/asprintf.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/asprintf.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -51,5 +51,5 @@
 }
 
-int vprintf_size(const char *fmt, va_list args)
+int vprintf_length(const char *fmt, va_list args)
 {
 	printf_spec_t ps = {
@@ -62,9 +62,9 @@
 }
 
-int printf_size(const char *fmt, ...)
+int printf_length(const char *fmt, ...)
 {
 	va_list args;
 	va_start(args, fmt);
-	int ret = vprintf_size(fmt, args);
+	int ret = vprintf_length(fmt, args);
 	va_end(args);
 
@@ -86,13 +86,13 @@
 	va_list args2;
 	va_copy(args2, args);
-	int ret = vprintf_size(fmt, args2);
+	int ret = vsnprintf(NULL, 0, fmt, args2);
 	va_end(args2);
 
 	if (ret > 0) {
-		*strp = malloc(STR_BOUNDS(ret) + 1);
+		*strp = malloc(ret + 1);
 		if (*strp == NULL)
 			return -1;
 
-		vsnprintf(*strp, STR_BOUNDS(ret) + 1, fmt, args);
+		vsnprintf(*strp, ret + 1, fmt, args);
 	}
 
Index: uspace/lib/c/generic/io/chardev.c
===================================================================
--- uspace/lib/c/generic/io/chardev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/chardev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -91,8 +91,11 @@
  * @param size Maximum number of bytes to read
  * @param nread Place to store actual number of bytes read
+ * @param flags @c chardev_f_nonblock to return immediately even if no
+ *              bytes are available
  *
  * @return EOK on success or non-zero error code
  */
-errno_t chardev_read(chardev_t *chardev, void *buf, size_t size, size_t *nread)
+errno_t chardev_read(chardev_t *chardev, void *buf, size_t size, size_t *nread,
+    chardev_flags_t flags)
 {
 	async_exch_t *exch = async_exchange_begin(chardev->sess);
@@ -104,5 +107,5 @@
 
 	ipc_call_t answer;
-	aid_t req = async_send_0(exch, CHARDEV_READ, &answer);
+	aid_t req = async_send_1(exch, CHARDEV_READ, flags, &answer);
 	errno_t rc = async_data_read_start(exch, buf, size);
 	async_exchange_end(exch);
@@ -122,7 +125,7 @@
 	}
 
-	*nread = IPC_GET_ARG2(answer);
+	*nread = ipc_get_arg2(&answer);
 	/* In case of partial success, ARG1 contains the error code */
-	return (errno_t) IPC_GET_ARG1(answer);
+	return (errno_t) ipc_get_arg1(&answer);
 
 }
@@ -173,7 +176,7 @@
 	}
 
-	*nwritten = IPC_GET_ARG2(answer);
+	*nwritten = ipc_get_arg2(&answer);
 	/* In case of partial success, ARG1 contains the error code */
-	return (errno_t) IPC_GET_ARG1(answer);
+	return (errno_t) ipc_get_arg1(&answer);
 }
 
Index: uspace/lib/c/generic/io/chardev_srv.c
===================================================================
--- uspace/lib/c/generic/io/chardev_srv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/chardev_srv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -48,5 +48,8 @@
 	size_t size;
 	size_t nread;
+	chardev_flags_t flags;
 	errno_t rc;
+
+	flags = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -70,5 +73,5 @@
 	}
 
-	rc = srv->srvs->ops->read(srv, buf, size, &nread);
+	rc = srv->srvs->ops->read(srv, buf, size, &nread, flags);
 	if (rc != EOK && nread == 0) {
 		async_answer_0(&call, rc);
@@ -151,5 +154,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/lib/c/generic/io/chargrid.c
===================================================================
--- uspace/lib/c/generic/io/chargrid.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/chargrid.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -263,4 +263,7 @@
 void chargrid_set_cursor(chargrid_t *scrbuf, sysarg_t col, sysarg_t row)
 {
+	if (col >= scrbuf->cols || row >= scrbuf->rows)
+		return;
+
 	scrbuf->col = col;
 	scrbuf->row = row;
Index: uspace/lib/c/generic/io/con_srv.c
===================================================================
--- uspace/lib/c/generic/io/con_srv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/con_srv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -44,18 +44,18 @@
 static errno_t console_ev_encode(cons_event_t *event, ipc_call_t *icall)
 {
-	IPC_SET_ARG1(*icall, event->type);
+	ipc_set_arg1(icall, event->type);
 
 	switch (event->type) {
 	case CEV_KEY:
-		IPC_SET_ARG2(*icall, event->ev.key.type);
-		IPC_SET_ARG3(*icall, event->ev.key.key);
-		IPC_SET_ARG4(*icall, event->ev.key.mods);
-		IPC_SET_ARG5(*icall, event->ev.key.c);
+		ipc_set_arg2(icall, event->ev.key.type);
+		ipc_set_arg3(icall, event->ev.key.key);
+		ipc_set_arg4(icall, event->ev.key.mods);
+		ipc_set_arg5(icall, event->ev.key.c);
 		break;
 	case CEV_POS:
-		IPC_SET_ARG2(*icall, (event->ev.pos.pos_id << 16) | (event->ev.pos.type & 0xffff));
-		IPC_SET_ARG3(*icall, event->ev.pos.btn_num);
-		IPC_SET_ARG4(*icall, event->ev.pos.hpos);
-		IPC_SET_ARG5(*icall, event->ev.pos.vpos);
+		ipc_set_arg2(icall, (event->ev.pos.pos_id << 16) | (event->ev.pos.type & 0xffff));
+		ipc_set_arg3(icall, event->ev.pos.btn_num);
+		ipc_set_arg4(icall, event->ev.pos.hpos);
+		ipc_set_arg5(icall, event->ev.pos.vpos);
 		break;
 	default:
@@ -158,6 +158,6 @@
 	sysarg_t row;
 
-	col = IPC_GET_ARG1(*icall);
-	row = IPC_GET_ARG2(*icall);
+	col = ipc_get_arg1(icall);
+	row = ipc_get_arg2(icall);
 
 	if (srv->srvs->ops->set_pos == NULL) {
@@ -218,5 +218,5 @@
 	console_style_t style;
 
-	style = IPC_GET_ARG1(*icall);
+	style = ipc_get_arg1(icall);
 
 	if (srv->srvs->ops->set_style == NULL) {
@@ -235,7 +235,7 @@
 	console_color_attr_t flags;
 
-	bgcolor = IPC_GET_ARG1(*icall);
-	fgcolor = IPC_GET_ARG2(*icall);
-	flags = IPC_GET_ARG3(*icall);
+	bgcolor = ipc_get_arg1(icall);
+	fgcolor = ipc_get_arg2(icall);
+	flags = ipc_get_arg3(icall);
 
 	if (srv->srvs->ops->set_color == NULL) {
@@ -253,6 +253,6 @@
 	pixel_t fgcolor;
 
-	bgcolor = IPC_GET_ARG1(*icall);
-	fgcolor = IPC_GET_ARG2(*icall);
+	bgcolor = ipc_get_arg1(icall);
+	fgcolor = ipc_get_arg2(icall);
 
 	if (srv->srvs->ops->set_rgb_color == NULL) {
@@ -269,5 +269,5 @@
 	bool show;
 
-	show = IPC_GET_ARG1(*icall);
+	show = ipc_get_arg1(icall);
 
 	if (srv->srvs->ops->set_cursor_visibility == NULL) {
@@ -303,6 +303,6 @@
 	}
 
-	async_answer_5(icall, rc, IPC_GET_ARG1(result), IPC_GET_ARG2(result),
-	    IPC_GET_ARG3(result), IPC_GET_ARG4(result), IPC_GET_ARG5(result));
+	async_answer_5(icall, rc, ipc_get_arg1(&result), ipc_get_arg2(&result),
+	    ipc_get_arg3(&result), ipc_get_arg4(&result), ipc_get_arg5(&result));
 }
 
@@ -364,5 +364,5 @@
 			break;
 
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/lib/c/generic/io/console.c
===================================================================
--- uspace/lib/c/generic/io/console.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/console.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -156,19 +156,19 @@
 static errno_t console_ev_decode(ipc_call_t *call, cons_event_t *event)
 {
-	event->type = IPC_GET_ARG1(*call);
+	event->type = ipc_get_arg1(call);
 
 	switch (event->type) {
 	case CEV_KEY:
-		event->ev.key.type = IPC_GET_ARG2(*call);
-		event->ev.key.key = IPC_GET_ARG3(*call);
-		event->ev.key.mods = IPC_GET_ARG4(*call);
-		event->ev.key.c = IPC_GET_ARG5(*call);
+		event->ev.key.type = ipc_get_arg2(call);
+		event->ev.key.key = ipc_get_arg3(call);
+		event->ev.key.mods = ipc_get_arg4(call);
+		event->ev.key.c = ipc_get_arg5(call);
 		break;
 	case CEV_POS:
-		event->ev.pos.pos_id = IPC_GET_ARG2(*call) >> 16;
-		event->ev.pos.type = IPC_GET_ARG2(*call) & 0xffff;
-		event->ev.pos.btn_num = IPC_GET_ARG3(*call);
-		event->ev.pos.hpos = IPC_GET_ARG4(*call);
-		event->ev.pos.vpos = IPC_GET_ARG5(*call);
+		event->ev.pos.pos_id = ipc_get_arg2(call) >> 16;
+		event->ev.pos.type = ipc_get_arg2(call) & 0xffff;
+		event->ev.pos.btn_num = ipc_get_arg3(call);
+		event->ev.pos.hpos = ipc_get_arg4(call);
+		event->ev.pos.vpos = ipc_get_arg5(call);
 		break;
 	default:
Index: uspace/lib/c/generic/io/input.c
===================================================================
--- uspace/lib/c/generic/io/input.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/input.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -112,8 +112,8 @@
 	errno_t rc;
 
-	type = IPC_GET_ARG1(*call);
-	key = IPC_GET_ARG2(*call);
-	mods = IPC_GET_ARG3(*call);
-	c = IPC_GET_ARG4(*call);
+	type = ipc_get_arg1(call);
+	key = ipc_get_arg2(call);
+	mods = ipc_get_arg3(call);
+	c = ipc_get_arg4(call);
 
 	rc = input->ev_ops->key(input, type, key, mods, c);
@@ -127,6 +127,6 @@
 	errno_t rc;
 
-	dx = IPC_GET_ARG1(*call);
-	dy = IPC_GET_ARG2(*call);
+	dx = ipc_get_arg1(call);
+	dy = ipc_get_arg2(call);
 
 	rc = input->ev_ops->move(input, dx, dy);
@@ -142,8 +142,8 @@
 	errno_t rc;
 
-	x = IPC_GET_ARG1(*call);
-	y = IPC_GET_ARG2(*call);
-	max_x = IPC_GET_ARG3(*call);
-	max_y = IPC_GET_ARG4(*call);
+	x = ipc_get_arg1(call);
+	y = ipc_get_arg2(call);
+	max_x = ipc_get_arg3(call);
+	max_y = ipc_get_arg4(call);
 
 	rc = input->ev_ops->abs_move(input, x, y, max_x, max_y);
@@ -157,6 +157,6 @@
 	errno_t rc;
 
-	bnum = IPC_GET_ARG1(*call);
-	press = IPC_GET_ARG2(*call);
+	bnum = ipc_get_arg1(call);
+	press = ipc_get_arg2(call);
 
 	rc = input->ev_ops->button(input, bnum, press);
@@ -172,10 +172,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case INPUT_EVENT_ACTIVE:
 			input_ev_active(input, &call);
Index: uspace/lib/c/generic/io/log.c
===================================================================
--- uspace/lib/c/generic/io/log.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/log.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -208,5 +208,5 @@
 		return parent;
 
-	return IPC_GET_ARG1(answer);
+	return ipc_get_arg1(&answer);
 }
 
Index: uspace/lib/c/generic/io/output.c
===================================================================
--- uspace/lib/c/generic/io/output.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/io/output.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -100,5 +100,5 @@
 		return 0;
 
-	return (frontbuf_handle_t) IPC_GET_ARG1(answer);
+	return (frontbuf_handle_t) ipc_get_arg1(&answer);
 }
 
Index: uspace/lib/c/generic/ipc.c
===================================================================
--- uspace/lib/c/generic/ipc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/ipc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -71,5 +71,5 @@
 {
 	return __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST,
-	    CAP_HANDLE_RAW(phandle), imethod, arg1, arg2, arg3,
+	    cap_handle_raw(phandle), imethod, arg1, arg2, arg3,
 	    (sysarg_t) label);
 }
@@ -98,13 +98,13 @@
 	ipc_call_t data;
 
-	IPC_SET_IMETHOD(data, imethod);
-	IPC_SET_ARG1(data, arg1);
-	IPC_SET_ARG2(data, arg2);
-	IPC_SET_ARG3(data, arg3);
-	IPC_SET_ARG4(data, arg4);
-	IPC_SET_ARG5(data, arg5);
+	ipc_set_imethod(&data, imethod);
+	ipc_set_arg1(&data, arg1);
+	ipc_set_arg2(&data, arg2);
+	ipc_set_arg3(&data, arg3);
+	ipc_set_arg4(&data, arg4);
+	ipc_set_arg5(&data, arg5);
 
 	return __SYSCALL3(SYS_IPC_CALL_ASYNC_SLOW,
-	    CAP_HANDLE_RAW(phandle), (sysarg_t) &data,
+	    cap_handle_raw(phandle), (sysarg_t) &data,
 	    (sysarg_t) label);
 }
@@ -130,5 +130,5 @@
 {
 	return (errno_t) __SYSCALL6(SYS_IPC_ANSWER_FAST,
-	    CAP_HANDLE_RAW(chandle), (sysarg_t) retval, arg1, arg2, arg3, arg4);
+	    cap_handle_raw(chandle), (sysarg_t) retval, arg1, arg2, arg3, arg4);
 }
 
@@ -152,13 +152,13 @@
 	ipc_call_t data;
 
-	IPC_SET_RETVAL(data, retval);
-	IPC_SET_ARG1(data, arg1);
-	IPC_SET_ARG2(data, arg2);
-	IPC_SET_ARG3(data, arg3);
-	IPC_SET_ARG4(data, arg4);
-	IPC_SET_ARG5(data, arg5);
+	ipc_set_retval(&data, retval);
+	ipc_set_arg1(&data, arg1);
+	ipc_set_arg2(&data, arg2);
+	ipc_set_arg3(&data, arg3);
+	ipc_set_arg4(&data, arg4);
+	ipc_set_arg5(&data, arg5);
 
 	return (errno_t) __SYSCALL2(SYS_IPC_ANSWER_SLOW,
-	    CAP_HANDLE_RAW(chandle), (sysarg_t) &data);
+	    cap_handle_raw(chandle), (sysarg_t) &data);
 }
 
@@ -186,5 +186,5 @@
 errno_t ipc_hangup(cap_phone_handle_t phandle)
 {
-	return (errno_t) __SYSCALL1(SYS_IPC_HANGUP, CAP_HANDLE_RAW(phandle));
+	return (errno_t) __SYSCALL1(SYS_IPC_HANGUP, cap_handle_raw(phandle));
 }
 
@@ -210,5 +210,5 @@
 {
 	return (errno_t) __SYSCALL6(SYS_IPC_FORWARD_FAST,
-	    CAP_HANDLE_RAW(chandle), CAP_HANDLE_RAW(phandle), imethod, arg1,
+	    cap_handle_raw(chandle), cap_handle_raw(phandle), imethod, arg1,
 	    arg2, mode);
 }
@@ -220,13 +220,13 @@
 	ipc_call_t data;
 
-	IPC_SET_IMETHOD(data, imethod);
-	IPC_SET_ARG1(data, arg1);
-	IPC_SET_ARG2(data, arg2);
-	IPC_SET_ARG3(data, arg3);
-	IPC_SET_ARG4(data, arg4);
-	IPC_SET_ARG5(data, arg5);
+	ipc_set_imethod(&data, imethod);
+	ipc_set_arg1(&data, arg1);
+	ipc_set_arg2(&data, arg2);
+	ipc_set_arg3(&data, arg3);
+	ipc_set_arg4(&data, arg4);
+	ipc_set_arg5(&data, arg5);
 
 	return (errno_t) __SYSCALL4(SYS_IPC_FORWARD_SLOW,
-	    CAP_HANDLE_RAW(chandle), CAP_HANDLE_RAW(phandle), (sysarg_t) &data,
+	    cap_handle_raw(chandle), cap_handle_raw(phandle), (sysarg_t) &data,
 	    mode);
 }
Index: uspace/lib/c/generic/iplink.c
===================================================================
--- uspace/lib/c/generic/iplink.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/iplink.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -248,5 +248,5 @@
 	iplink_recv_sdu_t sdu;
 
-	ip_ver_t ver = IPC_GET_ARG1(*icall);
+	ip_ver_t ver = ipc_get_arg1(icall);
 
 	errno_t rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
@@ -287,10 +287,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IPLINK_EV_RECV:
 			iplink_ev_recv(iplink, &call);
Index: uspace/lib/c/generic/iplink_srv.c
===================================================================
--- uspace/lib/c/generic/iplink_srv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/iplink_srv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -162,6 +162,6 @@
 	iplink_sdu_t sdu;
 
-	sdu.src = IPC_GET_ARG1(*icall);
-	sdu.dest = IPC_GET_ARG2(*icall);
+	sdu.src = ipc_get_arg1(icall);
+	sdu.dest = ipc_get_arg2(icall);
 
 	errno_t rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
@@ -253,5 +253,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/lib/c/generic/irc.c
===================================================================
--- uspace/lib/c/generic/irc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/irc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,4 +36,5 @@
 #include <async.h>
 #include <errno.h>
+#include <fibril.h>
 #include <ipc/irc.h>
 #include <ipc/services.h>
Index: uspace/lib/c/generic/irq.c
===================================================================
--- uspace/lib/c/generic/irq.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/irq.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -83,5 +83,5 @@
 {
 	return (errno_t) __SYSCALL1(SYS_IPC_IRQ_UNSUBSCRIBE,
-	    CAP_HANDLE_RAW(cap));
+	    cap_handle_raw(cap));
 }
 
Index: uspace/lib/c/generic/loc.c
===================================================================
--- uspace/lib/c/generic/loc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/loc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,10 +62,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOC_EVENT_CAT_CHANGE:
 			fibril_mutex_lock(&loc_callback_mutex);
@@ -239,5 +239,5 @@
 }
 
-/** Register new driver with loc. */
+/** Register new server with loc. */
 errno_t loc_server_register(const char *name)
 {
@@ -303,5 +303,5 @@
 
 	if (sid != NULL)
-		*sid = (service_id_t) IPC_GET_ARG1(answer);
+		*sid = (service_id_t) ipc_get_arg1(&answer);
 
 	return retval;
@@ -359,5 +359,5 @@
 
 	if (handle != NULL)
-		*handle = (service_id_t) IPC_GET_ARG1(answer);
+		*handle = (service_id_t) ipc_get_arg1(&answer);
 
 	return retval;
@@ -404,5 +404,5 @@
 		return retval;
 
-	act_size = IPC_GET_ARG2(dreply);
+	act_size = ipc_get_arg2(&dreply);
 	assert(act_size <= LOC_NAME_MAXLEN);
 	name_buf[act_size] = '\0';
@@ -492,5 +492,5 @@
 
 	if (handle != NULL)
-		*handle = (service_id_t) IPC_GET_ARG1(answer);
+		*handle = (service_id_t) ipc_get_arg1(&answer);
 
 	return retval;
@@ -541,5 +541,5 @@
 
 	if (cat_id != NULL)
-		*cat_id = (category_id_t) IPC_GET_ARG1(answer);
+		*cat_id = (category_id_t) ipc_get_arg1(&answer);
 
 	return retval;
@@ -778,5 +778,5 @@
 	}
 
-	*act_size = IPC_GET_ARG1(answer);
+	*act_size = ipc_get_arg1(&answer);
 	return EOK;
 }
Index: uspace/lib/c/generic/mem.c
===================================================================
--- uspace/lib/c/generic/mem.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/mem.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,7 +38,9 @@
 #include <stddef.h>
 #include <stdint.h>
+#include "private/cc.h"
 
 /** Fill memory block with a constant value. */
-void *memset(void *dest, int b, size_t n)
+ATTRIBUTE_OPTIMIZE_NO_TLDP
+    void *memset(void *dest, int b, size_t n)
 {
 	char *pb;
@@ -114,5 +116,6 @@
 
 /** Copy memory block. */
-void *memcpy(void *dst, const void *src, size_t n)
+ATTRIBUTE_OPTIMIZE_NO_TLDP
+    void *memcpy(void *dst, const void *src, size_t n)
 {
 	size_t i;
Index: uspace/lib/c/generic/pci.c
===================================================================
--- uspace/lib/c/generic/pci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/generic/pci.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file PCI control service API
+ */
+
+#include <abi/ipc/interfaces.h>
+#include <errno.h>
+#include <ipc/devman.h>
+#include <ipc/services.h>
+#include <ipc/pci.h>
+#include <loc.h>
+#include <pci.h>
+#include <stdlib.h>
+#include <types/pci.h>
+
+/** Open PCI service.
+ *
+ * @param svc_id PCI sevice ID
+ * @param rpci   Place to store pointer to PCI service object.
+ *
+ * @return EOK on success, ENOMEM if out of memory, EIO if service
+ *         cannot be contacted.
+ */
+errno_t pci_open(service_id_t svc_id, pci_t **rpci)
+{
+	pci_t *pci;
+	errno_t rc;
+
+	pci = calloc(1, sizeof(pci_t));
+	if (pci == NULL) {
+		rc = ENOMEM;
+		goto error;
+	}
+
+	pci->sess = loc_service_connect(svc_id, INTERFACE_PCI, 0);
+	if (pci->sess == NULL) {
+		rc = EIO;
+		goto error;
+	}
+
+	*rpci = pci;
+	return EOK;
+error:
+	free(pci);
+	return rc;
+}
+
+/** Close PCI service.
+ *
+ * @param pci PCI service object or @c NULL
+ */
+void pci_close(pci_t *pci)
+{
+	if (pci == NULL)
+		return;
+
+	async_hangup(pci->sess);
+	free(pci);
+}
+
+/** Get list of IDs into a buffer of fixed size.
+ *
+ * @param pci      PCI service
+ * @param method   IPC method
+ * @param arg1     First argument
+ * @param id_buf   Buffer to store IDs
+ * @param buf_size Buffer size
+ * @param act_size Place to store actual size of complete data.
+ *
+ * @return EOK on success or an error code.
+ */
+static errno_t pci_get_ids_once(pci_t *pci, sysarg_t method, sysarg_t arg1,
+    sysarg_t *id_buf, size_t buf_size, size_t *act_size)
+{
+	async_exch_t *exch = async_exchange_begin(pci->sess);
+
+	ipc_call_t answer;
+	aid_t req = async_send_1(exch, method, arg1, &answer);
+	errno_t rc = async_data_read_start(exch, id_buf, buf_size);
+
+	async_exchange_end(exch);
+
+	if (rc != EOK) {
+		async_forget(req);
+		return rc;
+	}
+
+	errno_t retval;
+	async_wait_for(req, &retval);
+
+	if (retval != EOK) {
+		return retval;
+	}
+
+	*act_size = ipc_get_arg1(&answer);
+	return EOK;
+}
+
+/** Get list of IDs.
+ *
+ * Returns an allocated array of service IDs.
+ *
+ * @param pci    PCI service
+ * @param method IPC method
+ * @param arg1   IPC argument 1
+ * @param data   Place to store pointer to array of IDs
+ * @param count  Place to store number of IDs
+ * @return       EOK on success or an error code
+ */
+static errno_t pci_get_ids_internal(pci_t *pci, sysarg_t method, sysarg_t arg1,
+    sysarg_t **data, size_t *count)
+{
+	*data = NULL;
+	*count = 0;
+
+	size_t act_size = 0;
+	errno_t rc = pci_get_ids_once(pci, method, arg1, NULL, 0, &act_size);
+	if (rc != EOK)
+		return rc;
+
+	size_t alloc_size = act_size;
+	service_id_t *ids = malloc(alloc_size);
+	if (ids == NULL)
+		return ENOMEM;
+
+	while (true) {
+		rc = pci_get_ids_once(pci, method, arg1, ids, alloc_size,
+		    &act_size);
+		if (rc != EOK)
+			return rc;
+
+		if (act_size <= alloc_size)
+			break;
+
+		alloc_size = act_size;
+		ids = realloc(ids, alloc_size);
+		if (ids == NULL)
+			return ENOMEM;
+	}
+
+	*count = act_size / sizeof(service_id_t);
+	*data = ids;
+	return EOK;
+}
+
+/** Get list of PCI devices as array of devman handles.
+ *
+ * @param pci PCI service
+ * @param data Place to store pointer to array
+ * @param count Place to store length of array (number of entries)
+ *
+ * @return EOK on success or an error code
+ */
+errno_t pci_get_devices(pci_t *pci, devman_handle_t **data, size_t *count)
+{
+	return pci_get_ids_internal(pci, PCI_GET_DEVICES, 0, data, count);
+}
+
+extern errno_t pci_dev_get_info(pci_t *, devman_handle_t, pci_dev_info_t *);
+
+/** Get PCI device information.
+ *
+ * @param pci PCI service
+ * @param dev_handle Device handle
+ * @param info Place to store device information
+ * @return EOK on success or an error code
+ */
+errno_t pci_dev_get_info(pci_t *pci, devman_handle_t dev_handle,
+    pci_dev_info_t *info)
+{
+	async_exch_t *exch;
+	errno_t retval;
+	ipc_call_t answer;
+
+	exch = async_exchange_begin(pci->sess);
+	aid_t req = async_send_1(exch, PCI_DEV_GET_INFO, dev_handle, &answer);
+
+	errno_t rc = async_data_read_start(exch, info, sizeof(pci_dev_info_t));
+	async_exchange_end(exch);
+	if (rc != EOK) {
+		async_forget(req);
+		return EIO;
+	}
+
+	async_wait_for(req, &retval);
+	if (retval != EOK)
+		return EIO;
+
+	return EOK;
+}
+
+/** @}
+ */
Index: uspace/lib/c/generic/pio_trace.c
===================================================================
--- uspace/lib/c/generic/pio_trace.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/pio_trace.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -81,7 +81,5 @@
 {
 	static pio_regions_t regions = {
-		.list = {
-			.head = { &regions.list.head, &regions.list.head },
-		},
+		.list = LIST_INITIALIZER(regions.list),
 		.guard = FIBRIL_RWLOCK_INITIALIZER(regions.guard),
 	};
Index: uspace/lib/c/generic/private/async.h
===================================================================
--- uspace/lib/c/generic/private/async.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/async.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_ASYNC_H_
-#define LIBC_PRIVATE_ASYNC_H_
+#ifndef _LIBC_PRIVATE_ASYNC_H_
+#define _LIBC_PRIVATE_ASYNC_H_
 
 #include <async.h>
Index: uspace/lib/c/generic/private/cc.h
===================================================================
--- uspace/lib/c/generic/private/cc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/generic/private/cc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ * Macros related to used compiler (such as GCC-specific attributes).
+ */
+
+#ifndef _LIBC_CC_H_
+#define _LIBC_CC_H_
+
+#ifndef __clang__
+#define ATTRIBUTE_OPTIMIZE(opt) \
+    __attribute__ ((optimize(opt)))
+#else
+#define ATTRIBUTE_OPTIMIZE(opt)
+#endif
+
+#define ATTRIBUTE_OPTIMIZE_NO_TLDP \
+    ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns")
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/generic/private/fibril.h
===================================================================
--- uspace/lib/c/generic/private/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_PRIVATE_FIBRIL_H_
-#define LIBC_PRIVATE_FIBRIL_H_
+#ifndef _LIBC_PRIVATE_FIBRIL_H_
+#define _LIBC_PRIVATE_FIBRIL_H_
 
 #include <adt/list.h>
@@ -35,4 +35,5 @@
 #include <abi/proc/uarg.h>
 #include <fibril.h>
+#include <ipc/common.h>
 
 #include "./futex.h"
Index: uspace/lib/c/generic/private/futex.h
===================================================================
--- uspace/lib/c/generic/private/futex.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/futex.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_FUTEX_H_
-#define LIBC_FUTEX_H_
+#ifndef _LIBC_FUTEX_H_
+#define _LIBC_FUTEX_H_
 
 #include <assert.h>
Index: uspace/lib/c/generic/private/io.h
===================================================================
--- uspace/lib/c/generic/private/io.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/io.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_IO_H_
-#define LIBC_PRIVATE_IO_H_
+#ifndef _LIBC_PRIVATE_IO_H_
+#define _LIBC_PRIVATE_IO_H_
 
 #include <loader/pcb.h>
Index: uspace/lib/c/generic/private/libc.h
===================================================================
--- uspace/lib/c/generic/private/libc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/libc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_LIBC_H_
-#define LIBC_PRIVATE_LIBC_H_
+#ifndef _LIBC_PRIVATE_LIBC_H_
+#define _LIBC_PRIVATE_LIBC_H_
 
 #include <types/common.h>
Index: uspace/lib/c/generic/private/loader.h
===================================================================
--- uspace/lib/c/generic/private/loader.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/loader.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_LOADER_H_
-#define LIBC_PRIVATE_LOADER_H_
+#ifndef _LIBC_PRIVATE_LOADER_H_
+#define _LIBC_PRIVATE_LOADER_H_
 
 #include <loader/loader.h>
Index: uspace/lib/c/generic/private/malloc.h
===================================================================
--- uspace/lib/c/generic/private/malloc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/malloc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_MALLOC_H_
-#define LIBC_PRIVATE_MALLOC_H_
+#ifndef _LIBC_PRIVATE_MALLOC_H_
+#define _LIBC_PRIVATE_MALLOC_H_
 
 extern void __malloc_init(void);
Index: uspace/lib/c/generic/private/ns.h
===================================================================
--- uspace/lib/c/generic/private/ns.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/ns.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_NS_H_
-#define LIBC_PRIVATE_NS_H_
+#ifndef _LIBC_PRIVATE_NS_H_
+#define _LIBC_PRIVATE_NS_H_
 
 #include <async.h>
Index: uspace/lib/c/generic/private/scanf.h
===================================================================
--- uspace/lib/c/generic/private/scanf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/scanf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_SCANF_H_
-#define LIBC_PRIVATE_SCANF_H_
+#ifndef _LIBC_PRIVATE_SCANF_H_
+#define _LIBC_PRIVATE_SCANF_H_
 
 #include <stddef.h>
Index: uspace/lib/c/generic/private/sstream.h
===================================================================
--- uspace/lib/c/generic/private/sstream.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/sstream.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_SSTREAM_H_
-#define LIBC_PRIVATE_SSTREAM_H_
+#ifndef _LIBC_PRIVATE_SSTREAM_H_
+#define _LIBC_PRIVATE_SSTREAM_H_
 
 #include <stdio.h>
Index: uspace/lib/c/generic/private/stdio.h
===================================================================
--- uspace/lib/c/generic/private/stdio.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/stdio.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_STDIO_H_
-#define LIBC_PRIVATE_STDIO_H_
+#ifndef _LIBC_PRIVATE_STDIO_H_
+#define _LIBC_PRIVATE_STDIO_H_
 
 #include <adt/list.h>
@@ -40,4 +40,5 @@
 #include <async.h>
 #include <stddef.h>
+#include <offset.h>
 
 /** Maximum characters that can be pushed back by ungetc() */
@@ -54,4 +55,15 @@
 	int (*flush)(FILE *stream);
 } __stream_ops_t;
+
+enum __buffer_state {
+	/** Buffer is empty */
+	_bs_empty,
+
+	/** Buffer contains data to be written */
+	_bs_write,
+
+	/** Buffer contains prefetched data for reading */
+	_bs_read
+};
 
 struct _IO_FILE {
@@ -87,5 +99,5 @@
 
 	/** Buffering type */
-	enum _buffer_type btype;
+	enum __buffer_type btype;
 
 	/** Buffer */
@@ -96,5 +108,5 @@
 
 	/** Buffer state */
-	enum _buffer_state buf_state;
+	enum __buffer_state buf_state;
 
 	/** Buffer I/O pointer */
Index: uspace/lib/c/generic/private/stdlib.h
===================================================================
--- uspace/lib/c/generic/private/stdlib.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/stdlib.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_STDLIB_H_
-#define LIBC_PRIVATE_STDLIB_H_
+#ifndef _LIBC_PRIVATE_STDLIB_H_
+#define _LIBC_PRIVATE_STDLIB_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/generic/private/thread.h
===================================================================
--- uspace/lib/c/generic/private/thread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/private/thread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRIVATE_THREAD_H_
-#define LIBC_PRIVATE_THREAD_H_
+#ifndef _LIBC_PRIVATE_THREAD_H_
+#define _LIBC_PRIVATE_THREAD_H_
 
 #include <time.h>
Index: uspace/lib/c/generic/rtld/dynamic.c
===================================================================
--- uspace/lib/c/generic/rtld/dynamic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/rtld/dynamic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -64,6 +64,6 @@
 		d_ptr = (void *)((uint8_t *)dp->d_un.d_ptr + bias);
 		d_val = dp->d_un.d_val;
-		DPRINTF("tag=%u ptr=0x%x val=%u\n", (unsigned)dp->d_tag,
-		    (unsigned)d_ptr, (unsigned)d_val);
+		DPRINTF("tag=%u ptr=0x%zx val=%zu\n", (unsigned)dp->d_tag,
+		    (uintptr_t)d_ptr, (uintptr_t)d_val);
 
 		switch (dp->d_tag) {
Index: uspace/lib/c/generic/rtld/module.c
===================================================================
--- uspace/lib/c/generic/rtld/module.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/rtld/module.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,4 +50,5 @@
 #include <rtld/rtld_arch.h>
 #include <rtld/module.h>
+#include <libarch/rtld/module.h>
 
 #include "../private/libc.h"
@@ -64,6 +65,8 @@
 
 	module = calloc(1, sizeof(module_t));
-	if (module == NULL)
+	if (module == NULL) {
+		DPRINTF("malloc failed\n");
 		return ENOMEM;
+	}
 
 	module->id = rtld_get_next_id(rtld);
@@ -181,10 +184,10 @@
 	char name_buf[NAME_BUF_SIZE];
 	module_t *m;
-	int rc;
+	errno_t rc;
 
 	m = calloc(1, sizeof(module_t));
 	if (m == NULL) {
-		printf("malloc failed\n");
-		exit(1);
+		DPRINTF("malloc failed\n");
+		goto error;
 	}
 
@@ -196,6 +199,6 @@
 
 	if (str_size(name) > NAME_BUF_SIZE - 2) {
-		printf("soname too long. increase NAME_BUF_SIZE\n");
-		exit(1);
+		DPRINTF("soname too long. increase NAME_BUF_SIZE\n");
+		goto error;
 	}
 
@@ -206,8 +209,8 @@
 	DPRINTF("filename:'%s'\n", name_buf);
 
-	rc = elf_load_file_name(name_buf, ELDF_RW, &info);
-	if (rc != EE_OK) {
-		printf("Failed to load '%s'\n", name_buf);
-		exit(1);
+	rc = elf_load_file_name(name_buf, RTLD_MODULE_LDF, &info);
+	if (rc != EOK) {
+		DPRINTF("Failed to load '%s'\n", name_buf);
+		goto error;
 	}
 
@@ -217,7 +220,7 @@
 
 	if (info.dynamic == NULL) {
-		printf("Error: '%s' is not a dynamically-linked object.\n",
+		DPRINTF("Error: '%s' is not a dynamically-linked object.\n",
 		    name_buf);
-		exit(1);
+		goto error;
 	}
 
@@ -242,9 +245,15 @@
 
 	return m;
+
+error:
+	if (m)
+		free(m);
+
+	return NULL;
 }
 
 /** Load all modules on which m (transitively) depends.
  */
-void module_load_deps(module_t *m, mlflags_t flags)
+errno_t module_load_deps(module_t *m, mlflags_t flags)
 {
 	elf_dyn_t *dp;
@@ -273,11 +282,11 @@
 		/* There are no dependencies, so we are done. */
 		m->deps = NULL;
-		return;
+		return EOK;
 	}
 
 	m->deps = malloc(n * sizeof(module_t *));
 	if (!m->deps) {
-		printf("malloc failed\n");
-		exit(1);
+		DPRINTF("malloc failed\n");
+		return ENOMEM;
 	}
 
@@ -293,5 +302,12 @@
 			if (!dm) {
 				dm = module_load(m->rtld, dep_name, flags);
-				module_load_deps(dm, flags);
+				if (!dm) {
+					return EINVAL;
+				}
+
+				errno_t rc = module_load_deps(dm, flags);
+				if (rc != EOK) {
+					return rc;
+				}
 			}
 
@@ -301,4 +317,6 @@
 		++dp;
 	}
+
+	return EOK;
 }
 
Index: uspace/lib/c/generic/rtld/rtld.c
===================================================================
--- uspace/lib/c/generic/rtld/rtld.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/rtld/rtld.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -125,5 +125,8 @@
 
 	DPRINTF("Load all program dependencies\n");
-	module_load_deps(prog, 0);
+	errno_t rc = module_load_deps(prog, 0);
+	if (rc != EOK) {
+		return rc;
+	}
 
 	/* Compute static TLS size */
Index: uspace/lib/c/generic/rtld/symbol.c
===================================================================
--- uspace/lib/c/generic/rtld/symbol.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/rtld/symbol.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -262,5 +262,5 @@
 void *symbol_get_addr(elf_symbol_t *sym, module_t *m, tcb_t *tcb)
 {
-	if (ELF_ST_TYPE(sym->st_info) == STT_TLS) {
+	if (elf_st_type(sym->st_info) == STT_TLS) {
 		if (tcb == NULL)
 			return NULL;
Index: uspace/lib/c/generic/setjmp.c
===================================================================
--- uspace/lib/c/generic/setjmp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/setjmp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,6 +38,9 @@
 void longjmp(jmp_buf env, int val)
 {
-	/* __longjmp defined in assembly doesn't "correct" the value. */
-	__longjmp(env, val == 0 ? 1 : val);
+	/*
+	 * The standard requires that longjmp() ensures that val is not zero.
+	 * __context_restore doesn't do that, so we do it here.
+	 */
+	__context_restore(env, val == 0 ? 1 : val);
 }
 
Index: uspace/lib/c/generic/str.c
===================================================================
--- uspace/lib/c/generic/str.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/str.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2001-2004 Jakub Jermar
  * Copyright (c) 2005 Martin Decky
  * Copyright (c) 2008 Jiri Svoboda
@@ -33,17 +34,88 @@
  * @{
  */
-/** @file
+
+/**
+ * @file
+ * @brief String functions.
+ *
+ * Strings and characters use the Universal Character Set (UCS). The standard
+ * strings, called just strings are encoded in UTF-8. Wide strings (encoded
+ * in UTF-32) are supported to a limited degree. A single character is
+ * represented as wchar_t.@n
+ *
+ * Overview of the terminology:@n
+ *
+ *  Term                  Meaning
+ *  --------------------  ----------------------------------------------------
+ *  byte                  8 bits stored in uint8_t (unsigned 8 bit integer)
+ *
+ *  character             UTF-32 encoded Unicode character, stored in wchar_t
+ *                        (signed 32 bit integer), code points 0 .. 1114111
+ *                        are valid
+ *
+ *  ASCII character       7 bit encoded ASCII character, stored in char
+ *                        (usually signed 8 bit integer), code points 0 .. 127
+ *                        are valid
+ *
+ *  string                UTF-8 encoded NULL-terminated Unicode string, char *
+ *
+ *  wide string           UTF-32 encoded NULL-terminated Unicode string,
+ *                        wchar_t *
+ *
+ *  [wide] string size    number of BYTES in a [wide] string (excluding
+ *                        the NULL-terminator), size_t
+ *
+ *  [wide] string length  number of CHARACTERS in a [wide] string (excluding
+ *                        the NULL-terminator), size_t
+ *
+ *  [wide] string width   number of display cells on a monospace display taken
+ *                        by a [wide] string, size_t
+ *
+ *
+ * Overview of string metrics:@n
+ *
+ *  Metric  Abbrev.  Type     Meaning
+ *  ------  ------   ------   -------------------------------------------------
+ *  size    n        size_t   number of BYTES in a string (excluding the
+ *                            NULL-terminator)
+ *
+ *  length  l        size_t   number of CHARACTERS in a string (excluding the
+ *                            null terminator)
+ *
+ *  width  w         size_t   number of display cells on a monospace display
+ *                            taken by a string
+ *
+ *
+ * Function naming prefixes:@n
+ *
+ *  chr_    operate on characters
+ *  ascii_  operate on ASCII characters
+ *  str_    operate on strings
+ *  wstr_   operate on wide strings
+ *
+ *  [w]str_[n|l|w]  operate on a prefix limited by size, length
+ *                  or width
+ *
+ *
+ * A specific character inside a [wide] string can be referred to by:@n
+ *
+ *  pointer (char *, wchar_t *)
+ *  byte offset (size_t)
+ *  character index (size_t)
+ *
  */
 
 #include <str.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdlib.h>
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
+
 #include <align.h>
 #include <mem.h>
-#include <limits.h>
 
 /** Check the condition if wchar_t is signed */
@@ -747,4 +819,5 @@
 	/* There must be space for a null terminator in the buffer. */
 	assert(size > 0);
+	assert(src != NULL);
 
 	size_t src_off = 0;
@@ -1311,7 +1384,7 @@
 {
 	size_t size = str_size(src) + 1;
-	char *dest = (char *) malloc(size);
-	if (dest == NULL)
-		return (char *) NULL;
+	char *dest = malloc(size);
+	if (!dest)
+		return NULL;
 
 	str_cpy(dest, size, src);
@@ -1345,7 +1418,7 @@
 		size = n;
 
-	char *dest = (char *) malloc(size + 1);
-	if (dest == NULL)
-		return (char *) NULL;
+	char *dest = malloc(size + 1);
+	if (!dest)
+		return NULL;
 
 	str_ncpy(dest, size + 1, src, size);
Index: uspace/lib/c/generic/string.c
===================================================================
--- uspace/lib/c/generic/string.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/string.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,11 +33,9 @@
  */
 
-/* Prevent an error from being generated */
-#undef _HELENOS_SOURCE
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <str_error.h>
 #include <string.h>
-#define _HELENOS_SOURCE
-
-#include <stddef.h>
-#include <str_error.h>
 
 /** Copy string.
@@ -504,4 +502,71 @@
 }
 
+/** Return number of characters in string with length limit.
+ *
+ * @param s String
+ * @param maxlen Maximum number of characters to read
+ * @return Number of characters preceding the null character, at most @a maxlen.
+ */
+size_t strnlen(const char *s, size_t maxlen)
+{
+	size_t n;
+
+	n = 0;
+	while (n < maxlen && *s != '\0') {
+		++s;
+		++n;
+	}
+
+	return n;
+}
+
+/** Allocate a new duplicate of string.
+ *
+ * @param s String to duplicate
+ * @return New string or @c NULL on failure (in which case @c errno is set
+ *         to ENOMEM).
+ */
+char *strdup(const char *s)
+{
+	size_t sz;
+	char *dup;
+
+	sz = strlen(s);
+	dup = malloc(sz + 1);
+	if (dup == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	strcpy(dup, s);
+	return dup;
+}
+
+/** Allocate a new duplicate of string with length limit.
+ *
+ * Creates a new duplicate of @a s. If @a s is longer than @a n characters,
+ * only @a n characters are copied and a null character is appended.
+ *
+ * @param s String to duplicate
+ * @param n Maximum number of characters to copy
+ * @return New string or @c NULL on failure (in which case @c errno is set
+ *         to ENOMEM).
+ */
+char *strndup(const char *s, size_t n)
+{
+	size_t sz;
+	char *dup;
+
+	sz = strnlen(s, n);
+	dup = malloc(sz + 1);
+	if (dup == NULL) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	strncpy(dup, s, sz);
+	return dup;
+}
+
 /** @}
  */
Index: uspace/lib/c/generic/task.c
===================================================================
--- uspace/lib/c/generic/task.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/task.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -374,6 +374,6 @@
 
 	if (rc == EOK) {
-		*texit = IPC_GET_ARG1(wait->result);
-		*retval = IPC_GET_ARG2(wait->result);
+		*texit = ipc_get_arg1(&wait->result);
+		*retval = ipc_get_arg2(&wait->result);
 	}
 
Index: uspace/lib/c/generic/thread/fibril.c
===================================================================
--- uspace/lib/c/generic/thread/fibril.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/thread/fibril.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -550,6 +550,5 @@
 		return 0;
 
-	fibril->stack_size = (stksz == FIBRIL_DFLT_STK_SIZE) ?
-	    stack_size_get() : stksz;
+	fibril->stack_size = stksz;
 	fibril->stack = as_area_create(AS_AREA_ANY, fibril->stack_size,
 	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE | AS_AREA_GUARD |
@@ -572,4 +571,9 @@
 	context_create(&fibril->ctx, &sctx);
 	return (fid_t) fibril;
+}
+
+fid_t fibril_create(errno_t (*func)(void *), void *arg)
+{
+	return fibril_create_generic(func, arg, stack_size_get());
 }
 
Index: uspace/lib/c/generic/time.c
===================================================================
--- uspace/lib/c/generic/time.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/time.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -79,5 +79,5 @@
 clock_t clock(void)
 {
-	static_assert(CLOCKS_PER_SEC == 1000000);
+	static_assert(CLOCKS_PER_SEC == 1000000, "");
 
 	size_t count;
Index: uspace/lib/c/generic/uuid.c
===================================================================
--- uspace/lib/c/generic/uuid.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/uuid.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,5 @@
 #include <stddef.h>
 #include <str.h>
+#include <stdio.h>
 
 /** Generate UUID.
@@ -64,8 +65,7 @@
 
 	/* Version 4 UUID from random or pseudo-random numbers */
-	uuid->b[8] = (uuid->b[8] & ~0xc0) | 0x40;
-	uuid->b[6] = (uuid->b[6] & 0xf0) | 0x40;
+	uuid->b[6] = (uuid->b[6] & 0x0f) | 0x40;
+	uuid->b[8] = (uuid->b[8] & 0x3f) | 0x80;
 
-	return EOK;
 error:
 	rndgen_destroy(rndgen);
@@ -139,5 +139,5 @@
 
 	rc = str_uint64_t(str + 24, &eptr, 16, false, &node);
-	if (rc != EOK || eptr != str + 36 || *eptr != '\0')
+	if (rc != EOK || eptr != str + 36)
 		return EINVAL;
 
@@ -176,7 +176,22 @@
  * @return EOK on success, ENOMEM if out of memory
  */
-errno_t uuid_format(uuid_t *uuid, char **rstr)
+errno_t uuid_format(uuid_t *uuid, char **rstr, bool uppercase)
 {
-	return ENOTSUP;
+	size_t size = 37;
+	char *str = malloc(sizeof(char) * size);
+	if (str == NULL)
+		return ENOMEM;
+
+	const char *format = "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x";
+	if (uppercase)
+		format = "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X";
+
+	int ret = snprintf(str, size, format, uuid->b[0], uuid->b[1], uuid->b[2], uuid->b[3], uuid->b[4], uuid->b[5], uuid->b[6], uuid->b[7], uuid->b[8], uuid->b[9], uuid->b[10], uuid->b[11], uuid->b[12], uuid->b[13], uuid->b[14], uuid->b[15]);
+
+	if (ret != 36)
+		return EINVAL;
+
+	*rstr = str;
+	return EOK;
 }
 
Index: uspace/lib/c/generic/vbd.c
===================================================================
--- uspace/lib/c/generic/vbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/vbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -190,5 +190,5 @@
 	}
 
-	*act_size = IPC_GET_ARG1(answer);
+	*act_size = ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -300,5 +300,5 @@
 		return EIO;
 
-	*rpart = (vbd_part_id_t)IPC_GET_ARG1(answer);
+	*rpart = (vbd_part_id_t)ipc_get_arg1(&answer);
 	return EOK;
 
Index: uspace/lib/c/generic/vfs/vfs.c
===================================================================
--- uspace/lib/c/generic/vfs/vfs.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/vfs/vfs.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -641,5 +641,5 @@
 
 	if (mountedfd)
-		*mountedfd = (int) IPC_GET_ARG1(answer);
+		*mountedfd = (int) ipc_get_arg1(&answer);
 
 	if (rc != EOK)
@@ -903,5 +903,5 @@
 		return rc;
 
-	*nread = (ssize_t) IPC_GET_ARG1(answer);
+	*nread = (ssize_t) ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -1283,5 +1283,5 @@
 		return (errno_t) rc;
 
-	*handle = (int) IPC_GET_ARG1(answer);
+	*handle = (int) ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -1367,5 +1367,5 @@
 		return rc;
 
-	*nwritten = (ssize_t) IPC_GET_ARG1(answer);
+	*nwritten = (ssize_t) ipc_get_arg1(&answer);
 	return EOK;
 }
Index: uspace/lib/c/generic/vol.c
===================================================================
--- uspace/lib/c/generic/vol.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/generic/vol.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -127,5 +127,5 @@
 	}
 
-	*act_size = IPC_GET_ARG1(answer);
+	*act_size = ipc_get_arg1(&answer);
 	return EOK;
 }
@@ -220,5 +220,5 @@
  * @param vol Volume service
  * @param sid Service ID of the partition
- * @param vinfo Place to sore partition information
+ * @param vinfo Place to store partition information
  * @return EOK on success or an error code
  */
@@ -578,5 +578,5 @@
  * @param vol Volume service
  * @param vid Volume ID
- * @param vinfo Place to sore volume configuration information
+ * @param vinfo Place to store volume configuration information
  * @return EOK on success or an error code
  */
Index: uspace/lib/c/include/adt/checksum.h
===================================================================
--- uspace/lib/c/include/adt/checksum.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/checksum.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CHECKSUM_H_
-#define LIBC_CHECKSUM_H_
+#ifndef _LIBC_CHECKSUM_H_
+#define _LIBC_CHECKSUM_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/adt/circ_buf.h
===================================================================
--- uspace/lib/c/include/adt/circ_buf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/circ_buf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CIRC_BUF_H_
-#define LIBC_CIRC_BUF_H_
+#ifndef _LIBC_CIRC_BUF_H_
+#define _LIBC_CIRC_BUF_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/adt/fifo.h
===================================================================
--- uspace/lib/c/include/adt/fifo.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/fifo.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -43,6 +43,6 @@
  */
 
-#ifndef LIBC_FIFO_H_
-#define LIBC_FIFO_H_
+#ifndef _LIBC_FIFO_H_
+#define _LIBC_FIFO_H_
 
 #include <stdlib.h>
Index: uspace/lib/c/include/adt/gcdlcm.h
===================================================================
--- uspace/lib/c/include/adt/gcdlcm.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/gcdlcm.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_GCDLCM_H_
-#define LIBC_GCDLCM_H_
+#ifndef _LIBC_GCDLCM_H_
+#define _LIBC_GCDLCM_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/adt/hash.h
===================================================================
--- uspace/lib/c/include/adt/hash.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/hash.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,6 +32,6 @@
 /** @file
  */
-#ifndef LIBC_ADT_HASH_H_
-#define LIBC_ADT_HASH_H_
+#ifndef _LIBC_ADT_HASH_H_
+#define _LIBC_ADT_HASH_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/adt/hash_table.h
===================================================================
--- uspace/lib/c/include/adt/hash_table.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/hash_table.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef LIBC_HASH_TABLE_H_
-#define LIBC_HASH_TABLE_H_
+#ifndef _LIBC_HASH_TABLE_H_
+#define _LIBC_HASH_TABLE_H_
 
 #include <adt/list.h>
@@ -53,5 +53,5 @@
 
 	/** Returns the hash of the key. */
-	size_t (*key_hash)(void *key);
+	size_t (*key_hash)(const void *key);
 
 	/** True if the items are equal (have the same lookup keys). */
@@ -59,5 +59,5 @@
 
 	/** Returns true if the key is equal to the item's lookup key. */
-	bool (*key_equal)(void *key, const ht_link_t *item);
+	bool (*key_equal)(const void *key, const ht_link_t *item);
 
 	/** Hash table item removal callback.
@@ -94,8 +94,8 @@
 extern void hash_table_insert(hash_table_t *, ht_link_t *);
 extern bool hash_table_insert_unique(hash_table_t *, ht_link_t *);
-extern ht_link_t *hash_table_find(const hash_table_t *, void *);
+extern ht_link_t *hash_table_find(const hash_table_t *, const void *);
 extern ht_link_t *hash_table_find_next(const hash_table_t *, ht_link_t *,
     ht_link_t *);
-extern size_t hash_table_remove(hash_table_t *, void *);
+extern size_t hash_table_remove(hash_table_t *, const void *);
 extern void hash_table_remove_item(hash_table_t *, ht_link_t *);
 extern void hash_table_apply(hash_table_t *, bool (*)(ht_link_t *, void *),
Index: uspace/lib/c/include/adt/list.h
===================================================================
--- uspace/lib/c/include/adt/list.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/list.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_LIST_H_
-#define LIBC_LIST_H_
+#ifndef _LIBC_LIST_H_
+#define _LIBC_LIST_H_
 
 #include <assert.h>
@@ -42,19 +42,14 @@
 #include <stdint.h>
 #include <trace.h>
-
-/** Doubly linked list link. */
-typedef struct link {
-	struct link *prev;  /**< Pointer to the previous item in the list. */
-	struct link *next;  /**< Pointer to the next item in the list. */
-} link_t;
-
-/** Doubly linked list. */
-typedef struct list {
-	link_t head;  /**< List head. Does not have any data. */
-} list_t;
-
-extern bool list_member(const link_t *, const list_t *);
-extern void list_splice(list_t *, link_t *);
-extern unsigned long list_count(const list_t *);
+#include <_bits/decls.h>
+
+#ifndef __cplusplus
+
+/**
+ * We don't define the macros in C++ to avoid polluting headers with
+ * namespaceless names. We don't actually need them, so this is fine.
+ * We still allow including the rest of the file (in `helenos` namespace)
+ * so that we can expose publicly visible types that have list_t members.
+ */
 
 /** Declare and initialize statically allocated list.
@@ -138,4 +133,27 @@
 	assert(!link_used(link))
 
+#define list_pop(list, type, member) \
+	((type *) list_pop_internal(list, \
+	    (list_link_to_void(&(((type *) NULL)->member)) - NULL)))
+
+#endif  /* !__cplusplus */
+
+__HELENOS_DECLS_BEGIN;
+
+/** Doubly linked list link. */
+typedef struct __adt_list_link {
+	struct __adt_list_link *prev;  /**< Pointer to the previous item in the list. */
+	struct __adt_list_link *next;  /**< Pointer to the next item in the list. */
+} link_t;
+
+/** Doubly linked list. */
+typedef struct {
+	link_t head;  /**< List head. Does not have any data. */
+} list_t;
+
+extern bool list_member(const link_t *, const list_t *);
+extern void list_splice(list_t *, link_t *);
+extern unsigned long list_count(const list_t *);
+
 /** Returns true if the link is definitely part of a list. False if not sure. */
 static inline bool link_in_use(const link_t *link)
@@ -151,5 +169,5 @@
  *
  */
-NO_TRACE static inline void link_initialize(link_t *link)
+_NO_TRACE static inline void link_initialize(link_t *link)
 {
 	link->prev = NULL;
@@ -164,5 +182,5 @@
  *
  */
-NO_TRACE static inline void list_initialize(list_t *list)
+_NO_TRACE static inline void list_initialize(list_t *list)
 {
 	list->head.prev = &list->head;
@@ -200,5 +218,5 @@
  *
  */
-NO_TRACE static inline void list_prepend(link_t *link, list_t *list)
+_NO_TRACE static inline void list_prepend(link_t *link, list_t *list)
 {
 	list_insert_after(link, &list->head);
@@ -213,5 +231,5 @@
  *
  */
-NO_TRACE static inline void list_append(link_t *link, list_t *list)
+_NO_TRACE static inline void list_append(link_t *link, list_t *list)
 {
 	list_insert_before(link, &list->head);
@@ -226,5 +244,5 @@
  *
  */
-NO_TRACE static inline void list_remove(link_t *link)
+_NO_TRACE static inline void list_remove(link_t *link)
 {
 	if ((link->prev != NULL) && (link->next != NULL)) {
@@ -243,5 +261,5 @@
  *
  */
-NO_TRACE static inline bool list_empty(const list_t *list)
+_NO_TRACE static inline bool list_empty(const list_t *list)
 {
 	return (list->head.next == &list->head);
@@ -311,5 +329,5 @@
  *
  */
-NO_TRACE static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
+_NO_TRACE static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
 {
 	part1->prev->next = part2;
@@ -332,5 +350,5 @@
  *
  */
-NO_TRACE static inline void headless_list_split(link_t *part1, link_t *part2)
+_NO_TRACE static inline void headless_list_split(link_t *part1, link_t *part2)
 {
 	headless_list_split_or_concat(part1, part2);
@@ -347,5 +365,5 @@
  *
  */
-NO_TRACE static inline void headless_list_concat(link_t *part1, link_t *part2)
+_NO_TRACE static inline void headless_list_concat(link_t *part1, link_t *part2)
 {
 	headless_list_split_or_concat(part1, part2);
@@ -362,5 +380,5 @@
  *
  */
-NO_TRACE static inline void list_concat(list_t *list1, list_t *list2)
+_NO_TRACE static inline void list_concat(list_t *list1, list_t *list2)
 {
 	list_splice(list2, list1->head.prev);
@@ -425,7 +443,5 @@
 }
 
-#define list_pop(list, type, member) \
-	((type *) list_pop_internal(list, \
-	    (list_link_to_void(&(((type *) NULL)->member)) - NULL)))
+__HELENOS_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/adt/prodcons.h
===================================================================
--- uspace/lib/c/include/adt/prodcons.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/adt/prodcons.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRODCONS_H_
-#define LIBC_PRODCONS_H_
+#ifndef _LIBC_PRODCONS_H_
+#define _LIBC_PRODCONS_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/align.h
===================================================================
--- uspace/lib/c/include/align.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/align.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ALIGN_H_
-#define LIBC_ALIGN_H_
+#ifndef _LIBC_ALIGN_H_
+#define _LIBC_ALIGN_H_
 
 /** Align to the nearest lower address which is a power of two.
Index: uspace/lib/c/include/arg_parse.h
===================================================================
--- uspace/lib/c/include/arg_parse.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/arg_parse.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ARG_PARSE_H_
-#define LIBC_ARG_PARSE_H_
+#ifndef _LIBC_ARG_PARSE_H_
+#define _LIBC_ARG_PARSE_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/as.h
===================================================================
--- uspace/lib/c/include/as.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/as.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_AS_H_
-#define LIBC_AS_H_
+#ifndef _LIBC_AS_H_
+#define _LIBC_AS_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/assert.h
===================================================================
--- uspace/lib/c/include/assert.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/assert.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,10 +38,14 @@
 // This is in accordance with the C standard.
 
-#ifndef LIBC_ASSERT_H_
-#define LIBC_ASSERT_H_
+#ifndef _LIBC_ASSERT_H_
+#define _LIBC_ASSERT_H_
+
+#include <_bits/decls.h>
 
 #ifndef __cplusplus
-#define static_assert(expr)	_Static_assert(expr, "")
+#define static_assert _Static_assert
 #endif
+
+__C_DECLS_BEGIN;
 
 extern void __helenos_assert_abort(const char *, const char *, unsigned int)
@@ -50,4 +54,6 @@
 extern void __helenos_assert_quick_abort(const char *, const char *, unsigned int)
     __attribute__((noreturn));
+
+__C_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/async.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,13 +33,12 @@
  */
 
-#if ((defined(LIBC_IPC_H_)) && (!defined(LIBC_ASYNC_C_)))
+#if ((defined(_LIBC_IPC_H_)) && (!defined(_LIBC_ASYNC_C_)))
 #error Do not intermix low-level IPC interface and async framework
 #endif
 
-#ifndef LIBC_ASYNC_H_
-#define LIBC_ASYNC_H_
+#ifndef _LIBC_ASYNC_H_
+#define _LIBC_ASYNC_H_
 
 #include <ipc/common.h>
-#include <fibril.h>
 #include <time.h>
 #include <stdbool.h>
@@ -109,32 +108,16 @@
 extern __noreturn void async_manager(void);
 
-#define async_get_call(data) \
-	async_get_call_timeout(data, 0)
-
+extern bool async_get_call(ipc_call_t *);
 extern bool async_get_call_timeout(ipc_call_t *, usec_t);
 
-/*
- * User-friendly wrappers for async_send_fast() and async_send_slow(). The
- * macros are in the form async_send_m(), where m denotes the number of payload
- * arguments. Each macros chooses between the fast and the slow version based
- * on m.
- */
-
-#define async_send_0(exch, method, dataptr) \
-	async_send_fast(exch, method, 0, 0, 0, 0, dataptr)
-#define async_send_1(exch, method, arg1, dataptr) \
-	async_send_fast(exch, method, arg1, 0, 0, 0, dataptr)
-#define async_send_2(exch, method, arg1, arg2, dataptr) \
-	async_send_fast(exch, method, arg1, arg2, 0, 0, dataptr)
-#define async_send_3(exch, method, arg1, arg2, arg3, dataptr) \
-	async_send_fast(exch, method, arg1, arg2, arg3, 0, dataptr)
-#define async_send_4(exch, method, arg1, arg2, arg3, arg4, dataptr) \
-	async_send_fast(exch, method, arg1, arg2, arg3, arg4, dataptr)
-#define async_send_5(exch, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
-	async_send_slow(exch, method, arg1, arg2, arg3, arg4, arg5, dataptr)
-
-extern aid_t async_send_fast(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+extern aid_t async_send_0(async_exch_t *, sysarg_t, ipc_call_t *);
+extern aid_t async_send_1(async_exch_t *, sysarg_t, sysarg_t, ipc_call_t *);
+extern aid_t async_send_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    ipc_call_t *);
+extern aid_t async_send_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, ipc_call_t *);
+extern aid_t async_send_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, ipc_call_t *);
-extern aid_t async_send_slow(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+extern aid_t async_send_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
 
@@ -199,134 +182,90 @@
  */
 
-extern errno_t async_forward_fast(ipc_call_t *, async_exch_t *, sysarg_t,
+extern errno_t async_forward_0(ipc_call_t *, async_exch_t *, sysarg_t,
+    unsigned int);
+extern errno_t async_forward_1(ipc_call_t *, async_exch_t *, sysarg_t,
+    sysarg_t, unsigned int);
+extern errno_t async_forward_2(ipc_call_t *, async_exch_t *, sysarg_t,
     sysarg_t, sysarg_t, unsigned int);
-extern errno_t async_forward_slow(ipc_call_t *, async_exch_t *, sysarg_t,
+extern errno_t async_forward_3(ipc_call_t *, async_exch_t *, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, unsigned int);
+extern errno_t async_forward_4(ipc_call_t *, async_exch_t *, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t, unsigned int);
+extern errno_t async_forward_5(ipc_call_t *, async_exch_t *, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t, unsigned int);
 
 /*
- * User-friendly wrappers for async_req_fast() and async_req_slow(). The macros
- * are in the form async_req_m_n(), where m is the number of payload arguments
- * and n is the number of return arguments. The macros decide between the fast
- * and slow verion based on m.
- */
-
-#define async_req_0_0(exch, method) \
-	async_req_fast(exch, method, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL)
-#define async_req_0_1(exch, method, r1) \
-	async_req_fast(exch, method, 0, 0, 0, 0, r1, NULL, NULL, NULL, NULL)
-#define async_req_0_2(exch, method, r1, r2) \
-	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, NULL, NULL, NULL)
-#define async_req_0_3(exch, method, r1, r2, r3) \
-	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, NULL, NULL)
-#define async_req_0_4(exch, method, r1, r2, r3, r4) \
-	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, r4, NULL)
-#define async_req_0_5(exch, method, r1, r2, r3, r4, r5) \
-	async_req_fast(exch, method, 0, 0, 0, 0, r1, r2, r3, r4, r5)
-
-#define async_req_1_0(exch, method, arg1) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, NULL, NULL, NULL, NULL, \
-	    NULL)
-#define async_req_1_1(exch, method, arg1, rc1) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, NULL, NULL, NULL, \
-	    NULL)
-#define async_req_1_2(exch, method, arg1, rc1, rc2) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, NULL, NULL, \
-	    NULL)
-#define async_req_1_3(exch, method, arg1, rc1, rc2, rc3) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, NULL, \
-	    NULL)
-#define async_req_1_4(exch, method, arg1, rc1, rc2, rc3, rc4) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, rc4, \
-	    NULL)
-#define async_req_1_5(exch, method, arg1, rc1, rc2, rc3, rc4, rc5) \
-	async_req_fast(exch, method, arg1, 0, 0, 0, rc1, rc2, rc3, rc4, \
-	    rc5)
-
-#define async_req_2_0(exch, method, arg1, arg2) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, NULL, NULL, NULL, \
-	    NULL, NULL)
-#define async_req_2_1(exch, method, arg1, arg2, rc1) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, NULL, NULL, \
-	    NULL, NULL)
-#define async_req_2_2(exch, method, arg1, arg2, rc1, rc2) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, NULL, NULL, \
-	    NULL)
-#define async_req_2_3(exch, method, arg1, arg2, rc1, rc2, rc3) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, NULL, \
-	    NULL)
-#define async_req_2_4(exch, method, arg1, arg2, rc1, rc2, rc3, rc4) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, rc4, \
-	    NULL)
-#define async_req_2_5(exch, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
-	async_req_fast(exch, method, arg1, arg2, 0, 0, rc1, rc2, rc3, rc4, \
-	    rc5)
-
-#define async_req_3_0(exch, method, arg1, arg2, arg3) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, NULL, NULL, NULL, \
-	    NULL, NULL)
-#define async_req_3_1(exch, method, arg1, arg2, arg3, rc1) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, NULL, NULL, \
-	    NULL, NULL)
-#define async_req_3_2(exch, method, arg1, arg2, arg3, rc1, rc2) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, NULL, \
-	    NULL, NULL)
-#define async_req_3_3(exch, method, arg1, arg2, arg3, rc1, rc2, rc3) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
-	    NULL, NULL)
-#define async_req_3_4(exch, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
-	    rc4, NULL)
-#define async_req_3_5(exch, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
-    rc5) \
-	async_req_fast(exch, method, arg1, arg2, arg3, 0, rc1, rc2, rc3, \
-	    rc4, rc5)
-
-#define async_req_4_0(exch, method, arg1, arg2, arg3, arg4) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, NULL, NULL, \
-	    NULL, NULL, NULL)
-#define async_req_4_1(exch, method, arg1, arg2, arg3, arg4, rc1) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, NULL, \
-	    NULL, NULL, NULL)
-#define async_req_4_2(exch, method, arg1, arg2, arg3, arg4, rc1, rc2) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, NULL, \
-	    NULL, NULL)
-#define async_req_4_3(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-	    NULL, NULL)
-#define async_req_4_4(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-    rc4) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-	    rc4, NULL)
-#define async_req_4_5(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-    rc4, rc5) \
-	async_req_fast(exch, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
-	    rc4, rc5)
-
-#define async_req_5_0(exch, method, arg1, arg2, arg3, arg4, arg5) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, NULL, \
-	    NULL, NULL, NULL, NULL)
-#define async_req_5_1(exch, method, arg1, arg2, arg3, arg4, arg5, rc1) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, \
-	    NULL, NULL, NULL, NULL)
-#define async_req_5_2(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-	    NULL, NULL, NULL)
-#define async_req_5_3(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-    rc3) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-	    rc3, NULL, NULL)
-#define async_req_5_4(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-    rc3, rc4) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-	    rc3, rc4, NULL)
-#define async_req_5_5(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-    rc3, rc4, rc5) \
-	async_req_slow(exch, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
-	    rc3, rc4, rc5)
-
-extern errno_t async_req_fast(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+ * User-friendly wrappers for async_req_*_*().
+ * The functions are in the form async_req_m_n(), where m is the number of
+ * payload arguments and n is the number of return arguments.
+ */
+
+extern errno_t async_req_0_0(async_exch_t *, sysarg_t);
+extern errno_t async_req_0_1(async_exch_t *, sysarg_t, sysarg_t *);
+extern errno_t async_req_0_2(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *);
+extern errno_t async_req_0_3(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *,
+    sysarg_t *);
+extern errno_t async_req_0_4(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *,
+    sysarg_t *, sysarg_t *);
+extern errno_t async_req_0_5(async_exch_t *, sysarg_t, sysarg_t *, sysarg_t *,
+    sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_1_0(async_exch_t *, sysarg_t, sysarg_t);
+extern errno_t async_req_1_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *);
+extern errno_t async_req_1_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
+    sysarg_t *);
+extern errno_t async_req_1_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
+    sysarg_t *, sysarg_t *);
+extern errno_t async_req_1_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
+    sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_1_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t *,
+    sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_2_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t);
+extern errno_t async_req_2_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t *);
+extern errno_t async_req_2_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t *, sysarg_t *);
+extern errno_t async_req_2_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_2_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_2_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_3_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t);
+extern errno_t async_req_3_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t *);
+extern errno_t async_req_3_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t *, sysarg_t *);
+extern errno_t async_req_3_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_3_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_3_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_4_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t);
+extern errno_t async_req_4_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t *);
+extern errno_t async_req_4_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t *, sysarg_t *);
+extern errno_t async_req_4_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_4_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_4_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *,
     sysarg_t *);
-extern errno_t async_req_slow(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+extern errno_t async_req_5_0(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t);
+extern errno_t async_req_5_1(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t *);
+extern errno_t async_req_5_2(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *);
+extern errno_t async_req_5_3(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *);
+extern errno_t async_req_5_4(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *,
+    sysarg_t *);
+extern errno_t async_req_5_5(async_exch_t *, sysarg_t, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *,
     sysarg_t *, sysarg_t *);
@@ -358,15 +297,12 @@
  */
 
-#define async_share_in_start_0_0(exch, size, dst) \
-	async_share_in_start(exch, size, 0, NULL, dst)
-#define async_share_in_start_0_1(exch, size, flags, dst) \
-	async_share_in_start(exch, size, 0, flags, dst)
-#define async_share_in_start_1_0(exch, size, arg, dst) \
-	async_share_in_start(exch, size, arg, NULL, dst)
-#define async_share_in_start_1_1(exch, size, arg, flags, dst) \
-	async_share_in_start(exch, size, arg, flags, dst)
-
-extern errno_t async_share_in_start(async_exch_t *, size_t, sysarg_t,
+extern errno_t async_share_in_start_0_0(async_exch_t *, size_t, void **);
+extern errno_t async_share_in_start_0_1(async_exch_t *, size_t,
     unsigned int *, void **);
+extern errno_t async_share_in_start_1_0(async_exch_t *, size_t, sysarg_t,
+    void **);
+extern errno_t async_share_in_start_1_1(async_exch_t *, size_t, sysarg_t,
+    unsigned int *, void **);
+
 extern bool async_share_in_receive(ipc_call_t *, size_t *);
 extern errno_t async_share_in_finalize(ipc_call_t *, void *, unsigned int);
@@ -376,33 +312,23 @@
 extern errno_t async_share_out_finalize(ipc_call_t *, void **);
 
-/*
- * User-friendly wrappers for async_data_read_forward_fast().
- */
-
-#define async_data_read_forward_0_0(exch, method, answer) \
-	async_data_read_forward_fast(exch, method, 0, 0, 0, 0, NULL)
-#define async_data_read_forward_0_1(exch, method, answer) \
-	async_data_read_forward_fast(exch, method, 0, 0, 0, 0, answer)
-#define async_data_read_forward_1_0(exch, method, arg1, answer) \
-	async_data_read_forward_fast(exch, method, arg1, 0, 0, 0, NULL)
-#define async_data_read_forward_1_1(exch, method, arg1, answer) \
-	async_data_read_forward_fast(exch, method, arg1, 0, 0, 0, answer)
-#define async_data_read_forward_2_0(exch, method, arg1, arg2, answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, 0, 0, NULL)
-#define async_data_read_forward_2_1(exch, method, arg1, arg2, answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, 0, 0, answer)
-#define async_data_read_forward_3_0(exch, method, arg1, arg2, arg3, answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, 0, NULL)
-#define async_data_read_forward_3_1(exch, method, arg1, arg2, arg3, answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, 0, \
-	    answer)
-#define async_data_read_forward_4_0(exch, method, arg1, arg2, arg3, arg4, \
-    answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
-	    NULL)
-#define async_data_read_forward_4_1(exch, method, arg1, arg2, arg3, arg4, \
-    answer) \
-	async_data_read_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
-	    answer)
+extern errno_t async_data_read_forward_0_0(async_exch_t *, sysarg_t);
+extern errno_t async_data_read_forward_1_0(async_exch_t *, sysarg_t, sysarg_t);
+extern errno_t async_data_read_forward_2_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t);
+extern errno_t async_data_read_forward_3_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t);
+extern errno_t async_data_read_forward_4_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t);
+
+extern errno_t async_data_read_forward_0_1(async_exch_t *, sysarg_t,
+    ipc_call_t *);
+extern errno_t async_data_read_forward_1_1(async_exch_t *, sysarg_t, sysarg_t,
+    ipc_call_t *);
+extern errno_t async_data_read_forward_2_1(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, ipc_call_t *);
+extern errno_t async_data_read_forward_3_1(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, ipc_call_t *);
+extern errno_t async_data_read_forward_4_1(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
 
 extern aid_t async_data_read(async_exch_t *, void *, size_t, ipc_call_t *);
@@ -411,37 +337,23 @@
 extern errno_t async_data_read_finalize(ipc_call_t *, const void *, size_t);
 
-extern errno_t async_data_read_forward_fast(async_exch_t *, sysarg_t, sysarg_t,
+extern errno_t async_data_write_forward_0_0(async_exch_t *, sysarg_t);
+extern errno_t async_data_write_forward_1_0(async_exch_t *, sysarg_t, sysarg_t);
+extern errno_t async_data_write_forward_2_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t);
+extern errno_t async_data_write_forward_3_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t);
+extern errno_t async_data_write_forward_4_0(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, sysarg_t);
+
+extern errno_t async_data_write_forward_0_1(async_exch_t *, sysarg_t,
+    ipc_call_t *);
+extern errno_t async_data_write_forward_1_1(async_exch_t *, sysarg_t, sysarg_t,
+    ipc_call_t *);
+extern errno_t async_data_write_forward_2_1(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, ipc_call_t *);
+extern errno_t async_data_write_forward_3_1(async_exch_t *, sysarg_t, sysarg_t,
+    sysarg_t, sysarg_t, ipc_call_t *);
+extern errno_t async_data_write_forward_4_1(async_exch_t *, sysarg_t, sysarg_t,
     sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
-
-/*
- * User-friendly wrappers for async_data_write_forward_fast().
- */
-
-#define async_data_write_forward_0_0(exch, method, answer) \
-	async_data_write_forward_fast(exch, method, 0, 0, 0, 0, NULL)
-#define async_data_write_forward_0_1(exch, method, answer) \
-	async_data_write_forward_fast(exch, method, 0, 0, 0, 0, answer)
-#define async_data_write_forward_1_0(exch, method, arg1, answer) \
-	async_data_write_forward_fast(exch, method, arg1, 0, 0, 0, NULL)
-#define async_data_write_forward_1_1(exch, method, arg1, answer) \
-	async_data_write_forward_fast(exch, method, arg1, 0, 0, 0, answer)
-#define async_data_write_forward_2_0(exch, method, arg1, arg2, answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, 0, 0, NULL)
-#define async_data_write_forward_2_1(exch, method, arg1, arg2, answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, 0, 0, answer)
-#define async_data_write_forward_3_0(exch, method, arg1, arg2, arg3, answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, 0, \
-	    NULL)
-#define async_data_write_forward_3_1(exch, method, arg1, arg2, arg3, answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, 0, \
-	    answer)
-#define async_data_write_forward_4_0(exch, method, arg1, arg2, arg3, arg4, \
-    answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
-	    NULL)
-#define async_data_write_forward_4_1(exch, method, arg1, arg2, arg3, arg4, \
-    answer) \
-	async_data_write_forward_fast(exch, method, arg1, arg2, arg3, arg4, \
-	    answer)
 
 extern errno_t async_data_write_start(async_exch_t *, const void *, size_t);
@@ -452,7 +364,4 @@
     const size_t, const size_t, size_t *);
 extern void async_data_write_void(errno_t);
-
-extern errno_t async_data_write_forward_fast(async_exch_t *, sysarg_t, sysarg_t,
-    sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
 
 extern async_sess_t *async_callback_receive(exch_mgmt_t);
@@ -473,5 +382,4 @@
 
 errno_t async_spawn_notification_handler(void);
-fid_t async_create_manager(void);
 
 #endif
Index: uspace/lib/c/include/barrier.h
===================================================================
--- uspace/lib/c/include/barrier.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/barrier.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_COMPILER_BARRIER_H_
-#define LIBC_COMPILER_BARRIER_H_
+#ifndef _LIBC_COMPILER_BARRIER_H_
+#define _LIBC_COMPILER_BARRIER_H_
 
 #include <stdatomic.h>
@@ -61,3 +61,3 @@
 #define ACCESS_ONCE(var) (*((volatile typeof(var)*)&(var)))
 
-#endif /* LIBC_COMPILER_BARRIER_H_ */
+#endif /* _LIBC_COMPILER_BARRIER_H_ */
Index: uspace/lib/c/include/bd.h
===================================================================
--- uspace/lib/c/include/bd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/bd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_BD_H_
-#define LIBC_BD_H_
+#ifndef _LIBC_BD_H_
+#define _LIBC_BD_H_
 
 #include <async.h>
Index: uspace/lib/c/include/bd_srv.h
===================================================================
--- uspace/lib/c/include/bd_srv.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/bd_srv.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_BD_SRV_H_
-#define LIBC_BD_SRV_H_
+#ifndef _LIBC_BD_SRV_H_
+#define _LIBC_BD_SRV_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/bitops.h
===================================================================
--- uspace/lib/c/include/bitops.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/bitops.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_BITOPS_H_
-#define LIBC_BITOPS_H_
+#ifndef _LIBC_BITOPS_H_
+#define _LIBC_BITOPS_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/bsearch.h
===================================================================
--- uspace/lib/c/include/bsearch.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/bsearch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,11 +33,16 @@
  */
 
-#ifndef LIBC_BSEARCH_H_
-#define LIBC_BSEARCH_H_
+#ifndef _LIBC_BSEARCH_H_
+#define _LIBC_BSEARCH_H_
 
 #include <stddef.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 extern void *bsearch(const void *, const void *, size_t, size_t,
     int (*)(const void *, const void *));
+
+__C_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/byteorder.h
===================================================================
--- uspace/lib/c/include/byteorder.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/byteorder.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_BYTEORDER_H_
-#define LIBC_BYTEORDER_H_
+#ifndef _LIBC_BYTEORDER_H_
+#define _LIBC_BYTEORDER_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/cap.h
===================================================================
--- uspace/lib/c/include/cap.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/cap.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_CAP_H_
-#define LIBC_CAP_H_
+#ifndef _LIBC_CAP_H_
+#define _LIBC_CAP_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/cc.h
===================================================================
--- uspace/lib/c/include/cc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,49 +1,0 @@
-/*
- * Copyright (c) 2013 Vojtech Horky
- * 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.
- */
-
-/** @addtogroup libc
- * @{
- */
-/** @file
- * Macros related to used compiler (such as GCC-specific attributes).
- */
-
-#ifndef LIBC_CC_H_
-#define LIBC_CC_H_
-
-#ifndef __clang__
-#define ATTRIBUTE_OPTIMIZE(opt) \
-	__attribute__ ((optimize(opt)))
-#else
-#define ATTRIBUTE_OPTIMIZE(opt)
-#endif
-
-#endif
-
-/** @}
- */
Index: uspace/lib/c/include/clipboard.h
===================================================================
--- uspace/lib/c/include/clipboard.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/clipboard.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CLIPBOARD_H_
-#define LIBC_CLIPBOARD_H_
+#ifndef _LIBC_CLIPBOARD_H_
+#define _LIBC_CLIPBOARD_H_
 
 extern errno_t clipboard_put_str(const char *);
Index: uspace/lib/c/include/config.h
===================================================================
--- uspace/lib/c/include/config.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/config.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CONFIG_H_
-#define LIBC_CONFIG_H_
+#ifndef _LIBC_CONFIG_H_
+#define _LIBC_CONFIG_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/context.h
===================================================================
--- uspace/lib/c/include/context.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/context.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,9 +27,11 @@
  */
 
-#ifndef LIBC_CONTEXT_H_
-#define LIBC_CONTEXT_H_
+#ifndef _LIBC_CONTEXT_H_
+#define _LIBC_CONTEXT_H_
 
 #include <_bits/size_t.h>
 #include <libarch/fibril_context.h>
+
+typedef __context_t context_t;
 
 /* Context initialization data. */
Index: uspace/lib/c/include/corecfg.h
===================================================================
--- uspace/lib/c/include/corecfg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/corecfg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CORECFG_H_
-#define LIBC_CORECFG_H_
+#ifndef _LIBC_CORECFG_H_
+#define _LIBC_CORECFG_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/ctype.h
===================================================================
--- uspace/lib/c/include/ctype.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ctype.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,104 +27,25 @@
  */
 
-/** @addtogroup libc
- * @{
- */
-/** @file
- */
+#ifndef _LIBC_CTYPE_H_
+#define _LIBC_CTYPE_H_
 
-#ifndef LIBC_CTYPE_H_
-#define LIBC_CTYPE_H_
+#include <_bits/decls.h>
 
-static inline int islower(int c)
-{
-	return ((c >= 'a') && (c <= 'z'));
-}
-
-static inline int isupper(int c)
-{
-	return ((c >= 'A') && (c <= 'Z'));
-}
-
-static inline int isalpha(int c)
-{
-	return (islower(c) || isupper(c));
-}
-
-static inline int isdigit(int c)
-{
-	return ((c >= '0') && (c <= '9'));
-}
-
-static inline int isalnum(int c)
-{
-	return (isalpha(c) || isdigit(c));
-}
-
-static inline int isblank(int c)
-{
-	return c == ' ' || c == '\t';
-}
-
-static inline int iscntrl(int c)
-{
-	return (c >= 0 && c < 0x20) || c == 0x7E;
-}
-
-static inline int isprint(int c)
-{
-	return c >= 0 && c < 0x80 && !iscntrl(c);
-}
-
-static inline int isgraph(int c)
-{
-	return isprint(c) && c != ' ';
-}
-
-static inline int isspace(int c)
-{
-	switch (c) {
-	case ' ':
-	case '\n':
-	case '\t':
-	case '\f':
-	case '\r':
-	case '\v':
-		return 1;
-		break;
-	default:
-		return 0;
-	}
-}
-
-static inline int ispunct(int c)
-{
-	return !isspace(c) && !isalnum(c) && isprint(c);
-}
-
-static inline int isxdigit(int c)
-{
-	return isdigit(c) ||
-	    (c >= 'a' && c <= 'f') ||
-	    (c >= 'A' && c <= 'F');
-}
-
-static inline int tolower(int c)
-{
-	if (isupper(c))
-		return (c + ('a' - 'A'));
-	else
-		return c;
-}
-
-static inline int toupper(int c)
-{
-	if (islower(c))
-		return (c + ('A' - 'a'));
-	else
-		return c;
-}
+__C_DECLS_BEGIN;
+int islower(int);
+int isupper(int);
+int isalpha(int);
+int isdigit(int);
+int isalnum(int);
+int isblank(int);
+int iscntrl(int);
+int isprint(int);
+int isgraph(int);
+int isspace(int);
+int ispunct(int);
+int isxdigit(int);
+int tolower(int);
+int toupper(int);
+__C_DECLS_END;
 
 #endif
-
-/** @}
- */
Index: uspace/lib/c/include/ddi.h
===================================================================
--- uspace/lib/c/include/ddi.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ddi.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DDI_H_
-#define LIBC_DDI_H_
+#ifndef _LIBC_DDI_H_
+#define _LIBC_DDI_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/device/clock_dev.h
===================================================================
--- uspace/lib/c/include/device/clock_dev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/device/clock_dev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DEVICE_CLOCK_DEV_H_
-#define LIBC_DEVICE_CLOCK_DEV_H_
+#ifndef _LIBC_DEVICE_CLOCK_DEV_H_
+#define _LIBC_DEVICE_CLOCK_DEV_H_
 
 #include <async.h>
Index: uspace/lib/c/include/device/hw_res.h
===================================================================
--- uspace/lib/c/include/device/hw_res.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/device/hw_res.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DEVICE_HW_RES_H_
-#define LIBC_DEVICE_HW_RES_H_
+#ifndef _LIBC_DEVICE_HW_RES_H_
+#define _LIBC_DEVICE_HW_RES_H_
 
 #include <ipc/dev_iface.h>
Index: uspace/lib/c/include/device/hw_res_parsed.h
===================================================================
--- uspace/lib/c/include/device/hw_res_parsed.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/device/hw_res_parsed.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DEVICE_HW_RES_PARSED_H_
-#define LIBC_DEVICE_HW_RES_PARSED_H_
+#ifndef _LIBC_DEVICE_HW_RES_PARSED_H_
+#define _LIBC_DEVICE_HW_RES_PARSED_H_
 
 #include <device/hw_res.h>
Index: uspace/lib/c/include/device/led_dev.h
===================================================================
--- uspace/lib/c/include/device/led_dev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/device/led_dev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DEVICE_LED_DEV_H_
-#define LIBC_DEVICE_LED_DEV_H_
+#ifndef _LIBC_DEVICE_LED_DEV_H_
+#define _LIBC_DEVICE_LED_DEV_H_
 
 #include <async.h>
Index: uspace/lib/c/include/device/pio_window.h
===================================================================
--- uspace/lib/c/include/device/pio_window.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/device/pio_window.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_DEVICE_PIO_WINDOW_H_
-#define LIBC_DEVICE_PIO_WINDOW_H_
+#ifndef _LIBC_DEVICE_PIO_WINDOW_H_
+#define _LIBC_DEVICE_PIO_WINDOW_H_
 
 #include <ipc/dev_iface.h>
Index: uspace/lib/c/include/devman.h
===================================================================
--- uspace/lib/c/include/devman.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/devman.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_DEVMAN_H_
-#define LIBC_DEVMAN_H_
+#ifndef _LIBC_DEVMAN_H_
+#define _LIBC_DEVMAN_H_
 
 #include <ipc/devman.h>
Index: uspace/lib/c/include/dirent.h
===================================================================
--- uspace/lib/c/include/dirent.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/dirent.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,20 +33,16 @@
  */
 
-#ifndef LIBC_DIRENT_H_
-#define LIBC_DIRENT_H_
+#ifndef _LIBC_DIRENT_H_
+#define _LIBC_DIRENT_H_
 
-#define NAME_MAX  256
+#include <_bits/decls.h>
 
-#include <offset.h>
+__C_DECLS_BEGIN;
 
 struct dirent {
-	char d_name[NAME_MAX + 1];
+	char d_name[256];
 };
 
-typedef struct {
-	int fd;
-	struct dirent res;
-	aoff64_t pos;
-} DIR;
+typedef struct __dirstream DIR;
 
 extern DIR *opendir(const char *);
@@ -55,4 +51,6 @@
 extern int closedir(DIR *);
 
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/c/include/dlfcn.h
===================================================================
--- uspace/lib/c/include/dlfcn.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/dlfcn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,9 +34,15 @@
  */
 
-#ifndef LIBC_DLFCN_H_
-#define LIBC_DLFCN_H_
+#ifndef _LIBC_DLFCN_H_
+#define _LIBC_DLFCN_H_
+
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 void *dlopen(const char *, int);
 void *dlsym(void *, const char *);
+
+__C_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/elf/elf.h
===================================================================
--- uspace/lib/c/include/elf/elf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/elf/elf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ELF_H_
-#define LIBC_ELF_H_
+#ifndef _LIBC_ELF_H_
+#define _LIBC_ELF_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/elf/elf_linux.h
===================================================================
--- uspace/lib/c/include/elf/elf_linux.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/elf/elf_linux.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ELF_LINUX_H_
-#define LIBC_ELF_LINUX_H_
+#ifndef _LIBC_ELF_LINUX_H_
+#define _LIBC_ELF_LINUX_H_
 
 #include <elf/elf.h>
Index: uspace/lib/c/include/elf/elf_load.h
===================================================================
--- uspace/lib/c/include/elf/elf_load.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/elf/elf_load.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,5 +45,5 @@
 } elf_info_t;
 
-extern int elf_load(int, elf_info_t *);
+extern errno_t elf_load(int, elf_info_t *);
 extern void elf_set_pcb(elf_info_t *, pcb_t *);
 
Index: uspace/lib/c/include/elf/elf_mod.h
===================================================================
--- uspace/lib/c/include/elf/elf_mod.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/elf/elf_mod.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,15 +42,4 @@
 #include <stdint.h>
 #include <loader/pcb.h>
-
-/**
- * ELF error return codes
- */
-#define EE_OK			0	/* No error */
-#define EE_INVALID		1	/* Invalid ELF image */
-#define EE_MEMORY		2	/* Cannot allocate address space */
-#define EE_INCOMPATIBLE		3	/* ELF image is not compatible with current architecture */
-#define EE_UNSUPPORTED		4	/* Non-supported ELF (e.g. dynamic ELFs) */
-#define EE_IRRECOVERABLE	5
-#define EE_IO			6	/* Could not read file. */
 
 typedef enum {
@@ -110,7 +99,6 @@
 } elf_ld_t;
 
-extern const char *elf_error(unsigned int);
-extern int elf_load_file(int, eld_flags_t, elf_finfo_t *);
-extern int elf_load_file_name(const char *, eld_flags_t, elf_finfo_t *);
+extern errno_t elf_load_file(int, eld_flags_t, elf_finfo_t *);
+extern errno_t elf_load_file_name(const char *, eld_flags_t, elf_finfo_t *);
 
 #endif
Index: uspace/lib/c/include/entry_point.h
===================================================================
--- uspace/lib/c/include/entry_point.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/entry_point.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_ENTRY_POINT_H_
-#define LIBC_ENTRY_POINT_H_
+#ifndef _LIBC_ENTRY_POINT_H_
+#define _LIBC_ENTRY_POINT_H_
 
 /* Defined in arch/ARCH/src/entryjmp.[c|s] */
Index: uspace/lib/c/include/errno.h
===================================================================
--- uspace/lib/c/include/errno.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/errno.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,13 +33,22 @@
  */
 
-#ifndef LIBC_ERRNO_H_
-#define LIBC_ERRNO_H_
+#ifndef _LIBC_ERRNO_H_
+#define _LIBC_ERRNO_H_
 
 #include <_bits/errno.h>
 #include <abi/errno.h>
+#include <_bits/decls.h>
 
-#define errno  (*(__errno()))
+__HELENOS_DECLS_BEGIN;
 
 extern errno_t *__errno(void) __attribute__((const));
+
+__HELENOS_DECLS_END;
+
+#ifdef __cplusplus
+#define errno  (*(::helenos::__errno()))
+#else
+#define errno  (*(__errno()))
+#endif
 
 #endif
Index: uspace/lib/c/include/fibril.h
===================================================================
--- uspace/lib/c/include/fibril.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/fibril.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,11 +33,13 @@
  */
 
-#ifndef LIBC_FIBRIL_H_
-#define LIBC_FIBRIL_H_
+#ifndef _LIBC_FIBRIL_H_
+#define _LIBC_FIBRIL_H_
 
-#include <types/common.h>
 #include <time.h>
+#include <_bits/errno.h>
 #include <_bits/__noreturn.h>
-#include <ipc/common.h>
+#include <_bits/decls.h>
+
+__HELENOS_DECLS_BEGIN;
 
 typedef struct fibril fibril_t;
@@ -49,10 +51,11 @@
 typedef fibril_t *fid_t;
 
+#ifndef __cplusplus
 /** Fibril-local variable specifier */
 #define fibril_local __thread
-
-#define FIBRIL_DFLT_STK_SIZE	0
+#endif
 
 extern fid_t fibril_create_generic(errno_t (*)(void *), void *, size_t);
+extern fid_t fibril_create(errno_t (*)(void *), void *);
 extern void fibril_destroy(fid_t);
 extern void fibril_add_ready(fid_t);
@@ -68,11 +71,8 @@
 extern void fibril_detach(fid_t fid);
 
-static inline fid_t fibril_create(errno_t (*func)(void *), void *arg)
-{
-	return fibril_create_generic(func, arg, FIBRIL_DFLT_STK_SIZE);
-}
-
 extern void fibril_start(fid_t);
 extern __noreturn void fibril_exit(long);
+
+__HELENOS_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/fibril_synch.h
===================================================================
--- uspace/lib/c/include/fibril_synch.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/fibril_synch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,18 +33,14 @@
  */
 
-#ifndef LIBC_FIBRIL_SYNCH_H_
-#define LIBC_FIBRIL_SYNCH_H_
+#ifndef _LIBC_FIBRIL_SYNCH_H_
+#define _LIBC_FIBRIL_SYNCH_H_
 
 #include <fibril.h>
 #include <adt/list.h>
-#include <tls.h>
 #include <time.h>
 #include <stdbool.h>
-
-typedef struct {
-	fibril_owner_info_t oi;  /**< Keep this the first thing. */
-	int counter;
-	list_t waiters;
-} fibril_mutex_t;
+#include <_bits/decls.h>
+
+#ifndef __cplusplus
 
 #define FIBRIL_MUTEX_INITIALIZER(name) \
@@ -54,21 +50,9 @@
 		}, \
 		.counter = 1, \
-		.waiters = { \
-			.head = { \
-				.prev = &(name).waiters.head, \
-				.next = &(name).waiters.head, \
-			} \
-		} \
+		.waiters = LIST_INITIALIZER((name).waiters), \
 	}
 
 #define FIBRIL_MUTEX_INITIALIZE(name) \
 	fibril_mutex_t name = FIBRIL_MUTEX_INITIALIZER(name)
-
-typedef struct {
-	fibril_owner_info_t oi;  /**< Keep this the first thing. */
-	unsigned int writers;
-	unsigned int readers;
-	list_t waiters;
-} fibril_rwlock_t;
 
 #define FIBRIL_RWLOCK_INITIALIZER(name) \
@@ -79,10 +63,5 @@
 		.readers = 0, \
 		.writers = 0, \
-		.waiters = { \
-			.head = { \
-				.prev = &(name).waiters.head, \
-				.next = &(name).waiters.head, \
-			} \
-		} \
+		.waiters = LIST_INITIALIZER((name).waiters), \
 	}
 
@@ -90,20 +69,41 @@
 	fibril_rwlock_t name = FIBRIL_RWLOCK_INITIALIZER(name)
 
-typedef struct {
-	list_t waiters;
-} fibril_condvar_t;
-
 #define FIBRIL_CONDVAR_INITIALIZER(name) \
 	{ \
-		.waiters = { \
-			.head = { \
-				.next = &(name).waiters.head, \
-				.prev = &(name).waiters.head, \
-			} \
-		} \
+		.waiters = LIST_INITIALIZER((name).waiters), \
 	}
 
 #define FIBRIL_CONDVAR_INITIALIZE(name) \
 	fibril_condvar_t name = FIBRIL_CONDVAR_INITIALIZER(name)
+
+#define FIBRIL_SEMAPHORE_INITIALIZER(name, cnt) \
+	{ \
+		.count = (cnt), \
+		.waiters = LIST_INITIALIZER((name).waiters), \
+	}
+
+#define FIBRIL_SEMAPHORE_INITIALIZE(name, cnt) \
+	fibril_semaphore_t name = FIBRIL_SEMAPHORE_INITIALIZER(name, cnt)
+
+#endif
+
+__HELENOS_DECLS_BEGIN;
+
+typedef struct {
+	fibril_owner_info_t oi;  /**< Keep this the first thing. */
+	int counter;
+	list_t waiters;
+} fibril_mutex_t;
+
+typedef struct {
+	fibril_owner_info_t oi;  /**< Keep this the first thing. */
+	unsigned int writers;
+	unsigned int readers;
+	list_t waiters;
+} fibril_rwlock_t;
+
+typedef struct {
+	list_t waiters;
+} fibril_condvar_t;
 
 typedef void (*fibril_timer_fun_t)(void *);
@@ -150,18 +150,4 @@
 } fibril_semaphore_t;
 
-#define FIBRIL_SEMAPHORE_INITIALIZER(name, cnt) \
-	{ \
-		.count = (cnt), \
-		.waiters = { \
-			.head = { \
-				.next = &(name).waiters.head, \
-				.prev = &(name).waiters.head, \
-			} \
-		} \
-	}
-
-#define FIBRIL_SEMAPHORE_INITIALIZE(name, cnt) \
-	fibril_semaphore_t name = FIBRIL_SEMAPHORE_INITIALIZER(name, cnt)
-
 extern void __fibril_synch_init(void);
 extern void __fibril_synch_fini(void);
@@ -211,4 +197,6 @@
 extern void mpsc_close(mpsc_t *);
 
+__HELENOS_DECLS_END;
+
 #endif
 
Index: uspace/lib/c/include/fourcc.h
===================================================================
--- uspace/lib/c/include/fourcc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/fourcc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_FOURCC_H_
-#define LIBC_FOURCC_H_
+#ifndef _LIBC_FOURCC_H_
+#define _LIBC_FOURCC_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/gsort.h
===================================================================
--- uspace/lib/c/include/gsort.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/gsort.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_SORT_H_
-#define LIBC_SORT_H_
+#ifndef _LIBC_SORT_H_
+#define _LIBC_SORT_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/ieee80211/ieee80211.h
===================================================================
--- uspace/lib/c/include/ieee80211/ieee80211.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ieee80211/ieee80211.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef LIBC_IEEE80211_H_
-#define LIBC_IEEE80211_H_
+#ifndef _LIBC_IEEE80211_H_
+#define _LIBC_IEEE80211_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/imath.h
===================================================================
--- uspace/lib/c/include/imath.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/imath.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IMATH_H_
-#define LIBC_IMATH_H_
+#ifndef _LIBC_IMATH_H_
+#define _LIBC_IMATH_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/inet/addr.h
===================================================================
--- uspace/lib/c/include/inet/addr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/addr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_ADDR_H_
-#define LIBC_INET_ADDR_H_
+#ifndef _LIBC_INET_ADDR_H_
+#define _LIBC_INET_ADDR_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/inet/dhcp.h
===================================================================
--- uspace/lib/c/include/inet/dhcp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/dhcp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_DHCP_H_
-#define LIBC_INET_DHCP_H_
+#ifndef _LIBC_INET_DHCP_H_
+#define _LIBC_INET_DHCP_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/inet/dnsr.h
===================================================================
--- uspace/lib/c/include/inet/dnsr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/dnsr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_DNSR_H_
-#define LIBC_INET_DNSR_H_
+#ifndef _LIBC_INET_DNSR_H_
+#define _LIBC_INET_DNSR_H_
 
 #include <inet/inet.h>
Index: uspace/lib/c/include/inet/endpoint.h
===================================================================
--- uspace/lib/c/include/inet/endpoint.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/endpoint.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_ENDPOINT_H_
-#define LIBC_INET_ENDPOINT_H_
+#ifndef _LIBC_INET_ENDPOINT_H_
+#define _LIBC_INET_ENDPOINT_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/inet/host.h
===================================================================
--- uspace/lib/c/include/inet/host.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/host.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_HOST_H_
-#define LIBC_INET_HOST_H_
+#ifndef _LIBC_INET_HOST_H_
+#define _LIBC_INET_HOST_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/inet/hostname.h
===================================================================
--- uspace/lib/c/include/inet/hostname.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/hostname.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_HOSTNAME_H_
-#define LIBC_INET_HOSTNAME_H_
+#ifndef _LIBC_INET_HOSTNAME_H_
+#define _LIBC_INET_HOSTNAME_H_
 
 extern errno_t inet_hostname_parse(const char *, char **, char **);
Index: uspace/lib/c/include/inet/hostport.h
===================================================================
--- uspace/lib/c/include/inet/hostport.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/hostport.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_HOSTPORT_H_
-#define LIBC_INET_HOSTPORT_H_
+#ifndef _LIBC_INET_HOSTPORT_H_
+#define _LIBC_INET_HOSTPORT_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/inet/inet.h
===================================================================
--- uspace/lib/c/include/inet/inet.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/inet.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_INET_H_
-#define LIBC_INET_INET_H_
+#ifndef _LIBC_INET_INET_H_
+#define _LIBC_INET_INET_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/inet/inetcfg.h
===================================================================
--- uspace/lib/c/include/inet/inetcfg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/inetcfg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_INETCFG_H_
-#define LIBC_INET_INETCFG_H_
+#ifndef _LIBC_INET_INETCFG_H_
+#define _LIBC_INET_INETCFG_H_
 
 #include <inet/inet.h>
Index: uspace/lib/c/include/inet/inetping.h
===================================================================
--- uspace/lib/c/include/inet/inetping.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/inetping.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_INETPING_H_
-#define LIBC_INET_INETPING_H_
+#ifndef _LIBC_INET_INETPING_H_
+#define _LIBC_INET_INETPING_H_
 
 #include <inet/inet.h>
Index: uspace/lib/c/include/inet/iplink.h
===================================================================
--- uspace/lib/c/include/inet/iplink.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/iplink.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_IPLINK_H_
-#define LIBC_INET_IPLINK_H_
+#ifndef _LIBC_INET_IPLINK_H_
+#define _LIBC_INET_IPLINK_H_
 
 #include <async.h>
Index: uspace/lib/c/include/inet/iplink_srv.h
===================================================================
--- uspace/lib/c/include/inet/iplink_srv.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/iplink_srv.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_IPLINK_SRV_H_
-#define LIBC_INET_IPLINK_SRV_H_
+#ifndef _LIBC_INET_IPLINK_SRV_H_
+#define _LIBC_INET_IPLINK_SRV_H_
 
 #include <async.h>
Index: uspace/lib/c/include/inet/tcp.h
===================================================================
--- uspace/lib/c/include/inet/tcp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/tcp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_TCP_H_
-#define LIBC_INET_TCP_H_
+#ifndef _LIBC_INET_TCP_H_
+#define _LIBC_INET_TCP_H_
 
 #include <fibril_synch.h>
Index: uspace/lib/c/include/inet/udp.h
===================================================================
--- uspace/lib/c/include/inet/udp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/inet/udp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_INET_UDP_H_
-#define LIBC_INET_UDP_H_
+#ifndef _LIBC_INET_UDP_H_
+#define _LIBC_INET_UDP_H_
 
 #include <async.h>
Index: uspace/lib/c/include/io/chardev.h
===================================================================
--- uspace/lib/c/include/io/chardev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/chardev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,9 +31,10 @@
  */
 
-#ifndef LIBC_IO_CHARDEV_H_
-#define LIBC_IO_CHARDEV_H_
+#ifndef _LIBC_IO_CHARDEV_H_
+#define _LIBC_IO_CHARDEV_H_
 
 #include <async.h>
 #include <stddef.h>
+#include <types/io/chardev.h>
 
 typedef struct {
@@ -43,5 +44,6 @@
 extern errno_t chardev_open(async_sess_t *, chardev_t **);
 extern void chardev_close(chardev_t *);
-extern errno_t chardev_read(chardev_t *, void *, size_t, size_t *);
+extern errno_t chardev_read(chardev_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 extern errno_t chardev_write(chardev_t *, const void *, size_t, size_t *);
 
Index: uspace/lib/c/include/io/chardev_srv.h
===================================================================
--- uspace/lib/c/include/io/chardev_srv.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/chardev_srv.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_CHARDEV_SRV_H_
-#define LIBC_IO_CHARDEV_SRV_H_
+#ifndef _LIBC_IO_CHARDEV_SRV_H_
+#define _LIBC_IO_CHARDEV_SRV_H_
 
 #include <adt/list.h>
@@ -41,4 +41,5 @@
 #include <stdbool.h>
 #include <stddef.h>
+#include <types/io/chardev.h>
 
 typedef struct chardev_ops chardev_ops_t;
@@ -59,5 +60,6 @@
 	errno_t (*open)(chardev_srvs_t *, chardev_srv_t *);
 	errno_t (*close)(chardev_srv_t *);
-	errno_t (*read)(chardev_srv_t *, void *, size_t, size_t *);
+	errno_t (*read)(chardev_srv_t *, void *, size_t, size_t *,
+	    chardev_flags_t);
 	errno_t (*write)(chardev_srv_t *, const void *, size_t, size_t *);
 	void (*def_handler)(chardev_srv_t *, ipc_call_t *);
Index: uspace/lib/c/include/io/charfield.h
===================================================================
--- uspace/lib/c/include/io/charfield.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/charfield.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IO_CHARFIELD_H_
-#define LIBC_IO_CHARFIELD_H_
+#ifndef _LIBC_IO_CHARFIELD_H_
+#define _LIBC_IO_CHARFIELD_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/io/chargrid.h
===================================================================
--- uspace/lib/c/include/io/chargrid.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/chargrid.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IO_CHARGRID_H_
-#define LIBC_IO_CHARGRID_H_
+#ifndef _LIBC_IO_CHARGRID_H_
+#define _LIBC_IO_CHARGRID_H_
 
 #include <io/charfield.h>
Index: uspace/lib/c/include/io/color.h
===================================================================
--- uspace/lib/c/include/io/color.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/color.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_COLOR_H_
-#define LIBC_IO_COLOR_H_
+#ifndef _LIBC_IO_COLOR_H_
+#define _LIBC_IO_COLOR_H_
 
 typedef enum {
Index: uspace/lib/c/include/io/con_srv.h
===================================================================
--- uspace/lib/c/include/io/con_srv.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/con_srv.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_CON_SRV_H_
-#define LIBC_CON_SRV_H_
+#ifndef _LIBC_CON_SRV_H_
+#define _LIBC_CON_SRV_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/io/concaps.h
===================================================================
--- uspace/lib/c/include/io/concaps.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/concaps.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_CONCAPS_H_
-#define LIBC_IO_CONCAPS_H_
+#ifndef _LIBC_IO_CONCAPS_H_
+#define _LIBC_IO_CONCAPS_H_
 
 typedef enum {
Index: uspace/lib/c/include/io/cons_event.h
===================================================================
--- uspace/lib/c/include/io/cons_event.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/cons_event.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_CONS_EVENT_H_
-#define LIBC_IO_CONS_EVENT_H_
+#ifndef _LIBC_IO_CONS_EVENT_H_
+#define _LIBC_IO_CONS_EVENT_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/io/console.h
===================================================================
--- uspace/lib/c/include/io/console.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/console.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_CONSOLE_H_
-#define LIBC_IO_CONSOLE_H_
+#ifndef _LIBC_IO_CONSOLE_H_
+#define _LIBC_IO_CONSOLE_H_
 
 #include <time.h>
Index: uspace/lib/c/include/io/input.h
===================================================================
--- uspace/lib/c/include/io/input.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/input.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_INPUT_H_
-#define LIBC_IO_INPUT_H_
+#ifndef _LIBC_IO_INPUT_H_
+#define _LIBC_IO_INPUT_H_
 
 #include <async.h>
Index: uspace/lib/c/include/io/kbd_event.h
===================================================================
--- uspace/lib/c/include/io/kbd_event.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/kbd_event.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_KBD_EVENT_H_
-#define LIBC_IO_KBD_EVENT_H_
+#ifndef _LIBC_IO_KBD_EVENT_H_
+#define _LIBC_IO_KBD_EVENT_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/io/keycode.h
===================================================================
--- uspace/lib/c/include/io/keycode.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/keycode.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_KEYCODE_H_
-#define LIBC_IO_KEYCODE_H_
+#ifndef _LIBC_IO_KEYCODE_H_
+#define _LIBC_IO_KEYCODE_H_
 
 /** Keycode definitions.
Index: uspace/lib/c/include/io/kio.h
===================================================================
--- uspace/lib/c/include/io/kio.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/kio.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_KIO_H_
-#define LIBC_IO_KIO_H_
+#ifndef _LIBC_IO_KIO_H_
+#define _LIBC_IO_KIO_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/io/klog.h
===================================================================
--- uspace/lib/c/include/io/klog.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/klog.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_KLOG_H_
-#define LIBC_IO_KLOG_H_
+#ifndef _LIBC_IO_KLOG_H_
+#define _LIBC_IO_KLOG_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/io/label.h
===================================================================
--- uspace/lib/c/include/io/label.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/label.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_LABEL_H_
-#define LIBC_IO_LABEL_H_
+#ifndef _LIBC_IO_LABEL_H_
+#define _LIBC_IO_LABEL_H_
 
 #include <types/label.h>
Index: uspace/lib/c/include/io/log.h
===================================================================
--- uspace/lib/c/include/io/log.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/log.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,6 +32,6 @@
  */
 
-#ifndef LIBC_IO_LOG_H_
-#define LIBC_IO_LOG_H_
+#ifndef _LIBC_IO_LOG_H_
+#define _LIBC_IO_LOG_H_
 
 #include <stdarg.h>
Index: uspace/lib/c/include/io/logctl.h
===================================================================
--- uspace/lib/c/include/io/logctl.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/logctl.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IO_LOGCTL_H_
-#define LIBC_IO_LOGCTL_H_
+#ifndef _LIBC_IO_LOGCTL_H_
+#define _LIBC_IO_LOGCTL_H_
 
 #include <io/log.h>
Index: uspace/lib/c/include/io/mode.h
===================================================================
--- uspace/lib/c/include/io/mode.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/mode.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IO_MODE_H_
-#define LIBC_IO_MODE_H_
+#ifndef _LIBC_IO_MODE_H_
+#define _LIBC_IO_MODE_H_
 
 #include <abi/fb/visuals.h>
Index: uspace/lib/c/include/io/output.h
===================================================================
--- uspace/lib/c/include/io/output.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/output.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_OUTPUT_H_
-#define LIBC_IO_OUTPUT_H_
+#ifndef _LIBC_IO_OUTPUT_H_
+#define _LIBC_IO_OUTPUT_H_
 
 #include <ipc/output.h>
Index: uspace/lib/c/include/io/pixel.h
===================================================================
--- uspace/lib/c/include/io/pixel.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/pixel.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IO_PIXEL_H_
-#define LIBC_IO_PIXEL_H_
+#ifndef _LIBC_IO_PIXEL_H_
+#define _LIBC_IO_PIXEL_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/io/pixelmap.h
===================================================================
--- uspace/lib/c/include/io/pixelmap.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/pixelmap.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef LIBC_IO_PIXELMAP_H_
-#define LIBC_IO_PIXELMAP_H_
+#ifndef _LIBC_IO_PIXELMAP_H_
+#define _LIBC_IO_PIXELMAP_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/io/pos_event.h
===================================================================
--- uspace/lib/c/include/io/pos_event.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/pos_event.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IO_POS_EVENT_H_
-#define LIBC_IO_POS_EVENT_H_
+#ifndef _LIBC_IO_POS_EVENT_H_
+#define _LIBC_IO_POS_EVENT_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/io/printf_core.h
===================================================================
--- uspace/lib/c/include/io/printf_core.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/printf_core.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_PRINTF_CORE_H_
-#define LIBC_PRINTF_CORE_H_
+#ifndef _LIBC_PRINTF_CORE_H_
+#define _LIBC_PRINTF_CORE_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/io/serial.h
===================================================================
--- uspace/lib/c/include/io/serial.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/serial.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_SERIAL_H_
-#define LIBC_IO_SERIAL_H_
+#ifndef _LIBC_IO_SERIAL_H_
+#define _LIBC_IO_SERIAL_H_
 
 #include <async.h>
Index: uspace/lib/c/include/io/style.h
===================================================================
--- uspace/lib/c/include/io/style.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/style.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_STYLE_H_
-#define LIBC_IO_STYLE_H_
+#ifndef _LIBC_IO_STYLE_H_
+#define _LIBC_IO_STYLE_H_
 
 typedef enum {
Index: uspace/lib/c/include/io/table.h
===================================================================
--- uspace/lib/c/include/io/table.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/table.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_TABLE_H_
-#define LIBC_IO_TABLE_H_
+#ifndef _LIBC_IO_TABLE_H_
+#define _LIBC_IO_TABLE_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/io/verify.h
===================================================================
--- uspace/lib/c/include/io/verify.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/verify.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_VERIFY_H_
-#define LIBC_IO_VERIFY_H_
+#ifndef _LIBC_IO_VERIFY_H_
+#define _LIBC_IO_VERIFY_H_
 
 #ifdef __clang__
Index: uspace/lib/c/include/io/visualizer.h
===================================================================
--- uspace/lib/c/include/io/visualizer.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/visualizer.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_VISUALIZER_H_
-#define LIBC_IO_VISUALIZER_H_
+#ifndef _LIBC_IO_VISUALIZER_H_
+#define _LIBC_IO_VISUALIZER_H_
 
 #include <async.h>
Index: uspace/lib/c/include/io/window.h
===================================================================
--- uspace/lib/c/include/io/window.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/io/window.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IO_WINDOW_H_
-#define LIBC_IO_WINDOW_H_
+#ifndef _LIBC_IO_WINDOW_H_
+#define _LIBC_IO_WINDOW_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/ipc/adb.h
===================================================================
--- uspace/lib/c/include/ipc/adb.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/adb.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IPC_ADB_H_
-#define LIBC_IPC_ADB_H_
+#ifndef _LIBC_IPC_ADB_H_
+#define _LIBC_IPC_ADB_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/bd.h
===================================================================
--- uspace/lib/c/include/ipc/bd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/bd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_BD_H_
-#define LIBC_IPC_BD_H_
+#ifndef _LIBC_IPC_BD_H_
+#define _LIBC_IPC_BD_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/chardev.h
===================================================================
--- uspace/lib/c/include/ipc/chardev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/chardev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IPC_CHARDEV_H_
-#define LIBC_IPC_CHARDEV_H_
+#ifndef _LIBC_IPC_CHARDEV_H_
+#define _LIBC_IPC_CHARDEV_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/clipboard.h
===================================================================
--- uspace/lib/c/include/ipc/clipboard.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/clipboard.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_CLIPBOARD_H_
-#define LIBC_IPC_CLIPBOARD_H_
+#ifndef _LIBC_IPC_CLIPBOARD_H_
+#define _LIBC_IPC_CLIPBOARD_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/common.h
===================================================================
--- uspace/lib/c/include/ipc/common.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/common.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_COMMON_H_
-#define LIBC_IPC_COMMON_H_
+#ifndef _LIBC_IPC_COMMON_H_
+#define _LIBC_IPC_COMMON_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/ipc/console.h
===================================================================
--- uspace/lib/c/include/ipc/console.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/console.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_CONSOLE_H_
-#define LIBC_IPC_CONSOLE_H_
+#ifndef _LIBC_IPC_CONSOLE_H_
+#define _LIBC_IPC_CONSOLE_H_
 
 #include <ipc/vfs.h>
Index: uspace/lib/c/include/ipc/corecfg.h
===================================================================
--- uspace/lib/c/include/ipc/corecfg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/corecfg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_CORECFG_H_
-#define LIBC_IPC_CORECFG_H_
+#ifndef _LIBC_IPC_CORECFG_H_
+#define _LIBC_IPC_CORECFG_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/dev_iface.h
===================================================================
--- uspace/lib/c/include/ipc/dev_iface.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/dev_iface.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_IPC_DEV_IFACE_H_
-#define LIBC_IPC_DEV_IFACE_H_
+#ifndef _LIBC_IPC_DEV_IFACE_H_
+#define _LIBC_IPC_DEV_IFACE_H_
 
 #include <stdlib.h>
@@ -91,8 +91,8 @@
  */
 
-#define DEV_IPC_GET_ARG1(call) IPC_GET_ARG2((call))
-#define DEV_IPC_GET_ARG2(call) IPC_GET_ARG3((call))
-#define DEV_IPC_GET_ARG3(call) IPC_GET_ARG4((call))
-#define DEV_IPC_GET_ARG4(call) IPC_GET_ARG5((call))
+#define DEV_IPC_GET_ARG1(call) ipc_get_arg2(&(call))
+#define DEV_IPC_GET_ARG2(call) ipc_get_arg3(&(call))
+#define DEV_IPC_GET_ARG3(call) ipc_get_arg4(&(call))
+#define DEV_IPC_GET_ARG4(call) ipc_get_arg5(&(call))
 
 #endif
Index: uspace/lib/c/include/ipc/devman.h
===================================================================
--- uspace/lib/c/include/ipc/devman.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/devman.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_DEVMAN_H_
-#define LIBC_IPC_DEVMAN_H_
+#ifndef _LIBC_IPC_DEVMAN_H_
+#define _LIBC_IPC_DEVMAN_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/dhcp.h
===================================================================
--- uspace/lib/c/include/ipc/dhcp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/dhcp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_DHCP_H_
-#define LIBC_IPC_DHCP_H_
+#ifndef _LIBC_IPC_DHCP_H_
+#define _LIBC_IPC_DHCP_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/dnsr.h
===================================================================
--- uspace/lib/c/include/ipc/dnsr.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/dnsr.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_DNSR_H_
-#define LIBC_IPC_DNSR_H_
+#ifndef _LIBC_IPC_DNSR_H_
+#define _LIBC_IPC_DNSR_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/event.h
===================================================================
--- uspace/lib/c/include/ipc/event.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/event.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_EVENT_H_
-#define LIBC_IPC_EVENT_H_
+#ifndef _LIBC_IPC_EVENT_H_
+#define _LIBC_IPC_EVENT_H_
 
 #include <abi/ipc/event.h>
Index: uspace/lib/c/include/ipc/graph.h
===================================================================
--- uspace/lib/c/include/ipc/graph.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/graph.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_GRAPH_H_
-#define LIBC_IPC_GRAPH_H_
+#ifndef _LIBC_IPC_GRAPH_H_
+#define _LIBC_IPC_GRAPH_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/inet.h
===================================================================
--- uspace/lib/c/include/ipc/inet.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/inet.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_INET_H_
-#define LIBC_IPC_INET_H_
+#ifndef _LIBC_IPC_INET_H_
+#define _LIBC_IPC_INET_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/input.h
===================================================================
--- uspace/lib/c/include/ipc/input.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/input.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_INPUT_H_
-#define LIBC_IPC_INPUT_H_
+#ifndef _LIBC_IPC_INPUT_H_
+#define _LIBC_IPC_INPUT_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/ipc.h
===================================================================
--- uspace/lib/c/include/ipc/ipc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/ipc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,10 +33,10 @@
  */
 
-#if ((defined(LIBC_ASYNC_H_)) && (!defined(LIBC_ASYNC_C_)))
+#if ((defined(_LIBC_ASYNC_H_)) && (!defined(_LIBC_ASYNC_C_)))
 #error Do not intermix low-level IPC interface and async framework
 #endif
 
-#ifndef LIBC_IPC_H_
-#define LIBC_IPC_H_
+#ifndef _LIBC_IPC_H_
+#define _LIBC_IPC_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/ipc_test.h
===================================================================
--- uspace/lib/c/include/ipc/ipc_test.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/ipc_test.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_IPC_TEST_H_
-#define LIBC_IPC_IPC_TEST_H_
+#ifndef _LIBC_IPC_IPC_TEST_H_
+#define _LIBC_IPC_IPC_TEST_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/iplink.h
===================================================================
--- uspace/lib/c/include/ipc/iplink.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/iplink.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_IPLINK_H_
-#define LIBC_IPC_IPLINK_H_
+#ifndef _LIBC_IPC_IPLINK_H_
+#define _LIBC_IPC_IPLINK_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/irc.h
===================================================================
--- uspace/lib/c/include/ipc/irc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/irc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_IRC_H_
-#define LIBC_IPC_IRC_H_
+#ifndef _LIBC_IPC_IRC_H_
+#define _LIBC_IPC_IRC_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/irq.h
===================================================================
--- uspace/lib/c/include/ipc/irq.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/irq.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_IRQ_H_
-#define LIBC_IPC_IRQ_H_
+#ifndef _LIBC_IPC_IRQ_H_
+#define _LIBC_IPC_IRQ_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/ipc/kbdev.h
===================================================================
--- uspace/lib/c/include/ipc/kbdev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/kbdev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_KBDEV_H_
-#define LIBC_IPC_KBDEV_H_
+#ifndef _LIBC_IPC_KBDEV_H_
+#define _LIBC_IPC_KBDEV_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/loader.h
===================================================================
--- uspace/lib/c/include/ipc/loader.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/loader.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_LOADER_H_
-#define LIBC_IPC_LOADER_H_
+#ifndef _LIBC_IPC_LOADER_H_
+#define _LIBC_IPC_LOADER_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/loc.h
===================================================================
--- uspace/lib/c/include/ipc/loc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/loc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,6 +32,6 @@
  */
 
-#ifndef LIBC_IPC_LOC_H_
-#define LIBC_IPC_LOC_H_
+#ifndef _LIBC_IPC_LOC_H_
+#define _LIBC_IPC_LOC_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/logger.h
===================================================================
--- uspace/lib/c/include/ipc/logger.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/logger.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_LOGGER_H_
-#define LIBC_IPC_LOGGER_H_
+#ifndef _LIBC_IPC_LOGGER_H_
+#define _LIBC_IPC_LOGGER_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/mouseev.h
===================================================================
--- uspace/lib/c/include/ipc/mouseev.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/mouseev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_IPC_MOUSEEV_H_
-#define LIBC_IPC_MOUSEEV_H_
+#ifndef _LIBC_IPC_MOUSEEV_H_
+#define _LIBC_IPC_MOUSEEV_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/ns.h
===================================================================
--- uspace/lib/c/include/ipc/ns.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/ns.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_NS_H_
-#define LIBC_IPC_NS_H_
+#ifndef _LIBC_IPC_NS_H_
+#define _LIBC_IPC_NS_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/output.h
===================================================================
--- uspace/lib/c/include/ipc/output.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/output.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_OUTPUT_H_
-#define LIBC_IPC_OUTPUT_H_
+#ifndef _LIBC_IPC_OUTPUT_H_
+#define _LIBC_IPC_OUTPUT_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/pci.h
===================================================================
--- uspace/lib/c/include/ipc/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/ipc/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libcipc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_IPC_PCI_H_
+#define _LIBC_IPC_PCI_H_
+
+#include <ipc/common.h>
+
+/** PCI control service requests */
+typedef enum {
+	PCI_GET_DEVICES = IPC_FIRST_USER_METHOD,
+	PCI_DEV_GET_INFO
+} pci_request_t;
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/c/include/ipc/serial_ctl.h
===================================================================
--- uspace/lib/c/include/ipc/serial_ctl.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/serial_ctl.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_IPC_SERIAL_CTL_H_
-#define LIBC_IPC_SERIAL_CTL_H_
+#ifndef _LIBC_IPC_SERIAL_CTL_H_
+#define _LIBC_IPC_SERIAL_CTL_H_
 
 #include <ipc/chardev.h>
Index: uspace/lib/c/include/ipc/services.h
===================================================================
--- uspace/lib/c/include/ipc/services.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/services.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef LIBC_SERVICES_H_
-#define LIBC_SERVICES_H_
+#ifndef _LIBC_SERVICES_H_
+#define _LIBC_SERVICES_H_
 
 #include <abi/fourcc.h>
Index: uspace/lib/c/include/ipc/tcp.h
===================================================================
--- uspace/lib/c/include/ipc/tcp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/tcp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_TCP_H_
-#define LIBC_IPC_TCP_H_
+#ifndef _LIBC_IPC_TCP_H_
+#define _LIBC_IPC_TCP_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/udp.h
===================================================================
--- uspace/lib/c/include/ipc/udp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/udp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_UDP_H_
-#define LIBC_IPC_UDP_H_
+#ifndef _LIBC_IPC_UDP_H_
+#define _LIBC_IPC_UDP_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/vbd.h
===================================================================
--- uspace/lib/c/include/ipc/vbd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/vbd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_VBD_H_
-#define LIBC_IPC_VBD_H_
+#ifndef _LIBC_IPC_VBD_H_
+#define _LIBC_IPC_VBD_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/vfs.h
===================================================================
--- uspace/lib/c/include/ipc/vfs.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/vfs.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_VFS_H_
-#define LIBC_IPC_VFS_H_
+#ifndef _LIBC_IPC_VFS_H_
+#define _LIBC_IPC_VFS_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/vol.h
===================================================================
--- uspace/lib/c/include/ipc/vol.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/vol.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,6 +31,6 @@
  */
 
-#ifndef LIBC_IPC_VOL_H_
-#define LIBC_IPC_VOL_H_
+#ifndef _LIBC_IPC_VOL_H_
+#define _LIBC_IPC_VOL_H_
 
 #include <ipc/common.h>
Index: uspace/lib/c/include/ipc/window.h
===================================================================
--- uspace/lib/c/include/ipc/window.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc/window.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_WINDOW_H_
-#define LIBC_IPC_WINDOW_H_
+#ifndef _LIBC_IPC_WINDOW_H_
+#define _LIBC_IPC_WINDOW_H_
 
 #include <ipc/vfs.h>
Index: uspace/lib/c/include/ipc_test.h
===================================================================
--- uspace/lib/c/include/ipc_test.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ipc_test.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IPC_TEST_H_
-#define LIBC_IPC_TEST_H_
+#ifndef _LIBC_IPC_TEST_H_
+#define _LIBC_IPC_TEST_H_
 
 #include <async.h>
Index: uspace/lib/c/include/irc.h
===================================================================
--- uspace/lib/c/include/irc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/irc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_IRC_H_
-#define LIBC_IRC_H_
+#ifndef _LIBC_IRC_H_
+#define _LIBC_IRC_H_
 
 extern errno_t irc_enable_interrupt(int);
Index: uspace/lib/c/include/l18n/langs.h
===================================================================
--- uspace/lib/c/include/l18n/langs.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/l18n/langs.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_L18N_LANGS_H_
-#define LIBC_L18N_LANGS_H_
+#ifndef _LIBC_L18N_LANGS_H_
+#define _LIBC_L18N_LANGS_H_
 
 /** Windows locale IDs.
Index: uspace/lib/c/include/libc.h
===================================================================
--- uspace/lib/c/include/libc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/libc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_LIBC_H_
-#define LIBC_LIBC_H_
+#ifndef _LIBC_LIBC_H_
+#define _LIBC_LIBC_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/loader/loader.h
===================================================================
--- uspace/lib/c/include/loader/loader.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/loader/loader.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_LOADER_H_
-#define LIBC_LOADER_H_
+#ifndef _LIBC_LOADER_H_
+#define _LIBC_LOADER_H_
 
 #include <abi/proc/task.h>
Index: uspace/lib/c/include/loader/pcb.h
===================================================================
--- uspace/lib/c/include/loader/pcb.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/loader/pcb.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_PCB_H_
-#define LIBC_PCB_H_
+#ifndef _LIBC_PCB_H_
+#define _LIBC_PCB_H_
 
 #include <tls.h>
Index: uspace/lib/c/include/loc.h
===================================================================
--- uspace/lib/c/include/loc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/loc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_LOC_H_
-#define LIBC_LOC_H_
+#ifndef _LIBC_LOC_H_
+#define _LIBC_LOC_H_
 
 #include <ipc/loc.h>
Index: uspace/lib/c/include/macros.h
===================================================================
--- uspace/lib/c/include/macros.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/macros.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_MACROS_H_
-#define LIBC_MACROS_H_
+#ifndef _LIBC_MACROS_H_
+#define _LIBC_MACROS_H_
 
 #define min(a, b)  ((a) < (b) ? (a) : (b))
Index: uspace/lib/c/include/malloc.h
===================================================================
--- uspace/lib/c/include/malloc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/malloc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,8 +33,11 @@
  */
 
-#ifndef LIBC_MALLOC_H_
-#define LIBC_MALLOC_H_
+#ifndef _LIBC_MALLOC_H_
+#define _LIBC_MALLOC_H_
 
 #include <stddef.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 extern void *malloc(size_t size)
@@ -42,10 +45,19 @@
 extern void *calloc(size_t nmemb, size_t size)
     __attribute__((malloc));
-extern void *memalign(size_t align, size_t size)
-    __attribute__((malloc));
 extern void *realloc(void *addr, size_t size)
     __attribute__((warn_unused_result));
 extern void free(void *addr);
+
+__C_DECLS_END;
+
+#ifdef _HELENOS_SOURCE
+__HELENOS_DECLS_BEGIN;
+
+extern void *memalign(size_t align, size_t size)
+    __attribute__((malloc));
 extern void *heap_check(void);
+
+__HELENOS_DECLS_END;
+#endif
 
 #endif
Index: uspace/lib/c/include/mem.h
===================================================================
--- uspace/lib/c/include/mem.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/mem.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,16 +34,16 @@
  */
 
-#ifndef LIBC_MEM_H_
-#define LIBC_MEM_H_
+#ifndef _LIBC_MEM_H_
+#define _LIBC_MEM_H_
 
 #include <stddef.h>
-#include <cc.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 extern void *memset(void *, int, size_t)
-    __attribute__((nonnull(1)))
-    ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns");
+    __attribute__((nonnull(1)));
 extern void *memcpy(void *, const void *, size_t)
-    __attribute__((nonnull(1, 2)))
-    ATTRIBUTE_OPTIMIZE("-fno-tree-loop-distribute-patterns");
+    __attribute__((nonnull(1, 2)));
 extern void *memmove(void *, const void *, size_t)
     __attribute__((nonnull(1, 2)));
@@ -53,4 +53,6 @@
     __attribute__((nonnull(1)));
 
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/c/include/nic/eth_phys.h
===================================================================
--- uspace/lib/c/include/nic/eth_phys.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/nic/eth_phys.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -28,6 +28,6 @@
  */
 
-#ifndef LIBC_NIC_ETH_PHYS_H_
-#define LIBC_NIC_ETH_PHYS_H_
+#ifndef _LIBC_NIC_ETH_PHYS_H_
+#define _LIBC_NIC_ETH_PHYS_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/nic/nic.h
===================================================================
--- uspace/lib/c/include/nic/nic.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/nic/nic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,6 +36,6 @@
  */
 
-#ifndef LIBC_NIC_H_
-#define LIBC_NIC_H_
+#ifndef _LIBC_NIC_H_
+#define _LIBC_NIC_H_
 
 #include <nic/eth_phys.h>
Index: uspace/lib/c/include/ns.h
===================================================================
--- uspace/lib/c/include/ns.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/ns.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_NS_H_
-#define LIBC_NS_H_
+#ifndef _LIBC_NS_H_
+#define _LIBC_NS_H_
 
 #include <ipc/services.h>
Index: uspace/lib/c/include/offset.h
===================================================================
--- uspace/lib/c/include/offset.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/offset.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,8 +33,14 @@
  */
 
-#ifndef LIBC_OFFSET_H_
-#define LIBC_OFFSET_H_
+#ifndef _LIBC_OFFSET_H_
+#define _LIBC_OFFSET_H_
+
+#ifndef _HELENOS_SOURCE
+#error This file should only be included from HelenOS sources
+#endif
 
 #include <stdint.h>
+#include <_bits/decls.h>
+#include <_bits/off64_t.h>
 
 /* off64_t */
@@ -52,9 +58,10 @@
 #define PRIXOFF64 PRIX64
 
-/** Relative offset */
-typedef int64_t off64_t;
+__HELENOS_DECLS_BEGIN;
 
 /** Absolute offset */
 typedef uint64_t aoff64_t;
+
+__HELENOS_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/pci.h
===================================================================
--- uspace/lib/c/include/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_PCI_H_
+#define _LIBC_PCI_H_
+
+#include <errno.h>
+#include <ipc/devman.h>
+#include <loc.h>
+#include <types/pci.h>
+
+extern errno_t pci_open(service_id_t, pci_t **);
+extern void pci_close(pci_t *);
+extern errno_t pci_get_devices(pci_t *, devman_handle_t **, size_t *);
+extern errno_t pci_dev_get_info(pci_t *, devman_handle_t, pci_dev_info_t *);
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/perf.h
===================================================================
--- uspace/lib/c/include/perf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/perf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2018 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ * System performance measurement utilities.
+ */
+
+#ifndef _LIBC_PERF_H_
+#define _LIBC_PERF_H_
+
+#include <time.h>
+
+/** Stopwatch is THE way to measure elapsed time on HelenOS. */
+typedef struct {
+	struct timespec start;
+	struct timespec end;
+} stopwatch_t;
+
+#define STOPWATCH_INITIALIZE_STATIC { { 0, 0 }, { 0, 0 } }
+
+/** Initialize system stopwatch.
+ *
+ * @param stopwatch Stopwatch to initialize.
+ */
+static inline void stopwatch_init(stopwatch_t *stopwatch)
+{
+	stopwatch->start.tv_sec = 0;
+	stopwatch->start.tv_nsec = 0;
+	stopwatch->end.tv_sec = 0;
+	stopwatch->end.tv_nsec = 0;
+}
+
+/** Emulate elapsed time for use in tests.
+ *
+ * @param stopwatch Stopwatch to use.
+ * @param nanos Elapsed time in nanoseconds to set.
+ */
+static inline void stopwatch_set_nanos(stopwatch_t *stopwatch, nsec_t nanos)
+{
+	stopwatch->start.tv_sec = 0;
+	stopwatch->start.tv_nsec = 0;
+	stopwatch->end.tv_sec = NSEC2SEC(nanos);
+	stopwatch->end.tv_nsec = nanos - SEC2NSEC(stopwatch->end.tv_sec);
+}
+
+/** Start the stopwatch.
+ *
+ * Note that repeated starts/stops do NOT aggregate the elapsed time.
+ *
+ * @param stopwatch Stopwatch to start.
+ */
+static inline void stopwatch_start(stopwatch_t *stopwatch)
+{
+	getuptime(&stopwatch->start);
+}
+
+/** Stop the stopwatch.
+ *
+ * Note that repeated starts/stops do NOT aggregate the elapsed time.
+ *
+ * @param stopwatch Stopwatch to stop.
+ */
+static inline void stopwatch_stop(stopwatch_t *stopwatch)
+{
+	getuptime(&stopwatch->end);
+}
+
+/** Get elapsed time in nanoseconds.
+ *
+ * @param stopwatch Stopwatch to read from.
+ * @return Elapsed time in nanoseconds.
+ */
+static inline nsec_t stopwatch_get_nanos(stopwatch_t *stopwatch)
+{
+	return ts_sub_diff(&stopwatch->end, &stopwatch->start);
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/qsort.h
===================================================================
--- uspace/lib/c/include/qsort.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/qsort.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,13 +33,21 @@
  */
 
-#ifndef LIBC_QSORT_H_
-#define LIBC_QSORT_H_
+#ifndef _LIBC_QSORT_H_
+#define _LIBC_QSORT_H_
 
 #include <stddef.h>
+#include <_bits/decls.h>
 
+__C_DECLS_BEGIN;
 extern void qsort(void *, size_t, size_t, int (*)(const void *,
     const void *));
+__C_DECLS_END;
+
+#ifdef _HELENOS_SOURCE
+__HELENOS_DECLS_BEGIN;
 extern void qsort_r(void *, size_t, size_t, int (*)(const void *,
     const void *, void *), void *);
+__HELENOS_DECLS_END;
+#endif
 
 #endif
Index: uspace/lib/c/include/refcount.h
===================================================================
--- uspace/lib/c/include/refcount.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/refcount.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,6 +37,6 @@
  */
 
-#ifndef LIBC_REFCOUNT_H_
-#define LIBC_REFCOUNT_H_
+#ifndef _LIBC_REFCOUNT_H_
+#define _LIBC_REFCOUNT_H_
 
 #include <assert.h>
Index: uspace/lib/c/include/rndgen.h
===================================================================
--- uspace/lib/c/include/rndgen.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rndgen.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RNDGEN_H_
-#define LIBC_RNDGEN_H_
+#ifndef _LIBC_RNDGEN_H_
+#define _LIBC_RNDGEN_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/rtld/dynamic.h
===================================================================
--- uspace/lib/c/include/rtld/dynamic.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/dynamic.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_DYNAMIC_H_
-#define LIBC_RTLD_DYNAMIC_H_
+#ifndef _LIBC_RTLD_DYNAMIC_H_
+#define _LIBC_RTLD_DYNAMIC_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/rtld/elf_dyn.h
===================================================================
--- uspace/lib/c/include/rtld/elf_dyn.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/elf_dyn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,84 +33,9 @@
  */
 
-#ifndef LIBC_RTLD_ELF_DYN_H_
-#define LIBC_RTLD_ELF_DYN_H_
+#ifndef _LIBC_RTLD_ELF_DYN_H_
+#define _LIBC_RTLD_ELF_DYN_H_
 
 #include <elf/elf.h>
 #include <libarch/rtld/elf_dyn.h>
-
-#define ELF32_R_SYM(i) ((i)>>8)
-#define ELF32_R_TYPE(i) ((unsigned char)(i))
-
-struct elf32_dyn {
-	elf_sword d_tag;
-	union {
-		elf_word d_val;
-		elf32_addr d_ptr;
-	} d_un;
-};
-
-struct elf32_rel {
-	elf32_addr r_offset;
-	elf_word r_info;
-};
-
-struct elf32_rela {
-	elf32_addr r_offset;
-	elf_word r_info;
-	elf_sword r_addend;
-};
-
-#ifdef __32_BITS__
-typedef struct elf32_dyn elf_dyn_t;
-typedef struct elf32_rel elf_rel_t;
-typedef struct elf32_rela elf_rela_t;
-#endif
-
-/*
- * Dynamic array tags
- */
-#define DT_NULL		0
-#define DT_NEEDED	1
-#define DT_PLTRELSZ	2
-#define DT_PLTGOT	3
-#define DT_HASH		4
-#define DT_STRTAB	5
-#define DT_SYMTAB	6
-#define DT_RELA		7
-#define DT_RELASZ	8
-#define DT_RELAENT	9
-#define DT_STRSZ	10
-#define DT_SYMENT	11
-#define DT_INIT		12
-#define DT_FINI		13
-#define DT_SONAME	14
-#define DT_RPATH	15
-#define DT_SYMBOLIC	16
-#define DT_REL		17
-#define DT_RELSZ	18
-#define DT_RELENT	19
-#define DT_PLTREL	20
-#define DT_DEBUG	21
-#define DT_TEXTREL	22
-#define DT_JMPREL	23
-#define DT_BIND_NOW	24
-#define DT_LOPROC	0x70000000
-#define DT_HIPROC	0x7fffffff
-
-/*
- * Special section indexes
- */
-#define SHN_UNDEF	0
-#define SHN_LORESERVE	0xff00
-#define SHN_LOPROC	0xff00
-#define SHN_HIPROC	0xff1f
-#define SHN_ABS		0xfff1
-#define SHN_COMMON	0xfff2
-#define SHN_HIRESERVE	0xffff
-
-/*
- * Special symbol table index
- */
-#define STN_UNDEF	0
 
 #endif
Index: uspace/lib/c/include/rtld/module.h
===================================================================
--- uspace/lib/c/include/rtld/module.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_MODULE_H_
-#define LIBC_RTLD_MODULE_H_
+#ifndef _LIBC_RTLD_MODULE_H_
+#define _LIBC_RTLD_MODULE_H_
 
 #include <rtld/dynamic.h>
@@ -45,5 +45,5 @@
 extern module_t *module_find(rtld_t *, const char *);
 extern module_t *module_load(rtld_t *, const char *, mlflags_t);
-extern void module_load_deps(module_t *, mlflags_t);
+extern errno_t module_load_deps(module_t *, mlflags_t);
 extern module_t *module_by_id(rtld_t *, unsigned long);
 
Index: uspace/lib/c/include/rtld/rtld.h
===================================================================
--- uspace/lib/c/include/rtld/rtld.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/rtld.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_H_
-#define LIBC_RTLD_H_
+#ifndef _LIBC_RTLD_H_
+#define _LIBC_RTLD_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/rtld/rtld_arch.h
===================================================================
--- uspace/lib/c/include/rtld/rtld_arch.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/rtld_arch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_RTLD_ARCH_H_
-#define LIBC_RTLD_RTLD_ARCH_H_
+#ifndef _LIBC_RTLD_RTLD_ARCH_H_
+#define _LIBC_RTLD_RTLD_ARCH_H_
 
 #include <rtld/rtld.h>
Index: uspace/lib/c/include/rtld/rtld_debug.h
===================================================================
--- uspace/lib/c/include/rtld/rtld_debug.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/rtld_debug.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_RTLD_DEBUG_H_
-#define LIBC_RTLD_RTLD_DEBUG_H_
+#ifndef _LIBC_RTLD_RTLD_DEBUG_H_
+#define _LIBC_RTLD_RTLD_DEBUG_H_
 
 #include <stdio.h>
Index: uspace/lib/c/include/rtld/symbol.h
===================================================================
--- uspace/lib/c/include/rtld/symbol.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/rtld/symbol.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_RTLD_SYMBOL_H_
-#define LIBC_RTLD_SYMBOL_H_
+#ifndef _LIBC_RTLD_SYMBOL_H_
+#define _LIBC_RTLD_SYMBOL_H_
 
 #include <elf/elf.h>
Index: uspace/lib/c/include/setjmp.h
===================================================================
--- uspace/lib/c/include/setjmp.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/setjmp.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,25 +31,23 @@
  */
 
-#ifndef LIBC_SETJMP_H_
-#define LIBC_SETJMP_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef _LIBC_SETJMP_H_
+#define _LIBC_SETJMP_H_
 
 #include <libarch/fibril_context.h>
 #include <_bits/__noreturn.h>
+#include <_bits/decls.h>
 
-typedef context_t jmp_buf[1];
+__C_DECLS_BEGIN;
 
-extern int __setjmp(jmp_buf) __attribute__((returns_twice));
-extern __noreturn void __longjmp(jmp_buf, int);
+typedef __context_t jmp_buf[1];
 
-#define setjmp __setjmp
+extern int __context_save(__context_t *) __attribute__((returns_twice));
+extern __noreturn void __context_restore(__context_t *, int);
+
 extern __noreturn void longjmp(jmp_buf, int);
 
-#ifdef __cplusplus
-}
-#endif
+__C_DECLS_END;
+
+#define setjmp __context_save
 
 #endif
Index: uspace/lib/c/include/smc.h
===================================================================
--- uspace/lib/c/include/smc.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/smc.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,7 +33,8 @@
  */
 
-#ifndef LIBC_SMC_H_
-#define LIBC_SMC_H_
+#ifndef _LIBC_SMC_H_
+#define _LIBC_SMC_H_
 
+#include <errno.h>
 #include <stddef.h>
 
Index: uspace/lib/c/include/stack.h
===================================================================
--- uspace/lib/c/include/stack.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/stack.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STACK_H_
-#define LIBC_STACK_H_
+#ifndef _LIBC_STACK_H_
+#define _LIBC_STACK_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/stacktrace.h
===================================================================
--- uspace/lib/c/include/stacktrace.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/stacktrace.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,6 +34,6 @@
  */
 
-#ifndef LIBC_STACKTRACE_H_
-#define LIBC_STACKTRACE_H_
+#ifndef _LIBC_STACKTRACE_H_
+#define _LIBC_STACKTRACE_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/stats.h
===================================================================
--- uspace/lib/c/include/stats.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/stats.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STATS_H_
-#define LIBC_STATS_H_
+#ifndef _LIBC_STATS_H_
+#define _LIBC_STATS_H_
 
 #include <task.h>
Index: uspace/lib/c/include/stdio.h
===================================================================
--- uspace/lib/c/include/stdio.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/stdio.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,12 +34,7 @@
  */
 
-#ifndef LIBC_STDIO_H_
-#define LIBC_STDIO_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <offset.h>
+#ifndef _LIBC_STDIO_H_
+#define _LIBC_STDIO_H_
+
 #include <stdarg.h>
 #include <io/verify.h>
@@ -48,13 +43,5 @@
 #include <_bits/wchar_t.h>
 #include <_bits/wint_t.h>
-
-/** Forward declaration */
-struct _IO_FILE;
-typedef struct _IO_FILE FILE;
-
-/** File position */
-typedef struct {
-	off64_t pos;
-} fpos_t;
+#include <_bits/decls.h>
 
 #ifndef _HELENOS_SOURCE
@@ -70,5 +57,5 @@
 
 /** Max number of files that is guaranteed to be able to open at the same time */
-#define FOPEN_MAX VFS_MAX_OPEN_FILES
+#define FOPEN_MAX 16
 
 /** Recommended size of fixed-size array for holding file names. */
@@ -92,4 +79,15 @@
 /** Minimum number of unique temporary file names */
 #define TMP_MAX 1000000
+
+__C_DECLS_BEGIN;
+
+/** Forward declaration */
+struct _IO_FILE;
+typedef struct _IO_FILE FILE;
+
+/** File position */
+typedef struct {
+	long long pos;
+} fpos_t;
 
 extern FILE *stdin;
@@ -98,15 +96,23 @@
 
 /* Character and string input functions */
-#define getc fgetc
 extern int fgetc(FILE *);
 extern char *fgets(char *, int, FILE *);
 extern char *gets(char *, size_t) __attribute__((deprecated));
 
+static inline int getc(FILE *f)
+{
+	return fgetc(f);
+}
+
 extern int getchar(void);
 
 /* Character and string output functions */
-#define putc fputc
 extern int fputc(int, FILE *);
 extern int fputs(const char *, FILE *);
+
+static inline int putc(int i, FILE *f)
+{
+	return fputc(i, f);
+}
 
 extern int putchar(int);
@@ -180,9 +186,15 @@
 extern char *tmpnam(char *s);
 
+__C_DECLS_END;
+
 #ifdef _HELENOS_SOURCE
 
+#include <_bits/off64_t.h>
+
+__HELENOS_DECLS_BEGIN;
+
 /* Nonstandard extensions. */
 
-enum _buffer_type {
+enum __buffer_type {
 	/** No buffering */
 	_IONBF,
@@ -193,30 +205,14 @@
 };
 
-enum _buffer_state {
-	/** Buffer is empty */
-	_bs_empty,
-
-	/** Buffer contains data to be written */
-	_bs_write,
-
-	/** Buffer contains prefetched data for reading */
-	_bs_read
-};
-
-extern int vprintf_size(const char *, va_list);
-extern int printf_size(const char *, ...)
+extern int vprintf_length(const char *, va_list);
+extern int printf_length(const char *, ...)
     _HELENOS_PRINTF_ATTRIBUTE(1, 2);
 extern FILE *fdopen(int, const char *);
 extern int fileno(FILE *);
 
-#include <offset.h>
-
 extern int fseek64(FILE *, off64_t, int);
 extern off64_t ftell64(FILE *);
 
-#endif
-
-#ifdef __cplusplus
-}
+__HELENOS_DECLS_END;
 #endif
 
Index: uspace/lib/c/include/stdlib.h
===================================================================
--- uspace/lib/c/include/stdlib.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/stdlib.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,16 +33,22 @@
  */
 
-#ifndef LIBC_STDLIB_H_
-#define LIBC_STDLIB_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef _LIBC_STDLIB_H_
+#define _LIBC_STDLIB_H_
 
 #include <_bits/size_t.h>
 #include <_bits/wchar_t.h>
+#include <_bits/decls.h>
 #include <bsearch.h>
 #include <malloc.h>
 #include <qsort.h>
+
+#define EXIT_SUCCESS 0
+#define EXIT_FAILURE 1
+
+#define RAND_MAX  714025
+
+#define MB_CUR_MAX 4
+
+__C_DECLS_BEGIN;
 
 /** Type returned by the div function */
@@ -69,11 +75,4 @@
 	long long rem;
 } lldiv_t;
-
-#define EXIT_FAILURE 1
-#define EXIT_SUCCESS 0
-
-#define RAND_MAX  714025
-
-#define MB_CUR_MAX 4
 
 extern long double strtold(const char *, char **);
@@ -109,7 +108,5 @@
 extern lldiv_t lldiv(long long, long long);
 
-#ifdef __cplusplus
-}
-#endif
+__C_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/str.h
===================================================================
--- uspace/lib/c/include/str.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/str.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,4 @@
 /*
+ * Copyright (c) 2001-2004 Jakub Jermar
  * Copyright (c) 2005 Martin Decky
  * Copyright (c) 2011 Oleg Romanenko
@@ -34,18 +35,19 @@
  */
 
-#ifndef LIBC_STR_H_
-#define LIBC_STR_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifndef _LIBC_STR_H_
+#define _LIBC_STR_H_
 
 #include <errno.h>
-#include <mem.h>
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <stdbool.h>
 
-#define U_SPECIAL  '?'
+#include <mem.h>
+#include <_bits/decls.h>
+
+#ifndef __cplusplus
+
+/* Common Unicode characters */
+#define U_SPECIAL      '?'
 
 /** No size limit constant */
@@ -61,7 +63,11 @@
 #define SPASCII_STR_BUFSIZE(spa_size) ((spa_size) + 1)
 
+#endif
+
+__HELENOS_DECLS_BEGIN;
+
 extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
 extern wchar_t str_decode_reverse(const char *str, size_t *offset, size_t sz);
-extern errno_t chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz);
+extern errno_t chr_encode(wchar_t ch, char *str, size_t *offset, size_t sz);
 
 extern size_t str_size(const char *str);
@@ -116,6 +122,6 @@
 extern bool wstr_remove(wchar_t *str, size_t pos);
 
-extern char *str_dup(const char *);
-extern char *str_ndup(const char *, size_t max_size);
+extern char *str_dup(const char *src);
+extern char *str_ndup(const char *src, size_t n);
 
 extern char *str_tok(char *, const char *, char **);
@@ -144,7 +150,5 @@
 extern unsigned long strtoul(const char *, char **, int);
 
-#ifdef __cplusplus
-}
-#endif
+__HELENOS_DECLS_END;
 
 #endif
Index: uspace/lib/c/include/str_error.h
===================================================================
--- uspace/lib/c/include/str_error.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/str_error.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_STRERROR_H_
-#define LIBC_STRERROR_H_
+#ifndef _LIBC_STRERROR_H_
+#define _LIBC_STRERROR_H_
 
 #include <errno.h>
Index: uspace/lib/c/include/string.h
===================================================================
--- uspace/lib/c/include/string.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/string.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,14 +33,18 @@
  */
 
-#ifndef LIBC_STRING_H_
-#define LIBC_STRING_H_
+#ifndef _LIBC_STRING_H_
+#define _LIBC_STRING_H_
 
-#if defined(_HELENOS_SOURCE) && !defined(_REALLY_WANT_STRING_H)
+#if defined(_HELENOS_SOURCE) && !defined(_REALLY_WANT_STRING_H) && \
+    !defined(_LIBC_SOURCE)
 #error Please use str.h and mem.h instead
 #endif
 
+#include <_bits/decls.h>
 #include <_bits/size_t.h>
 #include <_bits/NULL.h>
 #include <mem.h>
+
+__C_DECLS_BEGIN;
 
 extern char *strcpy(char *, const char *);
@@ -63,4 +67,12 @@
 extern size_t strlen(const char *);
 
+#if defined(_HELENOS_SOURCE) || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_LIBC_SOURCE)
+extern size_t strnlen(const char *, size_t);
+extern char *strdup(const char *);
+extern char *strndup(const char *, size_t);
+#endif
+
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/c/include/syscall.h
===================================================================
--- uspace/lib/c/include/syscall.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/syscall.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,6 +37,6 @@
  */
 
-#ifndef LIBC_SYSCALL_H_
-#define LIBC_SYSCALL_H_
+#ifndef _LIBC_SYSCALL_H_
+#define _LIBC_SYSCALL_H_
 
 #ifndef LIBARCH_SYSCALL_GENERIC
Index: uspace/lib/c/include/sysinfo.h
===================================================================
--- uspace/lib/c/include/sysinfo.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/sysinfo.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_SYSINFO_H_
-#define LIBC_SYSINFO_H_
+#ifndef _LIBC_SYSINFO_H_
+#define _LIBC_SYSINFO_H_
 
 #include <types/common.h>
Index: uspace/lib/c/include/task.h
===================================================================
--- uspace/lib/c/include/task.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/task.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TASK_H_
-#define LIBC_TASK_H_
+#ifndef _LIBC_TASK_H_
+#define _LIBC_TASK_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/time.h
===================================================================
--- uspace/lib/c/include/time.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/time.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,10 +33,8 @@
  */
 
-#ifndef LIBC_TIME_H_
-#define LIBC_TIME_H_
+#ifndef _LIBC_TIME_H_
+#define _LIBC_TIME_H_
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include <_bits/decls.h>
 
 /* ISO/IEC 9899:2011 7.27.1 (2) */
@@ -52,4 +50,6 @@
 #include <_bits/size_t.h>
 
+__C_DECLS_BEGIN;
+
 /* ISO/IEC 9899:2011 7.27.1 (3), (4) */
 
@@ -64,7 +64,5 @@
 struct tm {
 	int tm_sec;
-#ifdef _HELENOS_SOURCE
-	int tm_nsec;
-#endif
+	int tm_nsec;  /**< Nonstandard extension, nanoseconds since last second. */
 	int tm_min;
 	int tm_hour;
@@ -108,4 +106,6 @@
     const struct tm *__restrict__);
 
+__C_DECLS_END;
+
 #ifdef _HELENOS_SOURCE
 
@@ -116,4 +116,6 @@
 #include <stdbool.h>
 #include <_bits/errno.h>
+
+__HELENOS_DECLS_BEGIN;
 
 typedef long long sec_t;
@@ -157,9 +159,7 @@
 extern void udelay(sysarg_t);
 
+__HELENOS_DECLS_END;
+
 #endif /* _HELENOS_SOURCE */
-
-#ifdef __cplusplus
-}
-#endif
 
 #endif
Index: uspace/lib/c/include/tls.h
===================================================================
--- uspace/lib/c/include/tls.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/tls.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TLS_H_
-#define LIBC_TLS_H_
+#ifndef _LIBC_TLS_H_
+#define _LIBC_TLS_H_
 
 #include <libarch/tls.h>
Index: uspace/lib/c/include/tmpfile.h
===================================================================
--- uspace/lib/c/include/tmpfile.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/tmpfile.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#ifndef LIBC_TMPFILE_H_
-#define LIBC_TMPFILE_H_
+#ifndef _LIBC_TMPFILE_H_
+#define _LIBC_TMPFILE_H_
 
 #include <stdbool.h>
Index: uspace/lib/c/include/trace.h
===================================================================
--- uspace/lib/c/include/trace.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/trace.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,8 +33,8 @@
  */
 
-#ifndef LIBC_TRACE_H_
-#define LIBC_TRACE_H_
+#ifndef _LIBC_TRACE_H_
+#define _LIBC_TRACE_H_
 
-#define NO_TRACE  __attribute__((no_instrument_function))
+#define _NO_TRACE  __attribute__((no_instrument_function))
 
 #endif
Index: uspace/lib/c/include/types/casting.h
===================================================================
--- uspace/lib/c/include/types/casting.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/types/casting.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019 Vojtech Horky
+ * 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_TYPES_CASTING_H_
+#define _LIBC_TYPES_CASTING_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+
+/**
+ * Checks that the size_t value can be casted to int without loss of data.
+ *
+ * @param val Value to test.
+ * @return Whether it is safe to typecast value to int.
+ */
+static inline bool can_cast_size_t_to_int(size_t val)
+{
+	unsigned int as_uint = (unsigned int) val;
+	return !((as_uint != val) || (((int) as_uint) < 0));
+}
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/types/common.h
===================================================================
--- uspace/lib/c/include/types/common.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/common.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_COMMON_H_
-#define LIBC_TYPES_COMMON_H_
+#ifndef _LIBC_TYPES_COMMON_H_
+#define _LIBC_TYPES_COMMON_H_
 
 #if __SIZEOF_POINTER__ == 4
Index: uspace/lib/c/include/types/inet.h
===================================================================
--- uspace/lib/c/include/types/inet.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/inet.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_INET_H_
-#define LIBC_TYPES_INET_H_
+#ifndef _LIBC_TYPES_INET_H_
+#define _LIBC_TYPES_INET_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/types/inet/host.h
===================================================================
--- uspace/lib/c/include/types/inet/host.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/inet/host.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_INET_HOST_H_
-#define LIBC_TYPES_INET_HOST_H_
+#ifndef _LIBC_TYPES_INET_HOST_H_
+#define _LIBC_TYPES_INET_HOST_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/types/inet/hostport.h
===================================================================
--- uspace/lib/c/include/types/inet/hostport.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/inet/hostport.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_INET_HOSTPORT_H_
-#define LIBC_TYPES_INET_HOSTPORT_H_
+#ifndef _LIBC_TYPES_INET_HOSTPORT_H_
+#define _LIBC_TYPES_INET_HOSTPORT_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/types/inetcfg.h
===================================================================
--- uspace/lib/c/include/types/inetcfg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/inetcfg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_INETCFG_H_
-#define LIBC_TYPES_INETCFG_H_
+#ifndef _LIBC_TYPES_INETCFG_H_
+#define _LIBC_TYPES_INETCFG_H_
 
 #include <inet/inet.h>
Index: uspace/lib/c/include/types/inetping.h
===================================================================
--- uspace/lib/c/include/types/inetping.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/inetping.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,6 +35,6 @@
  */
 
-#ifndef LIBC_TYPES_INETPING_H_
-#define LIBC_TYPES_INETPING_H_
+#ifndef _LIBC_TYPES_INETPING_H_
+#define _LIBC_TYPES_INETPING_H_
 
 #include <inet/addr.h>
Index: uspace/lib/c/include/types/io/chardev.h
===================================================================
--- uspace/lib/c/include/types/io/chardev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/types/io/chardev.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+/** @addtogroup libc
+ * @{
+ */
+
+#ifndef _LIBC_TYPES_IO_CHARDEV_H_
+#define _LIBC_TYPES_IO_CHARDEV_H_
+
+/** Chardev read/write operation flags */
+typedef enum {
+	/** No flags */
+	chardev_f_none = 0,
+	/** Do not block even if no bytes can be transferred */
+	chardev_f_nonblock = 0x1
+} chardev_flags_t;
+
+#endif
+/**
+ * @}
+ */
Index: uspace/lib/c/include/types/label.h
===================================================================
--- uspace/lib/c/include/types/label.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/label.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_LABEL_H_
-#define LIBC_TYPES_LABEL_H_
+#ifndef _LIBC_TYPES_LABEL_H_
+#define _LIBC_TYPES_LABEL_H_
 
 #include <types/uuid.h>
Index: uspace/lib/c/include/types/pci.h
===================================================================
--- uspace/lib/c/include/types/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/include/types/pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/** @file
+ */
+
+#ifndef _LIBC_TYPES_PCI_H_
+#define _LIBC_TYPES_PCI_H_
+
+#include <async.h>
+#include <ipc/devman.h>
+#include <stdint.h>
+
+/** PCI device information */
+typedef struct {
+	/** Devman function handle */
+	devman_handle_t dev_handle;
+	/** Bus number */
+	uint8_t bus_num;
+	/** Device number */
+	uint8_t dev_num;
+	/** Function number */
+	uint8_t fn_num;
+	/** Vendor ID */
+	uint16_t vendor_id;
+	/** Device ID */
+	uint16_t device_id;
+} pci_dev_info_t;
+
+/** PCI service */
+typedef struct {
+	/** Session with PCI control service */
+	async_sess_t *sess;
+} pci_t;
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/c/include/types/rtld/module.h
===================================================================
--- uspace/lib/c/include/types/rtld/module.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/rtld/module.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_RTLD_MODULE_H_
-#define LIBC_TYPES_RTLD_MODULE_H_
+#ifndef _LIBC_TYPES_RTLD_MODULE_H_
+#define _LIBC_TYPES_RTLD_MODULE_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/types/rtld/rtld.h
===================================================================
--- uspace/lib/c/include/types/rtld/rtld.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/rtld/rtld.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_RTLD_RTLD_H_
-#define LIBC_TYPES_RTLD_RTLD_H_
+#ifndef _LIBC_TYPES_RTLD_RTLD_H_
+#define _LIBC_TYPES_RTLD_RTLD_H_
 
 #include <adt/list.h>
Index: uspace/lib/c/include/types/task.h
===================================================================
--- uspace/lib/c/include/types/task.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/task.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_TASK_H_
-#define LIBC_TYPES_TASK_H_
+#ifndef _LIBC_TYPES_TASK_H_
+#define _LIBC_TYPES_TASK_H_
 
 typedef enum {
Index: uspace/lib/c/include/types/uuid.h
===================================================================
--- uspace/lib/c/include/types/uuid.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/uuid.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_UUID_H_
-#define LIBC_TYPES_UUID_H_
+#ifndef _LIBC_TYPES_UUID_H_
+#define _LIBC_TYPES_UUID_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/types/vol.h
===================================================================
--- uspace/lib/c/include/types/vol.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/types/vol.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_TYPES_VOL_H_
-#define LIBC_TYPES_VOL_H_
+#ifndef _LIBC_TYPES_VOL_H_
+#define _LIBC_TYPES_VOL_H_
 
 #include <async.h>
Index: uspace/lib/c/include/udebug.h
===================================================================
--- uspace/lib/c/include/udebug.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/udebug.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_UDEBUG_H_
-#define LIBC_UDEBUG_H_
+#ifndef _LIBC_UDEBUG_H_
+#define _LIBC_UDEBUG_H_
 
 #include <abi/udebug.h>
Index: uspace/lib/c/include/unaligned.h
===================================================================
--- uspace/lib/c/include/unaligned.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/unaligned.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_UNALIGNED_H_
-#define LIBC_UNALIGNED_H_
+#ifndef _LIBC_UNALIGNED_H_
+#define _LIBC_UNALIGNED_H_
 
 #include <stdint.h>
Index: uspace/lib/c/include/uuid.h
===================================================================
--- uspace/lib/c/include/uuid.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/uuid.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,9 +33,10 @@
  */
 
-#ifndef LIBC_UUID_H_
-#define LIBC_UUID_H_
+#ifndef _LIBC_UUID_H_
+#define _LIBC_UUID_H_
 
 #include <stdint.h>
 #include <types/uuid.h>
+#include <stdbool.h>
 
 extern errno_t uuid_generate(uuid_t *);
@@ -43,5 +44,5 @@
 extern void uuid_decode(uint8_t *, uuid_t *);
 extern errno_t uuid_parse(const char *, uuid_t *, const char **);
-extern errno_t uuid_format(uuid_t *, char **);
+extern errno_t uuid_format(uuid_t *, char **, bool);
 
 #endif
Index: uspace/lib/c/include/vbd.h
===================================================================
--- uspace/lib/c/include/vbd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vbd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VBD_H_
-#define LIBC_VBD_H_
+#ifndef _LIBC_VBD_H_
+#define _LIBC_VBD_H_
 
 #include <async.h>
Index: uspace/lib/c/include/vfs/canonify.h
===================================================================
--- uspace/lib/c/include/vfs/canonify.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vfs/canonify.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VFS_CANONIFY_H_
-#define LIBC_VFS_CANONIFY_H_
+#ifndef _LIBC_VFS_CANONIFY_H_
+#define _LIBC_VFS_CANONIFY_H_
 
 #include <stddef.h>
Index: uspace/lib/c/include/vfs/inbox.h
===================================================================
--- uspace/lib/c/include/vfs/inbox.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vfs/inbox.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,6 +36,6 @@
  */
 
-#ifndef LIBC_VFS_INBOX_H_
-#define LIBC_VFS_INBOX_H_
+#ifndef _LIBC_VFS_INBOX_H_
+#define _LIBC_VFS_INBOX_H_
 
 enum {
Index: uspace/lib/c/include/vfs/vfs.h
===================================================================
--- uspace/lib/c/include/vfs/vfs.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vfs/vfs.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VFS_H_
-#define LIBC_VFS_H_
+#ifndef _LIBC_VFS_H_
+#define _LIBC_VFS_H_
 
 #include <stddef.h>
@@ -44,6 +44,4 @@
 #include <async.h>
 #include <offset.h>
-
-#define VFS_MAX_OPEN_FILES  128
 
 enum vfs_change_state_type {
Index: uspace/lib/c/include/vfs/vfs_mtab.h
===================================================================
--- uspace/lib/c/include/vfs/vfs_mtab.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vfs/vfs_mtab.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VFS_MTAB_H_
-#define LIBC_VFS_MTAB_H_
+#ifndef _LIBC_VFS_MTAB_H_
+#define _LIBC_VFS_MTAB_H_
 
 #include <ipc/vfs.h>
Index: uspace/lib/c/include/vfs/vfs_sess.h
===================================================================
--- uspace/lib/c/include/vfs/vfs_sess.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vfs/vfs_sess.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VFS_SESS_H_
-#define LIBC_VFS_SESS_H_
+#ifndef _LIBC_VFS_SESS_H_
+#define _LIBC_VFS_SESS_H_
 
 #include <async.h>
Index: uspace/lib/c/include/vol.h
===================================================================
--- uspace/lib/c/include/vol.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/vol.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,6 +33,6 @@
  */
 
-#ifndef LIBC_VOL_H_
-#define LIBC_VOL_H_
+#ifndef _LIBC_VOL_H_
+#define _LIBC_VOL_H_
 
 #include <async.h>
Index: uspace/lib/c/include/wchar.h
===================================================================
--- uspace/lib/c/include/wchar.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/include/wchar.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,6 +38,6 @@
  */
 
-#ifndef LIBC_WCHAR_H_
-#define LIBC_WCHAR_H_
+#ifndef _LIBC_WCHAR_H_
+#define _LIBC_WCHAR_H_
 
 #include <_bits/size_t.h>
Index: uspace/lib/c/test/adt/odict.c
===================================================================
--- uspace/lib/c/test/adt/odict.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/adt/odict.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2016 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 <adt/odict.h>
+#include <pcut/pcut.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/** Test entry */
+typedef struct {
+	odlink_t odict;
+	int key;
+} test_entry_t;
+
+enum {
+	/** Length of test number sequences */
+	test_seq_len = 100
+};
+
+/** Test get key function.
+ *
+ * @param odlink Ordered dictionary link
+ * @return Pointer to key
+ */
+static void *test_getkey(odlink_t *odlink)
+{
+	return &odict_get_instance(odlink, test_entry_t, odict)->key;
+}
+
+/** Test compare function.
+ *
+ * @param a First key
+ * @param b Second key
+ * @return <0, 0, >0 if @a a is less than, equal or greater than @a b
+ */
+static int test_cmp(void *a, void *b)
+{
+	int *ia = (int *)a;
+	int *ib = (int *)b;
+
+	return *ia - *ib;
+}
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(odict);
+
+/** Increasing sequence test.
+ *
+ * Test initialization, emptiness, insertion of increasing sequence and walking.
+ */
+PCUT_TEST(incr_seq)
+{
+	odict_t odict;
+	test_entry_t *e;
+	odlink_t *c;
+	int i;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = i;
+		odict_insert(&e->odict, &odict, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+	}
+
+	i = 0;
+	c = odict_first(&odict);
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_next(c, &odict);
+		++i;
+	}
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+
+	i = test_seq_len;
+	c = odict_last(&odict);
+	while (c != NULL) {
+		--i;
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_prev(c, &odict);
+	}
+
+	PCUT_ASSERT_INT_EQUALS(0, i);
+}
+
+/** Decreasing sequence test.
+ *
+ * Test initialization, emptiness, insertion of decreasing sequence and walking.
+ */
+PCUT_TEST(decr_seq)
+{
+	odict_t odict;
+	test_entry_t *e;
+	odlink_t *c;
+	int i;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = test_seq_len - i - 1;
+		odict_insert(&e->odict, &odict, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+	}
+
+	i = 0;
+	c = odict_first(&odict);
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_next(c, &odict);
+		++i;
+	}
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+
+	i = test_seq_len;
+	c = odict_last(&odict);
+	while (c != NULL) {
+		--i;
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+		c = odict_prev(c, &odict);
+	}
+
+	PCUT_ASSERT_INT_EQUALS(0, i);
+}
+
+/** Increasing sequence insertion and removal test.
+ *
+ * Test sequential insertion of increasing sequence and sequential removal.
+ */
+PCUT_TEST(incr_seq_ins_rem)
+{
+	odict_t odict;
+	test_entry_t *e;
+	odlink_t *c;
+	int i;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = i;
+		odict_insert(&e->odict, &odict, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+	}
+
+	i = 0;
+	c = odict_first(&odict);
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(i, e->key);
+
+		odict_remove(c);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+
+		c = odict_first(&odict);
+		++i;
+	}
+
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+}
+
+/** Generate pseudorandom sequence. */
+static int seq_next(int cur)
+{
+	return (cur * 1951) % 1000000;
+}
+
+/** Test 4.
+ *
+ * Test inserting a pseudorandom sequence and then extracting it again.
+ */
+PCUT_TEST(prseq_ins_extract)
+{
+	odict_t odict;
+	test_entry_t *e, *ep;
+	odlink_t *c, *d;
+	int prev;
+	int i;
+	int v;
+
+	odict_initialize(&odict, test_getkey, test_cmp);
+
+	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
+
+	v = 1;
+	ep = NULL;
+	for (i = 0; i < test_seq_len; i++) {
+		e = calloc(1, sizeof(test_entry_t));
+		PCUT_ASSERT_NOT_NULL(e);
+
+		e->key = v;
+		odict_insert(&e->odict, &odict, &ep->odict);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+		v = seq_next(v);
+		ep = e;
+	}
+
+	/* Verify that entries are in ascending order */
+	c = odict_first(&odict);
+	prev = -1;
+	i = 0;
+	while (c != NULL) {
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_EQUALS(true, e->key > prev);
+
+		prev = e->key;
+		c = odict_next(c, &odict);
+		++i;
+	}
+
+	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
+
+	/* Try extracting the sequence */
+	v = 1;
+	for (i = 0; i < test_seq_len; i++) {
+		c = odict_find_eq(&odict, (void *)&v, NULL);
+		PCUT_ASSERT_NOT_NULL(c);
+
+		e = odict_get_instance(c, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(v, e->key);
+
+		d = odict_find_eq_last(&odict, (void *)&v, NULL);
+		PCUT_ASSERT_NOT_NULL(d);
+
+		e = odict_get_instance(d, test_entry_t, odict);
+		PCUT_ASSERT_INT_EQUALS(v, e->key);
+
+		odict_remove(c);
+		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
+
+		v = seq_next(v);
+	}
+}
+
+PCUT_EXPORT(odict);
Index: uspace/lib/c/test/cap.c
===================================================================
--- uspace/lib/c/test/cap.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/cap.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <cap.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(cap);
+
+PCUT_TEST(cap_format)
+{
+	int block_size = 4;
+	size_t block[] = {
+		0,
+		1,
+		2,
+		10,
+	};
+
+	int input_size = 5;
+	size_t input[] = {
+		0,
+		10,
+		100,
+		1000,
+		1000000,
+		1000000000,
+	};
+
+	const char *out[] = {
+		"0 B",
+		"0 B",
+		"0 B",
+		"0 B",
+
+		"0 B",
+		"10 B",
+		"20 B",
+		"100 B",
+
+		"0 B",
+		"100 B",
+		"200 B",
+		"1.000 kB",
+
+		"0 B",
+		"1.000 kB",
+		"2.000 kB",
+		"10.00 kB",
+
+		"0 B",
+		"1.000 MB",
+		"2.000 MB",
+		"10.00 MB",
+
+		"0 B",
+		"1.000 GB",
+		"2.000 GB",
+		"10.00 GB",
+	};
+
+	cap_spec_t cap;
+	char *str;
+	errno_t rc;
+
+	int x, i;
+	for (i = 0; i < input_size; i++) {
+		for (x = 0; x < block_size; x++) {
+			cap_from_blocks(input[i], block[x], &cap);
+			cap_simplify(&cap);
+
+			rc = cap_format(&cap, &str);
+
+			PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+			PCUT_ASSERT_STR_EQUALS(out[x + (block_size * i)], str);
+			free(str);
+
+			cap_from_blocks(block[x], input[i], &cap);
+			cap_simplify(&cap);
+
+			rc = cap_format(&cap, &str);
+
+			PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+			PCUT_ASSERT_STR_EQUALS(out[x + (block_size * i)], str);
+			free(str);
+		}
+	}
+}
+
+PCUT_TEST(cap_format_rounding)
+{
+	int input_size = 8;
+	uint64_t input[] = {
+		555,
+		5555,
+		55555,
+		555555555,
+		5555555555,
+		555999999,
+		5999999,
+		999999
+	};
+
+	const char *out[] = {
+		"555 B",
+		"5.555 kB",
+		"55.56 kB",
+		"555.6 MB",
+		"5.556 GB",
+		"556.0 MB",
+		"6.000 MB",
+		"1.000 MB",
+	};
+
+	cap_spec_t cap;
+	char *str;
+	errno_t rc;
+
+	int i;
+	for (i = 0; i < input_size; i++) {
+		cap_from_blocks(input[i], 1, &cap);
+		cap_simplify(&cap);
+
+		rc = cap_format(&cap, &str);
+
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_STR_EQUALS(out[i], str);
+		free(str);
+
+		cap_from_blocks(1, input[i], &cap);
+		cap_simplify(&cap);
+
+		rc = cap_format(&cap, &str);
+
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_STR_EQUALS(out[i], str);
+		free(str);
+	}
+}
+
+PCUT_TEST(cap_parse)
+{
+	int input_size = 4;
+	const char *input[] = {
+		"0 B",
+		"100 B",
+		"1 kB",
+		"1.555 kB",
+	};
+
+	int out_cunit[] = {
+		cu_byte,
+		cu_byte,
+		cu_kbyte,
+		cu_kbyte,
+	};
+
+	int out_dp[] = {
+		0,
+		0,
+		0,
+		3,
+	};
+
+	int out_m[] = {
+		0,
+		100,
+		1,
+		1555,
+	};
+
+	cap_spec_t cap;
+	errno_t rc;
+	int i;
+
+	for (i = 0; i < input_size; i++) {
+		rc = cap_parse(input[i], &cap);
+
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_cunit[i], cap.cunit);
+		PCUT_ASSERT_INT_EQUALS(out_dp[i], cap.dp);
+		PCUT_ASSERT_INT_EQUALS(out_m[i], cap.m);
+	}
+}
+
+PCUT_TEST(cap_to_blocks)
+{
+	int input_size = 0;
+	int input_m[] = {
+		0,
+		1,
+		1000,
+		5555,
+		7777,
+	};
+
+	int input_dp[] = {
+		0,
+		0,
+		3,
+		3,
+		2,
+	};
+
+	int block[] = {
+		1,
+		1,
+		1,
+		2,
+		3,
+	};
+
+	int out_nom[] = {
+		0,
+		1000,
+		1000,
+		2778,
+		25923,
+	};
+
+	int out_min[] = {
+		0,
+		1000,
+		1000,
+		2777,
+		25923,
+	};
+
+	int out_max[] = {
+		0,
+		1000,
+		1000,
+		2778,
+		25924,
+	};
+
+	cap_spec_t cap;
+	errno_t rc;
+	int i;
+	uint64_t ret;
+
+	for (i = 0; i < input_size; i++) {
+		cap.m = input_m[i];
+		cap.dp = input_dp[i];
+		cap.cunit = cu_kbyte;
+
+		rc = cap_to_blocks(&cap, cv_nom, block[i], &ret);
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_nom[i], ret);
+
+		rc = cap_to_blocks(&cap, cv_min, block[i], &ret);
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_min[i], ret);
+
+		rc = cap_to_blocks(&cap, cv_max, block[i], &ret);
+		PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+		PCUT_ASSERT_INT_EQUALS(out_max[i], ret);
+	}
+}
+
+PCUT_EXPORT(cap);
Index: uspace/lib/c/test/casting.c
===================================================================
--- uspace/lib/c/test/casting.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/casting.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2019 Vojtech Horky
+ * 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 <pcut/pcut.h>
+#include <limits.h>
+#include <types/casting.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(casting);
+
+/*
+ * Following tests checks functionality of can_cast_size_t_to_int.
+ */
+
+PCUT_TEST(size_t_to_int_with_small)
+{
+	PCUT_ASSERT_TRUE(can_cast_size_t_to_int(0));
+	PCUT_ASSERT_TRUE(can_cast_size_t_to_int(128));
+}
+
+PCUT_TEST(size_t_to_int_with_biggest_int)
+{
+	PCUT_ASSERT_TRUE(can_cast_size_t_to_int(INT_MAX));
+}
+
+PCUT_TEST(size_t_to_int_with_biggest_size_t)
+{
+	PCUT_ASSERT_FALSE(can_cast_size_t_to_int(SIZE_MAX));
+}
+
+PCUT_EXPORT(casting);
Index: uspace/lib/c/test/double_to_str.c
===================================================================
--- uspace/lib/c/test/double_to_str.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/double_to_str.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <ieee_double.h>
+#include <double_to_str.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(double_to_str);
+
+PCUT_TEST(double_to_short_str_pos_zero)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(0.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("0", buf);
+}
+
+PCUT_TEST(double_to_short_str_neg_zero)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(-0.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("0", buf);
+}
+
+PCUT_TEST(double_to_short_str_pos_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_TEST(double_to_short_str_neg_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(-1.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_TEST(double_to_short_str_small)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.1);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(2, ret);
+	PCUT_ASSERT_INT_EQUALS(-1, dec);
+	PCUT_ASSERT_STR_EQUALS("11", buf);
+}
+
+PCUT_TEST(double_to_short_str_large)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1234.56789);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(9, ret);
+	PCUT_ASSERT_INT_EQUALS(-5, dec);
+	PCUT_ASSERT_STR_EQUALS("123456789", buf);
+}
+
+PCUT_TEST(double_to_short_str_mill)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1000000.0);
+	int ret = double_to_short_str(d, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(6, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_zero)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(0.0);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("0", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_pos_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.0);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(4, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1000", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_neg_one)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(-1.0);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(4, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1000", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_small)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.1);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(4, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1100", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_large)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1234.56789);
+	int ret = double_to_fixed_str(d, -1, 3, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(7, ret);
+	PCUT_ASSERT_INT_EQUALS(-3, dec);
+	PCUT_ASSERT_STR_EQUALS("1234567", buf);
+}
+
+PCUT_TEST(double_to_fixed_str_nodecimals)
+{
+	size_t size = 255;
+	char buf[size];
+	int dec;
+	ieee_double_t d = extract_ieee_double(1.999);
+	int ret = double_to_fixed_str(d, -1, 0, buf, size, &dec);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(0, dec);
+	PCUT_ASSERT_STR_EQUALS("1", buf);
+}
+
+PCUT_EXPORT(double_to_str);
Index: uspace/lib/c/test/getopt.c
===================================================================
--- uspace/lib/c/test/getopt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/getopt.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,569 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <getopt.h>
+#include <stdio.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(getopt);
+
+PCUT_TEST(getopt_param_flag)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"-p",
+		"param",
+	};
+
+	const char *options = "fp:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_concat_flags)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-fda",
+	};
+
+	const char *options = "afd";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(1, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('d', ret);
+	PCUT_ASSERT_INT_EQUALS(1, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('a', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_concat_flag_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"-fp",
+		"param"
+	};
+
+	const char *options = "fp:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(1, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_missing_param1)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-p",
+	};
+
+	const char *options = "p:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_missing_param2)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-p",
+	};
+
+	const char *options = ":p:";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS(':', ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_illegal_option)
+{
+	int argc = 2;
+	const char *argv[] = {
+		"get_opt_test",
+		"-p",
+	};
+
+	const char *options = "a";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+
+	options = ":a";
+	optreset = 1;
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+	PCUT_ASSERT_INT_EQUALS('p', optopt);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_flag_with_param)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"param",
+		"-d"
+	};
+
+	const char *options = "fd";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	/* getopt() would print a error message but thx to opterror=0 it doesnt */
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('d', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_case_sensitive)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"-F",
+		"-f"
+	};
+
+	const char *options = "fF";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('F', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_optional_param)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"-p",
+		"param"
+	};
+
+	const char *options = "f::p::";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_NULL(optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_special_option)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"--",
+		"-p"
+	};
+
+	const char *options = "fp";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_gnu_plus)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"break",
+		"-p"
+	};
+
+	const char *options = "+fp";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_gnu_minus)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"-f",
+		"break",
+		"-p"
+	};
+
+	const char *options = "-fp";
+
+	int ret;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS(1, ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_STR_EQUALS("break", optarg);
+
+	ret = getopt(argc, (char *const *)argv, options);
+
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+
+	ret = getopt(argc, (char *const *)argv, options);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_flag_param)
+{
+	int argc = 4;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag",
+		"--parameter",
+		"param"
+	};
+
+	const char *options = "fp:";
+
+	const struct option long_options[] = {
+		{ "flag", no_argument, NULL, 'f' },
+		{ "parameter", required_argument, NULL, 'p' },
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(4, optind);
+	PCUT_ASSERT_INT_EQUALS(1, idx);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_alt_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag=\"param param\"",
+		"--parameter=param",
+	};
+
+	const char *options = "f:p:";
+
+	const struct option long_options[] = {
+		{ "flag", required_argument, NULL, 'f' },
+		{ "parameter", required_argument, NULL, 'p' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_STR_EQUALS("\"param param\"", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_INT_EQUALS(1, idx);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_optional_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag=param",
+		"--parameter",
+	};
+
+	const char *options = "f::p::";
+
+	const struct option long_options[] = {
+		{ "flag", optional_argument, NULL, 'f' },
+		{ "parameter", optional_argument, NULL, 'p' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('f', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_STR_EQUALS("param", optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('p', ret);
+	PCUT_ASSERT_INT_EQUALS(3, optind);
+	PCUT_ASSERT_INT_EQUALS(1, idx);
+	PCUT_ASSERT_NULL(optarg);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_illegal_option)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--param",
+		"param",
+	};
+
+	const char *options = "f::";
+
+	const struct option long_options[] = {
+		{ "cflag", required_argument, NULL, 'c' },
+		{ "flag", required_argument, NULL, 'f' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_INT_EQUALS(0, optopt);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_TEST(getopt_long_ambiguous_param)
+{
+	int argc = 3;
+	const char *argv[] = {
+		"get_opt_test",
+		"--flag",
+		"param",
+	};
+
+	const char *options = "f::";
+
+	const struct option long_options[] = {
+		{ "flag1", optional_argument, NULL, 'f' },
+		{ "flag2", required_argument, NULL, 'f' },
+		{ 0, 0, 0, 0 }
+	};
+
+	int ret;
+	int idx;
+	optreset = 1;
+	opterr = 0;
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS('?', ret);
+	PCUT_ASSERT_INT_EQUALS(2, optind);
+	PCUT_ASSERT_INT_EQUALS(0, idx);
+	PCUT_ASSERT_INT_EQUALS(0, optopt);
+
+	ret = getopt_long(argc, (char *const *)argv, options, long_options, &idx);
+	PCUT_ASSERT_INT_EQUALS(-1, ret);
+}
+
+PCUT_EXPORT(getopt);
Index: uspace/lib/c/test/gsort.c
===================================================================
--- uspace/lib/c/test/gsort.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/gsort.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <gsort.h>
+
+static int cmp_func(void *a, void *b, void *param)
+{
+	int ia = *(int *)a;
+	int ib = *(int *)b;
+
+	if (ia == ib)
+		return 0;
+
+	return ia < ib ? -1 : 1;
+}
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(gsort);
+
+/* sort ascending */
+PCUT_TEST(gsort_asc)
+{
+	int size = 10;
+	int data[size];
+
+	for (int i = 0; i < size; i++) {
+		data[i] = i;
+	}
+
+	bool ret = gsort(data, size, sizeof(int), cmp_func, NULL);
+	PCUT_ASSERT_TRUE(ret);
+
+	for (int i = 0; i < size; i++) {
+		PCUT_ASSERT_INT_EQUALS(i, data[i]);
+	}
+}
+
+/* sort ascending including double entries of the same number */
+PCUT_TEST(gsort_asc_complex)
+{
+	int size = 10;
+	int data[size];
+
+	for (int i = 0; i < size; i++) {
+		data[i] = (i * 13) % 9;
+	}
+
+	data[0] = 2;
+	data[1] = 0;
+	data[2] = 4;
+	data[3] = 1;
+
+	bool ret = gsort(data, size, sizeof(int), cmp_func, NULL);
+	PCUT_ASSERT_TRUE(ret);
+
+	int prev = data[0];
+	for (int i = 1; i < size; i++) {
+		PCUT_ASSERT_TRUE(prev <= data[i]);
+		prev = data[i];
+	}
+}
+
+/* sort descanding */
+PCUT_TEST(gsort_desc)
+{
+	int size = 10;
+	int data[size];
+
+	for (int i = 0; i < size; i++) {
+		data[i] = size - i;
+	}
+
+	bool ret = gsort(&data, size, sizeof(int), cmp_func, NULL);
+	PCUT_ASSERT_TRUE(ret);
+
+	for (int i = 0; i < size; i++) {
+		PCUT_ASSERT_INT_EQUALS(i + 1, data[i]);
+	}
+}
+
+PCUT_EXPORT(gsort);
Index: uspace/lib/c/test/ieee_double.c
===================================================================
--- uspace/lib/c/test/ieee_double.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/ieee_double.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <ieee_double.h>
+
+union {
+	uint64_t integer;
+	double floating;
+} ieee_double_bits;
+
+const int EXP_BIAS = 1023;
+const int EXP_BIAS_UNDERFLOWED = 1075;
+const int SIGN_SHIFT = 52;
+const uint64_t HIDDEN_BIT = 1ULL << SIGN_SHIFT;
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(ieee_double);
+
+PCUT_TEST(extract_ieee_sizeof_double)
+{
+	PCUT_ASSERT_INT_EQUALS(8, sizeof(double));
+}
+
+PCUT_TEST(extract_ieee_double_pos_infinity)
+{
+	ieee_double_bits.integer = 0x7FF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_TRUE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_TRUE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_neg_infinity)
+{
+	ieee_double_bits.integer = 0xFFF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_TRUE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_TRUE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_nan)
+{
+	ieee_double_bits.integer = 0xFFFFFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_TRUE(d.is_special);
+	PCUT_ASSERT_TRUE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_pos_zero)
+{
+	ieee_double_bits.integer = 0x0000000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+}
+
+PCUT_TEST(extract_ieee_double_neg_zero)
+{
+	ieee_double_bits.integer = 0x8000000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0, d.pos_val.significand);
+}
+
+PCUT_TEST(extract_ieee_double_normal_pos_one)
+{
+	ieee_double_bits.integer = 0x3FF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_TRUE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(EXP_BIAS - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_neg_one)
+{
+	ieee_double_bits.integer = 0xBFF0000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_TRUE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(EXP_BIAS - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_pos_smallest)
+{
+	ieee_double_bits.integer = 0x0000000000000001ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(1, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_neg_smallest)
+{
+	ieee_double_bits.integer = 0x8000000000000001ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(1, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_pos_largest)
+{
+	ieee_double_bits.integer = 0x000FFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_denormal_neg_largest)
+{
+	ieee_double_bits.integer = 0x800FFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_TRUE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_pos_smallest)
+{
+	ieee_double_bits.integer = 0x0010000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_neg_smallest)
+{
+	ieee_double_bits.integer = 0x8010000000000000ULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(1 - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_pos_largest)
+{
+	ieee_double_bits.integer = 0x7FEFFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_FALSE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL + HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0x7FEULL - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_TEST(extract_ieee_double_normal_neg_largest)
+{
+	ieee_double_bits.integer = 0xFFEFFFFFFFFFFFFFULL;
+	ieee_double_t d = extract_ieee_double(ieee_double_bits.floating);
+
+	PCUT_ASSERT_FALSE(d.is_special);
+	PCUT_ASSERT_FALSE(d.is_nan);
+	PCUT_ASSERT_FALSE(d.is_infinity);
+	PCUT_ASSERT_TRUE(d.is_negative);
+	PCUT_ASSERT_FALSE(d.is_denormal);
+	PCUT_ASSERT_FALSE(d.is_accuracy_step);
+
+	PCUT_ASSERT_INT_EQUALS(0xFFFFFFFFFFFFFULL + HIDDEN_BIT, d.pos_val.significand);
+	PCUT_ASSERT_INT_EQUALS(0x7FEULL - EXP_BIAS_UNDERFLOWED, d.pos_val.exponent);
+}
+
+PCUT_EXPORT(ieee_double);
Index: uspace/lib/c/test/imath.c
===================================================================
--- uspace/lib/c/test/imath.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/imath.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <imath.h>
+
+static uint64_t MAX_NUM = 10000000000000000000U;
+static unsigned MAX_EXP = 19;
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(imath);
+
+PCUT_TEST(ipow10_u64_zero)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(0, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_INT_EQUALS(1, result);
+}
+
+PCUT_TEST(ipow10_u64_one)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(1, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_INT_EQUALS(10, result);
+}
+
+PCUT_TEST(ipow10_u64_max)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(MAX_EXP, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_INT_EQUALS(MAX_NUM, result);
+}
+
+PCUT_TEST(ipow10_u64_too_large)
+{
+	errno_t ret;
+	uint64_t result;
+	ret = ipow10_u64(MAX_EXP + 1, &result);
+
+	PCUT_ASSERT_ERRNO_VAL(ERANGE, ret);
+}
+
+PCUT_TEST(ilog10_u64_zero)
+{
+	unsigned ret = ilog10_u64(0);
+	PCUT_ASSERT_INT_EQUALS(0, ret);
+}
+
+PCUT_TEST(ilog10_u64_one)
+{
+	unsigned ret = ilog10_u64(1);
+	PCUT_ASSERT_INT_EQUALS(0, ret);
+}
+
+PCUT_TEST(ilog10_u64_max)
+{
+	unsigned ret = ilog10_u64(MAX_NUM);
+	PCUT_ASSERT_INT_EQUALS(MAX_EXP, ret);
+}
+
+PCUT_EXPORT(imath);
Index: uspace/lib/c/test/main.c
===================================================================
--- uspace/lib/c/test/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/test/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -32,9 +32,17 @@
 PCUT_INIT;
 
+PCUT_IMPORT(cap);
+PCUT_IMPORT(casting);
 PCUT_IMPORT(circ_buf);
+PCUT_IMPORT(double_to_str);
 PCUT_IMPORT(fibril_timer);
+PCUT_IMPORT(getopt);
+PCUT_IMPORT(gsort);
+PCUT_IMPORT(ieee_double);
+PCUT_IMPORT(imath);
 PCUT_IMPORT(inttypes);
 PCUT_IMPORT(mem);
 PCUT_IMPORT(odict);
+PCUT_IMPORT(perf);
 PCUT_IMPORT(perm);
 PCUT_IMPORT(qsort);
@@ -45,5 +53,7 @@
 PCUT_IMPORT(str);
 PCUT_IMPORT(string);
+PCUT_IMPORT(strtol);
 PCUT_IMPORT(table);
+PCUT_IMPORT(uuid);
 
 PCUT_MAIN();
Index: uspace/lib/c/test/odict.c
===================================================================
--- uspace/lib/c/test/odict.c	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,278 +1,0 @@
-/*
- * Copyright (c) 2016 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 <adt/odict.h>
-#include <pcut/pcut.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/** Test entry */
-typedef struct {
-	odlink_t odict;
-	int key;
-} test_entry_t;
-
-enum {
-	/** Length of test number sequences */
-	test_seq_len = 100
-};
-
-/** Test get key function.
- *
- * @param odlink Ordered dictionary link
- * @return Pointer to key
- */
-static void *test_getkey(odlink_t *odlink)
-{
-	return &odict_get_instance(odlink, test_entry_t, odict)->key;
-}
-
-/** Test compare function.
- *
- * @param a First key
- * @param b Second key
- * @return <0, 0, >0 if @a a is less than, equal or greater than @a b
- */
-static int test_cmp(void *a, void *b)
-{
-	int *ia = (int *)a;
-	int *ib = (int *)b;
-
-	return *ia - *ib;
-}
-
-PCUT_INIT;
-
-PCUT_TEST_SUITE(odict);
-
-/** Increasing sequence test.
- *
- * Test initialization, emptiness, insertion of increasing sequence and walking.
- */
-PCUT_TEST(incr_seq)
-{
-	odict_t odict;
-	test_entry_t *e;
-	odlink_t *c;
-	int i;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = i;
-		odict_insert(&e->odict, &odict, NULL);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-	}
-
-	i = 0;
-	c = odict_first(&odict);
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_next(c, &odict);
-		++i;
-	}
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-
-	i = test_seq_len;
-	c = odict_last(&odict);
-	while (c != NULL) {
-		--i;
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_prev(c, &odict);
-	}
-
-	PCUT_ASSERT_INT_EQUALS(0, i);
-}
-
-/** Decreasing sequence test.
- *
- * Test initialization, emptiness, insertion of decreasing sequence and walking.
- */
-PCUT_TEST(decr_seq)
-{
-	odict_t odict;
-	test_entry_t *e;
-	odlink_t *c;
-	int i;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = test_seq_len - i - 1;
-		odict_insert(&e->odict, &odict, NULL);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-	}
-
-	i = 0;
-	c = odict_first(&odict);
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_next(c, &odict);
-		++i;
-	}
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-
-	i = test_seq_len;
-	c = odict_last(&odict);
-	while (c != NULL) {
-		--i;
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-		c = odict_prev(c, &odict);
-	}
-
-	PCUT_ASSERT_INT_EQUALS(0, i);
-}
-
-/** Increasing sequence insertion and removal test.
- *
- * Test sequential insertion of increasing sequence and sequential removal.
- */
-PCUT_TEST(incr_seq_ins_rem)
-{
-	odict_t odict;
-	test_entry_t *e;
-	odlink_t *c;
-	int i;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = i;
-		odict_insert(&e->odict, &odict, NULL);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-	}
-
-	i = 0;
-	c = odict_first(&odict);
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(i, e->key);
-
-		odict_remove(c);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-
-		c = odict_first(&odict);
-		++i;
-	}
-
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-}
-
-/** Generate pseudorandom sequence. */
-static int seq_next(int cur)
-{
-	return (cur * 1951) % 1000000;
-}
-
-/** Test 4.
- *
- * Test inserting a pseudorandom sequence and then extracting it again.
- */
-PCUT_TEST(prseq_ins_extract)
-{
-	odict_t odict;
-	test_entry_t *e, *ep;
-	odlink_t *c, *d;
-	int prev;
-	int i;
-	int v;
-
-	odict_initialize(&odict, test_getkey, test_cmp);
-
-	PCUT_ASSERT_EQUALS(true, odict_empty(&odict));
-
-	v = 1;
-	ep = NULL;
-	for (i = 0; i < test_seq_len; i++) {
-		e = calloc(1, sizeof(test_entry_t));
-		PCUT_ASSERT_NOT_NULL(e);
-
-		e->key = v;
-		odict_insert(&e->odict, &odict, &ep->odict);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-		v = seq_next(v);
-		ep = e;
-	}
-
-	/* Verify that entries are in ascending order */
-	c = odict_first(&odict);
-	prev = -1;
-	i = 0;
-	while (c != NULL) {
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_EQUALS(true, e->key > prev);
-
-		prev = e->key;
-		c = odict_next(c, &odict);
-		++i;
-	}
-
-	PCUT_ASSERT_INT_EQUALS(test_seq_len, i);
-
-	/* Try extracting the sequence */
-	v = 1;
-	for (i = 0; i < test_seq_len; i++) {
-		c = odict_find_eq(&odict, (void *)&v, NULL);
-		PCUT_ASSERT_NOT_NULL(c);
-
-		e = odict_get_instance(c, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(v, e->key);
-
-		d = odict_find_eq_last(&odict, (void *)&v, NULL);
-		PCUT_ASSERT_NOT_NULL(d);
-
-		e = odict_get_instance(d, test_entry_t, odict);
-		PCUT_ASSERT_INT_EQUALS(v, e->key);
-
-		odict_remove(c);
-		PCUT_ASSERT_ERRNO_VAL(EOK, odict_validate(&odict));
-
-		v = seq_next(v);
-	}
-}
-
-PCUT_EXPORT(odict);
Index: uspace/lib/c/test/perf.c
===================================================================
--- uspace/lib/c/test/perf.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/perf.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018 Vojtech Horky
+ * 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 <pcut/pcut.h>
+#include <fibril.h>
+#include <perf.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(perf);
+
+/* Checks that initialization zeroes out all entries. */
+PCUT_TEST(zero_diff)
+{
+	stopwatch_t sw;
+	stopwatch_init(&sw);
+	PCUT_ASSERT_INT_EQUALS(0, (int) stopwatch_get_nanos(&sw));
+}
+
+/* Checks that initialization zeroes out all entries. */
+PCUT_TEST(zero_diff_static)
+{
+	stopwatch_t sw = STOPWATCH_INITIALIZE_STATIC;
+	PCUT_ASSERT_INT_EQUALS(0, (int) stopwatch_get_nanos(&sw));
+}
+
+/* Checks that measuring 1s sleep does not give completely invalid results. */
+PCUT_TEST(stopwatch_smokes)
+{
+	stopwatch_t sw = STOPWATCH_INITIALIZE_STATIC;
+	stopwatch_start(&sw);
+	fibril_sleep(1);
+	stopwatch_stop(&sw);
+	nsec_t diff_nanos = stopwatch_get_nanos(&sw);
+	PCUT_ASSERT_TRUE(diff_nanos > MSEC2NSEC(500));
+	PCUT_ASSERT_TRUE(diff_nanos < SEC2NSEC(5));
+}
+
+/* Checks that setting time works for small values. */
+PCUT_TEST(stopwatch_emulation_works_small)
+{
+	stopwatch_t sw = STOPWATCH_INITIALIZE_STATIC;
+	stopwatch_set_nanos(&sw, 42);
+	PCUT_ASSERT_INT_EQUALS(42, (int) stopwatch_get_nanos(&sw));
+}
+
+/* Checks that setting time works for big values too. */
+PCUT_TEST(stopwatch_emulation_works_big)
+{
+	stopwatch_t sw = STOPWATCH_INITIALIZE_STATIC;
+	stopwatch_set_nanos(&sw, 4200000000021);
+	PCUT_ASSERT_EQUALS(4200000000021, (long long) stopwatch_get_nanos(&sw));
+}
+
+PCUT_EXPORT(perf);
Index: uspace/lib/c/test/stdlib.c
===================================================================
--- uspace/lib/c/test/stdlib.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/test/stdlib.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -63,31 +63,4 @@
 }
 
-/** atoi function */
-PCUT_TEST(atoi)
-{
-	int i;
-
-	i = atoi(" \t42");
-	PCUT_ASSERT_TRUE(i == 42);
-}
-
-/** atol function */
-PCUT_TEST(atol)
-{
-	long li;
-
-	li = atol(" \t42");
-	PCUT_ASSERT_TRUE(li == 42);
-}
-
-/** atoll function */
-PCUT_TEST(atoll)
-{
-	long long lli;
-
-	lli = atoll(" \t42");
-	PCUT_ASSERT_TRUE(lli == 42);
-}
-
 /** strtold function */
 #include <stdio.h>
@@ -101,95 +74,4 @@
 	printf("ld=%.10lf\n", (double)ld);
 	PCUT_ASSERT_TRUE(ld == 42.0);
-}
-
-/** strtol function */
-PCUT_TEST(strtol)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t42x", &ep, 10);
-	PCUT_ASSERT_TRUE(li == 42);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with auto-detected base 10 */
-PCUT_TEST(strtol_dec_auto)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t42x", &ep, 0);
-	PCUT_ASSERT_TRUE(li == 42);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with octal number */
-PCUT_TEST(strtol_oct)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t052x", &ep, 8);
-	PCUT_ASSERT_TRUE(li == 052);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with octal number with prefix */
-#include <stdio.h>
-PCUT_TEST(strtol_oct_prefix)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t052x", &ep, 0);
-	printf("li=%ld (0%lo)\n", li, li);
-	PCUT_ASSERT_TRUE(li == 052);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with hex number */
-PCUT_TEST(strtol_hex)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t2ax", &ep, 16);
-	PCUT_ASSERT_TRUE(li == 0x2a);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with hex number with hex prefix */
-PCUT_TEST(strtol_hex_prefixed)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t0x2ax", &ep, 0);
-	PCUT_ASSERT_TRUE(li == 0x2a);
-	PCUT_ASSERT_TRUE(*ep == 'x');
-}
-
-/** strtol function with base 16 and number with 0x prefix */
-PCUT_TEST(strtol_base16_prefix)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \t0x1y", &ep, 16);
-	printf("li=%ld\n", li);
-	PCUT_ASSERT_TRUE(li == 1);
-	PCUT_ASSERT_TRUE(*ep == 'y');
-}
-
-/** strtol function with base 36 number */
-PCUT_TEST(strtol_base36)
-{
-	long li;
-	char *ep;
-
-	li = strtol(" \tz1.", &ep, 36);
-	PCUT_ASSERT_TRUE(li == 35 * 36 + 1);
-	PCUT_ASSERT_TRUE(*ep == '.');
 }
 
Index: uspace/lib/c/test/string.c
===================================================================
--- uspace/lib/c/test/string.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/c/test/string.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -722,3 +722,113 @@
 }
 
+/** strlen function with empty string and non-zero limit */
+PCUT_TEST(strnlen_empty_short)
+{
+	PCUT_ASSERT_INT_EQUALS(0, strnlen("", 1));
+}
+
+/** strlen function with empty string and zero limit */
+PCUT_TEST(strnlen_empty_eq)
+{
+	PCUT_ASSERT_INT_EQUALS(0, strnlen("", 0));
+}
+
+/** strlen function with non empty string below limit */
+PCUT_TEST(strnlen_nonempty_short)
+{
+	PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 5));
+}
+
+/** strlen function with non empty string just below limit */
+PCUT_TEST(strnlen_nonempty_just_short)
+{
+	PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 4));
+}
+
+/** strlen function with non empty string of length equal to limit */
+PCUT_TEST(strnlen_nonempty_eq)
+{
+	PCUT_ASSERT_INT_EQUALS(3, strnlen("abc", 3));
+}
+
+/** strlen function with non empty string of length above limit */
+PCUT_TEST(strnlen_nonempty_long)
+{
+	PCUT_ASSERT_INT_EQUALS(2, strnlen("abc", 2));
+}
+
+/** strdup function with empty string */
+PCUT_TEST(strdup_empty)
+{
+	char *d = strdup("");
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == '\0');
+	free(d);
+}
+
+/** strdup function with non-empty string */
+PCUT_TEST(strdup_nonempty)
+{
+	char *d = strdup("abc");
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == 'a');
+	PCUT_ASSERT_TRUE(d[1] == 'b');
+	PCUT_ASSERT_TRUE(d[2] == 'c');
+	PCUT_ASSERT_TRUE(d[3] == '\0');
+	free(d);
+}
+
+/** strndup function with empty string and non-zero limit */
+PCUT_TEST(strndup_empty_short)
+{
+	char *d = strndup("", 1);
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == '\0');
+	free(d);
+}
+
+/** strndup function with empty string and zero limit */
+PCUT_TEST(strndup_empty_eq)
+{
+	char *d = strndup("", 0);
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == '\0');
+	free(d);
+}
+
+/** strndup function with non-empty string of length below limit */
+PCUT_TEST(strndup_nonempty_short)
+{
+	char *d = strndup("abc", 5);
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == 'a');
+	PCUT_ASSERT_TRUE(d[1] == 'b');
+	PCUT_ASSERT_TRUE(d[2] == 'c');
+	PCUT_ASSERT_TRUE(d[3] == '\0');
+	free(d);
+}
+
+/** strndup function with non-empty string of length equal to limit */
+PCUT_TEST(strndup_nonempty_eq)
+{
+	char *d = strndup("abc", 3);
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == 'a');
+	PCUT_ASSERT_TRUE(d[1] == 'b');
+	PCUT_ASSERT_TRUE(d[2] == 'c');
+	PCUT_ASSERT_TRUE(d[3] == '\0');
+	free(d);
+}
+
+/** strndup function with non-empty string of length above limit */
+PCUT_TEST(strndup_nonempty_long)
+{
+	char *d = strndup("abc", 2);
+	PCUT_ASSERT_NOT_NULL(d);
+	PCUT_ASSERT_TRUE(d[0] == 'a');
+	PCUT_ASSERT_TRUE(d[1] == 'b');
+	PCUT_ASSERT_TRUE(d[2] == '\0');
+	free(d);
+}
+
 PCUT_EXPORT(string);
Index: uspace/lib/c/test/strtol.c
===================================================================
--- uspace/lib/c/test/strtol.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/strtol.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+/** @addtogroup libc
+ * @{
+ */
+/**
+ * @file
+ * @brief Test string to int conversion functions
+ */
+
+#include <pcut/pcut.h>
+#include <stdlib.h>
+#include <str.h>
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(strtol);
+
+/** atoi function */
+PCUT_TEST(atoi)
+{
+	int i;
+
+	i = atoi(" \t42");
+	PCUT_ASSERT_TRUE(i == 42);
+}
+
+/** atol function */
+PCUT_TEST(atol)
+{
+	long li;
+
+	li = atol(" \t42");
+	PCUT_ASSERT_TRUE(li == 42);
+}
+
+/** atoll function */
+PCUT_TEST(atoll)
+{
+	long long lli;
+
+	lli = atoll(" \t42");
+	PCUT_ASSERT_TRUE(lli == 42);
+}
+
+/** strtol function */
+PCUT_TEST(strtol)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t42x", &ep, 10);
+	PCUT_ASSERT_TRUE(li == 42);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with auto-detected base 10 */
+PCUT_TEST(strtol_dec_auto)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t42x", &ep, 0);
+	PCUT_ASSERT_TRUE(li == 42);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with octal number */
+PCUT_TEST(strtol_oct)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t052x", &ep, 8);
+	PCUT_ASSERT_TRUE(li == 052);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with octal number with prefix */
+#include <stdio.h>
+PCUT_TEST(strtol_oct_prefix)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t052x", &ep, 0);
+	printf("li=%ld (0%lo)\n", li, li);
+	PCUT_ASSERT_TRUE(li == 052);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with hex number */
+PCUT_TEST(strtol_hex)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t2ax", &ep, 16);
+	PCUT_ASSERT_TRUE(li == 0x2a);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with hex number with hex prefix */
+PCUT_TEST(strtol_hex_prefixed)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t0x2ax", &ep, 0);
+	PCUT_ASSERT_TRUE(li == 0x2a);
+	PCUT_ASSERT_TRUE(*ep == 'x');
+}
+
+/** strtol function with base 16 and number with 0x prefix */
+PCUT_TEST(strtol_base16_prefix)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \t0x1y", &ep, 16);
+	printf("li=%ld\n", li);
+	PCUT_ASSERT_TRUE(li == 1);
+	PCUT_ASSERT_TRUE(*ep == 'y');
+}
+
+/** strtol function with base 36 number */
+PCUT_TEST(strtol_base36)
+{
+	long li;
+	char *ep;
+
+	li = strtol(" \tz1.", &ep, 36);
+	PCUT_ASSERT_TRUE(li == 35 * 36 + 1);
+	PCUT_ASSERT_TRUE(*ep == '.');
+}
+
+PCUT_TEST(str_uint_hex)
+{
+	int base;
+	bool strict;
+	const char *endp;
+	uint32_t result;
+	errno_t rc;
+	const char *input;
+
+	/*
+	 * str_* conversion function do not admit a prefix when base is
+	 * specified.
+	 */
+
+	rc = str_uint32_t(input = "0x10", &endp, base = 0, strict = false, &result);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_INT_EQUALS(0x10, result);
+	PCUT_ASSERT_PTR_EQUALS(input + 4, endp);
+
+	rc = str_uint32_t(input = "0x10", &endp, base = 16, strict = false, &result);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_INT_EQUALS(0, result);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+
+	rc = str_uint32_t(input = "  \t0x10", &endp, base = 0, strict = false, &result);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_INT_EQUALS(0x10, result);
+	PCUT_ASSERT_PTR_EQUALS(input + 7, endp);
+
+	rc = str_uint32_t(input = "  \t0x10", &endp, base = 16, strict = false, &result);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_INT_EQUALS(0, result);
+	PCUT_ASSERT_PTR_EQUALS(input + 4, endp);
+}
+
+PCUT_TEST(str_uint_overflow)
+{
+	int base;
+	bool strict;
+	uint64_t result;
+	errno_t rc;
+	const char *input;
+
+	/*
+	 * Naive overflow check will not detect this overflow,
+	 * since the intermediate result is equal to the previous step.
+	 */
+
+	rc = str_uint64_t(input = "0xffffffffffffffffffffffffffffffff", NULL, base = 0, strict = false, &result);
+#if 0
+	/* Buggy result. */
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_UINT_EQUALS(0xffffffffffffffff, result);
+#else
+	/* Correct result. */
+	PCUT_ASSERT_INT_EQUALS(EOVERFLOW, rc);
+	PCUT_ASSERT_UINT_EQUALS(UINT64_MAX, result);
+#endif
+
+	/* 3^40 */
+
+	rc = str_uint64_t(input = "1" "0000000000" "0000000000" "0000000000" "0000000000", NULL, base = 3, strict = false, &result);
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	PCUT_ASSERT_UINT_EQUALS(0xa8b8b452291fe821, result);
+
+	/*
+	 * Naive overflow check will not detect this overflow,
+	 * since the intermediate result is greater than the previous step,
+	 * despite overflowing 64 bits.
+	 *
+	 * The input is 3^41 which is greater than 2^64,
+	 * but (3^41 mod 2^64) is still greater than 3^40, so overflow is not
+	 * detected by a naive magnitude check.
+	 */
+
+	rc = str_uint64_t(input = "10" "0000000000" "0000000000" "0000000000" "0000000000", NULL, base = 3, strict = false, &result);
+#if 0
+	/* Buggy result. */
+	PCUT_ASSERT_INT_EQUALS(EOK, rc);
+	/* Correct value is    0x1fa2a1cf67b5fb863 */
+	PCUT_ASSERT_UINT_EQUALS(0xfa2a1cf67b5fb863, result);
+#else
+	/* Correct result. */
+	PCUT_ASSERT_INT_EQUALS(EOVERFLOW, rc);
+	PCUT_ASSERT_UINT_EQUALS(UINT64_MAX, result);
+#endif
+}
+
+PCUT_TEST(strtol_fringe)
+{
+	long output;
+	char *endp;
+	char *endp_unchanged = (char *) "endp_unchanged unique pointer";
+	int errno_unchanged = -1;
+	const char *input;
+	int base;
+
+	/* Variants of plain zero with various bases. */
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = -10);
+	PCUT_ASSERT_INT_EQUALS(EINVAL, errno);
+	PCUT_ASSERT_PTR_EQUALS(endp_unchanged, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 1);
+	PCUT_ASSERT_INT_EQUALS(EINVAL, errno);
+	PCUT_ASSERT_PTR_EQUALS(endp_unchanged, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	for (base = 2; base <= 36; base++) {
+		endp = endp_unchanged;
+		errno = errno_unchanged;
+		output = strtol(input = "0", &endp, base);
+		PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+		PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+		PCUT_ASSERT_INT_EQUALS(0, output);
+
+		endp = endp_unchanged;
+		errno = errno_unchanged;
+		output = strtol(input = "1", &endp, base);
+		PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+		PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+		PCUT_ASSERT_INT_EQUALS(1, output);
+
+		endp = endp_unchanged;
+		errno = errno_unchanged;
+		output = strtol(input = "10", &endp, base);
+		PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+		PCUT_ASSERT_PTR_EQUALS(input + 2, endp);
+		PCUT_ASSERT_INT_EQUALS(base, output);
+
+		endp = endp_unchanged;
+		errno = errno_unchanged;
+		output = strtol(input = "100", &endp, base);
+		PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+		PCUT_ASSERT_PTR_EQUALS(input + 3, endp);
+		PCUT_ASSERT_INT_EQUALS(base * base, output);
+
+		endp = endp_unchanged;
+		errno = errno_unchanged;
+		output = strtol(input = "1000", &endp, base);
+		PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+		PCUT_ASSERT_PTR_EQUALS(input + 4, endp);
+		PCUT_ASSERT_INT_EQUALS(base * base * base, output);
+	}
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 8);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 10);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 16);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 36);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 1, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 37);
+	PCUT_ASSERT_INT_EQUALS(EINVAL, errno);
+	PCUT_ASSERT_PTR_EQUALS(endp_unchanged, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "0", &endp, base = 37);
+	PCUT_ASSERT_INT_EQUALS(EINVAL, errno);
+	PCUT_ASSERT_PTR_EQUALS(endp_unchanged, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	/* No valid number */
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    ", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    ", &endp, base = 10);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    x", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    x0", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    0x", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 5, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    0x1", &endp, base = 0);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 7, endp);
+	PCUT_ASSERT_INT_EQUALS(1, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    0x", &endp, base = 16);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 5, endp);
+	PCUT_ASSERT_INT_EQUALS(0, output);
+
+	endp = endp_unchanged;
+	errno = errno_unchanged;
+	output = strtol(input = "    0x1", &endp, base = 16);
+	PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
+	PCUT_ASSERT_PTR_EQUALS(input + 7, endp);
+	PCUT_ASSERT_INT_EQUALS(1, output);
+}
+
+PCUT_EXPORT(strtol);
Index: uspace/lib/c/test/uuid.c
===================================================================
--- uspace/lib/c/test/uuid.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
+++ uspace/lib/c/test/uuid.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2019 Matthieu Riolo
+ * 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 <pcut/pcut.h>
+#include <uuid.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <str.h>
+#include <ctype.h>
+
+static size_t MAX_SUB_TESTS = 10;
+static size_t uuids_len = 6;
+static const char *uuids[] = {
+	/* uppercase */
+	"F81163AE-299A-4DA2-BED1-0E096C59F3AB",
+	"4A0CE2A3-FD1C-4951-972E-AAA13A703078",
+	"69C7DB62-8309-4C58-831B-8C4E4161E8AC",
+
+	/* lower case*/
+	"c511bf24-70cb-422e-933b-2a74ab699a56",
+	"7b1abd05-456f-4661-ab62-917685069343",
+	"5b00f76b-4a16-4dce-a1fc-b78c60324d89"
+};
+
+static bool uuid_valid(uuid_t uuid)
+{
+	if (!(uuid.b[6] & 0x40)) {
+		return false;
+	}
+
+	int f = (uuid.b[8] & 0x80) || (uuid.b[8] & 0x90);
+	f = f || (uuid.b[8] & 0xA0) || (uuid.b[8] & 0xB0);
+	if (!f) {
+		return false;
+	}
+
+	return true;
+}
+
+PCUT_INIT;
+
+PCUT_TEST_SUITE(uuid);
+
+PCUT_TEST(uuid_generate)
+{
+	uuid_t uuid;
+	size_t i;
+
+	for (i = 0; i < MAX_SUB_TESTS; i++) {
+		errno_t ret = uuid_generate(&uuid);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+	}
+}
+
+PCUT_TEST(uuid_parse)
+{
+	uuid_t uuid;
+	errno_t ret;
+
+	for (size_t i = 0; i < uuids_len; i++) {
+		ret = uuid_parse(uuids[i], &uuid, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+	}
+}
+
+PCUT_TEST(uuid_parse_in_text)
+{
+	uuid_t uuid;
+	errno_t ret;
+	const char *endptr;
+	const char *uuid_in_text = "7b1abd05-456f-4661-ab62-917685069343hello world!";
+
+	ret = uuid_parse(uuid_in_text, &uuid, &endptr);
+
+	PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+	PCUT_ASSERT_TRUE(uuid_valid(uuid));
+	PCUT_ASSERT_STR_EQUALS("hello world!", endptr);
+}
+
+PCUT_TEST(uuid_format_generated)
+{
+	uuid_t uuid;
+	size_t i;
+	char *rstr;
+
+	for (i = 0; i < MAX_SUB_TESTS; i++) {
+		errno_t ret = uuid_generate(&uuid);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+
+		ret = uuid_format(&uuid, &rstr, true);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_INT_EQUALS('\0', rstr[37]);
+		PCUT_ASSERT_INT_EQUALS(36, str_length(rstr));
+		PCUT_ASSERT_INT_EQUALS('4', rstr[14]);
+
+		int f = rstr[19] == '8' || rstr[19] == '9';
+		f = f || toupper(rstr[19]) == 'A' || toupper(rstr[19]) == 'B';
+		PCUT_ASSERT_TRUE(f);
+
+		free(rstr);
+	}
+}
+
+PCUT_TEST(uuid_format_parsed)
+{
+	uuid_t uuid;
+	char *rstr;
+	errno_t ret;
+
+	for (size_t i = 0; i < uuids_len; i++) {
+		ret = uuid_parse(uuids[i], &uuid, NULL);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_TRUE(uuid_valid(uuid));
+
+		ret = uuid_format(&uuid, &rstr, true);
+		PCUT_ASSERT_ERRNO_VAL(EOK, ret);
+		PCUT_ASSERT_INT_EQUALS('\0', rstr[37]);
+		PCUT_ASSERT_INT_EQUALS(36, str_length(rstr));
+		PCUT_ASSERT_INT_EQUALS(0, str_casecmp(uuids[i], rstr));
+
+		free(rstr);
+	}
+}
+
+PCUT_EXPORT(uuid);
Index: uspace/lib/clui/tinput.c
===================================================================
--- uspace/lib/clui/tinput.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/clui/tinput.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -56,4 +56,5 @@
 } seek_dir_t;
 
+static void tinput_update_origin(tinput_t *);
 static void tinput_init(tinput_t *);
 static void tinput_insert_string(tinput_t *, const char *);
@@ -71,6 +72,10 @@
 static void tinput_console_set_lpos(tinput_t *ti, unsigned lpos)
 {
-	console_set_pos(ti->console, LIN_TO_COL(ti, lpos),
-	    LIN_TO_ROW(ti, lpos));
+	unsigned col = LIN_TO_COL(ti, lpos);
+	unsigned row = LIN_TO_ROW(ti, lpos);
+
+	assert(col < ti->con_cols);
+	assert(row < ti->con_rows);
+	console_set_pos(ti->console, col, row);
 }
 
@@ -163,4 +168,5 @@
 static void tinput_position_caret(tinput_t *ti)
 {
+	tinput_update_origin(ti);
 	tinput_console_set_lpos(ti, ti->text_coord + ti->pos);
 }
@@ -232,5 +238,4 @@
 
 	tinput_display_tail(ti, ti->pos - 1, 0);
-	tinput_update_origin(ti);
 	tinput_position_caret(ti);
 }
@@ -276,5 +281,4 @@
 
 	tinput_display_tail(ti, ti->pos - ilen, 0);
-	tinput_update_origin(ti);
 	tinput_position_caret(ti);
 }
Index: uspace/lib/cpp/include/__bits/adt/list.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/adt/list.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/adt/list.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -32,4 +32,5 @@
 #include <__bits/adt/list_node.hpp>
 #include <__bits/insert_iterator.hpp>
+#include <cassert>
 #include <cstdlib>
 #include <iterator>
@@ -580,4 +581,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -585,4 +587,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -1042,4 +1045,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -1053,4 +1057,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -1064,4 +1069,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -1069,4 +1075,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
@@ -1075,4 +1082,5 @@
             {
                 // TODO: implement
+                __unimplemented();
             }
 
Index: uspace/lib/cpp/include/__bits/chrono.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/chrono.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/chrono.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -611,6 +611,6 @@
             static time_point now()
             {
-                hel::timespec ts{};
-                hel::getrealtime(&ts);
+                ::std::timespec ts{};
+                ::helenos::getrealtime(&ts);
 
                 rep time = NSEC2USEC(ts.tv_nsec);
@@ -654,6 +654,6 @@
             static time_point now()
             {
-                hel::timespec ts{};
-                hel::getuptime(&ts);
+                ::std::timespec ts{};
+                ::helenos::getuptime(&ts);
 
                 rep time = NSEC2USEC(ts.tv_nsec);
Index: uspace/lib/cpp/include/__bits/common.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/common.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/*
- * Copyright (c) 2018 Jaroslav Jindrak
- * 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.
- */
-
-#ifndef LIBCPP_BITS_COMMON
-#define LIBCPP_BITS_COMMON
-
-/**
- * According to section 17.2 of the standard,
- * the restrict qualifier shall be omitted.
- */
-#define restrict
-
-#undef NULL
-#define NULL nullptr
-
-#endif
Index: uspace/lib/cpp/include/__bits/complex.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/complex.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/complex.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_COMPLEX
 
+#include <cassert>
 #include <iosfwd>
 #include <sstream>
@@ -724,4 +725,6 @@
     {
         // TODO: implement
+        __unimplemented();
+        return is;
     }
 
@@ -766,4 +769,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -779,4 +783,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -786,4 +791,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -793,4 +799,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return complex<T>{};
     }
@@ -804,4 +811,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -811,4 +819,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -818,4 +827,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -825,4 +835,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -832,4 +843,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -839,4 +851,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -846,4 +859,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -853,4 +867,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -860,4 +875,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -867,4 +883,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -874,4 +891,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -881,4 +899,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return base;
     }
@@ -888,4 +907,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return base;
     }
@@ -895,4 +915,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return complex<T>{base};
     }
@@ -902,4 +923,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -909,4 +931,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -916,4 +939,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -923,4 +947,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
@@ -930,4 +955,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return c;
     }
Index: uspace/lib/cpp/include/__bits/functional/bind.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/functional/bind.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/functional/bind.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -33,4 +33,5 @@
 #include <__bits/functional/invoke.hpp>
 #include <__bits/functional/reference_wrapper.hpp>
+#include <cassert>
 #include <tuple>
 #include <type_traits>
@@ -133,4 +134,5 @@
                 constexpr decltype(auto) operator[](const bind_t<R, B, F, BindArgs...> b)
                 {
+                    __unimplemented();
                     return b; // TODO: bind subexpressions
                 }
Index: uspace/lib/cpp/include/__bits/io/fstream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/fstream.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/io/fstream.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_IO_FSTREAM
 
+#include <cassert>
 #include <cstdio>
 #include <ios>
@@ -267,4 +268,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return nullptr;
             }
@@ -274,4 +276,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return pos_type{};
             }
@@ -281,4 +284,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return pos_type{};
             }
Index: uspace/lib/cpp/include/__bits/io/ios.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/ios.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/io/ios.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -41,5 +41,5 @@
 {
     using streamoff = long long;
-    using streamsize = hel::ssize_t;
+    using streamsize = ::ssize_t;
 
     /**
Index: uspace/lib/cpp/include/__bits/io/istream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/istream.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/io/istream.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_IO_ISTREAM
 
+#include <cassert>
 #include <ios>
 #include <iosfwd>
@@ -339,4 +340,6 @@
             {
                 // TODO: implement
+                __unimplemented();
+                return *this;
             }
 
@@ -344,4 +347,6 @@
             {
                 // TODO: implement
+                __unimplemented();
+                return *this;
             }
 
@@ -349,4 +354,6 @@
             {
                 // TODO: implement
+                __unimplemented();
+                return *this;
             }
 
@@ -354,4 +361,6 @@
             {
                 // TODO: implement
+                __unimplemented();
+                return *this;
             }
 
Index: uspace/lib/cpp/include/__bits/io/ostream.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/io/ostream.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/io/ostream.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_IO_OSTREAM
 
+#include <cassert>
 #include <ios>
 #include <iosfwd>
@@ -458,4 +459,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return pos_type{};
             }
@@ -464,4 +466,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return *this;
             }
@@ -470,4 +473,5 @@
             {
                 // TODO: implement
+                __unimplemented();
                 return *this;
             }
Index: uspace/lib/cpp/include/__bits/limits.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/limits.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/limits.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -528,5 +528,5 @@
             static constexpr unsigned short min()
             {
-                return USHRT_MIN;
+                return 0;
             }
 
@@ -552,5 +552,5 @@
             static constexpr unsigned int min()
             {
-                return UINT_MIN;
+                return 0;
             }
 
@@ -576,5 +576,5 @@
             static constexpr unsigned long min()
             {
-                return ULONG_MIN;
+                return 0;
             }
 
@@ -600,5 +600,5 @@
             static constexpr unsigned long long min()
             {
-                return ULLONG_MIN;
+                return 0;
             }
 
Index: uspace/lib/cpp/include/__bits/locale/num_get.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/locale/num_get.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/locale/num_get.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -301,16 +301,19 @@
                 if (size > 0)
                 {
-                    int ret{};
+                    int olderrno{errno};
+                    errno = EOK;
+                    char *endptr = NULL;
+
                     if constexpr (is_signed<BaseType>::value)
-                        ret = std::hel::str_int64_t(base.buffer_, nullptr, num_base, false, &res);
-                    else
-                        ret = std::hel::str_uint64_t(base.buffer_, nullptr, num_base, false, &res);
-
-                    if (ret != EOK)
-                    {
+                        res = ::strtoll(base.buffer_, &endptr, num_base);
+                    else
+                        res = ::strtoull(base.buffer_, &endptr, num_base);
+
+                    if (errno != EOK || endptr == base.buffer_)
                         err |= ios_base::failbit;
-                        v = 0;
-                    }
-                    else if (res > static_cast<BaseType>(numeric_limits<T>::max()))
+
+                    errno = olderrno;
+
+                    if (res > static_cast<BaseType>(numeric_limits<T>::max()))
                     {
                         err |= ios_base::failbit;
Index: uspace/lib/cpp/include/__bits/new.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/new.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/new.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_NEW
 
+#include <cstddef>
 #include <exception>
 
Index: uspace/lib/cpp/include/__bits/random.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/random.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/random.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1030,10 +1030,10 @@
              *       something better.
              */
-            hel::srand(hel::time(nullptr));
+            ::srand(::time(nullptr));
         }
 
         result_type operator()()
         {
-            return hel::rand();
+            return ::rand();
         }
 
Index: uspace/lib/cpp/include/__bits/string/string.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/string/string.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/string/string.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -32,4 +32,5 @@
 #include <__bits/string/stringfwd.hpp>
 #include <algorithm>
+#include <cassert>
 #include <initializer_list>
 #include <iosfwd>
@@ -81,10 +82,10 @@
         static int compare(const char_type* s1, const char_type* s2, size_t n)
         {
-            return hel::str_lcmp(s1, s2, n);
+            return ::strncmp(s1, s2, n);
         }
 
         static size_t length(const char_type* s)
         {
-            return hel::str_size(s);
+            return ::strlen(s);
         }
 
@@ -178,4 +179,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return 0;
         }
@@ -184,4 +186,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return 0;
         }
@@ -190,4 +193,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -196,4 +200,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -202,4 +207,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -208,4 +214,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -266,4 +273,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return 0;
         }
@@ -272,4 +280,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return 0;
         }
@@ -278,4 +287,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -284,4 +294,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -290,4 +301,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -296,4 +308,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return nullptr;
         }
@@ -353,5 +366,5 @@
         {
             // TODO: This function does not exits...
-            //return hel::wstr_lcmp(s1, s2, n);
+            __unimplemented();
             return 0;
         }
@@ -359,5 +372,8 @@
         static size_t length(const char_type* s)
         {
-            return hel::wstr_size(s);
+            size_t i = 0;
+            while (s[i] != 0)
+                i++;
+            return i;
         }
 
@@ -1939,4 +1955,5 @@
         {
             // TODO: implement
+            __unimplemented();
             return size_t{};
         }
Index: uspace/lib/cpp/include/__bits/thread/condition_variable.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/condition_variable.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/thread/condition_variable.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,9 +35,4 @@
 namespace std
 {
-    extern "C" {
-        #include <fibril.h>
-        #include <fibril_synch.h>
-    }
-
     enum class cv_status
     {
Index: uspace/lib/cpp/include/__bits/thread/future.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/future.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/thread/future.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,4 +30,5 @@
 #define LIBCPP_BITS_THREAD_FUTURE
 
+#include <cassert>
 #include <memory>
 #include <system_error>
@@ -171,4 +172,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -178,4 +180,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 }
Index: uspace/lib/cpp/include/__bits/thread/mutex.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/mutex.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/thread/mutex.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,5 +30,4 @@
 #define LIBCPP_BITS_THREAD_MUTEX
 
-#include <__bits/common.hpp>
 #include <__bits/thread/threading.hpp>
 #include <functional>
Index: uspace/lib/cpp/include/__bits/thread/thread.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/thread.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/thread/thread.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,5 +30,4 @@
 #define LIBCPP_BITS_THREAD
 
-#include <__bits/common.hpp>
 #include <__bits/thread/threading.hpp>
 #include <chrono>
Index: uspace/lib/cpp/include/__bits/thread/threading.hpp
===================================================================
--- uspace/lib/cpp/include/__bits/thread/threading.hpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/__bits/thread/threading.hpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,14 +30,8 @@
 #define LIBCPP_BITS_THREAD_THREADING
 
-namespace std::hel
-{
-    extern "C" {
-        #include <async.h>
-        #include <fibril.h>
-        #include <fibril_synch.h>
-    }
-}
-
 #include <chrono>
+
+#include <fibril.h>
+#include <fibril_synch.h>
 
 namespace std::aux
@@ -55,9 +49,9 @@
     struct threading_policy<fibril_tag>
     {
-        using mutex_type        = hel::fibril_mutex_t;
-        using thread_type       = hel::fid_t;
-        using condvar_type      = hel::fibril_condvar_t;
-        using time_unit         = hel::usec_t;
-        using shared_mutex_type = hel::fibril_rwlock_t;
+        using mutex_type        = ::helenos::fibril_mutex_t;
+        using thread_type       = ::helenos::fid_t;
+        using condvar_type      = ::helenos::fibril_condvar_t;
+        using time_unit         = ::helenos::usec_t;
+        using shared_mutex_type = ::helenos::fibril_rwlock_t;
 
         struct thread
@@ -66,20 +60,20 @@
             static thread_type create(Callable clbl, Payload& pld)
             {
-                return hel::fibril_create(clbl, (void*)&pld);
+                return ::helenos::fibril_create(clbl, (void*)&pld);
             }
 
             static void start(thread_type thr)
             {
-                hel::fibril_add_ready(thr);
+                ::helenos::fibril_add_ready(thr);
             }
 
             static thread_type this_thread()
             {
-                return hel::fibril_get_id();
+                return ::helenos::fibril_get_id();
             }
 
             static void yield()
             {
-                hel::fibril_yield();
+                ::helenos::fibril_yield();
             }
 
@@ -95,20 +89,20 @@
             static void init(mutex_type& mtx)
             {
-                hel::fibril_mutex_initialize(&mtx);
+                ::helenos::fibril_mutex_initialize(&mtx);
             }
 
             static void lock(mutex_type& mtx)
             {
-                hel::fibril_mutex_lock(&mtx);
+                ::helenos::fibril_mutex_lock(&mtx);
             }
 
             static void unlock(mutex_type& mtx)
             {
-                hel::fibril_mutex_unlock(&mtx);
+                ::helenos::fibril_mutex_unlock(&mtx);
             }
 
             static bool try_lock(mutex_type& mtx)
             {
-                return hel::fibril_mutex_trylock(&mtx);
+                return ::helenos::fibril_mutex_trylock(&mtx);
             }
 
@@ -124,25 +118,25 @@
             static void init(condvar_type& cv)
             {
-                hel::fibril_condvar_initialize(&cv);
+                ::helenos::fibril_condvar_initialize(&cv);
             }
 
             static void wait(condvar_type& cv, mutex_type& mtx)
             {
-                hel::fibril_condvar_wait(&cv, &mtx);
+                ::helenos::fibril_condvar_wait(&cv, &mtx);
             }
 
             static int wait_for(condvar_type& cv, mutex_type& mtx, time_unit timeout)
             {
-                return hel::fibril_condvar_wait_timeout(&cv, &mtx, timeout);
+                return ::helenos::fibril_condvar_wait_timeout(&cv, &mtx, timeout);
             }
 
             static void signal(condvar_type& cv)
             {
-                hel::fibril_condvar_signal(&cv);
+                ::helenos::fibril_condvar_signal(&cv);
             }
 
             static void broadcast(condvar_type& cv)
             {
-                hel::fibril_condvar_broadcast(&cv);
+                ::helenos::fibril_condvar_broadcast(&cv);
             }
         };
@@ -158,5 +152,5 @@
             static void sleep(time_unit time)
             {
-                hel::fibril_usleep(time);
+                ::helenos::fibril_usleep(time);
             }
         };
@@ -166,25 +160,25 @@
             static void init(shared_mutex_type& mtx)
             {
-                hel::fibril_rwlock_initialize(&mtx);
+                ::helenos::fibril_rwlock_initialize(&mtx);
             }
 
             static void lock(shared_mutex_type& mtx)
             {
-                hel::fibril_rwlock_write_lock(&mtx);
+                ::helenos::fibril_rwlock_write_lock(&mtx);
             }
 
             static void unlock(shared_mutex_type& mtx)
             {
-                hel::fibril_rwlock_write_unlock(&mtx);
+                ::helenos::fibril_rwlock_write_unlock(&mtx);
             }
 
             static void lock_shared(shared_mutex_type& mtx)
             {
-                hel::fibril_rwlock_read_lock(&mtx);
+                ::helenos::fibril_rwlock_read_lock(&mtx);
             }
 
             static void unlock_shared(shared_mutex_type& mtx)
             {
-                hel::fibril_rwlock_read_unlock(&mtx);
+                ::helenos::fibril_rwlock_read_unlock(&mtx);
             }
 
Index: uspace/lib/cpp/include/cassert
===================================================================
--- uspace/lib/cpp/include/cassert	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cassert	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -30,30 +30,7 @@
 #define LIBCPP_CASSERT
 
-#include <__bits/common.hpp>
+#include <assert.h>
 
-namespace std::hel
-{
-    extern "C" {
-        #include <assert.h>
-    }
-}
-
-namespace std
-{
-    // Note: The only thing imported is assert
-    //       and that is a macro.
-}
-
-/**
- * We need to fix the assert macro because it uses
- * a non-standard function that we have in the
- * std::hel namespace.
- */
-#undef assert
-#define assert(expr) \
-	do { \
-		if (!(expr)) \
-			std::hel::assert_abort(#expr, __FILE__, __LINE__); \
-	} while (0)
+#define __unimplemented() assert(!"Not implemented!")
 
 #endif
Index: uspace/lib/cpp/include/cctype
===================================================================
--- uspace/lib/cpp/include/cctype	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cctype	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,29 +30,22 @@
 #define LIBCPP_CCTYPE
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <ctype.h>
-    }
-}
+#include <ctype.h>
 
 namespace std
 {
-    using std::hel::isalnum;
-    using std::hel::isalpha;
-    using std::hel::islower;
-    using std::hel::isupper;
-    using std::hel::isdigit;
-    /* using std::hel::isxdigit; */
-    /* using std::hel::iscntrl; */
-    /* using std::hel::isgraph; */
-    using std::hel::isspace;
-    /* using std::hel::isblank; */
-    /* using std::hel::isprint; */
-    /* using std::hel::ispunct; */
-    using std::hel::tolower;
-    using std::hel::toupper;
+    using ::isalnum;
+    using ::isalpha;
+    using ::islower;
+    using ::isupper;
+    using ::isdigit;
+    using ::isxdigit;
+    using ::iscntrl;
+    using ::isgraph;
+    using ::isspace;
+    using ::isblank;
+    using ::isprint;
+    using ::ispunct;
+    using ::tolower;
+    using ::toupper;
 }
 
Index: uspace/lib/cpp/include/cerrno
===================================================================
--- uspace/lib/cpp/include/cerrno	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cerrno	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,17 +30,5 @@
 #define LIBCPP_CERRNO
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <errno.h>
-    }
-}
-
-namespace std
-{
-    // Note: Only macros are imported here.
-}
+#include <errno.h>
 
 #endif
Index: uspace/lib/cpp/include/cinttypes
===================================================================
--- uspace/lib/cpp/include/cinttypes	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cinttypes	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,37 +30,17 @@
 #define LIBCPP_CINTTYPES
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <inttypes.h>
-    }
-}
+#include <cstdint>
+#include <inttypes.h>
 
 namespace std
 {
-    using std::hel::imaxdiv_t;
-    /* using std::hel::abs; */
-    /* using std::hel::div; */
-    /* using std::hel::imaxabs; */
-    /* using std::hel::imaxdiv; */
-    /* using std::hel::strtoimax; */
-    /* using std::hel::strtoumax; */
-    /* using std::hel::wcstoimax; */
-    /* using std::hel::wcstoumax; */
+    using ::imaxdiv_t;
+    using ::imaxabs;
+    using ::imaxdiv;
+    using ::strtoimax;
+    using ::strtoumax;
+    using ::wcstoimax;
+    using ::wcstoumax;
 }
 
-using std::hel::imaxdiv_t;
-/* using std::hel::abs; */
-/* using std::hel::div; */
-/* using std::hel::imaxabs; */
-/* using std::hel::imaxdiv; */
-/* using std::hel::strtoimax; */
-/* using std::hel::strtoumax; */
-/* using std::hel::wcstoimax; */
-/* using std::hel::wcstoumax; */
-
-#include <cstdint>
-
 #endif
Index: uspace/lib/cpp/include/climits
===================================================================
--- uspace/lib/cpp/include/climits	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/climits	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,17 +30,5 @@
 #define LIBCPP_CLIMITS
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <limits.h>
-    }
-}
-
-namespace std
-{
-    // Note: Only macros imported here.
-}
+#include <limits.h>
 
 #endif
Index: uspace/lib/cpp/include/csetjmp
===================================================================
--- uspace/lib/cpp/include/csetjmp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/csetjmp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,26 +30,11 @@
 #define LIBCPP_CSETJMP
 
-#include <__bits/common.hpp>
-
-/**
- * TODO: Currently the <setjmp.h> header uses
- *       _Noreturn, which is not available in C++.
- */
-
-namespace std::hel
-{
-    extern "C" {
-        //#include <setjmp.h>
-    }
-}
+#include <setjmp.h>
 
 namespace std
 {
-    /* using std::hel::jmp_buf; */
-    /* using std::hel::longjmp; */
+    using ::jmp_buf;
+    using ::longjmp;
 }
 
-/* using std::hel::jmp_buf; */
-/* using std::hel::longjmp; */
-
 #endif
Index: uspace/lib/cpp/include/cstdarg
===================================================================
--- uspace/lib/cpp/include/cstdarg	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstdarg	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,19 +30,10 @@
 #define LIBCPP_CSTDARG
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <stdarg.h>
-    }
-}
+#include <stdarg.h>
 
 namespace std
 {
-    using std::hel::va_list;
+    using ::va_list;
 }
 
-using std::hel::va_list;
-
 #endif
Index: uspace/lib/cpp/include/cstddef
===================================================================
--- uspace/lib/cpp/include/cstddef	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstddef	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,27 +30,13 @@
 #define LIBCPP_CSTDDEF
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <stddef.h>
-    }
-}
-
+#include <stddef.h>
 
 namespace std
 {
-    using nullptr_t = decltype(nullptr);
-
-    using std::hel::size_t;
-    using std::hel::ptrdiff_t;
-    /* using std::hel::max_align_t; */
+    using ::nullptr_t;
+    using ::size_t;
+    using ::ptrdiff_t;
+    using ::max_align_t;
 }
 
-using std::nullptr_t;
-using std::hel::size_t;
-using std::hel::ptrdiff_t;
-/* using std::hel::max_align_t; */
-
 #endif
Index: uspace/lib/cpp/include/cstdint
===================================================================
--- uspace/lib/cpp/include/cstdint	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstdint	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,87 +30,44 @@
 #define LIBCPP_CSTDINT
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <stdint.h>
-    }
-}
+#include <stdint.h>
 
 namespace std
 {
-    using int8_t  = std::hel::int8_t;
-    using int16_t = std::hel::int16_t;
-    using int32_t = std::hel::int32_t;
-    using int64_t = std::hel::int64_t;
+    using ::int8_t;
+    using ::int16_t;
+    using ::int32_t;
+    using ::int64_t;
 
-    using intmax_t = std::hel::intmax_t;
-    using intptr_t = std::hel::intptr_t;
+    using ::intmax_t;
+    using ::intptr_t;
 
-    using int_fast8_t  = std::hel::int8_t;
-    using int_fast16_t = std::hel::int16_t;
-    using int_fast32_t = std::hel::int32_t;
-    using int_fast64_t = std::hel::int64_t;
+    using ::int_fast8_t;
+    using ::int_fast16_t;
+    using ::int_fast32_t;
+    using ::int_fast64_t;
 
-    using int_least8_t  = std::hel::int8_t;
-    using int_least16_t = std::hel::int16_t;
-    using int_least32_t = std::hel::int32_t;
-    using int_least64_t = std::hel::int64_t;
+    using ::int_least8_t;
+    using ::int_least16_t;
+    using ::int_least32_t;
+    using ::int_least64_t;
 
-    using uint8_t  = std::hel::uint8_t;
-    using uint16_t = std::hel::uint16_t;
-    using uint32_t = std::hel::uint32_t;
-    using uint64_t = std::hel::uint64_t;
+    using ::uint8_t;
+    using ::uint16_t;
+    using ::uint32_t;
+    using ::uint64_t;
 
-    using uintmax_t = std::hel::uintmax_t;
-    using uintptr_t = std::hel::uintptr_t;
+    using ::uintmax_t;
+    using ::uintptr_t;
 
-    using uint_fast8_t  = std::hel::uint8_t;
-    using uint_fast16_t = std::hel::uint16_t;
-    using uint_fast32_t = std::hel::uint32_t;
-    using uint_fast64_t = std::hel::uint64_t;
+    using ::uint_fast8_t;
+    using ::uint_fast16_t;
+    using ::uint_fast32_t;
+    using ::uint_fast64_t;
 
-    using uint_least8_t  = std::hel::uint8_t;
-    using uint_least16_t = std::hel::uint16_t;
-    using uint_least32_t = std::hel::uint32_t;
-    using uint_least64_t = std::hel::uint64_t;
+    using ::uint_least8_t;
+    using ::uint_least16_t;
+    using ::uint_least32_t;
+    using ::uint_least64_t;
 }
 
-using int8_t  = std::hel::int8_t;
-using int16_t = std::hel::int16_t;
-using int32_t = std::hel::int32_t;
-using int64_t = std::hel::int64_t;
-
-using intmax_t = std::hel::intmax_t;
-using intptr_t = std::hel::intptr_t;
-
-using int_fast8_t  = std::hel::int8_t;
-using int_fast16_t = std::hel::int16_t;
-using int_fast32_t = std::hel::int32_t;
-using int_fast64_t = std::hel::int64_t;
-
-using int_least8_t  = std::hel::int8_t;
-using int_least16_t = std::hel::int16_t;
-using int_least32_t = std::hel::int32_t;
-using int_least64_t = std::hel::int64_t;
-
-using uint8_t  = std::hel::uint8_t;
-using uint16_t = std::hel::uint16_t;
-using uint32_t = std::hel::uint32_t;
-using uint64_t = std::hel::uint64_t;
-
-using uintmax_t = std::hel::uintmax_t;
-using uintptr_t = std::hel::uintptr_t;
-
-using uint_fast8_t  = std::hel::uint8_t;
-using uint_fast16_t = std::hel::uint16_t;
-using uint_fast32_t = std::hel::uint32_t;
-using uint_fast64_t = std::hel::uint64_t;
-
-using uint_least8_t  = std::hel::uint8_t;
-using uint_least16_t = std::hel::uint16_t;
-using uint_least32_t = std::hel::uint32_t;
-using uint_least64_t = std::hel::uint64_t;
-
 #endif
Index: uspace/lib/cpp/include/cstdio
===================================================================
--- uspace/lib/cpp/include/cstdio	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstdio	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,116 +30,60 @@
 #define LIBCPP_CSTDIO
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <stdio.h>
-    }
-}
+#include <stdio.h>
 
 namespace std
 {
-    using std::hel::FILE;
-    using std::hel::stdin;
-    using std::hel::stdout;
-    using std::hel::stderr;
-    /* using std::hel::fpos_t */
-    using std::hel::size_t;
+    using ::FILE;
+    using ::stdin;
+    using ::stdout;
+    using ::stderr;
+    using ::fpos_t;
+    using ::size_t;
 
-    using std::hel::clearerr;
-    using std::hel::fclose;
-    using std::hel::feof;
-    using std::hel::ferror;
-    using std::hel::fflush;
-    using std::hel::fgetc;
-    /* using std::hel::fgetpos; */
-    using std::hel::fgets;
-    using std::hel::fopen;
-    using std::hel::fprintf;
-    using std::hel::fputc;
-    using std::hel::fputs;
-    using std::hel::fread;
-    using std::hel::freopen;
-    /* using std::hel::fscanf; */
-    using std::hel::fseek;
-    /* using std::hel::fsetpos; */
-    using std::hel::ftell;
-    using std::hel::fwrite;
-    /* using std::hel::getc; */
-    using std::hel::getchar;
-    /* using std::hel::perror; */
-    using std::hel::printf;
-    /* using std::hel::putc; */
-    using std::hel::putchar;
-    using std::hel::puts;
-    using std::hel::remove;
-    using std::hel::rename;
-    using std::hel::rewind;
-    /* using std::hel::scanf; */
-    using std::hel::setbuf;
-    using std::hel::setvbuf;
-    using std::hel::snprintf;
-    /* using std::hel::sprintf; */
-    /* using std::hel::sscanf; */
-    /* using std::hel::tmpfile; */
-    /* using std::hel::tmpnam; */
-    using std::hel::ungetc;
-    using std::hel::vfprintf;
-    using std::hel::vprintf;
-    /* using std::hel::vscanf; */
-    using std::hel::vsnprintf;
-    /* using std::hel::vsprintf; */
-    /* using std::hel::vsscanf; */
+    using ::clearerr;
+    using ::fclose;
+    using ::feof;
+    using ::ferror;
+    using ::fflush;
+    using ::fgetc;
+    using ::fgetpos;
+    using ::fgets;
+    using ::fopen;
+    using ::fprintf;
+    using ::fputc;
+    using ::fputs;
+    using ::fread;
+    using ::freopen;
+    using ::fscanf;
+    using ::fseek;
+    using ::fsetpos;
+    using ::ftell;
+    using ::fwrite;
+    using ::getc;
+    using ::getchar;
+    using ::perror;
+    using ::printf;
+    using ::putc;
+    using ::putchar;
+    using ::puts;
+    using ::remove;
+    using ::rename;
+    using ::rewind;
+    using ::scanf;
+    using ::setbuf;
+    using ::setvbuf;
+    using ::snprintf;
+    /* using ::sprintf; */
+    /* using ::sscanf; */
+    /* using ::tmpfile; */
+    /* using ::tmpnam; */
+    using ::ungetc;
+    using ::vfprintf;
+    using ::vprintf;
+    /* using ::vscanf; */
+    using ::vsnprintf;
+    /* using ::vsprintf; */
+    /* using ::vsscanf; */
 }
 
-using std::hel::FILE;
-/* using std::hel::fpos_t */
-using std::hel::size_t;
-
-using std::hel::clearerr;
-using std::hel::fclose;
-using std::hel::feof;
-using std::hel::ferror;
-using std::hel::fflush;
-using std::hel::fgetc;
-/* using std::hel::fgetpos; */
-using std::hel::fgets;
-using std::hel::fopen;
-using std::hel::fprintf;
-using std::hel::fputc;
-using std::hel::fputs;
-using std::hel::fread;
-using std::hel::freopen;
-/* using std::hel::fscanf; */
-using std::hel::fseek;
-/* using std::hel::fsetpos; */
-using std::hel::ftell;
-using std::hel::fwrite;
-/* using std::hel::getc; */
-using std::hel::getchar;
-/* using std::hel::perror; */
-using std::hel::printf;
-/* using std::hel::putc; */
-using std::hel::putchar;
-using std::hel::puts;
-using std::hel::remove;
-using std::hel::rename;
-using std::hel::rewind;
-/* using std::hel::scanf; */
-using std::hel::setbuf;
-using std::hel::setvbuf;
-using std::hel::snprintf;
-/* using std::hel::sprintf; */
-/* using std::hel::sscanf; */
-/* using std::hel::tmpfile; */
-/* using std::hel::tmpnam; */
-using std::hel::ungetc;
-using std::hel::vfprintf;
-using std::hel::vprintf;
-/* using std::hel::vscanf; */
-using std::hel::vsnprintf;
-/* using std::hel::vsprintf; */
-/* using std::hel::vsscanf; */
-
 #endif
Index: uspace/lib/cpp/include/cstdlib
===================================================================
--- uspace/lib/cpp/include/cstdlib	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstdlib	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,112 +30,57 @@
 #define LIBCPP_CSTDLIB
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <stdlib.h>
-        #include <_bits/ssize_t.h>
-    }
-}
+#include <stdlib.h>
+#include <_bits/ssize_t.h>
 
 namespace std
 {
-    /* using std::hel::div_t; */
-    /* using std::hel::ldiv_t; */
-    /* using std::hel::lldiv_t; */
-    using std::hel::size_t;
+    /* using ::div_t; */
+    /* using ::ldiv_t; */
+    /* using ::lldiv_t; */
+    using ::size_t;
 
-    using std::hel::abort;
-    using std::hel::exit;
-    /* using std::hel::quick_exit; */
-    /* using std::hel::_Exit; */
-    using std::hel::atexit;
-    /* using std::hel::at_quick_exit; */
-    /* using std::hel::system; */
-    /* using std::hel::getenv; */
+    using ::abort;
+    using ::exit;
+    /* using ::quick_exit; */
+    /* using ::_Exit; */
+    using ::atexit;
+    /* using ::at_quick_exit; */
+    /* using ::system; */
+    /* using ::getenv; */
 
-    using std::hel::malloc;
-    using std::hel::calloc;
-    using std::hel::realloc;
-    using std::hel::free;
+    using ::malloc;
+    using ::calloc;
+    using ::realloc;
+    using ::free;
 
-    /* using std::hel::atof; */
-    /* using std::hel::atoi; */
-    /* using std::hel::atol; */
-    /* using std::hel::atoll; */
-    /* using std::hel::strtol; */
-    /* using std::hel::strtoll; */
-    /* using std::hel::strtoul; */
-    /* using std::hel::strtoull; */
-    /* using std::hel::strtof; */
-    /* using std::hel::strtod; */
-    /* using std::hel::strtold; */
+    /* using ::atof; */
+    /* using ::atoi; */
+    /* using ::atol; */
+    /* using ::atoll; */
+    /* using ::strtol; */
+    /* using ::strtoll; */
+    /* using ::strtoul; */
+    /* using ::strtoull; */
+    /* using ::strtof; */
+    /* using ::strtod; */
+    /* using ::strtold; */
 
-    /* using std::hel::mblen; */
-    /* using std::hel::mbtowc; */
-    /* using std::hel::wctomb; */
-    /* using std::hel::mbstowcs; */
-    /* using std::hel::wcstombs; */
+    /* using ::mblen; */
+    /* using ::mbtowc; */
+    /* using ::wctomb; */
+    /* using ::mbstowcs; */
+    /* using ::wcstombs; */
 
-    using std::hel::rand;
-    using std::hel::srand;
-    using std::hel::qsort;
-    /* using std::hel::bsearch; */
-    /* using std::hel::abs; */
-    /* using std::hel::labs; */
-    /* using std::hel::llabs; */
-    /* using std::hel::div; */
-    /* using std::hel::ldiv; */
-    /* using std::hel::lldiv; */
+    using ::rand;
+    using ::srand;
+    using ::qsort;
+    /* using ::bsearch; */
+    /* using ::abs; */
+    /* using ::labs; */
+    /* using ::llabs; */
+    /* using ::div; */
+    /* using ::ldiv; */
+    /* using ::lldiv; */
 }
 
-/* using std::hel::div_t; */
-/* using std::hel::ldiv_t; */
-/* using std::hel::lldiv_t; */
-using std::hel::size_t;
-
-using std::hel::abort;
-using std::hel::exit;
-/* using std::hel::quick_exit; */
-/* using std::hel::_Exit; */
-using std::hel::atexit;
-/* using std::hel::at_quick_exit; */
-/* using std::hel::system; */
-/* using std::hel::getenv; */
-
-using std::hel::malloc;
-using std::hel::calloc;
-using std::hel::realloc;
-using std::hel::free;
-
-/* using std::hel::atof; */
-/* using std::hel::atoi; */
-/* using std::hel::atol; */
-/* using std::hel::atoll; */
-/* using std::hel::strtol; */
-/* using std::hel::strtoll; */
-/* using std::hel::strtoul; */
-/* using std::hel::strtoull; */
-/* using std::hel::strtof; */
-/* using std::hel::strtod; */
-/* using std::hel::strtold; */
-
-/* using std::hel::mblen; */
-/* using std::hel::mbtowc; */
-/* using std::hel::wctomb; */
-/* using std::hel::mbstowcs; */
-/* using std::hel::wcstombs; */
-
-using std::hel::rand;
-using std::hel::srand;
-using std::hel::qsort;
-/* using std::hel::bsearch; */
-/* using std::hel::abs; */
-/* using std::hel::labs; */
-/* using std::hel::llabs; */
-/* using std::hel::div; */
-/* using std::hel::ldiv; */
-/* using std::hel::lldiv; */
-
 #endif
Index: uspace/lib/cpp/include/cstring
===================================================================
--- uspace/lib/cpp/include/cstring	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cstring	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,71 +30,37 @@
 #define LIBCPP_CSTRING
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <str.h>
-    }
-}
+#define _REALLY_WANT_STRING_H
+#include <string.h>
 
 namespace std
 {
-    using std::hel::size_t;
+    using ::size_t;
 
-    /* using std::hel::strcpy; */
-    /* using std::hel::strncpy; */
-    /* using std::hel::strcat; */
-    /* using std::hel::strncat; */
-    /* using std::hel::strxfrm; */
+    using ::strcpy;
+    using ::strncpy;
+    using ::strcat;
+    using ::strncat;
+    using ::strxfrm;
 
-    /* using std::hel::strlen; */
-    /* using std::hel::strcmp; */
-    /* using std::hel::strncmp; */
-    /* using std::hel::strcoll; */
-    /* using std::hel::strchr; */
-    /* using std::hel::strrchr; */
-    /* using std::hel::strspn; */
-    /* using std::hel::strcspn; */
-    /* using std::hel::strpbrk; */
-    /* using std::hel::strstr; */
-    /* using std::hel::strok; */
+    using ::strlen;
+    using ::strcmp;
+    using ::strncmp;
+    using ::strcoll;
+    using ::strchr;
+    using ::strrchr;
+    using ::strspn;
+    using ::strcspn;
+    using ::strpbrk;
+    using ::strstr;
+    using ::strtok;
 
-    /* using std::hel::memchr; */
-    using std::hel::memcmp;
-    using std::hel::memset;
-    using std::hel::memcpy;
-    using std::hel::memmove;
+    using ::memchr;
+    using ::memcmp;
+    using ::memset;
+    using ::memcpy;
+    using ::memmove;
 
-    /* using std::hel::strerror; */
+    using ::strerror;
 }
 
-using std::hel::size_t;
-
-/* using std::hel::strcpy; */
-/* using std::hel::strncpy; */
-/* using std::hel::strcat; */
-/* using std::hel::strncat; */
-/* using std::hel::strxfrm; */
-
-/* using std::hel::strlen; */
-/* using std::hel::strcmp; */
-/* using std::hel::strncmp; */
-/* using std::hel::strcoll; */
-/* using std::hel::strchr; */
-/* using std::hel::strrchr; */
-/* using std::hel::strspn; */
-/* using std::hel::strcspn; */
-/* using std::hel::strpbrk; */
-/* using std::hel::strstr; */
-/* using std::hel::strok; */
-
-/* using std::hel::memchr; */
-using std::hel::memcmp;
-using std::hel::memset;
-using std::hel::memcpy;
-using std::hel::memmove;
-
-/* using std::hel::strerror; */
-
 #endif
Index: uspace/lib/cpp/include/ctime
===================================================================
--- uspace/lib/cpp/include/ctime	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/ctime	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,51 +30,26 @@
 #define LIBCPP_CTIME
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <time.h>
-    }
-}
+#include <time.h>
 
 namespace std
 {
-    /* using std::hel::clock_t; */
-    using std::hel::size_t;
-    using std::hel::time_t;
-    using std::hel::tm;
-    /* using std::hel::timespec; */
+    using ::clock_t;
+    using ::size_t;
+    using ::time_t;
+    using ::tm;
+    using ::timespec;
 
-    /* using std::hel::clock; */
-    using std::hel::time;
-    using std::hel::difftime;
+    using ::clock;
+    using ::time;
+    using ::difftime;
 
-    /* using std::hel::ctime; */
-    /* using std::hel::asctime; */
-    using std::hel::strftime;
-    /* using std::hel::wcsftime; */
-    /* using std::hel::gmtime; */
-    /* using std::hel::localtime; */
-    using std::hel::mktime;
+    using ::ctime;
+    using ::asctime;
+    using ::strftime;
+    /* using ::wcsftime; */
+    /* using ::gmtime; */
+    /* using ::localtime; */
+    using ::mktime;
 }
 
-/* using std::hel::clock_t; */
-using std::hel::size_t;
-using std::hel::time_t;
-using std::hel::tm;
-/* using std::hel::timespec; */
-
-/* using std::hel::clock; */
-using std::hel::time;
-using std::hel::difftime;
-
-/* using std::hel::ctime; */
-/* using std::hel::asctime; */
-using std::hel::strftime;
-/* using std::hel::wcsftime; */
-/* using std::hel::gmtime; */
-/* using std::hel::localtime; */
-using std::hel::mktime;
-
 #endif
Index: uspace/lib/cpp/include/cwchar
===================================================================
--- uspace/lib/cpp/include/cwchar	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/include/cwchar	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -30,150 +30,76 @@
 #define LIBCPP_WCHAR
 
-#include <__bits/common.hpp>
-
-namespace std::hel
-{
-    extern "C" {
-        #include <wchar.h>
-        #include <time.h>
-    }
-}
+#include <wchar.h>
+#include <time.h>
 
 namespace std
 {
-    /* using std::hel::mbstate_t; */
-    using std::hel::size_t;
-    using std::hel::wint_t;
-    using std::hel::tm;
+    /* using ::mbstate_t; */
+    using ::size_t;
+    using ::wint_t;
+    using ::tm;
 
-    /* using std::hel::wcscpy; */
-    /* using std::hel::wcsncpy; */
-    /* using std::hel::wcscat; */
-    /* using std::hel::wcsncat; */
-    /* using std::hel::wcsnxfrm; */
+    /* using ::wcscpy; */
+    /* using ::wcsncpy; */
+    /* using ::wcscat; */
+    /* using ::wcsncat; */
+    /* using ::wcsnxfrm; */
 
-    /* using std::hel::wcslen; */
-    /* using std::hel::wcscmp; */
-    /* using std::hel::wcsncmp; */
-    /* using std::hel::wcscoll; */
-    /* using std::hel::wcschr; */
-    /* using std::hel::wcsrchr; */
-    /* using std::hel::wcsspn; */
-    /* using std::hel::wcscspn; */
-    /* using std::hel::wcspbrk; */
-    /* using std::hel::wcsstr; */
-    /* using std::hel::wcstok; */
+    /* using ::wcslen; */
+    /* using ::wcscmp; */
+    /* using ::wcsncmp; */
+    /* using ::wcscoll; */
+    /* using ::wcschr; */
+    /* using ::wcsrchr; */
+    /* using ::wcsspn; */
+    /* using ::wcscspn; */
+    /* using ::wcspbrk; */
+    /* using ::wcsstr; */
+    /* using ::wcstok; */
 
-    /* using std::hel::wmemcpy; */
-    /* using std::hel::wmemmove; */
-    /* using std::hel::wmemcmp; */
-    /* using std::hel::wmemchr; */
-    /* using std::hel::wmemset; */
+    /* using ::wmemcpy; */
+    /* using ::wmemmove; */
+    /* using ::wmemcmp; */
+    /* using ::wmemchr; */
+    /* using ::wmemset; */
 
-    /* using std::hel::msbinit; */
-    /* using std::hel::btowc; */
-    /* using std::hel::wctob; */
-    /* using std::hel::mbrlen; */
-    /* using std::hel::mbrtowc; */
-    /* using std::hel::wctomb; */
-    /* using std::hel::mbsrtowcs; */
-    /* using std::hel::wcsrtombs; */
+    /* using ::msbinit; */
+    /* using ::btowc; */
+    /* using ::wctob; */
+    /* using ::mbrlen; */
+    /* using ::mbrtowc; */
+    /* using ::wctomb; */
+    /* using ::mbsrtowcs; */
+    /* using ::wcsrtombs; */
 
-    /* using std::hel::fgetwc; */
-    /* using std::hel::getwc; */
-    /* using std::hel::fgetws; */
-    /* using std::hel::fputwc; */
-    /* using std::hel::putwc; */
-    /* using std::hel::fputws; */
-    /* using std::hel::getwchar; */
-    /* using std::hel::putwchar; */
-    /* using std::hel::ungetwc; */
-    /* using std::hel::fwide; */
-    /* using std::hel::wscanf; */
-    /* using std::hel::fwscanf; */
-    /* using std::hel::swscanf; */
-    /* using std::hel::vwscanf; */
-    /* using std::hel::vfwscanf; */
-    /* using std::hel::vswscanf; */
-    /* using std::hel::wprintf; */
-    /* using std::hel::fwprintf; */
-    /* using std::hel::swprintf; */
+    /* using ::fgetwc; */
+    /* using ::getwc; */
+    /* using ::fgetws; */
+    /* using ::fputwc; */
+    /* using ::putwc; */
+    /* using ::fputws; */
+    /* using ::getwchar; */
+    /* using ::putwchar; */
+    /* using ::ungetwc; */
+    /* using ::fwide; */
+    /* using ::wscanf; */
+    /* using ::fwscanf; */
+    /* using ::swscanf; */
+    /* using ::vwscanf; */
+    /* using ::vfwscanf; */
+    /* using ::vswscanf; */
+    /* using ::wprintf; */
+    /* using ::fwprintf; */
+    /* using ::swprintf; */
 
-    /* using std::hel::wcsftime; */
-    /* using std::hel::wcstol; */
-    /* using std::hel::wcstoll; */
-    /* using std::hel::wcstoul; */
-    /* using std::hel::wcstoull; */
-    /* using std::hel::wcstof; */
-    /* using std::hel::wcstod; */
-    /* using std::hel::wcstold; */
+    /* using ::wcsftime; */
+    /* using ::wcstol; */
+    /* using ::wcstoll; */
+    /* using ::wcstoul; */
+    /* using ::wcstoull; */
+    /* using ::wcstof; */
+    /* using ::wcstod; */
+    /* using ::wcstold; */
 }
 
-/* using std::hel::mbstate_t; */
-using std::hel::size_t;
-using std::hel::wint_t;
-using std::hel::tm;
-
-/* using std::hel::wcscpy; */
-/* using std::hel::wcsncpy; */
-/* using std::hel::wcscat; */
-/* using std::hel::wcsncat; */
-/* using std::hel::wcsnxfrm; */
-
-/* using std::hel::wcslen; */
-/* using std::hel::wcscmp; */
-/* using std::hel::wcsncmp; */
-/* using std::hel::wcscoll; */
-/* using std::hel::wcschr; */
-/* using std::hel::wcsrchr; */
-/* using std::hel::wcsspn; */
-/* using std::hel::wcscspn; */
-/* using std::hel::wcspbrk; */
-/* using std::hel::wcsstr; */
-/* using std::hel::wcstok; */
-
-/* using std::hel::wmemcpy; */
-/* using std::hel::wmemmove; */
-/* using std::hel::wmemcmp; */
-/* using std::hel::wmemchr; */
-/* using std::hel::wmemset; */
-
-/* using std::hel::msbinit; */
-/* using std::hel::btowc; */
-/* using std::hel::wctob; */
-/* using std::hel::mbrlen; */
-/* using std::hel::mbrtowc; */
-/* using std::hel::wctomb; */
-/* using std::hel::mbsrtowcs; */
-/* using std::hel::wcsrtombs; */
-
-/* using std::hel::fgetwc; */
-/* using std::hel::getwc; */
-/* using std::hel::fgetws; */
-/* using std::hel::fputwc; */
-/* using std::hel::putwc; */
-/* using std::hel::fputws; */
-/* using std::hel::getwchar; */
-/* using std::hel::putwchar; */
-/* using std::hel::ungetwc; */
-/* using std::hel::fwide; */
-/* using std::hel::wscanf; */
-/* using std::hel::fwscanf; */
-/* using std::hel::swscanf; */
-/* using std::hel::vwscanf; */
-/* using std::hel::vfwscanf; */
-/* using std::hel::vswscanf; */
-/* using std::hel::wprintf; */
-/* using std::hel::fwprintf; */
-/* using std::hel::swprintf; */
-
-/* using std::hel::wcsftime; */
-/* using std::hel::wcstol; */
-/* using std::hel::wcstoll; */
-/* using std::hel::wcstoul; */
-/* using std::hel::wcstoull; */
-/* using std::hel::wcstof; */
-/* using std::hel::wcstod; */
-/* using std::hel::wcstold; */
-
 #endif
Index: uspace/lib/cpp/src/__bits/runtime.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/runtime.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/__bits/runtime.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -33,4 +33,6 @@
 #include <mutex>
 
+void* __dso_handle = nullptr;
+
 namespace __cxxabiv1
 {
Index: uspace/lib/cpp/src/__bits/unwind.cpp
===================================================================
--- uspace/lib/cpp/src/__bits/unwind.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/__bits/unwind.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2017 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,4 +27,5 @@
  */
 
+#include <cassert>
 #include <cstdint>
 #include <cstdlib>
@@ -175,4 +176,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return nullptr;
     }
@@ -181,4 +183,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -186,4 +189,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -191,4 +195,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return nullptr;
     }
@@ -197,4 +202,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return nullptr;
     }
@@ -203,4 +209,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -208,4 +215,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -213,4 +221,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -218,4 +227,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -223,4 +233,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 
@@ -231,4 +242,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return _URC_NO_REASON;
     }
Index: uspace/lib/cpp/src/condition_variable.cpp
===================================================================
--- uspace/lib/cpp/src/condition_variable.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/condition_variable.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,4 +27,5 @@
  */
 
+#include <cassert>
 #include <condition_variable>
 
@@ -88,4 +89,5 @@
     {
         // TODO: implement
+        __unimplemented();
     }
 }
Index: uspace/lib/cpp/src/stdexcept.cpp
===================================================================
--- uspace/lib/cpp/src/stdexcept.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/stdexcept.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,17 +31,18 @@
 #include <stdexcept>
 #include <string>
+#include <str.h>
 
 namespace std
 {
     logic_error::logic_error(const string& what)
-        : what_{hel::str_dup(what.c_str())}
+        : what_{::helenos::str_dup(what.c_str())}
     { /* DUMMY BODY */ }
 
     logic_error::logic_error(const char* what)
-        : what_{hel::str_dup(what)}
+        : what_{::helenos::str_dup(what)}
     { /* DUMMY BODY */ }
 
     logic_error::logic_error(const logic_error& other) noexcept
-        : exception{other}, what_{hel::str_dup(other.what_)}
+        : exception{other}, what_{::helenos::str_dup(other.what_)}
     { /* DUMMY BODY */ }
 
@@ -50,5 +51,5 @@
         if (what_)
             free(what_);
-        what_ = hel::str_dup(other.what_);
+        what_ = ::helenos::str_dup(other.what_);
 
         return *this;
@@ -114,13 +115,13 @@
 
     runtime_error::runtime_error(const string& what)
-        : what_{hel::str_dup(what.c_str())}
+        : what_{::helenos::str_dup(what.c_str())}
     { /* DUMMY BODY */ }
 
     runtime_error::runtime_error(const char* what)
-        : what_{hel::str_dup(what)}
+        : what_{::helenos::str_dup(what)}
     { /* DUMMY BODY */ }
 
     runtime_error::runtime_error(const runtime_error& other) noexcept
-        : exception{other}, what_{hel::str_dup(other.what_)}
+        : exception{other}, what_{::helenos::str_dup(other.what_)}
     { /* DUMMY BODY */ }
 
@@ -129,5 +130,5 @@
         if (what_)
             free(what_);
-        what_ = hel::str_dup(other.what_);
+        what_ = ::helenos::str_dup(other.what_);
 
         return *this;
Index: uspace/lib/cpp/src/string.cpp
===================================================================
--- uspace/lib/cpp/src/string.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/string.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,4 +27,5 @@
  */
 
+#include <cassert>
 #include <string>
 
@@ -34,4 +35,5 @@
     {
         // TODO: implement using stol once we have numeric limits
+        __unimplemented();
         return 0;
     }
@@ -40,5 +42,5 @@
     {
         char* end;
-        long result = hel::strtol(str.c_str(), &end, base);
+        long result = ::strtol(str.c_str(), &end, base);
 
         if (end != str.c_str())
@@ -56,5 +58,5 @@
     {
         char* end;
-        unsigned long result = hel::strtoul(str.c_str(), &end, base);
+        unsigned long result = ::strtoul(str.c_str(), &end, base);
 
         if (end != str.c_str())
@@ -72,4 +74,5 @@
     {
         // TODO: implement using stol once we have numeric limits
+        __unimplemented();
         return 0;
     }
@@ -78,4 +81,5 @@
     {
         // TODO: implement using stoul once we have numeric limits
+        __unimplemented();
         return 0;
     }
@@ -84,4 +88,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.f;
     }
@@ -90,4 +95,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.0;
     }
@@ -96,16 +102,12 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.0l;
     }
 
-    namespace hel
-    {
-        extern "C" int asprintf(char**, const char*, ...);
-    }
-
     string to_string(int val)
     {
         char* tmp;
-        hel::asprintf(&tmp, "%d", val);
+        ::asprintf(&tmp, "%d", val);
 
         std::string res{tmp};
@@ -118,5 +120,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%u", val);
+        ::asprintf(&tmp, "%u", val);
 
         std::string res{tmp};
@@ -129,5 +131,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%ld", val);
+        ::asprintf(&tmp, "%ld", val);
 
         std::string res{tmp};
@@ -140,5 +142,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%lu", val);
+        ::asprintf(&tmp, "%lu", val);
 
         std::string res{tmp};
@@ -151,5 +153,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%lld", val);
+        ::asprintf(&tmp, "%lld", val);
 
         std::string res{tmp};
@@ -162,5 +164,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%llu", val);
+        ::asprintf(&tmp, "%llu", val);
 
         std::string res{tmp};
@@ -173,5 +175,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%f", val);
+        ::asprintf(&tmp, "%f", val);
 
         std::string res{tmp};
@@ -184,5 +186,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%f", val);
+        ::asprintf(&tmp, "%f", val);
 
         std::string res{tmp};
@@ -195,5 +197,5 @@
     {
         char* tmp;
-        hel::asprintf(&tmp, "%Lf", val);
+        ::asprintf(&tmp, "%Lf", val);
 
         std::string res{tmp};
@@ -206,4 +208,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0;
     }
@@ -212,4 +215,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0;
     }
@@ -218,4 +222,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0;
     }
@@ -224,4 +229,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0;
     }
@@ -230,4 +236,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0;
     }
@@ -236,4 +243,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.f;
     }
@@ -242,4 +250,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.0;
     }
@@ -248,4 +257,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return 0.0l;
     }
@@ -254,4 +264,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -260,4 +271,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -266,4 +278,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -272,4 +285,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -278,4 +292,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -284,4 +299,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -290,4 +306,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -296,4 +313,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
@@ -302,4 +320,5 @@
     {
         // TODO: implement
+        __unimplemented();
         return wstring{};
     }
Index: uspace/lib/cpp/src/thread.cpp
===================================================================
--- uspace/lib/cpp/src/thread.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/thread.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2018 Jaroslav Jindrak
+ * Copyright (c) 2019 Jaroslav Jindrak
  * All rights reserved.
  *
@@ -27,4 +27,5 @@
  */
 
+#include <cassert>
 #include <cstdlib>
 #include <exception>
@@ -120,4 +121,5 @@
     {
         // TODO:
+        __unimplemented();
         return 0;
     }
Index: uspace/lib/cpp/src/typeinfo.cpp
===================================================================
--- uspace/lib/cpp/src/typeinfo.cpp	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/cpp/src/typeinfo.cpp	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,6 +38,5 @@
     bool type_info::operator==(const type_info& other) const noexcept
     {
-        return (this == &other) ||
-               std::hel::str_cmp(name(), other.name());
+        return (this == &other) || ::strcmp(name(), other.name()) == 0;
     }
 
Index: uspace/lib/dltest/dltest.c
===================================================================
--- uspace/lib/dltest/dltest.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/dltest/dltest.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,4 +60,14 @@
 {
 	return dl_constant;
+}
+
+/** Return constant value by calling another function.
+ *
+ * This can be used to test dynamically linked call (via PLT) even in case
+ * binaries are statically linked.
+ */
+int dl_get_constant_via_call(void)
+{
+	return dl_get_constant();
 }
 
Index: uspace/lib/dltest/libdltest.h
===================================================================
--- uspace/lib/dltest/libdltest.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/dltest/libdltest.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,4 +47,5 @@
 
 extern int dl_get_constant(void);
+extern int dl_get_constant_via_call(void);
 extern int dl_get_private_var(void);
 extern int *dl_get_private_var_addr(void);
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/driver.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -119,6 +119,6 @@
 static void driver_dev_add(ipc_call_t *icall)
 {
-	devman_handle_t dev_handle = IPC_GET_ARG1(*icall);
-	devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall);
+	devman_handle_t dev_handle = ipc_get_arg1(icall);
+	devman_handle_t parent_fun_handle = ipc_get_arg2(icall);
 
 	char *dev_name = NULL;
@@ -173,5 +173,5 @@
 static void driver_dev_remove(ipc_call_t *icall)
 {
-	devman_handle_t devh = IPC_GET_ARG1(*icall);
+	devman_handle_t devh = ipc_get_arg1(icall);
 
 	fibril_mutex_lock(&devices_mutex);
@@ -206,5 +206,5 @@
 static void driver_dev_gone(ipc_call_t *icall)
 {
-	devman_handle_t devh = IPC_GET_ARG1(*icall);
+	devman_handle_t devh = ipc_get_arg1(icall);
 
 	fibril_mutex_lock(&devices_mutex);
@@ -239,5 +239,5 @@
 static void driver_fun_online(ipc_call_t *icall)
 {
-	devman_handle_t funh = IPC_GET_ARG1(*icall);
+	devman_handle_t funh = ipc_get_arg1(icall);
 
 	/*
@@ -274,5 +274,5 @@
 static void driver_fun_offline(ipc_call_t *icall)
 {
-	devman_handle_t funh = IPC_GET_ARG1(*icall);
+	devman_handle_t funh = ipc_get_arg1(icall);
 
 	/*
@@ -343,10 +343,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case DRIVER_DEV_ADD:
 			driver_dev_add(&call);
@@ -385,5 +385,5 @@
 	 * the device to which the client connected.
 	 */
-	devman_handle_t handle = IPC_GET_ARG2(*icall);
+	devman_handle_t handle = ipc_get_arg2(icall);
 
 	fibril_mutex_lock(&functions_mutex);
@@ -429,5 +429,5 @@
 		async_get_call(&call);
 
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
@@ -483,5 +483,5 @@
 
 		/* get the method of the remote interface */
-		sysarg_t iface_method_idx = IPC_GET_ARG1(call);
+		sysarg_t iface_method_idx = ipc_get_arg1(&call);
 		remote_iface_func_ptr_t iface_method_ptr =
 		    get_remote_method(rem_iface, iface_method_idx);
@@ -526,4 +526,6 @@
 		return NULL;
 
+	refcount_init(&dev->refcnt);
+
 	return dev;
 }
@@ -541,4 +543,5 @@
 		return NULL;
 
+	refcount_init(&fun->refcnt);
 	init_match_ids(&fun->match_ids);
 	link_initialize(&fun->link);
Index: uspace/lib/drv/generic/remote_audio_pcm.c
===================================================================
--- uspace/lib/drv/generic/remote_audio_pcm.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/remote_audio_pcm.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -142,9 +142,9 @@
 audio_pcm_sess_t *audio_pcm_open(const char *name)
 {
-	devman_handle_t device_handle = 0;
-	const errno_t ret = devman_fun_get_handle(name, &device_handle, 0);
+	service_id_t sid;
+	const errno_t ret = loc_service_get_id(name, &sid, 0);
 	if (ret != EOK)
 		return NULL;
-	return devman_device_connect(device_handle, IPC_FLAG_BLOCKING);
+	return loc_service_connect(sid, INTERFACE_DDF, 0);
 }
 
Index: uspace/lib/drv/generic/remote_ieee80211.c
===================================================================
--- uspace/lib/drv/generic/remote_ieee80211.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/remote_ieee80211.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -276,5 +276,5 @@
 	memset(&scan_results, 0, sizeof(ieee80211_scan_results_t));
 
-	bool now = IPC_GET_ARG2(*call);
+	bool now = ipc_get_arg2(call);
 
 	errno_t rc = ieee80211_iface->get_scan_results(fun, &scan_results, now);
Index: uspace/lib/drv/generic/remote_nic.c
===================================================================
--- uspace/lib/drv/generic/remote_nic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/remote_nic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1010,5 +1010,5 @@
 	async_wait_for(message_id, &res);
 
-	*id = IPC_GET_ARG1(result);
+	*id = ipc_get_arg1(&result);
 	return res;
 }
@@ -1385,5 +1385,5 @@
 	assert(nic_iface->set_state);
 
-	nic_device_state_t state = (nic_device_state_t) IPC_GET_ARG2(*call);
+	nic_device_state_t state = (nic_device_state_t) ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->set_state(dev, state);
@@ -1569,7 +1569,7 @@
 	}
 
-	int speed = (int) IPC_GET_ARG2(*call);
-	nic_channel_mode_t duplex = (nic_channel_mode_t) IPC_GET_ARG3(*call);
-	nic_role_t role = (nic_role_t) IPC_GET_ARG4(*call);
+	int speed = (int) ipc_get_arg2(call);
+	nic_channel_mode_t duplex = (nic_channel_mode_t) ipc_get_arg3(call);
+	nic_role_t role = (nic_role_t) ipc_get_arg4(call);
 
 	errno_t rc = nic_iface->set_operation_mode(dev, speed, duplex, role);
@@ -1586,5 +1586,5 @@
 	}
 
-	uint32_t advertisement = (uint32_t) IPC_GET_ARG2(*call);
+	uint32_t advertisement = (uint32_t) ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->autoneg_enable(dev, advertisement);
@@ -1664,7 +1664,7 @@
 	}
 
-	int allow_send = (int) IPC_GET_ARG2(*call);
-	int allow_receive = (int) IPC_GET_ARG3(*call);
-	uint16_t pause = (uint16_t) IPC_GET_ARG4(*call);
+	int allow_send = (int) ipc_get_arg2(call);
+	int allow_receive = (int) ipc_get_arg3(call);
+	uint16_t pause = (uint16_t) ipc_get_arg4(call);
 
 	errno_t rc = nic_iface->set_pause(dev, allow_send, allow_receive,
@@ -1682,5 +1682,5 @@
 	}
 
-	size_t max_count = IPC_GET_ARG2(*call);
+	size_t max_count = ipc_get_arg2(call);
 	nic_address_t *address_list = NULL;
 
@@ -1733,6 +1733,6 @@
 
 	size_t length;
-	nic_unicast_mode_t mode = IPC_GET_ARG2(*call);
-	size_t address_count = IPC_GET_ARG3(*call);
+	nic_unicast_mode_t mode = ipc_get_arg2(call);
+	size_t address_count = ipc_get_arg3(call);
 	nic_address_t *address_list = NULL;
 
@@ -1785,5 +1785,5 @@
 	}
 
-	size_t max_count = IPC_GET_ARG2(*call);
+	size_t max_count = ipc_get_arg2(call);
 	nic_address_t *address_list = NULL;
 
@@ -1835,6 +1835,6 @@
 	nic_iface_t *nic_iface = (nic_iface_t *) iface;
 
-	nic_multicast_mode_t mode = IPC_GET_ARG2(*call);
-	size_t address_count = IPC_GET_ARG3(*call);
+	nic_multicast_mode_t mode = ipc_get_arg2(call);
+	size_t address_count = ipc_get_arg3(call);
 	nic_address_t *address_list = NULL;
 
@@ -1903,5 +1903,5 @@
 	}
 
-	nic_broadcast_mode_t mode = IPC_GET_ARG2(*call);
+	nic_broadcast_mode_t mode = ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->broadcast_set_mode(dev, mode);
@@ -1933,5 +1933,5 @@
 	}
 
-	uint32_t mode = IPC_GET_ARG2(*call);
+	uint32_t mode = ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->defective_set_mode(dev, mode);
@@ -1948,5 +1948,5 @@
 	}
 
-	size_t max_count = IPC_GET_ARG2(*call);
+	size_t max_count = ipc_get_arg2(call);
 	nic_address_t *address_list = NULL;
 
@@ -1998,5 +1998,5 @@
 
 	size_t length;
-	size_t address_count = IPC_GET_ARG2(*call);
+	size_t address_count = ipc_get_arg2(call);
 	nic_address_t *address_list = NULL;
 
@@ -2081,5 +2081,5 @@
 	nic_vlan_mask_t vlan_mask;
 	nic_vlan_mask_t *vlan_mask_pointer = NULL;
-	bool vlan_mask_set = (bool) IPC_GET_ARG2(*call);
+	bool vlan_mask_set = (bool) ipc_get_arg2(call);
 
 	if (vlan_mask_set) {
@@ -2124,7 +2124,7 @@
 	}
 
-	uint16_t tag = (uint16_t) IPC_GET_ARG2(*call);
-	bool add = (int) IPC_GET_ARG3(*call);
-	bool strip = (int) IPC_GET_ARG4(*call);
+	uint16_t tag = (uint16_t) ipc_get_arg2(call);
+	bool add = (int) ipc_get_arg3(call);
+	bool strip = (int) ipc_get_arg4(call);
 
 	errno_t rc = nic_iface->vlan_set_tag(dev, tag, add, strip);
@@ -2137,5 +2137,5 @@
 	nic_iface_t *nic_iface = (nic_iface_t *) iface;
 
-	int send_data = (int) IPC_GET_ARG3(*call);
+	int send_data = (int) ipc_get_arg3(call);
 	ipc_call_t data;
 
@@ -2175,5 +2175,5 @@
 
 	nic_wv_id_t id = 0;
-	nic_wv_type_t type = (nic_wv_type_t) IPC_GET_ARG2(*call);
+	nic_wv_type_t type = (nic_wv_type_t) ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->wol_virtue_add(dev, type, virtue, length, &id);
@@ -2192,5 +2192,5 @@
 	}
 
-	nic_wv_id_t id = (nic_wv_id_t) IPC_GET_ARG2(*call);
+	nic_wv_id_t id = (nic_wv_id_t) ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->wol_virtue_remove(dev, id);
@@ -2208,6 +2208,6 @@
 	}
 
-	nic_wv_id_t id = (nic_wv_id_t) IPC_GET_ARG2(*call);
-	size_t max_length = IPC_GET_ARG3(*call);
+	nic_wv_id_t id = (nic_wv_id_t) ipc_get_arg2(call);
+	size_t max_length = ipc_get_arg3(call);
 	nic_wv_type_t type = NIC_WV_NONE;
 	size_t length = 0;
@@ -2259,6 +2259,6 @@
 	}
 
-	nic_wv_type_t type = (nic_wv_type_t) IPC_GET_ARG2(*call);
-	size_t max_count = IPC_GET_ARG3(*call);
+	nic_wv_type_t type = (nic_wv_type_t) ipc_get_arg2(call);
+	size_t max_count = ipc_get_arg3(call);
 	size_t count = 0;
 	nic_wv_id_t *id_list = NULL;
@@ -2310,5 +2310,5 @@
 
 	int count = -1;
-	nic_wv_type_t type = (nic_wv_type_t) IPC_GET_ARG2(*call);
+	nic_wv_type_t type = (nic_wv_type_t) ipc_get_arg2(call);
 
 	errno_t rc = nic_iface->wol_virtue_get_caps(dev, type, &count);
@@ -2325,5 +2325,5 @@
 	}
 
-	size_t max_length = (size_t) IPC_GET_ARG2(*call);
+	size_t max_length = (size_t) ipc_get_arg2(call);
 	size_t frame_length = 0;
 	nic_wv_type_t type = NIC_WV_NONE;
@@ -2386,6 +2386,6 @@
 	}
 
-	uint32_t mask = (uint32_t) IPC_GET_ARG2(*call);
-	uint32_t active = (uint32_t) IPC_GET_ARG3(*call);
+	uint32_t mask = (uint32_t) ipc_get_arg2(call);
+	uint32_t active = (uint32_t) ipc_get_arg3(call);
 
 	errno_t rc = nic_iface->offload_set(dev, mask, active);
@@ -2403,5 +2403,5 @@
 
 	nic_poll_mode_t mode = NIC_POLL_IMMEDIATE;
-	int request_data = IPC_GET_ARG2(*call);
+	int request_data = ipc_get_arg2(call);
 	struct timespec period = {
 		.tv_sec = 0,
@@ -2438,6 +2438,6 @@
 	nic_iface_t *nic_iface = (nic_iface_t *) iface;
 
-	nic_poll_mode_t mode = IPC_GET_ARG2(*call);
-	int has_period = IPC_GET_ARG3(*call);
+	nic_poll_mode_t mode = ipc_get_arg2(call);
+	int has_period = ipc_get_arg3(call);
 	struct timespec period_buf;
 	struct timespec *period = NULL;
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -221,5 +221,5 @@
 
 	if (transferred)
-		*transferred = IPC_GET_ARG1(call);
+		*transferred = ipc_get_arg1(&call);
 
 	return (errno_t) opening_request_rc;
@@ -265,5 +265,5 @@
 	}
 
-	const bool reserve = IPC_GET_ARG2(*call);
+	const bool reserve = ipc_get_arg2(call);
 	const errno_t ret = usbhc_iface->default_address_reservation(fun, reserve);
 	async_answer_0(call, ret);
Index: uspace/lib/drv/generic/remote_usbhid.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhid.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/drv/generic/remote_usbhid.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -190,5 +190,5 @@
 		return (errno_t) opening_request_rc;
 
-	size_t act_size = IPC_GET_ARG2(data_request_call);
+	size_t act_size = ipc_get_arg2(&data_request_call);
 
 	/* Copy the individual items. */
@@ -199,5 +199,5 @@
 
 	if (event_nr != NULL)
-		*event_nr = IPC_GET_ARG1(opening_request_call);
+		*event_nr = ipc_get_arg1(&opening_request_call);
 
 	return EOK;
@@ -275,5 +275,5 @@
 		return (errno_t) opening_request_rc;
 
-	size_t act_size = IPC_GET_ARG2(data_request_call);
+	size_t act_size = ipc_get_arg2(&data_request_call);
 
 	if (actual_size != NULL)
Index: uspace/lib/ext4/include/ext4/cfg.h
===================================================================
--- uspace/lib/ext4/include/ext4/cfg.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/include/ext4/cfg.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -53,4 +53,6 @@
 	/** Volume name encoded as UTF-8 string */
 	const char *volume_name;
+	/** Filesystem block size */
+	size_t bsize;
 } ext4_cfg_t;
 
Index: uspace/lib/ext4/include/ext4/superblock.h
===================================================================
--- uspace/lib/ext4/include/ext4/superblock.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/include/ext4/superblock.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -147,4 +147,5 @@
 extern void ext4_superblock_set_reserved_gdt_blocks(ext4_superblock_t *sb,
     uint32_t n);
+extern uint32_t ext4_superblock_get_flex_group_size(ext4_superblock_t *sb);
 
 /* More complex superblock functions */
Index: uspace/lib/ext4/src/balloc.c
===================================================================
--- uspace/lib/ext4/src/balloc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/src/balloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -261,32 +261,28 @@
 		 * is always after the inode table.
 		 */
+		return itable + itable_sz;
+	}
+
+	uint32_t flex_group_size = ext4_superblock_get_flex_group_size(sb);
+	if ((bg_ref->index % flex_group_size) == 0) {
+		/* This is the base group */
+		uint32_t i;
+
 		r = itable + itable_sz;
-		return ext4_filesystem_blockaddr2_index_in_group(sb, r);
-	}
-
-	uint64_t bbmap = ext4_block_group_get_block_bitmap(bg_ref->block_group,
-	    sb);
-	uint64_t ibmap = ext4_block_group_get_inode_bitmap(bg_ref->block_group,
-	    sb);
-
-	r = ext4_filesystem_index_in_group2blockaddr(sb, 0, bg_ref->index);
-	r += ext4_filesystem_bg_get_backup_blocks(bg_ref);
-
-	if (ext4_filesystem_blockaddr2group(sb, bbmap) != bg_ref->index)
-		bbmap = -1; /* Invalid */
-
-	if (ext4_filesystem_blockaddr2group(sb, ibmap) != bg_ref->index)
-		ibmap = -1;
-
-	while (true) {
-		if (r == bbmap || r == ibmap)
-			r++;
-		else if (r >= itable && r < (itable + itable_sz))
-			r = itable + itable_sz;
-		else
-			break;
-	}
-
-	return r;
+
+		uint32_t total_groups = ext4_superblock_get_block_group_count(sb);
+		for (i = bg_ref->index + 1;
+		    i < min(total_groups, bg_ref->index + flex_group_size); ++i) {
+			r += ext4_filesystem_bg_get_itable_size(sb, i);
+		}
+
+		return r;
+	}
+
+	uint64_t base_addr = ext4_filesystem_index_in_group2blockaddr(sb, 0,
+	    bg_ref->index);
+	uint32_t reserved = ext4_filesystem_bg_get_backup_blocks(bg_ref);
+
+	return base_addr + reserved;
 }
 
Index: uspace/lib/ext4/src/filesystem.c
===================================================================
--- uspace/lib/ext4/src/filesystem.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/src/filesystem.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -421,4 +421,5 @@
     enum cache_mode cmode, aoff64_t *size, ext4_filesystem_t **rfs)
 {
+	int fs_inited = 0;
 	ext4_filesystem_t *fs = NULL;
 	fs_node_t *root_node = NULL;
@@ -437,4 +438,6 @@
 	if (rc != EOK)
 		goto error;
+
+	fs_inited = 1;
 
 	/* Read root node */
@@ -463,9 +466,7 @@
 		ext4_node_put(root_node);
 
-	if (fs != NULL) {
+	if (fs_inited)
 		ext4_filesystem_fini(fs);
-		free(fs);
-	}
-
+	free(fs);
 	return rc;
 }
@@ -714,6 +715,4 @@
 		/* One for block bitmap one for inode bitmap */
 		free_blocks = free_blocks - reserved - 2 - inode_table_blocks;
-		if (bg_index == 0)
-			++free_blocks; /* XXX Why? */
 
 		ext4_block_group_set_free_blocks_count(bg_ref->block_group,
Index: uspace/lib/ext4/src/ialloc.c
===================================================================
--- uspace/lib/ext4/src/ialloc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/src/ialloc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -176,10 +176,16 @@
 errno_t ext4_ialloc_alloc_inode(ext4_filesystem_t *fs, uint32_t *index, bool is_dir)
 {
+	int pick_first_free = 0;
 	ext4_superblock_t *sb = fs->superblock;
-
-	uint32_t bgid = 0;
-	uint32_t bg_count = ext4_superblock_get_block_group_count(sb);
-	uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
-	uint32_t avg_free_inodes = sb_free_inodes / bg_count;
+	uint32_t bgid;
+	uint32_t sb_free_inodes;
+	uint32_t avg_free_inodes;
+	uint32_t const bg_count = ext4_superblock_get_block_group_count(sb);
+
+retry:
+
+	bgid = 0;
+	sb_free_inodes = ext4_superblock_get_free_inodes_count(sb);
+	avg_free_inodes = sb_free_inodes / bg_count;
 
 	/* Try to find free i-node in all block groups */
@@ -210,6 +216,6 @@
 		 * blocks.
 		 */
-		if (((free_inodes >= avg_free_inodes) || (bgid == bg_count - 1)) &&
-		    (free_blocks > 0)) {
+		if (((free_inodes >= avg_free_inodes) ||
+		    (bgid == bg_count - 1) || pick_first_free) && (free_blocks > 0)) {
 			/* Load block with bitmap */
 			uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap(
@@ -307,4 +313,10 @@
 	}
 
+	/* Try again with less strict conditions */
+	if (pick_first_free == 0) {
+		pick_first_free = 1;
+		goto retry;
+	}
+
 	return ENOSPC;
 }
Index: uspace/lib/ext4/src/ops.c
===================================================================
--- uspace/lib/ext4/src/ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/src/ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -101,7 +101,7 @@
 } node_key_t;
 
-static size_t open_nodes_key_hash(void *key_arg)
-{
-	node_key_t *key = (node_key_t *)key_arg;
+static size_t open_nodes_key_hash(const void *key_arg)
+{
+	const node_key_t *key = key_arg;
 	return hash_combine(key->service_id, key->index);
 }
@@ -113,7 +113,7 @@
 }
 
-static bool open_nodes_key_equal(void *key_arg, const ht_link_t *item)
-{
-	node_key_t *key = (node_key_t *)key_arg;
+static bool open_nodes_key_equal(const void *key_arg, const ht_link_t *item)
+{
+	const node_key_t *key = key_arg;
 	ext4_node_t *enode = hash_table_get_inst(item, ext4_node_t, link);
 
Index: uspace/lib/ext4/src/superblock.c
===================================================================
--- uspace/lib/ext4/src/superblock.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ext4/src/superblock.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1315,10 +1315,12 @@
 	    ext4_superblock_get_blocks_per_group(sb);
 	uint64_t total_blocks =
-	    ext4_superblock_get_blocks_count(sb) - 1;
+	    ext4_superblock_get_blocks_count(sb);
+	uint32_t first_block =
+	    ext4_superblock_get_first_data_block(sb);
 
 	if (bgid < block_group_count - 1)
 		return blocks_per_group;
 	else
-		return (total_blocks - ((block_group_count - 1) * blocks_per_group));
+		return (total_blocks - ((block_group_count - 1) * blocks_per_group)) - first_block;
 }
 
@@ -1392,4 +1394,15 @@
 {
 	sb->reserved_gdt_blocks = host2uint32_t_le(n);
+}
+
+/** Get the size of the flex groups
+ *
+ * @param sb	Pointer to the superblock
+ *
+ * @return	Size of the flex groups
+ */
+uint32_t ext4_superblock_get_flex_group_size(ext4_superblock_t *sb)
+{
+	return 2 << sb->log_groups_per_flex;
 }
 
@@ -1465,12 +1478,4 @@
 		 */
 
-		if (idx == 0 && block_size == 1024) {
-			/*
-			 * Special case for first group were the boot block
-			 * resides
-			 */
-			r++;
-		}
-
 		/* This accounts for the superblock */
 		r++;
@@ -1505,5 +1510,5 @@
 	uuid_t uuid;
 	uint32_t cur_ts;
-	uint64_t first_block;
+	uint64_t first_block = 0;
 	uint64_t fs_blocks;
 	uint32_t blocks_count;
@@ -1518,4 +1523,5 @@
 	uint32_t idx;
 	size_t fs_bsize;
+	size_t fs_bsize_log;
 	errno_t rc;
 	struct timespec ts;
@@ -1533,6 +1539,22 @@
 	cur_ts = ts.tv_sec;
 
-	fs_bsize = 1024;
-	first_block = 1; /* 1 for 1k block size, 0 otherwise */
+	fs_bsize = cfg->bsize;
+	switch (fs_bsize) {
+	case 1024:
+		first_block = 1;
+		fs_bsize_log = 0;
+		blocks_group = 8192;
+		break;
+	case 2048:
+		fs_bsize_log = 1;
+		blocks_group = 8192 * 2;
+		break;
+	case 4096:
+		fs_bsize_log = 2;
+		blocks_group = 8192 * 4;
+		break;
+	default:
+		return ENOTSUP;
+	}
 
 	if (fs_bsize % dev_bsize == 0) {
@@ -1543,7 +1565,4 @@
 		fs_blocks = dev_bcnt * (dev_bsize / fs_bsize);
 	}
-
-	/* FS blocks per group */
-	blocks_group = 8 * fs_bsize;
 
 	/* Inodes per group */
@@ -1581,8 +1600,7 @@
 	ext4_superblock_set_free_inodes_count(sb, inodes_count);
 	ext4_superblock_set_first_data_block(sb, first_block);
-	/* Block size will be 1024 bytes */
-	ext4_superblock_set_log_block_size(sb, 0);
+	ext4_superblock_set_log_block_size(sb, fs_bsize_log);
 	/* Fragment size should be equal to block size */
-	ext4_superblock_set_log_frag_size(sb, 0);
+	ext4_superblock_set_log_frag_size(sb, fs_bsize_log);
 	ext4_superblock_set_blocks_per_group(sb, blocks_group);
 	/* Should be the same as blocks per group. */
@@ -1634,5 +1652,4 @@
 	/* Compute free blocks */
 	free_blocks = blocks_count;
-	++free_blocks; // XXX Why?
 	for (idx = 0; idx < ngroups; idx++) {
 		free_blocks -= ext4_superblock_get_group_backup_blocks(sb, idx);
Index: uspace/lib/fs/libfs.c
===================================================================
--- uspace/lib/fs/libfs.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/fs/libfs.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -79,5 +79,5 @@
 static void vfs_out_fsprobe(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
 	errno_t rc;
 	vfs_fs_probe_info_t info;
@@ -106,5 +106,5 @@
 static void vfs_out_mounted(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
 	char *opts;
 	errno_t rc;
@@ -132,5 +132,5 @@
 static void vfs_out_unmounted(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
 	errno_t rc;
 
@@ -152,8 +152,8 @@
 static void vfs_out_read(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
-	aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
-	    IPC_GET_ARG4(*req));
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
+	aoff64_t pos = (aoff64_t) MERGE_LOUP32(ipc_get_arg3(req),
+	    ipc_get_arg4(req));
 	size_t rbytes;
 	errno_t rc;
@@ -169,8 +169,8 @@
 static void vfs_out_write(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
-	aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
-	    IPC_GET_ARG4(*req));
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
+	aoff64_t pos = (aoff64_t) MERGE_LOUP32(ipc_get_arg3(req),
+	    ipc_get_arg4(req));
 	size_t wbytes;
 	aoff64_t nsize;
@@ -188,8 +188,8 @@
 static void vfs_out_truncate(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
-	aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
-	    IPC_GET_ARG4(*req));
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
+	aoff64_t size = (aoff64_t) MERGE_LOUP32(ipc_get_arg3(req),
+	    ipc_get_arg4(req));
 	errno_t rc;
 
@@ -201,6 +201,6 @@
 static void vfs_out_close(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 	errno_t rc;
 
@@ -212,6 +212,6 @@
 static void vfs_out_destroy(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 
 	errno_t rc;
@@ -239,6 +239,6 @@
 static void vfs_out_sync(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 	errno_t rc;
 
@@ -255,6 +255,6 @@
 static void vfs_out_is_empty(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 	errno_t rc;
 
@@ -290,10 +290,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case VFS_OUT_FSPROBE:
 			vfs_out_fsprobe(&call);
@@ -424,7 +424,7 @@
 	 */
 	async_wait_for(req, NULL);
-	reg.fs_handle = (int) IPC_GET_ARG1(answer);
-
-	return IPC_GET_RETVAL(answer);
+	reg.fs_handle = (int) ipc_get_arg1(&answer);
+
+	return ipc_get_retval(&answer);
 }
 
@@ -490,7 +490,7 @@
 void libfs_link(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_call_t *req)
 {
-	service_id_t parent_sid = IPC_GET_ARG1(*req);
-	fs_index_t parent_index = IPC_GET_ARG2(*req);
-	fs_index_t child_index = IPC_GET_ARG3(*req);
+	service_id_t parent_sid = ipc_get_arg1(req);
+	fs_index_t parent_index = ipc_get_arg2(req);
+	fs_index_t child_index = ipc_get_arg3(req);
 
 	char component[NAME_MAX + 1];
@@ -536,9 +536,9 @@
 void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_call_t *req)
 {
-	unsigned first = IPC_GET_ARG1(*req);
-	unsigned len = IPC_GET_ARG2(*req);
-	service_id_t service_id = IPC_GET_ARG3(*req);
-	fs_index_t index = IPC_GET_ARG4(*req);
-	int lflag = IPC_GET_ARG5(*req);
+	unsigned first = ipc_get_arg1(req);
+	unsigned len = ipc_get_arg2(req);
+	service_id_t service_id = ipc_get_arg3(req);
+	fs_index_t index = ipc_get_arg4(req);
+	int lflag = ipc_get_arg5(req);
 
 	// TODO: Validate flags.
@@ -716,6 +716,6 @@
 void libfs_stat(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 
 	fs_node_t *fn;
@@ -753,6 +753,6 @@
 void libfs_statfs(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
-	fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
+	fs_index_t index = (fs_index_t) ipc_get_arg2(req);
 
 	fs_node_t *fn;
@@ -810,6 +810,6 @@
 void libfs_open_node(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_call_t *req)
 {
-	service_id_t service_id = IPC_GET_ARG1(*req);
-	fs_index_t index = IPC_GET_ARG2(*req);
+	service_id_t service_id = ipc_get_arg1(req);
+	fs_index_t index = ipc_get_arg2(req);
 
 	fs_node_t *fn;
Index: uspace/lib/graph/graph.c
===================================================================
--- uspace/lib/graph/graph.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/graph/graph.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -243,5 +243,5 @@
 static void vs_claim(visualizer_t *vs, ipc_call_t *icall)
 {
-	vs->client_side_handle = IPC_GET_ARG1(*icall);
+	vs->client_side_handle = ipc_get_arg1(icall);
 	errno_t rc = vs->ops.claim(vs);
 	async_answer_0(icall, rc);
@@ -283,5 +283,5 @@
 
 	fibril_mutex_lock(&vs->mode_mtx);
-	link_t *link = list_nth(&vs->modes, IPC_GET_ARG1(*icall));
+	link_t *link = list_nth(&vs->modes, ipc_get_arg1(icall));
 
 	if (link != NULL) {
@@ -360,5 +360,5 @@
 	}
 
-	sysarg_t mode_idx = IPC_GET_ARG1(*icall);
+	sysarg_t mode_idx = ipc_get_arg1(icall);
 
 	fibril_mutex_lock(&vs->mode_mtx);
@@ -397,6 +397,6 @@
 
 	/* Retrieve mode index and version. */
-	sysarg_t mode_idx = IPC_GET_ARG1(*icall);
-	sysarg_t mode_version = IPC_GET_ARG2(*icall);
+	sysarg_t mode_idx = ipc_get_arg1(icall);
+	sysarg_t mode_version = ipc_get_arg2(icall);
 
 	/* Find mode in the list. */
@@ -470,10 +470,10 @@
 static void vs_update_damaged_region(visualizer_t *vs, ipc_call_t *icall)
 {
-	sysarg_t x_offset = (IPC_GET_ARG5(*icall) >> 16);
-	sysarg_t y_offset = (IPC_GET_ARG5(*icall) & 0x0000ffff);
+	sysarg_t x_offset = (ipc_get_arg5(icall) >> 16);
+	sysarg_t y_offset = (ipc_get_arg5(icall) & 0x0000ffff);
 
 	errno_t rc = vs->ops.handle_damage(vs,
-	    IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall),
-	    IPC_GET_ARG3(*icall), IPC_GET_ARG4(*icall),
+	    ipc_get_arg1(icall), ipc_get_arg2(icall),
+	    ipc_get_arg3(icall), ipc_get_arg4(icall),
 	    x_offset, y_offset);
 	async_answer_0(icall, rc);
@@ -516,10 +516,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case VISUALIZER_CLAIM:
 			vs_claim(vs, &call);
@@ -576,10 +576,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		default:
 			async_answer_0(&call, EINVAL);
@@ -595,6 +595,6 @@
 {
 	/* Find the visualizer or renderer with the given service ID. */
-	visualizer_t *vs = graph_get_visualizer(IPC_GET_ARG2(*icall));
-	renderer_t *rnd = graph_get_renderer(IPC_GET_ARG2(*icall));
+	visualizer_t *vs = graph_get_visualizer(ipc_get_arg2(icall));
+	renderer_t *rnd = graph_get_renderer(ipc_get_arg2(icall));
 
 	if (vs != NULL)
Index: uspace/lib/gui/terminal.c
===================================================================
--- uspace/lib/gui/terminal.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/gui/terminal.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -682,5 +682,5 @@
 
 	list_foreach(terms, link, terminal_t, cur) {
-		if (cur->dsid == (service_id_t) IPC_GET_ARG2(*icall)) {
+		if (cur->dsid == (service_id_t) ipc_get_arg2(icall)) {
 			term = cur;
 			break;
Index: uspace/lib/hound/src/protocol.c
===================================================================
--- uspace/lib/hound/src/protocol.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/hound/src/protocol.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -140,5 +140,5 @@
 	async_exchange_end(exch);
 	if (ret == EOK) {
-		*id = (hound_context_id_t) IPC_GET_ARG1(call);
+		*id = (hound_context_id_t) ipc_get_arg1(&call);
 	}
 
@@ -158,5 +158,5 @@
 	async_exch_t *exch = async_exchange_begin(sess);
 	const errno_t ret = async_req_1_0(exch, IPC_M_HOUND_CONTEXT_UNREGISTER,
-	    CAP_HANDLE_RAW(id));
+	    cap_handle_raw(id));
 	async_exchange_end(exch);
 	return ret;
@@ -203,5 +203,5 @@
 		return ret;
 	}
-	unsigned name_count = IPC_GET_ARG1(res_call);
+	unsigned name_count = ipc_get_arg1(&res_call);
 
 	/* Start receiving names */
@@ -315,5 +315,5 @@
 	};
 
-	return async_req_4_0(exch, IPC_M_HOUND_STREAM_ENTER, CAP_HANDLE_RAW(id),
+	return async_req_4_0(exch, IPC_M_HOUND_STREAM_ENTER, cap_handle_raw(id),
 	    flags, c.arg, bsize);
 }
@@ -406,5 +406,5 @@
 		async_get_call(&call);
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IPC_M_HOUND_CONTEXT_REGISTER:
 			/* check interface functions */
@@ -413,5 +413,5 @@
 				break;
 			}
-			bool record = IPC_GET_ARG1(call);
+			bool record = ipc_get_arg1(&call);
 			void *name;
 
@@ -431,5 +431,5 @@
 				async_answer_0(&call, ret);
 			} else {
-				async_answer_1(&call, EOK, CAP_HANDLE_RAW(context));
+				async_answer_1(&call, EOK, cap_handle_raw(context));
 			}
 			break;
@@ -442,5 +442,5 @@
 
 			/* get id, 1st param */
-			context = (hound_context_id_t) IPC_GET_ARG1(call);
+			context = (hound_context_id_t) ipc_get_arg1(&call);
 			ret = server_iface->rem_context(server_iface->server,
 			    context);
@@ -455,7 +455,7 @@
 
 			char **list = NULL;
-			flags = IPC_GET_ARG1(call);
-			size_t count = IPC_GET_ARG2(call);
-			const bool conn = IPC_GET_ARG3(call);
+			flags = ipc_get_arg1(&call);
+			size_t count = ipc_get_arg2(&call);
+			const bool conn = ipc_get_arg3(&call);
 			char *conn_name = NULL;
 			ret = EOK;
@@ -568,7 +568,7 @@
 
 			/* get parameters */
-			context = (hound_context_id_t) IPC_GET_ARG1(call);
-			flags = IPC_GET_ARG2(call);
-			const format_convert_t c = { .arg = IPC_GET_ARG3(call) };
+			context = (hound_context_id_t) ipc_get_arg1(&call);
+			flags = ipc_get_arg2(&call);
+			const format_convert_t c = { .arg = ipc_get_arg3(&call) };
 			const pcm_format_t f = {
 				.sampling_rate = c.f.rate * 100,
@@ -576,5 +576,5 @@
 				.sample_format = c.f.format,
 			};
-			size_t bsize = IPC_GET_ARG4(call);
+			size_t bsize = ipc_get_arg4(&call);
 
 			void *stream;
@@ -640,7 +640,7 @@
 	/* accept data write or drain */
 	while (async_data_write_receive(&call, &size) ||
-	    (IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_DRAIN)) {
+	    (ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_DRAIN)) {
 		/* check drain first */
-		if (IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_DRAIN) {
+		if (ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_DRAIN) {
 			errno_t ret = ENOTSUP;
 			if (server_iface->drain_stream)
@@ -668,5 +668,5 @@
 		}
 	}
-	const errno_t ret = IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_EXIT ?
+	const errno_t ret = ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_EXIT ?
 	    EOK : EINVAL;
 
@@ -687,7 +687,7 @@
 	/* accept data read and drain */
 	while (async_data_read_receive(&call, &size) ||
-	    (IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_DRAIN)) {
+	    (ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_DRAIN)) {
 		/* drain does not make much sense but it is allowed */
-		if (IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_DRAIN) {
+		if (ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_DRAIN) {
 			errno_t ret = ENOTSUP;
 			if (server_iface->drain_stream)
@@ -712,5 +712,5 @@
 		}
 	}
-	const errno_t ret = IPC_GET_IMETHOD(call) == IPC_M_HOUND_STREAM_EXIT ?
+	const errno_t ret = ipc_get_imethod(&call) == IPC_M_HOUND_STREAM_EXIT ?
 	    EOK : EINVAL;
 
Index: uspace/lib/http/src/headers.c
===================================================================
--- uspace/lib/http/src/headers.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/http/src/headers.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -85,10 +85,6 @@
 {
 	/* TODO properly split long header values */
-	if (buf == NULL) {
-		return printf_size(HTTP_HEADER_LINE, header->name, header->value);
-	} else {
-		return snprintf(buf, buf_size,
-		    HTTP_HEADER_LINE, header->name, header->value);
-	}
+	return snprintf(buf, buf_size,
+	    HTTP_HEADER_LINE, header->name, header->value);
 }
 
Index: uspace/lib/http/src/request.c
===================================================================
--- uspace/lib/http/src/request.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/http/src/request.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -82,9 +82,5 @@
     const char *method, const char *path)
 {
-	if (buf == NULL) {
-		return printf_size(HTTP_METHOD_LINE, method, path);
-	} else {
-		return snprintf(buf, buf_size, HTTP_METHOD_LINE, method, path);
-	}
+	return snprintf(buf, buf_size, HTTP_METHOD_LINE, method, path);
 }
 
Index: uspace/lib/ieee80211/src/ieee80211.c
===================================================================
--- uspace/lib/ieee80211/src/ieee80211.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/ieee80211/src/ieee80211.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -479,5 +479,5 @@
 }
 
-extern bool ieee80211_query_using_key(ieee80211_dev_t *ieee80211_dev)
+bool ieee80211_query_using_key(ieee80211_dev_t *ieee80211_dev)
 {
 	fibril_mutex_lock(&ieee80211_dev->gen_mutex);
@@ -803,4 +803,5 @@
 	if (rc != EOK) {
 		ddf_fun_unbind(fun);
+		ddf_fun_destroy(fun);
 		return rc;
 	}
@@ -809,4 +810,5 @@
 	if (rc != EOK) {
 		ddf_fun_unbind(fun);
+		ddf_fun_destroy(fun);
 		return rc;
 	}
Index: uspace/lib/nettl/include/nettl/amap.h
===================================================================
--- uspace/lib/nettl/include/nettl/amap.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/nettl/include/nettl/amap.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -82,5 +82,5 @@
 	/** Local links */
 	list_t llink; /* of amap_llink_t */
-	/** Nothing specified (listen on all local adresses) */
+	/** Nothing specified (listen on all local addresses) */
 	portrng_t *unspec;
 } amap_t;
Index: uspace/lib/nic/src/nic_addr_db.c
===================================================================
--- uspace/lib/nic/src/nic_addr_db.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/nic/src/nic_addr_db.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,7 +62,7 @@
 } addr_key_t;
 
-static bool nic_addr_key_equal(void *key_arg, const ht_link_t *item)
-{
-	addr_key_t *key = (addr_key_t *)key_arg;
+static bool nic_addr_key_equal(const void *key_arg, const ht_link_t *item)
+{
+	const addr_key_t *key = key_arg;
 	nic_addr_entry_t *entry = member_to_inst(item, nic_addr_entry_t, link);
 
@@ -81,7 +81,7 @@
 }
 
-static size_t nic_addr_key_hash(void *k)
-{
-	addr_key_t *key = (addr_key_t *)k;
+static size_t nic_addr_key_hash(const void *k)
+{
+	const addr_key_t *key = k;
 	return addr_hash(key->len, key->addr);
 }
@@ -163,5 +163,5 @@
  * @return EOK		If the address was inserted
  * @return ENOMEM	If there was not enough memory
- * @return EEXIST	If this adress already is in the db
+ * @return EEXIST	If this address already is in the db
  */
 errno_t nic_addr_db_insert(nic_addr_db_t *db, const uint8_t *addr)
Index: uspace/lib/nic/src/nic_driver.c
===================================================================
--- uspace/lib/nic/src/nic_driver.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/nic/src/nic_driver.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -418,5 +418,5 @@
 }
 
-/** Inform the NICF about device's MAC adress.
+/** Inform the NICF about device's MAC address.
  *
  * @return EOK On success
Index: uspace/lib/nic/src/nic_wol_virtues.c
===================================================================
--- uspace/lib/nic/src/nic_wol_virtues.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/nic/src/nic_wol_virtues.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,7 +45,8 @@
  */
 
-static size_t nic_wv_key_hash(void *key)
-{
-	return *(nic_wv_id_t *) key;
+static size_t nic_wv_key_hash(const void *key)
+{
+	const nic_wv_id_t *k = key;
+	return *k;
 }
 
@@ -56,8 +57,9 @@
 }
 
-static bool nic_wv_key_equal(void *key, const ht_link_t *item)
-{
-	nic_wol_virtue_t *virtue = (nic_wol_virtue_t *) item;
-	return (virtue->id == *(nic_wv_id_t *) key);
+static bool nic_wv_key_equal(const void *key, const ht_link_t *item)
+{
+	const nic_wv_id_t *k = key;
+	const nic_wol_virtue_t *virtue = (const nic_wol_virtue_t *) item;
+	return (virtue->id == *k);
 }
 
Index: uspace/lib/pcm/src/format.c
===================================================================
--- uspace/lib/pcm/src/format.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcm/src/format.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -40,4 +40,5 @@
 #include <stdio.h>
 #include <inttypes.h>
+#include <limits.h>
 
 #include "format.h"
Index: uspace/lib/pcut/Makefile
===================================================================
--- uspace/lib/pcut/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -23,5 +23,5 @@
 	$(PCUT_TEST_PREFIX)testlist$(PCUT_TEST_SUFFIX) \
 	$(PCUT_TEST_PREFIX)timeout$(PCUT_TEST_SUFFIX) \
-	$(PCUT_TEST_PREFIX)xmlreport$(PCUT_TEST_SUFFIX) 
+	$(PCUT_TEST_PREFIX)xmlreport$(PCUT_TEST_SUFFIX)
 
 EXTRA_CLEAN = $(SELF_TESTS)
Index: uspace/lib/pcut/include/pcut/asserts.h
===================================================================
--- uspace/lib/pcut/include/pcut/asserts.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/include/pcut/asserts.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -186,10 +186,41 @@
 #define PCUT_ASSERT_INT_EQUALS(expected, actual) \
 	do {\
-		long pcut_expected_eval = (expected); \
-		long pcut_actual_eval = (actual); \
+		long long pcut_expected_eval = (expected); \
+		long long pcut_actual_eval = (actual); \
 		if (pcut_expected_eval != pcut_actual_eval) { \
-			PCUT_ASSERTION_FAILED("Expected <%ld> but got <%ld> (%s != %s)", \
+			PCUT_ASSERTION_FAILED("Expected <%lld> but got <%lld> (%s != %s)", \
 				pcut_expected_eval, pcut_actual_eval, \
 				#expected, #actual); \
+		} \
+	} while (0)
+
+/** Assertion for checking that two integers are equal.
+ *
+ * @param expected Expected (correct) value.
+ * @param actual Actually obtained (computed) value we wish to test.
+ */
+#define PCUT_ASSERT_UINT_EQUALS(expected, actual) \
+	do {\
+		unsigned long long pcut_expected_eval = (expected); \
+		unsigned long long pcut_actual_eval = (actual); \
+		if (pcut_expected_eval != pcut_actual_eval) { \
+			PCUT_ASSERTION_FAILED("Expected <%llu> but got <%llu> (%s != %s)", \
+				pcut_expected_eval, pcut_actual_eval, \
+				#expected, #actual); \
+		} \
+	} while (0)
+
+/** Assertion for checking that two pointers are equal.
+ *
+ * @param expected Expected (correct) value.
+ * @param actual Actually obtained (computed) value we wish to test.
+ */
+#define PCUT_ASSERT_PTR_EQUALS(expected, actual) \
+	do {\
+		const void *pcut_expected_eval = (expected); \
+		const void *pcut_actual_eval = (actual); \
+		if (pcut_expected_eval != pcut_actual_eval) { \
+			PCUT_ASSERTION_FAILED("Expected '" #actual "' = '" #expected "' = <%p> but got '" #actual "' = <%p>", \
+				pcut_expected_eval, pcut_actual_eval); \
 		} \
 	} while (0)
Index: uspace/lib/pcut/src/os/generic.c
===================================================================
--- uspace/lib/pcut/src/os/generic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/src/os/generic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -121,5 +121,5 @@
 	FORMAT_COMMAND(command, PCUT_COMMAND_LINE_BUFFER_SIZE - 1,
 		self_path, (test)->id, tempfile_name);
-	
+
 	PCUT_DEBUG("Will execute <%s> (temp file <%s>) with system().",
 		command, tempfile_name);
Index: uspace/lib/pcut/src/os/helenos.c
===================================================================
--- uspace/lib/pcut/src/os/helenos.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/src/os/helenos.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -109,10 +109,8 @@
 
 /** Mutex guard for forced_termination_cv. */
-static fibril_mutex_t forced_termination_mutex
-	= FIBRIL_MUTEX_INITIALIZER(forced_termination_mutex);
+static FIBRIL_MUTEX_INITIALIZE(forced_termination_mutex);
 
 /** Condition-variable for checking whether test timed-out. */
-static fibril_condvar_t forced_termination_cv
-	= FIBRIL_CONDVAR_INITIALIZER(forced_termination_cv);
+static FIBRIL_CONDVAR_INITIALIZE(forced_termination_cv);
 
 /** Spawned task id. */
Index: uspace/lib/pcut/src/report/tap.c
===================================================================
--- uspace/lib/pcut/src/report/tap.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/src/report/tap.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,11 +35,10 @@
 #include "report.h"
 
-#ifndef __helenos__
+#ifdef __helenos__
+#define _REALLY_WANT_STRING_H
+#endif
+
 #pragma warning(push, 0)
 #include <string.h>
-#pragma warning(pop)
-#endif
-
-#pragma warning(push, 0)
 #include <stdio.h>
 #pragma warning(pop)
@@ -57,4 +56,7 @@
 /** Counter of failed tests in current suite. */
 static int failed_tests_in_suite;
+
+/** Comma-separated list of failed test names. */
+static char *failed_test_names;
 
 /** Initialize the TAP output.
@@ -170,4 +172,17 @@
 
 	print_by_lines(extra_output, "# stdio: ");
+
+	if (outcome != PCUT_OUTCOME_PASS) {
+		if (failed_test_names == NULL) {
+			failed_test_names = strdup(test_name);
+		} else {
+			char *fs = NULL;
+			if (asprintf(&fs, "%s, %s",
+			    failed_test_names, test_name) >= 0) {
+				free(failed_test_names);
+				failed_test_names = fs;
+			}
+		}
+	}
 }
 
@@ -178,4 +193,5 @@
 	} else {
 		printf("#> Done: %d of %d tests failed.\n", failed_test_counter, test_counter);
+		printf("#> Failed tests: %s\n", failed_test_names);
 	}
 }
Index: uspace/lib/pcut/update-from-master.sh
===================================================================
--- uspace/lib/pcut/update-from-master.sh	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/pcut/update-from-master.sh	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1,3 +1,3 @@
-#!/bin/sh
+#!/bin/bash
 
 #
Index: uspace/lib/posix/Makefile
===================================================================
--- uspace/lib/posix/Makefile	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/Makefile	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -31,5 +31,5 @@
 LIBRARY = libposix
 
-EXTRA_CFLAGS = -Iinclude/posix
+EXTRA_CFLAGS = -Iinclude/posix -D_XOPEN_SOURCE
 
 EXPORT_FILES = \
@@ -41,4 +41,5 @@
 	../hound/libhound.a \
 	../pcm/libpcm.a \
+	../cpp/libcpp.a \
 	$(LIBC_PREFIX)/libc.a \
 	$(LIBC_PREFIX)/crt0.o \
@@ -96,4 +97,7 @@
 	$(COMMON_CFLAGS)
 
+EXPORT_CXXFLAGS = \
+	$(COMMON_CXXFLAGS)
+
 include $(USPACE_PREFIX)/Makefile.common
 
@@ -109,5 +113,5 @@
 	echo 'HELENOS_CPPFLAGS="$(EXPORT_CPPFLAGS)"' >> $@.new
 	echo 'HELENOS_CFLAGS="$(EXPORT_CFLAGS)"' >> $@.new
-	echo 'HELENOS_CXXFLAGS="$(EXPORT_CFLAGS)"' >> $@.new
+	echo 'HELENOS_CXXFLAGS="$(EXPORT_CXXFLAGS)"' >> $@.new
 	echo 'HELENOS_LDFLAGS="$(EXPORT_LDFLAGS)"' >> $@.new
 	echo 'HELENOS_LDLIBS="$(EXPORT_LDLIBS)"' >> $@.new
@@ -146,3 +150,5 @@
 	mkdir -p $(EXPORT_DIR)/include.new/libpcm
 	cp -r -L -t $(EXPORT_DIR)/include.new/libpcm ../pcm/include/*
+	mkdir -p $(EXPORT_DIR)/include.new/libcpp
+	cp -r -L -t $(EXPORT_DIR)/include.new/libcpp ../cpp/include/*
 	mv $(EXPORT_DIR)/include.new $(EXPORT_DIR)/include
Index: uspace/lib/posix/include/posix/ctype.h
===================================================================
--- uspace/lib/posix/include/posix/ctype.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/ctype.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,6 @@
 #include <libc/ctype.h>
 
+__C_DECLS_BEGIN;
+
 /* Obsolete Functions and Macros */
 extern int isascii(int c);
@@ -46,4 +48,6 @@
 #define _toupper(c) ((c) - 'a' + 'A')
 
+__C_DECLS_END;
+
 #endif /* POSIX_CTYPE_H_ */
 
Index: uspace/lib/posix/include/posix/dlfcn.h
===================================================================
--- uspace/lib/posix/include/posix/dlfcn.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/dlfcn.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -41,8 +41,12 @@
 #define RTLD_LOCAL 0
 
+__C_DECLS_BEGIN;
+
 extern void *dlopen(const char *, int);
 extern void *dlsym(void *, const char *);
 extern int dlclose(void *);
 extern char *dlerror(void);
+
+__C_DECLS_END;
 
 #endif
Index: uspace/lib/posix/include/posix/fcntl.h
===================================================================
--- uspace/lib/posix/include/posix/fcntl.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/fcntl.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,11 +38,4 @@
 #include <sys/types.h>
 
-#undef O_CREAT
-#undef O_EXCL
-#undef O_TRUNC
-#undef O_APPEND
-#undef O_RDONLY
-#undef O_RDWR
-#undef O_WRONLY
 #define O_CREAT   1
 #define O_EXCL    2
@@ -54,23 +47,10 @@
 
 /* Mask for file access modes. */
-#undef O_ACCMODE
 #define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
 
 /* Dummy compatibility flag */
-#undef O_NOCTTY
 #define O_NOCTTY 0
 
 /* fcntl commands */
-#undef F_DUPFD
-#undef F_DUPFD_CLOEXEC
-#undef F_GETFD
-#undef F_SETFD
-#undef F_GETFL
-#undef F_SETFL
-#undef F_GETOWN
-#undef F_SETOWN
-#undef F_GETLK
-#undef F_SETLK
-#undef F_SETLKW
 #define F_DUPFD            0 /* Duplicate file descriptor. */
 #define F_DUPFD_CLOEXEC    1 /* Same as F_DUPFD but with FD_CLOEXEC flag set. */
@@ -86,9 +66,12 @@
 
 /* File descriptor flags used with F_GETFD and F_SETFD. */
-#undef FD_CLOEXEC
 #define FD_CLOEXEC         1 /* Close on exec. */
+
+__C_DECLS_BEGIN;
 
 extern int open(const char *pathname, int flags, ...);
 extern int fcntl(int fd, int cmd, ...);
+
+__C_DECLS_END;
 
 #endif /* POSIX_FCNTL_H_ */
Index: uspace/lib/posix/include/posix/fnmatch.h
===================================================================
--- uspace/lib/posix/include/posix/fnmatch.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/fnmatch.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -36,12 +36,10 @@
 #define POSIX_FNMATCH_H_
 
+#include <_bits/decls.h>
+
 /* Error Values */
-#undef FNM_NOMATCH
 #define FNM_NOMATCH 1
 
 /* Flags */
-#undef FNM_PATHNAME
-#undef FNM_PERIOD
-#undef FNM_NOESCAPE
 #define FNM_PATHNAME 1
 #define FNM_PERIOD 2
@@ -49,12 +47,13 @@
 
 /* GNU Extensions */
-#undef FNM_FILE_NAME
-#undef FNM_LEADING_DIR
-#undef FNM_CASEFOLD
 #define FNM_FILE_NAME FNM_PATHNAME
 #define FNM_LEADING_DIR 8
 #define FNM_CASEFOLD 16
 
+__C_DECLS_BEGIN;
+
 extern int fnmatch(const char *pattern, const char *string, int flags);
+
+__C_DECLS_END;
 
 #endif /* POSIX_FNMATCH_H_ */
Index: uspace/lib/posix/include/posix/locale.h
===================================================================
--- uspace/lib/posix/include/posix/locale.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/locale.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,17 +37,6 @@
 
 #include <stddef.h>
+#include <_bits/decls.h>
 
-#ifndef __locale_t_defined
-#define __locale_t_defined
-typedef struct __posix_locale *locale_t;
-#endif
-
-#undef LC_ALL
-#undef LC_COLLATE
-#undef LC_CTYPE
-#undef LC_MESSAGES
-#undef LC_MONETARY
-#undef LC_NUMERIC
-#undef LC_TIME
 #define LC_ALL 0
 #define LC_COLLATE 1
@@ -58,11 +47,4 @@
 #define LC_TIME 6
 
-#undef LC_COLLATE_MASK
-#undef LC_CTYPE_MASK
-#undef LC_MESSAGES_MASK
-#undef LC_MONETARY_MASK
-#undef LC_NUMERIC_MASK
-#undef LC_TIME_MASK
-#undef LC_ALL_MASK
 #define LC_COLLATE_MASK (1 << 0)
 #define LC_CTYPE_MASK (1 << 1)
@@ -74,6 +56,12 @@
     LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK)
 
-#undef LC_GLOBAL_LOCALE
 #define LC_GLOBAL_LOCALE NULL
+
+__C_DECLS_BEGIN;
+
+#ifndef __locale_t_defined
+#define __locale_t_defined
+typedef struct __posix_locale *locale_t;
+#endif
 
 struct lconv {
@@ -114,4 +102,6 @@
 extern locale_t uselocale(locale_t newloc);
 
+__C_DECLS_END;
+
 #endif /* POSIX_LOCALE_H_ */
 
Index: uspace/lib/posix/include/posix/pthread.h
===================================================================
--- uspace/lib/posix/include/posix/pthread.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/pthread.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -34,4 +34,13 @@
 
 #include <time.h>
+#include <_bits/decls.h>
+
+#define PTHREAD_MUTEX_RECURSIVE 1
+
+#define PTHREAD_MUTEX_INITIALIZER { 0 }
+
+#define PTHREAD_COND_INITIALIZER { 0 }
+
+__C_DECLS_BEGIN;
 
 typedef void *pthread_t;
@@ -43,11 +52,7 @@
 typedef int pthread_key_t;
 
-#define PTHREAD_MUTEX_RECURSIVE 1
-
 typedef struct pthread_mutex {
 	int dummy;
 } pthread_mutex_t;
-
-#define PTHREAD_MUTEX_INITIALIZER { 0 }
 
 typedef struct {
@@ -62,6 +67,4 @@
 	int dummy;
 } pthread_cond_t;
-
-#define PTHREAD_COND_INITIALIZER { 0 }
 
 extern pthread_t pthread_self(void);
@@ -106,4 +109,6 @@
 extern int pthread_key_create(pthread_key_t *, void (*)(void *));
 
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/posix/include/posix/pwd.h
===================================================================
--- uspace/lib/posix/include/posix/pwd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/pwd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,4 +37,7 @@
 
 #include <sys/types.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 struct passwd {
@@ -58,4 +61,6 @@
     char *buffer, size_t bufsize, struct passwd **result);
 
+__C_DECLS_END;
+
 #endif /* POSIX_PWD_H_ */
 
Index: uspace/lib/posix/include/posix/signal.h
===================================================================
--- uspace/lib/posix/include/posix/signal.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/signal.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,67 +39,21 @@
 #include <ucontext.h>
 
-extern void __posix_default_signal_handler(int signo);
-extern void __posix_hold_signal_handler(int signo);
-extern void __posix_ignore_signal_handler(int signo);
-
-#undef SIG_DFL
 #define SIG_DFL ((void (*)(int)) __posix_default_signal_handler)
-#undef SIG_ERR
 #define SIG_ERR ((void (*)(int)) NULL)
-#undef SIG_HOLD
 #define SIG_HOLD ((void (*)(int)) __posix_hold_signal_handler)
-#undef SIG_IGN
 #define SIG_IGN ((void (*)(int)) __posix_ignore_signal_handler)
 
-typedef struct {
-	int si_signo;
-	int si_code;
-
-	int si_errno;
-
-	pid_t si_pid;
-	uid_t si_uid;
-	void *si_addr;
-	int si_status;
-
-	long si_band;
-
-	union sigval si_value;
-} siginfo_t;
-
-struct sigaction {
-	void (*sa_handler)(int);
-	sigset_t sa_mask;
-	int sa_flags;
-	void (*sa_sigaction)(int, siginfo_t *, void *);
-};
-
 /* Values of sigevent::sigev_notify */
-#undef SIGEV_NONE
-#undef SIGEV_SIGNAL
-#undef SIGEV_THREAD
 #define SIGEV_NONE 0
 #define SIGEV_SIGNAL 0
 #define SIGEV_THREAD 0
 
-#undef SIGRT_MIN
-#undef SIGRT_MAX
 #define SIGRT_MIN 0
 #define SIGRT_MAX 0
 
-#undef SIG_BLOCK
-#undef SIG_UNBLOCK
-#undef SIG_SETMASK
 #define SIG_BLOCK 0
 #define SIG_UNBLOCK 1
 #define SIG_SETMASK 2
 
-#undef SA_NOCLDSTOP
-#undef SA_ONSTACK
-#undef SA_RESETHAND
-#undef SA_RESTART
-#undef SA_SIGINFO
-#undef SA_NOCLDWAIT
-#undef SA_NODEFER
 #define SA_NOCLDSTOP (1 << 0)
 #define SA_ONSTACK (1 << 1)
@@ -110,13 +64,38 @@
 #define SA_NODEFER (1 << 6)
 
-#undef SS_ONSTACK
-#undef SS_DISABLE
 #define SS_ONSTACK 0
 #define SS_DISABLE 0
 
-#undef MINSIGSTKSZ
-#undef SIGSTKSZ
 #define MINSIGSTKSZ 0
 #define SIGSTKSZ 0
+
+__C_DECLS_BEGIN;
+
+extern void __posix_default_signal_handler(int signo);
+extern void __posix_hold_signal_handler(int signo);
+extern void __posix_ignore_signal_handler(int signo);
+
+typedef struct {
+	int si_signo;
+	int si_code;
+
+	int si_errno;
+
+	pid_t si_pid;
+	uid_t si_uid;
+	void *si_addr;
+	int si_status;
+
+	long si_band;
+
+	union sigval si_value;
+} siginfo_t;
+
+struct sigaction {
+	void (*sa_handler)(int);
+	sigset_t sa_mask;
+	int sa_flags;
+	void (*sa_sigaction)(int, siginfo_t *, void *);
+};
 
 /* Full POSIX set */
@@ -245,4 +224,6 @@
     sigset_t *__restrict__ oset);
 
+__C_DECLS_END;
+
 #endif /* POSIX_SIGNAL_H_ */
 
Index: uspace/lib/posix/include/posix/stdio.h
===================================================================
--- uspace/lib/posix/include/posix/stdio.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/stdio.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,12 +45,14 @@
 #include <limits.h>
 
+#define P_tmpdir "/tmp"
+
+#define L_ctermid PATH_MAX
+
+__C_DECLS_BEGIN;
+
 extern FILE *fdopen(int, const char *);
 extern int fileno(FILE *);
 
-#define P_tmpdir "/tmp"
-
 /* Identifying the Terminal */
-#undef L_ctermid
-#define L_ctermid PATH_MAX
 extern char *ctermid(char *s);
 
@@ -61,5 +63,5 @@
     FILE *__restrict__ stream);
 
-#ifdef _LARGEFILE64_SOURCE
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
 extern int fseeko64(FILE *stream, off64_t offset, int whence);
 extern off64_t ftello64(FILE *stream);
@@ -98,4 +100,6 @@
 extern char *tempnam(const char *dir, const char *pfx);
 
+__C_DECLS_END;
+
 #endif /* POSIX_STDIO_H_ */
 
Index: uspace/lib/posix/include/posix/stdlib.h
===================================================================
--- uspace/lib/posix/include/posix/stdlib.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/stdlib.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,4 +42,6 @@
 #include <stddef.h>
 
+__C_DECLS_BEGIN;
+
 /* Environment Access */
 extern int putenv(char *string);
@@ -60,4 +62,6 @@
 extern int bsd_getloadavg(double loadavg[], int nelem);
 
+__C_DECLS_END;
+
 #endif  // POSIX_STDLIB_H_
 
Index: uspace/lib/posix/include/posix/string.h
===================================================================
--- uspace/lib/posix/include/posix/string.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/string.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,11 +47,9 @@
 
 #include <libc/mem.h>
-#ifdef _HELENOS_SOURCE
-#undef _HELENOS_SOURCE
+
+#define _REALLY_WANT_STRING_H
 #include <libc/string.h>
-#define _HELENOS_SOURCE
-#else
-#include <libc/string.h>
-#endif
+
+__C_DECLS_BEGIN;
 
 /* Copying and Concatenation */
@@ -59,6 +57,4 @@
 extern char *stpncpy(char *__restrict__ dest, const char *__restrict__ src, size_t n);
 extern void *memccpy(void *__restrict__ dest, const void *__restrict__ src, int c, size_t n);
-extern char *strdup(const char *s);
-extern char *strndup(const char *s, size_t n);
 
 /* Search Functions */
@@ -71,16 +67,13 @@
 extern int strerror_r(int errnum, char *buf, size_t bufsz);
 
-/* String Length */
-extern size_t strnlen(const char *s, size_t n);
-
 /* Signal Messages */
 extern char *strsignal(int signum);
 
 /* Legacy Declarations */
-#ifndef POSIX_STRINGS_H_
 extern int ffs(int i);
 extern int strcasecmp(const char *s1, const char *s2);
 extern int strncasecmp(const char *s1, const char *s2, size_t n);
-#endif
+
+__C_DECLS_END;
 
 #endif  // POSIX_STRING_H_
Index: uspace/lib/posix/include/posix/strings.h
===================================================================
--- uspace/lib/posix/include/posix/strings.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/strings.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,14 +39,12 @@
 #include <types/common.h>
 
+__C_DECLS_BEGIN;
+
 /* Search Functions */
-#ifndef POSIX_STRING_H_
 extern int ffs(int i);
-#endif
 
 /* String/Array Comparison */
-#ifndef POSIX_STRING_H_
 extern int strcasecmp(const char *s1, const char *s2);
 extern int strncasecmp(const char *s1, const char *s2, size_t n);
-#endif
 
 /*
@@ -64,4 +62,6 @@
 extern char *rindex(const char *s, int c);
 
+__C_DECLS_END;
+
 #endif  // POSIX_STRINGS_H_
 
Index: uspace/lib/posix/include/posix/sys/mman.h
===================================================================
--- uspace/lib/posix/include/posix/sys/mman.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/sys/mman.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,7 +37,7 @@
 
 #include <sys/types.h>
-#include <abi/mm/as.h>
+#include <_bits/decls.h>
 
-#define MAP_FAILED ((void *) -1)
+#define MAP_FAILED  ((void *) -1)
 
 #define MAP_SHARED     (1 << 0)
@@ -45,14 +45,12 @@
 #define MAP_FIXED      (1 << 2)
 #define MAP_ANONYMOUS  (1 << 3)
-#define MAP_ANON MAP_ANONYMOUS
+#define MAP_ANON       MAP_ANONYMOUS
 
-#undef PROT_NONE
-#undef PROT_READ
-#undef PROT_WRITE
-#undef PROT_EXEC
-#define PROT_NONE  0
-#define PROT_READ  AS_AREA_READ
-#define PROT_WRITE AS_AREA_WRITE
-#define PROT_EXEC  AS_AREA_EXEC
+#define PROT_NONE   0
+#define PROT_READ   1
+#define PROT_WRITE  2
+#define PROT_EXEC   4
+
+__C_DECLS_BEGIN;
 
 extern void *mmap(void *start, size_t length, int prot, int flags, int fd,
@@ -60,4 +58,6 @@
 extern int munmap(void *start, size_t length);
 
+__C_DECLS_END;
+
 #endif /* POSIX_SYS_MMAN_H_ */
 
Index: uspace/lib/posix/include/posix/sys/stat.h
===================================================================
--- uspace/lib/posix/include/posix/sys/stat.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/sys/stat.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,15 +39,8 @@
 #include <sys/types.h>
 #include <time.h>
+#include <_bits/decls.h>
 
 /* values are the same as on Linux */
 
-#undef S_IFMT
-#undef S_IFSOCK
-#undef S_IFLNK
-#undef S_IFREG
-#undef S_IFBLK
-#undef S_IFDIR
-#undef S_IFCHR
-#undef S_IFIFO
 #define S_IFMT     0170000   /* all file types */
 #define S_IFSOCK   0140000   /* socket */
@@ -59,15 +52,8 @@
 #define S_IFIFO    0010000   /* FIFO */
 
-#undef S_ISUID
-#undef S_ISGID
-#undef S_ISVTX
 #define S_ISUID    0004000   /* SUID */
 #define S_ISGID    0002000   /* SGID */
 #define S_ISVTX    0001000   /* sticky */
 
-#undef S_IRWXU
-#undef S_IRUSR
-#undef S_IWUSR
-#undef S_IXUSR
 #define S_IRWXU    00700     /* owner permissions */
 #define S_IRUSR    00400
@@ -75,8 +61,4 @@
 #define S_IXUSR    00100
 
-#undef S_IRWXG
-#undef S_IRGRP
-#undef S_IWGRP
-#undef S_IXGRP
 #define S_IRWXG    00070     /* group permissions */
 #define S_IRGRP    00040
@@ -84,8 +66,4 @@
 #define S_IXGRP    00010
 
-#undef S_IRWXO
-#undef S_IROTH
-#undef S_IWOTH
-#undef S_IXOTH
 #define S_IRWXO    00007     /* other permissions */
 #define S_IROTH    00004
@@ -93,11 +71,4 @@
 #define S_IXOTH    00001
 
-#undef S_ISREG
-#undef S_ISDIR
-#undef S_ISCHR
-#undef S_ISBLK
-#undef S_ISFIFO
-#undef S_ISLNK
-#undef S_ISSOCK
 #define S_ISREG(m) ((m & S_IFREG) != 0)
 #define S_ISDIR(m) ((m & S_IFDIR) != 0)
@@ -107,4 +78,6 @@
 #define S_ISLNK(m) ((m & S_IFLNK) != 0) /* symbolic link? (Not in POSIX.1-1996.) */
 #define S_ISSOCK(m) ((m & S_IFSOCK) != 0) /* socket? (Not in POSIX.1-1996.) */
+
+__C_DECLS_BEGIN;
 
 struct stat {
@@ -131,4 +104,6 @@
 extern int mkdir(const char *path, mode_t mode);
 
+__C_DECLS_END;
+
 #endif /* POSIX_SYS_STAT_H */
 
Index: uspace/lib/posix/include/posix/sys/time.h
===================================================================
--- uspace/lib/posix/include/posix/sys/time.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/sys/time.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -35,4 +35,7 @@
 
 #include <time.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 struct timeval {
@@ -43,4 +46,6 @@
 extern int gettimeofday(struct timeval *, void *);
 
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/posix/include/posix/sys/types.h
===================================================================
--- uspace/lib/posix/include/posix/sys/types.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/sys/types.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,5 +37,10 @@
 #define POSIX_SYS_TYPES_H_
 
-#include <types/common.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <_bits/ssize_t.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 typedef unsigned int ino_t;
@@ -46,5 +51,5 @@
 typedef long blkcnt_t;
 typedef int pid_t;
-typedef sysarg_t dev_t;
+typedef unsigned long dev_t;
 typedef unsigned int mode_t;
 
@@ -55,5 +60,5 @@
 #endif
 
-#ifdef _LARGEFILE64_SOURCE
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
 typedef int64_t off64_t;
 #endif
@@ -67,4 +72,6 @@
 typedef long suseconds_t;
 
+__C_DECLS_END;
+
 #endif /* POSIX_SYS_TYPES_H_ */
 
Index: uspace/lib/posix/include/posix/sys/wait.h
===================================================================
--- uspace/lib/posix/include/posix/sys/wait.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/sys/wait.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,13 +37,12 @@
 
 #include <sys/types.h>
+#include <_bits/decls.h>
 
-#undef WIFEXITED
-#undef WEXITSTATUS
-#undef WIFSIGNALED
-#undef WTERMSIG
 #define WIFEXITED(status) __posix_wifexited(status)
 #define WEXITSTATUS(status) __posix_wexitstatus(status)
 #define WIFSIGNALED(status) __posix_wifsignaled(status)
 #define WTERMSIG(status) __posix_wtermsig(status)
+
+__C_DECLS_BEGIN;
 
 extern int __posix_wifexited(int status);
@@ -55,4 +54,6 @@
 extern pid_t waitpid(pid_t pid, int *stat_ptr, int options);
 
+__C_DECLS_END;
+
 #endif /* POSIX_SYS_WAIT_H_ */
 
Index: uspace/lib/posix/include/posix/time.h
===================================================================
--- uspace/lib/posix/include/posix/time.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/time.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -41,4 +41,10 @@
 #include <libc/time.h>
 
+#define CLOCK_REALTIME ((clockid_t) 0)
+
+#define ASCTIME_BUF_LEN  26
+
+__C_DECLS_BEGIN;
+
 #ifndef __locale_t_defined
 #define __locale_t_defined
@@ -46,12 +52,5 @@
 #endif
 
-#ifndef POSIX_SIGNAL_H_
 struct sigevent;
-#endif
-
-#undef CLOCK_REALTIME
-#define CLOCK_REALTIME ((clockid_t) 0)
-
-#define ASCTIME_BUF_LEN  26
 
 struct itimerspec {
@@ -97,4 +96,6 @@
     const struct timespec *rqtp, struct timespec *rmtp);
 
+__C_DECLS_END;
+
 #endif  // POSIX_TIME_H_
 
Index: uspace/lib/posix/include/posix/ucontext.h
===================================================================
--- uspace/lib/posix/include/posix/ucontext.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/ucontext.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,4 +37,7 @@
 
 #include <sys/types.h>
+#include <_bits/decls.h>
+
+__C_DECLS_BEGIN;
 
 typedef int sig_atomic_t;
@@ -71,4 +74,6 @@
 } ucontext_t;
 
+__C_DECLS_END;
+
 #endif
 
Index: uspace/lib/posix/include/posix/unistd.h
===================================================================
--- uspace/lib/posix/include/posix/unistd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/include/posix/unistd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,4 +47,16 @@
 #define _exit exit
 
+/* Standard Streams */
+#define STDIN_FILENO (fileno(stdin))
+#define STDOUT_FILENO (fileno(stdout))
+#define STDERR_FILENO (fileno(stderr))
+
+#define	F_OK 0 /* Test for existence. */
+#define	X_OK 1 /* Test for execute permission. */
+#define	W_OK 2 /* Test for write permission. */
+#define	R_OK 4 /* Test for read permission. */
+
+__C_DECLS_BEGIN;
+
 extern char *optarg;
 extern int optind, opterr, optopt;
@@ -86,5 +98,9 @@
 extern int dup2(int fildes, int fildes2);
 
-#ifdef _LARGEFILE64_SOURCE
+#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
+// FIXME: this should just be defined in <sys/types.h>, but for some reason
+//        build of coastline binutils on mips32 doesn't see the definition there
+typedef int64_t off64_t;
+
 extern off64_t lseek64(int fildes, off64_t offset, int whence);
 extern int ftruncate64(int fildes, off64_t length);
@@ -106,21 +122,5 @@
 #endif
 
-/* Standard Streams */
-#undef STDIN_FILENO
-#define STDIN_FILENO (fileno(stdin))
-#undef STDOUT_FILENO
-#define STDOUT_FILENO (fileno(stdout))
-#undef STDERR_FILENO
-#define STDERR_FILENO (fileno(stderr))
-
 /* File Accessibility */
-#undef F_OK
-#undef X_OK
-#undef W_OK
-#undef R_OK
-#define	F_OK 0 /* Test for existence. */
-#define	X_OK 1 /* Test for execute permission. */
-#define	W_OK 2 /* Test for write permission. */
-#define	R_OK 4 /* Test for read permission. */
 extern int access(const char *path, int amode);
 
@@ -171,4 +171,6 @@
 extern unsigned int alarm(unsigned int);
 
+__C_DECLS_END;
+
 #endif /* POSIX_UNISTD_H_ */
 
Index: uspace/lib/posix/src/internal/common.h
===================================================================
--- uspace/lib/posix/src/internal/common.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/src/internal/common.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -67,4 +67,7 @@
 }
 
+// TODO: Remove this arbitrary limit.
+#define VFS_MAX_OPEN_FILES 128
+
 extern aoff64_t posix_pos[VFS_MAX_OPEN_FILES];
 
Index: uspace/lib/posix/src/string.c
===================================================================
--- uspace/lib/posix/src/string.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/src/string.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -135,38 +135,4 @@
 
 /**
- * Duplicate a string.
- *
- * @param s String to be duplicated.
- * @return Newly allocated copy of the string.
- */
-char *strdup(const char *s)
-{
-	return strndup(s, SIZE_MAX);
-}
-
-/**
- * Duplicate a specific number of bytes from a string.
- *
- * @param s String to be duplicated.
- * @param n Maximum length of the resulting string..
- * @return Newly allocated string copy of length at most n.
- */
-char *strndup(const char *s, size_t n)
-{
-	assert(s != NULL);
-
-	size_t len = strnlen(s, n);
-	char *dup = malloc(len + 1);
-	if (dup == NULL) {
-		return NULL;
-	}
-
-	memcpy(dup, s, len);
-	dup[len] = '\0';
-
-	return dup;
-}
-
-/**
  * Scan string for a first occurence of a character.
  *
@@ -225,25 +191,4 @@
 
 	return EOK;
-}
-
-/**
- * Get limited length of the string.
- *
- * @param s String which length shall be determined.
- * @param n Maximum number of bytes that can be examined to determine length.
- * @return The lower of either string length or n limit.
- */
-size_t strnlen(const char *s, size_t n)
-{
-	assert(s != NULL);
-
-	for (size_t sz = 0; sz < n; ++sz) {
-
-		if (s[sz] == '\0') {
-			return sz;
-		}
-	}
-
-	return n;
 }
 
Index: uspace/lib/posix/src/sys/mman.c
===================================================================
--- uspace/lib/posix/src/sys/mman.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/src/sys/mman.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -39,4 +39,20 @@
 #include <unistd.h>
 
+static int _prot_to_as(int prot)
+{
+	int ret = 0;
+
+	if (prot & PROT_READ)
+		ret |= AS_AREA_READ;
+
+	if (prot & PROT_WRITE)
+		ret |= AS_AREA_WRITE;
+
+	if (prot & PROT_EXEC)
+		ret |= AS_AREA_EXEC;
+
+	return ret;
+}
+
 void *mmap(void *start, size_t length, int prot, int flags, int fd,
     off_t offset)
@@ -53,5 +69,5 @@
 		return MAP_FAILED;
 
-	return as_area_create(start, length, prot, AS_AREA_UNPAGED);
+	return as_area_create(start, length, _prot_to_as(prot), AS_AREA_UNPAGED);
 }
 
Index: uspace/lib/posix/src/time.c
===================================================================
--- uspace/lib/posix/src/time.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/src/time.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -46,5 +46,5 @@
 #include <assert.h>
 
-#include <async.h>
+#include <fibril.h>
 #include <malloc.h>
 #include <task.h>
Index: uspace/lib/posix/src/unistd.c
===================================================================
--- uspace/lib/posix/src/unistd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/posix/src/unistd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -47,4 +47,5 @@
 #include <fcntl.h>
 
+#include <fibril.h>
 #include <task.h>
 #include <stats.h>
Index: uspace/lib/sif/src/sif.c
===================================================================
--- uspace/lib/sif/src/sif.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/sif/src/sif.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -894,5 +894,5 @@
 	sif_node_t *node = NULL;
 	sif_node_t *child;
-	sif_attr_t *attr;
+	sif_attr_t *attr = NULL;
 	char *ntype;
 	int c;
Index: uspace/lib/untar/untar.c
===================================================================
--- uspace/lib/untar/untar.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/untar/untar.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -154,5 +154,5 @@
 		return rc;
 	}
-	
+
 	while (true) {
 		tar_header_raw_t header_raw;
Index: uspace/lib/usb/include/usb/request.h
===================================================================
--- uspace/lib/usb/include/usb/request.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usb/include/usb/request.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -117,5 +117,5 @@
 } __attribute__((packed)) usb_device_request_setup_packet_t;
 
-static_assert(sizeof(usb_device_request_setup_packet_t) == USB_SETUP_PACKET_SIZE);
+static_assert(sizeof(usb_device_request_setup_packet_t) == USB_SETUP_PACKET_SIZE, "");
 
 #define GET_DEVICE_DESC(size) \
Index: uspace/lib/usbdev/src/request.c
===================================================================
--- uspace/lib/usbdev/src/request.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbdev/src/request.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -45,5 +45,5 @@
 #define MAX_DATA_LENGTH ((size_t)(0xFFFF))
 
-static_assert(sizeof(usb_device_request_setup_packet_t) == 8);
+static_assert(sizeof(usb_device_request_setup_packet_t) == 8, "");
 
 /** Generic wrapper for SET requests using standard control request format.
Index: uspace/lib/usbhost/include/usb/host/hcd.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/hcd.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbhost/include/usb/host/hcd.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -38,4 +38,5 @@
 #define LIBUSBHOST_HOST_HCD_H
 
+#include <fibril.h>
 #include <ddf/driver.h>
 #include <usb/request.h>
Index: uspace/lib/usbhost/src/hcd.c
===================================================================
--- uspace/lib/usbhost/src/hcd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbhost/src/hcd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -101,5 +101,5 @@
 	hc_device_t *hcd = dev_to_hcd(dev);
 
-	const uint32_t status = IPC_GET_ARG1(*call);
+	const uint32_t status = ipc_get_arg1(call);
 	hcd->bus->ops->interrupt(hcd->bus, status);
 }
Index: uspace/lib/usbvirt/src/device.c
===================================================================
--- uspace/lib/usbvirt/src/device.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbvirt/src/device.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -66,5 +66,5 @@
 		bool processed = usbvirt_ipc_handle_call(DEV, &call);
 		if (!processed) {
-			if (!IPC_GET_IMETHOD(call)) {
+			if (!ipc_get_imethod(&call)) {
 				async_answer_0(&call, EOK);
 				return;
Index: uspace/lib/usbvirt/src/ipc_dev.c
===================================================================
--- uspace/lib/usbvirt/src/ipc_dev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbvirt/src/ipc_dev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -133,5 +133,5 @@
 static void ipc_control_write(usbvirt_device_t *dev, ipc_call_t *icall)
 {
-	size_t data_buffer_len = IPC_GET_ARG1(*icall);
+	size_t data_buffer_len = ipc_get_arg1(icall);
 	errno_t rc;
 
@@ -177,5 +177,5 @@
     usb_transfer_type_t transfer_type, ipc_call_t *icall)
 {
-	usb_endpoint_t endpoint = IPC_GET_ARG1(*icall);
+	usb_endpoint_t endpoint = ipc_get_arg1(icall);
 
 	errno_t rc;
@@ -220,5 +220,5 @@
     usb_transfer_type_t transfer_type, ipc_call_t *icall)
 {
-	usb_endpoint_t endpoint = IPC_GET_ARG1(*icall);
+	usb_endpoint_t endpoint = ipc_get_arg1(icall);
 
 	void *data_buffer = NULL;
@@ -250,5 +250,5 @@
 bool usbvirt_ipc_handle_call(usbvirt_device_t *dev, ipc_call_t *call)
 {
-	switch (IPC_GET_IMETHOD(*call)) {
+	switch (ipc_get_imethod(call)) {
 	case IPC_M_USBVIRT_GET_NAME:
 		ipc_get_name(dev, call);
Index: uspace/lib/usbvirt/src/ipc_hc.c
===================================================================
--- uspace/lib/usbvirt/src/ipc_hc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/usbvirt/src/ipc_hc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -113,5 +113,5 @@
 
 	if (data_transferred_size != NULL)
-		*data_transferred_size = IPC_GET_ARG2(data_request_call);
+		*data_transferred_size = ipc_get_arg2(&data_request_call);
 
 	return EOK;
@@ -250,5 +250,5 @@
 
 	if (act_size != NULL)
-		*act_size = IPC_GET_ARG2(data_request_call);
+		*act_size = ipc_get_arg2(&data_request_call);
 
 	return EOK;
Index: uspace/lib/virtio/virtio-pci.h
===================================================================
--- uspace/lib/virtio/virtio-pci.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/virtio/virtio-pci.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,4 +60,7 @@
 
 #define VIRTIO_FEATURES_0_31	0
+#define VIRTIO_FEATURES_32_63	1
+
+#define VIRTIO_F_VERSION_1	1
 
 /** Common configuration structure layout according to VIRTIO version 1.0 */
Index: uspace/lib/virtio/virtio.c
===================================================================
--- uspace/lib/virtio/virtio.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/lib/virtio/virtio.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,5 +50,5 @@
  *                     buffers.
  *
- * The buffers can be deallocated by virtio_net_teardown_bufs().
+ * The buffers can be deallocated by virtio_teardown_dma_bufs().
  *
  * @return  EOK on success or error code.
@@ -63,5 +63,6 @@
 	uintptr_t phys;
 	errno_t rc = dmamem_map_anonymous(buffers * size, 0,
-	    write ? AS_AREA_WRITE : AS_AREA_READ, 0, &phys, &virt);
+	    write ? AS_AREA_WRITE | AS_AREA_READ : AS_AREA_READ, 0, &phys,
+	    &virt);
 	if (rc != EOK)
 		return rc;
@@ -83,7 +84,7 @@
  *
  * @param buf[in]  Array holding the virtual addresses of the DMA buffers
- *                 previously allocated by virtio_net_setup_bufs().
- */
-extern void virtio_teardown_dma_bufs(void *buf[])
+ *                 previously allocated by virtio_setup_dma_bufs().
+ */
+void virtio_teardown_dma_bufs(void *buf[])
 {
 	if (buf[0]) {
@@ -319,5 +320,10 @@
 	uint32_t device_features = pio_read_le32(&cfg->device_feature);
 
-	ddf_msg(LVL_NOTE, "offered features %x", device_features);
+	uint32_t reserved_features = VIRTIO_F_VERSION_1;
+	pio_write_le32(&cfg->device_feature_select, VIRTIO_FEATURES_32_63);
+	uint32_t device_reserved_features = pio_read_le32(&cfg->device_feature);
+
+	ddf_msg(LVL_NOTE, "offered features %x, reserved features %x",
+	    device_features, device_reserved_features);
 
 	if (features != (features & device_features))
@@ -325,9 +331,16 @@
 	features &= device_features;
 
+	if (reserved_features != (reserved_features & device_reserved_features))
+		return ENOTSUP;
+	reserved_features &= device_reserved_features;
+
 	/* 4. Write the accepted feature flags */
 	pio_write_le32(&cfg->driver_feature_select, VIRTIO_FEATURES_0_31);
 	pio_write_le32(&cfg->driver_feature, features);
-
-	ddf_msg(LVL_NOTE, "accepted features %x", features);
+	pio_write_le32(&cfg->driver_feature_select, VIRTIO_FEATURES_32_63);
+	pio_write_le32(&cfg->driver_feature, reserved_features);
+
+	ddf_msg(LVL_NOTE, "accepted features %x, reserved features %x",
+	    features, reserved_features);
 
 	/* 5. Set FEATURES_OK */
Index: uspace/srv/audio/hound/audio_device.c
===================================================================
--- uspace/srv/audio/hound/audio_device.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/audio/hound/audio_device.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -275,5 +275,5 @@
 		async_answer_0(&call, EOK);
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case PCM_EVENT_FRAMES_PLAYED:
 			getuptime(&time1);
Index: uspace/srv/audio/hound/hound.c
===================================================================
--- uspace/srv/audio/hound/hound.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/audio/hound/hound.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -146,4 +146,5 @@
 static void hound_remove_source_internal(hound_t *hound, audio_source_t *source)
 {
+	assert(fibril_mutex_is_locked(&hound->list_guard));
 	log_verbose("Removing source '%s'.", source->name);
 	if (!list_empty(&source->connections))
Index: uspace/srv/bd/sata_bd/sata_bd.c
===================================================================
--- uspace/srv/bd/sata_bd/sata_bd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/bd/sata_bd/sata_bd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -173,5 +173,5 @@
 
 	/* Get the device service ID. */
-	dsid = IPC_GET_ARG2(*icall);
+	dsid = ipc_get_arg2(icall);
 
 	/* Determine which disk device is the client connecting to. */
Index: uspace/srv/bd/vbd/disk.c
===================================================================
--- uspace/srv/bd/vbd/disk.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/bd/vbd/disk.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -1077,5 +1077,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_bd_conn()");
 
-	svcid = IPC_GET_ARG2(*icall);
+	svcid = ipc_get_arg2(icall);
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_bd_conn() - svcid=%zu", svcid);
Index: uspace/srv/bd/vbd/vbd.c
===================================================================
--- uspace/srv/bd/vbd/vbd.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/bd/vbd/vbd.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -129,5 +129,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_disk_info_srv()");
 
-	disk_sid = IPC_GET_ARG1(*icall);
+	disk_sid = ipc_get_arg1(icall);
 	rc = vbds_disk_info(disk_sid, &dinfo);
 	if (rc != EOK) {
@@ -169,6 +169,6 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_create_srv()");
 
-	disk_sid = IPC_GET_ARG1(*icall);
-	ltype = IPC_GET_ARG2(*icall);
+	disk_sid = ipc_get_arg1(icall);
+	ltype = ipc_get_arg2(icall);
 	rc = vbds_label_create(disk_sid, ltype);
 	async_answer_0(icall, rc);
@@ -182,5 +182,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_label_delete_srv()");
 
-	disk_sid = IPC_GET_ARG1(*icall);
+	disk_sid = ipc_get_arg1(icall);
 	rc = vbds_label_delete(disk_sid);
 	async_answer_0(icall, rc);
@@ -203,5 +203,5 @@
 	}
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 
 	category_id_t *id_buf = (category_id_t *) malloc(size);
@@ -233,5 +233,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_get_info_srv()");
 
-	part = IPC_GET_ARG1(*icall);
+	part = ipc_get_arg1(icall);
 	rc = vbds_part_get_info(part, &pinfo);
 	if (rc != EOK) {
@@ -274,5 +274,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_create_srv()");
 
-	disk_sid = IPC_GET_ARG1(*icall);
+	disk_sid = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -313,5 +313,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_part_delete_srv()");
 
-	part = IPC_GET_ARG1(*icall);
+	part = ipc_get_arg1(icall);
 	rc = vbds_part_delete(part);
 	async_answer_0(icall, rc);
@@ -327,6 +327,6 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_suggest_ptype_srv()");
 
-	disk_sid = IPC_GET_ARG1(*icall);
-	pcnt = IPC_GET_ARG2(*icall);
+	disk_sid = ipc_get_arg1(icall);
+	pcnt = ipc_get_arg2(icall);
 
 	rc = vbds_suggest_ptype(disk_sid, pcnt, &ptype);
@@ -370,5 +370,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
@@ -418,5 +418,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vbds_client_conn()");
 
-	sid = (service_id_t) IPC_GET_ARG2(*icall);
+	sid = (service_id_t) ipc_get_arg2(icall);
 
 	if (sid == ctl_sid)
Index: uspace/srv/clipboard/clipboard.c
===================================================================
--- uspace/srv/clipboard/clipboard.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/clipboard/clipboard.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -53,5 +53,5 @@
 	size_t size;
 
-	switch (IPC_GET_ARG1(*req)) {
+	switch (ipc_get_arg1(req)) {
 	case CLIPBOARD_TAG_NONE:
 		fibril_mutex_lock(&clip_mtx);
@@ -99,5 +99,5 @@
 
 	/* Check for clipboard data tag compatibility */
-	switch (IPC_GET_ARG1(*req)) {
+	switch (ipc_get_arg1(req)) {
 	case CLIPBOARD_TAG_DATA:
 		if (!async_data_read_receive(&call, &size)) {
@@ -161,10 +161,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case CLIPBOARD_PUT_DATA:
 			clip_put_data(&call);
Index: uspace/srv/devman/client_conn.c
===================================================================
--- uspace/srv/devman/client_conn.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/devman/client_conn.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -102,6 +102,6 @@
 static void devman_fun_get_match_id(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
-	size_t index = IPC_GET_ARG2(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
+	size_t index = ipc_get_arg2(icall);
 	void *buffer = NULL;
 
@@ -165,5 +165,5 @@
 static void devman_fun_get_name(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
 
 	fun_node_t *fun = find_fun_node(&device_tree, handle);
@@ -218,5 +218,5 @@
 static void devman_fun_get_driver_name(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
 
 	fun_node_t *fun = find_fun_node(&device_tree, handle);
@@ -283,5 +283,5 @@
 static void devman_fun_get_path(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
 
 	fun_node_t *fun = find_fun_node(&device_tree, handle);
@@ -340,5 +340,5 @@
 	fibril_rwlock_read_lock(&device_tree.rwlock);
 
-	dev = find_dev_node_no_lock(&device_tree, IPC_GET_ARG1(*icall));
+	dev = find_dev_node_no_lock(&device_tree, ipc_get_arg1(icall));
 	if (dev == NULL || dev->state == DEVICE_REMOVED) {
 		fibril_rwlock_read_unlock(&device_tree.rwlock);
@@ -374,5 +374,5 @@
 
 	dev_node_t *dev = find_dev_node_no_lock(&device_tree,
-	    IPC_GET_ARG1(*icall));
+	    ipc_get_arg1(icall));
 	if (dev == NULL || dev->state == DEVICE_REMOVED) {
 		fibril_rwlock_read_unlock(&device_tree.rwlock);
@@ -413,5 +413,5 @@
 	fibril_rwlock_read_lock(&device_tree.rwlock);
 
-	fun = find_fun_node_no_lock(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_fun_node_no_lock(&device_tree, ipc_get_arg1(icall));
 	if (fun == NULL || fun->state == FUN_REMOVED) {
 		fibril_rwlock_read_unlock(&device_tree.rwlock);
@@ -442,5 +442,5 @@
 	errno_t rc;
 
-	fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
 	if (fun == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -467,5 +467,5 @@
 	errno_t rc;
 
-	fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
 	if (fun == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -484,5 +484,5 @@
 	fun_node_t *fun;
 
-	fun = find_loc_tree_function(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_loc_tree_function(&device_tree, ipc_get_arg1(icall));
 
 	if (fun == NULL) {
@@ -550,5 +550,5 @@
 	}
 
-	driver_t *drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
+	driver_t *drv = driver_find(&drivers_list, ipc_get_arg1(icall));
 	if (drv == NULL) {
 		async_answer_0(&call, ENOENT);
@@ -604,6 +604,6 @@
 static void devman_driver_get_match_id(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
-	size_t index = IPC_GET_ARG2(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
+	size_t index = ipc_get_arg2(icall);
 
 	driver_t *drv = driver_find(&drivers_list, handle);
@@ -655,5 +655,5 @@
 static void devman_driver_get_name(ipc_call_t *icall)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*icall);
+	devman_handle_t handle = ipc_get_arg1(icall);
 
 	driver_t *drv = driver_find(&drivers_list, handle);
@@ -697,5 +697,5 @@
 	driver_t *drv;
 
-	drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
+	drv = driver_find(&drivers_list, ipc_get_arg1(icall));
 	if (drv == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -712,5 +712,5 @@
 	errno_t rc;
 
-	drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
+	drv = driver_find(&drivers_list, ipc_get_arg1(icall));
 	if (drv == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -731,5 +731,5 @@
 	errno_t rc;
 
-	drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
+	drv = driver_find(&drivers_list, ipc_get_arg1(icall));
 	if (drv == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -754,10 +754,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case DEVMAN_DEVICE_GET_HANDLE:
 			devman_function_get_handle(&call);
Index: uspace/srv/devman/devtree.c
===================================================================
--- uspace/srv/devman/devtree.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/devman/devtree.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -42,8 +42,8 @@
 /* hash table operations */
 
-static inline size_t handle_key_hash(void *key)
-{
-	devman_handle_t handle = *(devman_handle_t *)key;
-	return handle;
+static inline size_t handle_key_hash(const void *key)
+{
+	const devman_handle_t *handle = key;
+	return *handle;
 }
 
@@ -60,22 +60,22 @@
 }
 
-static bool devman_devices_key_equal(void *key, const ht_link_t *item)
-{
-	devman_handle_t handle = *(devman_handle_t *)key;
+static bool devman_devices_key_equal(const void *key, const ht_link_t *item)
+{
+	const devman_handle_t *handle = key;
 	dev_node_t *dev = hash_table_get_inst(item, dev_node_t, devman_dev);
-	return dev->handle == handle;
-}
-
-static bool devman_functions_key_equal(void *key, const ht_link_t *item)
-{
-	devman_handle_t handle = *(devman_handle_t *)key;
+	return dev->handle == *handle;
+}
+
+static bool devman_functions_key_equal(const void *key, const ht_link_t *item)
+{
+	const devman_handle_t *handle = key;
 	fun_node_t *fun = hash_table_get_inst(item, fun_node_t, devman_fun);
-	return fun->handle == handle;
-}
-
-static inline size_t service_id_key_hash(void *key)
-{
-	service_id_t service_id = *(service_id_t *)key;
-	return service_id;
+	return fun->handle == *handle;
+}
+
+static inline size_t service_id_key_hash(const void *key)
+{
+	const service_id_t *service_id = key;
+	return *service_id;
 }
 
@@ -86,9 +86,9 @@
 }
 
-static bool loc_functions_key_equal(void *key, const ht_link_t *item)
-{
-	service_id_t service_id = *(service_id_t *)key;
+static bool loc_functions_key_equal(const void *key, const ht_link_t *item)
+{
+	const service_id_t *service_id = key;
 	fun_node_t *fun = hash_table_get_inst(item, fun_node_t, loc_fun);
-	return fun->service_id == service_id;
+	return fun->service_id == *service_id;
 }
 
Index: uspace/srv/devman/drv_conn.c
===================================================================
--- uspace/srv/devman/drv_conn.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/devman/drv_conn.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -169,5 +169,5 @@
 
 	async_get_call(&call);
-	if (DEVMAN_ADD_MATCH_ID != IPC_GET_IMETHOD(call)) {
+	if (DEVMAN_ADD_MATCH_ID != ipc_get_imethod(&call)) {
 		log_msg(LOG_DEFAULT, LVL_ERROR,
 		    "Invalid protocol when trying to receive match id.");
@@ -185,5 +185,5 @@
 	async_answer_0(&call, EOK);
 
-	match_id->score = IPC_GET_ARG1(call);
+	match_id->score = ipc_get_arg1(&call);
 
 	char *match_id_str;
@@ -230,7 +230,7 @@
 static void devman_add_function(ipc_call_t *call)
 {
-	fun_type_t ftype = (fun_type_t) IPC_GET_ARG1(*call);
-	devman_handle_t dev_handle = IPC_GET_ARG2(*call);
-	sysarg_t match_count = IPC_GET_ARG3(*call);
+	fun_type_t ftype = (fun_type_t) ipc_get_arg1(call);
+	devman_handle_t dev_handle = ipc_get_arg2(call);
+	sysarg_t match_count = ipc_get_arg3(call);
 	dev_tree_t *tree = &device_tree;
 
@@ -330,5 +330,5 @@
 static void devman_add_function_to_cat(ipc_call_t *call)
 {
-	devman_handle_t handle = IPC_GET_ARG1(*call);
+	devman_handle_t handle = ipc_get_arg1(call);
 	category_id_t cat_id;
 	errno_t rc;
@@ -385,5 +385,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "devman_drv_fun_online()");
 
-	fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
 	if (fun == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -425,5 +425,5 @@
 	errno_t rc;
 
-	fun = find_fun_node(&device_tree, IPC_GET_ARG1(*icall));
+	fun = find_fun_node(&device_tree, ipc_get_arg1(icall));
 	if (fun == NULL) {
 		async_answer_0(icall, ENOENT);
@@ -458,5 +458,5 @@
 static void devman_remove_function(ipc_call_t *call)
 {
-	devman_handle_t fun_handle = IPC_GET_ARG1(*call);
+	devman_handle_t fun_handle = ipc_get_arg1(call);
 	dev_tree_t *tree = &device_tree;
 	errno_t rc;
@@ -602,10 +602,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		if (IPC_GET_IMETHOD(call) != DEVMAN_DRIVER_REGISTER) {
+		if (ipc_get_imethod(&call) != DEVMAN_DRIVER_REGISTER) {
 			fibril_mutex_lock(&client->mutex);
 			driver = client->driver;
@@ -618,5 +618,5 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case DEVMAN_DRIVER_REGISTER:
 			fibril_mutex_lock(&client->mutex);
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/devman/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -67,5 +67,5 @@
 static void devman_connection_device(ipc_call_t *icall, void *arg)
 {
-	devman_handle_t handle = IPC_GET_ARG2(*icall);
+	devman_handle_t handle = ipc_get_arg2(icall);
 	dev_node_t *dev = NULL;
 
@@ -136,5 +136,5 @@
 
 	async_exch_t *exch = async_exchange_begin(driver->sess);
-	async_forward_fast(icall, exch, INTERFACE_DDF_CLIENT, handle, 0, IPC_FF_NONE);
+	async_forward_1(icall, exch, INTERFACE_DDF_CLIENT, handle, IPC_FF_NONE);
 	async_exchange_end(exch);
 
@@ -149,5 +149,5 @@
 static void devman_connection_parent(ipc_call_t *icall, void *arg)
 {
-	devman_handle_t handle = IPC_GET_ARG2(*icall);
+	devman_handle_t handle = ipc_get_arg2(icall);
 	dev_node_t *dev = NULL;
 
@@ -215,5 +215,5 @@
 
 	async_exch_t *exch = async_exchange_begin(driver->sess);
-	async_forward_fast(icall, exch, INTERFACE_DDF_DRIVER, fun_handle, 0, IPC_FF_NONE);
+	async_forward_1(icall, exch, INTERFACE_DDF_DRIVER, fun_handle, IPC_FF_NONE);
 	async_exchange_end(exch);
 
@@ -228,6 +228,6 @@
 static void devman_forward(ipc_call_t *icall, void *arg)
 {
-	iface_t iface = IPC_GET_ARG1(*icall);
-	service_id_t service_id = IPC_GET_ARG2(*icall);
+	iface_t iface = ipc_get_arg1(icall);
+	service_id_t service_id = ipc_get_arg2(icall);
 
 	fun_node_t *fun = find_loc_tree_function(&device_tree, service_id);
@@ -250,5 +250,5 @@
 
 	async_exch_t *exch = async_exchange_begin(driver->sess);
-	async_forward_fast(icall, exch, iface, handle, 0, IPC_FF_NONE);
+	async_forward_1(icall, exch, iface, handle, IPC_FF_NONE);
 	async_exchange_end(exch);
 
Index: uspace/srv/fs/cdfs/cdfs_ops.c
===================================================================
--- uspace/srv/fs/cdfs/cdfs_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/cdfs/cdfs_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -285,7 +285,7 @@
 } ht_key_t;
 
-static size_t nodes_key_hash(void *k)
-{
-	ht_key_t *key = (ht_key_t *)k;
+static size_t nodes_key_hash(const void *k)
+{
+	const ht_key_t *key = k;
 	return hash_combine(key->service_id, key->index);
 }
@@ -297,8 +297,8 @@
 }
 
-static bool nodes_key_equal(void *k, const ht_link_t *item)
+static bool nodes_key_equal(const void *k, const ht_link_t *item)
 {
 	cdfs_node_t *node = hash_table_get_inst(item, cdfs_node_t, nh_link);
-	ht_key_t *key = (ht_key_t *)k;
+	const ht_key_t *key = k;
 
 	return key->service_id == node->fs->service_id && key->index == node->index;
Index: uspace/srv/fs/exfat/exfat_idx.c
===================================================================
--- uspace/srv/fs/exfat/exfat_idx.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/exfat/exfat_idx.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -117,7 +117,7 @@
 } pos_key_t;
 
-static inline size_t pos_key_hash(void *key)
-{
-	pos_key_t *pos = (pos_key_t *)key;
+static inline size_t pos_key_hash(const void *key)
+{
+	const pos_key_t *pos = key;
 
 	size_t hash = 0;
@@ -139,7 +139,7 @@
 }
 
-static bool pos_key_equal(void *key, const ht_link_t *item)
-{
-	pos_key_t *pos = (pos_key_t *)key;
+static bool pos_key_equal(const void *key, const ht_link_t *item)
+{
+	const pos_key_t *pos = key;
 	exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uph_link);
 
@@ -168,7 +168,7 @@
 } idx_key_t;
 
-static size_t idx_key_hash(void *key_arg)
-{
-	idx_key_t *key = (idx_key_t *)key_arg;
+static size_t idx_key_hash(const void *key_arg)
+{
+	const idx_key_t *key = key_arg;
 	return hash_combine(key->service_id, key->index);
 }
@@ -180,8 +180,8 @@
 }
 
-static bool idx_key_equal(void *key_arg, const ht_link_t *item)
+static bool idx_key_equal(const void *key_arg, const ht_link_t *item)
 {
 	exfat_idx_t *fidx = hash_table_get_inst(item, exfat_idx_t, uih_link);
-	idx_key_t *key = (idx_key_t *)key_arg;
+	const idx_key_t *key = key_arg;
 
 	return key->index == fidx->index && key->service_id == fidx->service_id;
Index: uspace/srv/fs/fat/fat_idx.c
===================================================================
--- uspace/srv/fs/fat/fat_idx.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/fat/fat_idx.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -117,7 +117,7 @@
 } pos_key_t;
 
-static inline size_t pos_key_hash(void *key)
-{
-	pos_key_t *pos = (pos_key_t *)key;
+static inline size_t pos_key_hash(const void *key)
+{
+	const pos_key_t *pos = key;
 
 	size_t hash = 0;
@@ -139,7 +139,7 @@
 }
 
-static bool pos_key_equal(void *key, const ht_link_t *item)
-{
-	pos_key_t *pos = (pos_key_t *)key;
+static bool pos_key_equal(const void *key, const ht_link_t *item)
+{
+	const pos_key_t *pos = key;
 	fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uph_link);
 
@@ -168,7 +168,7 @@
 } idx_key_t;
 
-static size_t idx_key_hash(void *key_arg)
-{
-	idx_key_t *key = (idx_key_t *)key_arg;
+static size_t idx_key_hash(const void *key_arg)
+{
+	const idx_key_t *key = key_arg;
 	return hash_combine(key->service_id, key->index);
 }
@@ -180,8 +180,8 @@
 }
 
-static bool idx_key_equal(void *key_arg, const ht_link_t *item)
+static bool idx_key_equal(const void *key_arg, const ht_link_t *item)
 {
 	fat_idx_t *fidx = hash_table_get_inst(item, fat_idx_t, uih_link);
-	idx_key_t *key = (idx_key_t *)key_arg;
+	const idx_key_t *key = key_arg;
 
 	return key->index == fidx->index && key->service_id == fidx->service_id;
Index: uspace/srv/fs/locfs/locfs_ops.c
===================================================================
--- uspace/srv/fs/locfs/locfs_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/locfs/locfs_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -71,7 +71,8 @@
 /* Implementation of hash table interface for the nodes hash table. */
 
-static size_t services_key_hash(void *key)
-{
-	return *(service_id_t *)key;
+static size_t services_key_hash(const void *key)
+{
+	const service_id_t *k = key;
+	return *k;
 }
 
@@ -82,8 +83,9 @@
 }
 
-static bool services_key_equal(void *key, const ht_link_t *item)
-{
+static bool services_key_equal(const void *key, const ht_link_t *item)
+{
+	const service_id_t *k = key;
 	service_t *dev = hash_table_get_inst(item, service_t, link);
-	return (dev->service_id == *(service_id_t *)key);
+	return (dev->service_id == *k);
 }
 
@@ -583,5 +585,5 @@
 
 		/* Forward the IPC_M_DATA_READ request to the driver */
-		async_forward_fast(&call, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+		async_forward_0(&call, exch, 0, IPC_FF_ROUTE_FROM_ME);
 
 		async_exchange_end(exch);
@@ -597,5 +599,5 @@
 			rc = ENOTSUP;
 
-		*rbytes = IPC_GET_ARG1(answer);
+		*rbytes = ipc_get_arg1(&answer);
 		return rc;
 	}
@@ -647,5 +649,5 @@
 
 		/* Forward the IPC_M_DATA_WRITE request to the driver */
-		async_forward_fast(&call, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
+		async_forward_0(&call, exch, 0, IPC_FF_ROUTE_FROM_ME);
 
 		async_exchange_end(exch);
@@ -661,5 +663,5 @@
 			rc = ENOTSUP;
 
-		*wbytes = IPC_GET_ARG1(answer);
+		*wbytes = ipc_get_arg1(&answer);
 		*nsize = 0;
 		return rc;
Index: uspace/srv/fs/mfs/mfs_ops.c
===================================================================
--- uspace/srv/fs/mfs/mfs_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/mfs/mfs_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -100,7 +100,7 @@
 
 static size_t
-open_nodes_key_hash(void *key)
-{
-	node_key_t *node_key = (node_key_t *)key;
+open_nodes_key_hash(const void *key)
+{
+	const node_key_t *node_key = key;
 	return hash_combine(node_key->service_id, node_key->index);
 }
@@ -114,7 +114,7 @@
 
 static bool
-open_nodes_key_equal(void *key, const ht_link_t *item)
-{
-	node_key_t *node_key = (node_key_t *)key;
+open_nodes_key_equal(const void *key, const ht_link_t *item)
+{
+	const node_key_t *node_key = key;
 	struct mfs_node *mnode = hash_table_get_inst(item, struct mfs_node, link);
 
Index: uspace/srv/fs/tmpfs/tmpfs_ops.c
===================================================================
--- uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/tmpfs/tmpfs_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -147,7 +147,7 @@
 } node_key_t;
 
-static size_t nodes_key_hash(void *k)
-{
-	node_key_t *key = (node_key_t *)k;
+static size_t nodes_key_hash(const void *k)
+{
+	const node_key_t *key = k;
 	return hash_combine(key->service_id, key->index);
 }
@@ -159,8 +159,8 @@
 }
 
-static bool nodes_key_equal(void *key_arg, const ht_link_t *item)
+static bool nodes_key_equal(const void *key_arg, const ht_link_t *item)
 {
 	tmpfs_node_t *node = hash_table_get_inst(item, tmpfs_node_t, nh_link);
-	node_key_t *key = (node_key_t *)key_arg;
+	const node_key_t *key = key_arg;
 
 	return key->service_id == node->service_id && key->index == node->index;
Index: uspace/srv/fs/udf/udf.h
===================================================================
--- uspace/srv/fs/udf/udf.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -70,5 +70,5 @@
 	uint32_t access_type;
 	uint32_t start;
-	uint32_t lenght;
+	uint32_t length;
 } udf_partition_t;
 
@@ -91,5 +91,5 @@
 	udf_unallocated_space_descriptor_t *uasd;
 	uint64_t uaspace_start;
-	uint64_t uaspace_lenght;
+	uint64_t uaspace_length;
 	uint8_t space_type;
 } udf_instance_t;
Index: uspace/srv/fs/udf/udf_file.c
===================================================================
--- uspace/srv/fs/udf/udf_file.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_file.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -114,5 +114,5 @@
 			if ((node->index >= node->instance->partitions[i].start) &&
 			    (node->index < node->instance->partitions[i].start +
-			    node->instance->partitions[i].lenght)) {
+			    node->instance->partitions[i].length)) {
 				if (node->instance->partitions[i].start >= min_start) {
 					min_start = node->instance->partitions[i].start;
@@ -258,9 +258,9 @@
 			    (udf_file_entry_descriptor_t *) block->data;
 			uint16_t icb_flag = FLE16(file->icbtag.flags) & UDF_ICBFLAG_MASK;
-			node->data_size = FLE64(file->info_lenght);
+			node->data_size = FLE64(file->info_length);
 			node->type = (file->icbtag.file_type == UDF_ICBTYPE_DIR) ? NODE_DIR : NODE_FILE;
 
 			rc = udf_read_allocation_sequence(node, (uint8_t *) file, icb_flag,
-			    FLE32(file->ea_lenght) + UDF_FE_OFFSET, FLE32(file->ad_lenght));
+			    FLE32(file->ea_length) + UDF_FE_OFFSET, FLE32(file->ad_length));
 			block_put(block);
 			return rc;
@@ -272,9 +272,9 @@
 			    (udf_extended_file_entry_descriptor_t *) block->data;
 			icb_flag = FLE16(efile->icbtag.flags) & UDF_ICBFLAG_MASK;
-			node->data_size = FLE64(efile->info_lenght);
+			node->data_size = FLE64(efile->info_length);
 			node->type = (efile->icbtag.file_type == UDF_ICBTYPE_DIR) ? NODE_DIR : NODE_FILE;
 
 			rc = udf_read_allocation_sequence(node, (uint8_t *) efile, icb_flag,
-			    FLE32(efile->ea_lenght) + UDF_EFE_OFFSET, FLE32(efile->ad_lenght));
+			    FLE32(efile->ea_length) + UDF_EFE_OFFSET, FLE32(efile->ad_length));
 			block_put(block);
 			return rc;
@@ -338,14 +338,14 @@
 
 		/* According to ECMA 167 4/14.4.9 */
-		size_t padding = 4 * (((*fid)->lenght_file_id +
-		    FLE16((*fid)->lenght_iu) + 38 + 3) / 4) -
-		    ((*fid)->lenght_file_id + FLE16((*fid)->lenght_iu) + 38);
-		size_t size_fid = (*fid)->lenght_file_id +
-		    FLE16((*fid)->lenght_iu) + padding + 38;
+		size_t padding = 4 * (((*fid)->length_file_id +
+		    FLE16((*fid)->length_iu) + 38 + 3) / 4) -
+		    ((*fid)->length_file_id + FLE16((*fid)->length_iu) + 38);
+		size_t size_fid = (*fid)->length_file_id +
+		    FLE16((*fid)->length_iu) + padding + 38;
 
 		fid_sum += size_fid;
 
 		/* aAcording to ECMA 167 4/8.6 */
-		if (((*fid)->lenght_file_id != 0) &&
+		if (((*fid)->length_file_id != 0) &&
 		    (((*fid)->file_characteristics & 4) == 0)) {
 			n++;
@@ -516,9 +516,9 @@
 
 			/* According to ECMA 167 4/14.4.9 */
-			size_t padding = 4 * (((*fid)->lenght_file_id +
-			    FLE16((*fid)->lenght_iu) + 38 + 3) / 4) -
-			    ((*fid)->lenght_file_id + FLE16((*fid)->lenght_iu) + 38);
-			size_t size_fid = (*fid)->lenght_file_id +
-			    FLE16((*fid)->lenght_iu) + padding + 38;
+			size_t padding = 4 * (((*fid)->length_file_id +
+			    FLE16((*fid)->length_iu) + 38 + 3) / 4) -
+			    ((*fid)->length_file_id + FLE16((*fid)->length_iu) + 38);
+			size_t size_fid = (*fid)->length_file_id +
+			    FLE16((*fid)->length_iu) + padding + 38;
 			if (buf_flag)
 				fid_sum += size_fid - *len;
@@ -527,5 +527,5 @@
 
 			/* According to ECMA 167 4/8.6 */
-			if (((*fid)->lenght_file_id != 0) &&
+			if (((*fid)->length_file_id != 0) &&
 			    (((*fid)->file_characteristics & 4) == 0)) {
 				(*n)++;
Index: uspace/srv/fs/udf/udf_file.h
===================================================================
--- uspace/srv/fs/udf/udf_file.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_file.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -99,7 +99,7 @@
 	uint16_t file_version_number;
 	uint8_t file_characteristics;
-	uint8_t lenght_file_id;
+	uint8_t length_file_id;
 	udf_long_ad_t icb;
-	uint16_t lenght_iu;
+	uint16_t length_iu;
 	uint8_t implementation_use[0];
 	udf_dstring file_id[0];
@@ -128,6 +128,6 @@
 	uint8_t record_format;
 	uint8_t record_display_attributes;
-	uint32_t record_lenght;
-	uint64_t info_lenght;
+	uint32_t record_length;
+	uint64_t info_length;
 	uint64_t lblocks_recorded;
 	udf_timestamp_t access_data_and_time;
@@ -138,6 +138,6 @@
 	udf_regid_t implementation_id;
 	uint64_t unique_id;
-	uint32_t ea_lenght;
-	uint32_t ad_lenght;
+	uint32_t ea_length;
+	uint32_t ad_length;
 	uint8_t extended_attributes [0];
 	uint8_t allocation_descriptors[0];
@@ -154,6 +154,6 @@
 	uint8_t record_format;
 	uint8_t record_display_attributes;
-	uint32_t record_lenght;
-	uint64_t info_lenght;
+	uint32_t record_length;
+	uint64_t info_length;
 	uint64_t object_size;
 	uint64_t lblocks_recorded;
@@ -166,6 +166,6 @@
 	udf_regid_t implementation_id;
 	uint64_t unique_id;
-	uint32_t ea_lenght;
-	uint32_t ad_lenght;
+	uint32_t ea_length;
+	uint32_t ad_length;
 	uint8_t extended_attributes [0];
 	uint8_t allocation_descriptors[0];
@@ -182,5 +182,5 @@
 	udf_descriptor_tag_t tag;
 	udf_icbtag_t icbtag;
-	uint32_t ad_lenght;
+	uint32_t ad_length;
 	uint8_t allocation_descriptors[0];
 } __attribute__((packed)) udf_unallocated_space_entry_descriptor_t;
Index: uspace/srv/fs/udf/udf_idx.c
===================================================================
--- uspace/srv/fs/udf/udf_idx.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_idx.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -63,13 +63,13 @@
 }
 
-static size_t udf_idx_key_hash(void *k)
-{
-	udf_ht_key_t *key = (udf_ht_key_t *) k;
+static size_t udf_idx_key_hash(const void *k)
+{
+	const udf_ht_key_t *key = k;
 	return hash_combine(key->service_id, key->index);
 }
 
-static bool udf_idx_key_equal(void *k, const ht_link_t *item)
-{
-	udf_ht_key_t *key = (udf_ht_key_t *) k;
+static bool udf_idx_key_equal(const void *k, const ht_link_t *item)
+{
+	const udf_ht_key_t *key = k;
 	udf_node_t *node = hash_table_get_inst(item, udf_node_t, link);
 
Index: uspace/srv/fs/udf/udf_ops.c
===================================================================
--- uspace/srv/fs/udf/udf_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,7 +62,4 @@
 #include "udf_osta.h"
 
-/** Mutex protecting the list of cached free nodes. */
-static FIBRIL_MUTEX_INITIALIZE(ffn_mutex);
-
 /** List of cached free nodes. */
 static LIST_INITIALIZE(ffn_list);
@@ -128,6 +125,6 @@
 
 		udf_to_unix_name(name, MAX_FILE_NAME_LEN,
-		    (char *) fid->implementation_use + FLE16(fid->lenght_iu),
-		    fid->lenght_file_id, &UDF_NODE(pfn)->instance->charset);
+		    (char *) fid->implementation_use + FLE16(fid->length_iu),
+		    fid->length_file_id, &UDF_NODE(pfn)->instance->charset);
 
 		if (str_casecmp(name, component) == 0) {
@@ -502,6 +499,6 @@
 
 			udf_to_unix_name(name, MAX_FILE_NAME_LEN,
-			    (char *) fid->implementation_use + FLE16(fid->lenght_iu),
-			    fid->lenght_file_id, &node->instance->charset);
+			    (char *) fid->implementation_use + FLE16(fid->length_iu),
+			    fid->length_file_id, &node->instance->charset);
 
 			async_data_read_finalize(&call, name, str_size(name) + 1);
Index: uspace/srv/fs/udf/udf_volume.c
===================================================================
--- uspace/srv/fs/udf/udf_volume.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_volume.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -386,9 +386,9 @@
 		udf_file_entry_descriptor_t *fed =
 		    (udf_file_entry_descriptor_t *) block->data;
-		uint32_t start_alloc = FLE32(fed->ea_lenght) + UDF_FE_OFFSET;
+		uint32_t start_alloc = FLE32(fed->ea_length) + UDF_FE_OFFSET;
 		udf_short_ad_t *short_d =
 		    (udf_short_ad_t *) ((uint8_t *) fed + start_alloc);
 		instance->partitions[id].start = FLE32(short_d->position);
-		instance->partitions[id].lenght = FLE32(short_d->length);
+		instance->partitions[id].length = FLE32(short_d->length);
 		break;
 
@@ -398,8 +398,8 @@
 		udf_extended_file_entry_descriptor_t *efed =
 		    (udf_extended_file_entry_descriptor_t *) block->data;
-		start_alloc = FLE32(efed->ea_lenght) + UDF_EFE_OFFSET;
+		start_alloc = FLE32(efed->ea_length) + UDF_EFE_OFFSET;
 		short_d = (udf_short_ad_t *) ((uint8_t *) efed + start_alloc);
 		instance->partitions[id].start = FLE32(short_d->position);
-		instance->partitions[id].lenght = FLE32(short_d->length);
+		instance->partitions[id].length = FLE32(short_d->length);
 		break;
 	}
@@ -503,5 +503,5 @@
 				instance->partitions[j].access_type =
 				    FLE32(pd[pd_num].access_type);
-				instance->partitions[j].lenght =
+				instance->partitions[j].length =
 				    FLE32(pd[pd_num].length);
 				instance->partitions[j].number =
@@ -518,5 +518,5 @@
 
 				instance->volumes[i].partition_cnt++;
-				idx += pm1->partition_map_lenght;
+				idx += pm1->partition_map_length;
 				continue;
 			}
@@ -586,5 +586,5 @@
 			    "found and skipped", i, pm->partition_map_type);
 
-			idx += pm->partition_map_lenght;
+			idx += pm->partition_map_length;
 		}
 	}
@@ -710,5 +710,5 @@
 				    FLE32(vol->partition.starting_location) +
 				    FLE32(phd->unallocated_space_table.position);
-				instance->uaspace_lenght =
+				instance->uaspace_length =
 				    FLE32(phd->unallocated_space_table.length);
 			}
@@ -724,5 +724,5 @@
 				    FLE32(vol->partition.starting_location) +
 				    FLE32(phd->unallocated_space_bitmap.position);
-				instance->uaspace_lenght =
+				instance->uaspace_length =
 				    FLE32(phd->unallocated_space_bitmap.length);
 			}
@@ -773,5 +773,5 @@
 			    sizeof(udf_extent_t)), sizeof(udf_common_descriptor_t));
 			instance->uaspace_start = pos;
-			instance->uaspace_lenght = sct;
+			instance->uaspace_length = sct;
 			instance->uasd = (udf_unallocated_space_descriptor_t *)
 			    malloc(sct * instance->sector_size);
Index: uspace/srv/fs/udf/udf_volume.h
===================================================================
--- uspace/srv/fs/udf/udf_volume.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/fs/udf/udf_volume.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -49,5 +49,5 @@
 #define UDF_TAG_LVID  0x0009  /* Logical Volume Integrity Descriptor */
 
-/* Start adress of Anchor Volume Descriptor */
+/* Start address of Anchor Volume Descriptor */
 #define UDF_AVDP_SECTOR  256
 
@@ -165,10 +165,10 @@
 typedef struct udf_general_type {
 	uint8_t partition_map_type;
-	uint8_t partition_map_lenght;
+	uint8_t partition_map_length;
 } __attribute__((packed)) udf_general_type_t;
 
 typedef struct udf_type1_partition_map {
 	uint8_t partition_map_type;
-	uint8_t partition_map_lenght;
+	uint8_t partition_map_length;
 	uint16_t volume_sequence_number;
 	uint16_t partition_number;
Index: uspace/srv/hid/compositor/compositor.c
===================================================================
--- uspace/srv/hid/compositor/compositor.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/compositor/compositor.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -224,4 +224,5 @@
 
 	link_initialize(&win->link);
+	/* One initial reference will be for being in the window list */
 	refcount_init(&win->ref_cnt);
 	prodcons_initialize(&win->queue);
@@ -241,5 +242,8 @@
 static void window_destroy(window_t *win)
 {
-	if (!win || !refcount_down(&win->ref_cnt))
+	if (win == NULL)
+		return;
+
+	if (!refcount_down(&win->ref_cnt))
 		return;
 
@@ -630,8 +634,8 @@
 static void comp_window_damage(window_t *win, ipc_call_t *icall)
 {
-	double x = IPC_GET_ARG1(*icall);
-	double y = IPC_GET_ARG2(*icall);
-	double width = IPC_GET_ARG3(*icall);
-	double height = IPC_GET_ARG4(*icall);
+	double x = ipc_get_arg1(icall);
+	double y = ipc_get_arg2(icall);
+	double width = ipc_get_arg3(icall);
+	double height = ipc_get_arg4(icall);
 
 	if ((width == 0) || (height == 0)) {
@@ -651,6 +655,6 @@
 static void comp_window_grab(window_t *win, ipc_call_t *icall)
 {
-	sysarg_t pos_id = IPC_GET_ARG1(*icall);
-	sysarg_t grab_flags = IPC_GET_ARG2(*icall);
+	sysarg_t pos_id = ipc_get_arg1(icall);
+	sysarg_t grab_flags = ipc_get_arg2(icall);
 
 	/*
@@ -728,6 +732,6 @@
 
 	/* Create new surface for the resized window. */
-	surface_t *new_surface = surface_create(IPC_GET_ARG3(*icall),
-	    IPC_GET_ARG4(*icall), new_cell_storage, SURFACE_FLAG_SHARED);
+	surface_t *new_surface = surface_create(ipc_get_arg3(icall),
+	    ipc_get_arg4(icall), new_cell_storage, SURFACE_FLAG_SHARED);
 	if (!new_surface) {
 		as_area_destroy(new_cell_storage);
@@ -736,8 +740,8 @@
 	}
 
-	sysarg_t offset_x = IPC_GET_ARG1(*icall);
-	sysarg_t offset_y = IPC_GET_ARG2(*icall);
+	sysarg_t offset_x = ipc_get_arg1(icall);
+	sysarg_t offset_y = ipc_get_arg2(icall);
 	window_placement_flags_t placement_flags =
-	    (window_placement_flags_t) IPC_GET_ARG5(*icall);
+	    (window_placement_flags_t) ipc_get_arg5(icall);
 
 	comp_update_viewport_bound_rect();
@@ -892,4 +896,7 @@
 	}
 
+	/* Down refcount for removing from the window list */
+	window_destroy(win);
+
 	comp_damage(x, y, width, height);
 	async_answer_0(icall, EOK);
@@ -914,5 +921,5 @@
 {
 	ipc_call_t call;
-	service_id_t service_id = (service_id_t) IPC_GET_ARG2(*icall);
+	service_id_t service_id = (service_id_t) ipc_get_arg2(icall);
 
 	/* Allocate resources for new window and register it to the location service. */
@@ -921,5 +928,5 @@
 
 		async_get_call(&call);
-		if (IPC_GET_IMETHOD(call) == WINDOW_REGISTER) {
+		if (ipc_get_imethod(&call) == WINDOW_REGISTER) {
 			fibril_mutex_lock(&window_list_mtx);
 
@@ -931,5 +938,5 @@
 			}
 
-			win->flags = IPC_GET_ARG1(call);
+			win->flags = ipc_get_arg1(&call);
 
 			char name_in[LOC_NAME_MAXLEN + 1];
@@ -1007,5 +1014,5 @@
 			async_get_call(&call);
 
-			if (!IPC_GET_IMETHOD(call)) {
+			if (!ipc_get_imethod(&call)) {
 				async_answer_0(&call, EOK);
 				window_destroy(win);
@@ -1013,5 +1020,5 @@
 			}
 
-			switch (IPC_GET_IMETHOD(call)) {
+			switch (ipc_get_imethod(&call)) {
 			case WINDOW_GET_EVENT:
 				comp_window_get_event(win, &call);
@@ -1025,5 +1032,5 @@
 			async_get_call(&call);
 
-			if (!IPC_GET_IMETHOD(call)) {
+			if (!ipc_get_imethod(&call)) {
 				comp_window_close(win, &call);
 				window_destroy(win);
@@ -1031,5 +1038,5 @@
 			}
 
-			switch (IPC_GET_IMETHOD(call)) {
+			switch (ipc_get_imethod(&call)) {
 			case WINDOW_DAMAGE:
 				comp_window_damage(win, &call);
@@ -1060,5 +1067,5 @@
 static void comp_mode_change(viewport_t *vp, ipc_call_t *icall)
 {
-	sysarg_t mode_idx = IPC_GET_ARG2(*icall);
+	sysarg_t mode_idx = ipc_get_arg2(icall);
 	fibril_mutex_lock(&viewport_list_mtx);
 
@@ -1158,5 +1165,5 @@
 	fibril_mutex_lock(&viewport_list_mtx);
 	list_foreach(viewport_list, link, viewport_t, cur) {
-		if (cur->dsid == (service_id_t) IPC_GET_ARG1(*icall)) {
+		if (cur->dsid == (service_id_t) ipc_get_arg1(icall)) {
 			vp = cur;
 			break;
@@ -1173,10 +1180,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_hangup(vp->sess);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case VISUALIZER_MODE_CHANGE:
 			comp_mode_change(vp, &call);
Index: uspace/srv/hid/console/console.c
===================================================================
--- uspace/srv/hid/console/console.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/console/console.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -513,5 +513,5 @@
 
 	for (size_t i = 0; i < CONSOLE_COUNT; i++) {
-		if (consoles[i].dsid == (service_id_t) IPC_GET_ARG2(*icall)) {
+		if (consoles[i].dsid == (service_id_t) ipc_get_arg2(icall)) {
 			cons = &consoles[i];
 			break;
Index: uspace/srv/hid/input/ctl/kbdev.c
===================================================================
--- uspace/srv/hid/input/ctl/kbdev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/ctl/kbdev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -160,5 +160,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			kbdev_destroy(kbdev);
@@ -166,10 +166,10 @@
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case KBDEV_EVENT:
 			/* Got event from keyboard device */
 			retval = 0;
-			type = IPC_GET_ARG1(call);
-			key = IPC_GET_ARG2(call);
+			type = ipc_get_arg1(&call);
+			key = ipc_get_arg2(&call);
 			kbd_push_event(kbdev->kbd_dev, type, key);
 			break;
Index: uspace/srv/hid/input/ctl/stty.c
===================================================================
--- uspace/srv/hid/input/ctl/stty.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/ctl/stty.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -228,4 +228,29 @@
 	0,	KC_RIGHT,	0x1b, 0x5b, 0x43, GSP_END,
 
+	KM_CTRL, 	KC_Q,		0x11, GSP_END,
+	KM_CTRL, 	KC_W,		0x17, GSP_END,
+	KM_CTRL, 	KC_E,		0x05, GSP_END,
+	KM_CTRL, 	KC_R,		0x12, GSP_END,
+	KM_CTRL,	KC_T,		0x14, GSP_END,
+	KM_CTRL,	KC_Y,		0x19, GSP_END,
+	KM_CTRL,	KC_U,		0x15, GSP_END,
+	KM_CTRL,	KC_O,		0x0f, GSP_END,
+	KM_CTRL,	KC_P,		0x10, GSP_END,
+
+	KM_CTRL,	KC_A,		0x01, GSP_END,
+	KM_CTRL,	KC_S,		0x13, GSP_END,
+	KM_CTRL,	KC_D,		0x04, GSP_END,
+	KM_CTRL,	KC_F,		0x06, GSP_END,
+	KM_CTRL,	KC_G,		0x07, GSP_END,
+	KM_CTRL,	KC_K,		0x0b, GSP_END,
+	KM_CTRL,	KC_L,		0x0c, GSP_END,
+
+	KM_CTRL,	KC_Z,		0x1a, GSP_END,
+	KM_CTRL,	KC_X,		0x18, GSP_END,
+	KM_CTRL,	KC_C,		0x03, GSP_END,
+	KM_CTRL,	KC_V,		0x16, GSP_END,
+	KM_CTRL,	KC_B,		0x02, GSP_END,
+	KM_CTRL,	KC_N,		0x0e, GSP_END,
+
 	/*
 	 * Sequences specific to Gnome terminal
Index: uspace/srv/hid/input/gsp.c
===================================================================
--- uspace/srv/hid/input/gsp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/gsp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -64,7 +64,7 @@
 } trans_key_t;
 
-static size_t trans_key_hash(void *key)
-{
-	trans_key_t *trans_key = (trans_key_t *)key;
+static size_t trans_key_hash(const void *key)
+{
+	const trans_key_t *trans_key = key;
 	return hash_combine(trans_key->input, trans_key->old_state);
 }
@@ -76,7 +76,7 @@
 }
 
-static bool trans_key_equal(void *key, const ht_link_t *item)
-{
-	trans_key_t *trans_key = (trans_key_t *)key;
+static bool trans_key_equal(const void *key, const ht_link_t *item)
+{
+	const trans_key_t *trans_key = key;
 	gsp_trans_t *t = hash_table_get_inst(item, gsp_trans_t, link);
 
Index: uspace/srv/hid/input/input.c
===================================================================
--- uspace/srv/hid/input/input.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/input.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -334,5 +334,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			if (client->sess != NULL) {
 				async_hangup(client->sess);
@@ -353,5 +353,5 @@
 				async_answer_0(&call, ELIMIT);
 		} else {
-			switch (IPC_GET_IMETHOD(call)) {
+			switch (ipc_get_imethod(&call)) {
 			case INPUT_ACTIVATE:
 				active_client = client;
@@ -368,5 +368,5 @@
 static void kconsole_event_handler(ipc_call_t *call, void *arg)
 {
-	if (IPC_GET_ARG1(*call)) {
+	if (ipc_get_arg1(call)) {
 		/* Kernel console activated */
 		active = false;
@@ -539,5 +539,6 @@
 		size_t nread;
 
-		chardev_read(sdev->chardev, &data, sizeof(data), &nread);
+		chardev_read(sdev->chardev, &data, sizeof(data), &nread,
+		    chardev_f_none);
 		/* XXX Handle error */
 		kbd_push_data(sdev->kdev, data);
@@ -629,4 +630,7 @@
 	kbd_add_dev(&chardev_port, &stty_ctl);
 #endif
+#if defined(UARCH_arm64) && defined(MACHINE_virt)
+	kbd_add_dev(&chardev_port, &stty_ctl);
+#endif
 	/* Silence warning on abs32le about kbd_add_dev() being unused */
 	(void) kbd_add_dev;
Index: uspace/srv/hid/input/port/chardev.c
===================================================================
--- uspace/srv/hid/input/port/chardev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/port/chardev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -64,5 +64,7 @@
 	"char/s3c24xx_uart",
 	/** Ski console, MSIM console, Sun4v console */
-	"devices/\\hw\\console\\a"
+	"devices/\\hw\\console\\a",
+	/** PL011 serial console */
+	"devices/\\hw\\uart\\a"
 };
 
@@ -138,5 +140,6 @@
 
 	while (true) {
-		rc = chardev_read(chardev, &b, sizeof(b), &nread);
+		rc = chardev_read(chardev, &b, sizeof(b), &nread,
+		    chardev_f_none);
 		if (rc != EOK || nread != sizeof(b)) {
 			printf("%s: Error reading data", NAME);
Index: uspace/srv/hid/input/proto/mousedev.c
===================================================================
--- uspace/srv/hid/input/proto/mousedev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/proto/mousedev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -79,5 +79,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			mousedev_destroy(mousedev);
@@ -87,20 +87,20 @@
 		errno_t retval;
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case MOUSEEV_MOVE_EVENT:
 			mouse_push_event_move(mousedev->mouse_dev,
-			    IPC_GET_ARG1(call), IPC_GET_ARG2(call),
-			    IPC_GET_ARG3(call));
+			    ipc_get_arg1(&call), ipc_get_arg2(&call),
+			    ipc_get_arg3(&call));
 			retval = EOK;
 			break;
 		case MOUSEEV_ABS_MOVE_EVENT:
 			mouse_push_event_abs_move(mousedev->mouse_dev,
-			    IPC_GET_ARG1(call), IPC_GET_ARG2(call),
-			    IPC_GET_ARG3(call), IPC_GET_ARG4(call));
+			    ipc_get_arg1(&call), ipc_get_arg2(&call),
+			    ipc_get_arg3(&call), ipc_get_arg4(&call));
 			retval = EOK;
 			break;
 		case MOUSEEV_BUTTON_EVENT:
 			mouse_push_event_button(mousedev->mouse_dev,
-			    IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			    ipc_get_arg1(&call), ipc_get_arg2(&call));
 			retval = EOK;
 			break;
Index: uspace/srv/hid/input/stroke.c
===================================================================
--- uspace/srv/hid/input/stroke.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/input/stroke.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -48,4 +48,5 @@
 static unsigned int mods_keys[][2] = {
 	{ KM_LSHIFT, KC_LSHIFT },
+	{ KM_LCTRL, KC_LCTRL },
 	{ 0, 0 }
 };
Index: uspace/srv/hid/isdv4_tablet/isdv4.c
===================================================================
--- uspace/srv/hid/isdv4_tablet/isdv4.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/isdv4_tablet/isdv4.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -27,6 +27,6 @@
  */
 
-#include <async.h>
 #include <errno.h>
+#include <fibril.h>
 #include <io/chardev.h>
 #include <mem.h>
@@ -293,5 +293,5 @@
 
 		rc = chardev_read(state->chardev, state->buf + state->buf_end,
-		    state->buf_size - state->buf_end, &nread);
+		    state->buf_size - state->buf_end, &nread, chardev_f_none);
 		if (rc != EOK && nread == 0)
 			return EIO;
Index: uspace/srv/hid/isdv4_tablet/main.c
===================================================================
--- uspace/srv/hid/isdv4_tablet/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/isdv4_tablet/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -81,5 +81,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
Index: uspace/srv/hid/output/output.c
===================================================================
--- uspace/srv/hid/output/output.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/output/output.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -187,5 +187,5 @@
 static void srv_frontbuf_destroy(ipc_call_t *icall)
 {
-	frontbuf_t *frontbuf = resolve_frontbuf(IPC_GET_ARG1(*icall), icall);
+	frontbuf_t *frontbuf = resolve_frontbuf(ipc_get_arg1(icall), icall);
 	if (frontbuf == NULL)
 		return;
@@ -200,5 +200,5 @@
 static void srv_cursor_update(ipc_call_t *icall)
 {
-	frontbuf_t *frontbuf = resolve_frontbuf(IPC_GET_ARG1(*icall), icall);
+	frontbuf_t *frontbuf = resolve_frontbuf(ipc_get_arg1(icall), icall);
 	if (frontbuf == NULL)
 		return;
@@ -235,5 +235,5 @@
 		dev->attrs.type = CHAR_ATTR_STYLE;
 		dev->attrs.val.style =
-		    (console_style_t) IPC_GET_ARG1(*icall);
+		    (console_style_t) ipc_get_arg1(icall);
 	}
 
@@ -246,9 +246,9 @@
 		dev->attrs.type = CHAR_ATTR_INDEX;
 		dev->attrs.val.index.bgcolor =
-		    (console_color_t) IPC_GET_ARG1(*icall);
+		    (console_color_t) ipc_get_arg1(icall);
 		dev->attrs.val.index.fgcolor =
-		    (console_color_t) IPC_GET_ARG2(*icall);
+		    (console_color_t) ipc_get_arg2(icall);
 		dev->attrs.val.index.attr =
-		    (console_color_attr_t) IPC_GET_ARG3(*icall);
+		    (console_color_attr_t) ipc_get_arg3(icall);
 	}
 
@@ -260,6 +260,6 @@
 	list_foreach(outdevs, link, outdev_t, dev) {
 		dev->attrs.type = CHAR_ATTR_RGB;
-		dev->attrs.val.rgb.bgcolor = IPC_GET_ARG1(*icall);
-		dev->attrs.val.rgb.fgcolor = IPC_GET_ARG2(*icall);
+		dev->attrs.val.rgb.bgcolor = ipc_get_arg1(icall);
+		dev->attrs.val.rgb.fgcolor = ipc_get_arg2(icall);
 	}
 
@@ -308,5 +308,5 @@
 static void srv_update(ipc_call_t *icall)
 {
-	frontbuf_t *frontbuf = resolve_frontbuf(IPC_GET_ARG1(*icall), icall);
+	frontbuf_t *frontbuf = resolve_frontbuf(ipc_get_arg1(icall), icall);
 	if (frontbuf == NULL)
 		return;
@@ -357,5 +357,5 @@
 static void srv_damage(ipc_call_t *icall)
 {
-	frontbuf_t *frontbuf = resolve_frontbuf(IPC_GET_ARG1(*icall), icall);
+	frontbuf_t *frontbuf = resolve_frontbuf(ipc_get_arg1(icall), icall);
 	if (frontbuf == NULL)
 		return;
@@ -369,9 +369,9 @@
 			continue;
 
-		sysarg_t col = IPC_GET_ARG2(*icall);
-		sysarg_t row = IPC_GET_ARG3(*icall);
-
-		sysarg_t cols = IPC_GET_ARG4(*icall);
-		sysarg_t rows = IPC_GET_ARG5(*icall);
+		sysarg_t col = ipc_get_arg2(icall);
+		sysarg_t row = ipc_get_arg3(icall);
+
+		sysarg_t cols = ipc_get_arg4(icall);
+		sysarg_t rows = ipc_get_arg5(icall);
 
 		for (sysarg_t y = 0; y < rows; y++) {
@@ -404,10 +404,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case OUTPUT_YIELD:
 			srv_yield(&call);
Index: uspace/srv/hid/output/port/chardev.c
===================================================================
--- uspace/srv/hid/output/port/chardev.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/output/port/chardev.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -216,4 +216,6 @@
 #elif defined(MACHINE_msim)
 		/* OK */
+#elif defined(UARCH_arm64) && defined(MACHINE_virt)
+		/* OK */
 #else
 		return EOK;
Index: uspace/srv/hid/remcons/remcons.c
===================================================================
--- uspace/srv/hid/remcons/remcons.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/remcons/remcons.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -219,5 +219,5 @@
 {
 	/* Find the user. */
-	telnet_user_t *user = telnet_user_get_for_client_connection(IPC_GET_ARG2(*icall));
+	telnet_user_t *user = telnet_user_get_for_client_connection(ipc_get_arg2(icall));
 	if (user == NULL) {
 		async_answer_0(icall, ENOENT);
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -378,5 +378,5 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			if (ts->client_sess != NULL) {
 				async_hangup(ts->client_sess);
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -69,5 +69,6 @@
 static void s3c24xx_uart_sendb(s3c24xx_uart_t *, uint8_t);
 
-static errno_t s3c24xx_uart_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t s3c24xx_uart_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 static errno_t s3c24xx_uart_write(chardev_srv_t *, const void *, size_t, size_t *);
 
@@ -199,5 +200,5 @@
 
 static errno_t s3c24xx_uart_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	s3c24xx_uart_t *uart = (s3c24xx_uart_t *) srv->srvs->sarg;
@@ -208,5 +209,6 @@
 	fibril_mutex_lock(&uart->buf_lock);
 
-	while (circ_buf_nused(&uart->cbuf) == 0)
+	while ((flags & chardev_f_nonblock) == 0 &&
+	    circ_buf_nused(&uart->cbuf) == 0)
 		fibril_condvar_wait(&uart->buf_cv, &uart->buf_lock);
 
Index: uspace/srv/loader/main.c
===================================================================
--- uspace/srv/loader/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/loader/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -290,6 +290,6 @@
 	DPRINTF("LOADER_LOAD()\n");
 
-	int rc = elf_load(program_fd, &prog_info);
-	if (rc != EE_OK) {
+	errno_t rc = elf_load(program_fd, &prog_info);
+	if (rc != EOK) {
 		DPRINTF("Failed to load executable for '%s'.\n", progname);
 		async_answer_0(req, EINVAL);
@@ -353,5 +353,5 @@
 	 */
 	async_get_call(req);
-	assert(!IPC_GET_IMETHOD(*req));
+	assert(!ipc_get_imethod(req));
 	async_answer_0(req, EOK);
 
@@ -392,10 +392,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			exit(0);
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOADER_GET_TASKID:
 			ldr_get_taskid(&call);
Index: uspace/srv/locsrv/locsrv.c
===================================================================
--- uspace/srv/locsrv/locsrv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/locsrv/locsrv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -342,5 +342,5 @@
 	async_get_call(&icall);
 
-	if (IPC_GET_IMETHOD(icall) != LOC_SERVER_REGISTER) {
+	if (ipc_get_imethod(&icall) != LOC_SERVER_REGISTER) {
 		async_answer_0(&icall, EREFUSED);
 		return NULL;
@@ -547,5 +547,5 @@
 
 	fibril_mutex_lock(&services_list_mutex);
-	svc = loc_service_find_id(IPC_GET_ARG1(*icall));
+	svc = loc_service_find_id(ipc_get_arg1(icall));
 	if (svc == NULL) {
 		fibril_mutex_unlock(&services_list_mutex);
@@ -583,5 +583,5 @@
 	fibril_mutex_lock(&cdir.mutex);
 
-	cat = category_get(&cdir, IPC_GET_ARG1(*icall));
+	cat = category_get(&cdir, ipc_get_arg1(icall));
 	if (cat == NULL) {
 		fibril_mutex_unlock(&cdir.mutex);
@@ -623,5 +623,5 @@
 	fibril_mutex_lock(&services_list_mutex);
 
-	svc = loc_service_find_id(IPC_GET_ARG1(*icall));
+	svc = loc_service_find_id(ipc_get_arg1(icall));
 	if (svc == NULL) {
 		fibril_mutex_unlock(&services_list_mutex);
@@ -671,5 +671,5 @@
 	fibril_mutex_lock(&services_list_mutex);
 
-	svc = loc_service_find_id(IPC_GET_ARG1(*icall));
+	svc = loc_service_find_id(ipc_get_arg1(icall));
 	if (svc == NULL) {
 		fibril_mutex_unlock(&services_list_mutex);
@@ -715,6 +715,6 @@
 	 * Get ID from request
 	 */
-	iface_t iface = IPC_GET_ARG1(*call);
-	service_id_t id = IPC_GET_ARG2(*call);
+	iface_t iface = ipc_get_arg1(call);
+	service_id_t id = ipc_get_arg2(call);
 	loc_service_t *svc = loc_service_find_id(id);
 
@@ -726,5 +726,5 @@
 
 	async_exch_t *exch = async_exchange_begin(svc->server->sess);
-	async_forward_fast(call, exch, iface, svc->id, 0, IPC_FF_NONE);
+	async_forward_1(call, exch, iface, svc->id, IPC_FF_NONE);
 	async_exchange_end(exch);
 
@@ -774,5 +774,5 @@
 	 */
 	if (svc == NULL) {
-		if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) {
+		if (ipc_get_arg1(icall) & IPC_FLAG_BLOCKING) {
 			/* Blocking lookup */
 			fibril_condvar_wait(&services_list_cv,
@@ -827,5 +827,5 @@
 	 */
 	if (namespace == NULL) {
-		if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) {
+		if (ipc_get_arg1(icall) & IPC_FLAG_BLOCKING) {
 			/* Blocking lookup */
 			fibril_condvar_wait(&services_list_cv,
@@ -932,8 +932,8 @@
 
 	loc_namespace_t *namespace =
-	    loc_namespace_find_id(IPC_GET_ARG1(*icall));
+	    loc_namespace_find_id(ipc_get_arg1(icall));
 	if (namespace == NULL) {
 		loc_service_t *svc =
-		    loc_service_find_id(IPC_GET_ARG1(*icall));
+		    loc_service_find_id(ipc_get_arg1(icall));
 		if (svc == NULL)
 			async_answer_1(icall, EOK, LOC_OBJECT_NONE);
@@ -958,5 +958,5 @@
 
 	loc_namespace_t *namespace =
-	    loc_namespace_find_id(IPC_GET_ARG1(*icall));
+	    loc_namespace_find_id(ipc_get_arg1(icall));
 	if (namespace == NULL)
 		async_answer_0(icall, EEXIST);
@@ -1079,5 +1079,5 @@
 
 	loc_namespace_t *namespace =
-	    loc_namespace_find_id(IPC_GET_ARG1(*icall));
+	    loc_namespace_find_id(ipc_get_arg1(icall));
 	if (namespace == NULL) {
 		fibril_mutex_unlock(&services_list_mutex);
@@ -1135,5 +1135,5 @@
 	fibril_mutex_lock(&cdir.mutex);
 
-	category_t *cat = category_get(&cdir, IPC_GET_ARG1(*icall));
+	category_t *cat = category_get(&cdir, ipc_get_arg1(icall));
 	if (cat == NULL) {
 		fibril_mutex_unlock(&cdir.mutex);
@@ -1247,5 +1247,5 @@
 static void loc_null_destroy(ipc_call_t *icall)
 {
-	sysarg_t i = IPC_GET_ARG1(*icall);
+	sysarg_t i = ipc_get_arg1(icall);
 	if (i >= NULL_SERVICES) {
 		async_answer_0(icall, ELIMIT);
@@ -1281,6 +1281,6 @@
 	errno_t retval;
 
-	svc_id = IPC_GET_ARG1(*icall);
-	cat_id = IPC_GET_ARG2(*icall);
+	svc_id = ipc_get_arg1(icall);
+	cat_id = ipc_get_arg2(icall);
 
 	fibril_mutex_lock(&services_list_mutex);
@@ -1387,4 +1387,10 @@
 	categ_dir_add_cat(&cdir, cat);
 
+	cat = category_new("printer-port");
+	categ_dir_add_cat(&cdir, cat);
+
+	cat = category_new("pci");
+	categ_dir_add_cat(&cdir, cat);
+
 	return true;
 }
@@ -1403,5 +1409,5 @@
 	 */
 	static_assert((INTERFACE_LOC_SUPPLIER & IFACE_EXCHANGE_MASK) ==
-	    IFACE_EXCHANGE_SERIALIZE);
+	    IFACE_EXCHANGE_SERIALIZE, "");
 
 	loc_server_t *server = loc_server_register();
@@ -1413,10 +1419,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOC_SERVER_UNREGISTER:
 			if (server == NULL)
@@ -1469,10 +1475,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOC_SERVICE_GET_ID:
 			loc_service_get_id(&call);
Index: uspace/srv/logger/ctl.c
===================================================================
--- uspace/srv/logger/ctl.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/logger/ctl.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -75,16 +75,16 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOGGER_CONTROL_SET_DEFAULT_LEVEL:
-			rc = set_default_logging_level(IPC_GET_ARG1(call));
+			rc = set_default_logging_level(ipc_get_arg1(&call));
 			async_answer_0(&call, rc);
 			break;
 		case LOGGER_CONTROL_SET_LOG_LEVEL:
-			rc = handle_log_level_change(IPC_GET_ARG1(call));
+			rc = handle_log_level_change(ipc_get_arg1(&call));
 			async_answer_0(&call, rc);
 			break;
Index: uspace/srv/logger/logs.c
===================================================================
--- uspace/srv/logger/logs.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/logger/logs.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -198,5 +198,5 @@
 }
 
-/** Decreases reference counter on the log and destory the log if
+/** Decreases reference counter on the log and destroy the log if
  * necessary.
  *
Index: uspace/srv/logger/writer.c
===================================================================
--- uspace/srv/logger/writer.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/logger/writer.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -109,12 +109,12 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case LOGGER_WRITER_CREATE_LOG:
-			log = handle_create_log(IPC_GET_ARG1(call));
+			log = handle_create_log(ipc_get_arg1(&call));
 			if (log == NULL) {
 				async_answer_0(&call, ENOMEM);
@@ -130,6 +130,6 @@
 			break;
 		case LOGGER_WRITER_MESSAGE:
-			rc = handle_receive_message(IPC_GET_ARG1(call),
-			    IPC_GET_ARG2(call));
+			rc = handle_receive_message(ipc_get_arg1(&call),
+			    ipc_get_arg2(&call));
 			async_answer_0(&call, rc);
 			break;
Index: uspace/srv/net/dhcp/main.c
===================================================================
--- uspace/srv/net/dhcp/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/dhcp/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -91,5 +91,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_link_add_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = dhcpsrv_link_add(link_id);
@@ -104,5 +104,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_link_remove_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = dhcpsrv_link_remove(link_id);
@@ -117,5 +117,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "dhcp_discover_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = dhcpsrv_discover(link_id);
@@ -133,5 +133,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/srv/net/dnsrsrv/dns_msg.c
===================================================================
--- uspace/srv/net/dnsrsrv/dns_msg.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/dnsrsrv/dns_msg.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -52,5 +52,5 @@
 /** Extend dynamically allocated string with suffix.
  *
- * @a *dstr points to a dynamically alocated buffer containing a string.
+ * @a *dstr points to a dynamically allocated buffer containing a string.
  * Reallocate this buffer so that concatenation of @a *dstr and @a suff can
  * fit in and append @a suff.
Index: uspace/srv/net/dnsrsrv/dnsrsrv.c
===================================================================
--- uspace/srv/net/dnsrsrv/dnsrsrv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/dnsrsrv/dnsrsrv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -90,5 +90,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srvaddr_srv()");
 
-	ip_ver_t ver = IPC_GET_ARG1(*icall);
+	ip_ver_t ver = ipc_get_arg1(icall);
 
 	char *name;
@@ -219,5 +219,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/srv/net/ethip/ethip.c
===================================================================
--- uspace/srv/net/ethip/ethip.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/ethip/ethip.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -147,5 +147,5 @@
 	service_id_t sid;
 
-	sid = (service_id_t) IPC_GET_ARG2(*icall);
+	sid = (service_id_t) ipc_get_arg2(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "ethip_client_conn(%u)", (unsigned)sid);
 	nic = ethip_nic_find_by_iplink_sid(sid);
Index: uspace/srv/net/ethip/ethip_nic.c
===================================================================
--- uspace/srv/net/ethip/ethip_nic.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/ethip/ethip_nic.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -299,10 +299,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			return;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case NIC_EV_ADDR_CHANGED:
 			ethip_nic_addr_changed(nic, &call);
@@ -315,5 +315,5 @@
 			break;
 		default:
-			log_msg(LOG_DEFAULT, LVL_DEBUG, "unknown IPC method: %" PRIun, IPC_GET_IMETHOD(call));
+			log_msg(LOG_DEFAULT, LVL_DEBUG, "unknown IPC method: %" PRIun, ipc_get_imethod(&call));
 			async_answer_0(&call, ENOTSUP);
 		}
Index: uspace/srv/net/inetsrv/icmp.c
===================================================================
--- uspace/srv/net/inetsrv/icmp.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/icmp.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -133,5 +133,5 @@
 	sdu.dest = dgram->dest;
 	sdu.seq_no = uint16_t_be2host(reply->seq_no);
-	sdu.data = reply + sizeof(icmp_echo_t);
+	sdu.data = dgram->data + sizeof(icmp_echo_t);
 	sdu.size = dgram->size - sizeof(icmp_echo_t);
 
Index: uspace/srv/net/inetsrv/icmpv6.c
===================================================================
--- uspace/srv/net/inetsrv/icmpv6.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/icmpv6.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -124,5 +124,5 @@
 
 	sdu.seq_no = uint16_t_be2host(reply->un.echo.seq_no);
-	sdu.data = reply + sizeof(icmpv6_message_t);
+	sdu.data = dgram->data + sizeof(icmpv6_message_t);
 	sdu.size = dgram->size - sizeof(icmpv6_message_t);
 
Index: uspace/srv/net/inetsrv/inetcfg.c
===================================================================
--- uspace/srv/net/inetsrv/inetcfg.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/inetcfg.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -257,5 +257,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_create_static_srv()");
 
-	sysarg_t link_id = IPC_GET_ARG1(*icall);
+	sysarg_t link_id = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -302,5 +302,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_delete_srv()");
 
-	addr_id = IPC_GET_ARG1(*call);
+	addr_id = ipc_get_arg1(call);
 
 	rc = inetcfg_addr_delete(addr_id);
@@ -312,5 +312,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_srv()");
 
-	sysarg_t addr_id = IPC_GET_ARG1(*icall);
+	sysarg_t addr_id = ipc_get_arg1(icall);
 
 	inet_addr_info_t ainfo;
@@ -375,5 +375,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_id_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
@@ -499,5 +499,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_add_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = inetcfg_link_add(link_id);
@@ -516,5 +516,5 @@
 	errno_t rc;
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_get_srv()");
 
@@ -566,5 +566,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_remove_srv()");
 
-	link_id = IPC_GET_ARG1(*call);
+	link_id = ipc_get_arg1(call);
 
 	rc = inetcfg_link_remove(link_id);
@@ -639,5 +639,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_delete_srv()");
 
-	sroute_id = IPC_GET_ARG1(*call);
+	sroute_id = ipc_get_arg1(call);
 
 	rc = inetcfg_sroute_delete(sroute_id);
@@ -649,5 +649,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_srv()");
 
-	sysarg_t sroute_id = IPC_GET_ARG1(*icall);
+	sysarg_t sroute_id = ipc_get_arg1(icall);
 
 	inet_sroute_info_t srinfo;
@@ -747,5 +747,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "method %d", (int)method);
Index: uspace/srv/net/inetsrv/inetping.c
===================================================================
--- uspace/srv/net/inetsrv/inetping.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/inetping.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -143,5 +143,5 @@
 	errno_t rc;
 
-	sdu.seq_no = IPC_GET_ARG1(*icall);
+	sdu.seq_no = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -294,5 +294,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/srv/net/inetsrv/inetsrv.c
===================================================================
--- uspace/srv/net/inetsrv/inetsrv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/inetsrv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -233,5 +233,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srcaddr_srv()");
 
-	uint8_t tos = IPC_GET_ARG1(*icall);
+	uint8_t tos = ipc_get_arg1(icall);
 
 	ipc_call_t call;
@@ -291,9 +291,9 @@
 	inet_dgram_t dgram;
 
-	dgram.iplink = IPC_GET_ARG1(*icall);
-	dgram.tos = IPC_GET_ARG2(*icall);
-
-	uint8_t ttl = IPC_GET_ARG3(*icall);
-	int df = IPC_GET_ARG4(*icall);
+	dgram.iplink = ipc_get_arg1(icall);
+	dgram.tos = ipc_get_arg2(icall);
+
+	uint8_t ttl = ipc_get_arg3(icall);
+	int df = ipc_get_arg4(icall);
 
 	ipc_call_t call;
@@ -352,5 +352,5 @@
 	sysarg_t proto;
 
-	proto = IPC_GET_ARG1(*call);
+	proto = ipc_get_arg1(call);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_set_proto_srv(%lu)", (unsigned long) proto);
 
@@ -397,5 +397,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/srv/net/inetsrv/pdu.c
===================================================================
--- uspace/srv/net/inetsrv/pdu.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/inetsrv/pdu.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -224,5 +224,5 @@
 		return EINVAL;
 
-	static_assert(sizeof(ip6_header_t) % 8 == 0);
+	static_assert(sizeof(ip6_header_t) % 8 == 0, "");
 	assert(hdr_size % 8 == 0);
 	assert(offs % FRAG_OFFS_UNIT == 0);
Index: uspace/srv/net/slip/slip.c
===================================================================
--- uspace/srv/net/slip/slip.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/slip/slip.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -212,5 +212,5 @@
 
 		rc = chardev_read(chardev, slip_recv_buf,
-		    sizeof(slip_recv_buf), &nread);
+		    sizeof(slip_recv_buf), &nread, chardev_f_none);
 		if (rc != EOK) {
 			log_msg(LOG_DEFAULT, LVL_ERROR,
Index: uspace/srv/net/tcp/service.c
===================================================================
--- uspace/srv/net/tcp/service.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/tcp/service.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -806,5 +806,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_destroy_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 	rc = tcp_conn_destroy_impl(client, conn_id);
 	async_answer_0(icall, rc);
@@ -872,5 +872,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_listener_destroy_srv()");
 
-	lst_id = IPC_GET_ARG1(*icall);
+	lst_id = ipc_get_arg1(icall);
 	rc = tcp_listener_destroy_impl(client, lst_id);
 	async_answer_0(icall, rc);
@@ -892,5 +892,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_send_fin_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 	rc = tcp_conn_send_fin_impl(client, conn_id);
 	async_answer_0(icall, rc);
@@ -912,5 +912,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_push_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 	rc = tcp_conn_push_impl(client, conn_id);
 	async_answer_0(icall, rc);
@@ -932,5 +932,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_reset_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 	rc = tcp_conn_reset_impl(client, conn_id);
 	async_answer_0(icall, rc);
@@ -984,5 +984,5 @@
 	}
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	rc = tcp_conn_send_impl(client, conn_id, data, size);
@@ -1015,5 +1015,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	if (!async_data_read_receive(&call, &size)) {
@@ -1070,5 +1070,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_conn_recv_wait_srv()");
 
-	conn_id = IPC_GET_ARG1(*icall);
+	conn_id = ipc_get_arg1(icall);
 
 	if (!async_data_read_receive(&call, &size)) {
@@ -1180,5 +1180,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_client_conn: method=%d",
Index: uspace/srv/net/udp/service.c
===================================================================
--- uspace/srv/net/udp/service.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/net/udp/service.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -405,5 +405,5 @@
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_assoc_destroy_srv()");
 
-	assoc_id = IPC_GET_ARG1(*icall);
+	assoc_id = ipc_get_arg1(icall);
 	rc = udp_assoc_destroy_impl(client, assoc_id);
 	async_answer_0(icall, rc);
@@ -425,5 +425,5 @@
 	log_msg(LOG_DEFAULT, LVL_NOTE, "udp_assoc_set_nolocal_srv()");
 
-	assoc_id = IPC_GET_ARG1(*icall);
+	assoc_id = ipc_get_arg1(icall);
 	rc = udp_assoc_set_nolocal_impl(client, assoc_id);
 	async_answer_0(icall, rc);
@@ -498,5 +498,5 @@
 	}
 
-	assoc_id = IPC_GET_ARG1(*icall);
+	assoc_id = ipc_get_arg1(icall);
 
 	rc = udp_assoc_send_msg_impl(client, assoc_id, &dest, data, size);
@@ -592,5 +592,5 @@
 
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_rmsg_read_srv()");
-	off = IPC_GET_ARG1(*icall);
+	off = ipc_get_arg1(icall);
 
 	enext = udp_rmsg_get_next(client);
@@ -679,5 +679,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		log_msg(LOG_DEFAULT, LVL_DEBUG, "udp_client_conn: method=%d",
Index: uspace/srv/ns/clonable.c
===================================================================
--- uspace/srv/ns/clonable.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/ns/clonable.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -94,6 +94,6 @@
 
 	async_exch_t *exch = async_exchange_begin(sess);
-	async_forward_fast(&csr->call, exch, csr->iface,
-	    IPC_GET_ARG3(csr->call), 0, IPC_FF_NONE);
+	async_forward_1(&csr->call, exch, csr->iface,
+	    ipc_get_arg3(&csr->call), IPC_FF_NONE);
 	async_exchange_end(exch);
 
Index: uspace/srv/ns/ns.c
===================================================================
--- uspace/srv/ns/ns.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/ns/ns.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -55,6 +55,6 @@
 	service_t service;
 
-	iface = IPC_GET_ARG1(*icall);
-	service = IPC_GET_ARG2(*icall);
+	iface = ipc_get_arg1(icall);
+	service = ipc_get_arg2(icall);
 	if (service != 0) {
 		/*
@@ -76,5 +76,5 @@
 
 		async_get_call(&call);
-		if (!IPC_GET_IMETHOD(call))
+		if (!ipc_get_imethod(&call))
 			break;
 
@@ -84,8 +84,8 @@
 		service_t service;
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case NS_REGISTER:
-			service = IPC_GET_ARG1(call);
-			iface = IPC_GET_ARG2(call);
+			service = ipc_get_arg1(&call);
+			iface = ipc_get_arg2(&call);
 
 			/*
@@ -101,5 +101,5 @@
 			break;
 		case NS_REGISTER_BROKER:
-			service = IPC_GET_ARG1(call);
+			service = ipc_get_arg1(&call);
 			retval = ns_service_register_broker(service);
 			break;
@@ -109,5 +109,5 @@
 		case NS_TASK_WAIT:
 			id = (task_id_t)
-			    MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call));
+			    MERGE_LOUP32(ipc_get_arg1(&call), ipc_get_arg2(&call));
 			wait_for_task(id, &call);
 			continue;
@@ -120,5 +120,5 @@
 		default:
 			printf("%s: Method not supported (%" PRIun ")\n",
-			    NAME, IPC_GET_IMETHOD(call));
+			    NAME, ipc_get_imethod(&call));
 			retval = ENOTSUP;
 			break;
Index: uspace/srv/ns/service.c
===================================================================
--- uspace/srv/ns/service.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/ns/service.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -65,7 +65,8 @@
 } hashed_iface_t;
 
-static size_t service_key_hash(void *key)
-{
-	return *(service_t *) key;
+static size_t service_key_hash(const void *key)
+{
+	const service_t *srv = key;
+	return *srv;
 }
 
@@ -78,15 +79,17 @@
 }
 
-static bool service_key_equal(void *key, const ht_link_t *item)
-{
+static bool service_key_equal(const void *key, const ht_link_t *item)
+{
+	const service_t *srv = key;
 	hashed_service_t *service =
 	    hash_table_get_inst(item, hashed_service_t, link);
 
-	return service->service == *(service_t *) key;
-}
-
-static size_t iface_key_hash(void *key)
-{
-	return *(iface_t *) key;
+	return service->service == *srv;
+}
+
+static size_t iface_key_hash(const void *key)
+{
+	const iface_t *iface = key;
+	return *iface;
 }
 
@@ -99,10 +102,11 @@
 }
 
-static bool iface_key_equal(void *key, const ht_link_t *item)
-{
+static bool iface_key_equal(const void *key, const ht_link_t *item)
+{
+	const iface_t *kiface = key;
 	hashed_iface_t *iface =
 	    hash_table_get_inst(item, hashed_iface_t, link);
 
-	return iface->iface == *(iface_t *) key;
+	return iface->iface == *kiface;
 }
 
@@ -154,6 +158,5 @@
 {
 	async_exch_t *exch = async_exchange_begin(sess);
-	async_forward_fast(call, exch, iface, IPC_GET_ARG3(*call), 0,
-	    IPC_FF_NONE);
+	async_forward_1(call, exch, iface, ipc_get_arg3(call), IPC_FF_NONE);
 	async_exchange_end(exch);
 }
@@ -367,5 +370,5 @@
 void ns_service_forward(service_t service, iface_t iface, ipc_call_t *call)
 {
-	sysarg_t flags = IPC_GET_ARG4(*call);
+	sysarg_t flags = ipc_get_arg4(call);
 	errno_t retval;
 
Index: uspace/srv/ns/task.c
===================================================================
--- uspace/srv/ns/task.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/ns/task.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -54,10 +54,11 @@
 } hashed_task_t;
 
-static size_t task_key_hash(void *key)
-{
-	return *(task_id_t *)key;
-}
-
-static size_t task_hash(const ht_link_t  *item)
+static size_t task_key_hash(const void *key)
+{
+	const task_id_t *tid = key;
+	return *tid;
+}
+
+static size_t task_hash(const ht_link_t *item)
 {
 	hashed_task_t *ht = hash_table_get_inst(item, hashed_task_t, link);
@@ -65,8 +66,9 @@
 }
 
-static bool task_key_equal(void *key, const ht_link_t *item)
-{
+static bool task_key_equal(const void *key, const ht_link_t *item)
+{
+	const task_id_t *tid = key;
 	hashed_task_t *ht = hash_table_get_inst(item, hashed_task_t, link);
-	return ht->id == *(task_id_t *)key;
+	return ht->id == *tid;
 }
 
@@ -97,8 +99,8 @@
 /* label-to-id hash table operations */
 
-static size_t p2i_key_hash(void *key)
-{
-	sysarg_t label = *(sysarg_t *)key;
-	return label;
+static size_t p2i_key_hash(const void *key)
+{
+	const sysarg_t *label = key;
+	return *label;
 }
 
@@ -109,10 +111,10 @@
 }
 
-static bool p2i_key_equal(void *key, const ht_link_t *item)
-{
-	sysarg_t label = *(sysarg_t *)key;
+static bool p2i_key_equal(const void *key, const ht_link_t *item)
+{
+	const sysarg_t *label = key;
 	p2i_entry_t *entry = hash_table_get_inst(item, p2i_entry_t, link);
 
-	return (label == entry->label);
+	return (*label == entry->label);
 }
 
@@ -225,5 +227,5 @@
 errno_t ns_task_id_intro(ipc_call_t *call)
 {
-	task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
+	task_id_t id = MERGE_LOUP32(ipc_get_arg1(call), ipc_get_arg2(call));
 
 	ht_link_t *link = hash_table_find(&phone_to_id, &call->request_label);
@@ -289,5 +291,5 @@
 	ht->finished = true;
 	ht->have_rval = true;
-	ht->retval = IPC_GET_ARG1(*call);
+	ht->retval = ipc_get_arg1(call);
 
 	process_pending_wait();
Index: uspace/srv/taskmon/taskmon.c
===================================================================
--- uspace/srv/taskmon/taskmon.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/taskmon/taskmon.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -61,6 +61,6 @@
 	uintptr_t thread;
 
-	taskid = MERGE_LOUP32(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call));
-	thread = IPC_GET_ARG3(*call);
+	taskid = MERGE_LOUP32(ipc_get_arg1(call), ipc_get_arg2(call));
+	thread = ipc_get_arg3(call);
 
 	if (asprintf(&s_taskid, "%" PRIu64, taskid) < 0) {
@@ -101,5 +101,5 @@
 static void corecfg_set_enable_srv(ipc_call_t *icall)
 {
-	write_core_files = IPC_GET_ARG1(*icall);
+	write_core_files = ipc_get_arg1(icall);
 	async_answer_0(icall, EOK);
 }
@@ -113,5 +113,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
Index: uspace/srv/test/chardev-test/main.c
===================================================================
--- uspace/srv/test/chardev-test/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/test/chardev-test/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -50,15 +50,18 @@
 static errno_t smallx_close(chardev_srv_t *);
 static errno_t smallx_write(chardev_srv_t *, const void *, size_t, size_t *);
-static errno_t smallx_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t smallx_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 
 static errno_t largex_open(chardev_srvs_t *, chardev_srv_t *);
 static errno_t largex_close(chardev_srv_t *);
 static errno_t largex_write(chardev_srv_t *, const void *, size_t, size_t *);
-static errno_t largex_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t largex_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 
 static errno_t partialx_open(chardev_srvs_t *, chardev_srv_t *);
 static errno_t partialx_close(chardev_srv_t *);
 static errno_t partialx_write(chardev_srv_t *, const void *, size_t, size_t *);
-static errno_t partialx_read(chardev_srv_t *, void *, size_t, size_t *);
+static errno_t partialx_read(chardev_srv_t *, void *, size_t, size_t *,
+    chardev_flags_t);
 
 static service_id_t smallx_svc_id;
@@ -97,5 +100,5 @@
 	sysarg_t svcid;
 
-	svcid = IPC_GET_ARG2(*icall);
+	svcid = ipc_get_arg2(icall);
 	if (svcid == smallx_svc_id) {
 		svc = &smallx_srvs;
@@ -186,5 +189,5 @@
 
 static errno_t smallx_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	if (size < 1) {
@@ -221,5 +224,5 @@
 
 static errno_t largex_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	if (size < 1) {
@@ -256,5 +259,5 @@
 
 static errno_t partialx_read(chardev_srv_t *srv, void *buf, size_t size,
-    size_t *nread)
+    size_t *nread, chardev_flags_t flags)
 {
 	if (size < 1) {
Index: uspace/srv/test/ipc-test/main.c
===================================================================
--- uspace/srv/test/ipc-test/main.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/test/ipc-test/main.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -191,10 +191,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IPC_TEST_PING:
 			async_answer_0(&call, EOK);
Index: uspace/srv/vfs/vfs.c
===================================================================
--- uspace/srv/vfs/vfs.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -62,10 +62,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case IPC_M_PAGE_IN:
 			vfs_page_in(&call);
@@ -80,9 +80,9 @@
 static void notification_handler(ipc_call_t *call, void *arg)
 {
-	if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE)
+	if (ipc_get_arg1(call) == VFS_PASS_HANDLE)
 		vfs_op_pass_handle(
-		    (task_id_t) MERGE_LOUP32(IPC_GET_ARG4(*call),
-		    IPC_GET_ARG5(*call)), call->task_id,
-		    (int) IPC_GET_ARG2(*call));
+		    (task_id_t) MERGE_LOUP32(ipc_get_arg4(call),
+		    ipc_get_arg5(call)), call->task_id,
+		    (int) ipc_get_arg2(call));
 }
 
Index: uspace/srv/vfs/vfs.h
===================================================================
--- uspace/srv/vfs/vfs.h	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs.h	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -49,4 +49,8 @@
 #define dprintf(...)
 #endif
+
+// TODO: Remove this arbitrary limit.
+/** Maximum number of open files per client. */
+#define VFS_MAX_OPEN_FILES  128
 
 /**
Index: uspace/srv/vfs/vfs_file.c
===================================================================
--- uspace/srv/vfs/vfs_file.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_file.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -148,5 +148,5 @@
 	async_wait_for(msg, &rc);
 
-	return IPC_GET_RETVAL(answer);
+	return ipc_get_retval(&answer);
 }
 
Index: uspace/srv/vfs/vfs_ipc.c
===================================================================
--- uspace/srv/vfs/vfs_ipc.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_ipc.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -37,7 +37,7 @@
 static void vfs_in_clone(ipc_call_t *req)
 {
-	int oldfd = IPC_GET_ARG1(*req);
-	int newfd = IPC_GET_ARG2(*req);
-	bool desc = IPC_GET_ARG3(*req);
+	int oldfd = ipc_get_arg1(req);
+	int newfd = ipc_get_arg2(req);
+	bool desc = ipc_get_arg3(req);
 
 	int outfd = -1;
@@ -48,5 +48,5 @@
 static void vfs_in_fsprobe(ipc_call_t *req)
 {
-	service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg1(req);
 	char *fs_name = NULL;
 	vfs_fs_probe_info_t info;
@@ -113,5 +113,5 @@
 static void vfs_in_mount(ipc_call_t *req)
 {
-	int mpfd = IPC_GET_ARG1(*req);
+	int mpfd = ipc_get_arg1(req);
 
 	/*
@@ -120,8 +120,8 @@
 	 * in the request.
 	 */
-	service_id_t service_id = (service_id_t) IPC_GET_ARG2(*req);
-
-	unsigned int flags = (unsigned int) IPC_GET_ARG3(*req);
-	unsigned int instance = IPC_GET_ARG4(*req);
+	service_id_t service_id = (service_id_t) ipc_get_arg2(req);
+
+	unsigned int flags = (unsigned int) ipc_get_arg3(req);
+	unsigned int instance = ipc_get_arg4(req);
 
 	char *opts = NULL;
@@ -159,6 +159,6 @@
 static void vfs_in_open(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
-	int mode = IPC_GET_ARG2(*req);
+	int fd = ipc_get_arg1(req);
+	int mode = ipc_get_arg2(req);
 
 	errno_t rc = vfs_op_open(fd, mode);
@@ -168,5 +168,5 @@
 static void vfs_in_put(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
+	int fd = ipc_get_arg1(req);
 	errno_t rc = vfs_op_put(fd);
 	async_answer_0(req, rc);
@@ -175,7 +175,7 @@
 static void vfs_in_read(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
-	aoff64_t pos = MERGE_LOUP32(IPC_GET_ARG2(*req),
-	    IPC_GET_ARG3(*req));
+	int fd = ipc_get_arg1(req);
+	aoff64_t pos = MERGE_LOUP32(ipc_get_arg2(req),
+	    ipc_get_arg3(req));
 
 	size_t bytes = 0;
@@ -192,5 +192,5 @@
 	errno_t rc;
 
-	basefd = IPC_GET_ARG1(*req);
+	basefd = ipc_get_arg1(req);
 
 	/* Retrieve the old path. */
@@ -230,6 +230,6 @@
 static void vfs_in_resize(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
-	int64_t size = MERGE_LOUP32(IPC_GET_ARG2(*req), IPC_GET_ARG3(*req));
+	int fd = ipc_get_arg1(req);
+	int64_t size = MERGE_LOUP32(ipc_get_arg2(req), ipc_get_arg3(req));
 	errno_t rc = vfs_op_resize(fd, size);
 	async_answer_0(req, rc);
@@ -238,5 +238,5 @@
 static void vfs_in_stat(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
+	int fd = ipc_get_arg1(req);
 	errno_t rc = vfs_op_stat(fd);
 	async_answer_0(req, rc);
@@ -245,5 +245,5 @@
 static void vfs_in_statfs(ipc_call_t *req)
 {
-	int fd = (int) IPC_GET_ARG1(*req);
+	int fd = (int) ipc_get_arg1(req);
 
 	errno_t rc = vfs_op_statfs(fd);
@@ -253,5 +253,5 @@
 static void vfs_in_sync(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
+	int fd = ipc_get_arg1(req);
 	errno_t rc = vfs_op_sync(fd);
 	async_answer_0(req, rc);
@@ -260,6 +260,6 @@
 static void vfs_in_unlink(ipc_call_t *req)
 {
-	int parentfd = IPC_GET_ARG1(*req);
-	int expectfd = IPC_GET_ARG2(*req);
+	int parentfd = ipc_get_arg1(req);
+	int expectfd = ipc_get_arg2(req);
 
 	char *path;
@@ -273,5 +273,5 @@
 static void vfs_in_unmount(ipc_call_t *req)
 {
-	int mpfd = IPC_GET_ARG1(*req);
+	int mpfd = ipc_get_arg1(req);
 	errno_t rc = vfs_op_unmount(mpfd);
 	async_answer_0(req, rc);
@@ -280,5 +280,5 @@
 static void vfs_in_wait_handle(ipc_call_t *req)
 {
-	bool high_fd = IPC_GET_ARG1(*req);
+	bool high_fd = ipc_get_arg1(req);
 	int fd = -1;
 	errno_t rc = vfs_op_wait_handle(high_fd, &fd);
@@ -292,6 +292,6 @@
 	 * For defined flags, see <ipc/vfs.h>.
 	 */
-	int parentfd = IPC_GET_ARG1(*req);
-	int flags = IPC_GET_ARG2(*req);
+	int parentfd = ipc_get_arg1(req);
+	int flags = ipc_get_arg2(req);
 
 	int fd = 0;
@@ -307,7 +307,7 @@
 static void vfs_in_write(ipc_call_t *req)
 {
-	int fd = IPC_GET_ARG1(*req);
-	aoff64_t pos = MERGE_LOUP32(IPC_GET_ARG2(*req),
-	    IPC_GET_ARG3(*req));
+	int fd = ipc_get_arg1(req);
+	aoff64_t pos = MERGE_LOUP32(ipc_get_arg2(req),
+	    ipc_get_arg3(req));
 
 	size_t bytes = 0;
@@ -330,10 +330,10 @@
 		async_get_call(&call);
 
-		if (!IPC_GET_IMETHOD(call)) {
+		if (!ipc_get_imethod(&call)) {
 			async_answer_0(&call, EOK);
 			break;
 		}
 
-		switch (IPC_GET_IMETHOD(call)) {
+		switch (ipc_get_imethod(&call)) {
 		case VFS_IN_CLONE:
 			vfs_in_clone(&call);
Index: uspace/srv/vfs/vfs_lookup.c
===================================================================
--- uspace/srv/vfs/vfs_lookup.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_lookup.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -226,12 +226,12 @@
 
 	unsigned last = *pfirst + *plen;
-	*pfirst = IPC_GET_ARG3(answer) & 0xffff;
+	*pfirst = ipc_get_arg3(&answer) & 0xffff;
 	*plen = last - *pfirst;
 
-	result->triplet.fs_handle = (fs_handle_t) IPC_GET_ARG1(answer);
+	result->triplet.fs_handle = (fs_handle_t) ipc_get_arg1(&answer);
 	result->triplet.service_id = base->service_id;
-	result->triplet.index = (fs_index_t) IPC_GET_ARG2(answer);
-	result->size = MERGE_LOUP32(IPC_GET_ARG4(answer), IPC_GET_ARG5(answer));
-	result->type = (IPC_GET_ARG3(answer) >> 16) ?
+	result->triplet.index = (fs_index_t) ipc_get_arg2(&answer);
+	result->size = MERGE_LOUP32(ipc_get_arg4(&answer), ipc_get_arg5(&answer));
+	result->type = (ipc_get_arg3(&answer) >> 16) ?
 	    VFS_NODE_DIRECTORY : VFS_NODE_FILE;
 	return EOK;
Index: uspace/srv/vfs/vfs_node.c
===================================================================
--- uspace/srv/vfs/vfs_node.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_node.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -60,7 +60,7 @@
 #define KEY_INDEX	2
 
-static size_t nodes_key_hash(void *);
+static size_t nodes_key_hash(const void *);
 static size_t nodes_hash(const ht_link_t *);
-static bool nodes_key_equal(void *, const ht_link_t *);
+static bool nodes_key_equal(const void *, const ht_link_t *);
 static vfs_triplet_t node_triplet(vfs_node_t *node);
 
@@ -280,7 +280,7 @@
 }
 
-static size_t nodes_key_hash(void *key)
-{
-	vfs_triplet_t *tri = key;
+static size_t nodes_key_hash(const void *key)
+{
+	const vfs_triplet_t *tri = key;
 	size_t hash = hash_combine(tri->fs_handle, tri->index);
 	return hash_combine(hash, tri->service_id);
@@ -294,7 +294,7 @@
 }
 
-static bool nodes_key_equal(void *key, const ht_link_t *item)
-{
-	vfs_triplet_t *tri = key;
+static bool nodes_key_equal(const void *key, const ht_link_t *item)
+{
+	const vfs_triplet_t *tri = key;
 	vfs_node_t *node = hash_table_get_inst(item, vfs_node_t, nh_link);
 	return node->fs_handle == tri->fs_handle &&
Index: uspace/srv/vfs/vfs_ops.c
===================================================================
--- uspace/srv/vfs/vfs_ops.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_ops.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -90,8 +90,4 @@
 	errno_t rc;
 
-	/* If the file descriptors are the same, do nothing. */
-	if (oldfd == newfd)
-		return EOK;
-
 	/* Lookup the file structure corresponding to fd. */
 	vfs_file_t *oldfile = vfs_file_get(oldfd);
@@ -100,4 +96,10 @@
 
 	assert(oldfile->node != NULL);
+
+	/* If the file descriptors are the same, do nothing. */
+	if (oldfd == newfd) {
+		vfs_file_put(oldfile);
+		return EOK;
+	}
 
 	if (newfd != -1) {
@@ -168,7 +170,7 @@
 	res.triplet.fs_handle = fs_handle;
 	res.triplet.service_id = service_id;
-	res.triplet.index = (fs_index_t) IPC_GET_ARG1(answer);
-	res.size = (int64_t) MERGE_LOUP32(IPC_GET_ARG2(answer),
-	    IPC_GET_ARG3(answer));
+	res.triplet.index = (fs_index_t) ipc_get_arg1(&answer);
+	res.size = (int64_t) MERGE_LOUP32(ipc_get_arg2(&answer),
+	    ipc_get_arg3(&answer));
 	res.type = VFS_NODE_DIRECTORY;
 
@@ -374,5 +376,5 @@
 	}
 
-	*bytes = IPC_GET_ARG1(*answer);
+	*bytes = ipc_get_arg1(answer);
 	return rc;
 }
@@ -401,5 +403,5 @@
 	async_wait_for(msg, &rc);
 
-	chunk->size = IPC_GET_ARG1(*answer);
+	chunk->size = ipc_get_arg1(answer);
 
 	return (errno_t) rc;
@@ -488,6 +490,6 @@
 		/* Update the cached version of node's size. */
 		if (rc == EOK) {
-			file->node->size = MERGE_LOUP32(IPC_GET_ARG2(answer),
-			    IPC_GET_ARG3(answer));
+			file->node->size = MERGE_LOUP32(ipc_get_arg2(&answer),
+			    ipc_get_arg3(&answer));
 		}
 		fibril_rwlock_write_unlock(&file->node->contents_rwlock);
@@ -616,4 +618,9 @@
 		return EBADF;
 
+	if (!file->open_write || file->node->type != VFS_NODE_FILE) {
+		vfs_file_put(file);
+		return EINVAL;
+	}
+
 	fibril_rwlock_write_lock(&file->node->contents_rwlock);
 
@@ -637,6 +644,6 @@
 
 	async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
-	errno_t rc = async_data_read_forward_fast(exch, VFS_OUT_STAT,
-	    node->service_id, node->index, true, 0, NULL);
+	errno_t rc = async_data_read_forward_3_0(exch, VFS_OUT_STAT,
+	    node->service_id, node->index, true);
 	vfs_exchange_release(exch);
 
@@ -654,6 +661,6 @@
 
 	async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
-	errno_t rc = async_data_read_forward_fast(exch, VFS_OUT_STATFS,
-	    node->service_id, node->index, false, 0, NULL);
+	errno_t rc = async_data_read_forward_3_0(exch, VFS_OUT_STATFS,
+	    node->service_id, node->index, false);
 	vfs_exchange_release(exch);
 
@@ -892,4 +899,5 @@
 	rc = vfs_fd_alloc(&file, false, out_fd);
 	if (rc != EOK) {
+		fibril_rwlock_read_unlock(&namespace_rwlock);
 		vfs_node_put(node);
 		vfs_file_put(parent);
Index: uspace/srv/vfs/vfs_pager.c
===================================================================
--- uspace/srv/vfs/vfs_pager.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/vfs/vfs_pager.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -44,7 +44,7 @@
 void vfs_page_in(ipc_call_t *req)
 {
-	aoff64_t offset = IPC_GET_ARG1(*req);
-	size_t page_size = IPC_GET_ARG2(*req);
-	int fd = IPC_GET_ARG3(*req);
+	aoff64_t offset = ipc_get_arg1(req);
+	size_t page_size = ipc_get_arg2(req);
+	int fd = ipc_get_arg3(req);
 	void *page;
 	errno_t rc;
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision c878693123930f0906703462cf2807430679517e)
+++ uspace/srv/volsrv/volsrv.c	(revision de9e28e0c0b35a214dcdc3688dc8579f50c5fbd6)
@@ -138,5 +138,5 @@
 	errno_t rc;
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 
 	rc = vol_part_add_part(parts, sid);
@@ -156,5 +156,5 @@
 	errno_t rc;
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_info_srv(%zu)",
 	    sid);
@@ -204,5 +204,5 @@
 	errno_t rc;
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_srv(%zu)", sid);
 
@@ -230,5 +230,5 @@
 	errno_t rc;
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_insert_srv(%zu)", sid);
 
@@ -294,5 +294,5 @@
 	errno_t rc;
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_empty_srv(%zu)", sid);
 
@@ -320,5 +320,5 @@
 	errno_t rc;
 
-	fstype = IPC_GET_ARG1(*icall);
+	fstype = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_get_lsupp_srv(%u)",
 	    fstype);
@@ -362,6 +362,6 @@
 	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_mkfs_srv()");
 
-	sid = IPC_GET_ARG1(*icall);
-	fstype = IPC_GET_ARG2(*icall);
+	sid = ipc_get_arg1(icall);
+	fstype = ipc_get_arg2(icall);
 
 	rc = async_data_write_accept((void **)&label, true, 0, VOL_LABEL_MAXLEN,
@@ -424,5 +424,5 @@
 	log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_set_mountp_srv()");
 
-	sid = IPC_GET_ARG1(*icall);
+	sid = ipc_get_arg1(icall);
 
 	rc = async_data_write_accept((void **)&mountp, true, 0,
@@ -499,5 +499,5 @@
 	errno_t rc;
 
-	vid.id = IPC_GET_ARG1(*icall);
+	vid.id = ipc_get_arg1(icall);
 	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_info_srv(%zu)", vid.id);
 
@@ -556,5 +556,5 @@
 		ipc_call_t call;
 		async_get_call(&call);
-		sysarg_t method = IPC_GET_IMETHOD(call);
+		sysarg_t method = ipc_get_imethod(&call);
 
 		if (!method) {
