diff --git a/project/common.mk b/project/common.mk
index 5b34286..6573439 100644
--- a/project/common.mk
+++ b/project/common.mk
@@ -1,4 +1,5 @@
 COMMON_SRCS = \
+	src/internal/slibtool_errinfo_impl.c \
 	src/internal/slibtool_libmeta_impl.c \
 	src/internal/slibtool_objmeta_impl.c \
 	src/internal/slibtool_symlink_impl.c \
diff --git a/project/headers.mk b/project/headers.mk
index eb78201..20fa046 100644
--- a/project/headers.mk
+++ b/project/headers.mk
@@ -5,6 +5,7 @@ API_HEADERS = \
 INTERNAL_HEADERS = \
 	$(PROJECT_DIR)/src/internal/argv/argv.h \
 	$(PROJECT_DIR)/src/internal/$(PACKAGE)_driver_impl.h \
+	$(PROJECT_DIR)/src/internal/$(PACKAGE)_errinfo_impl.h \
 	$(PROJECT_DIR)/src/internal/$(PACKAGE)_install_impl.h \
 	$(PROJECT_DIR)/src/internal/$(PACKAGE)_metafile_impl.h \
 	$(PROJECT_DIR)/src/internal/$(PACKAGE)_mkdir_impl.h \
diff --git a/src/internal/slibtool_errinfo_impl.c b/src/internal/slibtool_errinfo_impl.c
new file mode 100644
index 0000000..889f566
--- /dev/null
+++ b/src/internal/slibtool_errinfo_impl.c
@@ -0,0 +1,41 @@
+/*******************************************************************/
+/*  slibtool: a skinny libtool implementation, written in C        */
+/*  Copyright (C) 2016  Z. Gilboa                                  */
+/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
+/*******************************************************************/
+
+#include <slibtool/slibtool.h>
+#include "slibtool_driver_impl.h"
+#include "slibtool_errinfo_impl.h"
+
+int slbt_record_error(
+	const struct slbt_driver_ctx *	dctx,
+	int				syserror,
+	int				liberror,
+	const char *			function,
+	int				line,
+	unsigned			flags,
+	void *				ctx)
+{
+	struct slbt_driver_ctx_impl *	ictx;
+	struct slbt_error_info *	erri;
+
+	ictx = slbt_get_driver_ictx(dctx);
+
+	if (ictx->errinfp == ictx->erricap)
+		return -1;
+
+	*ictx->errinfp = &ictx->erribuf[ictx->errinfp - ictx->erriptr];
+	erri = *ictx->errinfp;
+
+	erri->syserror = syserror;
+	erri->liberror = liberror;
+	erri->function = function;
+	erri->line     = line;
+	erri->flags    = flags;
+	erri->ctx      = ctx;
+
+	ictx->errinfp++;
+
+	return -1;
+}
diff --git a/src/internal/slibtool_errinfo_impl.h b/src/internal/slibtool_errinfo_impl.h
new file mode 100644
index 0000000..c830975
--- /dev/null
+++ b/src/internal/slibtool_errinfo_impl.h
@@ -0,0 +1,80 @@
+/*******************************************************************/
+/*  slibtool: a skinny libtool implementation, written in C        */
+/*  Copyright (C) 2016  Z. Gilboa                                  */
+/*  Released under the Standard MIT License; see COPYING.SLIBTOOL. */
+/*******************************************************************/
+
+#include <errno.h>
+#include <slibtool/slibtool.h>
+
+int slbt_record_error(
+	const struct slbt_driver_ctx *,
+	int		syserror,
+	int		liberror,
+	const char *	function,
+	int		line,
+	unsigned	flags,
+	void *		ctx);
+
+#define SLBT_SYSTEM_ERROR(dctx)           \
+	slbt_record_error(                \
+		dctx,                     \
+		errno,                    \
+		0,                        \
+		__func__,                 \
+		__LINE__,                 \
+		SLBT_ERROR_TOP_LEVEL,     \
+		0)
+
+#define SLBT_BUFFER_ERROR(dctx)           \
+	slbt_record_error(                \
+		dctx,                     \
+		ENOBUFS,                  \
+		0,                        \
+		__func__,                 \
+		__LINE__,                 \
+		SLBT_ERROR_TOP_LEVEL,     \
+		0)
+
+#define SLBT_SPAWN_ERROR(dctx)            \
+	slbt_record_error(                \
+		dctx,                     \
+		errno,                    \
+		0,                        \
+		__func__,                 \
+		__LINE__,                 \
+		SLBT_ERROR_TOP_LEVEL      \
+		| (errno ? 0              \
+		   : SLBT_ERROR_CHILD),   \
+		0)
+
+#define SLBT_FILE_ERROR(dctx)             \
+	slbt_record_error(                \
+		dctx,                     \
+		EIO,                      \
+		0,                        \
+		__func__,                 \
+		__LINE__,                 \
+		SLBT_ERROR_TOP_LEVEL,     \
+		0)
+
+#define SLBT_CUSTOM_ERROR(dctx,liberror)  \
+	slbt_record_error(                \
+		dctx,                     \
+		0,                        \
+		liberror,                 \
+		__func__,                 \
+		__LINE__,                 \
+		SLBT_ERROR_TOP_LEVEL      \
+		| SLBT_ERROR_CUSTOM,      \
+		0)
+
+#define SLBT_NESTED_ERROR(dctx)           \
+	slbt_record_error(                \
+		dctx,                     \
+		0,                        \
+		0,                        \
+		__func__,                 \
+		__LINE__,                 \
+		SLBT_ERROR_NESTED,        \
+		0)