From 0c2dabf9751dc59aa6c20f99bd2f98ed88548846 Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Wed, 27 Oct 2021 10:11:43 +0200 Subject: [PATCH] new-build: get rid of Go(ogle) with few rc scripts Also, in binutils: fix inlining compilation error, see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=242053 --- .gitignore | 7 +- .gitmodules | 19 +- QA.sh | 4 +- bin/.gitignore | 1 + bin/build | 3 + bin/runqemu | 57 ++ bin/start-u9fs.sh | 3 + bin/template | 3 + buildtools.sh | 26 +- continuous-build.sh | 11 +- cross/init.sh | 6 +- cross/pkgs/build.json | 12 - cross/pkgs/build.sh | 10 + cross/pkgs/gcc/build.sh | 2 +- cross/pkgs/gcc/src/fetch.sh | 45 ++ cross/pkgs/gcc/src/sha256sum.txt | 5 + cross/src/fetch.json | 53 -- cross/src/fetch.sh | 45 ++ cross/src/sha256sum.txt | 5 + devshell.sh | 10 +- rcmain | 51 ++ runOver9P.sh | 7 +- .../src/github.com/0intro => src}/drawterm | 0 src/jehanne/cmd/build/build.go | 669 ------------------ src/jehanne/cmd/build/codegen.go | 182 ----- src/jehanne/cmd/build/doc.go | 184 ----- src/jehanne/cmd/build/paths.go | 31 - src/jehanne/cmd/build/paths_harvey.go | 17 - src/jehanne/cmd/convert/convert.go | 155 ---- src/jehanne/cmd/data2c/data2c.go | 39 - src/jehanne/cmd/elf2c/elf2c.go | 113 --- src/jehanne/cmd/fetch/fetch.go | 197 ------ src/jehanne/cmd/jsonpretty/jsonpretty.go | 53 -- src/jehanne/cmd/kpdump/kpdump.go | 115 --- src/jehanne/cmd/ksyscalls/ksyscalls.go | 385 ---------- src/jehanne/cmd/mksys/mksys.go | 325 --------- src/jehanne/cmd/op2/op2.go | 107 --- src/jehanne/cmd/preen/.gitignore | 1 - src/jehanne/cmd/preen/preen.go | 157 ---- src/jehanne/cmd/profile/profile.go | 131 ---- src/jehanne/cmd/removemach/removemach.go | 78 -- src/jehanne/cmd/runqemu/runqemu.go | 119 ---- src/jehanne/cmd/telnet/telnet.go | 244 ------- src/jehanne/cmd/usyscalls/usyscalls.go | 272 ------- src/jehanne/cmd/vendor/doc.go | 45 -- src/jehanne/cmd/vendor/vendor.go | 248 ------- src/netcat | 1 + src/trampoline | 1 + src/u9fs | 1 + third_party/src/github.com/lionkov/ninep | 1 - 50 files changed, 278 insertions(+), 3978 deletions(-) create mode 100755 bin/build create mode 100755 bin/runqemu create mode 100755 bin/start-u9fs.sh create mode 100755 bin/template delete mode 100644 cross/pkgs/build.json create mode 100755 cross/pkgs/build.sh create mode 100755 cross/pkgs/gcc/src/fetch.sh create mode 100644 cross/pkgs/gcc/src/sha256sum.txt delete mode 100644 cross/src/fetch.json create mode 100755 cross/src/fetch.sh create mode 100644 cross/src/sha256sum.txt create mode 100644 rcmain rename {third_party/src/github.com/0intro => src}/drawterm (100%) delete mode 100644 src/jehanne/cmd/build/build.go delete mode 100644 src/jehanne/cmd/build/codegen.go delete mode 100644 src/jehanne/cmd/build/doc.go delete mode 100644 src/jehanne/cmd/build/paths.go delete mode 100644 src/jehanne/cmd/build/paths_harvey.go delete mode 100644 src/jehanne/cmd/convert/convert.go delete mode 100644 src/jehanne/cmd/data2c/data2c.go delete mode 100644 src/jehanne/cmd/elf2c/elf2c.go delete mode 100644 src/jehanne/cmd/fetch/fetch.go delete mode 100644 src/jehanne/cmd/jsonpretty/jsonpretty.go delete mode 100644 src/jehanne/cmd/kpdump/kpdump.go delete mode 100644 src/jehanne/cmd/ksyscalls/ksyscalls.go delete mode 100644 src/jehanne/cmd/mksys/mksys.go delete mode 100644 src/jehanne/cmd/op2/op2.go delete mode 100644 src/jehanne/cmd/preen/.gitignore delete mode 100644 src/jehanne/cmd/preen/preen.go delete mode 100644 src/jehanne/cmd/profile/profile.go delete mode 100644 src/jehanne/cmd/removemach/removemach.go delete mode 100644 src/jehanne/cmd/runqemu/runqemu.go delete mode 100644 src/jehanne/cmd/telnet/telnet.go delete mode 100644 src/jehanne/cmd/usyscalls/usyscalls.go delete mode 100644 src/jehanne/cmd/vendor/doc.go delete mode 100644 src/jehanne/cmd/vendor/vendor.go create mode 160000 src/netcat create mode 160000 src/trampoline create mode 160000 src/u9fs delete mode 160000 third_party/src/github.com/lionkov/ninep diff --git a/.gitignore b/.gitignore index 7478cec..f739d90 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ -third_party/pkg/ -third_party/src/github.com/kr/ -third_party/src/github.com/creack/ -third_party/src/golang.org/ - *.build.log + +lib/ diff --git a/.gitmodules b/.gitmodules index 5175e00..184b1f0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,13 +1,18 @@ -[submodule "third_party/src/github.com/lionkov/ninep"] - path = third_party/src/github.com/lionkov/ninep - url = https://github.com/JehanneOS/devtools-ninep.git - branch = master -[submodule "third_party/src/github.com/0intro/drawterm"] - path = third_party/src/github.com/0intro/drawterm - url = https://github.com/JehanneOS/devtools-drawterm.git [submodule "cross/pkgs/newlib/src"] path = cross/pkgs/newlib/src url = https://github.com/JehanneOS/newlib.git [submodule "cross/pkgs/mksh"] path = cross/pkgs/mksh/src url = https://github.com/JehanneOS/mksh.git +[submodule "src/trampoline"] + path = src/trampoline + url = https://tesio@bitbucket.org/tesio/trampoline.git +[submodule "src/u9fs"] + path = src/u9fs + url = https://bitbucket.org/plan9-from-bell-labs/u9fs.git +[submodule "src/drawterm"] + path = src/drawterm + url = https://github.com/JehanneOS/devtools-drawterm.git +[submodule "src/netcat"] + path = src/netcat + url = https://git.code.sf.net/p/nc110/git diff --git a/QA.sh b/QA.sh index ab20d90..b0a9e6b 100755 --- a/QA.sh +++ b/QA.sh @@ -11,7 +11,7 @@ fi trap : 2 -$JEHANNE/hacking/bin/ufs -d=0 -root=$JEHANNE & +$JEHANNE/hacking/bin/nc -p 5640 -l -e $JEHANNE/hacking/bin/start-u9fs.sh & ufspid=$! export machineflag=pc @@ -76,6 +76,6 @@ EOF echo $cmd eval $cmd -kill $ufspid +# kill $ufspid # not needed anymore thank to netcat wait diff --git a/bin/.gitignore b/bin/.gitignore index d6b7ef3..4367c98 100644 --- a/bin/.gitignore +++ b/bin/.gitignore @@ -1,2 +1,3 @@ * !.gitignore +!build diff --git a/bin/build b/bin/build new file mode 100755 index 0000000..c596522 --- /dev/null +++ b/bin/build @@ -0,0 +1,3 @@ +#!/bin/sh + +rc $JEHANNE/arch/rc/cmd/build $@ diff --git a/bin/runqemu b/bin/runqemu new file mode 100755 index 0000000..5c5564b --- /dev/null +++ b/bin/runqemu @@ -0,0 +1,57 @@ +#!/usr/bin/env rc +# poor man portable expect + +QPROMPT='10.0.2.15# ' +INFILE=/tmp/runqemu.$pid.in +OUTFILE=/tmp/runqemu.$pid.out + +cd $JEHANNE/arch/amd64/kern +echo -n > $INFILE +echo -n > $OUTFILE + +@{tail -f $INFILE | $JEHANNE/hacking/QA.sh >> $OUTFILE} & +QPID=$apid + +tail -f $OUTFILE & +TPID=$apid + +ifs=' +' +INPUT=`{cat} + +fn descendants { + if( ! ~ 0 $#1 ) { + echo $1; + ps -o pid= --ppid $1|xargs -n 1 rc -c 'descendants $1' + } +} + +fn quit { + kill -2 `{descendants $QPID} + kill -2 $TPID + wait + rm $INFILE + rm $OUTFILE + exit $1 +} + +fn failOnError { + if( ! ~ 0 `{cat $OUTFILE | grep FAIL | wc -c}){ + quit 1 + } +} + +for(cmd in $INPUT){ + while( ~ 0 `{tail -n 1 $OUTFILE | sed -n '/'$QPROMPT'/p' | wc -c}){ + sleep 2 + } + failOnError + echo $cmd >> $INFILE + sleep 2 +} + +while( ~ 0 `{tail -n 1 $OUTFILE | sed -n '/'$QPROMPT'/p' | wc -c}){ + sleep 2 +} +failOnError +quit diff --git a/bin/start-u9fs.sh b/bin/start-u9fs.sh new file mode 100755 index 0000000..4d61cb9 --- /dev/null +++ b/bin/start-u9fs.sh @@ -0,0 +1,3 @@ +#!/bin/sh +# U9FS_LOG="-l $JEHANNE/hacking/lib/u9fs.log -z -D" +$JEHANNE/hacking/bin/u9fs $U9FS_LOG -a none -u $USER $JEHANNE diff --git a/bin/template b/bin/template new file mode 100755 index 0000000..06cabd6 --- /dev/null +++ b/bin/template @@ -0,0 +1,3 @@ +#!/bin/sh + +$JEHANNE/hacking/bin/rc $JEHANNE/arch/rc/cmd/template $@ diff --git a/buildtools.sh b/buildtools.sh index 135f026..42f12b7 100755 --- a/buildtools.sh +++ b/buildtools.sh @@ -4,16 +4,16 @@ # # Copyright (C) 2016-2017 Giacomo Tesio -BUILD_GO_TOOLS=true +BUILD_TRAMPOLINE=true BUILD_DRAWTERM=true while test $# -gt 0 do case "$1" in - --help) echo "$0 [ --no-tools | --no-drawterm | --help ]" + --help) echo "$0 [ --no-trampoline | --no-drawterm | --help ]" exit 0 ;; - --no-tools) BUILD_GO_TOOLS=false + --no-tools) BUILD_TRAMPOLINE=false ;; --no-drawterm) BUILD_DRAWTERM=false ;; @@ -29,10 +29,10 @@ cd `dirname $0` if [ -z "$UTILITIES" ]; then UTILITIES=`pwd` fi -if [ "$BUILD_GO_TOOLS$BUILD_DRAWTERM" = "truetrue" ]; then +if [ "$BUILD_TRAMPOLINE$BUILD_DRAWTERM" = "truetrue" ]; then git clean -x -d -f $UTILITIES/bin fi -if [ "$BUILD_GO_TOOLS" = "true" ]; then +if [ "$BUILD_TRAMPOLINE" = "true" ]; then echo -n Building development tools. ( # Inside parentheses, and therefore a subshell . . . @@ -44,18 +44,20 @@ if [ "$BUILD_GO_TOOLS" = "true" ]; then ) & dotter=$! ( - GOBIN="$UTILITIES/bin" GOPATH="$UTILITIES/third_party:$UTILITIES" go get -d jehanne/cmd/... && - GOBIN="$UTILITIES/bin" GOPATH="$UTILITIES/third_party:$UTILITIES" go install jehanne/cmd/... && - GOBIN="$UTILITIES/bin" GOPATH="$UTILITIES/third_party:$UTILITIES" go install github.com/lionkov/ninep/srv/examples/ufs - ) + (cd $UTILITIES/src/trampoline/ && ./build.sh) + (cd $UTILITIES/src/netcat && XLIB=-lresolv DFLAGS=-DGAPING_SECURITY_HOLE make linux && mv nc $UTILITIES/bin && git clean -xdf .) + (cd $UTILITIES/src/u9fs && make && mv u9fs $UTILITIES/bin && git clean -xdf .) + ) > $UTILITIES/src/utils.build.log 2>&1 STATUS="$?" kill $dotter wait $dotter 2>/dev/null if [ ! $STATUS -eq "0" ] then echo "FAIL" + cat utils.build.log exit $STATUS else + rm $UTILITIES/src/utils.build.log echo "done." fi fi @@ -72,7 +74,7 @@ if [ "$BUILD_DRAWTERM" = "true" ]; then ) & dotter=$! ( - cd $UTILITIES/third_party/src/github.com/0intro/drawterm/ && + cd $UTILITIES/src/drawterm/ && git clean -xdf > ../drawterm.build.log 2>&1 && CONF=unix make >> ../drawterm.build.log 2>&1 && mv drawterm $UTILITIES/bin @@ -82,11 +84,11 @@ if [ "$BUILD_DRAWTERM" = "true" ]; then wait $dotter 2>/dev/null if [ $STATUS -eq "0" ] then - rm $UTILITIES/third_party/src/github.com/0intro/drawterm.build.log + rm $UTILITIES/src/drawterm.build.log echo "done." else echo "FAIL" - cat $UTILITIES/third_party/src/github.com/0intro/drawterm.build.log + cat $$UTILITIES/src/drawterm.build.log exit $STATUS fi fi diff --git a/continuous-build.sh b/continuous-build.sh index bc660c0..1734810 100755 --- a/continuous-build.sh +++ b/continuous-build.sh @@ -54,16 +54,7 @@ if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then export TOOLPREFIX=x86_64-jehanne- export CC=x86_64-jehanne-gcc - echo - echo "Vendorized code verification..." - echo - for v in `find $JEHANNE -type f|grep vendor.json`; do - echo "cd `dirname $v`" - (cd `dirname $v`; vendor -check) - done - echo - - build all + build if [ "$TRAVIS_BUILD_DIR" != "" ]; then if [ "$QA_CHECKS" != "" ]; then diff --git a/cross/init.sh b/cross/init.sh index 62646fb..2caad53 100755 --- a/cross/init.sh +++ b/cross/init.sh @@ -51,7 +51,7 @@ function dynpatch { # setup Jehanne's headers -usyscalls header $JEHANNE/sys/src/sysconf.json > $JEHANNE/arch/amd64/include/syscalls.h +cat $JEHANNE/sys/src/lib/jehanne/syscallh.rc.template | template | rc | sed 's/ ,/,/g; s/ )/)/g' > $JEHANNE/arch/amd64/include/syscalls.h mkdir -p $WORKING_DIR date > $LOG @@ -63,7 +63,7 @@ failOnError $? "libtool installation check" cp -fpr $JEHANNE/hacking/cross/src $WORKING_DIR cd $WORKING_DIR/src -fetch >> $LOG +./fetch.sh >> $LOG failOnError $? "fetching sources" mkdir -p $WORKING_DIR/build @@ -76,10 +76,12 @@ echo -n Building binutils... export BINUTILS_BUILD_DIR=$WORKING_DIR/build/binutils mkdir -p $BINUTILS_BUILD_DIR +# for libctf/swap.h patch see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=242053 ( ( grep -q jehanne $WORKING_DIR/src/binutils/config.sub || ( cd $WORKING_DIR && sed -i '/jehanne/b; /ELF_TARGET_ID/,/elf_backend_can_gc_sections/s/0x200000/0x1000 \/\/ jehanne hack/g' src/binutils/bfd/elf64-x86-64.c && sed -i '/jehanne/b; s/| midnightbsd\*/| midnightbsd* | jehanne*/g' src/binutils/config.sub && + sed -i 's/inline/static inline/g' src/binutils/libctf/swap.h && dynpatch 'binutils/bfd/config.bfd' '\# END OF targmatch.h' && dynpatch 'binutils/gas/configure.tgt' ' i386-\*-darwin\*)' && ( grep -q jehanne src/binutils/ld/configure.tgt || patch -p1 < $CROSS_DIR/patch/binutils/ld/configure.tgt ) && diff --git a/cross/pkgs/build.json b/cross/pkgs/build.json deleted file mode 100644 index eee6a5b..0000000 --- a/cross/pkgs/build.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "CrossCompiledPackages": { - "Env": [ - "CROSS_PKGS_BUILD=1" - ], - "Pre": [ - "./newlib/build.sh", - "./mksh/build.sh", - "./gcc/build.sh" - ] - } -} diff --git a/cross/pkgs/build.sh b/cross/pkgs/build.sh new file mode 100755 index 0000000..c5901d4 --- /dev/null +++ b/cross/pkgs/build.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +export IFS="$ifs" +export CROSS_PKGS_BUILD=1 +export CFLAGS='' +export CC='' + +./newlib/build.sh +./mksh/build.sh +./gcc/build.sh diff --git a/cross/pkgs/gcc/build.sh b/cross/pkgs/gcc/build.sh index 58c6aef..3eb23f7 100755 --- a/cross/pkgs/gcc/build.sh +++ b/cross/pkgs/gcc/build.sh @@ -50,7 +50,7 @@ ln -s `which echo` $JEHANNE/hacking/bin/makeinfo libtool --version >> /dev/null failOnError $? "libtool installation check" -(cd $JEHANNE_TOOLCHAIN/src && fetch) >> $LOG +(cd $JEHANNE_TOOLCHAIN/src && ./fetch.sh) >> $LOG failOnError $? "fetching sources" diff --git a/cross/pkgs/gcc/src/fetch.sh b/cross/pkgs/gcc/src/fetch.sh new file mode 100755 index 0000000..d0f1d18 --- /dev/null +++ b/cross/pkgs/gcc/src/fetch.sh @@ -0,0 +1,45 @@ +#!/bin/sh -e + +download () { + TARGET=$(basename $1) + if [ -f $TARGET ]; then + echo "fetch: skip $TARGET (already present)" + elif command -v curl >/dev/null 2>&1; then + curl -s --fail "$1" > $TARGET + elif command -v wget >/dev/null 2>&1; then + wget -O- "$1" > $TARGET + else + echo "ERROR: Unable to find either curl or wget" >&2 + exit 1 + fi +} + +extract () { + TARGET=$1 + ARCHIVE=$2 + if [ -d $TARGET ]; then + echo "fetch: skip $TARGET (already present)" + else + mkdir -p $TARGET + (cd $TARGET && tar xf ../$ARCHIVE --strip-components=1) + fi +} + +echo "fetch: downloading..." +download 'https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2' +download 'https://www.mpfr.org/mpfr-4.0.1/mpfr-4.0.1.tar.bz2' +download 'https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz' +download 'http://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.bz2' +download 'https://ftp.gnu.org/gnu/gcc/gcc-9.2.0/gcc-9.2.0.tar.gz' + +echo "fetch: check sum..." +sha256sum -c sha256sum.txt + +echo "fetch: extract archive..." +extract libgmp gmp-6.1.2.tar.bz2 +extract libmpfr mpfr-4.0.1.tar.bz2 +extract libmpc mpc-1.1.0.tar.gz +extract binutils binutils-2.33.1.tar.bz2 +extract gcc gcc-9.2.0.tar.gz + +echo "fetch: done." diff --git a/cross/pkgs/gcc/src/sha256sum.txt b/cross/pkgs/gcc/src/sha256sum.txt new file mode 100644 index 0000000..62643b7 --- /dev/null +++ b/cross/pkgs/gcc/src/sha256sum.txt @@ -0,0 +1,5 @@ +0cb4843da15a65a953907c96bad658283f3c4419d6bcc56bf2789db16306adb2 binutils-2.33.1.tar.bz2 +a931a750d6feadacbeecb321d73925cd5ebb6dfa7eff0802984af3aef63759f4 gcc-9.2.0.tar.gz +5275bb04f4863a13516b2f39392ac5e272f5e1bb8057b18aec1c9b79d73d8fb2 gmp-6.1.2.tar.bz2 +6985c538143c1208dcb1ac42cedad6ff52e267b47e5f970183a3e75125b43c2e mpc-1.1.0.tar.gz +a4d97610ba8579d380b384b225187c250ef88cfe1d5e7226b89519374209b86b mpfr-4.0.1.tar.bz2 diff --git a/cross/src/fetch.json b/cross/src/fetch.json deleted file mode 100644 index 6ea8069..0000000 --- a/cross/src/fetch.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "libgmp" : { - "Upstream":"https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2", - "Digest": { - "sha256":"5275bb04f4863a13516b2f39392ac5e272f5e1bb8057b18aec1c9b79d73d8fb2" - }, - "Compress":"bzip2", - "RemovePrefix": true, - "Exclude": [ - ] - }, - "libmpfr" : { - "Upstream":"https://www.mpfr.org/mpfr-4.0.1/mpfr-4.0.1.tar.bz2", - "Digest": { - "sha256":"a4d97610ba8579d380b384b225187c250ef88cfe1d5e7226b89519374209b86b" - }, - "Compress":"bzip2", - "RemovePrefix": true, - "Exclude": [ - ] - }, - "libmpc" : { - "Upstream":"https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz", - "Digest": { - "sha256":"6985c538143c1208dcb1ac42cedad6ff52e267b47e5f970183a3e75125b43c2e" - }, - "Compress":"gzip", - "RemovePrefix": true, - "Exclude": [ - ] - }, - "binutils": { - "Upstream":"http://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.bz2", - "Digest": { - "sha256":"0cb4843da15a65a953907c96bad658283f3c4419d6bcc56bf2789db16306adb2" - }, - "Compress":"bzip2", - "RemovePrefix": true, - "Exclude": [ - ] - }, - "gcc": { - "Upstream":"https://ftp.gnu.org/gnu/gcc/gcc-9.2.0/gcc-9.2.0.tar.gz", - "Digest": { - "sha256":"a931a750d6feadacbeecb321d73925cd5ebb6dfa7eff0802984af3aef63759f4" - }, - "Compress":"gzip", - "RemovePrefix": true, - "Exclude": [ - ] - } - -} diff --git a/cross/src/fetch.sh b/cross/src/fetch.sh new file mode 100755 index 0000000..d0f1d18 --- /dev/null +++ b/cross/src/fetch.sh @@ -0,0 +1,45 @@ +#!/bin/sh -e + +download () { + TARGET=$(basename $1) + if [ -f $TARGET ]; then + echo "fetch: skip $TARGET (already present)" + elif command -v curl >/dev/null 2>&1; then + curl -s --fail "$1" > $TARGET + elif command -v wget >/dev/null 2>&1; then + wget -O- "$1" > $TARGET + else + echo "ERROR: Unable to find either curl or wget" >&2 + exit 1 + fi +} + +extract () { + TARGET=$1 + ARCHIVE=$2 + if [ -d $TARGET ]; then + echo "fetch: skip $TARGET (already present)" + else + mkdir -p $TARGET + (cd $TARGET && tar xf ../$ARCHIVE --strip-components=1) + fi +} + +echo "fetch: downloading..." +download 'https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2' +download 'https://www.mpfr.org/mpfr-4.0.1/mpfr-4.0.1.tar.bz2' +download 'https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz' +download 'http://ftp.gnu.org/gnu/binutils/binutils-2.33.1.tar.bz2' +download 'https://ftp.gnu.org/gnu/gcc/gcc-9.2.0/gcc-9.2.0.tar.gz' + +echo "fetch: check sum..." +sha256sum -c sha256sum.txt + +echo "fetch: extract archive..." +extract libgmp gmp-6.1.2.tar.bz2 +extract libmpfr mpfr-4.0.1.tar.bz2 +extract libmpc mpc-1.1.0.tar.gz +extract binutils binutils-2.33.1.tar.bz2 +extract gcc gcc-9.2.0.tar.gz + +echo "fetch: done." diff --git a/cross/src/sha256sum.txt b/cross/src/sha256sum.txt new file mode 100644 index 0000000..62643b7 --- /dev/null +++ b/cross/src/sha256sum.txt @@ -0,0 +1,5 @@ +0cb4843da15a65a953907c96bad658283f3c4419d6bcc56bf2789db16306adb2 binutils-2.33.1.tar.bz2 +a931a750d6feadacbeecb321d73925cd5ebb6dfa7eff0802984af3aef63759f4 gcc-9.2.0.tar.gz +5275bb04f4863a13516b2f39392ac5e272f5e1bb8057b18aec1c9b79d73d8fb2 gmp-6.1.2.tar.bz2 +6985c538143c1208dcb1ac42cedad6ff52e267b47e5f970183a3e75125b43c2e mpc-1.1.0.tar.gz +a4d97610ba8579d380b384b225187c250ef88cfe1d5e7226b89519374209b86b mpfr-4.0.1.tar.bz2 diff --git a/devshell.sh b/devshell.sh index 4dc54fa..5f83014 100755 --- a/devshell.sh +++ b/devshell.sh @@ -9,10 +9,16 @@ REPONAME=`basename $JEHANNE` JEHANNE_TOOLCHAIN=`dirname $JEHANNE` JEHANNE_TOOLCHAIN="$JEHANNE_TOOLCHAIN/$REPONAME.TOOLCHAIN" export JEHANNE_TOOLCHAIN +JEHANNE_TOOLCHAIN_CROSS="$JEHANNE_TOOLCHAIN/cross" +export JEHANNE_TOOLCHAIN_CROSS +JEHANNE_HACKING=$JEHANNE/hacking +export JEHANNE_HACKING -export PATH="$JEHANNE/hacking/bin:$PATH" export PATH="$JEHANNE_TOOLCHAIN/cross/posix/bin:$PATH" -#export CPATH="$JEHANNE_TOOLCHAIN/cross/posix/lib/gcc/x86_64-jehanne/9.2.0/include:$JEHANNE_TOOLCHAIN/cross/posix/lib/gcc/x86_64-jehanne/9.2.0/include-fixed" +export PATH="$JEHANNE_HACKING/bin:$PATH" +export PATH_CLONE=$PATH + + export ARCH=amd64 export TOOLPREFIX=x86_64-jehanne- diff --git a/rcmain b/rcmain new file mode 100644 index 0000000..461cb3e --- /dev/null +++ b/rcmain @@ -0,0 +1,51 @@ +# rcmain: Plan 9 on Unix version +if(~ $#home 0) home=$HOME +if(~ $#home 0) home=/ +if(~ $#ifs 0) ifs=' +' +switch($#prompt){ +case 0 + prompt=('% ' ' ') +case 1 + prompt=($prompt ' ') +} +if(~ $rcname ?.out ?.rc */?.rc */?.out) prompt=('broken! ' ' ') +if(flag p) path=(/bin /usr/bin) +if not{ + finit + # should be taken care of by rc now, but leave just in case +} +fn sigexit +if(! ~ $#cflag 0){ + if(flag l && test -r $home/lib/profile) . $home/lib/profile + status='' + eval $cflag + exit $status +} +if(flag i){ + if(~ $termprog 9term || ~ $termprog win){ + fn cd { + # builtin cd $1 && flag i && awd + # is not sufficient when running in a subshell + # that is rc -e (like mk uses!) + if(builtin cd $1){ + if(flag i) $PLAN9/bin/9 awd || status='' + status='' + } + } + $PLAN9/bin/9 awd + } + if(flag l && test -r $home/lib/profile) . $home/lib/profile + status='' + if(! ~ $#* 0) . $* + . -i '/dev/stdin' + exit $status +} +if(flag l && test -r $home/lib/profile) . $home/lib/profile +if(~ $#* 0){ + . /dev/stdin + exit $status +} +status='' +. $* +exit $status diff --git a/runOver9P.sh b/runOver9P.sh index fd38b62..edddc42 100755 --- a/runOver9P.sh +++ b/runOver9P.sh @@ -13,8 +13,7 @@ fi trap : 2 -$JEHANNE/hacking/bin/ufs -root=$JEHANNE & -# To debug ufs add: -d 5 > $JEHANNE/../ufs.log 2>&1 +$JEHANNE/hacking/bin/nc -p 5640 -l -e $JEHANNE/hacking/bin/start-u9fs.sh & ufspid=$! export machineflag=pc @@ -53,7 +52,7 @@ QEMU_USER=`whoami` cd $KERNDIR read -r cmd < 0 { - for _, i := range b.SourceFilesCmd { - largs := make([]string, 3) - largs[0] = i - largs[1] = "-o" - largs[2] = strings.Replace(filepath.Base(i), filepath.Ext(i), "", 1) - cmd := exec.Command(tools["cc"], append(largs, args...)...) - run(b, *shellhack, cmd) - } - return - } - if !isValueInList("-c", b.Cflags) { - args = append(args, "-o", b.Program) - } - cmd := exec.Command(tools["cc"], args...) - run(b, *shellhack, cmd) -} - -func link(b *build) { - if !isValueInList("-c", b.Cflags) { - return - } - log.Printf("Linking %s\n", b.name) - if len(b.SourceFilesCmd) > 0 { - for _, n := range b.SourceFilesCmd { - // Split off the last element of the file - var ext = filepath.Ext(n) - if len(ext) == 0 { - log.Fatalf("refusing to overwrite extension-less source file %v", n) - continue - } - n = n[:len(n)-len(ext)] - f := path.Base(n) - o := f[:len(f)] + ".o" - args := []string{"-o", n, o} - args = append(args, b.Oflags...) - args = append(args, b.Libs...) - run(b, *shellhack, exec.Command(tools["ld"], args...)) - } - return - } - args := []string{"-o", b.Program} - args = append(args, b.ObjectFiles...) - args = append(args, b.Oflags...) - args = append(args, b.Libs...) - run(b, *shellhack, exec.Command(tools["ld"], args...)) -} - -func install(b *build) { - if b.Install == "" { - return - } - - log.Printf("Installing %s\n", b.name) - failOn(os.MkdirAll(b.Install, 0755)) - - switch { - case len(b.SourceFilesCmd) > 0: - for _, n := range b.SourceFilesCmd { - ext := filepath.Ext(n) - exe := n[:len(n)-len(ext)] - move(exe, b.Install) - } - case len(b.Program) > 0: - move(b.Program, b.Install) - case len(b.Library) > 0: - ofiles := []string{} - for _, o := range b.ObjectFiles { - os.Rename(o, b.Library + "-" + o) - ofiles = append(ofiles, b.Library + "-" + o) - } - libpath := path.Join(b.Install, b.Library) - - args := append([]string{"-rs", libpath}, ofiles...) - run(b, *shellhack, exec.Command(tools["ar"], args...)) - run(b, *shellhack, exec.Command(tools["ranlib"], libpath)) - } -} - -func move(from, to string) { - final := path.Join(to, from) - log.Printf("move %s %s\n", from, final) - _ = os.Remove(final) - failOn(os.Link(from, final)) - failOn(os.Remove(from)) -} - -func run(b *build, pipe bool, cmd *exec.Cmd) { - if b != nil { - cmd.Env = append(os.Environ(), b.Env...) - } - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if pipe { - // Sh sends cmd to a shell. It's needed to enable $LD_PRELOAD tricks, see https://github.com/Harvey-OS/jehanne/issues/8#issuecomment-131235178 - shell := exec.Command(tools["sh"]) - shell.Env = cmd.Env - shell.Stderr = os.Stderr - shell.Stdout = os.Stdout - - commandString := cmd.Args[0] - commandString += " " + strings.Join(wrapInQuote(cmd.Args[1:]), " ") - shStdin, err := shell.StdinPipe() - if err != nil { - log.Fatalf("cannot pipe [%v] to %s: %v", commandString, tools["sh"], err) - } - go func() { - defer shStdin.Close() - io.WriteString(shStdin, commandString) - }() - - log.Printf("%q | %s\n", commandString, tools["sh"]) - failOn(shell.Run()) - return - } - log.Println(strings.Join(cmd.Args, " ")) - failOn(cmd.Run()) -} - -func projects(b *build, r []*regexp.Regexp) { - for _, v := range b.Projects { - f, _ := findBuildfile(v) - log.Printf("Doing %s\n", f) - project(f, r, b) - } -} - -// assumes we are in the wd of the project. -func project(bf string, which []*regexp.Regexp, container *build) { - cwd, err := os.Getwd() - failOn(err) - debug("Start new project cwd is %v", cwd) - defer os.Chdir(cwd) - dir := path.Dir(bf) - root := path.Base(bf) - debug("CD to %v and build using %v", dir, root) - failOn(os.Chdir(dir)) - builds := process(root, which) - debug("Processing %v: %d target", root, len(builds)) - for _, b := range builds { - debug("Processing %v: %v", b.name, b) - if container != nil { - b.Env = append(container.Env, b.Env...) - } - projects(&b, regexpAll) - for _, c := range b.Pre { - // this is a hack: we just pass the command through as an exec.Cmd - run(&b, true, exec.Command(c)) - } - envFunc := buildEnv(&b); - b.Program = os.Expand(b.Program, envFunc) - for i, s := range b.SourceFiles { - b.SourceFiles[i] = fromRoot(os.Expand(s, envFunc)); - } - for i, s := range b.SourceFilesCmd { - b.SourceFilesCmd[i] = fromRoot(os.Expand(s, envFunc)); - } - for i, s := range b.ObjectFiles { - b.ObjectFiles[i] = fromRoot(os.Expand(s, envFunc)); - } - buildkernel(&b) - if len(b.SourceFiles) > 0 || len(b.SourceFilesCmd) > 0 { - compile(&b) - } - if b.Program != "" || len(b.SourceFilesCmd) > 0 { - link(&b) - } - install(&b) - for _, c := range b.Post { - run(&b, true, exec.Command(c)) - } - } -} - -func main() { - // A small amount of setup is done in the paths*.go files. They are - // OS-specific path setup/manipulation. "jehanne" is set there and $PATH is - // adjusted. - var err error - findTools(os.Getenv("TOOLPREFIX")) - flag.Parse() - cwd, err = os.Getwd() - failOn(err) - - a := os.Getenv("ARCH") - if a == "" || !arch[a] { - s := []string{} - for i := range arch { - s = append(s, i) - } - log.Fatalf("You need to set the ARCH environment variable from: %v", s) - } - - // ensure this is exported, in case we used a default value - os.Setenv("JEHANNE", jehanne) - - if os.Getenv("LD_PRELOAD") != "" { - log.Println("Using shellhack") - *shellhack = true - } - - // If no args, assume 'build.json' - // Otherwise the first argument is either - // - the path to a json file - // - a directory containing a 'build.json' file - // - a regular expression to apply assuming 'build.json' - // Further arguments are regular expressions. - consumedArgs := 0; - bf := "" - if len(flag.Args()) == 0 { - f, err := findBuildfile("build.json") - failOn(err) - bf = f - } else { - f, err := findBuildfile(flag.Arg(0)) - failOn(err) - - if f == "" { - f, err := findBuildfile("build.json") - failOn(err) - bf = f - } else { - consumedArgs = 1 - bf = f - } - } - - re := []*regexp.Regexp{regexp.MustCompile(".")} - if len(flag.Args()) > consumedArgs { - re = re[:0] - for _, r := range flag.Args()[consumedArgs:] { - rx, err := regexp.Compile(r) - failOn(err) - re = append(re, rx) - } - } - project(bf, re, nil) -} - -func findTools(toolprefix string) { - var err error - for k, v := range tools { - if x := os.Getenv(strings.ToUpper(k)); x != "" { - v = x - } - if toolprefix != "" && v != "sh" && !strings.Contains(v, toolprefix) { - v = toolprefix + v; - } - v, err = exec.LookPath(v) - failOn(err) - tools[k] = v - } -} - -// disambiguate the buildfile argument -func findBuildfile(f string) (string, error) { - if strings.HasSuffix(f, ".json"){ - if fi, err := os.Stat(f); err == nil && !fi.IsDir() { - return f, nil - } - return "", fmt.Errorf("unable to find buildfile %s", f) - } - if strings.Contains(f, "/") { - return findBuildfile(path.Join(f, "build.json")) - } - return "", nil -} diff --git a/src/jehanne/cmd/build/codegen.go b/src/jehanne/cmd/build/codegen.go deleted file mode 100644 index 1c53bba..0000000 --- a/src/jehanne/cmd/build/codegen.go +++ /dev/null @@ -1,182 +0,0 @@ -package main - -import ( - "bytes" - "debug/elf" - "fmt" - "io/ioutil" - "os" - "os/exec" - "text/template" -) - -const kernconfTmpl = ` -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "io.h" - -void -rdb(void) -{ - splhi(); - iprint("rdb...not installed\n"); - for(;;); -} - -{{ range .Rootcodes }} -{{ . }} -{{ end }} - -{{ range .Config.Dev }}extern Dev {{ . }}devtab; -{{ end }} -Dev *devtab[] = { -{{ range .Config.Dev }} - &{{ . }}devtab, -{{ end }} - nil, -}; - -{{ range .Config.Link }}extern void {{ . }}link(void); -{{ end }} -void -links(void) -{ -{{ range .Rootnames }}addbootfile("{{ . }}", ramfs_{{ . }}_code, ramfs_{{ . }}_len); -{{ end }} -{{ range .Config.Link }}{{ . }}link(); -{{ end }} -} - -#include "../ip/ip.h" -{{ range .Config.Ip }}extern void {{ . }}init(Fs*); -{{ end }} -void (*ipprotoinit[])(Fs*) = { -{{ range .Config.Ip }} {{ . }}init, -{{ end }} - nil, -}; - -#include "../port/sd.h" -{{ range .Config.Sd }}extern SDifc {{ . }}ifc; -{{ end }} -SDifc* sdifc[] = { -{{ range .Config.Sd }} &{{ . }}ifc, -{{ end }} - nil, -}; - -{{ range .Config.Uart }}extern PhysUart {{ . }}physuart; -{{ end }} -PhysUart* physuart[] = { -{{ range .Config.Uart }} &{{ . }}physuart, -{{ end }} - nil, -}; - -#define Image IMAGE -#include -#include -#include -#include "screen.h" -{{ range .Config.VGA }}extern VGAdev {{ . }}dev; -{{ end }} -VGAdev* vgadev[] = { -{{ range .Config.VGA }} &{{ . }}dev, -{{ end }} - nil, -}; - -{{ range .Config.VGA }}extern VGAcur {{ . }}cur; -{{ end }} -VGAcur* vgacur[] = { -{{ range .Config.VGA }} &{{ . }}cur, -{{ end }} - nil, -}; - -{{ range .Config.Code }}{{ . }} -{{ end }} - -char* conffile = "{{ .Path }}"; - -` - -// These are the two big code generation functions. - -// data2c takes the file at path and creates a C byte array containing it. -func data2c(name string, path string) string { - var out []byte - var in []byte - - if elf, err := elf.Open(path); err == nil { - elf.Close() - cwd, err := os.Getwd() - tmpf, err := ioutil.TempFile(cwd, name) - failOn(err) - - run(nil, *shellhack, exec.Command(tools["strip"], "-o", tmpf.Name(), path)) - - in, err = ioutil.ReadAll(tmpf) - failOn(err) - - tmpf.Close() - os.Remove(tmpf.Name()) - } else { - var file *os.File - var err error - - file, err = os.Open(path) - failOn(err) - - in, err = ioutil.ReadAll(file) - failOn(err) - - file.Close() - } - - total := len(in) - - out = []byte(fmt.Sprintf("static unsigned char ramfs_%s_code[] = {\n", name)) - for len(in) > 0 { - for j := 0; j < 16 && len(in) > 0; j++ { - out = append(out, []byte(fmt.Sprintf("0x%02x, ", in[0]))...) - in = in[1:] - } - out = append(out, '\n') - } - - out = append(out, []byte(fmt.Sprintf("0,\n};\nint ramfs_%s_len = %v;\n", name, total))...) - - return string(out) -} - -// confcode creates a kernel configuration header. -func confcode(path string, kern *kernel) []byte { - var rootcodes []string - var rootnames []string - for name, path := range kern.Ramfiles { - code := data2c(name, fromRoot(path)) - rootcodes = append(rootcodes, code) - rootnames = append(rootnames, name) - } - - vars := struct { - Path string - Config kernconfig - Rootnames []string - Rootcodes []string - }{ - path, - kern.Config, - rootnames, - rootcodes, - } - tmpl := template.Must(template.New("kernconf").Parse(kernconfTmpl)) - codebuf := &bytes.Buffer{} - failOn(tmpl.Execute(codebuf, vars)) - return codebuf.Bytes() -} diff --git a/src/jehanne/cmd/build/doc.go b/src/jehanne/cmd/build/doc.go deleted file mode 100644 index 58bf91f..0000000 --- a/src/jehanne/cmd/build/doc.go +++ /dev/null @@ -1,184 +0,0 @@ -/* -BUILDFILE FORMAT - -A buildfile is a json object containing build objects. By convention, it's -broken out onto multiple lines indented by tabs, and the keys are TitleCased. - -The environment varibles JEHANNE and ARCH are guarenteed to be set for the -buildfile. PATH is modified so that "$JEHANNE/hacking" is included. - -Any key that takes a path or array of paths as its value has absolute paths -re-rooted to the jehanne tree and variables in the string expanded once. - -The shell commands in the "Pre" and "Post" steps must be in the subset of -syntax that's accepted by both POSIX sh and rc. Practically, this means -arguments with a "=" must be single-quoted, "test" must be called as -"test" (not "["), "if" statements may not have an "else" clause, "switch" -statements may not be used, "for" statements may only have one body command, -and redirection to a file descriptor cannont be used. - -BUILD OBJECT - -A build object has the following keys and types: - - Projects []string - Pre []string - Post []string - Cflags []string - Oflags []string - Include []string - SourceFiles []string - ObjectFiles []string - Libs []string - Env []string - SourceFilesCmd []string - Program string - Library string - Install string - Kernel kernel - -These are the steps taken, in order: - - Env - Include - Projects - Pre - Kernel - [compile] SourceFiles SourceFilesCmd Cflags Program - [link] ObjectFiles Libs Oflags Library - Install - Post - -"[compile]" and "[link]" are steps synthesized from the specified keys. - -The meaning of the keys is as follows: - -"Env" is an array of environment variables to be put in the environment of -every command run in a build. They are expanded once and only available for -use in other steps. - -"Include" is an array of buildfiles to "merge" into the current one. This -is done before other projects are built. - -"Projects" is an array of buildfiles to build in their entirety before -starting the current build. - -"Pre" is an array of commands to run before starting the build. - -"Kernel" is a kernel build object. See the kernel object section. - -"Cflags" is an array of flags to pass to the C compiler. They are in addition -to the standard flags of - - -std=c11 -c -I /$ARCH/include -I /sys/include -I . - -The standard include paths are re-rooted to the jehanne tree if not on a jehanne -system. - -"SourceFilesCmd" is an array of C files where each one should result in an -executable. If this key is provided, "SourceFiles" and "Program" are ignored. - -"SourceFiles" is an array of C files that will ultimately produce a single -binary or library, named by "Program" or "Library" respectively. - -"Program" is the name of the final executable for the files specified by -"SourceFiles". - -"Oflags" is an array of flags to pass to the linker. They are in addition -to the standard flags of - - -o $program $objfiles -L /$ARCH/lib $libs - -The lib path is re-rooted to the jehanne tree if not on a jehanne system. - -"ObjectFiles" is an array of strings specifying object files to be linked -into the final program specified by "Program". Any object files produced -by the preceeding "[compile]" step are automatically added to this before -beginning the "[link]" step. - -"Libs" is a an array of library arguments to pass to the linker. - -"Library" is the name of the archive resulting from bundling "SourceFiles" -into a library. The resulting archive has 'ranlib' run on it automatically. - -"Install" is a directory where the result of the "[link]" step is moved -to. If it does not exist, it is created. - -"Post" is an array of commands to run last during the build. - -KERNEL OBJECT - -A build object has the following keys and types: - - Systab string - Ramfiles map[string]string - Config { - Code []string - Dev []string - Ip []string - Link []string - Sd []string - Uart []string - VGA []string - } - -"Systab" is the header that defines the syscall table. - -"Ramfiles" is an object of name, path pairs of binaries at "path" that will -be baked into the kernel and available at a binary named "name". - -"Config" is an object used to generate the kernel configuration source. "Dev", -"Ip", "Sd", "Uart", "Link", and "VGA" control which drivers of the various -types are included. "Code" is lines of arbitrary C code. - -*/ -package main - -import ( - "flag" - "fmt" - "os" - "strings" -) - -var helptext = ` -The buildfile is looked for at these positions, in this order: - - ./$arg - ./$arg/build.json - /sys/src/$arg.json - /sys/src/$arg/build.json - -If the buildfile argument is not provided, it defaults to "build.json". - -After the buildfile, a number of regexps specifying targets may be provided. -If a target matches any supplied regexp, it is acted on. These regexps only -apply to the top-level buildfile. - -BUILDFILE - -See the build godoc for more information about the buildfile format. - -ENVIRONMENT - -ARCH is needed. Current acceptable vaules are: amd64 - -JEHANNE may be supplied to point at a jehanne tree. -The default on Jehanne is "/". -The default on Linux and OSX is to attempt to find the top level of a git -repository. -` - -func init() { - flag.Usage = func() { - fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) - fmt.Fprintf(os.Stderr, " %s [options] [buildfile] [target...]\n\n", os.Args[0]) - flag.PrintDefaults() - fmt.Fprintln(os.Stderr, helptext) - fmt.Fprintln(os.Stderr, "Tools to be used with current settings:") - fmt.Fprintf(os.Stderr, " prefix ($TOOLPREFIX): %q\n", os.Getenv("TOOLPREFIX")) - for k, v := range tools { - fmt.Fprintf(os.Stderr, " %s ($%s): %s\n", k, strings.ToUpper(k), v) - } - } -} diff --git a/src/jehanne/cmd/build/paths.go b/src/jehanne/cmd/build/paths.go deleted file mode 100644 index 083b1f1..0000000 --- a/src/jehanne/cmd/build/paths.go +++ /dev/null @@ -1,31 +0,0 @@ -// +build !jehanne - -package main - -import ( - "log" - "os" - "os/exec" - "strings" -) - -func init() { - jehanne = os.Getenv("JEHANNE") - if jehanne != "" { - return - } - // git is purely optional, for lazy people. - out, err := exec.Command("git", "rev-parse", "--show-toplevel").Output() - if err == nil { - jehanne = strings.TrimSpace(string(out)) - hackingAt := strings.LastIndex("/hacking", jehanne) - if(hackingAt >= 0){ - jehanne = jehanne[0:hackingAt] - } - } - if jehanne == "" { - log.Fatal("Set the JEHANNE environment variable or run from a git checkout.") - } - - os.Setenv("PATH", strings.Join([]string{fromRoot("/hacking"), os.Getenv("PATH")}, string(os.PathListSeparator))) -} diff --git a/src/jehanne/cmd/build/paths_harvey.go b/src/jehanne/cmd/build/paths_harvey.go deleted file mode 100644 index c293c4b..0000000 --- a/src/jehanne/cmd/build/paths_harvey.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build jehanne - -package main - -import ( - "os" - "strings" -) - -func init() { - jehanne = os.Getenv("JEHANNE") - if jehanne != "" { - return - } - jehanne = "/" - os.Setenv("path", strings.Join([]string{fromRoot("/util"), os.Getenv("path")}, string(os.PathListSeparator))) -} diff --git a/src/jehanne/cmd/convert/convert.go b/src/jehanne/cmd/convert/convert.go deleted file mode 100644 index 1632292..0000000 --- a/src/jehanne/cmd/convert/convert.go +++ /dev/null @@ -1,155 +0,0 @@ -package main - -import ( - "encoding/json" - "flag" - "io/ioutil" - "log" - "os" - "path/filepath" -) - -var config = struct { - Jehanne string - Args []string - Except map[string]bool - CmdName string - FullPath string - Src string - Uroot string - Cwd string - Bbsh string - - Goroot string - Gosrcroot string - Arch string - Goos string - Gopath string - TempDir string - Go string - Debug bool - Fail bool -}{ - Jehanne: os.Getenv("JEHANNE"), - Except: map[string]bool{"sysconf.json": true}, -} - -type fixup func(string, map[string]interface{}) - -func cflags(n string, jsmap map[string]interface{}) { - if _, ok := jsmap["Cflags"]; ok { - log.Printf("Deleting Cflags from %v", n) - delete(jsmap, "Cflags") - // TODO: once we have another ARCH, use it. - a := []string{"/arch/amd64/include/cflags.json"} - switch tval := jsmap["Include"].(type) { - case []interface{}: - for _, v := range tval { - a = append(a, v.(string)) - } - } - jsmap["Include"] = a - } -} - -func removeempty(n string, jsmap map[string]interface{}) { - for key, val := range jsmap { - switch tval := val.(type) { - case map[string]interface{}: - log.Printf("%s: tval %s", n, tval) - if len(tval) == 0 { - delete(jsmap, key) - } - case []interface{}: - if len(tval) == 0 { - delete(jsmap, key) - } - } - } -} - -func checkname(n string, jsmap map[string]interface{}) { - if _, ok := jsmap["Name"]; !ok { - log.Print("File %v has no \"Name\" key", n) - } -} - -func one(n string, f ...fixup) error { - buf, err := ioutil.ReadFile(n) - if err != nil { - return err - } - - var jsmap map[string]interface{} - if err := json.Unmarshal(buf, &jsmap); err != nil { - return err - } - if config.Debug { - log.Printf("%v: %v", n, jsmap) - } - - mapname := jsmap["Name"].(string) - delete(jsmap, "Name") - var nmap = make(map[string]map[string]interface{}) - nmap[mapname] = jsmap - buf, err = json.MarshalIndent(nmap, "", "\t") - if err != nil { - return err - } - buf = append(buf, '\n') - - if config.Debug { - os.Stdout.Write(buf) - } else { - ioutil.WriteFile(n, buf, 0666) - } - return nil -} - -func init() { - if config.Jehanne == "" { - log.Fatalf("Please set $JEHANNE") - } - - if len(config.Args) == 0 { - config.Args = []string{config.Jehanne} - } -} - -func main() { - var err error - - flag.BoolVar(&config.Debug, "d", true, "Enable debug prints") - flag.Parse() - config.Args = flag.Args() - for _, n := range config.Args { - err = filepath.Walk(n, func(name string, fi os.FileInfo, err error) error { - if err != nil { - return err - } - if fi.IsDir() { - return nil - } - n := fi.Name() - if len(n) < 5 || n[len(n)-5:] != ".json" { - return nil - } - if config.Except[fi.Name()] { - return nil - } - todo := []fixup{removeempty, checkname} - log.Printf("process %s", name) - err = one(name, todo...) - if err != nil { - log.Printf("%s: %s\n", name, err) - return err - } - return nil - }) - - if err != nil { - log.Fatal("%v", err) - - } - } -} diff --git a/src/jehanne/cmd/data2c/data2c.go b/src/jehanne/cmd/data2c/data2c.go deleted file mode 100644 index ab3b5d5..0000000 --- a/src/jehanne/cmd/data2c/data2c.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "io/ioutil" - "os" -) - -func main() { - flag.Parse() - a := flag.Args() - if len(a) != 2 { - fmt.Fprintf(os.Stderr, "[%v]usage: data2s name input-file (writes to stdout)\n", a) - os.Exit(1) - } - - n := a[0] - i := a[1] - in, err := ioutil.ReadFile(i) - if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.Exit(1) - } - - total := len(in) - - fmt.Printf("unsigned char %vcode[] = {\n", n) - for len(in) > 0 { - for j := 0; j < 16 && len(in) > 0; j++ { - fmt.Printf("0x%02x, ", in[0]) - in = in[1:] - } - fmt.Printf("\n") - - } - - fmt.Printf("0,\n};\nint %vlen = %v;\n", n, total) -} diff --git a/src/jehanne/cmd/elf2c/elf2c.go b/src/jehanne/cmd/elf2c/elf2c.go deleted file mode 100644 index 6cd8e06..0000000 --- a/src/jehanne/cmd/elf2c/elf2c.go +++ /dev/null @@ -1,113 +0,0 @@ -package main - -import ( - "bufio" - "debug/elf" - "flag" - "fmt" - "io" - "math" - "os" - "path" -) - -var dry = flag.Bool("dryrun", true, "don't really do it") - -func gencode(w io.Writer, n, t string, m []byte, start, end uint64) { - fmt.Fprintf(os.Stderr, "Write %v %v start %v end %v\n", n, t, start, end) - fmt.Fprintf(w, "int %v_%v_start = %v;\n", n, t, start) - fmt.Fprintf(w, "int %v_%v_end = %v;\n", n, t, end) - fmt.Fprintf(w, "int %v_%v_len = %v;\n", n, t, end-start) - fmt.Fprintf(w, "uint8_t %v_%v_out[] = {\n", n, t) - for i := uint64(start); i < end; i += 16 { - for j := uint64(0); i+j < end && j < 16; j++ { - fmt.Fprintf(w, "0x%02x, ", m[j+i]) - } - fmt.Fprintf(w, "\n") - } - fmt.Fprintf(w, "};\n") -} -func main() { - flag.Parse() - a := flag.Args() - for _, n := range a { - f, err := elf.Open(n) - if err != nil { - fmt.Printf("%v %v\n", n, err) - continue - } - var dataend, codeend, end uint64 - var datastart, codestart, start uint64 - datastart, codestart, start = math.MaxUint64, math.MaxUint64, math.MaxUint64 - mem := []byte{} - for _, v := range f.Progs { - if v.Type != elf.PT_LOAD { - continue - } - fmt.Fprintf(os.Stderr, "processing %v\n", v) - // MUST alignt to 2M page boundary. - // then MUST allocate a []byte that - // is the right size. And MUST - // see if by some off chance it - // joins to a pre-existing segment. - // It's easier than it seems. We produce ONE text - // array and ONE data array. So it's a matter of creating - // a virtual memory space with an assumed starting point of - // 0x200000, and filling it. We just grow that as needed. - - curstart := v.Vaddr & ^uint64(0xfff) // 0x1fffff) - curend := v.Vaddr + v.Memsz - fmt.Fprintf(os.Stderr, "s %x e %x\n", curstart, curend) - if curend > end { - nmem := make([]byte, curend) - copy(nmem, mem) - mem = nmem - } - if curstart < start { - start = curstart - } - - if v.Flags&elf.PF_X == elf.PF_X { - if curstart < codestart { - codestart = curstart - } - if curend > codeend { - codeend = curend - } - fmt.Fprintf(os.Stderr, "code s %v e %v\n", codestart, codeend) - } else { - if curstart < datastart { - datastart = curstart - } - if curend > dataend { - dataend = curend - } - fmt.Fprintf(os.Stderr, "data s %v e %v\n", datastart, dataend) - } - for i := uint64(0); i < v.Filesz; i++ { - if amt, err := v.ReadAt(mem[v.Vaddr+i:], int64(i)); err != nil && err != io.EOF { - fmt.Fprintf(os.Stderr, "%v: %v\n", amt, err) - os.Exit(1) - } else if amt == 0 { - if i < v.Filesz { - fmt.Fprintf(os.Stderr, "%v: Short read: %v of %v\n", v, i, v.Filesz) - os.Exit(1) - } - break - } else { - i = i + uint64(amt) - fmt.Fprintf(os.Stderr, "i now %v\n", i) - } - } - fmt.Fprintf(os.Stderr, "Processed %v\n", v) - } - fmt.Fprintf(os.Stderr, "gencode\n") - // Gen code to stdout. For each file, create an array, a start, and an end variable. - w := bufio.NewWriter(os.Stdout) - _, file := path.Split(n) - gencode(w, file, "code", mem, codestart, codeend) - gencode(w, file, "data", mem, datastart, dataend) - w.Flush() - } - -} diff --git a/src/jehanne/cmd/fetch/fetch.go b/src/jehanne/cmd/fetch/fetch.go deleted file mode 100644 index c258df3..0000000 --- a/src/jehanne/cmd/fetch/fetch.go +++ /dev/null @@ -1,197 +0,0 @@ -package main - -import ( - "archive/tar" - "bytes" - "compress/bzip2" - "compress/gzip" - "crypto/sha256" - "crypto/sha512" - "encoding/hex" - "encoding/json" - "hash" - "io" - "io/ioutil" - "log" - "net/http" - "os" - "os/exec" - "path" - "strings" -) - -const ( - dirPermissions = 0755 -) - -type Fetch struct { - Upstream string - Digest map[string]string - Compress string - RemovePrefix bool - Exclude []string -} - -func main() { - - j, err := ioutil.ReadFile("fetch.json") - if err != nil { - log.Fatal(err) - } - - fetches := make(map[string]Fetch) - if err := json.Unmarshal(j, &fetches); err != nil { - log.Fatal(err) - } - - for name, f := range(fetches) { - if _, err := os.Stat(name); err == nil { - log.Printf("Fetch: skip %v (already present)", name) - } else { - log.Printf("Fetch: %v from %v", name, f.Upstream) - if err := do(&f, name); err != nil { - log.Fatal(err) - } - } - } -} - -func do(f *Fetch, name string) error { - fname := fetch(f) - s, err := os.Open(fname) - if err != nil { - return err - } - defer os.Remove(fname) - - os.MkdirAll(name, dirPermissions) - - var unZ io.Reader - switch f.Compress { - case "gzip": - unZ, err = gzip.NewReader(s) - if err != nil { - return err - } - case "bzip2": - unZ = bzip2.NewReader(s) - default: - unZ = s - } - - ar := tar.NewReader(unZ) - h, err := ar.Next() -untar: - for ; err == nil; h, err = ar.Next() { - n := h.Name - if f.RemovePrefix { - n = strings.SplitN(n, "/", 2)[1] - } - for _, ex := range f.Exclude { - if strings.HasPrefix(n, ex) { - continue untar - } - } - n = path.Join(name, n) - if h.FileInfo().IsDir() { - os.MkdirAll(n, dirPermissions) - continue - } - os.MkdirAll(path.Dir(n), dirPermissions) - out, err := os.Create(n) - if err != nil { - log.Println(err) - continue - } - - if n, err := io.Copy(out, ar); n != h.Size || err != nil { - return err - } - out.Close() - if err := os.Chmod(n, h.FileInfo().Mode()); err != nil { - return err; - } - } - if err != io.EOF { - return err - } - return nil -} - -type match struct { - hash.Hash - Good []byte - Name string -} - -func (m match) OK() bool { - return bytes.Equal(m.Good, m.Hash.Sum(nil)) -} - -func fetch(v *Fetch) string { - if len(v.Digest) == 0 { - log.Fatal("no checksums specifed") - } - - f, err := ioutil.TempFile("", "cmdVendor") - if err != nil { - log.Fatal(err) - } - defer f.Close() - - req, err := http.NewRequest("GET", v.Upstream, nil) - if err != nil { - log.Fatal(err) - } - client := &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DisableCompression: true, - }, - } - res, err := client.Do(req) - if err != nil { - log.Fatal(err) - } - defer res.Body.Close() - - var digests []match - for k, v := range v.Digest { - g, err := hex.DecodeString(v) - if err != nil { - log.Fatal(err) - } - switch k { - case "sha224": - digests = append(digests, match{sha256.New224(), g, k}) - case "sha256": - digests = append(digests, match{sha256.New(), g, k}) - case "sha384": - digests = append(digests, match{sha512.New384(), g, k}) - case "sha512": - digests = append(digests, match{sha512.New(), g, k}) - } - } - ws := make([]io.Writer, len(digests)) - for i := range digests { - ws[i] = digests[i] - } - w := io.MultiWriter(ws...) - - if _, err := io.Copy(f, io.TeeReader(res.Body, w)); err != nil { - log.Fatal(err) - } - for _, h := range digests { - if !h.OK() { - log.Fatalf("mismatched %q hash\n\tWanted %x\n\tGot %x\n", h.Name, h.Good, h.Hash.Sum(nil)) - } - } - return f.Name() -} - -func run(exe string, arg ...string) error { - cmd := exec.Command(exe, arg...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - return cmd.Run() -} diff --git a/src/jehanne/cmd/jsonpretty/jsonpretty.go b/src/jehanne/cmd/jsonpretty/jsonpretty.go deleted file mode 100644 index 7938ba2..0000000 --- a/src/jehanne/cmd/jsonpretty/jsonpretty.go +++ /dev/null @@ -1,53 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" -) - -func main() { - if len(os.Args) < 2 { - fmt.Printf("usage: jsonpretty input.json [output.json]\n") - os.Exit(1) - } - - buf, err := ioutil.ReadFile(os.Args[1]) - if err != nil { - fmt.Printf("%v\n", err) - os.Exit(1) - } - - var jsmap map[string]interface{} - if err := json.Unmarshal(buf, &jsmap); err != nil { - fmt.Printf("%v\n", err) - os.Exit(1) - } - - for key, val := range jsmap { - switch tval := val.(type) { - case map[string]interface{}: - if len(tval) == 0 { - delete(jsmap, key) - } - case []interface{}: - if len(tval) == 0 { - delete(jsmap, key) - } - } - } - - buf, err = json.MarshalIndent(jsmap, "", "\t") - if err != nil { - fmt.Printf("%v\n", err) - os.Exit(1) - } - buf = append(buf, '\n') - - if len(os.Args) == 3 { - ioutil.WriteFile(os.Args[2], buf, 0666) - } else { - os.Stdout.Write(buf) - } -} diff --git a/src/jehanne/cmd/kpdump/kpdump.go b/src/jehanne/cmd/kpdump/kpdump.go deleted file mode 100644 index 74bbf16..0000000 --- a/src/jehanne/cmd/kpdump/kpdump.go +++ /dev/null @@ -1,115 +0,0 @@ -package main - -import ( - "debug/elf" - "encoding/binary" - "flag" - "fmt" - "io" - "math" - "os" -) - -const LRES = 3 - -var kernel = flag.String("k", "9k", "kernel name") - -func main() { - flag.Parse() - - n := flag.Args()[0] - d, err := os.Open(n) - if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.Exit(1) - } - f, err := elf.Open(*kernel) - if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.Exit(1) - } - - var codeend uint64 - var codestart uint64 = math.MaxUint64 - - for _, v := range f.Progs { - if v.Type != elf.PT_LOAD { - continue - } - fmt.Fprintf(os.Stderr, "processing %v\n", v) - // MUST alignt to 2M page boundary. - // then MUST allocate a []byte that - // is the right size. And MUST - // see if by some off chance it - // joins to a pre-existing segment. - // It's easier than it seems. We produce ONE text - // array and ONE data array. So it's a matter of creating - // a virtual memory space with an assumed starting point of - // 0x200000, and filling it. We just grow that as needed. - - curstart := v.Vaddr - curend := v.Vaddr + v.Memsz - // magic numbers, BAH! - if curstart < uint64(0xffffffff00000000) { - curstart += 0xfffffffff0000000 - curend += 0xfffffffff0000000 - } - fmt.Fprintf(os.Stderr, "s %x e %x\n", curstart, curend) - if v.Flags&elf.PF_X == elf.PF_X { - if curstart < codestart { - codestart = curstart - } - if curend > codeend { - codeend = curend - } - fmt.Fprintf(os.Stderr, "code s %x e %x\n", codestart, codeend) - } - } - fmt.Fprintf(os.Stderr, "code s %x e %x\n", codestart, codeend) - s, err := f.Symbols() - if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.Exit(1) - } - // maybe we should stop doing LRES ... - symname := make([]string, codeend-codestart) - for i := range symname { - symname[i] = fmt.Sprintf("[0x%x]", codestart+uint64(i)) - } - for _, v := range s { - vstart := v.Value - vend := v.Value + v.Size - if v.Value > codeend { - continue - } - if v.Value+v.Size < codestart { - continue - } - if vstart < codestart { - v.Value = codestart - } - if vend > codeend { - vend = codeend - } - for i := vstart; i < vend; i++ { - symname[i-codestart] = v.Name - } - } - symname[0] = "Total ms" - symname[1< 0 { - fmt.Printf("%s %d\n", symname[pc-codestart], count) - } - pc += (1 << LRES) - } -} diff --git a/src/jehanne/cmd/ksyscalls/ksyscalls.go b/src/jehanne/cmd/ksyscalls/ksyscalls.go deleted file mode 100644 index 0c6abbd..0000000 --- a/src/jehanne/cmd/ksyscalls/ksyscalls.go +++ /dev/null @@ -1,385 +0,0 @@ -/* - * This file is part of Jehanne. - * - * Copyright (C) 2016 Giacomo Tesio - * - * Jehanne is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * Jehanne is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Jehanne. If not, see . - */ -package main - -import ( - "encoding/json" - "flag" - "fmt" - "io/ioutil" - "log" - "os" - "text/template" -) - -type SyscallConf struct { - Ret []string - Args []string - Name string - Id uint32 -} - -type Sysconf struct { - Syscalls []SyscallConf -} - -func usage(msg string) { - fmt.Fprint(os.Stderr, msg) - fmt.Fprint(os.Stderr, "Usage: ksyscalls path/to/sysconf.json\n") - flag.PrintDefaults() - os.Exit(1) -} - -type SyscallWrapper struct { - Id uint32 - Name string - Vars []string - CommonCode string - ExecCode string - EntryPrint string - ExitPrint string - SysRetField string - DefaultRet string -} - -type KernelCode struct { - Externs []string - Wrappers []SyscallWrapper -} - -func uregArg(index int) string{ - switch(index){ - case 0: - return "di"; - case 1: - return "si"; - case 2: - return "dx"; - case 3: - return "r10"; - case 4: - return "r8"; - case 5: - return "r9"; - } - return "" -} - -func sysret(t string) string { - switch(t){ - case "int", "int32_t": - return "i" - case "long", "int64_t": - return "vl" - case "uintptr_t", "void": - return "p" - case "void*", "char*", "char**", "uint8_t*", "int32_t*", "uint64_t*", "int64_t*": - return "v" - } - return " [?? " + t + "]" -} - -func formatArg(i int, t string) string{ - switch(t){ - case "int", "int32_t": - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%d\", a%d);\n", i) - case "unsigned int", "uint32_t": - /* unsigned int is reserved for flags */ - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%#ux\", a%d);\n", i) - case "long", "int64_t": - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%lld\", a%d);\n", i) - case "unsigned long", "uint64_t": - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%#lud\", a%d);\n", i) - case "void*", "uint8_t*", "const void*", "const uint8_t*": - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%#p\", a%d);\n", i) - case "int32_t*", "int*", "const int32_t*", "const int*": - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%#p(%%d)\", a%d, a%d);\n", i, i) - case "const char*", "char*": - return fmt.Sprintf("\tfmtuserstring(fmt, a%d);\n", i) - case "const char**", "char**": - return fmt.Sprintf("\tfmtuserstringlist(fmt, a%d);\n", i); - } - return " [?? " + t + "]" -} - -func formatRet(t string) string{ - switch(t){ - case "int", "int32_t": - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%d\", ret->%s);\n", sysret(t)) - case "unsigned int", "uint32_t": - /* unsigned int is reserved for flags */ - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%#ux\", ret->%s);\n", sysret(t)) - case "long", "int64_t": - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%lld\", ret->%s);\n", sysret(t)) - case "unsigned long", "uint64_t", "void": - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%#llud\", ret->%s);\n", sysret(t)) - case "void*", "uintptr_t", "const void*", "const uintptr_t": - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%#p\", ret->%s);\n", sysret(t)) - case "int32_t*", "int*", "const int32_t*", "const int*": - return fmt.Sprintf("\tjehanne_fmtprint(fmt, \" %%#p(%%d)\", ret->%s, *ret->%s);\n", sysret(t), sysret(t)) - } - return " [?? " + t + "]" -} - -func generateKernelCode(calls []SyscallConf){ - code := new(KernelCode) - - for _, call := range(calls) { - /* extern definitions */ - ext := "extern " + call.Ret[0] + " sys" + call.Name + "(" - if len(call.Args) == 0 { - ext += "void"; - } else { - for i, a := range(call.Args){ - if i > 0 { - ext += ", " - } - ext += fmt.Sprintf("%s", a) - } - } - ext += ");\n" - - wcall := new(SyscallWrapper) - wcall.Id = call.Id - wcall.Name = call.Name - wcall.SysRetField = sysret(call.Ret[0]) - wcall.DefaultRet = fmt.Sprintf("ret.%s = (%s)-1;", wcall.SysRetField, call.Ret[0]) - - for i, a := range(call.Args){ - wcall.Vars = append(wcall.Vars, fmt.Sprintf("%s a%v;", a, i)) - wcall.CommonCode += fmt.Sprintf("\ta%v = (%s)ureg->%s;\n", i, a, uregArg(i)) - } - wcall.ExecCode += "\tret->" + wcall.SysRetField + " = sys" + call.Name + "(" - for i, _ := range(call.Args){ - if i > 0 { - wcall.ExecCode += ", " - } - wcall.ExecCode += fmt.Sprintf("a%v", i) - } - wcall.ExecCode += ");" - - if call.Name == "pwrite"{ - wcall.EntryPrint += formatArg(0, call.Args[0]) - wcall.EntryPrint += "\tfmtrwdata(fmt, (char*)a1, MIN(a2, 64));\n" - wcall.EntryPrint += formatArg(2, call.Args[2]) - wcall.EntryPrint += formatArg(3, call.Args[3]) - } else { - for i, a := range(call.Args){ - wcall.EntryPrint += formatArg(i, a) - } - } - - wcall.ExitPrint += formatRet(call.Ret[0]) - if call.Name == "pread"{ - wcall.ExitPrint += fmt.Sprintf("\tfmtrwdata(fmt, (char*)ureg->%s, MIN(ureg->%s, 64));\n", uregArg(1), uregArg(2)) - } else if call.Name == "fd2path"{ - wcall.ExitPrint += fmt.Sprintf("\tfmtrwdata(fmt, (char*)ureg->%s, MIN(ureg->%s, 64));\n", uregArg(1), uregArg(2)) - } else if call.Name == "await"{ - wcall.ExitPrint += fmt.Sprintf("\tfmtrwdata(fmt, (char*)ureg->%s, MIN(ureg->%s, 64));\n", uregArg(0), uregArg(1)) - } else if call.Name == "errstr"{ - wcall.ExitPrint += fmt.Sprintf("\tfmtrwdata(fmt, (char*)ureg->%s, MIN(ureg->%s, 64));\n", uregArg(0), uregArg(1)) - } - - code.Wrappers = append(code.Wrappers, *wcall) - code.Externs = append(code.Externs, ext) - } - - tmpl, err := template.New("systab.c").Parse(`/* - * This file is part of Jehanne. - * - * Copyright (C) 2016 Giacomo Tesio - * - * Jehanne is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * Jehanne is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Jehanne. If not, see . - */ -/* automatically generated by ksyscalls */ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "ureg.h" - -extern void fmtrwdata(Fmt* f, char* a, int n); -extern void fmtuserstring(Fmt* f, const char* a); -extern void fmtuserstringlist(Fmt* f, const char** argv); - -{{ range .Externs }}{{.}}{{ end }} -{{ range .Wrappers }} -static void -wrap_{{ .Name }}(ScRet* ret, Ureg* ureg) -{ - {{ range .Vars }}{{.}} - {{ end }} -{{ .CommonCode }} -{{ .ExecCode }} -} -{{ end }} -int nsyscall = {{len .Wrappers}}; - -ScRet -default_syscall_ret(int syscall) -{ - static ScRet zero; - ScRet ret = zero; - switch(syscall){ - {{ range .Wrappers }}case {{ .Id }}: - {{ .DefaultRet }} - break; - {{ end }} - default: - ret.vl = -1; - break; - } - return ret; -} - -char* -syscall_name(int syscall) -{ - switch(syscall){ - {{ range .Wrappers }}case {{ .Id }}: - return "{{ .Name }}"; - {{ end }} - default: - return nil; - } -} - -void -dispatch_syscall(int syscall, Ureg* ureg, ScRet* ret) -{ - switch(syscall){ - {{ range .Wrappers }}case {{ .Id }}: - wrap_{{ .Name }}(ret, ureg); - break; - {{ end }} - default: - panic("dispatch_syscall: bad sys call number %d pc %#p\n", syscall, ureg->ip); - } -} - -{{ range .Wrappers }} -static void -enter_{{ .Name }}(Fmt* fmt, Ureg* ureg) -{ - {{ range .Vars }}{{.}} - {{ end }} -{{ .CommonCode }} - jehanne_fmtprint(fmt, "{{ .Name }} %#p >", ureg->ip); - if(up->notified) - jehanne_fmtprint(fmt, "!"); -{{ .EntryPrint }} - jehanne_fmtprint(fmt, "\n"); -} -{{ end }} - -char* -syscallfmt(int syscall, Ureg* ureg) -{ - Fmt fmt; - jehanne_fmtstrinit(&fmt); - jehanne_fmtprint(&fmt, "%d %s ", up->pid, up->text); - - switch(syscall){ - {{ range .Wrappers }}case {{ .Id }}: - enter_{{ .Name }}(&fmt, ureg); - break; - {{ end }} - default: - panic("syscallfmt: bad sys call number %d pc %#p\n", syscall, ureg->ip); - } - - return jehanne_fmtstrflush(&fmt); -} - -{{ range .Wrappers }} -static void -exit_{{ .Name }}(Fmt* fmt, Ureg* ureg, ScRet* ret) -{ - jehanne_fmtprint(fmt, "{{ .Name }} %#p <", ureg->ip); - if(up->notified) - jehanne_fmtprint(fmt, "!"); -{{ .ExitPrint }} -} -{{ end }} - -char* -sysretfmt(int syscall, Ureg* ureg, ScRet* ret, uint64_t start, uint64_t stop) -{ - Fmt fmt; - jehanne_fmtstrinit(&fmt); - jehanne_fmtprint(&fmt, "%d %s ", up->pid, up->text); - - switch(syscall){ - {{ range .Wrappers }}case {{ .Id }}: - exit_{{ .Name }}(&fmt, ureg, ret); - break; - {{ end }} - default: - panic("sysretfmt: bad sys call number %d pc %#p\n", syscall, ureg->ip); - } - - if(0 > ret->vl){ - jehanne_fmtprint(&fmt, " %s %#llud %#llud\n", up->syserrstr, start, stop-start); - } else { - jehanne_fmtprint(&fmt, " \"\" %#llud %#llud\n", start, stop-start); - } - - return jehanne_fmtstrflush(&fmt); -} - -`) - err = tmpl.Execute(os.Stdout, code) - if err != nil { - log.Fatal(err) - } -} - -func main() { - - flag.Parse() - - if flag.NArg() != 1 { - usage("no path to sysconf.json") - } - - buf, err := ioutil.ReadFile(flag.Arg(0)) - if err != nil { - log.Fatal(err) - } - - var sysconf Sysconf - err = json.Unmarshal(buf, &sysconf) - if err != nil { - log.Fatal(err) - } - - generateKernelCode(sysconf.Syscalls) - -} diff --git a/src/jehanne/cmd/mksys/mksys.go b/src/jehanne/cmd/mksys/mksys.go deleted file mode 100644 index 0bc68ac..0000000 --- a/src/jehanne/cmd/mksys/mksys.go +++ /dev/null @@ -1,325 +0,0 @@ -/* - * This file is part of the UCB release of Plan 9. It is subject to the license - * terms in the LICENSE file found in the top-level directory of this - * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No - * part of the UCB release of Plan 9, including this file, may be copied, - * modified, propagated, or distributed except according to the terms contained - * in the LICENSE file. - */ - -package main - -import ( - "encoding/json" - "flag" - "fmt" - "io/ioutil" - "log" - "os" - "path" - "strings" - "text/template" -) - -type Syscall struct { - Ret []string - Args []string - Name string - Id uint32 - Define string - Sysname string - Libname string - Fudge string `json:"-"` - GoArgs []string `json:"-"` - Ret0 string `json:"-"` -} - -type Syserror struct { - Name string - String string - Id uint32 -} - -type Bootmethods struct { - Name string - Config string - Connect string - Arg string -} - -type Sysconf struct { - Syscalls []Syscall - Syserrors []Syserror - Bootmethods []Bootmethods -} - -var mode = flag.String("mode", "", "must be one of: sys.h, sysdecl.h, syscallfiles, systab.c, error.h, errstr.h, sys_jehanne.s, sysnum.go") -var outpath = flag.String("o", "", "path/to/output.c") - -func usage(msg string) { - fmt.Fprint(os.Stderr, msg) - fmt.Fprint(os.Stderr, "Usage: mksys [-o outpath] -mode=MODE path/to/sysconf.json\n") - flag.PrintDefaults() - os.Exit(1) -} - -func main() { - - flag.Parse() - - if flag.NArg() != 1 { - usage("no path to sysconf.json") - } - - outfile := os.Stdout - if *mode != "syscallfiles" && *outpath != "" { - of, err := os.Create(*outpath) - if err != nil { - log.Fatal(err) - } - outfile = of - } - - buf, err := ioutil.ReadFile(flag.Arg(0)) - if err != nil { - log.Fatal(err) - } - - var sysconf Sysconf - err = json.Unmarshal(buf, &sysconf) - if err != nil { - log.Fatal(err) - } - - syscalls := sysconf.Syscalls - syserrors := sysconf.Syserrors - bootmethods := sysconf.Bootmethods - for i := range syscalls { - if syscalls[i].Define == "" { - syscalls[i].Define = strings.ToUpper(syscalls[i].Name) - } - if syscalls[i].Sysname == "" { - syscalls[i].Sysname = "sys" + syscalls[i].Name - } - if syscalls[i].Libname == "" { - syscalls[i].Libname = syscalls[i].Name - } - } - - switch *mode { - case "sys_jehanne.s": - if os.Getenv("ARCH") != "amd64" { - usage("ARCH unsupported or not set") - } - syscallargs := []string{"DI", "SI", "DX", "R10", "R8", "R9"} - //funcallregs := []string{ "DI", "SI", "DX", "CX", "R8", "R9" }; - for i := range syscalls { - goargs := []string{} - fpoff := 0 - for k := range syscalls[i].Args { - switch syscalls[i].Args[k] { - case "int32_t", "uint32_t": - goargs = append(goargs, fmt.Sprintf("MOVL arg%d+%d(FP), %s", k, fpoff, syscallargs[k])) - fpoff += 4 - case "void*", "char*", "char**", "uint8_t*", "int32_t*", "uint64_t*", "int64_t*", "int64_t": - fpoff = (fpoff + 7) & ^7 - goargs = append(goargs, fmt.Sprintf("MOVQ arg%d+%d(FP), %s", k, fpoff, syscallargs[k])) - fpoff += 8 - default: - log.Fatalf("unsupported arg %s in syscall: %v", syscalls[i].Args[k], syscalls[i]) - } - } - syscalls[i].GoArgs = goargs - switch syscalls[i].Ret[0] { - case "int32_t", "uint32_t": - syscalls[i].Ret0 = fmt.Sprintf("MOVL AX, ret+%d(FP)", fpoff) - fpoff += 4 - case "void*", "char*", "char**", "uint8_t*", "int32_t*", "uint64_t*", "int64_t*", "int64_t": - fpoff = (fpoff + 7) & ^7 - syscalls[i].Ret0 = fmt.Sprintf("MOVQ AX, ret+%d(FP)", fpoff) - fpoff += 8 - default: - log.Fatalf("unsupported Ret[0] in syscall: %v", syscalls[i]) - } - } - tmpl, err := template.New("sys_jehanne.s").Parse(`/* automatically generated by mksys */ -/* System calls for AMD64, Jehanne */ -#include "go_asm.h" -#include "go_tls.h" -#include "textflag.h" -{{ range . }} -TEXT runtimeĀ·{{ .Libname }}(SB),NOSPLIT,$0 -{{ range .GoArgs }} {{ . }} -{{ end }} MOVQ ${{ .Id }}, AX - SYSCALL - {{ .Ret0 }} - RET -{{ end }} -`) - if err != nil { - log.Fatal(err) - } - - err = tmpl.Execute(outfile, syscalls) - if err != nil { - log.Fatal(err) - } - - case "syscallfiles": - if os.Getenv("ARCH") != "amd64" { - usage("ARCH unsupported or not set") - } - tmpl, err := template.New("syscall.s").Parse(`/* automatically generated by mksys */ -.globl {{ .Libname }} -{{ .Libname }}: - movq %rcx, %r10 /* rcx gets smashed by systenter. Use r10.*/ - movq ${{ .Id }},%rax /* Put the system call into rax, just like linux. */ - syscall - ret -`) - if err != nil { - log.Fatal(err) - } - - for i := range syscalls { - - path := path.Join(*outpath, syscalls[i].Libname+".s") - file, err := os.Create(path) - if err != nil { - log.Fatal(err) - } - - err = tmpl.Execute(file, syscalls[i]) - if err != nil { - log.Fatal(err) - } - - err = file.Close() - if err != nil { - log.Fatal(err) - } - } - case "sysnum.go": - tmpl, err := template.New("sysnum.go").Parse(`// automatically generated by mksys -package syscall - -const( -{{ range . }} SYS_{{ .Define }} = {{ .Id }} -{{ end }} -) -`) - err = tmpl.Execute(outfile, syscalls) - if err != nil { - log.Fatal(err) - } - - case "sys.h": - tmpl, err := template.New("sys.h").Parse(`/* automatically generated by mksys */ -{{ range . }}#define {{ .Define }} {{ .Id }} -{{ end }} -`) - err = tmpl.Execute(outfile, syscalls) - if err != nil { - log.Fatal(err) - } - - case "sysdecl.h": - tmpl, err := template.New("sysdecl.h").Parse(`/* automatically generated by mksys */ -{{ range . }}extern {{ .Ret0 }} {{ .Libname }}({{ range $i, $e := .Args }}{{ if $i }}, {{ end }}{{ $e }}{{ end }}); -{{ end }} -`) - err = tmpl.Execute(outfile, syscalls) - if err != nil { - log.Fatal(err) - } - - case "systab.c": - for i := range syscalls { - var fudge string - switch syscalls[i].Ret[0] { - case "int32_t": - fudge = "{ .i = -1 }" - case "int64_t": - fudge = "{ .vl = -1ll }" - case "void*", "char*": - fudge = "{ .v = (void*)-1ll }" - default: - log.Fatalf("unsupported Ret[0] in syscall: %v", syscalls[i]) - } - if syscalls[i].Fudge == "" { - syscalls[i].Fudge = fudge - } - - syscalls[i].Ret0 = syscalls[i].Ret[0] - } - tmpl, err := template.New("systab.c").Parse(`/* automatically generated by mksys */ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include <9syscall/sys.h> - -{{ range . }}extern void {{ .Sysname }}(ScRet*, ScArg, ScArg, ScArg, ScArg, ScArg, ScArg); -{{ end }} -Systab systab[] = { -{{ range . }}[{{ .Define }}] { "{{ .Name }}", {{ .Sysname }}, {{ .Fudge }} }, -{{ end }} -}; -int nsyscall = nelem(systab); -`) - err = tmpl.Execute(outfile, syscalls) - if err != nil { - log.Fatal(err) - } - - case "error.h": - tmpl, err := template.New("error.h").Parse(`/* automatically generated by mksys */ -{{ range . }}extern char {{ .Name }}[]; /* {{ .String }} */ -{{ end }} -`) - err = tmpl.Execute(outfile, syserrors) - if err != nil { - log.Fatal(err) - } - - case "errstr.h": - tmpl, err := template.New("errstr.h").Parse(`/* automatically generated by mksys */ -{{ range . }}char {{ .Name }}[] = "{{ .String }}"; -{{ end }} -`) - err = tmpl.Execute(outfile, syserrors) - if err != nil { - log.Fatal(err) - } - case "bootamd64cpu.c": - tmpl, err := template.New("bootamd64cpu.c").Parse(`/* automatically generated by mksys */ -#include -#include - -#include "../boot/boot.h" - -Method method[] = { -{{ range . }}{ "{{.Name}}", {{.Config}}, {{.Connect}}, "{{.Arg}}", }, -{{ end }} - { nil }, -}; - -int cpuflag = 1; -char* rootdir = "/root"; -char* bootdisk = "#S/sdE0/"; -extern void boot(int, char**); - -void -main(int argc, char **argv) -{ - boot(argc, argv); -} -int (*cfs)(int) = 0; -`) - err = tmpl.Execute(outfile, bootmethods) - if err != nil { - log.Fatal(err) - } - } -} diff --git a/src/jehanne/cmd/op2/op2.go b/src/jehanne/cmd/op2/op2.go deleted file mode 100644 index 045d87f..0000000 --- a/src/jehanne/cmd/op2/op2.go +++ /dev/null @@ -1,107 +0,0 @@ -package main - -import ( - "encoding/binary" - "fmt" - "io" - "os" -) - -/* -first word -high 8 bits is ee, which is an invalid address on amd64. -next 8 bits is protocol version -next 16 bits is unused, MBZ. Later, we can make it a packet type. -next 16 bits is core id -next 8 bits is unused -next 8 bits is # words following. - -second word is time in ns. (soon to be tsc ticks) - -Third and following words are PCs, there must be at least one of them. -*/ -type sample struct { - Wordcount, _ uint8 - Coreid uint16 - _ uint16 - Version, Marker uint8 - Ns uint64 -} - -type backtrace struct { - Pcs []uint64 -} - -/* the docs lie. Perl expects Count to be zero. I only wasted a day figuring this out. */ -type hdr struct { - Count, Slots, Format, Period, Padding uint64 -} - -type record struct { - Count, Size uint64 - Pcs []uint64 -} - -type trailer struct { - Zero, One, Zeroh uint64 -} - -func main() { - var s sample - - r := io.Reader(os.Stdin) - w := io.Writer(os.Stdout) - - records := make(map[string]uint64, 16384) - backtraces := make(map[string][]uint64, 1024) - - /* ignore the documentation, it's wrong, first word must be zero. - * the perl code that figures word length depends on it. - */ - hdr := hdr{0, 3, 0, 10000, 0} - trailer := trailer{0, 1, 0} - start := uint64(0) - end := start - nsamples := end - for binary.Read(r, binary.LittleEndian, &s) == nil { - numpcs := int(s.Wordcount) - bt := make([]uint64, numpcs) - binary.Read(r, binary.LittleEndian, &bt) - //fmt.Printf("%v\n", bt) - record := "" - /* Fix the symbols. pprof was unhappy about the 0xfffffff. - * N.B. The fact that we have to mess with the bt values - * is the reason we did not write a stringer for bt. - */ - for i := range bt { - bt[i] = bt[i] & ((uint64(1) << 32) - 1) - record = record + fmt.Sprintf("0x%x ", bt[i]) - } - records[record]++ - backtraces[record] = bt - //fmt.Printf("%v %d %d %x %v record %v\n", s, s.Wordcount, s.Coreid, s.Ns, bt, record) - /* how sad, once we go to ticks this gets ugly. */ - if start == 0 { - start = s.Ns - } - end = s.Ns - nsamples++ - } - /* we'll need to fix this once we go to ticks. */ - hdr.Period = (end - start) / nsamples - hdr.Count = uint64(0) // !@$@!#$!@#$len(records)) - //fmt.Printf("start %v end %v nsamples %d period %d\n", start, end, nsamples, hdr.Period) - binary.Write(w, binary.LittleEndian, &hdr) - out := make([]uint64, 2) - /* note that the backtrace length varies. But we're good with that. */ - for key, v := range records { - bt := backtraces[key] - out[0] = v - out[1] = uint64(len(bt)) - dump := append(out, bt...) - //fmt.Printf("dump %v\n", dump) - binary.Write(w, binary.LittleEndian, &dump) - } - binary.Write(w, binary.LittleEndian, &trailer) - -} diff --git a/src/jehanne/cmd/preen/.gitignore b/src/jehanne/cmd/preen/.gitignore deleted file mode 100644 index 33e5349..0000000 --- a/src/jehanne/cmd/preen/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/preen diff --git a/src/jehanne/cmd/preen/preen.go b/src/jehanne/cmd/preen/preen.go deleted file mode 100644 index 78a0216..0000000 --- a/src/jehanne/cmd/preen/preen.go +++ /dev/null @@ -1,157 +0,0 @@ -package main - -import ( - "encoding/json" - "flag" - "io/ioutil" - "log" - "os" - "path/filepath" -) - -var config = struct { - Jehanne string - Args []string - Except map[string]bool - CmdName string - FullPath string - Src string - Uroot string - Cwd string - Bbsh string - - Goroot string - Gosrcroot string - Arch string - Goos string - Gopath string - TempDir string - Go string - Debug bool - Fail bool -}{ - Jehanne: os.Getenv("JEHANNE"), - Except: map[string]bool{"cflags.json": true, "9": true, "libauthcmd.json": true, "awk.json": true, "bzip2": true, "klibc.json": true, "kcmds.json": true, "klib.json": true, "kernel.json": true}, -} - -type fixup func(string, map[string]interface{}) - -func cflags(n string, jsmap map[string]interface{}) { - if _, ok := jsmap["Cflags"]; ok { - log.Printf("Deleting Cflags from %v", n) - delete(jsmap, "Cflags") - // TODO: once we have another ARCH, use it. - a := []string{"/arch/amd64/include/cflags.json"} - switch tval := jsmap["Include"].(type) { - case []interface{}: - for _, v := range tval { - a = append(a, v.(string)) - } - } - jsmap["Include"] = a - } -} - -func removeempty(n string, jsmap map[string]interface{}) { - for key, val := range jsmap { - switch tval := val.(type) { - case map[string]interface{}: - log.Printf("%s: tval %s", n, tval) - if len(tval) == 0 { - delete(jsmap, key) - } - case []interface{}: - if len(tval) == 0 { - delete(jsmap, key) - } - } - } -} - -func checkname(n string, jsmap map[string]interface{}) { - if _, ok := jsmap["Name"]; !ok { - log.Print("File %v has no \"Name\" key", n) - } -} - -func one(n string, f ...fixup) error { - buf, err := ioutil.ReadFile(n) - if err != nil { - return err - } - - var jsmap map[string]interface{} - if err := json.Unmarshal(buf, &jsmap); err != nil { - return err - } - if config.Debug { - log.Printf("%v: %v", n, jsmap) - } - - for _, d := range f { - d(n, jsmap) - } - buf, err = json.MarshalIndent(jsmap, "", "\t") - if err != nil { - return err - } - buf = append(buf, '\n') - - if config.Debug { - os.Stdout.Write(buf) - } else { - ioutil.WriteFile(n, buf, 0666) - } - return nil -} - -func init() { - if config.Jehanne == "" { - log.Fatalf("Please set $JEHANNE") - } - - if len(config.Args) == 0 { - config.Args = []string{config.Jehanne} - } -} - -func main() { - var err error - - flag.BoolVar(&config.Debug, "d", true, "Enable debug prints") - flag.Parse() - config.Args = flag.Args() - for _, n := range config.Args { - err = filepath.Walk(n, func(name string, fi os.FileInfo, err error) error { - if err != nil { - return err - } - if fi.IsDir() { - if config.Except[fi.Name()] { - return filepath.SkipDir - } - return nil - } - n := fi.Name() - if len(n) < 5 || n[len(n)-5:] != ".json" { - return nil - } - todo := []fixup{cflags, removeempty, checkname} - if config.Except[n] { - todo = todo[1:] - } - log.Printf("process %s", name) - err = one(name, todo...) - if err != nil { - log.Printf("%s: %s\n", name, err) - return err - } - return nil - }) - - if err != nil { - log.Fatal("%v", err) - - } - } -} diff --git a/src/jehanne/cmd/profile/profile.go b/src/jehanne/cmd/profile/profile.go deleted file mode 100644 index 17573b5..0000000 --- a/src/jehanne/cmd/profile/profile.go +++ /dev/null @@ -1,131 +0,0 @@ -package main - -import ( - "bytes" - "debug/elf" - "encoding/binary" - "flag" - "fmt" - "io" - "io/ioutil" - "os" - "sort" -) - -type Header struct { - Sz byte - _ byte - Core uint16 - _ uint16 - Ver byte - Sig byte - Time uint64 -} - -type pc uint64 - -type Record struct { - Header - pcs []pc -} - - -type Symbol struct { - Addr uint64 - Name string -} - -type Symbols []*Symbol - -func (s Symbols) Len() int { return len(s) } -func (s Symbols) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -type ByAddress struct{ Symbols } - -func (s ByAddress) Less(i, j int) bool { return s.Symbols[i].Addr < s.Symbols[j].Addr } - -var ( - profile = flag.String("profile", "", "name of file containing profile data") - debug = flag.Bool("d", false, "Debug printing") - kernel = flag.String("kernel", "", "kernel to profile against") - symbolTable []*Symbol -) - -func loadSymbols(kernel *elf.File) { - syms, err := kernel.Symbols() - if err != nil { - fmt.Println(err) - return - } - - for _, sym := range syms { - value := sym.Value | 0xffffffff00000000 - symbolTable = append(symbolTable, &Symbol{value, sym.Name}) - } - sort.Sort(ByAddress{symbolTable}) -} - -func findFunction(pc pc) string { - addr := uint64(pc) - var prevSym *Symbol - for _, sym := range symbolTable { - if sym.Addr > addr && prevSym != nil { - return prevSym.Name - } - prevSym = sym - } - return "*** Not Found ***" -} - -func main() { - flag.Parse() - kernelElf, err := elf.Open(*kernel) - if err != nil { - fmt.Println(err) - return - } - loadSymbols(kernelElf) - - backtraces, err := ioutil.ReadFile(*profile) - if err != nil { - fmt.Println(err) - return - } - - b := bytes.NewBuffer(backtraces) - var numRecords int - var records []Record - for { - var h Header - if err := binary.Read(b, binary.LittleEndian, &h); err != nil { - if err == io.EOF { - break - } - fmt.Fprintf(os.Stderr, "header: %v\n", err) - os.Exit(1) - } - if *debug { - fmt.Fprintf(os.Stderr, "%d: %v\n", numRecords, h) - } - - if h.Sig != 0xee { - fmt.Fprintf(os.Stderr, "Record %d: sig is 0x%x, not 0xee", numRecords, h.Sig) - os.Exit(1) - } - pcs := make([]pc, h.Sz) - if err := binary.Read(b, binary.LittleEndian, pcs); err != nil { - fmt.Fprintf(os.Stderr, "data: %v\n", err) - os.Exit(1) - } - numRecords++ - records = append(records, Record{Header: h, pcs: pcs}) - } - - for _, r := range records { - fmt.Printf("0x%x: ", r.Time) - for _, pc := range r.pcs { - fmt.Printf("[0x%x, %s] ", pc, findFunction(pc)) - } - fmt.Printf("\n") - } -} diff --git a/src/jehanne/cmd/removemach/removemach.go b/src/jehanne/cmd/removemach/removemach.go deleted file mode 100644 index 0a55f06..0000000 --- a/src/jehanne/cmd/removemach/removemach.go +++ /dev/null @@ -1,78 +0,0 @@ -package main - -import ( - "bytes" - "debug/elf" - "flag" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "strings" -) - -var dry = flag.Bool("dryrun", true, "don't really do it") - -func main() { - flag.Parse() - a := flag.Args() - for _, n := range a { - f, err := elf.Open(n) - if err != nil { - fmt.Printf("%v %v\n", n, err) - continue - } - - s, err := f.Symbols() - if err != nil { - fmt.Printf("%v %v\n", n, err) - continue - } - usem := false - for _, v := range s { - if v.Name == "m" && v.Section == elf.SHN_UNDEF { - usem = true - cf := strings.Split(n, ".") - globs, err := filepath.Glob("../*/" + cf[0] + ".c") - if err != nil || len(globs) == 0 { - fmt.Fprintf(os.Stderr, "%v has NO source?\n", cf[0]) - continue - } - if len(globs) > 1 { - fmt.Fprintf(os.Stderr, "Skipping %v has more than one source?\n", cf[0]) - continue - } - file := globs[0] - fi, err := os.Stat(file) - if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - continue - } - /* OK, read it in, write it out */ - b, err := ioutil.ReadFile(file) - if err != nil { - fmt.Fprintf(os.Stderr, "%v: %v\n", file, err) - } - header := []byte("extern Mach *m; // REMOVE ME\n") - if bytes.Compare(header[:], b[0:len(header)]) == 0 { - fmt.Fprintf(os.Stderr, "%v already done; skipping\n", file) - continue - } - out := append([]byte("typedef struct Mach Mach; extern Mach *m; // REMOVE ME\n"), b...) - if *dry { - fmt.Fprintf(os.Stderr, "Would do %v mode %v\n", file, fi.Mode()) - continue - } - if err := ioutil.WriteFile(file, out, fi.Mode()); err != nil { - fmt.Fprintf(os.Stderr, "Write %v failed: %v; git checkout %v\n", file, err, file) - } - } - } - if !usem { - fmt.Fprintf(os.Stderr, "Ignored %v as it did not reference Mach *m\n", n) - } else { - fmt.Fprintf(os.Stderr, "Procssed %v as it did reference Mach *m\n", n) - } - } - -} diff --git a/src/jehanne/cmd/runqemu/runqemu.go b/src/jehanne/cmd/runqemu/runqemu.go deleted file mode 100644 index 2a93576..0000000 --- a/src/jehanne/cmd/runqemu/runqemu.go +++ /dev/null @@ -1,119 +0,0 @@ -// Run commands received from stdin in qemu -// -// -p prompt => prompt to expect (default "10.0.2.15#") -// -// ENVIRONMENT -// Needed: JEHANNE -package main - -import ( - "bufio" - "fmt" - "flag" - "os" - "os/exec" - "strings" - "github.com/creack/pty" - "golang.org/x/crypto/ssh/terminal" -) - -func main() { - var prompt string - flag.StringVar(&prompt, "p", "10.0.2.15#", "the prompt to expect") - flag.Parse() - jehanne := os.Getenv("JEHANNE") - if jehanne == "" { - fmt.Printf("usage: cat cmds.rc | runqemu [-p prompt]\n") - fmt.Printf("error: missing $JEHANNE\n"); - os.Exit(1) - } - if terminal.IsTerminal(0) { - fmt.Printf("usage: cat cmds.rc | runqemu [-p prompt]\n") - fmt.Printf("error: runqemu is intended for automation, pipe commands in.\n") - os.Exit(1) - } - - qemuCmd := "cd $JEHANNE/arch/amd64/kern && $JEHANNE/hacking/QA.sh\n" - qemuCmd = os.ExpandEnv(qemuCmd) - - sh := exec.Command("/bin/sh") - qemu, err := pty.Start(sh) - if err != nil { - fmt.Printf("REGRESS start (%s): %s", qemuCmd, err) - os.Exit(2) - } - qemu.WriteString(qemuCmd) - defer qemu.Close() - - exitStatus := 0 - - qemuInput := make(chan string) - qemuOutputRaw := make(chan string) - wait := make(chan int) - - scanner := bufio.NewScanner(os.Stdin) - - go func() { - qemuOut := make([]byte, 256) - for { - r, err := qemu.Read(qemuOut) - if err != nil { - fmt.Fprintln(os.Stderr, "error:", err) - wait <- 3 - } - qemuOutputRaw <- string(qemuOut[0:r]) - } - }() - go func(){ - line := "" - for { - s := <- qemuOutputRaw - line += s - if strings.Contains(line, prompt) { - if scanner.Scan() { - cmd := scanner.Text() - qemuInput <- fmt.Sprintf("%s\n", cmd) - } else { - if err := scanner.Err(); err != nil { - fmt.Fprintln(os.Stderr, "error:", err) - wait <- 4 - } else { - wait <- exitStatus - } - return - } - fmt.Printf("%s", line) - line = "" - } else if strings.ContainsAny(line, "\r\n") { - if strings.Contains(line, "FAIL") { - exitStatus = 5 - } - fmt.Printf("%s", line) - line = "" - } - } - }() - go func(){ - for { - s := <- qemuInput - i := 0; - for { - n, err := qemu.WriteString(s[i:]) - if err != nil { - fmt.Fprintln(os.Stderr, "error:", err) - wait <- 6 - } - i += n - if i == len(s) { - break - } - } - } - }() - - e := <- wait - if e == 0 { - fmt.Printf("\nDone.\n") - } - os.Exit(e) -} diff --git a/src/jehanne/cmd/telnet/telnet.go b/src/jehanne/cmd/telnet/telnet.go deleted file mode 100644 index e6e026c..0000000 --- a/src/jehanne/cmd/telnet/telnet.go +++ /dev/null @@ -1,244 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "golang.org/x/crypto/ssh/terminal" - "io" - "net" - "os" - "os/signal" - "strings" - "syscall" -) - -// Copyright 2012 the u-root Authors. All rights reserved -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -type ( - chunk struct { - id int - buf []byte - } -) - -const ( - echo = false -) - -func comprefix(lines [][]byte) (int, int) { - var line0 []byte - len0 := 0 - for _, ln := range lines { - if len(ln) > len0 { - line0 = ln - len0 = len(ln) - } - } - ndiff := 0 - for i := range line0 { - nshort := 0 - for _, ln := range lines { - if i >= len(ln) { - nshort++ - } else if ln[i] != line0[i] { - ndiff++ - } - } - if ndiff > 0 { - return i, ndiff - } - if nshort > 0 { - return i, ndiff - } - } - return len(line0), ndiff -} - -func main() { - - if len(os.Args) < 2 { - os.Exit(1) - } - - var conns []*net.TCPConn - for _, a := range os.Args[1:] { - port := "1522" - if !strings.Contains(a, ":") { - a = a + ":" + port - } - - tcpdst, err := net.ResolveTCPAddr("tcp", a) - if err != nil { - fmt.Printf("%v\n", err) - os.Exit(1) - } - - c, err := net.DialTCP("tcp", nil, tcpdst) - if err != nil { - fmt.Printf("%v\n", err) - os.Exit(1) - } - conns = append(conns, c) - } - - if terminal.IsTerminal(0) { - unraw, err := terminal.MakeRaw(0) - if err != nil { - fmt.Printf("%v\n", err) - os.Exit(1) - } - defer terminal.Restore(0, unraw) - - sigc := make(chan os.Signal, 1) - signal.Notify(sigc, os.Interrupt, os.Kill, syscall.SIGTERM) - go func() { - for _ = range sigc { - terminal.Restore(0, unraw) - os.Exit(1) - } - }() - } - - go func() { - buf := make([]byte, 256) - for { - n, err := os.Stdin.Read(buf) - if err != nil { - if err != io.EOF { - fmt.Printf("%v\n", err) - } - for _, c := range conns { - c.CloseWrite() // I know, I know.. but it is handy sometimes. - } - break - } - buf = buf[0:n] - for i := range buf { - if echo { - fmt.Printf("%s", string(buf[i])) - } - if buf[i] == '\r' { - buf[i] = '\n' - if echo { - fmt.Printf("\n") - } - } - } - - for _, c := range conns { - if _, err := c.Write(buf); err != nil { - fmt.Printf("%v\n", err) - break - } - } - - } - }() - - waitc := make(chan int) - chunkc := make(chan chunk) - for id, c := range conns { - go func(id int, c *net.TCPConn) { - for { - buf := make([]byte, 256) - n, err := c.Read(buf) - if err != nil { - if err != io.EOF { - fmt.Printf("%v\n", err) - } - c.Close() - waitc <- 1 - break - } - if n == 0 { - continue - } - chunkc <- chunk{id, buf[0:n]} - } - }(id, c) - } - - act := make([][]byte, len(conns)) - - go func() { - oldpfix := 0 - insync := true - for { - chunk, more := <-chunkc - if !more { - break - } - id := chunk.id - for _, b := range chunk.buf { - act[id] = append(act[id], b) - if false && b == '\b' { - act[id] = append(act[id], ' ') - act[id] = append(act[id], '\b') - } - } - - /* streams agree, so spit out all they agree on */ - if insync { - newpfix, ndiff := comprefix(act) - if ndiff == 0 && newpfix > oldpfix { - os.Stdout.Write(act[id][oldpfix:newpfix]) - for { - i := bytes.IndexByte(act[id][:newpfix], '\n') - if i == -1 { - break - } - for id := range act { - clen := copy(act[id], act[id][i+1:]) - act[id] = act[id][0:clen] - } - newpfix = newpfix - (i + 1) - } - oldpfix = newpfix - } - - if ndiff > 0 { - insync = false - } - } - - /* - * streams disagree, first to newline completes from oldpfix on. - * the outer loop is just for transitioning from insync, where - * a leader may be several lines ahead - */ - if !insync { - for id := range act { - for { - i := bytes.IndexByte(act[id], '\n') - if i != -1 { - if oldpfix == 0 { - fmt.Fprintf(os.Stdout, "[%d]", id) - } - os.Stdout.Write(act[id][oldpfix : i+1]) - clen := copy(act[id], act[id][i+1:]) - act[id] = act[id][0:clen] - oldpfix = 0 - } else { - break - } - } - } - - /* try for prompt (or sheer luck) */ - if _, ndiff := comprefix(act); ndiff == 0 { - insync = true - oldpfix = 0 - } - } - } - waitc <- 1 - }() - - for _ = range conns { - <-waitc - } - close(chunkc) - <-waitc -} diff --git a/src/jehanne/cmd/usyscalls/usyscalls.go b/src/jehanne/cmd/usyscalls/usyscalls.go deleted file mode 100644 index f912c80..0000000 --- a/src/jehanne/cmd/usyscalls/usyscalls.go +++ /dev/null @@ -1,272 +0,0 @@ -/* - * This file is part of Jehanne. - * - * Copyright (C) 2016-2019 Giacomo Tesio - * - * Jehanne is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * Jehanne is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Jehanne. If not, see . - */ -package main - -import ( - "encoding/json" - "flag" - "fmt" - "io/ioutil" - "log" - "os" - "strings" - "text/template" -) - -const gplHeader string = `/* - * This file is part of Jehanne. - * - * Copyright (C) 2016-2019 Giacomo Tesio - * - * Jehanne is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3 of the License. - * - * Jehanne is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Jehanne. If not, see . - */ -/* automatically generated by usyscalls */ -` - -type SyscallConf struct { - Ret []string - Args []string - Name string - Id uint32 -} - -type Sysconf struct { - Syscalls []SyscallConf -} - -type SyscallWrapper struct { - Id uint32 - Name string - FuncArgs string - MacroArgs string - VarValues []string - Vars []string - AsmArgs string - AsmClobbers string - RetType string -} - -type HeaderCode struct { - Wrappers []SyscallWrapper -} - - -func usage(msg string) { - fmt.Fprint(os.Stderr, msg) - fmt.Fprint(os.Stderr, "Usage: usyscalls header|code path/to/sysconf.json\n") - flag.PrintDefaults() - os.Exit(1) -} - -func argTypeName(t string) string{ - switch(t){ - case "int", "int32_t": - return "i" - case "unsigned int", "uint32_t": - /* unsigned int is reserved for flags */ - return "ui" - case "long", "int64_t": - return "l" - case "unsigned long", "uint64_t": - return "ul" - case "void*", "uint8_t*", "const void*", "const uint8_t*": - return "p" - case "int32_t*", "int*", "const int32_t*", "const int*": - return "p" - case "const char*", "char*": - return "p" - case "const char**", "char**": - return "p" - } - return " [?? " + t + "]" -} - -func argRegister(index int, t string) string{ - prefix := "" - switch(t){ - case "int", "unsigned int", "uint32_t", "int32_t": - prefix = "e" - default: - prefix = "r" - } - switch(index){ - case 0: - return prefix + "di"; - case 1: - return prefix + "si"; - case 2: - return prefix + "dx"; - case 3: - return "r10"; - case 4: - return "r8"; - case 5: - return "r9"; - } - return "" -} - -func getHeaderData(calls []SyscallConf) *HeaderCode { - code := new(HeaderCode) - for _, call := range(calls) { - wcall := new(SyscallWrapper) - wcall.Id = call.Id - wcall.Name = call.Name - wcall.RetType = call.Ret[0] - - clobberMemory := false - wcall.AsmClobbers = "\"cc\", \"rcx\", \"r11\"" - wcall.AsmArgs = fmt.Sprintf("\"0\"(%d)", wcall.Id) - for i, a := range(call.Args){ - typeName := argTypeName(a) - if i > 0 { - wcall.FuncArgs += ", " - wcall.MacroArgs += ", " - } - if strings.HasSuffix(a, "*") && !strings.HasPrefix(a, "const"){ - clobberMemory = true - } - wcall.FuncArgs += fmt.Sprintf("%s a%d", a, i) - wcall.MacroArgs += fmt.Sprintf("/* %s */ a%d", a, i) - if typeName == "p" { - wcall.VarValues = append(wcall.VarValues, fmt.Sprintf("_sysargs[%d].%s = ((volatile void*)(a%d)); \\\n\t", i, typeName, i)) - } else { - wcall.VarValues = append(wcall.VarValues, fmt.Sprintf("_sysargs[%d].%s = (a%d); \\\n\t", i, typeName, i)) - } - wcall.Vars = append(wcall.Vars, fmt.Sprintf("register %s __r%d asm(\"%s\") = _sysargs[%d].%s; \\\n\t", a, i, argRegister(i, a), i, argTypeName(a))) - wcall.AsmArgs += fmt.Sprintf(", \"r\"(__r%d)", i) - } - if clobberMemory { - wcall.AsmClobbers += ", \"memory\"" - } - code.Wrappers = append(code.Wrappers, *wcall) - } - - return code -} - -func generateSyscallTable(calls []SyscallConf){ - code := getHeaderData(calls) - tmpl, err := template.New("tab.c").Parse(` -{{ range .Wrappers }}"{{ .Name }}", (int(*)()) sys_{{ .Name }}, -{{ end }} -`) - err = tmpl.Execute(os.Stdout, code) - if err != nil { - log.Fatal(err) - } -} - -func generateLibcCode(calls []SyscallConf){ - code := getHeaderData(calls) - tmpl, err := template.New("syscalls.c").Parse(gplHeader + ` -#define PORTABLE_SYSCALLS -#include - -{{ range .Wrappers }} -#pragma weak sys_{{ .Name }} -{{ .RetType }} -sys_{{ .Name }}({{ .FuncArgs }}) -{ - register {{ .RetType }} __ret asm ("rax"); - __asm__ __volatile__ ( - "movq %%rcx, %%r10" "\n\t" - "movq ${{ .Id }}, %%rax" "\n\t" - "syscall" - : "=r" (__ret) - : /* args are ready */ - : {{ .AsmClobbers }} - ); - return __ret; -} -{{ end }} -`) - err = tmpl.Execute(os.Stdout, code) - if err != nil { - log.Fatal(err) - } -} - -func generateSyscallHeader(calls []SyscallConf){ - funcMap := template.FuncMap{ - "title": strings.Title, - } - code := getHeaderData(calls) - tmpl, err := template.New("syscall.h").Funcs(funcMap).Parse(gplHeader + ` -typedef enum Syscalls -{ -{{ range .Wrappers }} Sys{{ .Name|title }} = {{ .Id }}, -{{ end }}} Syscalls; - -#ifndef KERNEL - -{{ range .Wrappers }}extern {{ .RetType }} sys_{{ .Name }}({{ .FuncArgs }}); -{{ end }} - -#endif -`) - err = tmpl.Execute(os.Stdout, code) - if err != nil { - log.Fatal(err) - } -} - -func main() { - - flag.Parse() - - if flag.NArg() != 2 { - usage("no path to sysconf.json") - } - - buf, err := ioutil.ReadFile(flag.Arg(1)) - if err != nil { - log.Fatal(err) - } - - var sysconf Sysconf - err = json.Unmarshal(buf, &sysconf) - if err != nil { - log.Fatal(err) - } - mode := flag.Arg(0) - switch(mode){ - case "header": - generateSyscallHeader(sysconf.Syscalls) - break - case "code": - generateLibcCode(sysconf.Syscalls) - break - case "tab": - generateSyscallTable(sysconf.Syscalls) - break - } - - - -} diff --git a/src/jehanne/cmd/vendor/doc.go b/src/jehanne/cmd/vendor/doc.go deleted file mode 100644 index e3a87a0..0000000 --- a/src/jehanne/cmd/vendor/doc.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Vendor is a tool to vendor software for Jehanne. - -It downloads a tarball, verifies it against supplied hashes, extracts it -into "upstream", modifies all the files to be read-only, and then commits -the results. - -When invoked with the flag `-check` it verify that the files present in -a previously vendorized "upstream" folder match those in the downloaded tarball. - -Vendor is purposely unhelpful and un-customisable. - -VENDORFILE - -It requires a "vendor.json" file in the current directory with the following -structure: - - { - "Upstream":"", - "Digest": { - "":"" - }, - "Compress":"", - "RemovePrefix": true, - "Exclude": [ - "" - ] - } - -"Upstream" is the URL to fetch a tarball from. - -"Digest" is a map of algorithm-hash pairs for calculating checksums. All -of the sha functions in the go standard library are supported except for sha1. -The hash is hex-encoded, just like sha*sum output. - -"Compress" is the compression type of the tarball. Gzip and bzip are -supported. If this key is omitted, the tarball is assumed to be uncompressed. - -"RemovePrefix" is a boolean toggle for if the first element of files in the -archive should be removed. Defaults to false if omitted. - -"Exclude" is an array of prefix strings for files that should not be -extracted. They are used as literal prefixes and not interpreted in any way. -*/ -package main diff --git a/src/jehanne/cmd/vendor/vendor.go b/src/jehanne/cmd/vendor/vendor.go deleted file mode 100644 index b5e23d7..0000000 --- a/src/jehanne/cmd/vendor/vendor.go +++ /dev/null @@ -1,248 +0,0 @@ -package main - -import ( - "archive/tar" - "bytes" - "compress/bzip2" - "compress/gzip" - "crypto/sha256" - "crypto/sha512" - "encoding/hex" - "encoding/json" - "flag" - "hash" - "io" - "io/ioutil" - "log" - "net/http" - "os" - "os/exec" - "path" - "strings" -) - -const ( - ignore = "*\n!.gitignore\n" - dirPermissions = 0755 -) - -type V struct { - Upstream string - Digest map[string]string - Compress string - RemovePrefix bool - Exclude []string -} - -func main() { - log.SetFlags(log.Lshortfile | log.LstdFlags) - - justCheck := flag.Bool("check", false, "verify the code in upstream/") - - flag.Parse() - - if(*justCheck && !repositoryIsClean()){ - log.Fatal("cannot verify upstream/ files: working directory not clean") - } - - f, err := ioutil.ReadFile("vendor.json") - if err != nil { - log.Fatal(err) - } - - vendor := &V{} - if err := json.Unmarshal(f, vendor); err != nil { - log.Fatal(err) - } - - if _, err := os.Stat("upstream"); err == nil { - log.Println("recreating upstream") - if(*justCheck){ - run("rm", "-r", "-f", "upstream") - } else { - run("git", "rm", "-r", "-f", "upstream") - } - } else { - if(*justCheck){ - log.Fatalf("Cannot verify upstream/ as it does not exists.") - } - os.MkdirAll("patch", dirPermissions) - os.MkdirAll("jehanne", dirPermissions) - ig, err := os.Create(path.Join("jehanne", ".gitignore")) - if err != nil { - log.Fatal(err) - } - defer ig.Close() - if _, err := ig.WriteString(ignore); err != nil { - log.Fatal(err) - } - run("git", "add", ig.Name()) - } - - if err := do(vendor, *justCheck); err != nil { - log.Fatal(err) - } - - if(*justCheck){ - if(repositoryIsClean()){ - log.Printf("the files in upstream/ matches those in "+path.Base(vendor.Upstream)) - } else { - log.Fatalf("the files in upstream/ does not match those in "+path.Base(vendor.Upstream)) - } - } else { - run("git", "add", "vendor.json") - run("git", "commit", "-s", "-m", "vendor: pull in "+path.Base(vendor.Upstream)) - } -} - -func repositoryIsClean() bool { - out, err := exec.Command("git", "status", "--porcelain").Output() - if err != nil { - log.Fatal(err) - } - if(len(out) > 0){ - log.Println("git status --porcelain"); - log.Println(string(out)) - return false - } - return true -} - -func do(v *V, justCheck bool) error { - name := fetch(v) - f, err := os.Open(name) - if err != nil { - return err - } - defer os.Remove(name) - - var unZ io.Reader - switch v.Compress { - case "gzip": - unZ, err = gzip.NewReader(f) - if err != nil { - return err - } - case "bzip2": - unZ = bzip2.NewReader(f) - default: - unZ = f - } - - ar := tar.NewReader(unZ) - h, err := ar.Next() -untar: - for ; err == nil; h, err = ar.Next() { - n := h.Name - if v.RemovePrefix { - n = strings.SplitN(n, "/", 2)[1] - } - for _, ex := range v.Exclude { - if strings.HasPrefix(n, ex) { - continue untar - } - } - n = path.Join("upstream", n) - if h.FileInfo().IsDir() { - os.MkdirAll(n, dirPermissions) - continue - } - os.MkdirAll(path.Dir(n), dirPermissions) - out, err := os.Create(n) - if err != nil { - log.Println(err) - continue - } - - if n, err := io.Copy(out, ar); n != h.Size || err != nil { - return err - } - out.Close() - } - if err != io.EOF { - return err - } - - if(justCheck){ - return nil; - } - return run("git", "add", "upstream") -} - -type match struct { - hash.Hash - Good []byte - Name string -} - -func (m match) OK() bool { - return bytes.Equal(m.Good, m.Hash.Sum(nil)) -} - -func fetch(v *V) string { - if len(v.Digest) == 0 { - log.Fatal("no checksums specifed") - } - - f, err := ioutil.TempFile("", "cmdVendor") - if err != nil { - log.Fatal(err) - } - defer f.Close() - - req, err := http.NewRequest("GET", v.Upstream, nil) - if err != nil { - log.Fatal(err) - } - client := &http.Client{ - Transport: &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DisableCompression: true, - }, - } - res, err := client.Do(req) - if err != nil { - log.Fatal(err) - } - defer res.Body.Close() - - var digests []match - for k, v := range v.Digest { - g, err := hex.DecodeString(v) - if err != nil { - log.Fatal(err) - } - switch k { - case "sha224": - digests = append(digests, match{sha256.New224(), g, k}) - case "sha256": - digests = append(digests, match{sha256.New(), g, k}) - case "sha384": - digests = append(digests, match{sha512.New384(), g, k}) - case "sha512": - digests = append(digests, match{sha512.New(), g, k}) - } - } - ws := make([]io.Writer, len(digests)) - for i := range digests { - ws[i] = digests[i] - } - w := io.MultiWriter(ws...) - - if _, err := io.Copy(f, io.TeeReader(res.Body, w)); err != nil { - log.Fatal(err) - } - for _, h := range digests { - if !h.OK() { - log.Fatalf("mismatched %q hash\n\tWanted %x\n\tGot %x\n", h.Name, h.Good, h.Hash.Sum(nil)) - } - } - return f.Name() -} - -func run(exe string, arg ...string) error { - cmd := exec.Command(exe, arg...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - return cmd.Run() -} diff --git a/src/netcat b/src/netcat new file mode 160000 index 0000000..6074016 --- /dev/null +++ b/src/netcat @@ -0,0 +1 @@ +Subproject commit 607401678236b608280b291ad849a109b8d9a8f2 diff --git a/src/trampoline b/src/trampoline new file mode 160000 index 0000000..1d47bf9 --- /dev/null +++ b/src/trampoline @@ -0,0 +1 @@ +Subproject commit 1d47bf91a6d4828038e9fbd11508c90fc983dce0 diff --git a/src/u9fs b/src/u9fs new file mode 160000 index 0000000..d65923f --- /dev/null +++ b/src/u9fs @@ -0,0 +1 @@ +Subproject commit d65923fd17e8b158350d3ccd6a4e32b89b15014a diff --git a/third_party/src/github.com/lionkov/ninep b/third_party/src/github.com/lionkov/ninep deleted file mode 160000 index aed6e1e..0000000 --- a/third_party/src/github.com/lionkov/ninep +++ /dev/null @@ -1 +0,0 @@ -Subproject commit aed6e1e7aa37744dba150fa2974f322813d23478