Added sel4_strerror() and some convenience macros for ZF_LOG().

* Moved sel4_strerror and ZF_LOG into seL4_libs, as opposed to util_libs.
* New library function sel4_strerror():
  * Does what your gut thinks: prints a stringified version of an seL4 system
    error code.
* New macros to make logging cleaner and reduce code size:
  * Can be found in sel4_zf_logif.h.
  * ZF_LOG?_IF(condition, fmt, ...):
    * Prints to log if "condition" is true.
  * ZF_LOG?_IFERR(error, fmt, ...):
    * Prints to log if error != 0.
    * Also prints stringified version of error code.
* Added static index-checking to an array of error-code strings.
* Moved sel4_debug.[ch] from libsel4utils into libsel4debug.
diff --git a/libsel4debug/include/sel4debug/sel4_debug.h b/libsel4debug/include/sel4debug/sel4_debug.h
new file mode 100644
index 0000000..baa6f9b
--- /dev/null
+++ b/libsel4debug/include/sel4debug/sel4_debug.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2014, NICTA
+ *
+ * This software may be distributed and modified according to the terms of
+ * the BSD 2-Clause license. Note that NO WARRANTY is provided.
+ * See "LICENSE_BSD2.txt" for details.
+ *
+ * @TAG(NICTA_BSD)
+ */
+
+#ifndef _SEL4_DEBUG_H_
+#define _SEL4_DEBUG_H_
+
+#define	sel4_error(e, str)	((e == seL4_NoError) ? (void)0 : __sel4_error(e, __FILE__, __func__, __LINE__, str))
+
+void __sel4_error(int, const char *, const char *, int, char *);
+
+const char *sel4_strerror(int errcode);
+extern char *sel4_errlist[];
+
+#endif /* _SEL4_DEBUG_ */
diff --git a/libsel4debug/src/sel4_debug.c b/libsel4debug/src/sel4_debug.c
new file mode 100644
index 0000000..1f75304
--- /dev/null
+++ b/libsel4debug/src/sel4_debug.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2014, NICTA
+ *
+ * This software may be distributed and modified according to the terms of
+ * the BSD 2-Clause license. Note that NO WARRANTY is provided.
+ * See "LICENSE_BSD2.txt" for details.
+ *
+ * @TAG(NICTA_BSD)
+ */
+
+#include <stdio.h> /* For fprintf() */
+#include <stdlib.h> /* For abort() */
+#include <assert.h>
+#include <sel4/sel4.h>
+#include <sel4utils/sel4_debug.h>
+#include <utils/stringify.h>
+
+char *sel4_errlist[] = {
+    [seL4_NoError] = STRINGIFY(seL4_NoError),
+    [seL4_InvalidArgument] = STRINGIFY(seL4_InvalidArgument),
+    [seL4_InvalidCapability] = STRINGIFY(seL4_InvalidCapability),
+    [seL4_IllegalOperation] = STRINGIFY(seL4_IllegalOperation),
+    [seL4_RangeError] = STRINGIFY(seL4_RangeError),
+    [seL4_AlignmentError] = STRINGIFY(seL4_AlignmentError),
+    [seL4_FailedLookup] = STRINGIFY(seL4_FailedLookup),
+    [seL4_TruncatedMessage] = STRINGIFY(seL4_TruncatedMessage),
+    [seL4_DeleteFirst] = STRINGIFY(seL4_DeleteFirst),
+    [seL4_RevokeFirst] = STRINGIFY(seL4_RevokeFirst),
+    [seL4_NotEnoughMemory] = STRINGIFY(seL4_NotEnoughMemory),
+    NULL
+};
+
+const char *
+sel4_strerror(int errcode)
+{
+    assert(errcode < sizeof(sel4_errlist) / sizeof(*sel4_errlist) - 1);
+    return sel4_errlist[errcode];
+}
+
+void
+__sel4_error(int sel4_error, const char *file,
+             const char *function, int line, char * str)
+{
+    fprintf(stderr, "seL4 Error: %s, function %s, file %s, line %d: %s\n",
+            sel4_errlist[sel4_error],
+            function, file, line, str);
+    abort();
+}
diff --git a/libsel4utils/include/sel4utils/sel4_debug.h b/libsel4utils/include/sel4utils/sel4_debug.h
index 6dc88fb..4304564 100644
--- a/libsel4utils/include/sel4utils/sel4_debug.h
+++ b/libsel4utils/include/sel4utils/sel4_debug.h
@@ -8,13 +8,9 @@
  * @TAG(NICTA_BSD)
  */
 
-#ifndef _SEL4_DEBUG_H_
-#define _SEL4_DEBUG_H_
+#ifndef _SEL4UTILS_SEL4_DEBUG_H_
+#define _SEL4UTILS_SEL4_DEBUG_H_
 
-#define	sel4_error(e, str)	((e == seL4_NoError) ? (void)0 : __sel4_error(e, __FILE__, __func__, __LINE__, str))
+#include <sel4debug/sel4_debug.h>
 
-void __sel4_error(int, const char *, const char *, int, const char *);
-
-extern const char *sel4_errlist[];
-
-#endif /* _SEL4_DEBUG_ */
+#endif /* _SEL4UTILS_SEL4_DEBUG_H_ */
diff --git a/libsel4utils/include/sel4utils/sel4_zf_logif.h b/libsel4utils/include/sel4utils/sel4_zf_logif.h
new file mode 100644
index 0000000..1abb698
--- /dev/null
+++ b/libsel4utils/include/sel4utils/sel4_zf_logif.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014, NICTA
+ *
+ * This software may be distributed and modified according to the terms of
+ * the BSD 2-Clause license. Note that NO WARRANTY is provided.
+ * See "LICENSE_BSD2.txt" for details.
+ *
+ * @TAG(NICTA_BSD)
+ */
+
+#ifndef _SEL4_ZF_LOGIF_H
+#define _SEL4_ZF_LOGIF_H
+
+#include <utils/zf_log.h>
+#include <sel4utils/sel4_debug.h>
+
+/*  sel4_zf_logif.h:
+ * This file contains some convenience macros built on top of the ZF_LOG
+ * library, to reduce source size and improve single-line readability.
+ *
+ * ZF_LOG?_IF(condition, fmt, ...):
+ *  These will call the relevant ZF_LOG?() macro if "condition" evaluates to
+ *  true at runtime.
+ *
+ * ZF_LOG?_IFERR(errorcode, fmt, ...):
+ *  These will call the relevant ZF_LOG?() macro if "errorcode" is not 0, at
+ *  runtime.
+ */
+
+#define ZF_LOGD_IF(cond, fmt, ...) \
+	if ((cond)) { ZF_LOGD("[Cond failed: %s]\n\t" fmt, #cond, ## __VA_ARGS__); }
+#define ZF_LOGI_IF(cond, fmt, ...) \
+	if ((cond)) { ZF_LOGI("[Cond failed: %s]\n\t" fmt, #cond, ## __VA_ARGS__); }
+#define ZF_LOGW_IF(cond, fmt, ...) \
+	if ((cond)) { ZF_LOGW("[Cond failed: %s]\n\t" fmt, #cond, ## __VA_ARGS__); }
+#define ZF_LOGE_IF(cond, fmt, ...) \
+	if ((cond)) { ZF_LOGE("[Cond failed: %s]\n\t" fmt, #cond, ## __VA_ARGS__); }
+#define ZF_LOGF_IF(cond, fmt, ...) \
+	if ((cond)) { ZF_LOGF("[Cond failed: %s]\n\t" fmt, #cond, ## __VA_ARGS__); }
+
+#define ZF_LOGD_IFERR(err, fmt, ...) \
+	if ((err) != seL4_NoError) \
+		{ ZF_LOGD("[Err %s]:\n\t" fmt, sel4_strerror(err), ## __VA_ARGS__); }
+
+#define ZF_LOGI_IFERR(err, fmt, ...) \
+	if ((err) != seL4_NoError) \
+		{ ZF_LOGI("[Err %s]:\n\t" fmt, sel4_strerror(err), ## __VA_ARGS__); }
+
+#define ZF_LOGW_IFERR(err, fmt, ...) \
+	if ((err) != seL4_NoError) \
+		{ ZF_LOGW("[Err %s]:\n\t" fmt, sel4_strerror(err), ## __VA_ARGS__); }
+
+#define ZF_LOGE_IFERR(err, fmt, ...) \
+	if ((err) != seL4_NoError) \
+		{ ZF_LOGE("[Err %s]:\n\t" fmt, sel4_strerror(err), ## __VA_ARGS__); }
+
+#define ZF_LOGF_IFERR(err, fmt, ...) \
+	if ((err) != seL4_NoError) \
+		{ ZF_LOGF("[Err %s]:\n\t" fmt, sel4_strerror(err), ## __VA_ARGS__); }
+
+#endif /* _SEL4_ZF_LOGIF_H */
diff --git a/libsel4utils/src/sel4_debug.c b/libsel4utils/src/sel4_debug.c
deleted file mode 100644
index 8f64b50..0000000
--- a/libsel4utils/src/sel4_debug.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2014, NICTA
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(NICTA_BSD)
- */
-
-#include <stdio.h> /* For fprintf() */
-#include <stdlib.h> /* For abort() */
-#include <sel4utils/sel4_debug.h>
-
-const char *sel4_errlist[] = {
-    "seL4_NoError",
-    "seL4_InvalidArgument",
-    "seL4_InvalidCapability",
-    "seL4_IllegalOperation",
-    "seL4_RangeError",
-    "seL4_AlignmentError",
-    "seL4_FailedLookup",
-    "seL4_TruncatedMessage",
-    "seL4_DeleteFirst",
-    "seL4_RevokeFirst",
-    "seL4_NotEnoughMemory",
-    NULL
-};
-
-void
-__sel4_error(int sel4_error, const char *file,
-             const char *function, int line, const char * str)
-{
-    fprintf(stderr, "seL4 Error: %s, function %s, file %s, line %d: %s\n",
-            sel4_errlist[sel4_error],
-            function, file, line, str);
-    abort();
-}