diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..1d8abd83a2 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: go + +go: + - 1.8 + +env: + global: + - GOROOT_BOOTSTRAP="/home/travis/.gimme/versions/go1.8.linux.amd64" + +before_install: + - echo "no" +install: + - echo "no" + +before_script: + - cd $TRAVIS_BUILD_DIR/src + +script: + - GOOS=harvey GOARCH=amd64 ./make.bash diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go index 76e42a4b6a..f8a6074ed0 100644 --- a/src/cmd/dist/build.go +++ b/src/cmd/dist/build.go @@ -78,6 +78,7 @@ var okgoos = []string{ "netbsd", "openbsd", "plan9", + "harvey", "windows", } @@ -1127,6 +1128,7 @@ var cgoEnabled = map[string]bool{ "plan9/386": false, "plan9/amd64": false, "plan9/arm": false, + "harvey/amd64": false, "solaris/amd64": true, "windows/386": true, "windows/amd64": true, diff --git a/src/cmd/internal/objabi/head.go b/src/cmd/internal/objabi/head.go index ff19606cd2..ee7f0e3556 100644 --- a/src/cmd/internal/objabi/head.go +++ b/src/cmd/internal/objabi/head.go @@ -57,7 +57,7 @@ func (h *HeadType) Set(s string) error { *h = Hdragonfly case "freebsd": *h = Hfreebsd - case "linux", "android": + case "linux", "android", "harvey": *h = Hlinux case "nacl": *h = Hnacl diff --git a/src/go/build/build.go b/src/go/build/build.go index fd89871d42..05b9f66b46 100644 --- a/src/go/build/build.go +++ b/src/go/build/build.go @@ -1493,6 +1493,9 @@ func (ctxt *Context) match(name string, allTags map[string]bool) bool { if ctxt.GOOS == "android" && name == "linux" { return true } + if ctxt.GOOS == "harvey" && name == "plan9" { + return true + } // other tags for _, tag := range ctxt.BuildTags { @@ -1555,6 +1558,9 @@ func (ctxt *Context) goodOSArchFile(name string, allTags map[string]bool) bool { if ctxt.GOOS == "android" && l[n-2] == "linux" { return true } + if ctxt.GOOS == "harvey" && l[n-2] == "plan9" { + return true + } return l[n-2] == ctxt.GOOS } if n >= 1 && knownOS[l[n-1]] { @@ -1564,6 +1570,9 @@ func (ctxt *Context) goodOSArchFile(name string, allTags map[string]bool) bool { if ctxt.GOOS == "android" && l[n-1] == "linux" { return true } + if ctxt.GOOS == "harvey" && l[n-1] == "plan9" { + return true + } return l[n-1] == ctxt.GOOS } if n >= 1 && knownArch[l[n-1]] { diff --git a/src/go/build/syslist.go b/src/go/build/syslist.go index 73fdbe6c85..eb3a3d783f 100644 --- a/src/go/build/syslist.go +++ b/src/go/build/syslist.go @@ -4,5 +4,5 @@ package build -const goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows zos " +const goosList = "android darwin dragonfly freebsd harvey linux nacl netbsd openbsd plan9 solaris windows zos " const goarchList = "386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc s390 s390x sparc sparc64 " diff --git a/src/runtime/defs_harvey_amd64.go b/src/runtime/defs_harvey_amd64.go new file mode 100644 index 0000000000..4381f74412 --- /dev/null +++ b/src/runtime/defs_harvey_amd64.go @@ -0,0 +1,70 @@ +package runtime + +const _PAGESIZE = 0x1000 + +type ureg struct { + ax uint64 + bx uint64 + cx uint64 + dx uint64 + si uint64 + di uint64 + bp uint64 + r8 uint64 + r9 uint64 + r10 uint64 + r11 uint64 + r12 uint64 + r13 uint64 + r14 uint64 + r15 uint64 + + _type uint64 + error uint64 /* error code (or zero) */ + ip uint64 /* pc */ + cs uint64 /* old context */ + flags uint64 /* old flags */ + sp uint64 /* sp */ + ss uint64 /* old stack segment */ +} + +type sigctxt struct { + u *ureg +} + +//go:nosplit +//go:nowritebarrierrec +func (c *sigctxt) pc() uintptr { return uintptr(c.u.ip) } + +func (c *sigctxt) sp() uintptr { return uintptr(c.u.sp) } +func (c *sigctxt) lr() uintptr { return uintptr(0) } + +func (c *sigctxt) setpc(x uintptr) { c.u.ip = uint64(x) } +func (c *sigctxt) setsp(x uintptr) { c.u.sp = uint64(x) } +func (c *sigctxt) setlr(x uintptr) {} + +func (c *sigctxt) savelr(x uintptr) {} + +func dumpregs(u *ureg) { + print("ax ", hex(u.ax), "\n") + print("bx ", hex(u.bx), "\n") + print("cx ", hex(u.cx), "\n") + print("dx ", hex(u.dx), "\n") + print("di ", hex(u.di), "\n") + print("si ", hex(u.si), "\n") + print("bp ", hex(u.bp), "\n") + print("sp ", hex(u.sp), "\n") + print("r8 ", hex(u.r8), "\n") + print("r9 ", hex(u.r9), "\n") + print("r10 ", hex(u.r10), "\n") + print("r11 ", hex(u.r11), "\n") + print("r12 ", hex(u.r12), "\n") + print("r13 ", hex(u.r13), "\n") + print("r14 ", hex(u.r14), "\n") + print("r15 ", hex(u.r15), "\n") + print("ip ", hex(u.ip), "\n") + print("flags ", hex(u.flags), "\n") + print("cs ", hex(u.cs), "\n") +} + +func sigpanictramp() {} diff --git a/src/runtime/defs_plan9_amd64.go b/src/runtime/defs_plan9_amd64.go index 29a2643c3a..609ba71c22 100644 --- a/src/runtime/defs_plan9_amd64.go +++ b/src/runtime/defs_plan9_amd64.go @@ -1,3 +1,5 @@ +// +build !harvey + package runtime const _PAGESIZE = 0x1000 diff --git a/src/runtime/internal/sys/gengoos.go b/src/runtime/internal/sys/gengoos.go index 4c45c0af02..4757bb8e6c 100644 --- a/src/runtime/internal/sys/gengoos.go +++ b/src/runtime/internal/sys/gengoos.go @@ -49,6 +49,9 @@ func main() { if target == "linux" { fmt.Fprintf(&buf, "// +build !android\n\n") // must explicitly exclude android for linux } + if target == "plan9" { + fmt.Fprintf(&buf, "// +build !harvey\n\n") // must explicitly exclude android for linux + } fmt.Fprintf(&buf, "package sys\n\n") fmt.Fprintf(&buf, "const GOOS = `%s`\n\n", target) for _, goos := range gooses { diff --git a/src/runtime/internal/sys/zgoos_android.go b/src/runtime/internal/sys/zgoos_android.go index 6503b15246..b9ea941750 100644 --- a/src/runtime/internal/sys/zgoos_android.go +++ b/src/runtime/internal/sys/zgoos_android.go @@ -8,6 +8,7 @@ const GoosAndroid = 1 const GoosDarwin = 0 const GoosDragonfly = 0 const GoosFreebsd = 0 +const GoosHarvey = 0 const GoosLinux = 0 const GoosNacl = 0 const GoosNetbsd = 0 diff --git a/src/runtime/internal/sys/zgoos_darwin.go b/src/runtime/internal/sys/zgoos_darwin.go index 6a285984bd..0958572415 100644 --- a/src/runtime/internal/sys/zgoos_darwin.go +++ b/src/runtime/internal/sys/zgoos_darwin.go @@ -8,6 +8,7 @@ const GoosAndroid = 0 const GoosDarwin = 1 const GoosDragonfly = 0 const GoosFreebsd = 0 +const GoosHarvey = 0 const GoosLinux = 0 const GoosNacl = 0 const GoosNetbsd = 0 diff --git a/src/runtime/internal/sys/zgoos_dragonfly.go b/src/runtime/internal/sys/zgoos_dragonfly.go index 886ac2698f..6a8b1755b4 100644 --- a/src/runtime/internal/sys/zgoos_dragonfly.go +++ b/src/runtime/internal/sys/zgoos_dragonfly.go @@ -8,6 +8,7 @@ const GoosAndroid = 0 const GoosDarwin = 0 const GoosDragonfly = 1 const GoosFreebsd = 0 +const GoosHarvey = 0 const GoosLinux = 0 const GoosNacl = 0 const GoosNetbsd = 0 diff --git a/src/runtime/internal/sys/zgoos_freebsd.go b/src/runtime/internal/sys/zgoos_freebsd.go index 0bf2403eab..1343d33abc 100644 --- a/src/runtime/internal/sys/zgoos_freebsd.go +++ b/src/runtime/internal/sys/zgoos_freebsd.go @@ -8,6 +8,7 @@ const GoosAndroid = 0 const GoosDarwin = 0 const GoosDragonfly = 0 const GoosFreebsd = 1 +const GoosHarvey = 0 const GoosLinux = 0 const GoosNacl = 0 const GoosNetbsd = 0 diff --git a/src/runtime/internal/sys/zgoos_harvey.go b/src/runtime/internal/sys/zgoos_harvey.go new file mode 100644 index 0000000000..ea2d627d25 --- /dev/null +++ b/src/runtime/internal/sys/zgoos_harvey.go @@ -0,0 +1,18 @@ +// generated by gengoos.go using 'go generate' + +package sys + +const GOOS = `harvey` + +const GoosAndroid = 0 +const GoosDarwin = 0 +const GoosDragonfly = 0 +const GoosFreebsd = 0 +const GoosHarvey = 1 +const GoosLinux = 0 +const GoosNacl = 0 +const GoosNetbsd = 0 +const GoosOpenbsd = 0 +const GoosPlan9 = 0 +const GoosSolaris = 0 +const GoosWindows = 0 diff --git a/src/runtime/internal/sys/zgoos_linux.go b/src/runtime/internal/sys/zgoos_linux.go index c8664db15d..399ae32c2c 100644 --- a/src/runtime/internal/sys/zgoos_linux.go +++ b/src/runtime/internal/sys/zgoos_linux.go @@ -10,6 +10,7 @@ const GoosAndroid = 0 const GoosDarwin = 0 const GoosDragonfly = 0 const GoosFreebsd = 0 +const GoosHarvey = 0 const GoosLinux = 1 const GoosNacl = 0 const GoosNetbsd = 0 diff --git a/src/runtime/internal/sys/zgoos_nacl.go b/src/runtime/internal/sys/zgoos_nacl.go index 054122638a..d53e17ea2d 100644 --- a/src/runtime/internal/sys/zgoos_nacl.go +++ b/src/runtime/internal/sys/zgoos_nacl.go @@ -8,6 +8,7 @@ const GoosAndroid = 0 const GoosDarwin = 0 const GoosDragonfly = 0 const GoosFreebsd = 0 +const GoosHarvey = 0 const GoosLinux = 0 const GoosNacl = 1 const GoosNetbsd = 0 diff --git a/src/runtime/internal/sys/zgoos_netbsd.go b/src/runtime/internal/sys/zgoos_netbsd.go index 5c509a1250..e49e1f5614 100644 --- a/src/runtime/internal/sys/zgoos_netbsd.go +++ b/src/runtime/internal/sys/zgoos_netbsd.go @@ -8,6 +8,7 @@ const GoosAndroid = 0 const GoosDarwin = 0 const GoosDragonfly = 0 const GoosFreebsd = 0 +const GoosHarvey = 0 const GoosLinux = 0 const GoosNacl = 0 const GoosNetbsd = 1 diff --git a/src/runtime/internal/sys/zgoos_openbsd.go b/src/runtime/internal/sys/zgoos_openbsd.go index dc43157d49..10608467ac 100644 --- a/src/runtime/internal/sys/zgoos_openbsd.go +++ b/src/runtime/internal/sys/zgoos_openbsd.go @@ -8,6 +8,7 @@ const GoosAndroid = 0 const GoosDarwin = 0 const GoosDragonfly = 0 const GoosFreebsd = 0 +const GoosHarvey = 0 const GoosLinux = 0 const GoosNacl = 0 const GoosNetbsd = 0 diff --git a/src/runtime/internal/sys/zgoos_plan9.go b/src/runtime/internal/sys/zgoos_plan9.go index 4b0934f77a..d8a5683e57 100644 --- a/src/runtime/internal/sys/zgoos_plan9.go +++ b/src/runtime/internal/sys/zgoos_plan9.go @@ -1,5 +1,7 @@ // generated by gengoos.go using 'go generate' +// +build !harvey + package sys const GOOS = `plan9` @@ -8,6 +10,7 @@ const GoosAndroid = 0 const GoosDarwin = 0 const GoosDragonfly = 0 const GoosFreebsd = 0 +const GoosHarvey = 0 const GoosLinux = 0 const GoosNacl = 0 const GoosNetbsd = 0 diff --git a/src/runtime/internal/sys/zgoos_solaris.go b/src/runtime/internal/sys/zgoos_solaris.go index 42511a36ad..e0c20b9df0 100644 --- a/src/runtime/internal/sys/zgoos_solaris.go +++ b/src/runtime/internal/sys/zgoos_solaris.go @@ -8,6 +8,7 @@ const GoosAndroid = 0 const GoosDarwin = 0 const GoosDragonfly = 0 const GoosFreebsd = 0 +const GoosHarvey = 0 const GoosLinux = 0 const GoosNacl = 0 const GoosNetbsd = 0 diff --git a/src/runtime/internal/sys/zgoos_windows.go b/src/runtime/internal/sys/zgoos_windows.go index d77f62c396..731afa83d9 100644 --- a/src/runtime/internal/sys/zgoos_windows.go +++ b/src/runtime/internal/sys/zgoos_windows.go @@ -8,6 +8,7 @@ const GoosAndroid = 0 const GoosDarwin = 0 const GoosDragonfly = 0 const GoosFreebsd = 0 +const GoosHarvey = 0 const GoosLinux = 0 const GoosNacl = 0 const GoosNetbsd = 0 diff --git a/src/runtime/sys_harvey_amd64.s b/src/runtime/sys_harvey_amd64.s new file mode 100644 index 0000000000..fedb91aae1 --- /dev/null +++ b/src/runtime/sys_harvey_amd64.s @@ -0,0 +1,268 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "go_asm.h" +#include "go_tls.h" +#include "textflag.h" + +// setldt(int entry, int address, int limit) +TEXT runtime·setldt(SB),NOSPLIT,$0 + RET + +TEXT runtime·open(SB),NOSPLIT,$0-20 + MOVQ name+0(FP), DI + MOVL mode+8(FP), SI + MOVL perm+12(FP), DX + MOVL $14, AX // syscall entry + SYSCALL + MOVQ AX, ret+16(FP) + RET + +TEXT runtime·pread(SB),NOSPLIT,$0 + MOVL a0+0(FP), DI + MOVQ a1+8(FP), SI + MOVL a2+16(FP), DX + MOVQ a3+24(FP), R10 + MOVQ $50, AX + SYSCALL + MOVQ AX, ret+32(FP) + RET + +TEXT runtime·pwrite(SB),NOSPLIT,$0 + MOVL fd+0(FP), DI + MOVQ p+8(FP), SI + MOVL n+16(FP), DX + MOVQ a4+24(FP), R10 + MOVQ $51, AX + SYSCALL + MOVQ AX, ret+32(FP) + RET + +// int64 seek(int32, int64, int32) +TEXT runtime·seek(SB),NOSPLIT,$32 + MOVL fd+0(FP), DI + MOVQ off+4(FP), SI + MOVL whence+12(FP), DX + MOVQ $39, AX + SYSCALL + MOVQ AX, ret+16(FP) + RET + +TEXT runtime·closefd(SB),NOSPLIT,$0 + MOVL a0+0(FP), DI + MOVQ $4, AX + SYSCALL + MOVQ AX, ret+8(FP) + RET + +TEXT runtime·exits(SB),NOSPLIT,$0 + MOVQ a0+0(FP), DI + MOVQ $8, AX + SYSCALL + RET + +TEXT runtime·brk_(SB),NOSPLIT,$0 + MOVQ a0+0(FP), DI + MOVQ $24, AX + SYSCALL + MOVQ AX, ret+8(FP) + RET + +TEXT runtime·sleep(SB),NOSPLIT,$0 + MOVL a0+0(FP), DI + MOVQ $17, AX + SYSCALL + MOVQ AX, ret+8(FP) + RET + +TEXT runtime·plan9_semacquire(SB),NOSPLIT,$0 + MOVQ a0+0(FP), DI + MOVQ a1+8(FP), SI + MOVQ $37, AX + SYSCALL + MOVQ AX, ret+16(FP) + RET + +TEXT runtime·plan9_tsemacquire(SB),NOSPLIT,$0 + MOVQ a0+0(FP), DI + MOVQ a1+8(FP), SI + MOVQ $52, AX + SYSCALL + MOVQ AX, ret+16(FP) + RET + +TEXT runtime·nsec(SB),NOSPLIT,$0 + MOVQ $53, AX + SYSCALL + MOVQ AX, ret+8(FP) + RET + +// func walltime() (sec int64, nsec int32) +TEXT runtime·walltime(SB),NOSPLIT,$8-12 + CALL runtime·nanotime(SB) + MOVQ 0(SP), AX + + // generated code for + // func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 } + // adapted to reduce duplication + MOVQ AX, CX + MOVQ $1360296554856532783, AX + MULQ CX + ADDQ CX, DX + RCRQ $1, DX + SHRQ $29, DX + MOVQ DX, sec+0(FP) + IMULQ $1000000000, DX + SUBQ DX, CX + MOVL CX, nsec+8(FP) + RET + +TEXT runtime·notify(SB),NOSPLIT,$0 + MOVQ a0+0(FP), DI + MOVQ $28, AX + SYSCALL + MOVQ AX, ret+8(FP) + RET + +TEXT runtime·noted(SB),NOSPLIT,$0 + MOVL a0+0(FP), DI + MOVQ $29, AX + SYSCALL + MOVQ AX, ret+8(FP) + RET + +TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0 + MOVQ a0+0(FP), DI + MOVQ a1+8(FP), SI + MOVQ $38, AX + SYSCALL + MOVQ AX, ret+16(FP) + RET + +TEXT runtime·rfork(SB),NOSPLIT,$0 + MOVL a0+0(FP), DI + MOVQ $19, AX + SYSCALL + MOVQ AX, ret+8(FP) + RET + +TEXT runtime·tstart_plan9(SB),NOSPLIT,$0 + MOVQ newm+0(FP), CX + MOVQ m_g0(CX), DX + + // Layout new m scheduler stack on os stack. + MOVQ SP, AX + MOVQ AX, (g_stack+stack_hi)(DX) + SUBQ $(64*1024), AX // stack size + MOVQ AX, (g_stack+stack_lo)(DX) + MOVQ AX, g_stackguard0(DX) + MOVQ AX, g_stackguard1(DX) + + // Initialize procid from TOS struct. + MOVQ _tos(SB), AX + MOVL 24(AX), AX + MOVQ AX, m_procid(CX) // save pid as m->procid + + // Finally, initialize g. + get_tls(BX) + MOVQ DX, g(BX) + + CALL runtime·stackcheck(SB) // smashes AX, CX + CALL runtime·mstart(SB) + + MOVQ $0x1234, 0x1234 // not reached + RET + +// This is needed by asm_amd64.s +TEXT runtime·settls(SB),NOSPLIT,$0 + RET + +// void sigtramp(void *ureg, int8 *note) +TEXT runtime·sigtramp(SB),NOSPLIT,$0 + get_tls(AX) + + // check that g exists + MOVQ g(AX), BX + CMPQ BX, $0 + JNE 3(PC) + CALL runtime·badsignal2(SB) // will exit + RET + + // save args + MOVQ DI, CX + MOVQ SI, DX + + // change stack + MOVQ g_m(BX), BX + MOVQ m_gsignal(BX), R10 + MOVQ (g_stack+stack_hi)(R10), BP + MOVQ BP, SP + + // make room for args and g + SUBQ $128, SP + + // save g + MOVQ g(AX), BP + MOVQ BP, 32(SP) + + // g = m->gsignal + MOVQ R10, g(AX) + + // load args and call sighandler + MOVQ CX, 0(SP) + MOVQ DX, 8(SP) + MOVQ BP, 16(SP) + + CALL runtime·sighandler(SB) + MOVL 24(SP), AX + + // restore g + get_tls(BX) + MOVQ 32(SP), R10 + MOVQ R10, g(BX) + + // call noted(AX) + MOVQ AX, 0(SP) + CALL runtime·noted(SB) + RET + +TEXT runtime·setfpmasks(SB),NOSPLIT,$8 + STMXCSR 0(SP) + MOVL 0(SP), AX + ANDL $~0x3F, AX + ORL $(0x3F<<7), AX + MOVL AX, 0(SP) + LDMXCSR 0(SP) + RET + +#define ERRMAX 128 /* from os_plan9.h */ + +// void errstr(int8 *buf, int32 len) +TEXT errstr<>(SB),NOSPLIT,$0 + MOVQ buf+0(FP), DI + MOVQ len+8(FP), SI + MOVQ $41, AX + SYSCALL + RET + +// func errstr() string +// Only used by package syscall. +// Grab error string due to a syscall made +// in entersyscall mode, without going +// through the allocator (issue 4994). +// See ../syscall/asm_plan9_amd64.s:/·Syscall/ +TEXT runtime·errstr(SB),NOSPLIT,$16-16 + get_tls(AX) + MOVQ g(AX), BX + MOVQ g_m(BX), BX + MOVQ (m_mOS+mOS_errstr)(BX), CX + MOVQ CX, 0(SP) + MOVQ $ERRMAX, 8(SP) + CALL errstr<>(SB) + CALL runtime·findnull(SB) + MOVQ 8(SP), AX + MOVQ AX, ret_len+8(FP) + MOVQ 0(SP), AX + MOVQ AX, ret_base+0(FP) + RET diff --git a/src/runtime/sys_plan9_amd64.s b/src/runtime/sys_plan9_amd64.s index d7bd92c1b4..64d788c143 100644 --- a/src/runtime/sys_plan9_amd64.s +++ b/src/runtime/sys_plan9_amd64.s @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !harvey + #include "go_asm.h" #include "go_tls.h" #include "textflag.h" diff --git a/src/syscall/asm_harvey_amd64.s b/src/syscall/asm_harvey_amd64.s new file mode 100644 index 0000000000..3c198de6da --- /dev/null +++ b/src/syscall/asm_harvey_amd64.s @@ -0,0 +1,146 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "textflag.h" +#include "funcdata.h" + +// +// // System call support for HarveyPlan 9System calls for AMD64, Linux +// + +// Trap # in AX, args in DI SI DX R10 R8 R9, return in AX DX +// Note that this differs from "standard" ABI convention, which +// would pass 4th arg in CX, not R10. + +//func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err string) +//func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err string) +//func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) +//func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) +TEXT ·Syscall(SB),NOSPLIT,$0-56 + CALL runtime·entersyscall(SB) + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ $0, R10 + MOVQ $0, R8 + MOVQ $0, R9 + MOVQ trap+0(FP), AX // syscall entry + SYSCALL + MOVQ AX, r1+32(FP) + MOVQ $0, r2+40(FP) + CMPL AX, $-1 + JNE ok3 + + SUBQ $16, SP + CALL runtime·errstr(SB) + MOVQ SP, SI + ADDQ $16, SP + JMP copyresult3 + +ok3: + LEAQ runtime·emptystring(SB), SI + +copyresult3: + LEAQ err+48(FP), DI + + CLD + MOVSQ + MOVSQ + + CALL runtime·exitsyscall(SB) + RET + +// func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) +TEXT ·Syscall6(SB),NOSPLIT,$0-80 + CALL runtime·entersyscall(SB) + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ a4+32(FP), R10 + MOVQ a5+40(FP), R8 + MOVQ a6+48(FP), R9 + MOVQ trap+0(FP), AX // syscall entry + SYSCALL + MOVQ AX, r1+56(FP) + MOVQ $0, r2+64(FP) + CMPL AX, $-1 + JNE ok4 + + SUBQ $16, SP + CALL runtime·errstr(SB) + MOVQ SP, SI + ADDQ $16, SP + JMP copyresult4 + +ok4: + LEAQ runtime·emptystring(SB), SI + +copyresult4: + LEAQ err+72(FP), DI + + CLD + MOVSQ + MOVSQ + + CALL runtime·exitsyscall(SB) + RET + +// func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) +TEXT ·RawSyscall(SB),NOSPLIT,$0-56 + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ $0, R10 + MOVQ $0, R8 + MOVQ $0, R9 + MOVQ trap+0(FP), AX // syscall entry + SYSCALL + MOVQ AX, r1+40(SP) + MOVQ AX, r2+48(SP) + MOVQ AX, err+56(SP) + RET + +// func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) +TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 + MOVQ a1+8(FP), DI + MOVQ a2+16(FP), SI + MOVQ a3+24(FP), DX + MOVQ a4+32(FP), R10 + MOVQ a5+40(FP), R8 + MOVQ a6+48(FP), R9 + MOVQ trap+0(FP), AX // syscall entry + SYSCALL + MOVQ AX, r1+56(FP) + MOVQ DX, r2+64(FP) + MOVQ $0, err+72(FP) + RET + +// func gettimeofday(tv *Timeval) (err uintptr) +TEXT ·gettimeofday(SB),NOSPLIT,$0-16 + MOVQ tv+0(FP), DI + MOVQ $0, SI + MOVQ runtime·__vdso_gettimeofday_sym(SB), AX + CALL AX + + CMPQ AX, $0xfffffffffffff001 + JLS ok7 + NEGQ AX + MOVQ AX, err+8(FP) + RET +ok7: + MOVQ $0, err+8(FP) + RET + + +//func exit(code int) +// Import runtime·exit for cleanly exiting. +TEXT ·exit(SB),NOSPLIT,$8-8 + NO_LOCAL_POINTERS + MOVQ code+0(FP), AX + MOVQ AX, 0(SP) + CALL runtime·exit(SB) + RET + +//func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string) +//TEXT ·seek(SB),NOSPLIT,$0-56 diff --git a/src/syscall/asm_plan9_amd64.s b/src/syscall/asm_plan9_amd64.s index 84050235e0..6e76483734 100644 --- a/src/syscall/asm_plan9_amd64.s +++ b/src/syscall/asm_plan9_amd64.s @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !harvey + #include "textflag.h" #include "funcdata.h" diff --git a/src/syscall/syscall_harvey.go b/src/syscall/syscall_harvey.go new file mode 100644 index 0000000000..46d9f09d14 --- /dev/null +++ b/src/syscall/syscall_harvey.go @@ -0,0 +1,351 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Plan 9 system calls. +// This file is compiled as ordinary Go code, +// but it is also input to mksyscall, +// which parses the //sys lines and generates system call stubs. +// Note that sometimes we use a lowercase //sys name and +// wrap it in our own nicer implementation. + +package syscall + +import "unsafe" + +const ImplementsGetwd = true + +// ErrorString implements Error's String method by returning itself. +type ErrorString string + +func (e ErrorString) Error() string { return string(e) } + +// NewError converts s to an ErrorString, which satisfies the Error interface. +func NewError(s string) error { return ErrorString(s) } + +func (e ErrorString) Temporary() bool { + return e == EINTR || e == EMFILE || e.Timeout() +} + +func (e ErrorString) Timeout() bool { + return e == EBUSY || e == ETIMEDOUT +} + +// A Note is a string describing a process note. +// It implements the os.Signal interface. +type Note string + +func (n Note) Signal() {} + +func (n Note) String() string { + return string(n) +} + +var ( + Stdin = 0 + Stdout = 1 + Stderr = 2 +) + +// For testing: clients can set this flag to force +// creation of IPv6 sockets to return EAFNOSUPPORT. +var SocketDisableIPv6 bool + +func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString) +func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err ErrorString) +func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) +func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) + +//go:nosplit +func atoi(b []byte) (n uint) { + n = 0 + for i := 0; i < len(b); i++ { + n = n*10 + uint(b[i]-'0') + } + return +} + +func cstring(s []byte) string { + for i := range s { + if s[i] == 0 { + return string(s[0:i]) + } + } + return string(s) +} + +func errstr() string { + var buf [ERRMAX]byte + + RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0) + + buf[len(buf)-1] = 0 + return cstring(buf[:]) +} + +// Implemented in assembly to import from runtime. +func exit(code int) + +func Exit(code int) { exit(code) } + +func readnum(path string) (uint, error) { + var b [12]byte + + fd, e := Open(path, O_RDONLY) + if e != nil { + return 0, e + } + defer Close(fd) + + n, e := Pread(fd, b[:], 0) + + if e != nil { + return 0, e + } + + m := 0 + for ; m < n && b[m] == ' '; m++ { + } + + return atoi(b[m : n-1]), nil +} + +func Getpid() (pid int) { + n, _ := readnum("#c/pid") + return int(n) +} + +func Getppid() (ppid int) { + n, _ := readnum("#c/ppid") + return int(n) +} + +func Read(fd int, p []byte) (n int, err error) { + return Pread(fd, p, -1) +} + +func Write(fd int, p []byte) (n int, err error) { + return Pwrite(fd, p, -1) +} + +var ioSync int64 + +//sys fd2path(fd int, buf []byte) (err error) +func Fd2path(fd int) (path string, err error) { + var buf [512]byte + + e := fd2path(fd, buf[:]) + if e != nil { + return "", e + } + return cstring(buf[:]), nil +} + +//sys pipe(p *[2]int32) (err error) +func Pipe(p []int) (err error) { + if len(p) != 2 { + return NewError("bad arg in system call") + } + var pp [2]int32 + err = pipe(&pp) + p[0] = int(pp[0]) + p[1] = int(pp[1]) + return +} + +func Mkdir(path string, mode uint32) (err error) { + fd, err := Create(path, O_RDONLY, DMDIR|mode) + + if fd != -1 { + Close(fd) + } + + return +} + +type Waitmsg struct { + Pid int + Time [3]uint32 + Msg string +} + +func (w Waitmsg) Exited() bool { return true } +func (w Waitmsg) Signaled() bool { return false } + +func (w Waitmsg) ExitStatus() int { + if len(w.Msg) == 0 { + // a normal exit returns no message + return 0 + } + return 1 +} + +//sys await(s []byte) (n int, err error) +func Await(w *Waitmsg) (err error) { + var buf [512]byte + var f [5][]byte + + n, err := await(buf[:]) + + if err != nil || w == nil { + return + } + + nf := 0 + p := 0 + for i := 0; i < n && nf < len(f)-1; i++ { + if buf[i] == ' ' { + f[nf] = buf[p:i] + p = i + 1 + nf++ + } + } + f[nf] = buf[p:] + nf++ + + if nf != len(f) { + return NewError("invalid wait message") + } + w.Pid = int(atoi(f[0])) + w.Time[0] = uint32(atoi(f[1])) + w.Time[1] = uint32(atoi(f[2])) + w.Time[2] = uint32(atoi(f[3])) + w.Msg = cstring(f[4]) + if w.Msg == "''" { + // await() returns '' for no error + w.Msg = "" + } + return +} + +func Unmount(name, old string) (err error) { + Fixwd() + oldp, err := BytePtrFromString(old) + if err != nil { + return err + } + oldptr := uintptr(unsafe.Pointer(oldp)) + + var r0 uintptr + var e ErrorString + + // bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted. + if name == "" { + r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0) + } else { + namep, err := BytePtrFromString(name) + if err != nil { + return err + } + r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0) + } + + if int32(r0) == -1 { + err = e + } + return +} + +func Fchdir(fd int) (err error) { + path, err := Fd2path(fd) + + if err != nil { + return + } + + return Chdir(path) +} + +type Timespec struct { + Sec int32 + Nsec int32 +} + +type Timeval struct { + Sec int32 + Usec int32 +} + +func NsecToTimeval(nsec int64) (tv Timeval) { + nsec += 999 // round up to microsecond + tv.Usec = int32(nsec % 1e9 / 1e3) + tv.Sec = int32(nsec / 1e9) + return +} + +func nsec() int64 { + var scratch int64 + + r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0) + // TODO(aram): remove hack after I fix _nsec in the pc64 kernel. + if r0 == 0 { + return scratch + } + return int64(r0) +} + +func Gettimeofday(tv *Timeval) error { + nsec := nsec() + *tv = NsecToTimeval(nsec) + return nil +} + +func Getegid() (egid int) { return -1 } +func Geteuid() (euid int) { return -1 } +func Getgid() (gid int) { return -1 } +func Getuid() (uid int) { return -1 } + +func Getgroups() (gids []int, err error) { + return make([]int, 0), nil +} + +//sys open(path string, mode int) (fd int, err error) +func Open(path string, mode int) (fd int, err error) { + Fixwd() + return open(path, mode) +} + +//sys create(path string, mode int, perm uint32) (fd int, err error) +func Create(path string, mode int, perm uint32) (fd int, err error) { + Fixwd() + return create(path, mode, perm) +} + +//sys remove(path string) (err error) +func Remove(path string) error { + Fixwd() + return remove(path) +} + +//sys stat(path string, edir []byte) (n int, err error) +func Stat(path string, edir []byte) (n int, err error) { + Fixwd() + return stat(path, edir) +} + +//sys bind(name string, old string, flag int) (err error) +func Bind(name string, old string, flag int) (err error) { + Fixwd() + return bind(name, old, flag) +} + +//sys mount(fd int, afd int, old string, flag int, aname string) (err error) +func Mount(fd int, afd int, old string, flag int, aname string) (err error) { + Fixwd() + return mount(fd, afd, old, flag, aname) +} + +//sys wstat(path string, edir []byte) (err error) +func Wstat(path string, edir []byte) (err error) { + Fixwd() + return wstat(path, edir) +} + +//sys chdir(path string) (err error) +//sys Dup(oldfd int, newfd int) (fd int, err error) +//sys Pread(fd int, p []byte, offset int64) (n int, err error) +//sys Pwrite(fd int, p []byte, offset int64) (n int, err error) +//sys Close(fd int) (err error) +//sys Fstat(fd int, edir []byte) (n int, err error) +//sys Fwstat(fd int, edir []byte) (err error) +//sys Seek(fd int, offset int64, whence int) (off int64, err error) diff --git a/src/syscall/syscall_plan9.go b/src/syscall/syscall_plan9.go index b7a0d543d9..1d6afaecdb 100644 --- a/src/syscall/syscall_plan9.go +++ b/src/syscall/syscall_plan9.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// +build !harvey + // Plan 9 system calls. // This file is compiled as ordinary Go code, // but it is also input to mksyscall, diff --git a/src/syscall/zsyscall_harvey_amd64.go b/src/syscall/zsyscall_harvey_amd64.go new file mode 100644 index 0000000000..7f6f40af08 --- /dev/null +++ b/src/syscall/zsyscall_harvey_amd64.go @@ -0,0 +1,293 @@ +// mksyscall.pl -plan9 syscall_plan9.go +// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT + +package syscall + +import "unsafe" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func fd2path(fd int, buf []byte) (err error) { + var _p0 unsafe.Pointer + if len(buf) > 0 { + _p0 = unsafe.Pointer(&buf[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf))) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func pipe(p *[2]int32) (err error) { + r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func await(s []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(s) > 0 { + _p0 = unsafe.Pointer(&s[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func open(path string, mode int) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) + fd = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func create(path string, mode int, perm uint32) (fd int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm)) + fd = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func remove(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func stat(path string, edir []byte) (n int, err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(edir) > 0 { + _p1 = unsafe.Pointer(&edir[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir))) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func bind(name string, old string, flag int) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(name) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(old) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag)) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mount(fd int, afd int, old string, flag int, aname string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(old) + if err != nil { + return + } + var _p1 *byte + _p1, err = BytePtrFromString(aname) + if err != nil { + return + } + r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func wstat(path string, edir []byte) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + var _p1 unsafe.Pointer + if len(edir) > 0 { + _p1 = unsafe.Pointer(&edir[0]) + } else { + _p1 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir))) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func chdir(path string) (err error) { + var _p0 *byte + _p0, err = BytePtrFromString(path) + if err != nil { + return + } + r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Dup(oldfd int, newfd int) (fd int, err error) { + r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0) + fd = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pread(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Pwrite(fd int, p []byte, offset int64) (n int, err error) { + var _p0 unsafe.Pointer + if len(p) > 0 { + _p0 = unsafe.Pointer(&p[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Close(fd int) (err error) { + r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fstat(fd int, edir []byte) (n int, err error) { + var _p0 unsafe.Pointer + if len(edir) > 0 { + _p0 = unsafe.Pointer(&edir[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir))) + n = int(r0) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Fwstat(fd int, edir []byte) (err error) { + var _p0 unsafe.Pointer + if len(edir) > 0 { + _p0 = unsafe.Pointer(&edir[0]) + } else { + _p0 = unsafe.Pointer(&_zero) + } + r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir))) + if int32(r0) == -1 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func Seek(fd int, offset int64, whence int) (off int64, err error) { + r0, _, e1 := Syscall(SYS_SEEK, uintptr(fd), uintptr(offset), uintptr(whence)) + off = int64(r0) + if int32(r0) == -1 { + err = e1 + } + return +} diff --git a/src/syscall/zsyscall_plan9_amd64.go b/src/syscall/zsyscall_plan9_amd64.go index d3e8b31cf1..7eb9597224 100644 --- a/src/syscall/zsyscall_plan9_amd64.go +++ b/src/syscall/zsyscall_plan9_amd64.go @@ -1,7 +1,7 @@ // mksyscall.pl -l32 -plan9 -tags plan9,amd64 syscall_plan9.go // MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT -// +build plan9,amd64 +// +build plan9,amd64,!harvey package syscall