Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision e131833cdbc9561a0a17a58dba2c57bb8e4f8c3e)
+++ uspace/app/tester/Makefile	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -56,4 +56,5 @@
 	float/float2.c \
 	vfs/vfs1.c \
+	ipc/sharein.c \
 	ipc/starve.c \
 	loop/loop1.c \
Index: uspace/app/tester/ipc/sharein.c
===================================================================
--- uspace/app/tester/ipc/sharein.c	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
+++ uspace/app/tester/ipc/sharein.c	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -0,0 +1,78 @@
+/*
+ * 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 <as.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ipc_test.h>
+#include "../tester.h"
+
+const char *test_sharein(void)
+{
+	ipc_test_t *test = NULL;
+	const void *ro_ptr;
+	size_t ro_size;
+	void *rw_ptr;
+	size_t rw_size;
+	errno_t rc;
+
+	rc = ipc_test_create(&test);
+	if (rc != EOK)
+		return "Error contacting IPC test service.";
+
+	rc = ipc_test_get_ro_area_size(test, &ro_size);
+	if (rc != EOK)
+		return "Error getting read-only area size.";
+
+	rc = ipc_test_share_in_ro(test, ro_size, &ro_ptr);
+	if (rc != EOK)
+		return "Error sharing in area.";
+
+	TPRINTF("Successfully shared in read-only area.\n");
+	TPRINTF("Byte from shared read-only area: 0x%02x\n",
+	    *(const uint8_t *)ro_ptr);
+
+	as_area_destroy((void *)ro_ptr);
+
+	rc = ipc_test_get_rw_area_size(test, &rw_size);
+	if (rc != EOK)
+		return "Error getting read-write area size.";
+
+	rc = ipc_test_share_in_rw(test, rw_size, &rw_ptr);
+	if (rc != EOK)
+		return "Error sharing in area.";
+
+	TPRINTF("Successfully shared in read-write area.\n");
+	TPRINTF("Byte from shared read-write area: 0x%02x\n",
+	    *(uint8_t *)rw_ptr);
+
+	ipc_test_destroy(test);
+	return NULL;
+}
Index: uspace/app/tester/ipc/sharein.def
===================================================================
--- uspace/app/tester/ipc/sharein.def	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
+++ uspace/app/tester/ipc/sharein.def	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -0,0 +1,6 @@
+{
+	"sharein",
+	"IPC share in test",
+	&test_sharein,
+	true
+},
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision e131833cdbc9561a0a17a58dba2c57bb8e4f8c3e)
+++ uspace/app/tester/tester.c	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -66,4 +66,5 @@
 #include "float/float2.def"
 #include "vfs/vfs1.def"
+#include "ipc/sharein.def"
 #include "ipc/starve.def"
 #include "loop/loop1.def"
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision e131833cdbc9561a0a17a58dba2c57bb8e4f8c3e)
+++ uspace/app/tester/tester.h	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -99,4 +99,5 @@
 extern const char *test_vfs1(void);
 extern const char *test_ping_pong(void);
+extern const char *test_sharein(void);
 extern const char *test_starve_ipc(void);
 extern const char *test_loop1(void);
Index: uspace/lib/c/generic/as.c
===================================================================
--- uspace/lib/c/generic/as.c	(revision e131833cdbc9561a0a17a58dba2c57bb8e4f8c3e)
+++ uspace/lib/c/generic/as.c	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -108,4 +108,19 @@
 }
 
+/** Get address-space area information.
+ *
+ * @param address Virtual address pointing into the address space area being
+ *                modified.
+ * @param info    Pointer to information structure to fill in.
+ *
+ * @return zero on success or a code from @ref errno.h on failure.
+ *
+ */
+errno_t as_area_get_info(void *address, as_area_info_t *info)
+{
+	return (errno_t) __SYSCALL2(SYS_AS_AREA_GET_INFO, (sysarg_t) address,
+	    (sysarg_t) info);
+}
+
 /** Find mapping to physical address.
  *
Index: uspace/lib/c/generic/ipc_test.c
===================================================================
--- uspace/lib/c/generic/ipc_test.c	(revision e131833cdbc9561a0a17a58dba2c57bb8e4f8c3e)
+++ uspace/lib/c/generic/ipc_test.c	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -34,4 +34,5 @@
 
 #include <abi/ipc/interfaces.h>
+#include <as.h>
 #include <errno.h>
 #include <ipc/services.h>
@@ -111,4 +112,113 @@
 }
 
+/** Get size of shared read-only memory area.
+ *
+ * @param test IPC test service
+ * @param rsize Place to store size of the shared area
+ * @return EOK on success or an error code
+ */
+errno_t ipc_test_get_ro_area_size(ipc_test_t *test, size_t *rsize)
+{
+	async_exch_t *exch;
+	errno_t retval;
+	sysarg_t size;
+
+	exch = async_exchange_begin(test->sess);
+	retval = async_req_0_1(exch, IPC_TEST_GET_RO_AREA_SIZE, &size);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return retval;
+
+	*rsize = size;
+	return EOK;
+}
+
+/** Get size of shared read-write memory area.
+ *
+ * @param test IPC test service
+ * @param rsize Place to store size of the shared area
+ * @return EOK on success or an error code
+ */
+errno_t ipc_test_get_rw_area_size(ipc_test_t *test, size_t *rsize)
+{
+	async_exch_t *exch;
+	errno_t retval;
+	sysarg_t size;
+
+	exch = async_exchange_begin(test->sess);
+	retval = async_req_0_1(exch, IPC_TEST_GET_RW_AREA_SIZE, &size);
+	async_exchange_end(exch);
+
+	if (retval != EOK)
+		return retval;
+
+	*rsize = size;
+	return EOK;
+}
+
+/** Test share-in of read-only area.
+ *
+ * @param test IPC test service
+ * @param size Size of the shared area
+ * @param rptr Place to store pointer to the shared-in area
+ * @return EOK on success or an error code
+ */
+errno_t ipc_test_share_in_ro(ipc_test_t *test, size_t size, const void **rptr)
+{
+	async_exch_t *exch;
+	ipc_call_t answer;
+	aid_t req;
+	void *dst;
+	errno_t rc;
+
+	exch = async_exchange_begin(test->sess);
+	req = async_send_0(exch, IPC_TEST_SHARE_IN_RO, &answer);
+
+	dst = NULL;
+	rc = async_share_in_start_0_0(exch, size, &dst);
+	if (rc != EOK || dst == AS_MAP_FAILED) {
+		async_exchange_end(exch);
+		async_forget(req);
+		return ENOMEM;
+	}
+
+	async_exchange_end(exch);
+	async_wait_for(req, NULL);
+	*rptr = dst;
+	return EOK;
+}
+
+/** Test share-in of read-write area.
+ *
+ * @param test IPC test service
+ * @param size Size of the shared area
+ * @param rptr Place to store pointer to the shared-in area
+ * @return EOK on success or an error code
+ */
+errno_t ipc_test_share_in_rw(ipc_test_t *test, size_t size, void **rptr)
+{
+	async_exch_t *exch;
+	ipc_call_t answer;
+	aid_t req;
+	void *dst;
+	errno_t rc;
+
+	exch = async_exchange_begin(test->sess);
+	req = async_send_0(exch, IPC_TEST_SHARE_IN_RW, &answer);
+
+	rc = async_share_in_start_0_0(exch, size, &dst);
+	if (rc != EOK || dst == AS_MAP_FAILED) {
+		async_exchange_end(exch);
+		async_forget(req);
+		return ENOMEM;
+	}
+
+	async_exchange_end(exch);
+	async_wait_for(req, NULL);
+	*rptr = dst;
+	return EOK;
+}
+
 /** @}
  */
Index: uspace/lib/c/include/as.h
===================================================================
--- uspace/lib/c/include/as.h	(revision e131833cdbc9561a0a17a58dba2c57bb8e4f8c3e)
+++ uspace/lib/c/include/as.h	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -59,4 +59,5 @@
 extern errno_t as_area_resize(void *, size_t, unsigned int);
 extern errno_t as_area_change_flags(void *, unsigned int);
+extern errno_t as_area_get_info(void *, as_area_info_t *);
 extern errno_t as_area_destroy(void *);
 extern void *set_maxheapsize(size_t);
Index: uspace/lib/c/include/ipc/ipc_test.h
===================================================================
--- uspace/lib/c/include/ipc/ipc_test.h	(revision e131833cdbc9561a0a17a58dba2c57bb8e4f8c3e)
+++ uspace/lib/c/include/ipc/ipc_test.h	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -39,5 +39,9 @@
 
 typedef enum {
-	IPC_TEST_PING = IPC_FIRST_USER_METHOD
+	IPC_TEST_PING = IPC_FIRST_USER_METHOD,
+	IPC_TEST_GET_RO_AREA_SIZE,
+	IPC_TEST_GET_RW_AREA_SIZE,
+	IPC_TEST_SHARE_IN_RO,
+	IPC_TEST_SHARE_IN_RW
 } ipc_test_request_t;
 
Index: uspace/lib/c/include/ipc_test.h
===================================================================
--- uspace/lib/c/include/ipc_test.h	(revision e131833cdbc9561a0a17a58dba2c57bb8e4f8c3e)
+++ uspace/lib/c/include/ipc_test.h	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -46,4 +46,8 @@
 extern void ipc_test_destroy(ipc_test_t *);
 extern errno_t ipc_test_ping(ipc_test_t *);
+extern errno_t ipc_test_get_ro_area_size(ipc_test_t *, size_t *);
+extern errno_t ipc_test_get_rw_area_size(ipc_test_t *, size_t *);
+extern errno_t ipc_test_share_in_ro(ipc_test_t *, size_t, const void **);
+extern errno_t ipc_test_share_in_rw(ipc_test_t *, size_t, void **);
 
 #endif
Index: uspace/srv/test/chardev-test/doc/doxygroups.h
===================================================================
--- uspace/srv/test/chardev-test/doc/doxygroups.h	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
+++ uspace/srv/test/chardev-test/doc/doxygroups.h	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -0,0 +1,4 @@
+/** @addtogroup chardev-test chardev-test
+ * @ingroup srvs
+ * @brief Character device interface test service
+ */
Index: uspace/srv/test/chardev-test/main.c
===================================================================
--- uspace/srv/test/chardev-test/main.c	(revision e131833cdbc9561a0a17a58dba2c57bb8e4f8c3e)
+++ uspace/srv/test/chardev-test/main.c	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -27,4 +27,12 @@
  */
 
+/** @addtogroup chardev-test
+ * @{
+ */
+/**
+ * @file
+ * @brief Character device interface test service
+ */
+
 #include <async.h>
 #include <errno.h>
@@ -259,2 +267,6 @@
 	return EIO;
 }
+
+/**
+ * @}
+ */
Index: uspace/srv/test/ipc-test/doc/doxygroups.h
===================================================================
--- uspace/srv/test/ipc-test/doc/doxygroups.h	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
+++ uspace/srv/test/ipc-test/doc/doxygroups.h	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -0,0 +1,4 @@
+/** @addtogroup ipc-test ipc-test
+ * @ingroup srvs
+ * @brief IPC test service
+ */
Index: uspace/srv/test/ipc-test/main.c
===================================================================
--- uspace/srv/test/ipc-test/main.c	(revision e131833cdbc9561a0a17a58dba2c57bb8e4f8c3e)
+++ uspace/srv/test/ipc-test/main.c	(revision 3b3fcf369f7972634c32240f6c2c7e342deadefe)
@@ -27,7 +27,20 @@
  */
 
+/** @addtogroup ipc-test
+ * @{
+ */
+/**
+ * @file
+ * @brief IPC test service
+ *
+ * If run as an initial task, this can be used to test sharing areas
+ * backed by the ELF backend.
+ */
+
+#include <as.h>
 #include <async.h>
 #include <errno.h>
 #include <str_error.h>
+#include <io/log.h>
 #include <ipc/ipc_test.h>
 #include <ipc/services.h>
@@ -41,4 +54,132 @@
 static service_id_t svc_id;
 
+/** Object in read-only memory area that will be shared.
+ *
+ * If the server is run as an initial task, the area should be backed
+ * by ELF backend.
+ */
+static const char *ro_data = "Hello, world!";
+
+/** Object in read-write memory area that will be shared.
+ *
+ * If the server is run as an initial task, the area should be backed
+ * by ELF backend.
+ */
+static char rw_data[] = "Hello, world!";
+
+static void ipc_test_get_ro_area_size_srv(ipc_call_t *icall)
+{
+	errno_t rc;
+	as_area_info_t info;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ipc_test_get_ro_area_size_srv");
+
+	rc = as_area_get_info((void *)ro_data, &info);
+	if (rc != EOK) {
+		async_answer_0(icall, EIO);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "as_area_get_info failed");
+		return;
+	}
+
+	async_answer_1(icall, EOK, info.size);
+}
+
+static void ipc_test_get_rw_area_size_srv(ipc_call_t *icall)
+{
+	errno_t rc;
+	as_area_info_t info;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ipc_test_get_rw_area_size_srv");
+
+	rc = as_area_get_info(rw_data, &info);
+	if (rc != EOK) {
+		async_answer_0(icall, EIO);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "as_area_get_info failed");
+		return;
+	}
+
+	async_answer_1(icall, EOK, info.size);
+}
+
+static void ipc_test_share_in_ro_srv(ipc_call_t *icall)
+{
+	ipc_call_t call;
+	errno_t rc;
+	size_t size;
+	as_area_info_t info;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ipc_test_share_in_ro_srv");
+	if (!async_share_in_receive(&call, &size)) {
+		async_answer_0(icall, EINVAL);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "share_in_receive failed");
+		return;
+	}
+
+	rc = as_area_get_info((void *)ro_data, &info);
+	if (rc != EOK) {
+		async_answer_0(icall, EINVAL);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "as_area_get_info failed");
+		return;
+	}
+
+	if (size != info.size) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, "size(%zu) != %zu",
+		    size, info.size);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	rc = async_share_in_finalize(&call, (void *) info.start_addr,
+	    AS_AREA_READ);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR,
+		    " - async_share_in_finalize failed");
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	async_answer_0(icall, EOK);
+}
+
+static void ipc_test_share_in_rw_srv(ipc_call_t *icall)
+{
+	ipc_call_t call;
+	errno_t rc;
+	size_t size;
+	as_area_info_t info;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "ipc_test_share_in_ro_srv");
+	if (!async_share_in_receive(&call, &size)) {
+		async_answer_0(icall, EINVAL);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "share_in_receive failed");
+		return;
+	}
+
+	rc = as_area_get_info(rw_data, &info);
+	if (rc != EOK) {
+		async_answer_0(icall, EINVAL);
+		log_msg(LOG_DEFAULT, LVL_ERROR, "as_area_get_info failed");
+		return;
+	}
+
+	if (size != info.size) {
+		log_msg(LOG_DEFAULT, LVL_ERROR, " size(%zu) != %zu",
+		    size, info.size);
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	rc = async_share_in_finalize(&call, (void *) info.start_addr,
+	    AS_AREA_READ | AS_AREA_WRITE);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_ERROR,
+		    "async_share_in_finalize failed");
+		async_answer_0(icall, EINVAL);
+		return;
+	}
+
+	async_answer_0(icall, EOK);
+}
+
 static void ipc_test_connection(ipc_call_t *icall, void *arg)
 {
@@ -59,4 +200,16 @@
 			async_answer_0(&call, EOK);
 			break;
+		case IPC_TEST_GET_RO_AREA_SIZE:
+			ipc_test_get_ro_area_size_srv(&call);
+			break;
+		case IPC_TEST_GET_RW_AREA_SIZE:
+			ipc_test_get_rw_area_size_srv(&call);
+			break;
+		case IPC_TEST_SHARE_IN_RO:
+			ipc_test_share_in_ro_srv(&call);
+			break;
+		case IPC_TEST_SHARE_IN_RW:
+			ipc_test_share_in_rw_srv(&call);
+			break;
 		default:
 			async_answer_0(&call, ENOTSUP);
@@ -73,7 +226,13 @@
 	async_set_fallback_port_handler(ipc_test_connection, NULL);
 
+	rc = log_init(NAME);
+	if (rc != EOK) {
+		printf(NAME ": Failed to initialize log.\n");
+		return rc;
+	}
+
 	rc = loc_server_register(NAME);
 	if (rc != EOK) {
-		printf("%s: Failed registering server. (%s)\n", NAME,
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering server. (%s)\n",
 		    str_error(rc));
 		return rc;
@@ -82,5 +241,5 @@
 	rc = loc_service_register(SERVICE_NAME_IPC_TEST, &svc_id);
 	if (rc != EOK) {
-		printf("%s: Failed registering service. (%s)\n", NAME,
+		log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service. (%s)\n",
 		    str_error(rc));
 		return rc;
@@ -94,2 +253,6 @@
 	return 0;
 }
+
+/**
+ * @}
+ */
