diff --git a/compileopts/target.go b/compileopts/target.go index 26a91086b9..c394fa8ca8 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -389,6 +389,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) { "-platform_version", "macos", platformVersion, platformVersion, ) spec.ExtraFiles = append(spec.ExtraFiles, + "src/runtime/os_darwin.c", "src/runtime/runtime_unix.c") case "linux": spec.Linker = "ld.lld" diff --git a/compiler/compiler.go b/compiler/compiler.go index 201605d78c..6756fe9693 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -1847,7 +1847,9 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) case strings.HasPrefix(name, "(device/riscv.CSR)."): return b.emitCSROperation(instr) case strings.HasPrefix(name, "syscall.Syscall") || strings.HasPrefix(name, "syscall.RawSyscall") || strings.HasPrefix(name, "golang.org/x/sys/unix.Syscall") || strings.HasPrefix(name, "golang.org/x/sys/unix.RawSyscall"): - return b.createSyscall(instr) + if b.GOOS != "darwin" { + return b.createSyscall(instr) + } case strings.HasPrefix(name, "syscall.rawSyscallNoError") || strings.HasPrefix(name, "golang.org/x/sys/unix.RawSyscallNoError"): return b.createRawSyscallNoError(instr) case name == "runtime.supportsRecover": @@ -1865,6 +1867,11 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error) return llvm.ConstInt(b.ctx.Int8Type(), panicStrategy, false), nil case name == "runtime/interrupt.New": return b.createInterruptGlobal(instr) + case name == "internal/abi.FuncPCABI0": + retval := b.createDarwinFuncPCABI0Call(instr) + if !retval.IsNil() { + return retval, nil + } } calleeType, callee = b.getFunction(fn) diff --git a/compiler/syscall.go b/compiler/syscall.go index d878df0270..aa40ad1a55 100644 --- a/compiler/syscall.go +++ b/compiler/syscall.go @@ -5,6 +5,7 @@ package compiler import ( "strconv" + "strings" "golang.org/x/tools/go/ssa" "tinygo.org/x/go-llvm" @@ -329,3 +330,64 @@ func (b *builder) createRawSyscallNoError(call *ssa.CallCommon) (llvm.Value, err retval = b.CreateInsertValue(retval, llvm.ConstInt(b.uintptrType, 0, false), 1, "") return retval, nil } + +// Lower a call to internal/abi.FuncPCABI0 on MacOS. +// This function is called like this: +// +// syscall(abi.FuncPCABI0(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0) +// +// So we'll want to return a function pointer (as uintptr) that points to the +// libc function. Specifically, we _don't_ want to point to the trampoline +// function (which is implemented in Go assembly which we can't read), but +// rather to the actually intended function. For this we're going to assume that +// all the functions follow a specific pattern: libc__trampoline. +// +// The return value is the function pointer as an uintptr, or a nil value if +// this isn't possible (and a regular call should be made as fallback). +func (b *builder) createDarwinFuncPCABI0Call(instr *ssa.CallCommon) llvm.Value { + if b.GOOS != "darwin" { + // This has only been tested on MacOS (and only seems to be used there). + return llvm.Value{} + } + + // Check that it uses a function call like syscall.libc_*_trampoline + itf := instr.Args[0].(*ssa.MakeInterface) + calledFn := itf.X.(*ssa.Function) + if pkgName := calledFn.Pkg.Pkg.Path(); pkgName != "syscall" && pkgName != "internal/syscall/unix" { + return llvm.Value{} + } + if !strings.HasPrefix(calledFn.Name(), "libc_") || !strings.HasSuffix(calledFn.Name(), "_trampoline") { + + return llvm.Value{} + } + + // Extract the libc function name. + name := strings.TrimPrefix(strings.TrimSuffix(calledFn.Name(), "_trampoline"), "libc_") + if name == "open" { + // Special case: open() is a variadic function and can't be called like + // a regular function. Therefore, we need to use a wrapper implemented + // in C. + name = "syscall_libc_open" + } + if b.GOARCH == "amd64" { + if name == "fdopendir" || name == "readdir_r" { + // Hack to support amd64, which needs the $INODE64 suffix. + // This is also done in upstream Go: + // https://github.com/golang/go/commit/096ab3c21b88ccc7d411379d09fe6274e3159467 + name += "$INODE64" + } + } + + // Obtain the C function. + // Use a simple function (no parameters or return value) because all we need + // is the address of the function. + llvmFn := b.mod.NamedFunction(name) + if llvmFn.IsNil() { + llvmFnType := llvm.FunctionType(b.ctx.VoidType(), nil, false) + llvmFn = llvm.AddFunction(b.mod, name, llvmFnType) + } + + // Cast the function pointer to a uintptr (because that's what + // abi.FuncPCABI0 returns). + return b.CreatePtrToInt(llvmFn, b.uintptrType, "") +} diff --git a/lib/macos-minimal-sdk b/lib/macos-minimal-sdk index 91ac2eabd8..4e4113e3b1 160000 --- a/lib/macos-minimal-sdk +++ b/lib/macos-minimal-sdk @@ -1 +1 @@ -Subproject commit 91ac2eabd80f10d95cb4255c78999d9d2c45a3be +Subproject commit 4e4113e3b1244b8fdc5e1486577f25e22d63f36e diff --git a/loader/goroot.go b/loader/goroot.go index 09edab3203..c7ac029d3d 100644 --- a/loader/goroot.go +++ b/loader/goroot.go @@ -218,7 +218,7 @@ func listGorootMergeLinks(goroot, tinygoroot string, overrides map[string]bool) // with the TinyGo version. This is the case on some targets. func needsSyscallPackage(buildTags []string) bool { for _, tag := range buildTags { - if tag == "baremetal" || tag == "darwin" || tag == "nintendoswitch" || tag == "tinygo.wasm" { + if tag == "baremetal" || tag == "nintendoswitch" || tag == "tinygo.wasm" { return true } } diff --git a/src/internal/abi/funcpc.go b/src/internal/abi/funcpc.go index a926c392f8..0661ed7178 100644 --- a/src/internal/abi/funcpc.go +++ b/src/internal/abi/funcpc.go @@ -4,11 +4,9 @@ package abi // (in particular internal/syscall/unix on MacOS). They do not currently have an // implementation, in part because TinyGo doesn't use ABI0 or ABIInternal (it // uses a C-like calling convention). +// Calls to FuncPCABI0 however are treated specially by the compiler when +// compiling for MacOS. -func FuncPCABI0(f interface{}) uintptr { - panic("unimplemented: internal/abi.FuncPCABI0") -} +func FuncPCABI0(f interface{}) uintptr -func FuncPCABIInternal(f interface{}) uintptr { - panic("unimplemented: internal/abi.FuncPCABIInternal") -} +func FuncPCABIInternal(f interface{}) uintptr diff --git a/src/os/dir_darwin.go b/src/os/dir_darwin.go index 3883a45c6a..645c91f8c1 100644 --- a/src/os/dir_darwin.go +++ b/src/os/dir_darwin.go @@ -135,7 +135,7 @@ func darwinOpenDir(fd syscallFd) (uintptr, string, error) { } var dir uintptr for { - dir, err = syscall.Fdopendir(fd2) + dir, err = fdopendir(fd2) if err != syscall.EINTR { break } @@ -149,6 +149,9 @@ func darwinOpenDir(fd syscallFd) (uintptr, string, error) { // Implemented in syscall/syscall_libc_darwin_*.go. +//go:linkname fdopendir syscall.fdopendir +func fdopendir(fd int) (dir uintptr, err error) + //go:linkname closedir syscall.closedir func closedir(dir uintptr) (err error) diff --git a/src/os/file_darwin.go b/src/os/file_darwin.go new file mode 100644 index 0000000000..8d96b7296e --- /dev/null +++ b/src/os/file_darwin.go @@ -0,0 +1,7 @@ +package os + +import "syscall" + +func pipe(p []int) error { + return syscall.Pipe(p) +} diff --git a/src/os/file_notdarwin.go b/src/os/file_notdarwin.go new file mode 100644 index 0000000000..d59a8eb6c1 --- /dev/null +++ b/src/os/file_notdarwin.go @@ -0,0 +1,9 @@ +//go:build (linux && !baremetal && !wasm_unknown) || wasip1 || wasip2 + +package os + +import "syscall" + +func pipe(p []int) error { + return syscall.Pipe2(p, syscall.O_CLOEXEC) +} diff --git a/src/os/file_unix.go b/src/os/file_unix.go index d8d086e8dc..efbd8ef672 100644 --- a/src/os/file_unix.go +++ b/src/os/file_unix.go @@ -70,7 +70,7 @@ func Truncate(name string, size int64) error { func Pipe() (r *File, w *File, err error) { var p [2]int - err = handleSyscallError(syscall.Pipe2(p[:], syscall.O_CLOEXEC)) + err = handleSyscallError(pipe(p[:])) if err != nil { return } diff --git a/src/runtime/os_darwin.c b/src/runtime/os_darwin.c index d5f6c807a7..5d7cd7c71d 100644 --- a/src/runtime/os_darwin.c +++ b/src/runtime/os_darwin.c @@ -1,7 +1,32 @@ -// Wrapper function because 'open' is a variadic function and variadic functions -// use a different (incompatible) calling convention on darwin/arm64. +//go:build none + +// This file is included in the build, despite the //go:build line above. #include + +// Wrapper function because 'open' is a variadic function and variadic functions +// use a different (incompatible) calling convention on darwin/arm64. +// This function is referenced from the compiler, when it sees a +// syscall.libc_open_trampoline function. int syscall_libc_open(const char *pathname, int flags, mode_t mode) { return open(pathname, flags, mode); } + +// The following functions are called by the runtime because Go can't call +// function pointers directly. + +int tinygo_syscall(int (*fn)(uintptr_t a1, uintptr_t a2, uintptr_t a3), uintptr_t a1, uintptr_t a2, uintptr_t a3) { + return fn(a1, a2, a3); +} + +uintptr_t tinygo_syscallX(uintptr_t (*fn)(uintptr_t a1, uintptr_t a2, uintptr_t a3), uintptr_t a1, uintptr_t a2, uintptr_t a3) { + return fn(a1, a2, a3); +} + +int tinygo_syscall6(int (*fn)(uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6), uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6) { + return fn(a1, a2, a3, a4, a5, a6); +} + +uintptr_t tinygo_syscall6X(uintptr_t (*fn)(uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6), uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6) { + return fn(a1, a2, a3, a4, a5, a6); +} diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go index 9255fb90f2..8338d0f18b 100644 --- a/src/runtime/os_darwin.go +++ b/src/runtime/os_darwin.go @@ -4,8 +4,6 @@ package runtime import "unsafe" -import "C" // dummy import so that os_darwin.c works - const GOOS = "darwin" const ( @@ -127,7 +125,107 @@ func hardwareRand() (n uint64, ok bool) { return n, true } +//go:linkname syscall_Getpagesize syscall.Getpagesize +func syscall_Getpagesize() int { + return int(libc_getpagesize()) +} + +// Call "system calls" (actually: libc functions) in a special way. +// - Most calls calls return a C int (which is 32-bits), and -1 on failure. +// - syscallX* is for functions that return a 64-bit integer (and also return +// -1 on failure). +// - syscallPtr is for functions that return a pointer on success or NULL on +// failure. +// - rawSyscall seems to avoid some stack modifications, which isn't relevant +// to TinyGo. + +//go:linkname syscall_syscall syscall.syscall +func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + // For TinyGo we don't need to do anything special to call C functions. + return syscall_rawSyscall(fn, a1, a2, a3) +} + +//go:linkname syscall_rawSyscall syscall.rawSyscall +func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + result := call_syscall(fn, a1, a2, a3) + r1 = uintptr(result) + if result == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc___error()) + } + return +} + +//go:linkname syscall_syscallX syscall.syscallX +func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + r1 = call_syscallX(fn, a1, a2, a3) + if int64(r1) == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc___error()) + } + return +} + +//go:linkname syscall_syscallPtr syscall.syscallPtr +func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { + r1 = call_syscallX(fn, a1, a2, a3) + if r1 == 0 { + // Syscall returns a pointer on success, or NULL on failure. + err = uintptr(*libc___error()) + } + return +} + +//go:linkname syscall_syscall6 syscall.syscall6 +func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { + result := call_syscall6(fn, a1, a2, a3, a4, a5, a6) + r1 = uintptr(result) + if result == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc___error()) + } + return +} + +//go:linkname syscall_syscall6X syscall.syscall6X +func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { + r1 = call_syscall6X(fn, a1, a2, a3, a4, a5, a6) + if int64(r1) == -1 { + // Syscall returns -1 on failure. + err = uintptr(*libc___error()) + } + return +} + // uint32_t arc4random(void); // //export arc4random func libc_arc4random() uint32 + +// int getpagesize(void); +// +//export getpagesize +func libc_getpagesize() int32 + +// This function returns the error location in the darwin ABI. +// Discovered by compiling the following code using Clang: +// +// #include +// int getErrno() { +// return errno; +// } +// +//export __error +func libc___error() *int32 + +//export tinygo_syscall +func call_syscall(fn, a1, a2, a3 uintptr) int32 + +//export tinygo_syscallX +func call_syscallX(fn, a1, a2, a3 uintptr) uintptr + +//export tinygo_syscall6 +func call_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) int32 + +//export tinygo_syscall6X +func call_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) uintptr diff --git a/src/syscall/env_libc.go b/src/syscall/env_libc.go index f558901cf4..4ad078dc54 100644 --- a/src/syscall/env_libc.go +++ b/src/syscall/env_libc.go @@ -1,4 +1,4 @@ -//go:build darwin || nintendoswitch || wasip1 +//go:build nintendoswitch || wasip1 package syscall diff --git a/src/syscall/errno_other.go b/src/syscall/errno_other.go index b988fbc1e0..3a06ac018f 100644 --- a/src/syscall/errno_other.go +++ b/src/syscall/errno_other.go @@ -1,4 +1,4 @@ -//go:build !wasip1 && !wasip2 && !darwin +//go:build !wasip1 && !wasip2 package syscall diff --git a/src/syscall/mmap_unix_test.go b/src/syscall/mmap_unix_test.go index 1946265d8c..62748a9395 100644 --- a/src/syscall/mmap_unix_test.go +++ b/src/syscall/mmap_unix_test.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. -//go:build darwin || linux +//go:build linux package syscall_test diff --git a/src/syscall/syscall_libc.go b/src/syscall/syscall_libc.go index 2321292d98..67cf6681f7 100644 --- a/src/syscall/syscall_libc.go +++ b/src/syscall/syscall_libc.go @@ -1,4 +1,4 @@ -//go:build darwin || nintendoswitch || wasip1 || wasip2 +//go:build nintendoswitch || wasip1 || wasip2 package syscall diff --git a/src/syscall/syscall_libc_darwin.go b/src/syscall/syscall_libc_darwin.go deleted file mode 100644 index 3b0341880a..0000000000 --- a/src/syscall/syscall_libc_darwin.go +++ /dev/null @@ -1,432 +0,0 @@ -//go:build darwin - -package syscall - -import ( - "internal/itoa" - "unsafe" -) - -// This file defines errno and constants to match the darwin libsystem ABI. -// Values have been copied from src/syscall/zerrors_darwin_amd64.go. - -// This function returns the error location in the darwin ABI. -// Discovered by compiling the following code using Clang: -// -// #include -// int getErrno() { -// return errno; -// } -// -//export __error -func libc___error() *int32 - -// getErrno returns the current C errno. It may not have been caused by the last -// call, so it should only be relied upon when the last call indicates an error -// (for example, by returning -1). -func getErrno() Errno { - errptr := libc___error() - return Errno(uintptr(*errptr)) -} - -func (e Errno) Is(target error) bool { - switch target.Error() { - case "permission denied": - return e == EACCES || e == EPERM - case "file already exists": - return e == EEXIST - case "file does not exist": - return e == ENOENT - } - return false -} - -// Source: upstream zerrors_darwin_amd64.go -const ( - DT_BLK = 0x6 - DT_CHR = 0x2 - DT_DIR = 0x4 - DT_FIFO = 0x1 - DT_LNK = 0xa - DT_REG = 0x8 - DT_SOCK = 0xc - DT_UNKNOWN = 0x0 - DT_WHT = 0xe - F_GETFL = 0x3 - F_SETFL = 0x4 - O_NONBLOCK = 0x4 - TIOCSPGRP = 0x80047476 -) - -// Source: https://opensource.apple.com/source/xnu/xnu-7195.141.2/bsd/sys/errno.h.auto.html -const ( - EPERM Errno = 1 - ENOENT Errno = 2 - ESRCH Errno = 3 - EINTR Errno = 4 - EIO Errno = 5 - ENXIO Errno = 6 - E2BIG Errno = 7 - ENOEXEC Errno = 8 - EBADF Errno = 9 - ECHILD Errno = 10 - EDEADLK Errno = 11 - ENOMEM Errno = 12 - EACCES Errno = 13 - EFAULT Errno = 14 - ENOTBLK Errno = 15 - EBUSY Errno = 16 - EEXIST Errno = 17 - EXDEV Errno = 18 - ENODEV Errno = 19 - ENOTDIR Errno = 20 - EISDIR Errno = 21 - EINVAL Errno = 22 - ENFILE Errno = 23 - EMFILE Errno = 24 - ENOTTY Errno = 25 - ETXTBSY Errno = 26 - EFBIG Errno = 27 - ENOSPC Errno = 28 - ESPIPE Errno = 29 - EROFS Errno = 30 - EMLINK Errno = 31 - EPIPE Errno = 32 - EDOM Errno = 33 - ERANGE Errno = 34 - EAGAIN Errno = 35 - EWOULDBLOCK Errno = EAGAIN - EINPROGRESS Errno = 36 - EALREADY Errno = 37 - ENOTSOCK Errno = 38 - EDESTADDRREQ Errno = 39 - EMSGSIZE Errno = 40 - EPROTOTYPE Errno = 41 - ENOPROTOOPT Errno = 42 - EPROTONOSUPPORT Errno = 43 - ESOCKTNOSUPPORT Errno = 44 - ENOTSUP Errno = 45 - EPFNOSUPPORT Errno = 46 - EAFNOSUPPORT Errno = 47 - EADDRINUSE Errno = 48 - EADDRNOTAVAIL Errno = 49 - ENETDOWN Errno = 50 - ENETUNREACH Errno = 51 - ENETRESET Errno = 52 - ECONNABORTED Errno = 53 - ECONNRESET Errno = 54 - ENOBUFS Errno = 55 - EISCONN Errno = 56 - ENOTCONN Errno = 57 - ESHUTDOWN Errno = 58 - ETOOMANYREFS Errno = 59 - ETIMEDOUT Errno = 60 - ECONNREFUSED Errno = 61 - ELOOP Errno = 62 - ENAMETOOLONG Errno = 63 - EHOSTDOWN Errno = 64 - EHOSTUNREACH Errno = 65 - ENOTEMPTY Errno = 66 - EPROCLIM Errno = 67 - EUSERS Errno = 68 - EDQUOT Errno = 69 - ESTALE Errno = 70 - EREMOTE Errno = 71 - EBADRPC Errno = 72 - ERPCMISMATCH Errno = 73 - EPROGUNAVAIL Errno = 74 - EPROGMISMATCH Errno = 75 - EPROCUNAVAIL Errno = 76 - ENOLCK Errno = 77 - ENOSYS Errno = 78 - EFTYPE Errno = 79 - EAUTH Errno = 80 - ENEEDAUTH Errno = 81 - EPWROFF Errno = 82 - EDEVERR Errno = 83 - EOVERFLOW Errno = 84 - EBADEXEC Errno = 85 - EBADARCH Errno = 86 - ESHLIBVERS Errno = 87 - EBADMACHO Errno = 88 - ECANCELED Errno = 89 - EIDRM Errno = 90 - ENOMSG Errno = 91 - EILSEQ Errno = 92 - ENOATTR Errno = 93 - EBADMSG Errno = 94 - EMULTIHOP Errno = 95 - ENODATA Errno = 96 - ENOLINK Errno = 97 - ENOSR Errno = 98 - ENOSTR Errno = 99 - EPROTO Errno = 100 - ETIME Errno = 101 - EOPNOTSUPP Errno = 102 - ENOPOLICY Errno = 103 - ENOTRECOVERABLE Errno = 104 - EOWNERDEAD Errno = 105 - EQFULL Errno = 106 - ELAST Errno = 106 -) - -type Signal int - -// Source: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/signal.h -const ( - SIGINT Signal = 2 /* interrupt */ - SIGQUIT Signal = 3 /* quit */ - SIGILL Signal = 4 /* illegal instruction (not reset when caught) */ - SIGTRAP Signal = 5 /* trace trap (not reset when caught) */ - SIGABRT Signal = 6 /* abort() */ - SIGFPE Signal = 8 /* floating point exception */ - SIGKILL Signal = 9 /* kill (cannot be caught or ignored) */ - SIGBUS Signal = 10 /* bus error */ - SIGSEGV Signal = 11 /* segmentation violation */ - SIGPIPE Signal = 13 /* write on a pipe with no one to read it */ - SIGTERM Signal = 15 /* software termination signal from kill */ - SIGCHLD Signal = 20 /* to parent on child stop or exit */ -) - -func (s Signal) Signal() {} - -func (s Signal) String() string { - if 0 <= s && int(s) < len(signals) { - str := signals[s] - if str != "" { - return str - } - } - return "signal " + itoa.Itoa(int(s)) -} - -var signals = [...]string{} - -const ( - Stdin = 0 - Stdout = 1 - Stderr = 2 -) - -const ( - O_RDONLY = 0x0 - O_WRONLY = 0x1 - O_RDWR = 0x2 - O_APPEND = 0x8 - O_SYNC = 0x80 - O_CREAT = 0x200 - O_TRUNC = 0x400 - O_EXCL = 0x800 - - O_CLOEXEC = 0x01000000 -) - -// Source: https://opensource.apple.com/source/xnu/xnu-7195.81.3/bsd/sys/mman.h.auto.html -const ( - PROT_NONE = 0x00 // no permissions - PROT_READ = 0x01 // pages can be read - PROT_WRITE = 0x02 // pages can be written - PROT_EXEC = 0x04 // pages can be executed - - MAP_SHARED = 0x0001 // share changes - MAP_PRIVATE = 0x0002 // changes are private - - MAP_FILE = 0x0000 // map from file (default) - MAP_ANON = 0x1000 // allocated from memory, swap space - MAP_ANONYMOUS = MAP_ANON -) - -type Timespec struct { - Sec int64 - Nsec int64 -} - -// Unix returns the time stored in ts as seconds plus nanoseconds. -func (ts *Timespec) Unix() (sec int64, nsec int64) { - return int64(ts.Sec), int64(ts.Nsec) -} - -// Source: upstream ztypes_darwin_amd64.go -type Dirent struct { - Ino uint64 - Seekoff uint64 - Reclen uint16 - Namlen uint16 - Type uint8 - Name [1024]int8 - Pad_cgo_0 [3]byte -} - -type Stat_t struct { - Dev int32 - Mode uint16 - Nlink uint16 - Ino uint64 - Uid uint32 - Gid uint32 - Rdev int32 - Pad_cgo_0 [4]byte - Atimespec Timespec - Mtimespec Timespec - Ctimespec Timespec - Btimespec Timespec - Size int64 - Blocks int64 - Blksize int32 - Flags uint32 - Gen uint32 - Lspare int32 - Qspare [2]int64 -} - -// Source: https://github.com/apple/darwin-xnu/blob/main/bsd/sys/_types/_s_ifmt.h -const ( - S_IEXEC = 0x40 - S_IFBLK = 0x6000 - S_IFCHR = 0x2000 - S_IFDIR = 0x4000 - S_IFIFO = 0x1000 - S_IFLNK = 0xa000 - S_IFMT = 0xf000 - S_IFREG = 0x8000 - S_IFSOCK = 0xc000 - S_IFWHT = 0xe000 - S_IREAD = 0x100 - S_IRGRP = 0x20 - S_IROTH = 0x4 - S_IRUSR = 0x100 - S_IRWXG = 0x38 - S_IRWXO = 0x7 - S_IRWXU = 0x1c0 - S_ISGID = 0x400 - S_ISTXT = 0x200 - S_ISUID = 0x800 - S_ISVTX = 0x200 - S_IWGRP = 0x10 - S_IWOTH = 0x2 - S_IWRITE = 0x80 - S_IWUSR = 0x80 - S_IXGRP = 0x8 - S_IXOTH = 0x1 - S_IXUSR = 0x40 -) - -func Stat(path string, p *Stat_t) (err error) { - data := cstring(path) - n := libc_stat(&data[0], unsafe.Pointer(p)) - - if n < 0 { - err = getErrno() - } - return -} - -func Fstat(fd int, p *Stat_t) (err error) { - n := libc_fstat(int32(fd), unsafe.Pointer(p)) - - if n < 0 { - err = getErrno() - } - return -} - -func Lstat(path string, p *Stat_t) (err error) { - data := cstring(path) - n := libc_lstat(&data[0], unsafe.Pointer(p)) - if n < 0 { - err = getErrno() - } - return -} - -func Fdopendir(fd int) (dir uintptr, err error) { - r0 := libc_fdopendir(int32(fd)) - dir = uintptr(r0) - if dir == 0 { - err = getErrno() - } - return -} - -func Pipe2(fds []int, flags int) (err error) { - // Mac only has Pipe, which ignores the flags argument - buf := make([]int32, 2) - fail := int(libc_pipe(&buf[0])) - if fail < 0 { - err = getErrno() - } else { - fds[0] = int(buf[0]) - fds[1] = int(buf[1]) - } - return -} - -func Chmod(path string, mode uint32) (err error) { - data := cstring(path) - fail := int(libc_chmod(&data[0], mode)) - if fail < 0 { - err = getErrno() - } - return -} - -func closedir(dir uintptr) (err error) { - e := libc_closedir(unsafe.Pointer(dir)) - if e != 0 { - err = getErrno() - } - return -} - -func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (err error) { - e1 := libc_readdir_r(unsafe.Pointer(dir), unsafe.Pointer(entry), unsafe.Pointer(result)) - if e1 != 0 { - err = getErrno() - } - return -} - -func Getpagesize() int { - return int(libc_getpagesize()) -} - -// The following RawSockAddr* types have been copied from the Go source tree and -// are here purely to fix build errors. - -type RawSockaddr struct { - Len uint8 - Family uint8 - Data [14]int8 -} - -type RawSockaddrInet4 struct { - Len uint8 - Family uint8 - Port uint16 - Addr [4]byte /* in_addr */ - Zero [8]int8 -} - -type RawSockaddrInet6 struct { - Len uint8 - Family uint8 - Port uint16 - Flowinfo uint32 - Addr [16]byte /* in6_addr */ - Scope_id uint32 -} - -// int pipe(int32 *fds); -// -//export pipe -func libc_pipe(fds *int32) int32 - -// int getpagesize(); -// -//export getpagesize -func libc_getpagesize() int32 - -// int open(const char *pathname, int flags, mode_t mode); -// -//export syscall_libc_open -func libc_open(pathname *byte, flags int32, mode uint32) int32 diff --git a/src/syscall/syscall_libc_darwin_amd64.go b/src/syscall/syscall_libc_darwin_amd64.go deleted file mode 100644 index 1f5528ec54..0000000000 --- a/src/syscall/syscall_libc_darwin_amd64.go +++ /dev/null @@ -1,43 +0,0 @@ -//go:build darwin - -package syscall - -import ( - "unsafe" -) - -// The odd $INODE64 suffix is an Apple compatibility feature, see -// __DARWIN_INODE64 in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h -// and https://assert.cc/posts/darwin_use_64_bit_inode_vs_ctypes/ -// Without it, you get the old, smaller struct stat from mac os 10.2 or so. -// It not needed on arm64. - -// struct DIR * buf fdopendir(int fd); -// -//export fdopendir$INODE64 -func libc_fdopendir(fd int32) unsafe.Pointer - -// int closedir(struct DIR * buf); -// -//export closedir -func libc_closedir(unsafe.Pointer) int32 - -// int readdir_r(struct DIR * buf, struct dirent *entry, struct dirent **result); -// -//export readdir_r$INODE64 -func libc_readdir_r(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) int32 - -// int stat(const char *path, struct stat * buf); -// -//export stat$INODE64 -func libc_stat(pathname *byte, ptr unsafe.Pointer) int32 - -// int fstat(int fd, struct stat * buf); -// -//export fstat$INODE64 -func libc_fstat(fd int32, ptr unsafe.Pointer) int32 - -// int lstat(const char *path, struct stat * buf); -// -//export lstat$INODE64 -func libc_lstat(pathname *byte, ptr unsafe.Pointer) int32 diff --git a/src/syscall/syscall_libc_darwin_arm64.go b/src/syscall/syscall_libc_darwin_arm64.go deleted file mode 100644 index f9ce3c4e39..0000000000 --- a/src/syscall/syscall_libc_darwin_arm64.go +++ /dev/null @@ -1,37 +0,0 @@ -//go:build darwin - -package syscall - -import ( - "unsafe" -) - -// struct DIR * buf fdopendir(int fd); -// -//export fdopendir -func libc_fdopendir(fd int32) unsafe.Pointer - -// int closedir(struct DIR * buf); -// -//export closedir -func libc_closedir(unsafe.Pointer) int32 - -// int readdir_r(struct DIR * buf, struct dirent *entry, struct dirent **result); -// -//export readdir_r -func libc_readdir_r(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) int32 - -// int stat(const char *path, struct stat * buf); -// -//export stat -func libc_stat(pathname *byte, ptr unsafe.Pointer) int32 - -// int fstat(int fd, struct stat * buf); -// -//export fstat -func libc_fstat(fd int32, ptr unsafe.Pointer) int32 - -// int lstat(const char *path, struct stat * buf); -// -//export lstat -func libc_lstat(pathname *byte, ptr unsafe.Pointer) int32