From a55315860ac1b000d7d84726c7a872ec61b5cae8 Mon Sep 17 00:00:00 2001 From: Andrea Barisani Date: Thu, 27 Feb 2020 15:20:07 +0100 Subject: [PATCH] align GOOS=tamago support to go1.14 --- src/cmd/dist/build.go | 2 +- src/cmd/dist/util.go | 4 + src/internal/poll/fcntl_tamago.go | 14 + src/os/stat_js.go | 2 +- src/os/stat_tamago.go | 54 +++ src/runtime/alg.go | 3 - src/runtime/internal/sys/zgoos_aix.go | 1 + src/runtime/internal/sys/zgoos_android.go | 2 +- src/runtime/internal/sys/zgoos_darwin.go | 2 +- src/runtime/internal/sys/zgoos_dragonfly.go | 2 +- src/runtime/internal/sys/zgoos_freebsd.go | 2 +- src/runtime/internal/sys/zgoos_hurd.go | 1 + src/runtime/internal/sys/zgoos_illumos.go | 1 + src/runtime/internal/sys/zgoos_js.go | 2 +- src/runtime/internal/sys/zgoos_linux.go | 2 +- src/runtime/internal/sys/zgoos_netbsd.go | 2 +- src/runtime/internal/sys/zgoos_openbsd.go | 2 +- src/runtime/internal/sys/zgoos_plan9.go | 2 +- src/runtime/internal/sys/zgoos_solaris.go | 2 +- src/runtime/internal/sys/zgoos_tamago.go | 3 +- src/runtime/internal/sys/zgoos_windows.go | 2 +- src/runtime/internal/sys/zgoos_zos.go | 2 +- src/runtime/lock_tamago.go | 24 +- src/runtime/mem_tamago.go | 2 +- src/runtime/os_tamago_arm.go | 15 +- src/runtime/proc.go | 3 + src/syscall/net_tamago.go | 2 +- src/syscall/syscall_tamago.go | 17 +- src/syscall/tables_js.go | 2 +- src/syscall/tables_tamago.go | 494 ++++++++++++++++++++ 30 files changed, 617 insertions(+), 51 deletions(-) create mode 100644 src/internal/poll/fcntl_tamago.go create mode 100644 src/os/stat_tamago.go create mode 100644 src/syscall/tables_tamago.go diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go index a300227408292a..b24af4f5c16a38 100644 --- a/src/cmd/dist/build.go +++ b/src/cmd/dist/build.go @@ -1556,10 +1556,10 @@ var cgoEnabled = map[string]bool{ "plan9/amd64": false, "plan9/arm": false, "solaris/amd64": true, + "tamago/arm": true, "windows/386": true, "windows/amd64": true, "windows/arm": false, - "tamago/arm": true, } // List of platforms which are supported but not complete yet. These get diff --git a/src/cmd/dist/util.go b/src/cmd/dist/util.go index b9e8a513d96930..8760ce3f196336 100644 --- a/src/cmd/dist/util.go +++ b/src/cmd/dist/util.go @@ -383,6 +383,10 @@ func xsamefile(f1, f2 string) bool { } func xgetgoarm() string { + if goos == "tamago" { + // tamago guarantees VFPv3 and is always cross-compiled. + return "7" + } if goos == "darwin" || goos == "android" { // Assume all darwin/arm and android devices have VFPv3. // These ports are also mostly cross-compiled, so it makes little diff --git a/src/internal/poll/fcntl_tamago.go b/src/internal/poll/fcntl_tamago.go new file mode 100644 index 00000000000000..9106ca526ded28 --- /dev/null +++ b/src/internal/poll/fcntl_tamago.go @@ -0,0 +1,14 @@ +// Copyright 2019 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. + +// +build tamago + +package poll + +import "syscall" + +// fcntl not supported on tamago +func fcntl(fd int, cmd int, arg int) (int, error) { + return 0, syscall.ENOSYS +} diff --git a/src/os/stat_js.go b/src/os/stat_js.go index 63aa5ee6a043dc..8d20ccddfcc43c 100644 --- a/src/os/stat_js.go +++ b/src/os/stat_js.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build js,wasm tamago +// +build js,wasm package os diff --git a/src/os/stat_tamago.go b/src/os/stat_tamago.go new file mode 100644 index 00000000000000..26a707875be7d6 --- /dev/null +++ b/src/os/stat_tamago.go @@ -0,0 +1,54 @@ +// 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. + +// +build tamago + +package os + +import ( + "syscall" + "time" +) + +func fillFileStatFromSys(fs *fileStat, name string) { + fs.name = basename(name) + fs.size = fs.sys.Size + fs.modTime = timespecToTime(fs.sys.Mtime, fs.sys.MtimeNsec) + fs.mode = FileMode(fs.sys.Mode & 0777) + switch fs.sys.Mode & syscall.S_IFMT { + case syscall.S_IFBLK: + fs.mode |= ModeDevice + case syscall.S_IFCHR: + fs.mode |= ModeDevice | ModeCharDevice + case syscall.S_IFDIR: + fs.mode |= ModeDir + case syscall.S_IFIFO: + fs.mode |= ModeNamedPipe + case syscall.S_IFLNK: + fs.mode |= ModeSymlink + case syscall.S_IFREG: + // nothing to do + case syscall.S_IFSOCK: + fs.mode |= ModeSocket + } + if fs.sys.Mode&syscall.S_ISGID != 0 { + fs.mode |= ModeSetgid + } + if fs.sys.Mode&syscall.S_ISUID != 0 { + fs.mode |= ModeSetuid + } + if fs.sys.Mode&syscall.S_ISVTX != 0 { + fs.mode |= ModeSticky + } +} + +func timespecToTime(sec, nsec int64) time.Time { + return time.Unix(sec, nsec) +} + +// For testing. +func atime(fi FileInfo) time.Time { + st := fi.Sys().(*syscall.Stat_t) + return timespecToTime(st.Atime, st.AtimeNsec) +} diff --git a/src/runtime/alg.go b/src/runtime/alg.go index 953bb2bae8cdb7..0af48ab25cc3b1 100644 --- a/src/runtime/alg.go +++ b/src/runtime/alg.go @@ -357,9 +357,6 @@ func alginit() { initAlgAES() return } - if GOOS == "tamago" { - initRNG() - } getRandomData((*[len(hashkey) * sys.PtrSize]byte)(unsafe.Pointer(&hashkey))[:]) hashkey[0] |= 1 // make sure these numbers are odd hashkey[1] |= 1 diff --git a/src/runtime/internal/sys/zgoos_aix.go b/src/runtime/internal/sys/zgoos_aix.go index 7c3acf0441a519..7ef733d0aed3fe 100644 --- a/src/runtime/internal/sys/zgoos_aix.go +++ b/src/runtime/internal/sys/zgoos_aix.go @@ -15,6 +15,7 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 +const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 diff --git a/src/runtime/internal/sys/zgoos_android.go b/src/runtime/internal/sys/zgoos_android.go index 0a07df1d468559..daf916c734a141 100644 --- a/src/runtime/internal/sys/zgoos_android.go +++ b/src/runtime/internal/sys/zgoos_android.go @@ -15,11 +15,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_darwin.go b/src/runtime/internal/sys/zgoos_darwin.go index 6c1c72808b7ff7..35007398c4b42a 100644 --- a/src/runtime/internal/sys/zgoos_darwin.go +++ b/src/runtime/internal/sys/zgoos_darwin.go @@ -15,11 +15,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_dragonfly.go b/src/runtime/internal/sys/zgoos_dragonfly.go index 9689e20e0d1c1b..39d0ed4a21fbfe 100644 --- a/src/runtime/internal/sys/zgoos_dragonfly.go +++ b/src/runtime/internal/sys/zgoos_dragonfly.go @@ -15,11 +15,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_freebsd.go b/src/runtime/internal/sys/zgoos_freebsd.go index dcf155e1224b7f..0083ebbd99226e 100644 --- a/src/runtime/internal/sys/zgoos_freebsd.go +++ b/src/runtime/internal/sys/zgoos_freebsd.go @@ -15,11 +15,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_hurd.go b/src/runtime/internal/sys/zgoos_hurd.go index d6dcc7bad456b5..627edb2ee4c25d 100644 --- a/src/runtime/internal/sys/zgoos_hurd.go +++ b/src/runtime/internal/sys/zgoos_hurd.go @@ -20,5 +20,6 @@ const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_illumos.go b/src/runtime/internal/sys/zgoos_illumos.go index 17f4ecc34edc3d..1efa2ba3489c59 100644 --- a/src/runtime/internal/sys/zgoos_illumos.go +++ b/src/runtime/internal/sys/zgoos_illumos.go @@ -20,5 +20,6 @@ const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_js.go b/src/runtime/internal/sys/zgoos_js.go index 42a7a31d709f26..0d06c09d292d6f 100644 --- a/src/runtime/internal/sys/zgoos_js.go +++ b/src/runtime/internal/sys/zgoos_js.go @@ -15,11 +15,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 1 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_linux.go b/src/runtime/internal/sys/zgoos_linux.go index 4e1dd2cdaa455a..7b21b5a620181e 100644 --- a/src/runtime/internal/sys/zgoos_linux.go +++ b/src/runtime/internal/sys/zgoos_linux.go @@ -16,11 +16,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 1 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_netbsd.go b/src/runtime/internal/sys/zgoos_netbsd.go index d72aa592841dcc..70df7d6fa70873 100644 --- a/src/runtime/internal/sys/zgoos_netbsd.go +++ b/src/runtime/internal/sys/zgoos_netbsd.go @@ -15,11 +15,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 1 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_openbsd.go b/src/runtime/internal/sys/zgoos_openbsd.go index 5974214bec8097..7ddd880f1cc555 100644 --- a/src/runtime/internal/sys/zgoos_openbsd.go +++ b/src/runtime/internal/sys/zgoos_openbsd.go @@ -15,11 +15,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 1 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_plan9.go b/src/runtime/internal/sys/zgoos_plan9.go index b49a32238539f6..cf464505650096 100644 --- a/src/runtime/internal/sys/zgoos_plan9.go +++ b/src/runtime/internal/sys/zgoos_plan9.go @@ -15,11 +15,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 1 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_solaris.go b/src/runtime/internal/sys/zgoos_solaris.go index a1db13a66b625f..045ba4f0e7b9c3 100644 --- a/src/runtime/internal/sys/zgoos_solaris.go +++ b/src/runtime/internal/sys/zgoos_solaris.go @@ -16,11 +16,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 1 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_tamago.go b/src/runtime/internal/sys/zgoos_tamago.go index e2bd9eb87cec44..4deff4fdf5fb89 100644 --- a/src/runtime/internal/sys/zgoos_tamago.go +++ b/src/runtime/internal/sys/zgoos_tamago.go @@ -12,13 +12,14 @@ const GoosDarwin = 0 const GoosDragonfly = 0 const GoosFreebsd = 0 const GoosHurd = 0 +const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 1 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 1 const GoosWindows = 0 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_windows.go b/src/runtime/internal/sys/zgoos_windows.go index 3d6f9879d17f6d..ce3e008344e601 100644 --- a/src/runtime/internal/sys/zgoos_windows.go +++ b/src/runtime/internal/sys/zgoos_windows.go @@ -15,11 +15,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 1 const GoosZos = 0 diff --git a/src/runtime/internal/sys/zgoos_zos.go b/src/runtime/internal/sys/zgoos_zos.go index 8871b4c9544f74..ef243a281b47d9 100644 --- a/src/runtime/internal/sys/zgoos_zos.go +++ b/src/runtime/internal/sys/zgoos_zos.go @@ -15,11 +15,11 @@ const GoosHurd = 0 const GoosIllumos = 0 const GoosJs = 0 const GoosLinux = 0 -const GoosTamago = 0 const GoosNacl = 0 const GoosNetbsd = 0 const GoosOpenbsd = 0 const GoosPlan9 = 0 const GoosSolaris = 0 +const GoosTamago = 0 const GoosWindows = 0 const GoosZos = 1 diff --git a/src/runtime/lock_tamago.go b/src/runtime/lock_tamago.go index b96ec381da19d0..1a1d22a2d45399 100644 --- a/src/runtime/lock_tamago.go +++ b/src/runtime/lock_tamago.go @@ -142,27 +142,9 @@ func checkTimeouts() { } } -var returnedEventHandler *g - -func init() { - // At the toplevel we need an extra goroutine that handles asynchronous events. - initg := getg() - go func() { - returnedEventHandler = getg() - goready(initg, 1) - - gopark(nil, nil, waitReasonZero, traceEvNone, 1) - returnedEventHandler = nil - }() - gopark(nil, nil, waitReasonZero, traceEvNone, 1) -} - // beforeIdle gets called by the scheduler if no goroutine is awake. -// We resume the event handler (if available) which will pause the execution. -func beforeIdle() bool { - if returnedEventHandler != nil { - goready(returnedEventHandler, 1) - return true - } +// If we are not already handling an event, then we pause for an async event. +// If an event handler returned, we resume it and it will pause the execution. +func beforeIdle(delay int64) bool { return false } diff --git a/src/runtime/mem_tamago.go b/src/runtime/mem_tamago.go index f42eef54b66c80..2a2bbe7f3bd266 100644 --- a/src/runtime/mem_tamago.go +++ b/src/runtime/mem_tamago.go @@ -196,7 +196,7 @@ func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer { // so try to extend the address space. p = sbrk(n) } - if p == nil { + if p == nil && v == nil { p = memAlloc(n) memCheck() } diff --git a/src/runtime/os_tamago_arm.go b/src/runtime/os_tamago_arm.go index 3f3628b1aecbdd..91bf483a83b953 100644 --- a/src/runtime/os_tamago_arm.go +++ b/src/runtime/os_tamago_arm.go @@ -50,8 +50,7 @@ func initRNG() // the following functions must be provided externally // (but are already stubbed somewhere else in the runtime) -//func initRNG() -//func nanotime() int64 +//func nanotime1() int64 // the following functions are defined in sys_tamago_arm.s func set_vbar(addr unsafe.Pointer) @@ -356,7 +355,7 @@ func syscall(number, a1, a2, a3 uintptr) (r1, r2, err uintptr) { } //go:nosplit -func write(fd uintptr, buf unsafe.Pointer, count int32) int32 { +func write1(fd uintptr, buf unsafe.Pointer, count int32) int32 { if fd != 1 && fd != 2 { throw("unexpected fd, only stdout/stderr are supported") } @@ -378,7 +377,7 @@ func syscall_now() (sec int64, nsec int32) { } //go:nosplit -func walltime() (sec int64, nsec int32) { +func walltime1() (sec int64, nsec int32) { // TODO: probably better implement this in sys_tamago_arm.s for better // performance nano := nanotime() @@ -409,3 +408,11 @@ func exitThread(wait *uint32) { // We should never reach exitThread throw("exitThread: not implemented") } + +const preemptMSupported = false + +func preemptM(mp *m) { + // Not currently supported. + // + // TODO: Use a note like we use signals on POSIX OSes +} diff --git a/src/runtime/proc.go b/src/runtime/proc.go index d4fc80c654b0e6..237e2367435ece 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -651,6 +651,9 @@ func mcommoninit(mp *m) { var fastrandseed uintptr func fastrandinit() { + if GOOS == "tamago" { + initRNG() + } s := (*[unsafe.Sizeof(fastrandseed)]byte)(unsafe.Pointer(&fastrandseed))[:] getRandomData(s) } diff --git a/src/syscall/net_tamago.go b/src/syscall/net_tamago.go index 409a7a4e277ee3..da967ddec0719a 100644 --- a/src/syscall/net_tamago.go +++ b/src/syscall/net_tamago.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// A simulated network for use within NaCl. +// A simulated network for use within tamago (adapted from net_nacl.go). // The simulation is not particularly tied to NaCl, // but other systems have real networks. diff --git a/src/syscall/syscall_tamago.go b/src/syscall/syscall_tamago.go index dd7a2d7692b62f..acb7a18de5da5b 100644 --- a/src/syscall/syscall_tamago.go +++ b/src/syscall/syscall_tamago.go @@ -24,7 +24,7 @@ type Dirent struct { } func direntIno(buf []byte) (uint64, bool) { - return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino)) + return 1, true } func direntReclen(buf []byte) (uint64, bool) { @@ -48,6 +48,12 @@ const PathMax = 256 // if errno != 0 { // err = errno // } +// +// Errno values can be tested against error values from the os package +// using errors.Is. For example: +// +// _, _, err := syscall.Syscall(...) +// if errors.Is(err, os.ErrNotExist) ... type Errno uintptr func (e Errno) Error() string { @@ -91,6 +97,7 @@ const ( SIGKILL SIGTRAP SIGQUIT + SIGTERM ) func (s Signal) Signal() {} @@ -116,9 +123,9 @@ const ( ) const ( - O_RDONLY = 0 - O_WRONLY = 1 - O_RDWR = 2 + O_RDONLY = 0 + O_WRONLY = 1 + O_RDWR = 2 O_ACCMODE = 3 O_CREAT = 0100 @@ -218,7 +225,7 @@ type Stat_t struct { } // Processes -// Not supported on tamago - just enough for package os. +// Not supported - just enough for package os. var ForkLock sync.RWMutex diff --git a/src/syscall/tables_js.go b/src/syscall/tables_js.go index ee3a647cfa4a1d..a7c4f8c890fbdb 100644 --- a/src/syscall/tables_js.go +++ b/src/syscall/tables_js.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build js,wasm tamago +// +build js,wasm package syscall diff --git a/src/syscall/tables_tamago.go b/src/syscall/tables_tamago.go new file mode 100644 index 00000000000000..94fa0c00a91b4f --- /dev/null +++ b/src/syscall/tables_tamago.go @@ -0,0 +1,494 @@ +// Copyright 2013 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. + +// +build tamago + +package syscall + +import "runtime" + +// These were originally used by Nacl, then later also used by +// tamago. Now that they're only used by tamago, these numbers are +// just arbitrary. +// +// TODO: delete? replace with something meaningful? +const ( + sys_null = 1 + sys_nameservice = 2 + sys_dup = 8 + sys_dup2 = 9 + sys_open = 10 + sys_close = 11 + sys_read = 12 + sys_write = 13 + sys_lseek = 14 + sys_stat = 16 + sys_fstat = 17 + sys_chmod = 18 + sys_isatty = 19 + sys_brk = 20 + sys_mmap = 21 + sys_munmap = 22 + sys_getdents = 23 + sys_mprotect = 24 + sys_list_mappings = 25 + sys_exit = 30 + sys_getpid = 31 + sys_sched_yield = 32 + sys_sysconf = 33 + sys_gettimeofday = 40 + sys_clock = 41 + sys_nanosleep = 42 + sys_clock_getres = 43 + sys_clock_gettime = 44 + sys_mkdir = 45 + sys_rmdir = 46 + sys_chdir = 47 + sys_getcwd = 48 + sys_unlink = 49 + sys_imc_makeboundsock = 60 + sys_imc_accept = 61 + sys_imc_connect = 62 + sys_imc_sendmsg = 63 + sys_imc_recvmsg = 64 + sys_imc_mem_obj_create = 65 + sys_imc_socketpair = 66 + sys_mutex_create = 70 + sys_mutex_lock = 71 + sys_mutex_trylock = 72 + sys_mutex_unlock = 73 + sys_cond_create = 74 + sys_cond_wait = 75 + sys_cond_signal = 76 + sys_cond_broadcast = 77 + sys_cond_timed_wait_abs = 79 + sys_thread_create = 80 + sys_thread_exit = 81 + sys_tls_init = 82 + sys_thread_nice = 83 + sys_tls_get = 84 + sys_second_tls_set = 85 + sys_second_tls_get = 86 + sys_exception_handler = 87 + sys_exception_stack = 88 + sys_exception_clear_flag = 89 + sys_sem_create = 100 + sys_sem_wait = 101 + sys_sem_post = 102 + sys_sem_get_value = 103 + sys_dyncode_create = 104 + sys_dyncode_modify = 105 + sys_dyncode_delete = 106 + sys_test_infoleak = 109 + sys_test_crash = 110 + sys_test_syscall_1 = 111 + sys_test_syscall_2 = 112 + sys_futex_wait_abs = 120 + sys_futex_wake = 121 + sys_pread = 130 + sys_pwrite = 131 + sys_truncate = 140 + sys_lstat = 141 + sys_link = 142 + sys_rename = 143 + sys_symlink = 144 + sys_access = 145 + sys_readlink = 146 + sys_utimes = 147 + sys_get_random_bytes = 150 +) + +// TODO: Auto-generate some day. (Hard-coded in binaries so not likely to change.) +const ( + // native_client/src/trusted/service_runtime/include/sys/errno.h + // The errors are mainly copied from Linux. + EPERM Errno = 1 /* Operation not permitted */ + ENOENT Errno = 2 /* No such file or directory */ + ESRCH Errno = 3 /* No such process */ + EINTR Errno = 4 /* Interrupted system call */ + EIO Errno = 5 /* I/O error */ + ENXIO Errno = 6 /* No such device or address */ + E2BIG Errno = 7 /* Argument list too long */ + ENOEXEC Errno = 8 /* Exec format error */ + EBADF Errno = 9 /* Bad file number */ + ECHILD Errno = 10 /* No child processes */ + EAGAIN Errno = 11 /* Try again */ + ENOMEM Errno = 12 /* Out of memory */ + EACCES Errno = 13 /* Permission denied */ + EFAULT Errno = 14 /* Bad address */ + EBUSY Errno = 16 /* Device or resource busy */ + EEXIST Errno = 17 /* File exists */ + EXDEV Errno = 18 /* Cross-device link */ + ENODEV Errno = 19 /* No such device */ + ENOTDIR Errno = 20 /* Not a directory */ + EISDIR Errno = 21 /* Is a directory */ + EINVAL Errno = 22 /* Invalid argument */ + ENFILE Errno = 23 /* File table overflow */ + EMFILE Errno = 24 /* Too many open files */ + ENOTTY Errno = 25 /* Not a typewriter */ + EFBIG Errno = 27 /* File too large */ + ENOSPC Errno = 28 /* No space left on device */ + ESPIPE Errno = 29 /* Illegal seek */ + EROFS Errno = 30 /* Read-only file system */ + EMLINK Errno = 31 /* Too many links */ + EPIPE Errno = 32 /* Broken pipe */ + ENAMETOOLONG Errno = 36 /* File name too long */ + ENOSYS Errno = 38 /* Function not implemented */ + EDQUOT Errno = 122 /* Quota exceeded */ + EDOM Errno = 33 /* Math arg out of domain of func */ + ERANGE Errno = 34 /* Math result not representable */ + EDEADLK Errno = 35 /* Deadlock condition */ + ENOLCK Errno = 37 /* No record locks available */ + ENOTEMPTY Errno = 39 /* Directory not empty */ + ELOOP Errno = 40 /* Too many symbolic links */ + ENOMSG Errno = 42 /* No message of desired type */ + EIDRM Errno = 43 /* Identifier removed */ + ECHRNG Errno = 44 /* Channel number out of range */ + EL2NSYNC Errno = 45 /* Level 2 not synchronized */ + EL3HLT Errno = 46 /* Level 3 halted */ + EL3RST Errno = 47 /* Level 3 reset */ + ELNRNG Errno = 48 /* Link number out of range */ + EUNATCH Errno = 49 /* Protocol driver not attached */ + ENOCSI Errno = 50 /* No CSI structure available */ + EL2HLT Errno = 51 /* Level 2 halted */ + EBADE Errno = 52 /* Invalid exchange */ + EBADR Errno = 53 /* Invalid request descriptor */ + EXFULL Errno = 54 /* Exchange full */ + ENOANO Errno = 55 /* No anode */ + EBADRQC Errno = 56 /* Invalid request code */ + EBADSLT Errno = 57 /* Invalid slot */ + EDEADLOCK Errno = EDEADLK /* File locking deadlock error */ + EBFONT Errno = 59 /* Bad font file fmt */ + ENOSTR Errno = 60 /* Device not a stream */ + ENODATA Errno = 61 /* No data (for no delay io) */ + ETIME Errno = 62 /* Timer expired */ + ENOSR Errno = 63 /* Out of streams resources */ + ENONET Errno = 64 /* Machine is not on the network */ + ENOPKG Errno = 65 /* Package not installed */ + EREMOTE Errno = 66 /* The object is remote */ + ENOLINK Errno = 67 /* The link has been severed */ + EADV Errno = 68 /* Advertise error */ + ESRMNT Errno = 69 /* Srmount error */ + ECOMM Errno = 70 /* Communication error on send */ + EPROTO Errno = 71 /* Protocol error */ + EMULTIHOP Errno = 72 /* Multihop attempted */ + EDOTDOT Errno = 73 /* Cross mount point (not really error) */ + EBADMSG Errno = 74 /* Trying to read unreadable message */ + EOVERFLOW Errno = 75 /* Value too large for defined data type */ + ENOTUNIQ Errno = 76 /* Given log. name not unique */ + EBADFD Errno = 77 /* f.d. invalid for this operation */ + EREMCHG Errno = 78 /* Remote address changed */ + ELIBACC Errno = 79 /* Can't access a needed shared lib */ + ELIBBAD Errno = 80 /* Accessing a corrupted shared lib */ + ELIBSCN Errno = 81 /* .lib section in a.out corrupted */ + ELIBMAX Errno = 82 /* Attempting to link in too many libs */ + ELIBEXEC Errno = 83 /* Attempting to exec a shared library */ + EILSEQ Errno = 84 + EUSERS Errno = 87 + ENOTSOCK Errno = 88 /* Socket operation on non-socket */ + EDESTADDRREQ Errno = 89 /* Destination address required */ + EMSGSIZE Errno = 90 /* Message too long */ + EPROTOTYPE Errno = 91 /* Protocol wrong type for socket */ + ENOPROTOOPT Errno = 92 /* Protocol not available */ + EPROTONOSUPPORT Errno = 93 /* Unknown protocol */ + ESOCKTNOSUPPORT Errno = 94 /* Socket type not supported */ + EOPNOTSUPP Errno = 95 /* Operation not supported on transport endpoint */ + EPFNOSUPPORT Errno = 96 /* Protocol family not supported */ + EAFNOSUPPORT Errno = 97 /* Address family not supported by protocol family */ + EADDRINUSE Errno = 98 /* Address already in use */ + EADDRNOTAVAIL Errno = 99 /* Address not available */ + ENETDOWN Errno = 100 /* Network interface is not configured */ + ENETUNREACH Errno = 101 /* Network is unreachable */ + ENETRESET Errno = 102 + ECONNABORTED Errno = 103 /* Connection aborted */ + ECONNRESET Errno = 104 /* Connection reset by peer */ + ENOBUFS Errno = 105 /* No buffer space available */ + EISCONN Errno = 106 /* Socket is already connected */ + ENOTCONN Errno = 107 /* Socket is not connected */ + ESHUTDOWN Errno = 108 /* Can't send after socket shutdown */ + ETOOMANYREFS Errno = 109 + ETIMEDOUT Errno = 110 /* Connection timed out */ + ECONNREFUSED Errno = 111 /* Connection refused */ + EHOSTDOWN Errno = 112 /* Host is down */ + EHOSTUNREACH Errno = 113 /* Host is unreachable */ + EALREADY Errno = 114 /* Socket already connected */ + EINPROGRESS Errno = 115 /* Connection already in progress */ + ESTALE Errno = 116 + ENOTSUP Errno = EOPNOTSUPP /* Not supported */ + ENOMEDIUM Errno = 123 /* No medium (in tape drive) */ + ECANCELED Errno = 125 /* Operation canceled. */ + ELBIN Errno = 2048 /* Inode is remote (not really error) */ + EFTYPE Errno = 2049 /* Inappropriate file type or format */ + ENMFILE Errno = 2050 /* No more files */ + EPROCLIM Errno = 2051 + ENOSHARE Errno = 2052 /* No such host or network path */ + ECASECLASH Errno = 2053 /* Filename exists with different case */ + EWOULDBLOCK Errno = EAGAIN /* Operation would block */ +) + +// TODO: Auto-generate some day. (Hard-coded in binaries so not likely to change.) +var errorstr = [...]string{ + EPERM: "Operation not permitted", + ENOENT: "No such file or directory", + ESRCH: "No such process", + EINTR: "Interrupted system call", + EIO: "I/O error", + ENXIO: "No such device or address", + E2BIG: "Argument list too long", + ENOEXEC: "Exec format error", + EBADF: "Bad file number", + ECHILD: "No child processes", + EAGAIN: "Try again", + ENOMEM: "Out of memory", + EACCES: "Permission denied", + EFAULT: "Bad address", + EBUSY: "Device or resource busy", + EEXIST: "File exists", + EXDEV: "Cross-device link", + ENODEV: "No such device", + ENOTDIR: "Not a directory", + EISDIR: "Is a directory", + EINVAL: "Invalid argument", + ENFILE: "File table overflow", + EMFILE: "Too many open files", + ENOTTY: "Not a typewriter", + EFBIG: "File too large", + ENOSPC: "No space left on device", + ESPIPE: "Illegal seek", + EROFS: "Read-only file system", + EMLINK: "Too many links", + EPIPE: "Broken pipe", + ENAMETOOLONG: "File name too long", + ENOSYS: "not implemented on " + runtime.GOOS, + EDQUOT: "Quota exceeded", + EDOM: "Math arg out of domain of func", + ERANGE: "Math result not representable", + EDEADLK: "Deadlock condition", + ENOLCK: "No record locks available", + ENOTEMPTY: "Directory not empty", + ELOOP: "Too many symbolic links", + ENOMSG: "No message of desired type", + EIDRM: "Identifier removed", + ECHRNG: "Channel number out of range", + EL2NSYNC: "Level 2 not synchronized", + EL3HLT: "Level 3 halted", + EL3RST: "Level 3 reset", + ELNRNG: "Link number out of range", + EUNATCH: "Protocol driver not attached", + ENOCSI: "No CSI structure available", + EL2HLT: "Level 2 halted", + EBADE: "Invalid exchange", + EBADR: "Invalid request descriptor", + EXFULL: "Exchange full", + ENOANO: "No anode", + EBADRQC: "Invalid request code", + EBADSLT: "Invalid slot", + EBFONT: "Bad font file fmt", + ENOSTR: "Device not a stream", + ENODATA: "No data (for no delay io)", + ETIME: "Timer expired", + ENOSR: "Out of streams resources", + ENONET: "Machine is not on the network", + ENOPKG: "Package not installed", + EREMOTE: "The object is remote", + ENOLINK: "The link has been severed", + EADV: "Advertise error", + ESRMNT: "Srmount error", + ECOMM: "Communication error on send", + EPROTO: "Protocol error", + EMULTIHOP: "Multihop attempted", + EDOTDOT: "Cross mount point (not really error)", + EBADMSG: "Trying to read unreadable message", + EOVERFLOW: "Value too large for defined data type", + ENOTUNIQ: "Given log. name not unique", + EBADFD: "f.d. invalid for this operation", + EREMCHG: "Remote address changed", + ELIBACC: "Can't access a needed shared lib", + ELIBBAD: "Accessing a corrupted shared lib", + ELIBSCN: ".lib section in a.out corrupted", + ELIBMAX: "Attempting to link in too many libs", + ELIBEXEC: "Attempting to exec a shared library", + ENOTSOCK: "Socket operation on non-socket", + EDESTADDRREQ: "Destination address required", + EMSGSIZE: "Message too long", + EPROTOTYPE: "Protocol wrong type for socket", + ENOPROTOOPT: "Protocol not available", + EPROTONOSUPPORT: "Unknown protocol", + ESOCKTNOSUPPORT: "Socket type not supported", + EOPNOTSUPP: "Operation not supported on transport endpoint", + EPFNOSUPPORT: "Protocol family not supported", + EAFNOSUPPORT: "Address family not supported by protocol family", + EADDRINUSE: "Address already in use", + EADDRNOTAVAIL: "Address not available", + ENETDOWN: "Network interface is not configured", + ENETUNREACH: "Network is unreachable", + ECONNABORTED: "Connection aborted", + ECONNRESET: "Connection reset by peer", + ENOBUFS: "No buffer space available", + EISCONN: "Socket is already connected", + ENOTCONN: "Socket is not connected", + ESHUTDOWN: "Can't send after socket shutdown", + ETIMEDOUT: "Connection timed out", + ECONNREFUSED: "Connection refused", + EHOSTDOWN: "Host is down", + EHOSTUNREACH: "Host is unreachable", + EALREADY: "Socket already connected", + EINPROGRESS: "Connection already in progress", + ENOMEDIUM: "No medium (in tape drive)", + ECANCELED: "Operation canceled.", + ELBIN: "Inode is remote (not really error)", + EFTYPE: "Inappropriate file type or format", + ENMFILE: "No more files", + ENOSHARE: "No such host or network path", + ECASECLASH: "Filename exists with different case", +} + +// Do the interface allocations only once for common +// Errno values. +var ( + errEAGAIN error = EAGAIN + errEINVAL error = EINVAL + errENOENT error = ENOENT +) + +// errnoErr returns common boxed Errno values, to prevent +// allocations at runtime. +func errnoErr(e Errno) error { + switch e { + case 0: + return nil + case EAGAIN: + return errEAGAIN + case EINVAL: + return errEINVAL + case ENOENT: + return errENOENT + } + return e +} + +var errnoByCode = map[string]Errno{ + "EPERM": EPERM, + "ENOENT": ENOENT, + "ESRCH": ESRCH, + "EINTR": EINTR, + "EIO": EIO, + "ENXIO": ENXIO, + "E2BIG": E2BIG, + "ENOEXEC": ENOEXEC, + "EBADF": EBADF, + "ECHILD": ECHILD, + "EAGAIN": EAGAIN, + "ENOMEM": ENOMEM, + "EACCES": EACCES, + "EFAULT": EFAULT, + "EBUSY": EBUSY, + "EEXIST": EEXIST, + "EXDEV": EXDEV, + "ENODEV": ENODEV, + "ENOTDIR": ENOTDIR, + "EISDIR": EISDIR, + "EINVAL": EINVAL, + "ENFILE": ENFILE, + "EMFILE": EMFILE, + "ENOTTY": ENOTTY, + "EFBIG": EFBIG, + "ENOSPC": ENOSPC, + "ESPIPE": ESPIPE, + "EROFS": EROFS, + "EMLINK": EMLINK, + "EPIPE": EPIPE, + "ENAMETOOLONG": ENAMETOOLONG, + "ENOSYS": ENOSYS, + "EDQUOT": EDQUOT, + "EDOM": EDOM, + "ERANGE": ERANGE, + "EDEADLK": EDEADLK, + "ENOLCK": ENOLCK, + "ENOTEMPTY": ENOTEMPTY, + "ELOOP": ELOOP, + "ENOMSG": ENOMSG, + "EIDRM": EIDRM, + "ECHRNG": ECHRNG, + "EL2NSYNC": EL2NSYNC, + "EL3HLT": EL3HLT, + "EL3RST": EL3RST, + "ELNRNG": ELNRNG, + "EUNATCH": EUNATCH, + "ENOCSI": ENOCSI, + "EL2HLT": EL2HLT, + "EBADE": EBADE, + "EBADR": EBADR, + "EXFULL": EXFULL, + "ENOANO": ENOANO, + "EBADRQC": EBADRQC, + "EBADSLT": EBADSLT, + "EDEADLOCK": EDEADLOCK, + "EBFONT": EBFONT, + "ENOSTR": ENOSTR, + "ENODATA": ENODATA, + "ETIME": ETIME, + "ENOSR": ENOSR, + "ENONET": ENONET, + "ENOPKG": ENOPKG, + "EREMOTE": EREMOTE, + "ENOLINK": ENOLINK, + "EADV": EADV, + "ESRMNT": ESRMNT, + "ECOMM": ECOMM, + "EPROTO": EPROTO, + "EMULTIHOP": EMULTIHOP, + "EDOTDOT": EDOTDOT, + "EBADMSG": EBADMSG, + "EOVERFLOW": EOVERFLOW, + "ENOTUNIQ": ENOTUNIQ, + "EBADFD": EBADFD, + "EREMCHG": EREMCHG, + "ELIBACC": ELIBACC, + "ELIBBAD": ELIBBAD, + "ELIBSCN": ELIBSCN, + "ELIBMAX": ELIBMAX, + "ELIBEXEC": ELIBEXEC, + "EILSEQ": EILSEQ, + "EUSERS": EUSERS, + "ENOTSOCK": ENOTSOCK, + "EDESTADDRREQ": EDESTADDRREQ, + "EMSGSIZE": EMSGSIZE, + "EPROTOTYPE": EPROTOTYPE, + "ENOPROTOOPT": ENOPROTOOPT, + "EPROTONOSUPPORT": EPROTONOSUPPORT, + "ESOCKTNOSUPPORT": ESOCKTNOSUPPORT, + "EOPNOTSUPP": EOPNOTSUPP, + "EPFNOSUPPORT": EPFNOSUPPORT, + "EAFNOSUPPORT": EAFNOSUPPORT, + "EADDRINUSE": EADDRINUSE, + "EADDRNOTAVAIL": EADDRNOTAVAIL, + "ENETDOWN": ENETDOWN, + "ENETUNREACH": ENETUNREACH, + "ENETRESET": ENETRESET, + "ECONNABORTED": ECONNABORTED, + "ECONNRESET": ECONNRESET, + "ENOBUFS": ENOBUFS, + "EISCONN": EISCONN, + "ENOTCONN": ENOTCONN, + "ESHUTDOWN": ESHUTDOWN, + "ETOOMANYREFS": ETOOMANYREFS, + "ETIMEDOUT": ETIMEDOUT, + "ECONNREFUSED": ECONNREFUSED, + "EHOSTDOWN": EHOSTDOWN, + "EHOSTUNREACH": EHOSTUNREACH, + "EALREADY": EALREADY, + "EINPROGRESS": EINPROGRESS, + "ESTALE": ESTALE, + "ENOTSUP": ENOTSUP, + "ENOMEDIUM": ENOMEDIUM, + "ECANCELED": ECANCELED, + "ELBIN": ELBIN, + "EFTYPE": EFTYPE, + "ENMFILE": ENMFILE, + "EPROCLIM": EPROCLIM, + "ENOSHARE": ENOSHARE, + "ECASECLASH": ECASECLASH, + "EWOULDBLOCK": EWOULDBLOCK, +}