Skip to content
Permalink
Browse files

syscall: implement syscalls on Darwin using libSystem

There are still some references to the bare Syscall functions
in the stdlib. I will root those out in a following CL.
(This CL is big enough as it is.)
Most are in vendor directories:

cmd/vendor/golang.org/x/sys/unix/
vendor/golang_org/x/net/route/syscall.go
syscall/bpf_bsd.go
syscall/exec_unix.go
syscall/flock.go

Update #17490

Change-Id: I69ab707811530c26b652b291cadee92f5bf5c1a4
Reviewed-on: https://go-review.googlesource.com/c/141639
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Elias Naur <elias.naur@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
  • Loading branch information...
randall77 committed Sep 24, 2018
1 parent 0fcd405 commit a3b01440fef3d2833909f6651455924a1c86d192
Showing with 4,996 additions and 689 deletions.
  1. +3 −1 src/cmd/internal/obj/x86/asm6.go
  2. +10 −6 src/internal/poll/fd_fsync_darwin.go
  3. +9 −1 src/internal/poll/fd_fsync_posix.go
  4. +16 −0 src/internal/poll/fd_fsync_windows.go
  5. +5 −4 src/internal/poll/fd_unix.go
  6. +16 −0 src/internal/poll/fd_writev_darwin.go
  7. +20 −0 src/internal/poll/fd_writev_unix.go
  8. +7 −12 src/internal/poll/writev.go
  9. +5 −0 src/internal/syscall/unix/empty.s
  10. +1 −1 src/internal/syscall/unix/nonblocking.go
  11. +24 −0 src/internal/syscall/unix/nonblocking_darwin.go
  12. +55 −0 src/runtime/sys_darwin.go
  13. +21 −0 src/runtime/sys_darwin_32.go
  14. +234 −0 src/runtime/sys_darwin_386.s
  15. +21 −0 src/runtime/sys_darwin_64.go
  16. +196 −0 src/runtime/sys_darwin_amd64.s
  17. +174 −0 src/runtime/sys_darwin_arm.s
  18. +183 −1 src/runtime/sys_darwin_arm64.s
  19. +3 −14 src/syscall/exec_bsd.go
  20. +248 −0 src/syscall/exec_darwin.go
  21. +15 −1 src/syscall/mkall.sh
  22. +53 −0 src/syscall/mkasm_darwin.go
  23. +41 −0 src/syscall/mksyscall.pl
  24. +0 −2 src/syscall/syscall_bsd.go
  25. +70 −16 src/syscall/syscall_darwin.go
  26. +10 −18 src/syscall/syscall_darwin_386.go
  27. +10 −18 src/syscall/syscall_darwin_amd64.go
  28. +10 −16 src/syscall/syscall_darwin_arm.go
  29. +10 −16 src/syscall/syscall_darwin_arm64.go
  30. +1 −0 src/syscall/syscall_dragonfly.go
  31. +1 −0 src/syscall/syscall_freebsd.go
  32. +1 −1 src/syscall/syscall_netbsd.go
  33. +1 −1 src/syscall/syscall_openbsd.go
  34. +10 −8 src/syscall/syscall_unix_test.go
  35. +635 −138 src/syscall/zsyscall_darwin_386.go
  36. +243 −0 src/syscall/zsyscall_darwin_386.s
  37. +635 −138 src/syscall/zsyscall_darwin_amd64.go
  38. +243 −0 src/syscall/zsyscall_darwin_amd64.s
  39. +635 −138 src/syscall/zsyscall_darwin_arm.go
  40. +243 −0 src/syscall/zsyscall_darwin_arm.s
  41. +635 −138 src/syscall/zsyscall_darwin_arm64.go
  42. +243 −0 src/syscall/zsyscall_darwin_arm64.s
@@ -4704,7 +4704,9 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
r = obj.Addrel(cursym)
r.Off = int32(p.Pc + int64(ab.Len()))
r.Sym = p.To.Sym
r.Type = objabi.R_PCREL
// Note: R_CALL instead of R_PCREL. R_CALL is more permissive in that
// it can point to a trampoline instead of the destination itself.
r.Type = objabi.R_CALL
r.Siz = 4
ab.PutInt32(0)
break
@@ -4,7 +4,10 @@

package poll

import "syscall"
import (
"syscall"
_ "unsafe" // for go:linkname
)

// Fsync invokes SYS_FCNTL with SYS_FULLFSYNC because
// on OS X, SYS_FSYNC doesn't fully flush contents to disk.
@@ -15,9 +18,10 @@ func (fd *FD) Fsync() error {
}
defer fd.decref()

_, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd.Sysfd), syscall.F_FULLFSYNC, 0)
if e1 != 0 {
return e1
}
return nil
_, e1 := fcntl(fd.Sysfd, syscall.F_FULLFSYNC, 0)
return e1
}

// Implemented in syscall/syscall_darwin.go.
//go:linkname fcntl syscall.fcntl
func fcntl(fd int, cmd int, arg int) (int, error)
@@ -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 aix dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris windows
// +build aix dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris

package poll

@@ -16,3 +16,11 @@ func (fd *FD) Fsync() error {
defer fd.decref()
return syscall.Fsync(fd.Sysfd)
}

func fcntl(fd int, cmd int, arg int) (int, error) {
r, _, e := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
if e != 0 {
return int(r), syscall.Errno(e)
}
return int(r), nil
}
@@ -0,0 +1,16 @@
// Copyright 2018 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.

package poll

import "syscall"

// Fsync wraps syscall.Fsync.
func (fd *FD) Fsync() error {
if err := fd.incref(); err != nil {
return err
}
defer fd.decref()
return syscall.Fsync(fd.Sysfd)
}
@@ -452,10 +452,11 @@ var tryDupCloexec = int32(1)
// DupCloseOnExec dups fd and marks it close-on-exec.
func DupCloseOnExec(fd int) (int, string, error) {
if atomic.LoadInt32(&tryDupCloexec) == 1 {
r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
switch e1 {
case 0:
return int(r0), "", nil
r0, e1 := fcntl(fd, syscall.F_DUPFD_CLOEXEC, 0)
if e1 == nil {
return r0, "", nil
}
switch e1.(syscall.Errno) {
case syscall.EINVAL, syscall.ENOSYS:
// Old kernel, or js/wasm (which returns
// ENOSYS). Fall back to the portable way from
@@ -0,0 +1,16 @@
// Copyright 2018 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 darwin

package poll

import (
"syscall"
_ "unsafe" // for go:linkname
)

// Implemented in syscall/syscall_darwin.go.
//go:linkname writev syscall.writev
func writev(fd int, iovecs []syscall.Iovec) (uintptr, error)
@@ -0,0 +1,20 @@
// Copyright 2018 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 dragonfly freebsd linux netbsd openbsd

package poll

import (
"syscall"
"unsafe"
)

func writev(fd int, iovecs []syscall.Iovec) (uintptr, error) {
r, _, e := syscall.Syscall(syscall.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(&iovecs[0])), uintptr(len(iovecs)))
if e != 0 {
return r, syscall.Errno(e)
}
return r, nil
}
@@ -9,7 +9,6 @@ package poll
import (
"io"
"syscall"
"unsafe"
)

// Writev wraps the writev system call.
@@ -54,24 +53,20 @@ func (fd *FD) Writev(v *[][]byte) (int64, error) {
}
fd.iovecs = &iovecs // cache

wrote, _, e0 := syscall.Syscall(syscall.SYS_WRITEV,
uintptr(fd.Sysfd),
uintptr(unsafe.Pointer(&iovecs[0])),
uintptr(len(iovecs)))
var wrote uintptr
wrote, err = writev(fd.Sysfd, iovecs)
if wrote == ^uintptr(0) {
wrote = 0
}
TestHookDidWritev(int(wrote))
n += int64(wrote)
consume(v, int64(wrote))
if e0 == syscall.EAGAIN {
if err = fd.pd.waitWrite(fd.isFile); err == nil {
continue
}
} else if e0 != 0 {
err = syscall.Errno(e0)
}
if err != nil {
if err.(syscall.Errno) == syscall.EAGAIN {
if err = fd.pd.waitWrite(fd.isFile); err == nil {
continue
}
}
break
}
if n == 0 {
@@ -0,0 +1,5 @@
// Copyright 2018 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.

// This exists solely so we can linkname in symbols from syscall.
@@ -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 aix darwin dragonfly freebsd linux netbsd openbsd solaris
// +build aix dragonfly freebsd linux netbsd openbsd solaris

package unix

@@ -0,0 +1,24 @@
// Copyright 2018 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 darwin

package unix

import (
"syscall"
_ "unsafe" // for go:linkname
)

func IsNonblock(fd int) (nonblocking bool, err error) {
flag, e1 := fcntl(fd, syscall.F_GETFL, 0)
if e1 != nil {
return false, e1
}
return flag&syscall.O_NONBLOCK != 0, nil
}

// Implemented in syscall/syscall_darwin.go.
//go:linkname fcntl syscall.fcntl
func fcntl(fd int, cmd int, arg int) (int, error)
@@ -50,6 +50,61 @@ func libcCall(fn, arg unsafe.Pointer) int32 {
return res
}

// The X versions of syscall expect the libc call to return a 64-bit result.
// Otherwise (the non-X version) expects a 32-bit result.
// This distinction is required because an error is indicated by returning -1,
// and we need to know whether to check 32 or 64 bits of the result.
// (Some libc functions that return 32 bits put junk in the upper 32 bits of AX.)

//go:linkname syscall_syscall syscall.syscall
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
entersyscallblock()
libcCall(unsafe.Pointer(funcPC(syscall)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall()

//go:linkname syscall_syscall6 syscall.syscall6
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
entersyscallblock()
libcCall(unsafe.Pointer(funcPC(syscall6)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall6()

//go:linkname syscall_syscall6X syscall.syscall6X
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
entersyscallblock()
libcCall(unsafe.Pointer(funcPC(syscall6X)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall6X()

//go:linkname syscall_rawSyscall syscall.rawSyscall
//go:nosplit
//go:cgo_unsafe_args
func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
libcCall(unsafe.Pointer(funcPC(syscall)), unsafe.Pointer(&fn))
return
}

//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
//go:nosplit
//go:cgo_unsafe_args
func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
libcCall(unsafe.Pointer(funcPC(syscall6)), unsafe.Pointer(&fn))
return
}

// The *_trampoline functions convert from the Go calling convention to the C calling convention
// and then call the underlying libc function. They are defined in sys_darwin_$ARCH.s.

@@ -0,0 +1,21 @@
// Copyright 2018 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 darwin
// +build 386 arm

package runtime

import "unsafe"

//go:linkname syscall_syscall9 syscall.syscall9
//go:nosplit
//go:cgo_unsafe_args
func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
entersyscallblock()
libcCall(unsafe.Pointer(funcPC(syscall9)), unsafe.Pointer(&fn))
exitsyscall()
return
}
func syscall9()

0 comments on commit a3b0144

Please sign in to comment.
You can’t perform that action at this time.