diff --git a/default.nix b/default.nix
index 496ddf3..2ff7811 100644
--- a/default.nix
+++ b/default.nix
@@ -10,6 +10,7 @@ let
dhallPackages = super.dhallPackages // (callPackage ./dhall { });
genode = callPackage ./upstream { };
nova = callPackage ./NOVA { };
+ solo5 = callPackage ./solo5 { };
};
toolchainOverlay = import ./toolchain-overlay;
diff --git a/release.nix b/release.nix
index abf4f07..1c35774 100644
--- a/release.nix
+++ b/release.nix
@@ -8,7 +8,7 @@
let pkgs = import ./default.nix { inherit nixpkgs; };
in {
build.x86_64 = {
- inherit (pkgs) nova stdenv;
+ inherit (pkgs) nova stdenv solo5;
genode = removeAttrs pkgs.genode [ "override" "overrideDerivation" ];
};
diff --git a/solo5/default.nix b/solo5/default.nix
new file mode 100644
index 0000000..0ef1550
--- /dev/null
+++ b/solo5/default.nix
@@ -0,0 +1,40 @@
+# SPDX-FileCopyrightText: Emery Hemingway
+#
+# SPDX-License-Identifier: LicenseRef-Hippocratic-1.1
+
+{ stdenv, buildPackages, fetchurl, llvmPackages }:
+
+let version = "0.6.2";
+in stdenv.mkDerivation {
+ pname = "solo5";
+ inherit version;
+
+ outputs = [ "out" "tests" ];
+
+ src = fetchurl {
+ url = "https://github.com/Solo5/solo5/releases/download/v${version}/solo5-v${version}.tar.gz";
+ sha256 = "0wi836wzv41carkxh16ajq2gzg65ns622byyibfc5ii8lvzww0ri";
+ };
+
+ patches = [ ./genode.patch ];
+
+ enableParallelBuilding = true;
+
+ configurePhase = "HOSTCC=${buildPackages.stdenv.cc}/bin/cc sh configure.sh";
+
+ installPhase = ''
+ mkdir -p $out/bin $tests/bin
+ make install-opam-genode PREFIX=$out
+ for test in tests/*/*.genode; do
+ cp $test $tests/bin/solo5-`basename $test .genode`
+ done
+ '';
+
+ meta = with stdenv.lib; {
+ description = "Sandboxed execution environment.";
+ homepage = "https://github.com/solo5/solo5";
+ license = licenses.isc;
+ maintainers = [ maintainers.ehmry ];
+ };
+
+}
diff --git a/solo5/genode.patch b/solo5/genode.patch
new file mode 100644
index 0000000..9cb4e28
--- /dev/null
+++ b/solo5/genode.patch
@@ -0,0 +1,513 @@
+diff --git a/GNUmakefile b/GNUmakefile
+index e168853..9cc46a7 100644
+--- a/GNUmakefile
++++ b/GNUmakefile
+@@ -100,7 +100,7 @@ install-opam-%: all opam/solo5-bindings-%.pc force-install
+ $(PREFIX)/lib/solo5-bindings-$* \
+ $(PREFIX)/include/solo5-bindings-$*/solo5 \
+ $(PREFIX)/include/solo5-bindings-$*/crt
+- cp -R include/solo5 include/crt $(PREFIX)/include/solo5-bindings-$*
++ cp -R include/solo5 $(PREFIX)/include/solo5-bindings-$*
+ ifndef CONFIG_GENODE
+ cp bindings/$*/solo5_$*.o bindings/$*/solo5_$*.lds \
+ $(PREFIX)/lib/solo5-bindings-$*
+@@ -109,7 +109,6 @@ else
+ $(PREFIX)/lib/solo5-bindings-$*
+ endif
+ cp opam/solo5-bindings-$*.pc $(PREFIX)/lib/pkgconfig
+- cp elftool/solo5-elftool $(PREFIX)/bin
+ ifdef CONFIG_HVT
+ cp tenders/hvt/solo5-hvt tenders/hvt/solo5-hvt-configure $(PREFIX)/bin
+ - [ -f tenders/hvt/solo5-hvt-debug ] && \
+diff --git a/Makefile.common b/Makefile.common
+index 5ccc2ea..a7d5671 100644
+--- a/Makefile.common
++++ b/Makefile.common
+@@ -31,6 +31,7 @@ include $(TOPDIR)/Makeconf
+ #
+ CC := $(MAKECONF_CC)
+ CFLAGS := -std=c11 -Wall -Wextra -Werror -O2 -g
++CXXLAGS += -std=gnu++17 -Wall -Wextra -Werror -O2 -g
+ CFLAGS += -ffreestanding -fstack-protector-strong $(MAKECONF_CFLAGS)
+ CPPFLAGS := -isystem $(TOPDIR)/include/crt -I$(TOPDIR)/include/solo5
+ LD := $(MAKECONF_LD)
+@@ -53,6 +54,12 @@ define COMPILE.c
+ mv -f $*.Td $*.d && touch $@
+ endef
+
++define COMPILE.cc
++ @echo "CXX $<"
++ $(CXX) $(DEPFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@
++ mv -f $*.Td $*.d && touch $@
++endef
++
+ define COMPILE.S
+ @echo "AS $<"
+ $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -DASM_FILE -c $< -o $@
+@@ -63,7 +70,7 @@ endef
+ # The following variables and recpies apply to building tenders, i.e.
+ # artifacts built to run on the (Solo5 tender's) *host*.
+ #
+-HOSTCC := $(MAKECONF_CC)
++HOSTCC := $(MAKECONF_HOSTCC)
+ HOSTCFLAGS := -Wall -Werror -std=c11 -fstack-protector-strong -O2 -g
+ HOSTCPPFLAGS := -I$(TOPDIR)/include/solo5
+ HOSTLDFLAGS :=
+@@ -71,7 +78,7 @@ HOSTLDLIBS :=
+ HOSTAR := ar
+
+ define HOSTCOMPILE.c
+- @echo "HOSTCC $<"
++ @echo "HOSTCC $(HOSTCC) $(DEPFLAGS) $(HOSTCFLAGS) $(HOSTCPPFLAGS) -c $< -o $@"
+ $(HOSTCC) $(DEPFLAGS) $(HOSTCFLAGS) $(HOSTCPPFLAGS) -c $< -o $@
+ mv -f $*.Td $*.d && touch $@
+ endef
+diff --git a/bindings/GNUmakefile b/bindings/GNUmakefile
+index 147c245..d3efb36 100644
+--- a/bindings/GNUmakefile
++++ b/bindings/GNUmakefile
+@@ -57,7 +57,7 @@ muen_SRCS := muen/start.c $(common_SRCS) $(common_hvt_SRCS) \
+ muen/muen-clock.c muen/muen-console.c muen/muen-net.c \
+ muen/muen-platform_lifecycle.c muen/muen-yield.c muen/muen-sinfo.c
+
+-genode_SRCS := genode/stubs.c
++genode_SRCS := genode/bindings.cc
+
+ CPPFLAGS+=-D__SOLO5_BINDINGS__
+
+@@ -70,6 +70,9 @@ endif
+ %.o: %.c %.d
+ $(COMPILE.c)
+
++%.o: %.cc %.d
++ $(COMPILE.cc)
++
+ %.o: %.S %.d
+ $(COMPILE.S)
+
+@@ -139,9 +142,7 @@ muen/solo5_muen.o: $(muen_OBJS)
+ endif
+
+ ifdef CONFIG_GENODE
+- genode_OBJS := $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(genode_SRCS)))
+-
+-$(genode_OBJS): CFLAGS += -Wno-unused-parameter
++ genode_OBJS := $(patsubst %.cc,%.o,$(patsubst %.S,%.o,$(genode_SRCS)))
+
+ GENODE_LDFLAGS := -nostdlib -z max-page-size=$(CONFIG_GUEST_PAGE_SIZE) -shared \
+ -gc-sections --eh-frame-hdr --entry=0x0 -T genode/genode_rel.ld
+diff --git a/bindings/genode/bindings.cc b/bindings/genode/bindings.cc
+index eb55ffb..1c1d082 100644
+--- a/bindings/genode/bindings.cc
++++ b/bindings/genode/bindings.cc
+@@ -35,10 +35,12 @@
+ #include
+ #include
+
++#define restrict __restrict__
++
+ /* Solo5 includes */
+ extern "C" {
+ #include "../bindings.h"
+-extern struct mft_note __solo5_manifest_note;
++extern struct mft1_note __solo5_mft1_note;
+ }
+
+ // Compile the MFT utilities as C++
+@@ -162,7 +164,7 @@ struct Solo5::Net_device final : Device
+ Net_device(struct mft_entry &me,
+ Genode::Env &env,
+ Range_allocator &alloc,
+- solo5_handle_set_t ready_set,
++ solo5_handle_set_t &ready_set,
+ solo5_handle_t handle)
+ : _nic(env, &alloc, NIC_BUFFER_SIZE, NIC_BUFFER_SIZE, me.name)
+ , _signal_handler(env.ep(), *this, &Net_device::_handle_signal)
+@@ -330,7 +332,7 @@ struct Solo5::Platform
+ static Platform *instance;
+ static Device *devices[MFT_MAX_ENTRIES];
+
+- struct mft &mft;
++ struct mft const &mft;
+
+ /**
+ * Reference to the Genode base enviroment
+@@ -376,7 +378,7 @@ struct Solo5::Platform
+ *
+ * TODO: periodic RTC synchronization
+ */
+- Genode::uint64_t _initial_epoch { rtc_epoch(env) };
++ Genode::uint64_t _initial_epoch { 0 };
+
+ /**
+ * Commandline buffer
+@@ -387,7 +389,8 @@ struct Solo5::Platform
+ /**
+ * Constructor
+ */
+- Platform(struct mft &mft, Genode::Env &env) : mft(mft), env(env)
++ Platform(struct mft const &mft, Genode::Env &env)
++ : mft(mft), env(env)
+ {
+ /**
+ * Acquire and attach a ROM dataspace (shared
+@@ -400,7 +403,7 @@ struct Solo5::Platform
+
+ // Copy-out the cmdline if configured.
+ try { cmdline = config.sub_node("cmdline").decoded_content(); }
+- catch (...) { }
++ catch (Genode::Xml_node::Nonexistent_sub_node) { }
+
+ for (solo5_handle_t i = 0U; i < MFT_MAX_ENTRIES; ++i) {
+ devices[i] = &invalid_device;
+@@ -422,6 +425,20 @@ struct Solo5::Platform
+ ** Solo5 bindings **
+ ********************/
+
++ solo5_time_t clock_wall()
++ {
++ if (_initial_epoch == 0) {
++ try { _initial_epoch = rtc_epoch(env); }
++ catch (Genode::Service_denied) {
++ Genode::error("Solo5: RTC time service not available. Aborting.");
++ solo5_abort();
++ }
++ }
++
++ return _initial_epoch * 1000000000ULL
++ + timer.curr_time().trunc_to_plain_us().value * 1000ULL;
++ }
++
+ void
+ yield(solo5_time_t deadline_ns, solo5_handle_set_t *ready_set)
+ {
+@@ -526,9 +543,7 @@ solo5_time_t solo5_clock_monotonic(void)
+
+ solo5_time_t solo5_clock_wall(void)
+ {
+- return Platform::instance->_initial_epoch * 1000000000ULL
+- + Platform::instance->timer.curr_time()
+- .trunc_to_plain_us().value * 1000ULL;
++ return Platform::instance->clock_wall();
+ }
+
+
+@@ -616,16 +631,19 @@ solo5_set_tls_base(uintptr_t base)
+ void Component::construct(Genode::Env &env)
+ {
+ /* Validate the device manifest */
+- struct mft &mft = __solo5_manifest_note.m;
+- size_t mft_size = __solo5_manifest_note.h.descsz;
+- if (mft_validate(&mft, mft_size) != 0) {
+- Genode::error("Solo5: Built-in manifest validation failed. Aborting");
++ const struct mft *mft;
++ size_t mft_size;
++
++ mft_get_builtin_mft1(&__solo5_mft1_note, &mft, &mft_size);
++
++ if (mft_validate(mft, mft_size) != 0) {
++ Genode::error("Solo5: Built-in manifest validation failed. Aborting.");
+ env.parent().exit(~0);
+ return;
+ }
+
+ /* Construct a statically allocated platform object */
+- static Solo5::Platform inst(mft, env);
++ static Solo5::Platform inst(*mft, env);
+ Platform::instance = &inst;
+
+ static struct solo5_start_info si {
+@@ -641,12 +659,14 @@ void Component::construct(Genode::Env &env)
+ if (si.heap_size > 1<<20)
+ si.heap_size -= 1<<19;
+
+- /* allocate a contiguous memory region for the application */
+- Genode::Dataspace_capability heap_ds =
+- env.pd().alloc(si.heap_size);
++ {
++ /* allocate a contiguous memory region for the application */
++ Genode::Dataspace_capability heap_ds =
++ env.pd().alloc(si.heap_size);
+
+- /* attach into our address-space */
+- si.heap_start = env.rm().attach(heap_ds);
++ /* attach into our address-space */
++ si.heap_start = env.rm().attach(heap_ds);
++ }
+
+ /* block for application then exit */
+ env.parent().exit(solo5_app_main(&si));
+diff --git a/configure.sh b/configure.sh
+index d5afdab..ab5419f 100755
+--- a/configure.sh
++++ b/configure.sh
+@@ -142,6 +142,10 @@ case ${CC_MACHINE} in
+ CONFIG_ARCH=x86_64 CONFIG_HOST=OpenBSD
+ CONFIG_GUEST_PAGE_SIZE=0x1000
+ ;;
++ x86_64-*genode*)
++ CONFIG_ARCH=x86_64 CONFIG_HOST=Genode
++ CONFIG_GUEST_PAGE_SIZE=0x1000
++ ;;
+ *)
+ die "Unsupported toolchain target: ${CC_MACHINE}"
+ ;;
+@@ -287,6 +291,21 @@ case "${CONFIG_HOST}" in
+ [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_MUEN=1
+ CONFIG_GENODE=
+ ;;
++ Genode)
++ cc_is_clang || die "Only 'clang' is supported on Genode"
++ [ "${CONFIG_ARCH}" = "x86_64" ] ||
++ die "Only 'x86_64' is supported on Genode"
++ ld_is_lld || die "Using GNU 'ld' is not supported on Genode"
++
++ MAKECONF_CFLAGS="-mno-retpoline -nostdlibinc"
++ MAKECONF_LDFLAGS="-nopie"
++
++ CONFIG_HVT=
++ CONFIG_SPT=
++ CONFIG_VIRTIO=
++ CONFIG_MUEN=
++ CONFIG_GENODE=1
++ ;;
+ *)
+ die "Unsupported build OS: ${CONFIG_HOST}"
+ ;;
+@@ -299,7 +318,7 @@ esac
+ # GNU make. Given the differences in quoting rules between the two
+ # (unable to sensibly use VAR="VALUE"), our convention is as follows:
+ #
+-# 1. GNU make parses the entire file, i.e. all variables defined below are
++# 1. GNU make parses the entire file, i.e. all variables defined below are
+ # available to Makefiles.
+ #
+ # 2. Shell scripts parse the subset of *lines* starting with "CONFIG_". I.e.
+@@ -323,6 +342,7 @@ CONFIG_HOST=${CONFIG_HOST}
+ CONFIG_GUEST_PAGE_SIZE=${CONFIG_GUEST_PAGE_SIZE}
+ MAKECONF_CC=${CC}
+ MAKECONF_LD=${LD}
++MAKECONF_HOSTCC=${HOSTCC}
+ CONFIG_SPT_NO_PIE=${CONFIG_SPT_NO_PIE}
+ EOM
+
+diff --git a/include/solo5/mft_abi.h b/include/solo5/mft_abi.h
+index 537c7bc..c51c90e 100644
+--- a/include/solo5/mft_abi.h
++++ b/include/solo5/mft_abi.h
+@@ -154,7 +154,8 @@ struct mft1_note {
+ * Internal alignment of (m) within struct mft1_note. Must be passed to
+ * elf_load_note() as note_align when loading.
+ */
+-#define MFT1_NOTE_ALIGN offsetof(struct { char c; struct mft m; }, m)
++struct foo { char c; struct mft m; };
++#define MFT1_NOTE_ALIGN offsetof(struct foo, m)
+
+ _Static_assert((offsetof(struct mft1_note, m) & (MFT1_NOTE_ALIGN - 1)) == 0,
+ "struct mft1_note.m is not aligned to a MFT1_NOTE_ALIGN boundary");
+diff --git a/tenders/common/mft.c b/tenders/common/mft.c
+index 56024ab..7d05713 100644
+--- a/tenders/common/mft.c
++++ b/tenders/common/mft.c
+@@ -37,11 +37,11 @@ int mft_validate(const struct mft *mft, size_t mft_size)
+ * as untrusted data.
+ */
+ if (mft_size < sizeof(*mft))
+- return -1;
++ return __LINE__;
+ if (mft->version != MFT_VERSION)
+- return -1;
++ return __LINE__;
+ if (mft->entries > MFT_MAX_ENTRIES)
+- return -1;
++ return __LINE__;
+ /*
+ * mft_size must be the exact expected structure size, including the space
+ * required for manifest entires.
+@@ -51,17 +51,17 @@ int mft_validate(const struct mft *mft, size_t mft_size)
+ */
+ if (mft_size != (sizeof(struct mft) +
+ (mft->entries * sizeof(struct mft_entry))))
+- return -1;
++ return __LINE__;
+ /*
+ * The manifest must contain at least one entry, and the first entry must
+ * be of type MFT_RESERVED_FIRST with an empty name.
+ */
+ if (mft->entries < 1)
+- return -1;
++ return __LINE__;
+ if (mft->e[0].type != MFT_RESERVED_FIRST)
+- return -1;
++ return __LINE__;
+ if (mft->e[0].name[0] != 0)
+- return -1;
++ return __LINE__;
+
+ for (unsigned i = 0; i != mft->entries; i++) {
+ /*
+@@ -69,7 +69,7 @@ int mft_validate(const struct mft *mft, size_t mft_size)
+ * in the array itself.
+ */
+ if (mft->e[i].name[MFT_NAME_MAX] != 0)
+- return -1;
++ return __LINE__;
+ /*
+ * Sanitize private fields (to be used by the tender/bindings):
+ *
+@@ -77,7 +77,7 @@ int mft_validate(const struct mft *mft, size_t mft_size)
+ * uninitialised).
+ */
+ if (mft->e[i].attached != false)
+- return -1;
++ return __LINE__;
+ }
+
+ return 0;
+diff --git a/tests/test_tls/GNUmakefile b/tests/test_tls/GNUmakefile
+deleted file mode 100644
+index cc7f951..0000000
+--- a/tests/test_tls/GNUmakefile
++++ /dev/null
+@@ -1,23 +0,0 @@
+-# Copyright (c) 2015-2019 Contributors as noted in the AUTHORS file
+-#
+-# This file is part of Solo5, a sandboxed execution environment.
+-#
+-# Permission to use, copy, modify, and/or distribute this software
+-# for any purpose with or without fee is hereby granted, provided
+-# that the above copyright notice and this permission notice appear
+-# in all copies.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+-# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+-# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+-# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-
+-include $(TOPDIR)/Makefile.common
+-
+-test_NAME := test_tls
+-
+-include ../Makefile.tests
+diff --git a/tests/test_tls/manifest.json b/tests/test_tls/manifest.json
+deleted file mode 100644
+index 1100fc5..0000000
+--- a/tests/test_tls/manifest.json
++++ /dev/null
+@@ -1,5 +0,0 @@
+-{
+- "type": "solo5.manifest",
+- "version": 1,
+- "devices": [ ]
+-}
+diff --git a/tests/test_tls/test_tls.c b/tests/test_tls/test_tls.c
+deleted file mode 100644
+index ce441b9..0000000
+--- a/tests/test_tls/test_tls.c
++++ /dev/null
+@@ -1,101 +0,0 @@
+-/*
+- * Copyright (c) 2015-2019 Contributors as noted in the AUTHORS file
+- *
+- * This file is part of Solo5, a sandboxed execution environment.
+- *
+- * Permission to use, copy, modify, and/or distribute this software
+- * for any purpose with or without fee is hereby granted, provided
+- * that the above copyright notice and this permission notice appear
+- * in all copies.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+- * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+- * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+- * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+- */
+-
+-#include "solo5.h"
+-#include "../../bindings/lib.c"
+-
+-#if defined(__x86_64__) || defined(__powerpc64__)
+-/* Variant II */
+-struct tcb {
+- volatile uint64_t _data;
+- void *tp;
+-};
+-
+-#define PPC64_TLS_OFFSET 0x7000
+-
+-#elif defined(__aarch64__)
+-/* Variant I */
+-struct tcb {
+- void *tp;
+- void *pad;
+- volatile uint64_t _data;
+-};
+-#else
+-#error Unsupported architecture
+-#endif
+-
+-struct tcb tcb1;
+-struct tcb tcb2;
+-
+-static void puts(const char *s)
+-{
+- solo5_console_write(s, strlen(s));
+-}
+-
+-#if defined(__OpenBSD__)
+-/* __thread is not supported in OpenBSD (this test fails on it). */
+-volatile uint64_t _data;
+-#else
+-__thread volatile uint64_t _data;
+-#endif
+-
+-uint64_t __attribute__ ((noinline)) get_data()
+-{
+- return _data;
+-}
+-
+-void __attribute__ ((noinline)) set_data(uint64_t data)
+-{
+- _data = data;
+-}
+-
+-int solo5_app_main(const struct solo5_start_info *si __attribute__((unused)))
+-{
+- puts("\n**** Solo5 standalone test_tls ****\n\n");
+-
+-#if defined (__powerpc64__)
+- tcb1.tp = (void *)&tcb1._data + PPC64_TLS_OFFSET;
+- tcb2.tp = (void *)&tcb2._data + PPC64_TLS_OFFSET;
+-#else
+- tcb1.tp = &tcb1.tp;
+- tcb2.tp = &tcb2.tp;
+-#endif
+-
+- if (solo5_set_tls_base((uintptr_t)tcb1.tp) != SOLO5_R_OK)
+- return 1;
+- set_data(1);
+-
+- if (solo5_set_tls_base((uintptr_t)tcb2.tp) != SOLO5_R_OK)
+- return 2;
+- set_data(2);
+-
+- if (solo5_set_tls_base((uintptr_t)tcb1.tp) != SOLO5_R_OK)
+- return 3;
+- if (get_data() != 1)
+- return 4;
+-
+- if (solo5_set_tls_base((uintptr_t)tcb2.tp) != SOLO5_R_OK)
+- return 5;
+- if (get_data() != 2)
+- return 6;
+-
+- puts("SUCCESS\n");
+- return SOLO5_EXIT_SUCCESS;
+-}
diff --git a/tests/default.nix b/tests/default.nix
index a1617d3..f399fc3 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -8,6 +8,7 @@ let
libc = call ./libc.nix { };
log = call ./log.nix { };
signal = call ./signal.nix { };
+ solo5 = call ./solo5.nix { };
};
in { pkgs ? (import ./.. { }) }:
diff --git a/tests/solo5.dhall b/tests/solo5.dhall
new file mode 100644
index 0000000..54393b7
--- /dev/null
+++ b/tests/solo5.dhall
@@ -0,0 +1,18 @@
+let Genode = env:DHALL_GENODE
+
+in λ(_ : {})
+ → { hello =
+ Genode.Init.Start.defaults
+ ⫽ { binary = "solo5-test_hello"
+ , resources = { caps = 256, ram = Genode.units.MiB 16 }
+ , routes = [ Genode.ServiceRoute.parent "Timer" ]
+ , config =
+ Genode.Prelude.XML.text
+ ''
+
+ "Hello_Solo5"
+
+ ''
+ }
+ : Genode.Init.Start.Type
+ }
diff --git a/tests/solo5.nix b/tests/solo5.nix
new file mode 100644
index 0000000..2c9df5b
--- /dev/null
+++ b/tests/solo5.nix
@@ -0,0 +1,15 @@
+{ pkgs, lib }:
+with pkgs;
+
+rec {
+ name = "solo5";
+ meta.maintainers = with pkgs.stdenv.lib.maintainers; [ ehmry ];
+
+ testConfig = lib.renderDhallInit ./solo5.dhall "{=}";
+
+ testScript = ''
+ file link -s solo5.lib.so ${solo5}/lib/solo5-bindings-genode/solo5.lib.so
+ file link -s solo5-test_hello ${solo5.tests}/bin/solo5-test_hello
+ run_genode_until "child .* exited with exit value 0.*\n" 30
+ '';
+}