Commit f5e5bc1a authored by Austin Clements's avatar Austin Clements

runtime: mark all Go symbols called from assembly in other packages

This marks all Go symbols called from assembly in other packages with
"go:linkname" directives to ensure they get ABI wrappers.

Now that we have this go:linkname convention, this also removes the
abi0Syms definition in the runtime, which was used to give morestackc
an ABI0 wrapper. Instead, we now just mark morestackc with a
go:linkname directive.

This was tested with buildall.bash in the default configuration, with
-race, and with -gcflags=all=-d=ssa/intrinsics/off. Since I couldn't
test cgo on non-Linux configurations, I manually grepped for runtime
symbols in runtime/cgo.

Updates #31230.

Change-Id: I6c8aa56be2ca6802dfa2bf159e49c411b9071bf1
Reviewed-on: https://go-review.googlesource.com/c/go/+/179862
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarMichael Knyszek <mknyszek@google.com>
parent dde7c770
...@@ -38,11 +38,3 @@ GLOBL runtime·memstats(SB), NOPTR, $0 ...@@ -38,11 +38,3 @@ GLOBL runtime·memstats(SB), NOPTR, $0
// This function must be sizeofSkipFunction bytes. // This function must be sizeofSkipFunction bytes.
TEXT runtime·skipPleaseUseCallersFrames(SB),NOSPLIT,$0-0 TEXT runtime·skipPleaseUseCallersFrames(SB),NOSPLIT,$0-0
SKIP64; SKIP64; SKIP64; SKIP64 SKIP64; SKIP64; SKIP64; SKIP64
// abi0Syms is a dummy symbol that creates ABI0 wrappers for Go
// functions called from assembly in other packages.
TEXT abi0Syms<>(SB),NOSPLIT,$0-0
// obj assumes it can call morestack* using ABI0, but
// morestackc is actually defined in Go.
CALL ·morestackc(SB)
// References from syscall are automatically collected by cmd/go.
...@@ -8,6 +8,10 @@ package atomic ...@@ -8,6 +8,10 @@ package atomic
import "unsafe" import "unsafe"
// Export some functions via linkname to assembly in sync/atomic.
//go:linkname Load
//go:linkname Loadp
//go:nosplit //go:nosplit
//go:noinline //go:noinline
func Load(ptr *uint32) uint32 { func Load(ptr *uint32) uint32 {
......
...@@ -8,6 +8,11 @@ package atomic ...@@ -8,6 +8,11 @@ package atomic
import "unsafe" import "unsafe"
// Export some functions via linkname to assembly in sync/atomic.
//go:linkname Load
//go:linkname Loadp
//go:linkname Load64
//go:nosplit //go:nosplit
//go:noinline //go:noinline
func Load(ptr *uint32) uint32 { func Load(ptr *uint32) uint32 {
......
...@@ -4,6 +4,13 @@ ...@@ -4,6 +4,13 @@
// +build mips mipsle // +build mips mipsle
// Export some functions via linkname to assembly in sync/atomic.
//go:linkname Xadd64
//go:linkname Xchg64
//go:linkname Cas64
//go:linkname Load64
//go:linkname Store64
package atomic package atomic
import ( import (
......
...@@ -6,6 +6,13 @@ package atomic ...@@ -6,6 +6,13 @@ package atomic
import "unsafe" import "unsafe"
// Export some functions via linkname to assembly in sync/atomic.
//go:linkname Load
//go:linkname Loadp
//go:linkname Load64
//go:linkname Store
//go:linkname Store64
//go:nosplit //go:nosplit
//go:noinline //go:noinline
func Load(ptr *uint32) uint32 { func Load(ptr *uint32) uint32 {
......
...@@ -5,6 +5,24 @@ ...@@ -5,6 +5,24 @@
// TODO(neelance): implement with actual atomic operations as soon as threads are available // TODO(neelance): implement with actual atomic operations as soon as threads are available
// See https://github.com/WebAssembly/design/issues/1073 // See https://github.com/WebAssembly/design/issues/1073
// Export some functions via linkname to assembly in sync/atomic.
//go:linkname Load
//go:linkname Loadp
//go:linkname Load64
//go:linkname Loaduintptr
//go:linkname Xadd
//go:linkname Xadd64
//go:linkname Xadduintptr
//go:linkname Xchg
//go:linkname Xchg64
//go:linkname Xchguintptr
//go:linkname Cas
//go:linkname Cas64
//go:linkname Casuintptr
//go:linkname Store
//go:linkname Store64
//go:linkname Storeuintptr
package atomic package atomic
import "unsafe" import "unsafe"
......
...@@ -2850,7 +2850,11 @@ func reentersyscall(pc, sp uintptr) { ...@@ -2850,7 +2850,11 @@ func reentersyscall(pc, sp uintptr) {
} }
// Standard syscall entry used by the go syscall library and normal cgo calls. // Standard syscall entry used by the go syscall library and normal cgo calls.
//
// This is exported via linkname to assembly in the syscall package.
//
//go:nosplit //go:nosplit
//go:linkname entersyscall
func entersyscall() { func entersyscall() {
reentersyscall(getcallerpc(), getcallersp()) reentersyscall(getcallerpc(), getcallersp())
} }
...@@ -2940,8 +2944,11 @@ func entersyscallblock_handoff() { ...@@ -2940,8 +2944,11 @@ func entersyscallblock_handoff() {
// //
// Write barriers are not allowed because our P may have been stolen. // Write barriers are not allowed because our P may have been stolen.
// //
// This is exported via linkname to assembly in the syscall package.
//
//go:nosplit //go:nosplit
//go:nowritebarrierrec //go:nowritebarrierrec
//go:linkname exitsyscall
func exitsyscall() { func exitsyscall() {
_g_ := getg() _g_ := getg()
......
...@@ -369,6 +369,9 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) { ...@@ -369,6 +369,9 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
// //
// The signal handler must not inject a call to sigpanic if // The signal handler must not inject a call to sigpanic if
// getg().throwsplit, since sigpanic may need to grow the stack. // getg().throwsplit, since sigpanic may need to grow the stack.
//
// This is exported via linkname to assembly in runtime/cgo.
//go:linkname sigpanic
func sigpanic() { func sigpanic() {
g := getg() g := getg()
if !canpanic(g) { if !canpanic(g) {
...@@ -843,7 +846,11 @@ func signalstack(s *stack) { ...@@ -843,7 +846,11 @@ func signalstack(s *stack) {
} }
// setsigsegv is used on darwin/arm{,64} to fake a segmentation fault. // setsigsegv is used on darwin/arm{,64} to fake a segmentation fault.
//
// This is exported via linkname to assembly in runtime/cgo.
//
//go:nosplit //go:nosplit
//go:linkname setsigsegv
func setsigsegv(pc uintptr) { func setsigsegv(pc uintptr) {
g := getg() g := getg()
g.sig = _SIGSEGV g.sig = _SIGSEGV
......
...@@ -1295,7 +1295,10 @@ type stackObjectRecord struct { ...@@ -1295,7 +1295,10 @@ type stackObjectRecord struct {
typ *_type typ *_type
} }
// This is exported as ABI0 via linkname so obj can call it.
//
//go:nosplit //go:nosplit
//go:linkname morestackc
func morestackc() { func morestackc() {
throw("attempt to execute system stack code on user stack") throw("attempt to execute system stack code on user stack")
} }
...@@ -310,6 +310,8 @@ func gobytes(p *byte, n int) (b []byte) { ...@@ -310,6 +310,8 @@ func gobytes(p *byte, n int) (b []byte) {
return return
} }
// This is exported via linkname to assembly in syscall (for Plan9).
//go:linkname gostring
func gostring(p *byte) string { func gostring(p *byte) string {
l := findnull(p) l := findnull(p)
if l == 0 { if l == 0 {
......
...@@ -206,6 +206,9 @@ func close_trampoline() ...@@ -206,6 +206,9 @@ func close_trampoline()
//go:nosplit //go:nosplit
//go:cgo_unsafe_args //go:cgo_unsafe_args
//
// This is exported via linkname to assembly in runtime/cgo.
//go:linkname exit
func exit(code int32) { func exit(code int32) {
libcCall(unsafe.Pointer(funcPC(exit_trampoline)), unsafe.Pointer(&code)) libcCall(unsafe.Pointer(funcPC(exit_trampoline)), unsafe.Pointer(&code))
} }
......
...@@ -57,19 +57,30 @@ var ( ...@@ -57,19 +57,30 @@ var (
// Syscall is needed because some packages (like net) need it too. // Syscall is needed because some packages (like net) need it too.
// The best way is to return EINVAL and let Golang handles its failure // The best way is to return EINVAL and let Golang handles its failure
// If the syscall can't fail, this function can redirect it to a real syscall. // If the syscall can't fail, this function can redirect it to a real syscall.
//
// This is exported via linkname to assembly in the syscall package.
//
//go:nosplit //go:nosplit
//go:linkname syscall_Syscall
func syscall_Syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { func syscall_Syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
return 0, 0, _EINVAL return 0, 0, _EINVAL
} }
// This is syscall.RawSyscall, it exists to satisfy some build dependency, // This is syscall.RawSyscall, it exists to satisfy some build dependency,
// but it doesn't work. // but it doesn't work.
//
// This is exported via linkname to assembly in the syscall package.
//
//go:linkname syscall_RawSyscall
func syscall_RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { func syscall_RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
panic("RawSyscall not available on AIX") panic("RawSyscall not available on AIX")
} }
// This is exported via linkname to assembly in the syscall package.
//
//go:nosplit //go:nosplit
//go:cgo_unsafe_args //go:cgo_unsafe_args
//go:linkname syscall_syscall6
func syscall_syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { func syscall_syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
c := libcall{ c := libcall{
fn: fn, fn: fn,
...@@ -83,8 +94,11 @@ func syscall_syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err ui ...@@ -83,8 +94,11 @@ func syscall_syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err ui
return c.r1, 0, c.err return c.r1, 0, c.err
} }
// This is exported via linkname to assembly in the syscall package.
//
//go:nosplit //go:nosplit
//go:cgo_unsafe_args //go:cgo_unsafe_args
//go:linkname syscall_rawSyscall6
func syscall_rawSyscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { func syscall_rawSyscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
c := libcall{ c := libcall{
fn: fn, fn: fn,
......
...@@ -31,7 +31,11 @@ var pipe1x libcFunc // name to take addr of pipe1 ...@@ -31,7 +31,11 @@ var pipe1x libcFunc // name to take addr of pipe1
func pipe1() // declared for vet; do NOT call func pipe1() // declared for vet; do NOT call
// Many of these are exported via linkname to assembly in the syscall
// package.
//go:nosplit //go:nosplit
//go:linkname syscall_sysvicall6
func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
call := libcall{ call := libcall{
fn: fn, fn: fn,
...@@ -45,6 +49,7 @@ func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err ...@@ -45,6 +49,7 @@ func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err
} }
//go:nosplit //go:nosplit
//go:linkname syscall_rawsysvicall6
func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
call := libcall{ call := libcall{
fn: fn, fn: fn,
...@@ -60,6 +65,7 @@ func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, e ...@@ -60,6 +65,7 @@ func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, e
// with calls to sysvicallN. // with calls to sysvicallN.
//go:nosplit //go:nosplit
//go:linkname syscall_chdir
func syscall_chdir(path uintptr) (err uintptr) { func syscall_chdir(path uintptr) (err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_chdir)), fn: uintptr(unsafe.Pointer(&libc_chdir)),
...@@ -71,6 +77,7 @@ func syscall_chdir(path uintptr) (err uintptr) { ...@@ -71,6 +77,7 @@ func syscall_chdir(path uintptr) (err uintptr) {
} }
//go:nosplit //go:nosplit
//go:linkname syscall_chroot
func syscall_chroot(path uintptr) (err uintptr) { func syscall_chroot(path uintptr) (err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_chroot)), fn: uintptr(unsafe.Pointer(&libc_chroot)),
...@@ -83,6 +90,7 @@ func syscall_chroot(path uintptr) (err uintptr) { ...@@ -83,6 +90,7 @@ func syscall_chroot(path uintptr) (err uintptr) {
// like close, but must not split stack, for forkx. // like close, but must not split stack, for forkx.
//go:nosplit //go:nosplit
//go:linkname syscall_close
func syscall_close(fd int32) int32 { func syscall_close(fd int32) int32 {
return int32(sysvicall1(&libc_close, uintptr(fd))) return int32(sysvicall1(&libc_close, uintptr(fd)))
} }
...@@ -90,11 +98,13 @@ func syscall_close(fd int32) int32 { ...@@ -90,11 +98,13 @@ func syscall_close(fd int32) int32 {
const _F_DUP2FD = 0x9 const _F_DUP2FD = 0x9
//go:nosplit //go:nosplit
//go:linkname syscall_dup2
func syscall_dup2(oldfd, newfd uintptr) (val, err uintptr) { func syscall_dup2(oldfd, newfd uintptr) (val, err uintptr) {
return syscall_fcntl(oldfd, _F_DUP2FD, newfd) return syscall_fcntl(oldfd, _F_DUP2FD, newfd)
} }
//go:nosplit //go:nosplit
//go:linkname syscall_execve
func syscall_execve(path, argv, envp uintptr) (err uintptr) { func syscall_execve(path, argv, envp uintptr) (err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_execve)), fn: uintptr(unsafe.Pointer(&libc_execve)),
...@@ -107,11 +117,13 @@ func syscall_execve(path, argv, envp uintptr) (err uintptr) { ...@@ -107,11 +117,13 @@ func syscall_execve(path, argv, envp uintptr) (err uintptr) {
// like exit, but must not split stack, for forkx. // like exit, but must not split stack, for forkx.
//go:nosplit //go:nosplit
//go:linkname syscall_exit
func syscall_exit(code uintptr) { func syscall_exit(code uintptr) {
sysvicall1(&libc_exit, code) sysvicall1(&libc_exit, code)
} }
//go:nosplit //go:nosplit
//go:linkname syscall_fcntl
func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) { func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_fcntl)), fn: uintptr(unsafe.Pointer(&libc_fcntl)),
...@@ -123,6 +135,7 @@ func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) { ...@@ -123,6 +135,7 @@ func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) {
} }
//go:nosplit //go:nosplit
//go:linkname syscall_forkx
func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) { func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_forkx)), fn: uintptr(unsafe.Pointer(&libc_forkx)),
...@@ -133,6 +146,7 @@ func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) { ...@@ -133,6 +146,7 @@ func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) {
return call.r1, call.err return call.r1, call.err
} }
//go:linkname syscall_gethostname
func syscall_gethostname() (name string, err uintptr) { func syscall_gethostname() (name string, err uintptr) {
cname := new([_MAXHOSTNAMELEN]byte) cname := new([_MAXHOSTNAMELEN]byte)
var args = [2]uintptr{uintptr(unsafe.Pointer(&cname[0])), _MAXHOSTNAMELEN} var args = [2]uintptr{uintptr(unsafe.Pointer(&cname[0])), _MAXHOSTNAMELEN}
...@@ -152,6 +166,7 @@ func syscall_gethostname() (name string, err uintptr) { ...@@ -152,6 +166,7 @@ func syscall_gethostname() (name string, err uintptr) {
} }
//go:nosplit //go:nosplit
//go:linkname syscall_getpid
func syscall_getpid() (pid, err uintptr) { func syscall_getpid() (pid, err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_getpid)), fn: uintptr(unsafe.Pointer(&libc_getpid)),
...@@ -163,6 +178,7 @@ func syscall_getpid() (pid, err uintptr) { ...@@ -163,6 +178,7 @@ func syscall_getpid() (pid, err uintptr) {
} }
//go:nosplit //go:nosplit
//go:linkname syscall_ioctl
func syscall_ioctl(fd, req, arg uintptr) (err uintptr) { func syscall_ioctl(fd, req, arg uintptr) (err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_ioctl)), fn: uintptr(unsafe.Pointer(&libc_ioctl)),
...@@ -173,6 +189,7 @@ func syscall_ioctl(fd, req, arg uintptr) (err uintptr) { ...@@ -173,6 +189,7 @@ func syscall_ioctl(fd, req, arg uintptr) (err uintptr) {
return call.err return call.err
} }
//go:linkname syscall_pipe
func syscall_pipe() (r, w, err uintptr) { func syscall_pipe() (r, w, err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&pipe1x)), fn: uintptr(unsafe.Pointer(&pipe1x)),
...@@ -187,17 +204,22 @@ func syscall_pipe() (r, w, err uintptr) { ...@@ -187,17 +204,22 @@ func syscall_pipe() (r, w, err uintptr) {
// This is syscall.RawSyscall, it exists to satisfy some build dependency, // This is syscall.RawSyscall, it exists to satisfy some build dependency,
// but it doesn't work. // but it doesn't work.
//
//go:linkname syscall_rawsyscall
func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
panic("RawSyscall not available on Solaris") panic("RawSyscall not available on Solaris")
} }
// This is syscall.RawSyscall6, it exists to avoid a linker error because // This is syscall.RawSyscall6, it exists to avoid a linker error because
// syscall.RawSyscall6 is already declared. See golang.org/issue/24357 // syscall.RawSyscall6 is already declared. See golang.org/issue/24357
//
//go:linkname syscall_rawsyscall6
func syscall_rawsyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { func syscall_rawsyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
panic("RawSyscall6 not available on Solaris") panic("RawSyscall6 not available on Solaris")
} }
//go:nosplit //go:nosplit
//go:linkname syscall_setgid
func syscall_setgid(gid uintptr) (err uintptr) { func syscall_setgid(gid uintptr) (err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_setgid)), fn: uintptr(unsafe.Pointer(&libc_setgid)),
...@@ -209,6 +231,7 @@ func syscall_setgid(gid uintptr) (err uintptr) { ...@@ -209,6 +231,7 @@ func syscall_setgid(gid uintptr) (err uintptr) {
} }
//go:nosplit //go:nosplit
//go:linkname syscall_setgroups
func syscall_setgroups(ngid, gid uintptr) (err uintptr) { func syscall_setgroups(ngid, gid uintptr) (err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_setgroups)), fn: uintptr(unsafe.Pointer(&libc_setgroups)),
...@@ -220,6 +243,7 @@ func syscall_setgroups(ngid, gid uintptr) (err uintptr) { ...@@ -220,6 +243,7 @@ func syscall_setgroups(ngid, gid uintptr) (err uintptr) {
} }
//go:nosplit //go:nosplit
//go:linkname syscall_setsid
func syscall_setsid() (pid, err uintptr) { func syscall_setsid() (pid, err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_setsid)), fn: uintptr(unsafe.Pointer(&libc_setsid)),
...@@ -231,6 +255,7 @@ func syscall_setsid() (pid, err uintptr) { ...@@ -231,6 +255,7 @@ func syscall_setsid() (pid, err uintptr) {
} }
//go:nosplit //go:nosplit
//go:linkname syscall_setuid
func syscall_setuid(uid uintptr) (err uintptr) { func syscall_setuid(uid uintptr) (err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_setuid)), fn: uintptr(unsafe.Pointer(&libc_setuid)),
...@@ -242,6 +267,7 @@ func syscall_setuid(uid uintptr) (err uintptr) { ...@@ -242,6 +267,7 @@ func syscall_setuid(uid uintptr) (err uintptr) {
} }
//go:nosplit //go:nosplit
//go:linkname syscall_setpgid
func syscall_setpgid(pid, pgid uintptr) (err uintptr) { func syscall_setpgid(pid, pgid uintptr) (err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_setpgid)), fn: uintptr(unsafe.Pointer(&libc_setpgid)),
...@@ -252,6 +278,7 @@ func syscall_setpgid(pid, pgid uintptr) (err uintptr) { ...@@ -252,6 +278,7 @@ func syscall_setpgid(pid, pgid uintptr) (err uintptr) {
return call.err return call.err
} }
//go:linkname syscall_syscall
func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_syscall)), fn: uintptr(unsafe.Pointer(&libc_syscall)),
...@@ -264,6 +291,7 @@ func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) { ...@@ -264,6 +291,7 @@ func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
return call.r1, call.r2, call.err return call.r1, call.r2, call.err
} }
//go:linkname syscall_wait4
func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.Pointer) (wpid int, err uintptr) { func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.Pointer) (wpid int, err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_wait4)), fn: uintptr(unsafe.Pointer(&libc_wait4)),
...@@ -277,6 +305,7 @@ func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe. ...@@ -277,6 +305,7 @@ func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.
} }
//go:nosplit //go:nosplit
//go:linkname syscall_write
func syscall_write(fd, buf, nbyte uintptr) (n, err uintptr) { func syscall_write(fd, buf, nbyte uintptr) (n, err uintptr) {
call := libcall{ call := libcall{
fn: uintptr(unsafe.Pointer(&libc_write)), fn: uintptr(unsafe.Pointer(&libc_write)),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment