]> xenbits.xensource.com Git - osstest/rumprun.git/commitdiff
Add genfs.
authorAntti Kantee <pooka@iki.fi>
Wed, 3 Feb 2016 23:57:52 +0000 (23:57 +0000)
committerAntti Kantee <pooka@iki.fi>
Wed, 3 Feb 2016 23:57:52 +0000 (23:57 +0000)
genfs is a tool for turning directory hierarchies into an
object file.  When the object file in question is baked into
a Rumprun unikernel image, the files from the hierarchies are
(magically) available in the booted unikernel.

app-tools/Makefile
app-tools/genfs.in [new file with mode: 0644]

index 379b6c7c0a6a9aab4e1315ae381b9de91874baff..a76a232a485b86d64a27794d1281a16bdeb55100 100644 (file)
@@ -12,6 +12,8 @@ TOOLOBJ:= ${RROBJ}/app-tools
 
 _CCVARIANT:=$(shell ${RUMPMAKE} -f bsd.own.mk -V '$${HAVE_LLVM:Dclang:Ugcc}')
 _CXXVARIANT:=$(shell ${RUMPMAKE} -f bsd.own.mk -V '$${HAVE_LLVM:Dclang++:Ug++}')
+MACHINE_GNU_PLATFORM:=\
+    $(shell ${RUMPMAKE} -f bsd.own.mk -V '$${MACHINE_GNU_PLATFORM}')
 
 _FILES=        toolchain.cmake recipe.s
 FILES= $(_FILES:%=$(TOOLTUPLE)-%)
@@ -29,6 +31,7 @@ BIN_G+=       $(TOOLTUPLE)-$(_CXXVARIANT)
 CCWRP+=        ${CXX}
 endif
 BIN_G+=        rumprun-bake
+BIN_G+= $(TOOLTUPLE)-genfs
 STATICBIN= rumprun rumpstop
 
 GENS.bin=      ${BIN_G:%=${TOOLOBJ}/%}
@@ -54,6 +57,7 @@ MACHDIR:= rumprun-${MACHINE_GNU_ARCH}-${PLATFORM}
 
 LIBEXEC_CC:= $(subst ${BRSOURCEDIR},${BRLIBEXECDEST},${CC})
 LIBEXEC_CXX:= $(subst ${BRSOURCEDIR},${BRLIBEXECDEST},${CXX})
+LIBEXEC_OBJCOPY:= ${BRLIBEXECDEST}/${MACHINE_GNU_PLATFORM}-objcopy
 
 TOOLS_CC := ${RRDEST}/bin/$(TOOLTUPLE)-${_CCVARIANT}
 TOOLS_CXX := ${RRDEST}/bin/$(TOOLTUPLE)-${_CXXVARIANT}
@@ -66,6 +70,7 @@ ${TOOLOBJ}/${2}: ${1} Makefile ${TOOLOBJ}
        sed <$$< > $$@                                                  \
                -e 's#!LIBEXEC_CC!#$(LIBEXEC_CC)#g;'                    \
                -e 's#!LIBEXEC_CXX!#$(LIBEXEC_CXX)#g;'                  \
+               -e 's#!LIBEXEC_OBJCOPY!#$(LIBEXEC_OBJCOPY)#g;'          \
                -e 's#!TOOLS_CC!#$(TOOLS_CC)#g;'                        \
                -e 's#!TOOLS_CXX!#$(TOOLS_CXX)#g;'                      \
                -e 's#!MACHINE_GNU_ARCH!#$(MACHINE_GNU_ARCH)#g;'        \
@@ -83,6 +88,7 @@ $(eval $(call templ,cc.in,$(TOOLTUPLE)-${_CCVARIANT}))
 $(eval $(call templ,cc.in,$(TOOLTUPLE)-${_CXXVARIANT}))
 $(eval $(call templ,specs-bake.in,specs-bake-$(TOOLTUPLE)-$(PLATFORM)))
 $(eval $(call templ,rumprun-bake.in,rumprun-bake))
+$(eval $(call templ,genfs.in,$(TOOLTUPLE)-genfs))
 
 define binwrapper
 uptool_$1=$(shell echo $1 | tr '[:lower:]' '[:upper:]')
diff --git a/app-tools/genfs.in b/app-tools/genfs.in
new file mode 100644 (file)
index 0000000..345ec55
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/bin/env sh
+
+#
+# Copyright (c) 2016 Antti Kantee <pooka@fixup.fi>
+# All Rights Reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+#
+# Include given files as binary and generate constructor code
+# which loads said files to rumpfs.
+#
+
+set -eu
+
+: ${RUMPRUN_GENFS_CC:=!LIBEXEC_CC!}
+: ${RUMPRUN_GENFS_OBJCOPY:=!LIBEXEC_OBJCOPY!}
+: ${RUMPRUN_GENFS_CFLAGS:=!CFLAGS!}
+: ${RUMPRUN_GENFS_INCDIR:=!DESTDIR!/rumprun-!MACHINE_GNU_ARCH!/include}
+
+nuketmpdir ()
+{
+
+       nukeme="${TMPDIR}"
+       TMPDIR=''
+       rm -rf ${nukeme}
+}
+
+TMPDIR=$(mktemp -d /tmp/rumprun-genfs.XXXXXX)
+trap nuketmpdir 0 INT TERM
+
+[ $# -ge 2 ] || { echo "usage: $0 outfile directory ..."; exit 1; }
+OUTFILE="$1"
+shift
+
+FILES=
+for sd in "$@"; do
+       FILES="${FILES} $(find ${sd} -type f)"
+done
+
+makedirlist ()
+{
+       DIRS=
+       for x in ${FILES}; do
+               d=$(dirname $x)
+               [ $d != . ] || continue
+               DIRS="${DIRS} /${d}"
+       done
+       DIRS=$(echo ${DIRS} | xargs -n1 | sort | uniq)
+
+       printf 'static const char *dirlist[] = {\n'
+       for d in ${DIRS}; do
+               printf '\t"%s",\n' $d
+       done
+       printf '};\n\n'
+}
+
+setfilevars ()
+{
+
+       fn=$((${fn}+1))
+       f_und=$(echo ${1} | sed 's,/,_,g;s/\./_/g')
+       bin=_binary_${f_und}
+       rf=_rumpfs_f${fn}
+}
+
+makeelfdata ()
+{
+
+       fn=0
+       DSRCS=
+       for f in ${FILES}; do
+               setfilevars ${f}
+               ${RUMPRUN_GENFS_CC} -Wl,-r,-b,binary -nostdlib          \
+                   -o ${TMPDIR}/d${fn}.elf ${f} -nostdlib
+               ${RUMPRUN_GENFS_OBJCOPY}                                \
+                   --redefine-sym ${bin}_start=${rf}_start             \
+                   --redefine-sym ${bin}_size=${rf}_size               \
+                   --strip-symbol ${bin}_end                           \
+               ${TMPDIR}/d${fn}.elf
+               DSRCS="${DSRCS} ${TMPDIR}/d${fn}.elf"
+
+               printf 'extern uint8_t %s_start, %s_size;\n' ${rf} ${rf}
+       done
+
+       printf '\n'
+       printf 'struct rumprun_extfile files[] = {\n'
+
+       fn=0
+       for f in ${FILES}; do
+               setfilevars %{f}
+               printf '\t{ "/%s",\n' ${f}
+               printf '\t    { (void *)&%s_start,\n' ${rf}
+               printf '\t      (size_t)(uintptr_t)&%s_size} },\n' ${rf}
+       done
+
+       printf '};\n'
+}
+
+printhead ()
+{
+
+       printf '#include <sys/types.h>\n\n'
+       printf '#include <rumprun/genfs.h>\n\n'
+}
+
+printtail ()
+{
+
+       printf 'static void __attribute__((constructor))\n'
+       printf 'rumpfs_externatilize(void)\n'
+       printf '{\n\n'
+       printf '\trumprun_genfs(dirlist, __arraycount(dirlist),\n'
+       printf '\t    files, __arraycount(files));\n'
+       printf '}\n'
+}
+
+exec 3>&1 1>${TMPDIR}/constr.c
+printhead
+makedirlist
+makeelfdata
+printtail
+exec 1>&3 3>&-
+
+${RUMPRUN_GENFS_CC} -nostdlib -Wl,-r -I${RUMPRUN_GENFS_INCDIR} \
+    -o ${OUTFILE} ${DSRCS} ${TMPDIR}/constr.c
+
+exit 0