From 9d01ae7aa8a8385bf72d9b20cd05051472806e9c Mon Sep 17 00:00:00 2001 From: Emery Hemingway Date: Mon, 21 Oct 2019 19:38:04 +0200 Subject: [PATCH] Solo5: add temporary patch --- pkgs/solo5/default.nix | 4 +- pkgs/solo5/genode.patch | 604 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 607 insertions(+), 1 deletion(-) create mode 100644 pkgs/solo5/genode.patch diff --git a/pkgs/solo5/default.nix b/pkgs/solo5/default.nix index f815fef..8977901 100644 --- a/pkgs/solo5/default.nix +++ b/pkgs/solo5/default.nix @@ -18,9 +18,11 @@ in stdenv.mkDerivation { enableParallelBuilding = true; + patches = [ ./genode.patch ]; + configurePhase = '' runHook preConfigure - rm -r tests/test_tls + rm -fr tests/test_tls HOSTCC=${buildPackages.stdenv.cc}/bin/cc sh configure.sh runHook postConfigure ''; diff --git a/pkgs/solo5/genode.patch b/pkgs/solo5/genode.patch new file mode 100644 index 0000000..c98fdd0 --- /dev/null +++ b/pkgs/solo5/genode.patch @@ -0,0 +1,604 @@ +diff --git a/GNUmakefile b/GNUmakefile +index e168853..161facf 100644 +--- a/GNUmakefile ++++ b/GNUmakefile +@@ -100,7 +100,8 @@ 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-$* ++ if [ -d "include/crt" ]; then cp -R include/crt $(PREFIX)/include/solo5-bindings-$*; fi + ifndef CONFIG_GENODE + cp bindings/$*/solo5_$*.o bindings/$*/solo5_$*.lds \ + $(PREFIX)/lib/solo5-bindings-$* +diff --git a/Makefile.common b/Makefile.common +index 5ccc2ea..0e1aed2 100644 +--- a/Makefile.common ++++ b/Makefile.common +@@ -32,6 +32,7 @@ include $(TOPDIR)/Makeconf + CC := $(MAKECONF_CC) + CFLAGS := -std=c11 -Wall -Wextra -Werror -O2 -g + CFLAGS += -ffreestanding -fstack-protector-strong $(MAKECONF_CFLAGS) ++CXXLAGS += -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 +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 := +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..a131ca3 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 +@@ -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(); + } + + +@@ -605,6 +613,44 @@ solo5_set_tls_base(uintptr_t base) + return SOLO5_R_EUNSPEC; + } + ++ ++__attribute__((__visibility__("hidden"))) ++void *memcpy(void *restrict dest, const void *restrict src, size_t n) ++{ ++ return Genode::memcpy(dest, src, n); ++} ++ ++ ++__attribute__((__visibility__("hidden"))) ++void *memset(void *dest, int c, size_t n) ++{ ++ return Genode::memset(dest, c, n); ++} ++ ++ ++__attribute__((__visibility__("hidden"))) ++int strncmp(const char *l, const char *r, size_t n) ++{ ++ return Genode::strcmp(l, r, n); ++} ++ ++ ++__attribute__((__visibility__("hidden"))) ++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, NULL); ++} ++ ++ ++__attribute__((__visibility__("hidden"))) ++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 +662,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 +690,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..b8c8d66 100755 +--- a/configure.sh ++++ b/configure.sh +@@ -116,6 +116,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}" + ;; +@@ -202,8 +206,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 +@@ -240,6 +244,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 +@@ -311,6 +330,7 @@ CONFIG_HOST=${CONFIG_HOST} + CONFIG_GUEST_PAGE_SIZE=${CONFIG_GUEST_PAGE_SIZE} + MAKECONF_CC=${CC} + 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/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; +-}