diff --git a/GNUmakefile b/GNUmakefile index e168853..02d81e1 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -98,9 +98,11 @@ install-opam-%: all opam/solo5-bindings-%.pc force-install (echo "error: PREFIX not set or incorrect"; false) mkdir -p $(PREFIX)/lib/pkgconfig \ $(PREFIX)/lib/solo5-bindings-$* \ - $(PREFIX)/include/solo5-bindings-$*/solo5 \ - $(PREFIX)/include/solo5-bindings-$*/crt - cp -R include/solo5 include/crt $(PREFIX)/include/solo5-bindings-$* + $(PREFIX)/include/solo5-bindings-$* + cp -R include/solo5 $(PREFIX)/include/solo5-bindings-$* +ifdef CONFIG_HOST_CRT + cp -R include/crt $(PREFIX)/include/solo5-bindings-$* +endif ifndef CONFIG_GENODE cp bindings/$*/solo5_$*.o bindings/$*/solo5_$*.lds \ $(PREFIX)/lib/solo5-bindings-$* diff --git a/Makefile.common b/Makefile.common index 5ccc2ea..2653a8b 100644 --- a/Makefile.common +++ b/Makefile.common @@ -30,8 +30,10 @@ include $(TOPDIR)/Makeconf # tests (applications). # CC := $(MAKECONF_CC) +CXX := $(MAKECONF_CXX) CFLAGS := -std=c11 -Wall -Wextra -Werror -O2 -g CFLAGS += -ffreestanding -fstack-protector-strong $(MAKECONF_CFLAGS) +CXXFLAGS += -Wall -Wextra -Werror -O2 -g CPPFLAGS := -isystem $(TOPDIR)/include/crt -I$(TOPDIR)/include/solo5 LD := $(MAKECONF_LD) LDFLAGS := -nostdlib -z max-page-size=$(CONFIG_GUEST_PAGE_SIZE) -static \ @@ -53,6 +55,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 +71,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 := 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..2b7db70 100644 --- a/bindings/genode/bindings.cc +++ b/bindings/genode/bindings.cc @@ -35,15 +35,15 @@ #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++ -#define memset Genode::memset -#define strncmp Genode::strcmp #include "../../tenders/common/mft.c" namespace Solo5 @@ -109,32 +109,32 @@ struct Solo5::Device { virtual solo5_result_t - net_info(solo5_net_info &info) { + net_info(solo5_net_info &) { return SOLO5_R_EINVAL; } virtual solo5_result_t - net_write(const uint8_t *buf, size_t size) { + net_write(const uint8_t *, size_t) { return SOLO5_R_EINVAL; } virtual solo5_result_t - net_read(uint8_t *buf, size_t size, size_t &read_size) { + net_read(uint8_t *, size_t, size_t &) { return SOLO5_R_EINVAL; } virtual solo5_result_t - block_info(solo5_block_info &info) { + block_info(solo5_block_info &) { return SOLO5_R_EINVAL; } virtual solo5_result_t - block_write(solo5_off_t offset, const uint8_t *buf, size_t size) { + block_write(solo5_off_t, const uint8_t *, size_t) { return SOLO5_R_EINVAL; } virtual solo5_result_t - block_read(solo5_off_t offset, uint8_t *buf, size_t size) { + block_read(solo5_off_t, uint8_t *, size_t) { return SOLO5_R_EINVAL; } }; @@ -162,7 +162,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 +330,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 +376,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 +387,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 +401,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 +423,15 @@ struct Solo5::Platform ** Solo5 bindings ** ********************/ + solo5_time_t clock_wall() + { + if (_initial_epoch == 0) + _initial_epoch = rtc_epoch(env); + + 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 +536,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(); } @@ -600,11 +608,44 @@ solo5_block_read(solo5_handle_t handle, solo5_off_t offset, solo5_result_t -solo5_set_tls_base(uintptr_t base) +solo5_set_tls_base(uintptr_t) { return SOLO5_R_EUNSPEC; } + +void *memcpy(void *restrict dest, const void *restrict src, size_t n) +{ + return Genode::memcpy(dest, src, n); +} + + +void *memset(void *dest, int c, size_t n) +{ + return Genode::memset(dest, c, n); +} + + +int strncmp(const char *l, const char *r, size_t n) +{ + return Genode::strcmp(l, r, n); +} + + +void _assert_fail(const char *file, const char *line, const char *e) +{ + Genode::error("Solo5: ABORT: ", file, ":", line, ": Assertion `", e, "' failed"); + Platform::instance->exit(SOLO5_EXIT_ABORT, nullptr); +} + + +void _abort(const char *file, const char *line, const char *s, void *regs_hint) +{ + Genode::error("Solo5: ABORT: ", file, ":", line, ": ", s); + Platform::instance->exit(SOLO5_EXIT_ABORT, regs_hint); +} + + } // extern "C" @@ -616,16 +657,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 +685,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/bindings/genode/stubs.c b/bindings/genode/stubs.c deleted file mode 100644 index 0f1ca5c..0000000 --- a/bindings/genode/stubs.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "../bindings.h" - -void solo5_console_write(const char *buf, size_t size) { } -void solo5_exit(int status) { for(;;); } -void solo5_abort(void) { for(;;); } - -solo5_time_t solo5_clock_monotonic(void) { return ~0; } -solo5_time_t solo5_clock_wall(void) { return ~0; } -void solo5_yield(solo5_time_t deadline, solo5_handle_set_t *ready_set) { return; } - -solo5_result_t solo5_net_acquire(const char *name, solo5_handle_t *handle, struct solo5_net_info *info) { return SOLO5_R_EUNSPEC; } -solo5_result_t solo5_net_write(solo5_handle_t handle, const uint8_t *buf, size_t size) { return SOLO5_R_EUNSPEC; } -solo5_result_t solo5_net_read(solo5_handle_t handle, uint8_t *buf, size_t size, size_t *read_size) { return SOLO5_R_EUNSPEC; } - -solo5_result_t solo5_block_acquire(const char *name, solo5_handle_t *handle, struct solo5_block_info *info) { return SOLO5_R_EUNSPEC; } - -solo5_result_t solo5_block_write(solo5_handle_t handle, solo5_off_t offset, const uint8_t *buf, size_t size) { return SOLO5_R_EUNSPEC; } -solo5_result_t solo5_block_read(solo5_handle_t handle, solo5_off_t offset, uint8_t *buf, size_t size) { return SOLO5_R_EUNSPEC; } - -solo5_result_t solo5_set_tls_base(uintptr_t base) { return SOLO5_R_EUNSPEC; } - -uintptr_t SSP_GUARD; -void SSP_FAIL (void) { } diff --git a/configure.sh b/configure.sh index be0f3a2..d5d0c14 100755 --- a/configure.sh +++ b/configure.sh @@ -89,6 +89,7 @@ ld_is_lld() # Allow external override of CC. CC=${CC:-cc} +CXX=${CXX:-c++} LD=${LD:-ld} CC_MACHINE=$(${CC} -dumpmachine) @@ -116,6 +117,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}" ;; @@ -131,6 +136,7 @@ CONFIG_SPT= CONFIG_VIRTIO= CONFIG_MUEN= CONFIG_GENODE= +CONFIG_HOST_CRT= MAKECONF_CFLAGS= MAKECONF_LDFLAGS= MAKECONF_SPT_CFLAGS= @@ -143,6 +149,8 @@ case "${CONFIG_HOST}" in cc_is_gcc || die "Only 'gcc' 4.x+ is supported on Linux" CC_INCDIR=$(${CC} -print-file-name=include) [ -d "${CC_INCDIR}" ] || die "Cannot determine gcc include directory" + + CONFIG_HOST_CRT=1 mkdir -p ${HOST_INCDIR} cp -R ${CC_INCDIR}/. ${HOST_INCDIR} @@ -202,8 +210,8 @@ case "${CONFIG_HOST}" in fi [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_VIRTIO=1 [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_MUEN=1 - [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_GENODE=1 [ "${CONFIG_ARCH}" = "ppc64le" ] && CONFIG_HVT= + CONFIG_GENODE= ;; FreeBSD) # On FreeBSD/clang we use -nostdlibinc which gives us access to the @@ -221,6 +229,7 @@ case "${CONFIG_HOST}" in x86/_types.h x86/_limits.h" SRCS="float.h osreldate.h stddef.h stdint.h stdbool.h stdarg.h" + CONFIG_HOST_CRT=1 mkdir -p ${HOST_INCDIR} mkdir -p ${HOST_INCDIR}/machine ${HOST_INCDIR}/sys ${HOST_INCDIR}/x86 for f in ${SRCS_MACH}; do cp -f ${INCDIR}/$f ${HOST_INCDIR}/machine; done @@ -240,6 +249,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 + ;; OpenBSD) # On OpenBSD/clang we use -nostdlibinc which gives us access to the # clang-provided headers for compiler instrinsics. We copy the rest @@ -259,6 +283,7 @@ case "${CONFIG_HOST}" in SRCS_AMD64="amd64/_float.h amd64/stdarg.h amd64/endian.h" SRCS="float.h stddef.h stdint.h stdbool.h stdarg.h" + CONFIG_HOST_CRT=1 mkdir -p ${HOST_INCDIR} mkdir -p ${HOST_INCDIR}/machine ${HOST_INCDIR}/sys ${HOST_INCDIR}/amd64 for f in ${SRCS_MACH}; do cp -f ${INCDIR}/$f ${HOST_INCDIR}/machine; done @@ -304,13 +329,16 @@ CONFIG_SPT=${CONFIG_SPT} CONFIG_VIRTIO=${CONFIG_VIRTIO} CONFIG_MUEN=${CONFIG_MUEN} CONFIG_GENODE=${CONFIG_GENODE} +CONFIG_HOST_CRT=${CONFIG_HOST_CRT} MAKECONF_CFLAGS=${MAKECONF_CFLAGS} MAKECONF_LDFLAGS=${MAKECONF_LDFLAGS} CONFIG_ARCH=${CONFIG_ARCH} CONFIG_HOST=${CONFIG_HOST} CONFIG_GUEST_PAGE_SIZE=${CONFIG_GUEST_PAGE_SIZE} MAKECONF_CC=${CC} +MAKECONF_CXX=${CXX} MAKECONF_LD=${LD} +MAKECONF_HOSTCC=${HOSTCC:-$CC} MAKECONF_SPT_CFLAGS=${MAKECONF_SPT_CFLAGS} MAKECONF_SPT_LDLIBS=${MAKECONF_SPT_LDLIBS} CONFIG_SPT_NO_PIE=${CONFIG_SPT_NO_PIE} diff --git a/include/solo5/mft_abi.h b/include/solo5/mft_abi.h index 537c7bc..47927b0 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 _mft1_note_aligned { char c; struct mft m; }; +#define MFT1_NOTE_ALIGN offsetof(struct _mft1_note_aligned, 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/opam/solo5-bindings-genode.opam b/opam/solo5-bindings-genode.opam index eba9ac0..e8ea3ba 100644 --- a/opam/solo5-bindings-genode.opam +++ b/opam/solo5-bindings-genode.opam @@ -16,7 +16,10 @@ remove: [ ["touch" "./Makeconf"] [make "V=1" "uninstall-opam-genode" "PREFIX=%{prefix}%"] ] -depends: "conf-pkg-config" +depends: [ + "conf-pkg-config" + "conf-libseccomp" {build & os = "linux"} +] conflicts: [ "solo5-bindings-hvt" "solo5-bindings-spt" diff --git a/opam/solo5-bindings-hvt.opam b/opam/solo5-bindings-hvt.opam index 81a2d70..04dd3f4 100644 --- a/opam/solo5-bindings-hvt.opam +++ b/opam/solo5-bindings-hvt.opam @@ -18,7 +18,10 @@ remove: [ ["touch" "./Makeconf"] [make "V=1" "uninstall-opam-hvt" "PREFIX=%{prefix}%"] ] -depends: "conf-pkg-config" +depends: [ + "conf-pkg-config" + "conf-libseccomp" {build & os = "linux"} +] depexts: [ ["linux-headers"] {os-distribution = "alpine"} ["linux-libc-dev"] {os-distribution = "debian"} diff --git a/opam/solo5-bindings-muen.opam b/opam/solo5-bindings-muen.opam index c180646..60b0356 100644 --- a/opam/solo5-bindings-muen.opam +++ b/opam/solo5-bindings-muen.opam @@ -18,7 +18,10 @@ remove: [ ["touch" "./Makeconf"] [make "V=1" "uninstall-opam-muen" "PREFIX=%{prefix}%"] ] -depends: "conf-pkg-config" +depends: [ + "conf-pkg-config" + "conf-libseccomp" {build & os = "linux"} +] conflicts: [ "solo5-bindings-genode" "solo5-bindings-hvt" diff --git a/opam/solo5-bindings-spt.opam b/opam/solo5-bindings-spt.opam index 416605c..74940f9 100644 --- a/opam/solo5-bindings-spt.opam +++ b/opam/solo5-bindings-spt.opam @@ -18,18 +18,16 @@ remove: [ ["touch" "./Makeconf"] [make "V=1" "uninstall-opam-spt" "PREFIX=%{prefix}%"] ] -depends: "conf-pkg-config" +depends: [ + "conf-pkg-config" + "conf-libseccomp" {os = "linux"} +] depexts: [ ["linux-headers"] {os-distribution = "alpine"} ["linux-libc-dev"] {os-distribution = "debian"} ["kernel-headers"] {os-distribution = "fedora"} ["kernel-headers"] {os-distribution = "rhel"} ["linux-libc-dev"] {os-distribution = "ubuntu"} - ["libseccomp-dev"] {os-distribution = "alpine"} - ["libseccomp-dev"] {os-distribution = "debian"} - ["libseccomp-devel"] {os-distribution = "fedora"} - ["libseccomp-devel"] {os-distribution = "rhel"} - ["libseccomp-dev"] {os-distribution = "ubuntu"} ] conflicts: [ "solo5-bindings-hvt" diff --git a/opam/solo5-bindings-virtio.opam b/opam/solo5-bindings-virtio.opam index 7171244..a10655f 100644 --- a/opam/solo5-bindings-virtio.opam +++ b/opam/solo5-bindings-virtio.opam @@ -18,7 +18,10 @@ remove: [ ["touch" "./Makeconf"] [make "V=1" "uninstall-opam-virtio" "PREFIX=%{prefix}%"] ] -depends: "conf-pkg-config" +depends: [ + "conf-pkg-config" + "conf-libseccomp" {build & os = "linux"} +] conflicts: [ "solo5-bindings-hvt" "solo5-bindings-spt" diff --git a/tests/Makefile.tests b/tests/Makefile.tests index 2cd0dcd..d4e1191 100644 --- a/tests/Makefile.tests +++ b/tests/Makefile.tests @@ -69,8 +69,9 @@ manifest.c: manifest.json ../../include/solo5/mft_abi.h $(ELFTOOL) $(CC) $(GENODE_APP_CFLAGS) $(CPPFLAGS) -c $< -o $@ %.genode: %.genode.o manifest.genode.o $(LDS.genode) $(BINDINGS.genode) + ln -sf $(BINDINGS.genode) solo5.lib.so @echo "LD $@" - $(LD) $(GENODE_APP_LDFLAGS) -T $(LDS.genode) $(BINDINGS.genode) \ + $(LD) $(GENODE_APP_LDFLAGS) -T $(LDS.genode) solo5.lib.so \ $< manifest.genode.o -o $@ ifdef CONFIG_HVT