From 2f1cae37d8b9f97826ea08934558a4360bdb13da Mon Sep 17 00:00:00 2001 From: Martin Lucina Date: Thu, 21 Feb 2019 16:26:49 +0100 Subject: [PATCH] Refactor build system, remove hvt compile-time specialization This is a large change, and the majority of it is effectively a full re-write of the build system. The actual removal of hvt compile-time specialization is fairly straightforward. User-visible changes: - 'configure.sh' now needs to be run manually before running 'make', this is consistent with POLA. - conversely, 'make clean' no longer cleans Makeconf. Use 'distclean' or 'clobber' for that. - 'configure.sh' will now print the targets that can (will) be built on this system. The strategy is still "build everything we can", however I have disabled Genode on all systems except Linux due to toolchain issues. - You can now build a subset of targets from the top-level 'make', by specifying 'CONFIG_XXX=' (disable) or 'CONFIG_XXX=1' (enable) either on the command line, or editing the generated Makeconf. - Makefiles use silent rules by default. To get the old verbose ones back, use 'make V=1'. - The 'solo5-hvt' tender is no longer "specialized" to the unikernel. We build two tenders, 'solo5-hvt' with all non-debug modules configured and 'solo5-hvt-debug' with additional debug modules (gdb, dumpcore where available). - 'solo5-hvt-configure' is kept around for now for backward compatibility with OPAM/MirageOS but is essentially a NOP. Developer-visible changes: - The build system now has proper support for auto-generation of dependencies. This means you can safely edit source files, run make and be sure you will get a complete incremental build. - Makefiles have been refactored to use common best practices, remove repetition, consistent variable names and clear interfaces between configure.sh/Makeconf/Makefiles, all the while keeping them simple enough to understand for me on a Monday morning before coffee. I.e. limit use of macros, eval, etc. - hvt tender modules are no longer defined by compile-time flags, instead a dynamic array is placed into a special ELF section (.modules). This means that a hvt tender binary can be combined from an arbitrary set of hvt_module_XXX object files, which is the right way to do things going forward and also simplifies the build system (not needing to build multiple targets from the same set of sources). Shortcomings / TODOs: - Dependency files (*.d) are stored in-tree. I spent several days on trying to figure out how to get them to work out of tree, but in combination with the non-recursive use of subdirectories in 'bindings' I could not figure out the required Makefile magic. - HVT_DROP_PRIVILEGES=0 is non-functional with the new modules arrangement, but needs a re-design anyway. Other changes included as part of this PR: - Revert privilege dropping on FreeBSD (see discussion in #282). - The build system changes effectively implement option 1 in #292, i.e. on x86_64 -m no-red-zone is only used for bindings, not for application code. - tests/tests.bats has been refactored for DRY as it was getting totally unmaintainable. --- .gitignore | 10 +- .travis.yml | 2 +- GNUmakefile | 232 ++++++++++---------------- Makefile.common | 108 +++++++++--- bindings/GNUmakefile | 237 +++++++++++++------------- build.sh | 5 +- configure.sh | 164 ++++++++++++------ solo5-bindings-genode.opam | 11 +- solo5-bindings-genode.pc.in | 5 +- solo5-bindings-hvt.opam | 13 +- solo5-bindings-hvt.pc.in | 6 +- solo5-bindings-muen.opam | 9 +- solo5-bindings-muen.pc.in | 4 +- solo5-bindings-spt.opam | 13 +- solo5-bindings-spt.pc.in | 6 +- solo5-bindings-virtio.opam | 13 +- solo5-bindings-virtio.pc.in | 4 +- tenders/hvt/GNUmakefile | 66 +++++++- tenders/hvt/hvt.h | 25 +-- tenders/hvt/hvt_core.c | 27 +-- tenders/hvt/hvt_freebsd.c | 19 +-- tenders/hvt/hvt_main.c | 33 ++-- tenders/hvt/hvt_module_blk.c | 8 +- tenders/hvt/hvt_module_dumpcore.c | 6 +- tenders/hvt/hvt_module_gdb.c | 6 +- tenders/hvt/hvt_module_net.c | 8 +- tenders/hvt/solo5-hvt-configure | 158 +++--------------- tenders/spt/GNUmakefile | 66 ++++++-- tests/GNUmakefile | 50 ++---- tests/Makefile.tests | 130 ++++++++------- tests/test_abort/GNUmakefile | 9 +- tests/test_blk/GNUmakefile | 10 +- tests/test_exception/GNUmakefile | 9 +- tests/test_fpu/GNUmakefile | 9 +- tests/test_globals/GNUmakefile | 9 +- tests/test_hello/GNUmakefile | 9 +- tests/test_notls/GNUmakefile | 9 +- tests/test_ping_serve/GNUmakefile | 9 +- tests/test_quiet/GNUmakefile | 9 +- tests/test_seccomp/GNUmakefile | 13 +- tests/test_ssp/GNUmakefile | 9 +- tests/test_time/GNUmakefile | 9 +- tests/test_zeropage/GNUmakefile | 9 +- tests/tests.bats | 266 ++++++++++++++---------------- 44 files changed, 883 insertions(+), 949 deletions(-) diff --git a/.gitignore b/.gitignore index 0cc91231..fe6c5e60 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,8 @@ *.o +*.d *.lib.so -*.swp -*.pcap +*.pc Makeconf -cscope.* tags include/crt tests/*/*.hvt @@ -11,9 +10,6 @@ tests/*/*.spt tests/*/*.virtio tests/*/*.muen tests/*/*.genode -tests/*/solo5-hvt -tests/*/Makefile.solo5-hvt -tenders/hvt/Makefile.solo5-hvt -tenders/hvt/_build-solo5-hvt/ tenders/hvt/solo5-hvt +tenders/hvt/solo5-hvt-debug tenders/spt/solo5-spt diff --git a/.travis.yml b/.travis.yml index 84e777d2..1be9aa2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,4 +5,4 @@ addons: packages: - qemu-system-x86 - libseccomp-dev -script: make && tests/run-tests.sh +script: ./configure.sh && make && tests/run-tests.sh diff --git a/GNUmakefile b/GNUmakefile index c9eb4014..c41820c4 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -16,166 +16,108 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -export TOP=$(abspath .) -$(TOP)/Makeconf: - ./configure.sh +export TOPDIR := $(abspath .) +$(TOPDIR)/Makeconf: + $(error Makeconf not found, please run ./configure.sh) include Makefile.common -.PHONY: all -all: hvt spt virtio muen genode -.DEFAULT_GOAL := all -.NOTPARALLEL: hvt virtio muen genode +SUBDIRS := bindings tenders/hvt tenders/spt tests -.PHONY: virtio -virtio: -ifeq ($(BUILD_VIRTIO), yes) - $(MAKE) -C bindings virtio - $(MAKE) -C tests virtio -endif +tests: bindings -.PHONY: hvt -hvt: -ifeq ($(BUILD_HVT), yes) - $(MAKE) -C bindings hvt - $(MAKE) -C tenders/hvt - $(MAKE) -C tests hvt -endif +.PHONY: $(SUBDIRS) -.PHONY: spt -spt: -ifeq ($(BUILD_SPT), yes) - $(MAKE) -C bindings spt - $(MAKE) -C tenders/spt - $(MAKE) -C tests spt -endif - -.PHONY: muen -muen: -ifeq ($(BUILD_MUEN), yes) - $(MAKE) -C bindings muen - $(MAKE) -C tests muen -endif - -.PHONY: genode -genode: -ifeq ($(BUILD_GENODE), yes) - $(MAKE) -C bindings genode - $(MAKE) -C tests genode -endif +.PHONY: all +all: $(SUBDIRS) +.DEFAULT_GOAL := all -.PHONY: clean -clean: - $(MAKE) -C bindings clean -ifeq ($(BUILD_HVT), yes) - $(MAKE) -C tenders/hvt clean -endif -ifeq ($(BUILD_SPT), yes) - $(MAKE) -C tenders/spt clean -endif - $(MAKE) -C tests clean +$(SUBDIRS): + @echo "MAKE $@" + $(MAKE) -C $@ $(MAKECMDGOALS) $(SUBOVERRIDE) + +.PHONY: clean before-clean +# Ensure that a top-level "make clean" always cleans *all* possible build +# products and not some subset dependent on the setting of $(BUILD_*). +before-clean: + $(eval export SUBOVERRIDE := CONFIG_HVT=1 CONFIG_SPT=1 CONFIG_VIRTIO=1 CONFIG_MUEN=1 CONFIG_GENODE=1) +clean: before-clean $(SUBDIRS) + @echo "CLEAN solo5" $(RM) solo5-bindings-virtio.pc $(RM) solo5-bindings-hvt.pc $(RM) solo5-bindings-muen.pc $(RM) solo5-bindings-genode.pc - $(RM) -r include/crt - $(RM) Makeconf - -PREFIX?=/nonexistent # Fail if not run from OPAM -OPAM_BINDIR=$(PREFIX)/bin -OPAM_HVT_LIBDIR=$(PREFIX)/lib/solo5-bindings-hvt -OPAM_HVT_INCDIR=$(PREFIX)/include/solo5-bindings-hvt -OPAM_VIRTIO_LIBDIR=$(PREFIX)/lib/solo5-bindings-virtio -OPAM_VIRTIO_INCDIR=$(PREFIX)/include/solo5-bindings-virtio -OPAM_MUEN_LIBDIR=$(PREFIX)/lib/solo5-bindings-muen -OPAM_MUEN_INCDIR=$(PREFIX)/include/solo5-bindings-muen -OPAM_GENODE_LIBDIR=$(PREFIX)/lib/solo5-bindings-genode -OPAM_GENODE_INCDIR=$(PREFIX)/include/solo5-bindings-genode -OPAM_SPT_LIBDIR=$(PREFIX)/lib/solo5-bindings-spt -OPAM_SPT_INCDIR=$(PREFIX)/include/solo5-bindings-spt - -# We want the MD CFLAGS, LDFLAGS and LD in the .pc file, where they can be -# picked up by the Mirage tool / other downstream consumers. -%.pc: %.pc.in - sed <$< > $@ \ - -e 's#!CFLAGS!#$(MD_CFLAGS)#g;' \ - -e 's#!LDFLAGS!#$(LDFLAGS)#g;' \ - -e 's#!GENODE_APP_LDFLAGS!#$(GENODE_APP_LDFLAGS)#g;' \ - -e 's#!LD!#$(LD)#g;' \ -.PHONY: opam-virtio-install -opam-virtio-install: solo5-bindings-virtio.pc virtio - mkdir -p $(OPAM_VIRTIO_INCDIR) $(OPAM_VIRTIO_LIBDIR) - cp -R include/. $(OPAM_VIRTIO_INCDIR) - cp bindings/virtio/solo5_virtio.o bindings/virtio/solo5_virtio.lds $(OPAM_VIRTIO_LIBDIR) - mkdir -p $(OPAM_BINDIR) - cp scripts/virtio-mkimage/solo5-virtio-mkimage.sh ${OPAM_BINDIR}/solo5-virtio-mkimage - cp scripts/virtio-run/solo5-virtio-run.sh ${OPAM_BINDIR}/solo5-virtio-run - mkdir -p $(PREFIX)/lib/pkgconfig - cp solo5-bindings-virtio.pc $(PREFIX)/lib/pkgconfig - -.PHONY: opam-virtio-uninstall -opam-virtio-uninstall: - $(RM) -r $(OPAM_VIRTIO_INCDIR) $(OPAM_VIRTIO_LIBDIR) - $(RM) $(PREFIX)/lib/pkgconfig/solo5-bindings-virtio.pc - $(RM) ${OPAM_BINDIR}/solo5-mkimage - $(RM) ${OPAM_BINDIR}/solo5-run-virtio - -.PHONY: opam-hvt-install -opam-hvt-install: solo5-bindings-hvt.pc hvt - mkdir -p $(OPAM_HVT_INCDIR) $(OPAM_HVT_LIBDIR) - cp -R include/. $(OPAM_HVT_INCDIR) - cp bindings/hvt/solo5_hvt.o bindings/hvt/solo5_hvt.lds $(OPAM_HVT_LIBDIR) - mkdir -p $(OPAM_HVT_LIBDIR)/src - cp -R tenders/hvt/*.[ch] include/solo5/hvt_abi.h $(OPAM_HVT_LIBDIR)/src - mkdir -p $(OPAM_BINDIR) - cp tenders/hvt/solo5-hvt-configure $(OPAM_BINDIR) - mkdir -p $(PREFIX)/lib/pkgconfig - cp solo5-bindings-hvt.pc $(PREFIX)/lib/pkgconfig +.PHONY: distclean +distclean: MAKECMDGOALS := clean +distclean: clean + @echo DISTCLEAN solo5 + -[ -d include/crt ] && $(RM) -r include/crt + $(RM) Makeconf -.PHONY: opam-hvt-uninstall -opam-hvt-uninstall: - $(RM) -r $(OPAM_HVT_INCDIR) $(OPAM_HVT_LIBDIR) - $(RM) $(OPAM_BINDIR)/solo5-hvt-configure - $(RM) $(PREFIX)/lib/pkgconfig/solo5-bindings-hvt.pc +.PHONY: force-install +install-opam-%: MAKECMDGOALS := +install-opam-%: all solo5-bindings-%.pc force-install + @echo INSTALL solo5 + @[ -d "$(PREFIX)" -a -d "$(PREFIX)/bin" ] || \ + (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-$* + cp bindings/$*/solo5_$*.o bindings/$*/solo5_$*.lds \ + $(PREFIX)/lib/solo5-bindings-$* + cp solo5-bindings-$*.pc $(PREFIX)/lib/pkgconfig +ifdef CONFIG_HVT + cp tenders/hvt/solo5-hvt tenders/hvt/solo5-hvt-configure $(PREFIX)/bin + [ -f tenders/hvt/solo5-hvt-debug ] && \ + cp tenders/hvt/solo5-hvt-debug $(PREFIX)/bin +endif +ifdef CONFIG_SPT + cp tenders/spt/solo5-spt $(PREFIX)/bin +endif +ifdef CONFIG_VIRTIO + cp scripts/virtio-mkimage/solo5-virtio-mkimage.sh \ + $(PREFIX)/bin/solo5-virtio-mkimage + cp scripts/virtio-run/solo5-virtio-run.sh \ + $(PREFIX)/bin/solo5-virtio-run +endif -.PHONY: opam-muen-install -opam-muen-install: solo5-bindings-muen.pc muen - mkdir -p $(OPAM_MUEN_INCDIR) $(OPAM_MUEN_LIBDIR) - cp -R include/. $(OPAM_MUEN_INCDIR) - cp bindings/muen/solo5_muen.o bindings/muen/solo5_muen.lds $(OPAM_MUEN_LIBDIR) - mkdir -p $(PREFIX)/lib/pkgconfig - cp solo5-bindings-muen.pc $(PREFIX)/lib/pkgconfig +.PHONY: force-uninstall +uninstall-opam-%: force-uninstall + @echo UNINSTALL solo5 + @[ -d "$(PREFIX)" -a -d "$(PREFIX)/bin" ] || \ + (echo "error: PREFIX not set or incorrect"; false) + -[ -d "$(PREFIX)/include/solo5-bindings-$*/solo5" ] && \ + $(RM) -r $(PREFIX)/include/solo5-bindings-$*/solo5 + -[ -d "$(PREFIX)/include/solo5-bindings-$*/crt" ] && \ + $(RM) -r $(PREFIX)/include/solo5-bindings-$*/crt + $(RM) $(PREFIX)/lib/solo5-bindings-$*/solo5_$*.o \ + $(PREFIX)/lib/solo5-bindings-$*/solo5_$*.lds + $(RM) $(PREFIX)/lib/pkgconfig/solo5-bindings-$*.pc +ifdef CONFIG_HVT + $(RM) $(PREFIX)/bin/solo5-hvt $(PREFIX)/bin/solo5-hvt-debug \ + $(PREFIX)/bin/solo5-hvt-configure +endif +ifdef CONFIG_SPT + $(RM) $(PREFIX)/bin/solo5-spt +endif +ifdef CONFIG_VIRTIO + $(RM) $(PREFIX)/bin/solo5-virtio-mkimage + $(RM) $(PREFIX)/bin/solo5-virtio-run +endif -.PHONY: opam-muen-uninstall -opam-muen-uninstall: - $(RM) -r $(OPAM_MUEN_INCDIR) $(OPAM_MUEN_LIBDIR) - $(RM) $(PREFIX)/lib/pkgconfig/solo5-bindings-muen.pc +# The following targets are kept for backwards compatibility, as otherwise +# upgrading existing OPAM switches will fail. They should be removed at some +# point, along with the dummy solo5-hvt-configure. +opam-hvt-uninstall: uninstall-opam-hvt ; + +opam-spt-uninstall: uninstall-opam-spt ; -.PHONY: opam-genode-install -opam-genode-install: solo5-bindings-genode.pc genode - mkdir -p $(OPAM_GENODE_INCDIR) $(OPAM_GENODE_LIBDIR) - cp -R include/. $(OPAM_GENODE_INCDIR) - cp bindings/genode/solo5.lib.so bindings/genode/genode_dyn.ld $(OPAM_GENODE_LIBDIR) - mkdir -p $(PREFIX)/lib/pkgconfig - cp solo5-bindings-genode.pc $(PREFIX)/lib/pkgconfig +opam-virtio-uninstall: uninstall-opam-virtio ; -.PHONY: opam-genode-uninstall -opam-genode-uninstall: - $(RM) -r $(OPAM_GENODE_INCDIR) $(OPAM_GENODE_LIBDIR) - $(RM) $(PREFIX)/lib/pkgconfig/solo5-bindings-genode.pc +opam-muen-uninstall: uninstall-opam-muen ; -.PHONY: opam-spt-install -opam-spt-install: solo5-bindings-spt.pc spt - mkdir -p $(OPAM_SPT_INCDIR) $(OPAM_SPT_LIBDIR) - cp -R include/. $(OPAM_SPT_INCDIR) - cp bindings/spt/solo5_spt.o bindings/spt/solo5_spt.lds $(OPAM_SPT_LIBDIR) - mkdir -p $(PREFIX)/lib/pkgconfig - cp solo5-bindings-spt.pc $(PREFIX)/lib/pkgconfig - mkdir -p $(OPAM_BINDIR) - cp tenders/spt/solo5-spt ${OPAM_BINDIR}/solo5-spt +opam-genode-uninstall: uninstall-opam-genode ; -.PHONY: opam-spt-uninstall -opam-spt-uninstall: - $(RM) -r $(OPAM_SPT_INCDIR) $(OPAM_SPT_LIBDIR) - $(RM) $(PREFIX)/lib/pkgconfig/solo5-bindings-spt.pc - $(RM) ${OPAM_BINDIR}/solo5-spt +$(V).SILENT: diff --git a/Makefile.common b/Makefile.common index 2546a514..f23db947 100644 --- a/Makefile.common +++ b/Makefile.common @@ -16,31 +16,87 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# This Makefile defines global defaults for building Solo5 and the in-tree test -# programs. These can be overriden either on the command line, or via Makeconf -# generated by configure.sh. -include $(TOP)/Makeconf - -# Be clear about some common programs we use! -AS?=as -CC?=cc -LD?=ld -OBJCOPY?=objcopy - -# Exported to OPAM via pkg-config. -MD_CFLAGS=-ffreestanding -fstack-protector-strong ${HOST_CFLAGS} -ifeq ($(TARGET_ARCH), x86_64) -MD_CFLAGS+=-mno-red-zone +# This Makefile defines common rules for building Solo5 and the in-tree test +# programs. Variables starting with CONFIG_ and MAKECONF_ are sourced from the +# Makeconf generated by configure.sh, and MAY be overriden by the user on the +# top-level "make" command line. +ifndef TOPDIR +$(error TOPDIR must be set, run $(MAKE) from the top of the source tree or set it manually) endif +include $(TOPDIR)/Makeconf -# Likewise. -COMMON_LDFLAGS=-nostdlib -z max-page-size=0x1000 -LDFLAGS=$(COMMON_LDFLAGS) -static $(HOST_LDFLAGS) -# CFLAGS used for building bindings/ and in-tree tests. -INCDIR=-isystem $(TOP)/include/crt -I$(TOP)/include/solo5 -CFLAGS=$(MD_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -O2 -g $(INCDIR) - -# Genode linking is a special case -GENODE_COMMON_LDFLAGS = $(COMMON_LDFLAGS) -shared -gc-sections --eh-frame-hdr -GENODE_LIB_LDFLAGS=$(GENODE_COMMON_LDFLAGS) --entry=0x0 -T $(TOP)/bindings/genode/genode_rel.ld -GENODE_APP_LDFLAGS=$(GENODE_COMMON_LDFLAGS) -Ttext=0x01000000 --dynamic-linker=ld.lib.so -rpath-link=. +# +# The following variables and recipes apply to building bindings and +# tests (applications). +# +CC := $(MAKECONF_CC) +CFLAGS := -std=gnu99 -Wall -Wextra -Werror -O2 -g +CFLAGS += -ffreestanding -fstack-protector-strong $(MAKECONF_CFLAGS) +CPPFLAGS := -isystem $(TOPDIR)/include/crt -I$(TOPDIR)/include/solo5 +LD := $(MAKECONF_LD) +LDFLAGS := -nostdlib -z max-page-size=0x1000 -static $(MAKECONF_LDFLAGS) +OBJCOPY := objcopy + +# Genode application compiling and linking is a special case +GENODE_APP_CFLAGS := $(CFLAGS) -fPIC +GENODE_APP_LDFLAGS := -nostdlib -z max-page-size=0x1000 -shared -gc-sections \ + --eh-frame-hdr -Ttext=0x01000000 --dynamic-linker=ld.lib.so -rpath-link=. + +# Also used by the HOST_ rules below. +DEPFLAGS = -MT $@ -MMD -MP -MF $*.Td + +define COMPILE.c + @echo "CC $<" + $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + mv -f $*.Td $*.d && touch $@ +endef + +define COMPILE.S + @echo "AS $<" + $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -DASM_FILE -c $< -o $@ + mv -f $*.Td $*.d && touch $@ +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) +HOSTCFLAGS := -Wall -Werror -std=c99 -O2 -g +HOSTCPPFLAGS := -I$(TOPDIR)/include/solo5 +HOSTLDFLAGS := +HOSTLDLIBS := + +define HOSTCOMPILE.c + @echo "HOSTCC $<" + $(HOSTCC) $(DEPFLAGS) $(HOSTCFLAGS) $(HOSTCPPFLAGS) -c $< -o $@ + mv -f $*.Td $*.d && touch $@ +endef + +define HOSTCOMPILE.S + @echo "HOSTAS $<" + $(HOSTCC) $(DEPFLAGS) $(HOSTCFLAGS) $(HOSTCPPFLAGS) -DASM_FILE -c $< -o $@ + mv -f $*.Td $*.d && touch $@ +endef + +define HOSTLINK + @echo "HOSTLINK $@" + $(HOSTCC) $(HOSTLDFLAGS) $^ $(HOSTLDLIBS) -o $@ +endef + +PC_CFLAGS := -ffreestanding -fstack-protector-strong $(MAKECONF_CFLAGS) +PC_GENODE_CFLAGS := $(GENODE_APP_CFLAGS) +PC_LD := $(MAKECONF_LD) +PC_LDFLAGS := $(LDFLAGS) +PC_GENODE_LDFLAGS := $(GENODE_APP_LDFLAGS) + +%.pc: %.pc.in + @echo SUBST $@ + sed <$< > $@ \ + -e 's#!PC_CFLAGS!#$(PC_CFLAGS)#g;' \ + -e 's#!PC_GENODE_CFLAGS!#$(PC_GENODE_CFLAGS)#g;' \ + -e 's#!PC_LD!#$(PC_LD)#g;' \ + -e 's#!PC_LDFLAGS!#$(PC_LDFLAGS)#g;' \ + -e 's#!PC_GENODE_LDFLAGS!#$(PC_GENODE_LDFLAGS)#g;' \ + +.PRECIOUS: %.pc diff --git a/bindings/GNUmakefile b/bindings/GNUmakefile index ecbf5404..ecfec6bc 100644 --- a/bindings/GNUmakefile +++ b/bindings/GNUmakefile @@ -16,134 +16,139 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -include $(TOP)/Makefile.common - -COMMON_COBJS=\ -abort.o \ -cpu_${TARGET_ARCH}.o \ -cpu_vectors_${TARGET_ARCH}.o \ -crt.o \ -printf.o \ -intr.o \ -lib.o \ -mem.o \ -exit.o \ -log.o \ -cmdline.o - -COMMON_HVT_COBJS=\ -hvt/start.o \ -hvt/platform.o \ -hvt/platform_intr.o \ -hvt/time.o - -HVT_COBJS=\ -$(COMMON_HVT_COBJS) \ -hvt/platform_lifecycle.o \ -hvt/yield.o \ -hvt/tscclock.o \ -hvt/console.o \ -hvt/net.o \ -hvt/block.o \ -$(COMMON_COBJS) - -VIRTIO_COBJS=\ -virtio/boot.o \ -virtio/start.o \ -virtio/platform.o \ -virtio/platform_intr.o \ -virtio/pci.o \ -virtio/serial.o \ -virtio/time.o \ -virtio/virtio_ring.o \ -virtio/virtio_net.o \ -virtio/virtio_blk.o \ -virtio/tscclock.o \ -virtio/clock_subr.o \ -virtio/pvclock.o \ -$(COMMON_COBJS) - -MUEN_COBJS=\ -$(COMMON_HVT_COBJS) \ -muen/channel.o \ -muen/reader.o \ -muen/writer.o \ -muen/muen-block.o \ -muen/muen-clock.o \ -muen/muen-console.o \ -muen/muen-net.o \ -muen/muen-platform_lifecycle.o \ -muen/muen-yield.o \ -muen/muen-sinfo.o \ -$(COMMON_COBJS) - -GENODE_COBJS=\ -genode/stubs.o - -SPT_COBJS=\ -abort.o \ -crt.o \ -printf.o \ -lib.o \ -mem.o \ -exit.o \ -log.o \ -cmdline.o \ -spt/bindings.o \ -spt/block.o \ -spt/net.o \ -spt/platform.o \ -spt/start.o \ -spt/sys_linux_${TARGET_ARCH}.o - -HEADERS=\ -bindings.h - -all: virtio hvt - -.PHONY: virtio hvt muen genode spt -virtio: virtio/solo5_virtio.o -hvt: hvt/solo5_hvt.o -muen: muen/solo5_muen.o -genode: genode/solo5.lib.so -spt: spt/solo5_spt.o - -CFLAGS+=-D__SOLO5_BINDINGS__ - -ifeq ($(TARGET_ARCH), x86_64) +ifndef TOPDIR +$(error TOPDIR must be set, run $(MAKE) from the top of the source tree or set it manually) +endif +include $(TOPDIR)/Makefile.common + +.PHONY: all +all: +all_TARGETS := + +.SUFFIXES: +$(V).SILENT: + +common_SRCS := abort.c cpu_$(CONFIG_ARCH).c cpu_vectors_$(CONFIG_ARCH).S \ + crt.c printf.c intr.c lib.c mem.c exit.c log.c cmdline.c + +common_hvt_SRCS := hvt/start.c hvt/platform.c hvt/platform_intr.c hvt/time.c + +hvt_SRCS := $(common_SRCS) $(common_hvt_SRCS) \ + hvt/platform_lifecycle.c hvt/yield.c hvt/tscclock.c hvt/console.c \ + hvt/net.c hvt/block.c + +spt_SRCS := abort.c crt.c printf.c lib.c mem.c exit.c log.c cmdline.c \ + spt/bindings.c spt/block.c spt/net.c spt/platform.c spt/start.c \ + spt/sys_linux_$(CONFIG_ARCH).c + +virtio_SRCS := $(common_SRCS) \ + virtio/boot.S virtio/start.c virtio/platform.c virtio/platform_intr.c \ + virtio/pci.c virtio/serial.c virtio/time.c virtio/virtio_ring.c \ + virtio/virtio_net.c virtio/virtio_blk.c virtio/tscclock.c \ + virtio/clock_subr.c virtio/pvclock.c + +muen_SRCS := $(common_SRCS) $(common_hvt_SRCS) \ + muen/channel.c muen/reader.c muen/writer.c muen/muen-block.c \ + 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 + +CPPFLAGS+=-D__SOLO5_BINDINGS__ + +ifeq ($(CONFIG_ARCH), x86_64) # Prevent the compiler from adding optimizations that use shared FPU state. # This is necessary for early boot code and trap handlers. -MD_CFLAGS+=-mno-sse -mno-mmx -mno-aes -mno-avx +CFLAGS+=-mno-sse -mno-mmx -mno-aes -mno-avx -mno-red-zone endif -genode/stubs.o: genode/stubs.c $(HEADERS) - $(CC) $(CFLAGS) -Wno-unused-parameter -c $< -o $@ +%.o: %.c %.d + $(COMPILE.c) -%.o: %.c $(HEADERS) - $(CC) $(CFLAGS) -c $< -o $@ +%.o: %.S %.d + $(COMPILE.S) -%.o: %.S $(HEADERS) - $(CC) $(CFLAGS) -DASM_FILE -c $< -o $@ +%.d: ; +.PRECIOUS: %.d -virtio/solo5_virtio.o: $(VIRTIO_COBJS) virtio/solo5_virtio.lds - $(LD) -r $(LDFLAGS) -o $@ $(VIRTIO_COBJS) - $(OBJCOPY) -w -G solo5_\* -G _start\* -G __stack_chk_\* $@ $@ +all_TARGETS := +all_OBJS := +all_SRCS := -hvt/solo5_hvt.o: $(HVT_COBJS) hvt/solo5_hvt.lds - $(LD) -r $(LDFLAGS) -o $@ $(HVT_COBJS) +define LINK.bindings + @echo "LD $@" + $(LD) -r $(LDFLAGS) $^ -o $@ + @echo "OBJCOPY $@" $(OBJCOPY) -w -G solo5_\* -G _start\* -G __stack_chk_\* $@ $@ +endef -muen/solo5_muen.o: $(MUEN_COBJS) muen/solo5_muen.lds - $(LD) -r $(LDFLAGS) -o $@ $(MUEN_COBJS) - $(OBJCOPY) -w -G solo5_\* -G _start\* -G __stack_chk_\* $@ $@ +ifdef CONFIG_HVT + hvt_OBJS := $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(hvt_SRCS))) -genode/solo5.lib.so: $(GENODE_COBJS) - $(LD) $(GENODE_LIB_LDFLAGS) -o $@ $^ +hvt/solo5_hvt.o: $(hvt_OBJS) + $(LINK.bindings) -spt/solo5_spt.o: $(SPT_COBJS) spt/solo5_spt.lds - $(LD) -r $(LDFLAGS) -o $@ $(SPT_COBJS) - $(OBJCOPY) -w -G solo5_\* -G _start\* -G __stack_chk_\* $@ $@ + all_TARGETS += hvt/solo5_hvt.o + all_OBJS += $(hvt_OBJS) + all_SRCS += $(hvt_SRCS) +endif + +ifdef CONFIG_SPT + spt_OBJS := $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(spt_SRCS))) + +spt/solo5_spt.o: $(spt_OBJS) + $(LINK.bindings) + + all_TARGETS += spt/solo5_spt.o + all_OBJS += $(spt_OBJS) + all_SRCS += $(spt_SRCS) +endif + +ifdef CONFIG_VIRTIO + virtio_OBJS := $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(virtio_SRCS))) + +virtio/solo5_virtio.o: $(virtio_OBJS) + $(LINK.bindings) + + all_TARGETS += virtio/solo5_virtio.o + all_OBJS += $(virtio_OBJS) + all_SRCS += $(virtio_SRCS) +endif + +ifdef CONFIG_MUEN + muen_OBJS := $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(muen_SRCS))) + +muen/solo5_muen.o: $(muen_OBJS) + $(LINK.bindings) + + all_TARGETS += muen/solo5_muen.o + all_OBJS += $(muen_OBJS) + all_SRCS += $(muen_SRCS) +endif + +ifdef CONFIG_GENODE + genode_OBJS := $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(genode_SRCS))) + +$(genode_OBJS): CFLAGS += -Wno-unused-parameter + +GENODE_LDFLAGS := -nostdlib -z max-page-size=0x1000 -shared -gc-sections \ + --eh-frame-hdr --entry=0x0 -T genode/genode_rel.ld +genode/solo5.lib.so: $(genode_OBJS) + @echo "LD $@" + $(LD) $(GENODE_LDFLAGS) $^ -o $@ + + all_TARGETS += genode/solo5.lib.so + all_OBJS += $(genode_OBJS) + all_SRCS += $(genode_SRCS) +endif + +all: $(all_TARGETS) + +all_DEPS := $(patsubst %.o,%.d,$(all_OBJS)) .PHONY: clean clean: - $(RM) *.o virtio/*.o hvt/*.o muen/*.o genode/*.o genode/*.lib.so spt/*.o + @echo "CLEAN bindings" + $(RM) $(all_TARGETS) $(all_OBJS) $(all_DEPS) + +include $(wildcard $(all_DEPS)) diff --git a/build.sh b/build.sh index f9608897..ad437cfb 100755 --- a/build.sh +++ b/build.sh @@ -44,7 +44,8 @@ try() do_basic() { - message "Starting build: '${MAKE}'" + message "Starting build." + try ./configure.sh try ${MAKE} # Some CIs can now run tests, so do that. if [ -n "${SURF_RUN_TESTS}" ]; then @@ -52,7 +53,7 @@ do_basic() # XXX grub-bhyve is unstable under nested virt, so don't run the # virtio tests on FreeBSD. if [ "$(uname -s)" = "FreeBSD" ]; then - echo BUILD_VIRTIO=no >>Makeconf + echo CONFIG_VIRTIO= >>Makeconf fi try ${SURF_SUDO} tests/setup-tests.sh try ${SURF_SUDO} tests/run-tests.sh diff --git a/configure.sh b/configure.sh index 77ef4152..ce4b721a 100755 --- a/configure.sh +++ b/configure.sh @@ -17,15 +17,17 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +prog_NAME="$(basename $0)" + die() { - echo "$0: ERROR: $@" 1>&2 + echo "${prog_NAME}: ERROR: $@" 1>&2 exit 1 } warn() { - echo "$0: WARNING: $@" 1>&2 + echo "${prog_NAME}: WARNING: $@" 1>&2 } cc_maybe_gcc() @@ -58,6 +60,16 @@ int main(int argc, char *argv[]) EOM } +gcc_check_lib() +{ + ${CC} -x c -o /dev/null - "$@" </dev/null 2>&1 +int main(int argc, char *argv[]) +{ + return 0; +} +EOM +} + ld_is_lld() { ${LD} --version 2>&1 | grep -q '^LLD' @@ -67,18 +79,25 @@ ld_is_lld() CC=${CC:-cc} LD=${LD:-ld} -TARGET=$(${CC} -dumpmachine) +CC_MACHINE=$(${CC} -dumpmachine) [ $? -ne 0 ] && die "Could not run '${CC} -dumpmachine', is your compiler working?" -case ${TARGET} in - x86_64-*|amd64-*) - TARGET_ARCH=x86_64 +# Determine HOST and ARCH based on what the toolchain reports. +case ${CC_MACHINE} in + x86_64-linux*) + CONFIG_ARCH=x86_64 CONFIG_HOST=Linux ;; - aarch64-*) - TARGET_ARCH=aarch64 + aarch64-linux*) + CONFIG_ARCH=aarch64 CONFIG_HOST=Linux ;; + x86_64-*freebsd*) + CONFIG_ARCH=x86_64 CONFIG_HOST=FreeBSD + ;; + amd64-*openbsd*) + CONFIG_ARCH=x86_64 CONFIG_HOST=OpenBSD + ;; *) - die "Unsupported compiler target: ${TARGET}" + die "Unsupported toolchain target: ${CC_MACHINE}" ;; esac @@ -87,7 +106,16 @@ esac # pkg-config. HOST_INCDIR=${PWD}/include/crt -case $(uname -s) in +CONFIG_HVT= +CONFIG_SPT= +CONFIG_VIRTIO= +CONFIG_MUEN= +CONFIG_GENODE= +MAKECONF_CFLAGS= +MAKECONF_LDFLAGS= +CONFIG_SPT_NO_PIE= + +case "${CONFIG_HOST}" in Linux) # On Linux/gcc we use -nostdinc and copy all the gcc-provided headers. cc_is_gcc || die "Only 'gcc' 4.x+ is supported on Linux" @@ -96,23 +124,23 @@ case $(uname -s) in mkdir -p ${HOST_INCDIR} cp -R ${CC_INCDIR}/. ${HOST_INCDIR} - HOST_CFLAGS="-nostdinc" + MAKECONF_CFLAGS="-nostdinc" # Recent distributions now default to PIE enabled. Disable it explicitly # if that's the case here. # XXX: This breaks MirageOS in (at least) the build of mirage-solo5 due # to -fno-pie breaking the build of lib/dllmirage-solo5_bindings.so. # Keep this disabled until that is resolved. - # cc_has_pie && HOST_CFLAGS="${HOST_CFLAGS} -fno-pie" + # cc_has_pie && MAKECONF_CFLAGS="${MAKECONF_CFLAGS} -fno-pie" # Stack smashing protection: # # Any GCC configured for a Linux/x86_64 target (actually, any # glibc-based target) will use a TLS slot to address __stack_chk_guard. # Disable this behaviour and use an ordinary global variable instead. - if [ "${TARGET_ARCH}" = "x86_64" ]; then + if [ "${CONFIG_ARCH}" = "x86_64" ]; then gcc_check_option -mstack-protector-guard=global || \ die "GCC 4.9.0 or newer is required for -mstack-protector-guard= support" - HOST_CFLAGS="${HOST_CFLAGS} -mstack-protector-guard=global" + MAKECONF_CFLAGS="${MAKECONF_CFLAGS} -mstack-protector-guard=global" fi # If the host toolchain is NOT configured to build PIE exectuables by @@ -121,27 +149,25 @@ case $(uname -s) in if ! cc_has_pie; then warn "Host toolchain does not build PIE executables, spt guest size will be limited to 1GB" warn "Consider upgrading to a Linux distribution with PIE support" - SPT_EXTRA_LDFLAGS="-Wl,-Ttext-segment=0x40000000" + CONFIG_SPT_NO_PIE=1 fi - BUILD_HVT="yes" - BUILD_SPT="yes" - if [ "${TARGET_ARCH}" = "x86_64" ]; then - BUILD_VIRTIO="yes" - BUILD_MUEN="yes" - BUILD_GENODE="yes" - else - BUILD_VIRTIO="no" - BUILD_MUEN="no" - BUILD_GENODE="no" - fi + CONFIG_HVT=1 + if gcc_check_lib -lseccomp; then + CONFIG_SPT=1 + else + warn "Could not link with -lseccomp, not building spt" + fi + [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_VIRTIO=1 + [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_MUEN=1 + [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_GENODE=1 ;; FreeBSD) # On FreeBSD/clang we use -nostdlibinc which gives us access to the # clang-provided headers for compiler instrinsics. We copy the rest # (std*.h, float.h and their dependencies) from the host. cc_is_clang || die "Only 'clang' is supported on FreeBSD" - [ "${TARGET_ARCH}" = "x86_64" ] || + [ "${CONFIG_ARCH}" = "x86_64" ] || die "Only 'x86_64' is supported on FreeBSD" INCDIR=/usr/include SRCS_MACH="machine/_stdint.h machine/_types.h machine/endian.h \ @@ -163,19 +189,20 @@ case $(uname -s) in # # FreeBSD toolchains use a global (non-TLS) __stack_chk_guard by # default on x86_64, so there is nothing special we need to do here. - HOST_CFLAGS="-nostdlibinc" - BUILD_HVT="yes" - BUILD_VIRTIO="yes" - BUILD_MUEN="yes" - BUILD_GENODE="yes" - BUILD_SPT="no" + MAKECONF_CFLAGS="-nostdlibinc" + + CONFIG_HVT=1 + CONFIG_SPT= + [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_VIRTIO=1 + [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_MUEN=1 + CONFIG_GENODE= ;; OpenBSD) # On OpenBSD/clang we use -nostdlibinc which gives us access to the # clang-provided headers for compiler instrinsics. We copy the rest # (std*.h, cdefs.h and their dependencies) from the host. cc_is_clang || die "Only 'clang' is supported on OpenBSD" - [ "${TARGET_ARCH}" = "x86_64" ] || + [ "${CONFIG_ARCH}" = "x86_64" ] || die "Only 'x86_64' is supported on OpenBSD" if ! ld_is_lld; then LD='/usr/bin/ld.lld' @@ -203,32 +230,59 @@ case $(uname -s) in # we don't support yet. Unfortunately LLVM does not support # -mstack-protector-guard, so disable SSP on OpenBSD for the time # being. - HOST_CFLAGS="-fno-stack-protector -nostdlibinc" + MAKECONF_CFLAGS="-fno-stack-protector -nostdlibinc" warn "Stack protector (SSP) disabled on OpenBSD due to toolchain issues" - HOST_LDFLAGS="-nopie" - BUILD_HVT="yes" - BUILD_VIRTIO="yes" - BUILD_MUEN="yes" - BUILD_GENODE="yes" - BUILD_SPT="no" + MAKECONF_LDFLAGS="-nopie" + + CONFIG_HVT=1 + CONFIG_SPT= + [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_VIRTIO=1 + [ "${CONFIG_ARCH}" = "x86_64" ] && CONFIG_MUEN=1 + CONFIG_GENODE= ;; *) - die "Unsupported build OS: $(uname -s)" + die "Unsupported build OS: ${CONFIG_HOST}" ;; esac +# WARNING: +# +# The generated Makeconf is dual-use! It is both sourced by GNU make, and by +# the test suite. As such, a subset of this file must parse in both shell *and* +# 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 +# available to Makefiles. +# +# 2. Shell scripts parse the subset of *lines* starting with "CONFIG_". I.e. +# only variables named "CONFIG_..." are available. When adding new variables +# to this group you must ensure that they do not contain more than a single +# "word". +# +# Please do NOT add variable names with new prefixes without asking first. +# cat <Makeconf -# Generated by configure.sh, using CC=${CC} for target ${TARGET} -BUILD_HVT=${BUILD_HVT} -BUILD_SPT=${BUILD_SPT} -BUILD_VIRTIO=${BUILD_VIRTIO} -BUILD_MUEN=${BUILD_MUEN} -BUILD_GENODE=${BUILD_GENODE} -HOST_CFLAGS=${HOST_CFLAGS} -HOST_LDFLAGS=${HOST_LDFLAGS} -TEST_TARGET=${TARGET} -TARGET_ARCH=${TARGET_ARCH} -CC=${CC} -LD=${LD} -SPT_EXTRA_LDFLAGS=${SPT_EXTRA_LDFLAGS} +# Generated by configure.sh, using CC=${CC} for target ${CC_MACHINE} +CONFIG_HVT=${CONFIG_HVT} +CONFIG_SPT=${CONFIG_SPT} +CONFIG_VIRTIO=${CONFIG_VIRTIO} +CONFIG_MUEN=${CONFIG_MUEN} +CONFIG_GENODE=${CONFIG_GENODE} +MAKECONF_CFLAGS=${MAKECONF_CFLAGS} +MAKECONF_LDFLAGS=${MAKECONF_LDFLAGS} +CONFIG_ARCH=${CONFIG_ARCH} +CONFIG_HOST=${CONFIG_HOST} +MAKECONF_CC=${CC} +MAKECONF_LD=${LD} +CONFIG_SPT_NO_PIE=${CONFIG_SPT_NO_PIE} EOM + +echo "${prog_NAME}: Configured for ${CC_MACHINE}." +echo -n "${prog_NAME}: Enabled targets:" +[ -n "${CONFIG_HVT}" ] && echo -n " hvt" +[ -n "${CONFIG_SPT}" ] && echo -n " spt" +[ -n "${CONFIG_VIRTIO}" ] && echo -n " virtio" +[ -n "${CONFIG_MUEN}" ] && echo -n " muen" +[ -n "${CONFIG_GENODE}" ] && echo -n " genode" +echo "." diff --git a/solo5-bindings-genode.opam b/solo5-bindings-genode.opam index 36e57baa..bad8cd97 100644 --- a/solo5-bindings-genode.opam +++ b/solo5-bindings-genode.opam @@ -7,15 +7,18 @@ homepage: "https://github.com/solo5/solo5" bug-reports: "https://github.com/solo5/solo5/issues" license: "ISC" dev-repo: "git+https://github.com/solo5/solo5.git" -build: [make "genode"] -install: [make "opam-genode-install" "PREFIX=%{prefix}%"] -remove: [make "opam-genode-uninstall" "PREFIX=%{prefix}%"] +build: [ + ["./configure.sh"] + [make "V=1" "CONFIG_HVT=" "CONFIG_SPT=" "CONFIG_VIRTIO=" "CONFIG_MUEN="] +] +install: [make "V=1" "install-opam-genode" "PREFIX=%{prefix}%"] +remove: [make "V=1" "uninstall-opam-genode" "PREFIX=%{prefix}%"] depends: "conf-pkg-config" conflicts: [ "solo5-bindings-hvt" - "solo5-bindings-muen" "solo5-bindings-spt" "solo5-bindings-virtio" + "solo5-bindings-muen" ] available: [ arch = "x86_64" & diff --git a/solo5-bindings-genode.pc.in b/solo5-bindings-genode.pc.in index 5324ddb7..94184b79 100644 --- a/solo5-bindings-genode.pc.in +++ b/solo5-bindings-genode.pc.in @@ -2,9 +2,10 @@ prefix=${pcfiledir}/../.. exec_prefix=${prefix} includedir=${prefix}/include/solo5-bindings-genode libdir=${exec_prefix}/lib/solo5-bindings-genode +ld=!PC_LD! +ldflags=!PC_GENODE_LDFLAGS! -T ${libdir}/genode_dyn.ld ${libdir}/solo5.lib.so Name: solo5-bindings-genode Version: 0.4.0 Description: Solo5 sandboxed execution environment (Genode target) -Cflags: !CFLAGS! -fPIC -isystem ${includedir}/crt -I${includedir}/solo5 -Libs: !GENODE_APP_LDFLAGS! -T ${libdir}/genode_dyn.ld ${libdir}/solo5.lib.so +Cflags: !PC_GENODE_CFLAGS! -isystem ${includedir}/crt -I${includedir}/solo5 diff --git a/solo5-bindings-hvt.opam b/solo5-bindings-hvt.opam index 9fb82612..2943da26 100644 --- a/solo5-bindings-hvt.opam +++ b/solo5-bindings-hvt.opam @@ -9,9 +9,12 @@ homepage: "https://github.com/solo5/solo5" bug-reports: "https://github.com/solo5/solo5/issues" license: "ISC" dev-repo: "git+https://github.com/solo5/solo5.git" -build: [make "hvt"] -install: [make "opam-hvt-install" "PREFIX=%{prefix}%"] -remove: [make "opam-hvt-uninstall" "PREFIX=%{prefix}%"] +build: [ + ["./configure.sh"] + [make "V=1" "CONFIG_SPT=" "CONFIG_VIRTIO=" "CONFIG_MUEN=" "CONFIG_GENODE="] +] +install: [make "V=1" "install-opam-hvt" "PREFIX=%{prefix}%"] +remove: [make "V=1" "uninstall-opam-hvt" "PREFIX=%{prefix}%"] depends: "conf-pkg-config" depexts: [ ["linux-headers"] {os-distribution = "alpine"} @@ -21,10 +24,10 @@ depexts: [ ["linux-libc-dev"] {os-distribution = "ubuntu"} ] conflicts: [ - "solo5-bindings-genode" - "solo5-bindings-muen" "solo5-bindings-spt" "solo5-bindings-virtio" + "solo5-bindings-muen" + "solo5-bindings-genode" ] available: [ (arch = "x86_64" | arch = "arm64") & diff --git a/solo5-bindings-hvt.pc.in b/solo5-bindings-hvt.pc.in index 045e8944..aef82e35 100644 --- a/solo5-bindings-hvt.pc.in +++ b/solo5-bindings-hvt.pc.in @@ -2,10 +2,10 @@ prefix=${pcfiledir}/../.. exec_prefix=${prefix} includedir=${prefix}/include/solo5-bindings-hvt libdir=${exec_prefix}/lib/solo5-bindings-hvt -ld=!LD! -ldflags=!LDFLAGS! -T ${libdir}/solo5_hvt.lds ${libdir}/solo5_hvt.o +ld=!PC_LD! +ldflags=!PC_LDFLAGS! -T ${libdir}/solo5_hvt.lds ${libdir}/solo5_hvt.o Name: solo5-bindings-hvt Version: 0.4.0 Description: Solo5 sandboxed execution environment (hvt target) -Cflags: !CFLAGS! -isystem ${includedir}/crt -I${includedir}/solo5 +Cflags: !PC_CFLAGS! -isystem ${includedir}/crt -I${includedir}/solo5 diff --git a/solo5-bindings-muen.opam b/solo5-bindings-muen.opam index 285b2089..da686578 100644 --- a/solo5-bindings-muen.opam +++ b/solo5-bindings-muen.opam @@ -9,9 +9,12 @@ homepage: "https://github.com/solo5/solo5" bug-reports: "https://github.com/solo5/solo5/issues" license: "ISC" dev-repo: "git+https://github.com/solo5/solo5.git" -build: [make "muen"] -install: [make "opam-muen-install" "PREFIX=%{prefix}%"] -remove: [make "opam-muen-uninstall" "PREFIX=%{prefix}%"] +build: [ + ["./configure.sh"] + [make "V=1" "CONFIG_HVT=" "CONFIG_SPT=" "CONFIG_VIRTIO=" "CONFIG_GENODE="] +] +install: [make "V=1" "install-opam-muen" "PREFIX=%{prefix}%"] +remove: [make "V=1" "uninstall-opam-muen" "PREFIX=%{prefix}%"] depends: "conf-pkg-config" conflicts: [ "solo5-bindings-genode" diff --git a/solo5-bindings-muen.pc.in b/solo5-bindings-muen.pc.in index 3fef8188..69090971 100644 --- a/solo5-bindings-muen.pc.in +++ b/solo5-bindings-muen.pc.in @@ -2,9 +2,9 @@ prefix=${pcfiledir}/../.. exec_prefix=${prefix} includedir=${prefix}/include/solo5-bindings-muen libdir=${exec_prefix}/lib/solo5-bindings-muen -ldflags=!LDFLAGS! -T ${libdir}/solo5_muen.lds ${libdir}/solo5_muen.o +ldflags=!PC_LDFLAGS! -T ${libdir}/solo5_muen.lds ${libdir}/solo5_muen.o Name: solo5-bindings-muen Version: 0.4.0 Description: Solo5 sandboxed execution environment (Muen target) -Cflags: !CFLAGS! -isystem ${includedir}/crt -I${includedir}/solo5 +Cflags: !PC_CFLAGS! -isystem ${includedir}/crt -I${includedir}/solo5 diff --git a/solo5-bindings-spt.opam b/solo5-bindings-spt.opam index 05f4780d..b6ca7d9a 100644 --- a/solo5-bindings-spt.opam +++ b/solo5-bindings-spt.opam @@ -9,9 +9,12 @@ homepage: "https://github.com/solo5/solo5" bug-reports: "https://github.com/solo5/solo5/issues" license: "ISC" dev-repo: "git+https://github.com/solo5/solo5.git" -build: [make "spt"] -install: [make "opam-spt-install" "PREFIX=%{prefix}%"] -remove: [make "opam-spt-uninstall" "PREFIX=%{prefix}%"] +build: [ + ["./configure.sh"] + [make "V=1" "CONFIG_HVT=" "CONFIG_VIRTIO=" "CONFIG_MUEN=" "CONFIG_GENODE="] +] +install: [make "V=1" "install-opam-spt" "PREFIX=%{prefix}%"] +remove: [make "V=1" "uninstall-opam-spt" "PREFIX=%{prefix}%"] depends: "conf-pkg-config" depexts: [ ["linux-headers"] {os-distribution = "alpine"} @@ -26,10 +29,10 @@ depexts: [ ["libseccomp-dev"] {os-distribution = "ubuntu"} ] conflicts: [ - "solo5-bindings-genode" "solo5-bindings-hvt" - "solo5-bindings-muen" "solo5-bindings-virtio" + "solo5-bindings-muen" + "solo5-bindings-genode" ] available: [ (arch = "x86_64" | arch = "arm64") & os = "linux" diff --git a/solo5-bindings-spt.pc.in b/solo5-bindings-spt.pc.in index 7cf5bea5..6b12c4ef 100644 --- a/solo5-bindings-spt.pc.in +++ b/solo5-bindings-spt.pc.in @@ -2,10 +2,10 @@ prefix=${pcfiledir}/../.. exec_prefix=${prefix} includedir=${prefix}/include/solo5-bindings-spt libdir=${exec_prefix}/lib/solo5-bindings-spt -ld=!LD! -ldflags=!LDFLAGS! -T ${libdir}/solo5_spt.lds ${libdir}/solo5_spt.o +ld=!PC_LD! +ldflags=!PC_LDFLAGS! -T ${libdir}/solo5_spt.lds ${libdir}/solo5_spt.o Name: solo5-bindings-spt Version: 0.4.0 Description: Solo5 sandboxed execution environment (spt target) -Cflags: !CFLAGS! -isystem ${includedir}/crt -I${includedir}/solo5 +Cflags: !PC_CFLAGS! -isystem ${includedir}/crt -I${includedir}/solo5 diff --git a/solo5-bindings-virtio.opam b/solo5-bindings-virtio.opam index 447f9da3..377b3ac5 100644 --- a/solo5-bindings-virtio.opam +++ b/solo5-bindings-virtio.opam @@ -9,15 +9,18 @@ homepage: "https://github.com/solo5/solo5" bug-reports: "https://github.com/solo5/solo5/issues" license: "ISC" dev-repo: "git+https://github.com/solo5/solo5.git" -build: [make "virtio"] -install: [make "opam-virtio-install" "PREFIX=%{prefix}%"] -remove: [make "opam-virtio-uninstall" "PREFIX=%{prefix}%"] +build: [ + ["./configure.sh"] + [make "V=1" "CONFIG_HVT=" "CONFIG_SPT=" "CONFIG_MUEN=" "CONFIG_GENODE="] +] +install: [make "V=1" "install-opam-virtio" "PREFIX=%{prefix}%"] +remove: [make "V=1" "uninstall-opam-virtio" "PREFIX=%{prefix}%"] depends: "conf-pkg-config" conflicts: [ - "solo5-bindings-genode" "solo5-bindings-hvt" - "solo5-bindings-muen" "solo5-bindings-spt" + "solo5-bindings-muen" + "solo5-bindings-genode" ] available: [ arch = "x86_64" & diff --git a/solo5-bindings-virtio.pc.in b/solo5-bindings-virtio.pc.in index 5ca753c5..253bf508 100644 --- a/solo5-bindings-virtio.pc.in +++ b/solo5-bindings-virtio.pc.in @@ -2,9 +2,9 @@ prefix=${pcfiledir}/../.. exec_prefix=${prefix} includedir=${prefix}/include/solo5-bindings-virtio libdir=${exec_prefix}/lib/solo5-bindings-virtio -ldflags=!LDFLAGS! -T ${libdir}/solo5_virtio.lds ${libdir}/solo5_virtio.o +ldflags=!PC_LDFLAGS! -T ${libdir}/solo5_virtio.lds ${libdir}/solo5_virtio.o Name: solo5-bindings-virtio Version: 0.4.0 Description: Solo5 sandboxed execution environment (virtio target) -Cflags: !CFLAGS! -isystem ${includedir}/crt -I${includedir}/solo5 +Cflags: !PC_CFLAGS! -isystem ${includedir}/crt -I${includedir}/solo5 diff --git a/tenders/hvt/GNUmakefile b/tenders/hvt/GNUmakefile index 7c6da311..53037b71 100644 --- a/tenders/hvt/GNUmakefile +++ b/tenders/hvt/GNUmakefile @@ -16,16 +16,64 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# The purpose of this Makefile is to ensure that a solo5-hvt tender with ALL -# modules configured compiles correctly. +ifndef TOPDIR +$(error TOPDIR must be set, run $(MAKE) from the top of the source tree or set it manually) +endif +include $(TOPDIR)/Makefile.common -.PHONY: all clean -all: solo5-hvt +.PHONY: all +all: +all_TARGETS := -Makefile.solo5-hvt: solo5-hvt-configure - ./solo5-hvt-configure . blk net gdb dumpcore +.SUFFIXES: +$(V).SILENT: --include Makefile.solo5-hvt +ifdef CONFIG_HVT -clean: solo5-hvt-clean - $(RM) Makefile.solo5-hvt +hvt_SRCS := hvt_core.c hvt_elf.c hvt_main.c hvt_cpu_$(CONFIG_ARCH).c +hvt_MODULES ?= blk net + +ifeq ($(CONFIG_HOST), Linux) + hvt_SRCS += hvt_kvm.c hvt_kvm_$(CONFIG_ARCH).c + hvt_debug_MODULES ?= gdb dumpcore + all_TARGETS += solo5-hvt solo5-hvt-debug +else ifeq ($(CONFIG_HOST), FreeBSD) + hvt_SRCS += hvt_freebsd.c hvt_freebsd_$(CONFIG_ARCH).c + hvt_debug_MODULES ?= gdb dumpcore + all_TARGETS += solo5-hvt solo5-hvt-debug +else ifeq ($(CONFIG_HOST), OpenBSD) + hvt_SRCS += hvt_openbsd.c hvt_openbsd_$(CONFIG_ARCH).c + all_TARGETS += solo5-hvt +endif + +hvt_SRCS += $(patsubst %,hvt_module_%.c,$(hvt_MODULES)) +hvt_debug_SRCS += $(patsubst %,hvt_module_%.c,$(hvt_debug_MODULES)) +hvt_OBJS := $(patsubst %.c,%.o,$(hvt_SRCS)) +hvt_debug_OBJS := $(patsubst %.c,%.o,$(hvt_debug_SRCS)) + +%.o: %.c %.d + $(HOSTCOMPILE.c) + +%.d: ; +.PRECIOUS: %.d + +solo5-hvt: $(hvt_OBJS) + $(HOSTLINK) + +solo5-hvt-debug: $(hvt_OBJS) $(hvt_debug_OBJS) + $(HOSTLINK) + +endif # CONFIG_HVT + +all: $(all_TARGETS) + +all_OBJS := $(hvt_OBJS) $(hvt_debug_OBJS) +all_DEPS := $(patsubst %.o,%.d,$(all_OBJS)) + +.PHONY: clean + +clean: + @echo "CLEAN tenders/hvt" + $(RM) $(all_TARGETS) $(all_OBJS) $(all_DEPS) + +include $(wildcard $(all_DEPS)) diff --git a/tenders/hvt/hvt.h b/tenders/hvt/hvt.h index 7311cc4d..cdb47a30 100644 --- a/tenders/hvt/hvt.h +++ b/tenders/hvt/hvt.h @@ -160,23 +160,26 @@ extern hvt_vmexit_fn_t hvt_core_vmexits[]; * Module definition. (name) and (setup) are required, all other functions are * optional. */ -struct hvt_module { - const char *name; +struct hvt_module_ops { int (*setup)(struct hvt *hvt); int (*handle_cmdarg)(char *cmdarg); char *(*usage)(void); }; -/* - * Array of compiled-in modules. NULL terminated. - */ -extern struct hvt_module *hvt_core_modules[]; +struct hvt_module { + const char *name; + struct hvt_module_ops ops; +}; + -extern struct hvt_module hvt_module_core; -extern struct hvt_module hvt_module_blk; -extern struct hvt_module hvt_module_net; -extern struct hvt_module hvt_module_gdb; -extern struct hvt_module hvt_module_dumpcore; +#define BEGIN_REGISTER_MODULE(module_name) \ + static struct hvt_module __module_ ##module_name \ + __attribute((section("modules"))) \ + __attribute((used)) = { \ + .name = #module_name, \ + .ops = + +#define END_REGISTER_MODULE }; /* * GDB specific functions to be implemented on all backends for all diff --git a/tenders/hvt/hvt_core.c b/tenders/hvt/hvt_core.c index c39afdaf..beee173b 100644 --- a/tenders/hvt/hvt_core.c +++ b/tenders/hvt/hvt_core.c @@ -41,26 +41,6 @@ #include "hvt.h" -struct hvt_module hvt_module_core; - -struct hvt_module *hvt_core_modules[] = { - &hvt_module_core, -#ifdef HVT_MODULE_DUMPCORE - &hvt_module_dumpcore, -#endif -#ifdef HVT_MODULE_BLK - &hvt_module_blk, -#endif -#ifdef HVT_MODULE_NET - &hvt_module_net, -#endif -#ifdef HVT_MODULE_GDB - &hvt_module_gdb, -#endif - NULL, -}; -#define NUM_MODULES ((sizeof hvt_core_modules / sizeof (struct hvt_module *)) - 1) - hvt_hypercall_fn_t hvt_core_hypercalls[HVT_HYPERCALL_MAX] = { 0 }; int hvt_core_register_hypercall(int nr, hvt_hypercall_fn_t fn) @@ -114,6 +94,7 @@ int hvt_core_hypercall_halt(struct hvt *hvt, hvt_gpa_t gpa) return t->exit_status; } +#define NUM_MODULES 8 hvt_vmexit_fn_t hvt_core_vmexits[NUM_MODULES + 1] = { 0 }; static int nvmexits = 0; @@ -195,7 +176,7 @@ static int setup(struct hvt *hvt) return 0; } -struct hvt_module hvt_module_core = { - .name = "core", +BEGIN_REGISTER_MODULE(core) { .setup = setup -}; +} +END_REGISTER_MODULE diff --git a/tenders/hvt/hvt_freebsd.c b/tenders/hvt/hvt_freebsd.c index b8b399db..6c6a828e 100644 --- a/tenders/hvt/hvt_freebsd.c +++ b/tenders/hvt/hvt_freebsd.c @@ -135,21 +135,8 @@ struct hvt *hvt_init(size_t mem_size) #if HVT_DROP_PRIVILEGES void hvt_drop_privileges() { - struct passwd *pw = getpwnam(VMM_USER); - if (pw == NULL) - err(1, "can't get %s user", VMM_USER); - uid_t uid = pw->pw_uid; - gid_t gid = pw->pw_gid; - - if (chroot(VMM_CHROOT) == -1) - err(1, "chroot(%s)", VMM_CHROOT); - - if (chdir("/") == -1) - err(1, "chdir(/)"); - - if (setgroups(1, &gid) || - setresgid(gid, gid, gid) || - setresuid(uid, uid, uid)) - err(1, "unable to revoke privs"); + /* + * This function intentionally left blank for now (see #282). + */ } #endif diff --git a/tenders/hvt/hvt_main.c b/tenders/hvt/hvt_main.c index 2fae612e..fd392481 100644 --- a/tenders/hvt/hvt_main.c +++ b/tenders/hvt/hvt_main.c @@ -54,15 +54,18 @@ static void setup_cmdline(char *cmdline, int argc, char **argv) } } +extern struct hvt_module __start_modules; +extern struct hvt_module __stop_modules; + static void setup_modules(struct hvt *hvt) { - for (struct hvt_module **m = hvt_core_modules; *m; m++) { - assert((*m)->setup); - if ((*m)->setup(hvt)) { - warnx("Module `%s' setup failed", (*m)->name); - if ((*m)->usage) { + for (struct hvt_module *m = &__start_modules; m < &__stop_modules; m++) { + assert(m->ops.setup); + if (m->ops.setup(hvt)) { + warnx("Module `%s' setup failed", m->name); + if (m->ops.usage) { warnx("Please check you have correctly specified:\n %s", - (*m)->usage()); + m->ops.usage()); } exit(1); } @@ -71,9 +74,9 @@ static void setup_modules(struct hvt *hvt) static int handle_cmdarg(char *cmdarg) { - for (struct hvt_module **m = hvt_core_modules; *m; m++) { - if ((*m)->handle_cmdarg) { - if ((*m)->handle_cmdarg(cmdarg) == 0) { + for (struct hvt_module *m = &__start_modules; m < &__stop_modules; m++) { + if (m->ops.handle_cmdarg) { + if (m->ops.handle_cmdarg(cmdarg) == 0) { return 0; } } @@ -107,16 +110,16 @@ static void usage(const char *prog) fprintf(stderr, " [ --mem=512 ] (guest memory in MB)\n"); fprintf(stderr, " --help (display this help)\n"); fprintf(stderr, "Compiled-in modules: "); - for (struct hvt_module **m = hvt_core_modules; *m; m++) { - assert((*m)->name); - fprintf(stderr, "%s ", (*m)->name); + for (struct hvt_module *m = &__start_modules; m < &__stop_modules; m++) { + assert(m->name); + fprintf(stderr, "%s ", m->name); } fprintf(stderr, "\n"); fprintf(stderr, "Compiled-in module options:\n"); int nm = 0; - for (struct hvt_module **m = hvt_core_modules; *m; m++) { - if ((*m)->usage) { - fprintf(stderr, " %s\n", (*m)->usage()); + for (struct hvt_module *m = &__start_modules; m < &__stop_modules; m++) { + if (m->ops.usage) { + fprintf(stderr, " %s\n", m->ops.usage()); nm++; } } diff --git a/tenders/hvt/hvt_module_blk.c b/tenders/hvt/hvt_module_blk.c index 4cd568c5..6a5d741f 100644 --- a/tenders/hvt/hvt_module_blk.c +++ b/tenders/hvt/hvt_module_blk.c @@ -109,7 +109,7 @@ static int handle_cmdarg(char *cmdarg) static int setup(struct hvt *hvt) { if (diskfile == NULL) - return -1; + return 0; /* Not present */ /* set up virtual disk */ diskfd = open(diskfile, O_RDWR); @@ -135,9 +135,9 @@ static char *usage(void) return "--disk=IMAGE (file exposed to the unikernel as a raw block device)"; } -struct hvt_module hvt_module_blk = { - .name = "blk", +BEGIN_REGISTER_MODULE(blk) { .setup = setup, .handle_cmdarg = handle_cmdarg, .usage = usage -}; +} +END_REGISTER_MODULE diff --git a/tenders/hvt/hvt_module_dumpcore.c b/tenders/hvt/hvt_module_dumpcore.c index 4db58a8e..721a54fe 100644 --- a/tenders/hvt/hvt_module_dumpcore.c +++ b/tenders/hvt/hvt_module_dumpcore.c @@ -254,9 +254,9 @@ static int setup(struct hvt *hvt) return 0; } -struct hvt_module hvt_module_dumpcore = { - .name = "dumpcore", +BEGIN_REGISTER_MODULE(dumpcore) { .setup = setup, .handle_cmdarg = handle_cmdarg, .usage = usage -}; +} +END_REGISTER_MODULE diff --git a/tenders/hvt/hvt_module_gdb.c b/tenders/hvt/hvt_module_gdb.c index a95928ea..eebc2b16 100644 --- a/tenders/hvt/hvt_module_gdb.c +++ b/tenders/hvt/hvt_module_gdb.c @@ -668,9 +668,9 @@ static char *usage(void) " [ --gdb-port=1234 ] (port to use) "; } -struct hvt_module hvt_module_gdb = { - .name = "gdb", +BEGIN_REGISTER_MODULE(gdb) { .setup = setup, .handle_cmdarg = handle_cmdarg, .usage = usage -}; +} +END_REGISTER_MODULE diff --git a/tenders/hvt/hvt_module_net.c b/tenders/hvt/hvt_module_net.c index 61713908..525d085a 100644 --- a/tenders/hvt/hvt_module_net.c +++ b/tenders/hvt/hvt_module_net.c @@ -253,7 +253,7 @@ static int handle_cmdarg(char *cmdarg) static int setup(struct hvt *hvt) { if (netiface == NULL) - return -1; + return 0; /* Not present */ /* attach to requested tap interface */ netfd = tap_attach(netiface); @@ -297,9 +297,9 @@ static char *usage(void) " [ --net-mac=HWADDR ] (guest MAC address)"; } -struct hvt_module hvt_module_net = { - .name = "net", +BEGIN_REGISTER_MODULE(net) { .setup = setup, .handle_cmdarg = handle_cmdarg, .usage = usage -}; +} +END_REGISTER_MODULE diff --git a/tenders/hvt/solo5-hvt-configure b/tenders/hvt/solo5-hvt-configure index 4b2c7e20..b97934a2 100755 --- a/tenders/hvt/solo5-hvt-configure +++ b/tenders/hvt/solo5-hvt-configure @@ -17,149 +17,33 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -die () -{ - echo "solo5-hvt-configure: error: $@" 1>&2 - exit 1 -} - -if [ "$#" -lt 1 ]; then - cat <&2 +NOTICE: MirageOS / your build scripts have invoked solo5-hvt-configure. +NOTICE: This command no longer does anything, and a solo5-hvt tender is +NOTICE: no longer built at unikernel build time. +NOTICE: +NOTICE: To run your unikernel, use the solo5-hvt binary installed by OPAM +NOTICE: from the solo5-bindings-hvt package. EOM - exit 1 -fi - -SOLO5_HVT_CC=${SOLO5_HVT_CC:-cc} -SOLO5_HVT_SRC=$(readlink -f $1) -if [ ! -d ${SOLO5_HVT_SRC} -o ! -f ${SOLO5_HVT_SRC}/hvt_core.c ]; then - die "Not a solo5-hvt source directory: ${SOLO5_HVT_SRC}" -fi -shift - -add_cflags () -{ - SOLO5_HVT_CFLAGS="${SOLO5_HVT_CFLAGS} $@" -} - -add_obj () -{ - for i in "$@"; do - SOLO5_HVT_OBJS="${SOLO5_HVT_OBJS} _build-solo5-hvt/${i}" - done -} - -add_header () -{ - for i in "$@"; do - # XXX: This is a hack for Solo5 in-tree builds to avoid keeping two - # copies or a symlink to hvt_abi.h around. - if [ ! -f "${SOLO5_HVT_SRC}/${i}" -a -f \ - "${SOLO5_HVT_SRC}/../../include/solo5/${i}" ]; then - SOLO5_HVT_HEADERS="${SOLO5_HVT_HEADERS} ${SOLO5_HVT_SRC}/../../include/solo5/${i}" - add_cflags "-I${SOLO5_HVT_SRC}/../../include/solo5" - else - SOLO5_HVT_HEADERS="${SOLO5_HVT_HEADERS} ${SOLO5_HVT_SRC}/${i}" - fi - done -} - -add_module () -{ - if [ ! -f ${SOLO5_HVT_SRC}/hvt_module_$1.c ]; then - die "Invalid module: $1" - fi - if [ $1 = 'dumpcore' ]; then - add_cflags "-DHVT_DROP_PRIVILEGES=0" - fi - enableit="-DHVT_MODULE_$(echo $1 | tr '[a-z]' '[A-Z]')" - add_obj "hvt_module_$1.o" - add_cflags "${enableit}" -} - -SOLO5_HVT_CFLAGS= -SOLO5_HVT_LDFLAGS= -SOLO5_HVT_LDLIBS= -SOLO5_HVT_HEADERS= -SOLO5_HVT_OBJS= -add_obj hvt_core.o hvt_elf.o hvt_main.o -add_header hvt.h hvt_abi.h cc.h - -for module in "$@"; do - [ -z "${module}" ] && continue - add_module ${module} -done - -[ -n "${SOLO5_HVT_STATIC}" ] && SOLO5_HVT_LDFLAGS="-static" - -TARGET=$(${SOLO5_HVT_CC} -dumpmachine) -[ $? -ne 0 ] && - die "Error running '${SOLO5_HVT_CC} -dumpmachine', is your compiler working?" -case ${TARGET} in - x86_64-*linux*) - add_obj hvt_kvm.o hvt_kvm_x86_64.o hvt_cpu_x86_64.o - add_header hvt_kvm.h hvt_cpu_x86_64.h - ;; - x86_64-*freebsd1[123]*) - add_obj hvt_freebsd.o hvt_freebsd_x86_64.o hvt_cpu_x86_64.o - add_header hvt_freebsd.h hvt_cpu_x86_64.h - ;; - amd64-*-openbsd6.[4-9]) - add_obj hvt_openbsd.o hvt_openbsd_x86_64.o hvt_cpu_x86_64.o - add_header hvt_openbsd.h hvt_cpu_x86_64.h - ;; - aarch64-*linux*) - add_obj hvt_kvm.o hvt_kvm_aarch64.o hvt_cpu_aarch64.o - add_header hvt_kvm.h hvt_cpu_aarch64.h - ;; - *) - die "Unsupported compiler target: ${TARGET}" - ;; -esac cat < Makefile.solo5-hvt -# Generated by 'solo5-hvt-configure $@' -# Using compiler '${SOLO5_HVT_CC}', target '${TARGET}' +# Dummy Makefile.solo5-hvt generated by solo5-hvt-configure for backwards +# compatibility with existing MirageOS releases. .BEGIN: ; @echo -e Warning: \$(MAKEFILE) requires GNU make.\\\\nWarning: Attempting to build with \"gmake -f \$(MAKEFILE) \$(.TARGETS)\" for you now. && gmake -f \$(MAKEFILE) \$(.TARGETS) -.PHONY: all -all: solo5-hvt - -SOLO5_HVT_CC=${SOLO5_HVT_CC} -SOLO5_HVT_CFLAGS=-Wall -Werror -std=c99 -O2 -g ${SOLO5_HVT_CFLAGS} -SOLO5_HVT_LDFLAGS=${SOLO5_HVT_LDFLAGS} -SOLO5_HVT_LDLIBS=${SOLO5_HVT_LDLIBS} - -SOLO5_HVT_OBJS=${SOLO5_HVT_OBJS} -SOLO5_HVT_HEADERS=${SOLO5_HVT_HEADERS} - -\$(SOLO5_HVT_OBJS): \$(SOLO5_HVT_HEADERS) - -_build-solo5-hvt: - mkdir -p _build-solo5-hvt - -_build-solo5-hvt/%.o: ${SOLO5_HVT_SRC}/%.c \$(MAKEFILE_LIST) | _build-solo5-hvt - \$(SOLO5_HVT_CC) \$(SOLO5_HVT_CFLAGS) -c \$< -o \$@ - -solo5-hvt: \$(SOLO5_HVT_OBJS) \$(MAKEFILE_LIST) - \$(SOLO5_HVT_CC) \$(SOLO5_HVT_LDFLAGS) -o \$@ \$(SOLO5_HVT_OBJS) \$(SOLO5_HVT_LDLIBS) +.PHONY: solo5-hvt -.PHONY: solo5-hvt-clean -solo5-hvt-clean: - rm -rf _build-solo5-hvt - rm -f solo5-hvt +solo5-hvt: ; EOF diff --git a/tenders/spt/GNUmakefile b/tenders/spt/GNUmakefile index 8ed6c322..252c5570 100644 --- a/tenders/spt/GNUmakefile +++ b/tenders/spt/GNUmakefile @@ -16,26 +16,60 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -TOP?=../.. -include $(TOP)/Makeconf +ifndef TOPDIR +$(error TOPDIR must be set, run $(MAKE) from the top of the source tree or set it manually) +endif +include $(TOPDIR)/Makefile.common -.PHONY: all clean -all: solo5-spt +.PHONY: all +all: +all_TARGETS := -CFLAGS=-Wall -Werror -std=c99 -O2 -g -I../../include/solo5 -LDFLAGS=-Wl,-z -Wl,noexecstack $(SPT_EXTRA_LDFLAGS) -LDLIBS=-lseccomp +.SUFFIXES: +$(V).SILENT: -OBJS=spt_main.o spt_core.o spt_elf.o spt_launch_$(TARGET_ARCH).o \ - spt_module_net.o spt_module_block.o +ifdef CONFIG_SPT -# This needs to be re-defined manually, as GNU Make has the undocumented -# "feature" of using $(TARGET_ARCH) in the default implicit rule for %.c. -%.o: %.c - $(CC) -c $(CFLAGS) -o $@ $< +HOSTLDFLAGS += -Wl,-z -Wl,noexecstack -solo5-spt: $(OBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) +ifdef CONFIG_SPT_NO_PIE + +HOSTLDFLAGS += -Wl,-Ttext-segment=0x40000000 + +endif + +HOSTLDLIBS += -lseccomp + +spt_SRCS := spt_main.c spt_core.c spt_elf.c spt_launch_$(CONFIG_ARCH).S \ + spt_module_net.c spt_module_block.c + +spt_OBJS := $(patsubst %.c,%.o,$(patsubst %.S,%.o,$(spt_SRCS))) + +%.o: %.c %.d + $(HOSTCOMPILE.c) + +%.o: %.S %.d + $(HOSTCOMPILE.S) + +%.d: ; +.PRECIOUS: %.d + +solo5-spt: $(spt_OBJS) + $(HOSTLINK) + +all_TARGETS += solo5-spt + +endif # CONFIG_SPT + +all: $(all_TARGETS) + +all_OBJS := $(spt_OBJS) +all_DEPS := $(patsubst %.o,%.d,$(all_OBJS)) + +.PHONY: clean clean: - $(RM) $(OBJS) solo5-spt + @echo "CLEAN tenders/spt" + $(RM) $(all_TARGETS) $(all_OBJS) $(all_DEPS) + +include $(wildcard $(all_DEPS)) diff --git a/tests/GNUmakefile b/tests/GNUmakefile index 7e5a1510..8bca6db0 100644 --- a/tests/GNUmakefile +++ b/tests/GNUmakefile @@ -16,47 +16,21 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -TESTDIRS=test_hello test_globals test_ping_serve test_blk \ - test_exception test_abort test_fpu test_time test_quiet \ - test_zeropage test_notls test_ssp test_seccomp +ifndef TOPDIR +$(error TOPDIR must be set, run $(MAKE) from the top of the source tree or set it manually) +endif -HVT_TESTS=$(subst test, _test_hvt, $(TESTDIRS)) -SPT_TESTS=$(subst test, _test_spt, $(TESTDIRS)) -VIRTIO_TESTS=$(subst test, _test_virtio, $(TESTDIRS)) -MUEN_TESTS=$(subst test, _test_muen, $(TESTDIRS)) -GENODE_TESTS=$(subst test, _test_genode, $(TESTDIRS)) -CLEANS=$(subst test, _clean, $(TESTDIRS)) +.SUFFIXES: +$(V).SILENT: -all: $(HVT_TESTS) $(SPT_TESTS) $(VIRTIO_TESTS) $(MUEN_TESTS) +TESTDIRS := $(wildcard test_*) -hvt: $(HVT_TESTS) +TOPTARGETS := all clean -spt: $(SPT_TESTS) +.PHONY: $(TOPTARGETS) $(TESTDIRS) -virtio: $(VIRTIO_TESTS) +$(TOPTARGETS): $(TESTDIRS) -muen: $(MUEN_TESTS) - -genode: $(GENODE_TESTS) - -clean: $(CLEANS) - -.PHONY: force_it - -_test_hvt%: force_it - $(MAKE) -C $(subst _test_hvt, test, $@) hvt - -_test_spt%: force_it - $(MAKE) -C $(subst _test_spt, test, $@) spt - -_test_virtio%: force_it - $(MAKE) -C $(subst _test_virtio, test, $@) virtio - -_test_muen%: force_it - $(MAKE) -C $(subst _test_muen, test, $@) muen - -_test_genode%: force_it - $(MAKE) -C $(subst _test_genode, test, $@) genode - -_clean_%: force_it - $(MAKE) -C $(subst _clean, test, $@) clean +$(TESTDIRS): + @echo "MAKE $@" + $(MAKE) -C $@ $(MAKECMDGOALS) $(SUBOVERRIDE) diff --git a/tests/Makefile.tests b/tests/Makefile.tests index 63747967..e57f321f 100644 --- a/tests/Makefile.tests +++ b/tests/Makefile.tests @@ -16,77 +16,83 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -TOP?=../.. -include $(TOP)/Makefile.common - -.PHONY: hvt -hvt: $(HVT_TARGETS) - -.PHONY: spt -spt: $(SPT_TARGETS) - -.PHONY: virtio -virtio: $(VIRTIO_TARGETS) - -.PHONY: muen -muen: $(MUEN_TARGETS) - -.PHONY: genode -genode: $(GENODE_TARGETS) - -BINDINGS_DIR=$(TOP)/bindings -SOLO5_HVT_SRC=$(TOP)/tenders/hvt - -CFLAGS+=-I$(BINDINGS_DIR) - -%.o: %.c $(HEADERS) - $(CC) $(CFLAGS) -c $< -o $@ -.PRECIOUS: %.o - -ifeq ($(BUILD_HVT), yes) -Makefile.solo5-hvt: $(SOLO5_HVT_SRC)/solo5-hvt-configure - $(SOLO5_HVT_SRC)/solo5-hvt-configure $(SOLO5_HVT_SRC) $(HVT_MODULES) - --include Makefile.solo5-hvt - -%.hvt: %.o $(BINDINGS_DIR)/hvt/solo5_hvt.lds $(BINDINGS_DIR)/hvt/solo5_hvt.o - $(LD) -T $(BINDINGS_DIR)/hvt/solo5_hvt.lds $(LDFLAGS) -o $@ $(BINDINGS_DIR)/hvt/solo5_hvt.o $< $(LDLIBS) - -$(BINDINGS_DIR)/hvt/solo5_hvt.o: - $(MAKE) -C $(BINDINGS_DIR) hvt +.SUFFIXES: + +LDS.hvt := $(TOPDIR)/bindings/hvt/solo5_hvt.lds +BINDINGS.hvt := $(TOPDIR)/bindings/hvt/solo5_hvt.o +LDS.spt := $(TOPDIR)/bindings/spt/solo5_spt.lds +BINDINGS.spt := $(TOPDIR)/bindings/spt/solo5_spt.o +LDS.virtio := $(TOPDIR)/bindings/virtio/solo5_virtio.lds +BINDINGS.virtio := $(TOPDIR)/bindings/virtio/solo5_virtio.o +LDS.muen := $(TOPDIR)/bindings/muen/solo5_muen.lds +BINDINGS.muen := $(TOPDIR)/bindings/muen/solo5_muen.o +LDS.genode := $(TOPDIR)/bindings/genode/genode_dyn.ld +BINDINGS.genode := $(TOPDIR)/bindings/genode/solo5.lib.so + +# As a test is currently a single source file, we don't try to do any +# dependency auto-generation here, and just hard-code all expected dependencies +# as pre-requisites below. + +%.o: %.c ../../include/solo5/solo5.h + @echo "CC $<" + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + +%.hvt: %.o $(LDS.hvt) $(BINDINGS.hvt) + @echo "LD $@" + $(LD) $(LDFLAGS) -T $(LDS.hvt) $(BINDINGS.hvt) $< -o $@ + +%.spt: %.o $(LDS.spt) $(BINDINGS.spt) + @echo "LD $@" + $(LD) $(LDFLAGS) -T $(LDS.spt) $(BINDINGS.spt) $< -o $@ + +%.virtio: %.o $(LDS.virtio) $(BINDINGS.virtio) + @echo "LD $@" + $(LD) $(LDFLAGS) -T $(LDS.virtio) $(BINDINGS.virtio) $< -o $@ + +%.muen: %.o $(LDS.muen) $(BINDINGS.muen) + @echo "LD $@" + $(LD) $(LDFLAGS) -T $(LDS.muen) $(BINDINGS.muen) $< -o $@ + +%.genode.o: %.c ../../include/solo5/solo5.h + @echo "GENODECC $<" + $(CC) $(GENODE_APP_CFLAGS) $(CPPFLAGS) -c $< -o $@ + +%.genode: %.genode.o $(LDS.genode) $(BINDINGS.genode) + @echo "LD $@" + $(LD) $(GENODE_APP_LDFLAGS) -T $(LDS.genode) $< $(BINDINGS.genode) -o $@ + +test_TARGETS := + +ifdef CONFIG_HVT + test_TARGETS += $(test_NAME).hvt endif -ifeq ($(BUILD_SPT), yes) - -%.spt: %.o $(BINDINGS_DIR)/spt/solo5_spt.lds $(BINDINGS_DIR)/spt/solo5_spt.o - $(LD) -T $(BINDINGS_DIR)/spt/solo5_spt.lds $(LDFLAGS) -o $@ $(BINDINGS_DIR)/spt/solo5_spt.o $< $(LDLIBS) +ifdef CONFIG_SPT + test_TARGETS += $(test_NAME).spt +endif -$(BINDINGS_DIR)/spt/solo5_spt.o: - $(MAKE) -C $(BINDINGS_DIR) spt +ifdef CONFIG_VIRTIO + test_TARGETS += $(test_NAME).virtio endif -ifeq ($(BUILD_MUEN), yes) -%.muen: %.o $(BINDINGS_DIR)/muen/solo5_muen.lds $(BINDINGS_DIR)/muen/solo5_muen.o - $(LD) -T $(BINDINGS_DIR)/muen/solo5_muen.lds $(LDFLAGS) -o $@ $(BINDINGS_DIR)/muen/solo5_muen.o $< $(LDLIBS) +ifdef CONFIG_MUEN + test_TARGETS += $(test_NAME).muen +endif -$(BINDINGS_DIR)/muen/solo5_muen.o: - $(MAKE) -C $(BINDINGS_DIR) muen +ifdef CONFIG_GENODE + test_TARGETS += $(test_NAME).genode endif -ifeq ($(BUILD_GENODE), yes) -%.genode: %.o $(BINDINGS_DIR)/genode/genode_dyn.ld $(BINDINGS_DIR)/genode/solo5.lib.so - $(LD) -T $(BINDINGS_DIR)/genode/genode_dyn.ld $(GENODE_LDFLAGS) -o $@ $(BINDINGS_DIR)/genode/solo5.lib.so $< $(LDLIBS) +.PRECIOUS: $(test_NAME).o $(test_NAME).genode.o -$(BINDINGS_DIR)/genode/solo5.lib.so: - $(MAKE) -C $(BINDINGS_DIR) genode -endif +.PHONY: all + +all: $(test_TARGETS) -%.virtio: %.o $(BINDINGS_DIR)/virtio/solo5_virtio.lds $(BINDINGS_DIR)/virtio/solo5_virtio.o - $(LD) -T $(BINDINGS_DIR)/virtio/solo5_virtio.lds $(LDFLAGS) -o $@ $(BINDINGS_DIR)/virtio/solo5_virtio.o $< $(LDLIBS) +.PHONY: clean -$(BINDINGS_DIR)/virtio/solo5_virtio.o: - $(MAKE) -C $(BINDINGS_DIR) virtio +clean: + @echo "CLEAN $(test_NAME)" + $(RM) $(test_NAME).o $(test_NAME).genode.o $(test_TARGETS) -.PHONY: clean solo5-hvt-clean -clean: solo5-hvt-clean - $(RM) *.o $(HVT_TARGETS) Makefile.solo5-hvt $(SPT_TARGETS) $(VIRTIO_TARGETS) $(MUEN_TARGETS) $(GENODE_TARGETS) +$(V).SILENT: diff --git a/tests/test_abort/GNUmakefile b/tests/test_abort/GNUmakefile index 1414bf7b..6dfaead6 100644 --- a/tests/test_abort/GNUmakefile +++ b/tests/test_abort/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_abort.hvt solo5-hvt -SPT_TARGETS=test_abort.spt -VIRTIO_TARGETS=test_abort.virtio -MUEN_TARGETS=test_abort.muen -GENODE_TARGETS=test_abort.genode -HVT_MODULES=dumpcore +include $(TOPDIR)/Makefile.common + +test_NAME := test_abort include ../Makefile.tests diff --git a/tests/test_blk/GNUmakefile b/tests/test_blk/GNUmakefile index 139622b7..277146ab 100644 --- a/tests/test_blk/GNUmakefile +++ b/tests/test_blk/GNUmakefile @@ -16,10 +16,10 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_blk.hvt solo5-hvt -SPT_TARGETS=test_blk.spt -VIRTIO_TARGETS=test_blk.virtio -GENODE_TARGETS=test_blk.genode -HVT_MODULES=blk +include $(TOPDIR)/Makefile.common + +test_NAME := test_blk + +CONFIG_MUEN := include ../Makefile.tests diff --git a/tests/test_exception/GNUmakefile b/tests/test_exception/GNUmakefile index 12c04d72..60dbb49b 100644 --- a/tests/test_exception/GNUmakefile +++ b/tests/test_exception/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_exception.hvt solo5-hvt -SPT_TARGETS=test_exception.spt -VIRTIO_TARGETS=test_exception.virtio -MUEN_TARGETS=test_exception.muen -GENODE_TARGETS=test_exception.genode -HVT_MODULES= +include $(TOPDIR)/Makefile.common + +test_NAME := test_exception include ../Makefile.tests diff --git a/tests/test_fpu/GNUmakefile b/tests/test_fpu/GNUmakefile index 3d4b1f55..3185b911 100644 --- a/tests/test_fpu/GNUmakefile +++ b/tests/test_fpu/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_fpu.hvt solo5-hvt -SPT_TARGETS=test_fpu.spt -VIRTIO_TARGETS=test_fpu.virtio -MUEN_TARGETS=test_fpu.muen -GENODE_TARGETS=test_fpu.genode -HVT_MODULES= +include $(TOPDIR)/Makefile.common + +test_NAME := test_fpu include ../Makefile.tests diff --git a/tests/test_globals/GNUmakefile b/tests/test_globals/GNUmakefile index 8968b4d2..cef38351 100644 --- a/tests/test_globals/GNUmakefile +++ b/tests/test_globals/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_globals.hvt solo5-hvt -SPT_TARGETS=test_globals.spt -VIRTIO_TARGETS=test_globals.virtio -MUEN_TARGETS=test_globals.muen -GENODE_TARGETS=test_globals.genode -HVT_MODULES= +include $(TOPDIR)/Makefile.common + +test_NAME := test_globals include ../Makefile.tests diff --git a/tests/test_hello/GNUmakefile b/tests/test_hello/GNUmakefile index 9fbea382..b6108209 100644 --- a/tests/test_hello/GNUmakefile +++ b/tests/test_hello/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_hello.hvt solo5-hvt -SPT_TARGETS=test_hello.spt -VIRTIO_TARGETS=test_hello.virtio -MUEN_TARGETS=test_hello.muen -GENODE_TARGETS=test_hello.genode -HVT_MODULES=gdb +include $(TOPDIR)/Makefile.common + +test_NAME := test_hello include ../Makefile.tests diff --git a/tests/test_notls/GNUmakefile b/tests/test_notls/GNUmakefile index 5299b501..7a322ba1 100644 --- a/tests/test_notls/GNUmakefile +++ b/tests/test_notls/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_notls.hvt solo5-hvt -SPT_TARGETS=test_notls.spt -VIRTIO_TARGETS=test_notls.virtio -MUEN_TARGETS=test_notls.muen -GENODE_TARGETS=test_notls.genode -HVT_MODULES= +include $(TOPDIR)/Makefile.common + +test_NAME := test_notls include ../Makefile.tests diff --git a/tests/test_ping_serve/GNUmakefile b/tests/test_ping_serve/GNUmakefile index b113a931..46fb02a1 100644 --- a/tests/test_ping_serve/GNUmakefile +++ b/tests/test_ping_serve/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_ping_serve.hvt solo5-hvt -SPT_TARGETS=test_ping_serve.spt -VIRTIO_TARGETS=test_ping_serve.virtio -MUEN_TARGETS=test_ping_serve.muen -GENODE_TARGETS=test_ping_serve.genode -HVT_MODULES=net +include $(TOPDIR)/Makefile.common + +test_NAME := test_ping_serve include ../Makefile.tests diff --git a/tests/test_quiet/GNUmakefile b/tests/test_quiet/GNUmakefile index 7e4dffe1..1451cb37 100644 --- a/tests/test_quiet/GNUmakefile +++ b/tests/test_quiet/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_quiet.hvt solo5-hvt -SPT_TARGETS=test_quiet.spt -VIRTIO_TARGETS=test_quiet.virtio -MUEN_TARGETS=test_quiet.muen -GENODE_TARGETS=test_quiet.genode -HVT_MODULES= +include $(TOPDIR)/Makefile.common + +test_NAME := test_quiet include ../Makefile.tests diff --git a/tests/test_seccomp/GNUmakefile b/tests/test_seccomp/GNUmakefile index 682541a4..f3322188 100644 --- a/tests/test_seccomp/GNUmakefile +++ b/tests/test_seccomp/GNUmakefile @@ -16,10 +16,13 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS= -SPT_TARGETS=test_seccomp.spt -VIRTIO_TARGETS= -MUEN_TARGETS= -GENODE_TARGETS= +include $(TOPDIR)/Makefile.common + +test_NAME := test_seccomp + +CONFIG_HVT := +CONFIG_VIRTIO := +CONFIG_MUEN := +CONFIG_GENODE := include ../Makefile.tests diff --git a/tests/test_ssp/GNUmakefile b/tests/test_ssp/GNUmakefile index 9ea11f64..ca430ea0 100644 --- a/tests/test_ssp/GNUmakefile +++ b/tests/test_ssp/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_ssp.hvt solo5-hvt -SPT_TARGETS=test_ssp.spt -VIRTIO_TARGETS=test_ssp.virtio -MUEN_TARGETS=test_ssp.muen -GENODE_TARGETS=test_ssp.genode -HVT_MODULES=gdb +include $(TOPDIR)/Makefile.common + +test_NAME := test_ssp include ../Makefile.tests diff --git a/tests/test_time/GNUmakefile b/tests/test_time/GNUmakefile index b9a9f6d5..44dd6060 100644 --- a/tests/test_time/GNUmakefile +++ b/tests/test_time/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_time.hvt solo5-hvt -SPT_TARGETS=test_time.spt -VIRTIO_TARGETS=test_time.virtio -MUEN_TARGETS=test_time.muen -GENODE_TARGETS=test_time.genode -HVT_MODULES= +include $(TOPDIR)/Makefile.common + +test_NAME := test_time include ../Makefile.tests diff --git a/tests/test_zeropage/GNUmakefile b/tests/test_zeropage/GNUmakefile index 604fa150..900b69e5 100644 --- a/tests/test_zeropage/GNUmakefile +++ b/tests/test_zeropage/GNUmakefile @@ -16,11 +16,8 @@ # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -HVT_TARGETS=test_zeropage.hvt solo5-hvt -SPT_TARGETS=test_zeropage.spt -VIRTIO_TARGETS=test_zeropage.virtio -MUEN_TARGETS=test_zeropage.muen -GENODE_TARGETS=test_zeropage.genode -HVT_MODULES= +include $(TOPDIR)/Makefile.common + +test_NAME := test_zeropage include ../Makefile.tests diff --git a/tests/tests.bats b/tests/tests.bats index d1e4ba41..9f7c4246 100644 --- a/tests/tests.bats +++ b/tests/tests.bats @@ -22,8 +22,8 @@ setup() { MAKECONF=../Makeconf [ ! -f ${MAKECONF} ] && skip "Can't find Makeconf, looked in ${MAKECONF}" - eval $(grep -E ^BUILD_.+=.+ ${MAKECONF}) - eval $(grep -E ^TEST_TARGET=.+ ${MAKECONF}) + # This is subtle; see the comments in configure.sh. + eval $(grep -E ^CONFIG_ ${MAKECONF}) if [ -x "$(command -v timeout)" ]; then TIMEOUT=timeout @@ -35,31 +35,30 @@ setup() { case "${BATS_TEST_NAME}" in *hvt) - [ "${BUILD_HVT}" = "no" ] && skip "hvt not built" - case ${TEST_TARGET} in - *-linux-gnu) + [ -z "${CONFIG_HVT}" ] && skip "hvt not configured" + case "${CONFIG_HOST}" in + Linux) [ -c /dev/kvm -a -w /dev/kvm ] || skip "no access to /dev/kvm or not present" ;; - x86_64-*-freebsd*) - # TODO, just try and run the test anyway - ;; - amd64-unknown-openbsd*) + FreeBSD|OpenBSD) # TODO, just try and run the test anyway ;; *) - skip "Don't know how to run ${BATS_TEST_NAME} on ${TEST_TARGET}" + skip "Don't know how to run ${BATS_TEST_NAME} on ${CONFIG_HOST}" ;; esac + HVT_TENDER=../tenders/hvt/solo5-hvt + HVT_TENDER_DEBUG=../tenders/hvt/solo5-hvt-debug ;; *virtio) if [ "$(uname -s)" = "OpenBSD" ]; then skip "virtio tests not run for OpenBSD" fi - [ "${BUILD_VIRTIO}" = "no" ] && skip "virtio not built" + [ -z "${CONFIG_VIRTIO}" ] && skip "virtio not configured" VIRTIO=../scripts/virtio-run/solo5-virtio-run.sh ;; *spt) - [ "${BUILD_SPT}" = "no" ] && skip "spt not built" + [ -z "${CONFIG_SPT}" ] && skip "spt not configured" SPT_TENDER=../tenders/spt/solo5-spt ;; esac @@ -75,261 +74,236 @@ teardown() { rm -f ${DISK} } +hvt_run() { + run ${TIMEOUT} --foreground 30s ${HVT_TENDER} "$@" +} + +spt_run() { + run ${TIMEOUT} --foreground 30s ${SPT_TENDER} "$@" +} + +virtio_run() { + run ${TIMEOUT} --foreground 30s ${VIRTIO} "$@" +} + +expect_success() { + [ "$status" -eq 0 ] && [[ "$output" == *"SUCCESS"* ]] +} + +virtio_expect_success() { + [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] && \ + [[ "$output" == *"SUCCESS"* ]] +} + +expect_abort() { + [ "$status" -eq 255 ] && [[ "$output" == *"ABORT"* ]] +} + +virtio_expect_abort() { + [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] && \ + [[ "$output" == *"ABORT"* ]] +} + +# ------------------------------------------------------------------------------ +# Tests start here +# ------------------------------------------------------------------------------ + @test "hello hvt" { - run ${TIMEOUT} --foreground 30s test_hello/solo5-hvt test_hello/test_hello.hvt Hello_Solo5 - [ "$status" -eq 0 ] + hvt_run test_hello/test_hello.hvt Hello_Solo5 + expect_success } @test "hello virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -- test_hello/test_hello.virtio Hello_Solo5 - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"SUCCESS"* ]] + virtio_run test_hello/test_hello.virtio Hello_Solo5 + virtio_expect_success } @test "hello spt" { - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} test_hello/test_hello.spt Hello_Solo5 - [ "$status" -eq 0 ] + spt_run test_hello/test_hello.spt Hello_Solo5 + expect_success } @test "quiet hvt" { - run ${TIMEOUT} --foreground 30s test_quiet/solo5-hvt test_quiet/test_quiet.hvt --solo5:quiet - [ "$status" -eq 0 ] - [[ "$output" == *"SUCCESS"* ]] + hvt_run -- test_quiet/test_quiet.hvt --solo5:quiet + expect_success [[ "$output" != *"Solo5:"* ]] } @test "quiet virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -- test_quiet/test_quiet.virtio --solo5:quiet - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - OS="$(uname -s)" - case ${OS} in - Linux) - [[ "$output" == *"SUCCESS"* ]] - [[ "$output" != *"Solo5:"* ]] - ;; - FreeBSD) - [[ "${lines[3]}" == "**** Solo5 standalone test_verbose ****" ]] - [[ "${lines[4]}" == "SUCCESS" ]] - [[ "${lines[5]}" == "Solo5: Halted" ]] - ;; - OpenBSD) - [[ "${lines[3]}" == "**** Solo5 standalone test_verbose ****" ]] - [[ "${lines[4]}" == "SUCCESS" ]] - [[ "${lines[5]}" == "Solo5: Halted" ]] - ;; - *) - skip "Don't know how to run on ${OS}" - ;; - esac + virtio_run -- test_quiet/test_quiet.virtio --solo5:quiet + virtio_expect_success + # XXX "Solo5: Halted" might be printed (see old version), what to test for + # here? } @test "quiet spt" { - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} test_quiet/test_quiet.spt --solo5:quiet - [ "$status" -eq 0 ] - [[ "$output" == *"SUCCESS"* ]] + spt_run -- test_quiet/test_quiet.spt --solo5:quiet + expect_success [[ "$output" != *"Solo5:"* ]] } @test "globals hvt" { - run ${TIMEOUT} --foreground 30s test_globals/solo5-hvt test_globals/test_globals.hvt - [ "$status" -eq 0 ] + hvt_run test_globals/test_globals.hvt + expect_success } @test "globals virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -- test_globals/test_globals.virtio - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"SUCCESS"* ]] + virtio_run test_globals/test_globals.virtio + virtio_expect_success } @test "globals spt" { - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} test_globals/test_globals.spt - [ "$status" -eq 0 ] + spt_run test_globals/test_globals.spt + expect_success } @test "exception hvt" { - run ${TIMEOUT} --foreground 30s test_exception/solo5-hvt test_exception/test_exception.hvt - [ "$status" -eq 255 ] - [[ "$output" == *"ABORT"* ]] + hvt_run test_exception/test_exception.hvt + expect_abort } @test "exception virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -- test_exception/test_exception.virtio - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"ABORT"* ]] + virtio_run test_exception/test_exception.virtio + virtio_expect_abort } @test "exception spt" { - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} test_exception/test_exception.spt + spt_run test_exception/test_exception.spt [ "$status" -eq 139 ] # SIGSEGV } @test "zeropage hvt" { - run ${TIMEOUT} --foreground 30s test_zeropage/solo5-hvt test_zeropage/test_zeropage.hvt - [ "$status" -eq 255 ] - [[ "$output" == *"ABORT"* ]] + hvt_run test_zeropage/test_zeropage.hvt + expect_abort } @test "zeropage virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -- test_zeropage/test_zeropage.virtio - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"ABORT"* ]] + virtio_run test_zeropage/test_zeropage.virtio + virtio_expect_abort } @test "zeropage spt" { - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} test_zeropage/test_zeropage.spt + spt_run test_zeropage/test_zeropage.spt [ "$status" -eq 139 ] # SIGSEGV } @test "notls hvt" { - run ${TIMEOUT} --foreground 30s test_notls/solo5-hvt test_notls/test_notls.hvt - [ "$status" -eq 255 ] - [[ "$output" == *"ABORT"* ]] + hvt_run test_notls/test_notls.hvt + expect_abort } @test "notls virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -- test_notls/test_notls.virtio - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"ABORT"* ]] + virtio_run test_notls/test_notls.virtio + virtio_expect_abort } @test "notls spt" { skip "not supported on spt yet" - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} test_notls/test_notls.spt - [ "$status" -eq 139 ] } @test "ssp hvt" { - run ${TIMEOUT} --foreground 30s test_ssp/solo5-hvt test_ssp/test_ssp.hvt - [ "$status" -eq 255 ] - [[ "$output" == *"ABORT"* ]] + hvt_run test_ssp/test_ssp.hvt + expect_abort } @test "ssp virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -- test_ssp/test_ssp.virtio - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"ABORT"* ]] + virtio_run test_ssp/test_ssp.virtio + virtio_expect_abort } @test "ssp spt" { - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} test_ssp/test_ssp.spt - [ "$status" -eq 255 ] - [[ "$output" == *"ABORT"* ]] + spt_run test_ssp/test_ssp.spt + expect_abort } @test "fpu hvt" { - run ${TIMEOUT} --foreground 30s test_fpu/solo5-hvt test_fpu/test_fpu.hvt - [ "$status" -eq 0 ] + hvt_run test_fpu/test_fpu.hvt + expect_success } @test "fpu virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -- test_fpu/test_fpu.virtio - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"SUCCESS"* ]] + virtio_run test_fpu/test_fpu.virtio + virtio_expect_success } @test "fpu spt" { - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} test_fpu/test_fpu.spt - [ "$status" -eq 0 ] + spt_run test_fpu/test_fpu.spt + expect_success } @test "time hvt" { - run ${TIMEOUT} --foreground 30s test_time/solo5-hvt test_time/test_time.hvt - [ "$status" -eq 0 ] + hvt_run test_time/test_time.hvt + expect_success } @test "time virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -- test_time/test_time.virtio - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"SUCCESS"* ]] + virtio_run test_time/test_time.virtio + virtio_expect_success } @test "time spt" { - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} test_time/test_time.spt - [ "$status" -eq 0 ] + spt_run test_time/test_time.spt + expect_success } @test "seccomp spt" { - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} test_seccomp/test_seccomp.spt + spt_run test_seccomp/test_seccomp.spt [ "$status" -eq 159 ] # SIGSYS } @test "blk hvt" { - run ${TIMEOUT} --foreground 30s test_blk/solo5-hvt --disk=${DISK} test_blk/test_blk.hvt - [ "$status" -eq 0 ] + hvt_run --disk=${DISK} -- test_blk/test_blk.hvt + expect_success } @test "blk virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -d ${DISK} -- test_blk/test_blk.virtio - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"SUCCESS"* ]] + virtio_run -d ${DISK} -- test_blk/test_blk.virtio + virtio_expect_success } @test "blk spt" { - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} --disk=${DISK} test_blk/test_blk.spt - [ "$status" -eq 0 ] + spt_run --disk=${DISK} -- test_blk/test_blk.spt + expect_success } @test "ping-serve hvt" { - TENDER=test_ping_serve/solo5-hvt - UNIKERNEL=test_ping_serve/test_ping_serve.hvt - [ $(id -u) -ne 0 ] && skip "Need root to run this test, for ping -f" - ( - sleep 1 - ${TIMEOUT} 30s ping -fq -c 100000 ${NET_IP} - ) & - - run ${TIMEOUT} --foreground 30s ${TENDER} --net=${NET} -- ${UNIKERNEL} limit - [ "$status" -eq 0 ] + ( sleep 1; ${TIMEOUT} 30s ping -fq -c 100000 ${NET_IP} ) & + hvt_run --net=${NET} -- test_ping_serve/test_ping_serve.hvt limit + expect_success } @test "ping-serve virtio" { - UNIKERNEL=test_ping_serve/test_ping_serve.virtio - [ $(id -u) -ne 0 ] && skip "Need root to run this test, for ping -f" - ( - sleep 1 - ${TIMEOUT} 30s ping -fq -c 100000 ${NET_IP} - ) & - - run ${TIMEOUT} --foreground 30s ${VIRTIO} -n ${NET} -- $UNIKERNEL limit - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"SUCCESS"* ]] + ( sleep 1; ${TIMEOUT} 30s ping -fq -c 100000 ${NET_IP} ) & + virtio_run -n ${NET} -- test_ping_serve/test_ping_serve.virtio limit + virtio_expect_success } @test "ping-serve spt" { - UNIKERNEL=test_ping_serve/test_ping_serve.spt - [ $(id -u) -ne 0 ] && skip "Need root to run this test, for ping -f" - ( - sleep 1 - ${TIMEOUT} 30s ping -fq -c 100000 ${NET_IP} - ) & - - run ${TIMEOUT} --foreground 30s ${SPT_TENDER} --net=${NET} -- ${UNIKERNEL} limit - [ "$status" -eq 0 ] + ( sleep 1; ${TIMEOUT} 30s ping -fq -c 100000 ${NET_IP} ) & + spt_run --net=${NET} -- test_ping_serve/test_ping_serve.spt limit + expect_success } @test "abort hvt" { - case ${TEST_TARGET} in - x86_64-linux-gnu|x86_64-*-freebsd*) + [ "${CONFIG_ARCH}" = "x86_64" ] || skip "not implemented for ${CONFIG_ARCH}" + case "${CONFIG_HOST}" in + Linux|FreeBSD) ;; *) - skip "not implemented for ${TEST_TARGET}" + skip "not implemented for ${CONFIG_HOST}" ;; esac - run ${TIMEOUT} --foreground 30s test_abort/solo5-hvt --dumpcore test_abort/test_abort.hvt + + run ${TIMEOUT} --foreground 30s ${HVT_TENDER_DEBUG} \ + --dumpcore test_abort/test_abort.hvt [ "$status" -eq 255 ] CORE=`echo "$output" | grep -o "core\.solo5-hvt\.[0-9]*$"` [ -f "$CORE" ] [ -f "$CORE" ] && mv "$CORE" "$BATS_TMPDIR" } - -@test "abort virtio" { - run ${TIMEOUT} --foreground 30s ${VIRTIO} -- test_abort/test_abort.virtio - [ "$status" -eq 0 -o "$status" -eq 2 -o "$status" -eq 83 ] - [[ "$output" == *"solo5_abort() called"* ]] -}