// 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.

// Linux system calls.
// This file is compiled as ordinary Go code,
// but it is also input to mksyscall,
// which parses the //sys lines and generates system call stubs.
// Note that sometimes we use a lowercase //sys name and
// wrap it in our own nicer implementation.

package syscall

import (
	
	
	
)

// N.B. RawSyscall6 is provided via linkname by runtime/internal/syscall.
//
// Errno is uintptr and thus compatible with the runtime/internal/syscall
// definition.

func (, , , , , ,  uintptr) (,  uintptr,  Errno)

// Pull in entersyscall/exitsyscall for Syscall/Syscall6.
//
// Note that this can't be a push linkname because the runtime already has a
// nameless linkname to export to assembly here and in x/sys. Additionally,
// entersyscall fetches the caller PC and SP and thus can't have a wrapper
// inbetween.

//go:linkname runtime_entersyscall runtime.entersyscall
func runtime_entersyscall()

//go:linkname runtime_exitsyscall runtime.exitsyscall
func runtime_exitsyscall()

// N.B. For the Syscall functions below:
//
// //go:uintptrkeepalive because the uintptr argument may be converted pointers
// that need to be kept alive in the caller (this is implied for RawSyscall6
// since it has no body).
//
// //go:nosplit because stack copying does not account for uintptrkeepalive, so
// the stack must not grow. Stack copying cannot blindly assume that all
// uintptr arguments are pointers, because some values may look like pointers,
// but not really be pointers, and adjusting their value would break the call.
//
// //go:norace, on RawSyscall, to avoid race instrumentation if RawSyscall is
// called after fork, or from a signal handler.
//
// //go:linkname to ensure ABI wrappers are generated for external callers
// (notably x/sys/unix assembly).

//go:uintptrkeepalive
//go:nosplit
//go:norace
//go:linkname RawSyscall
func (, , ,  uintptr) (,  uintptr,  Errno) {
	return RawSyscall6(, , , , 0, 0, 0)
}

//go:uintptrkeepalive
//go:nosplit
//go:linkname Syscall
func (, , ,  uintptr) (,  uintptr,  Errno) {
	runtime_entersyscall()
	// N.B. Calling RawSyscall here is unsafe with atomic coverage
	// instrumentation and race mode.
	//
	// Coverage instrumentation will add a sync/atomic call to RawSyscall.
	// Race mode will add race instrumentation to sync/atomic. Race
	// instrumentation requires a P, which we no longer have.
	//
	// RawSyscall6 is fine because it is implemented in assembly and thus
	// has no coverage instrumentation.
	//
	// This is typically not a problem in the runtime because cmd/go avoids
	// adding coverage instrumentation to the runtime in race mode.
	, ,  = RawSyscall6(, , , , 0, 0, 0)
	runtime_exitsyscall()
	return
}

//go:uintptrkeepalive
//go:nosplit
//go:linkname Syscall6
func (, , , , , ,  uintptr) (,  uintptr,  Errno) {
	runtime_entersyscall()
	, ,  = RawSyscall6(, , , , , , )
	runtime_exitsyscall()
	return
}

func rawSyscallNoError(, , ,  uintptr) (,  uintptr)
func rawVforkSyscall(, , ,  uintptr) ( uintptr,  Errno)

/*
 * Wrapped
 */

func ( string,  uint32) ( error) {
	return Faccessat(_AT_FDCWD, , , 0)
}

func ( string,  uint32) ( error) {
	return Fchmodat(_AT_FDCWD, , , 0)
}

func ( string,  int,  int) ( error) {
	return Fchownat(_AT_FDCWD, , , , 0)
}

func ( string,  uint32) ( int,  error) {
	return Open(, O_CREAT|O_WRONLY|O_TRUNC, )
}

func ( int) ( int,  error) {
	if  <= 0 {
		return -1, EINVAL
	}
	return EpollCreate1(0)
}

func isGroupMember( int) bool {
	,  := Getgroups()
	if  != nil {
		return false
	}

	for ,  := range  {
		if  ==  {
			return true
		}
	}
	return false
}

func isCapDacOverrideSet() bool {
	const  = 1
	var  caps
	.hdr.version = _LINUX_CAPABILITY_VERSION_3

	, ,  := RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&.hdr)), uintptr(unsafe.Pointer(&.data[0])), 0)

	return  == 0 && .data[0].effective&capToMask() != 0
}

//sys	faccessat(dirfd int, path string, mode uint32) (err error)
//sys	faccessat2(dirfd int, path string, mode uint32, flags int) (err error) = _SYS_faccessat2

func ( int,  string,  uint32,  int) ( error) {
	if  == 0 {
		return faccessat(, , )
	}

	// Attempt to use the newer faccessat2, which supports flags directly,
	// falling back if it doesn't exist.
	//
	// Don't attempt on Android, which does not allow faccessat2 through
	// its seccomp policy [1] on any version of Android as of 2022-12-20.
	//
	// [1] https://cs.android.com/android/platform/superproject/+/master:bionic/libc/SECCOMP_BLOCKLIST_APP.TXT;l=4;drc=dbb8670dfdcc677f7e3b9262e93800fa14c4e417
	if runtime.GOOS != "android" {
		if  := faccessat2(, , , );  != ENOSYS &&  != EPERM {
			return 
		}
	}

	// The Linux kernel faccessat system call does not take any flags.
	// The glibc faccessat implements the flags itself; see
	// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD
	// Because people naturally expect syscall.Faccessat to act
	// like C faccessat, we do the same.

	if  & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
		return EINVAL
	}

	var  Stat_t
	if  := fstatat(, , &, &_AT_SYMLINK_NOFOLLOW);  != nil {
		return 
	}

	 &= 7
	if  == 0 {
		return nil
	}

	// Fallback to checking permission bits.
	var  int
	if &_AT_EACCESS != 0 {
		 = Geteuid()
		if  != 0 && isCapDacOverrideSet() {
			// If CAP_DAC_OVERRIDE is set, file access check is
			// done by the kernel in the same way as for root
			// (see generic_permission() in the Linux sources).
			 = 0
		}
	} else {
		 = Getuid()
	}

	if  == 0 {
		if &1 == 0 {
			// Root can read and write any file.
			return nil
		}
		if .Mode&0111 != 0 {
			// Root can execute any file that anybody can execute.
			return nil
		}
		return EACCES
	}

	var  uint32
	if uint32() == .Uid {
		 = (.Mode >> 6) & 7
	} else {
		var  int
		if &_AT_EACCESS != 0 {
			 = Getegid()
		} else {
			 = Getgid()
		}

		if uint32() == .Gid || isGroupMember(int(.Gid)) {
			 = (.Mode >> 3) & 7
		} else {
			 = .Mode & 7
		}
	}

	if & ==  {
		return nil
	}

	return EACCES
}

//sys	fchmodat(dirfd int, path string, mode uint32) (err error)
//sys	fchmodat2(dirfd int, path string, mode uint32, flags int) (err error) = _SYS_fchmodat2

func ( int,  string,  uint32,  int) error {
	// Linux fchmodat doesn't support the flags parameter, but fchmodat2 does.
	// Try fchmodat2 if flags are specified.
	if  != 0 {
		 := fchmodat2(, , , )
		if  == ENOSYS {
			// fchmodat2 isn't available. If the flags are known to be valid,
			// return EOPNOTSUPP to indicate that fchmodat doesn't support them.
			if &^(_AT_SYMLINK_NOFOLLOW|_AT_EMPTY_PATH) != 0 {
				return EINVAL
			} else if &(_AT_SYMLINK_NOFOLLOW|_AT_EMPTY_PATH) != 0 {
				return EOPNOTSUPP
			}
		}
		return 
	}
	return fchmodat(, , )
}

//sys	linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)

func ( string,  string) ( error) {
	return linkat(_AT_FDCWD, , _AT_FDCWD, , 0)
}

func ( string,  uint32) ( error) {
	return Mkdirat(_AT_FDCWD, , )
}

func ( string,  uint32,  int) ( error) {
	return Mknodat(_AT_FDCWD, , , )
}

func ( string,  int,  uint32) ( int,  error) {
	return openat(_AT_FDCWD, , |O_LARGEFILE, )
}

//sys	openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)

func ( int,  string,  int,  uint32) ( int,  error) {
	return openat(, , |O_LARGEFILE, )
}

func ( []int) error {
	return Pipe2(, 0)
}

//sysnb pipe2(p *[2]_C_int, flags int) (err error)

func ( []int,  int) error {
	if len() != 2 {
		return EINVAL
	}
	var  [2]_C_int
	 := pipe2(&, )
	if  == nil {
		[0] = int([0])
		[1] = int([1])
	}
	return 
}

//sys	readlinkat(dirfd int, path string, buf []byte) (n int, err error)

func ( string,  []byte) ( int,  error) {
	return readlinkat(_AT_FDCWD, , )
}

func ( string,  string) ( error) {
	return Renameat(_AT_FDCWD, , _AT_FDCWD, )
}

func ( string) error {
	return unlinkat(_AT_FDCWD, , _AT_REMOVEDIR)
}

//sys	symlinkat(oldpath string, newdirfd int, newpath string) (err error)

func ( string,  string) ( error) {
	return symlinkat(, _AT_FDCWD, )
}

func ( string) error {
	return unlinkat(_AT_FDCWD, , 0)
}

//sys	unlinkat(dirfd int, path string, flags int) (err error)

func ( int,  string) error {
	return unlinkat(, , 0)
}

func ( string,  []Timeval) ( error) {
	if len() != 2 {
		return EINVAL
	}
	return utimes(, (*[2]Timeval)(unsafe.Pointer(&[0])))
}

//sys	utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)

func ( string,  []Timespec) ( error) {
	if len() != 2 {
		return EINVAL
	}
	return utimensat(_AT_FDCWD, , (*[2]Timespec)(unsafe.Pointer(&[0])), 0)
}

func ( int,  string,  []Timeval) ( error) {
	if len() != 2 {
		return EINVAL
	}
	return futimesat(, , (*[2]Timeval)(unsafe.Pointer(&[0])))
}

func ( int,  []Timeval) ( error) {
	// Believe it or not, this is the best we can do on Linux
	// (and is what glibc does).
	return Utimes("/proc/self/fd/"+itoa.Itoa(), )
}

const ImplementsGetwd = true

//sys	Getcwd(buf []byte) (n int, err error)

func () ( string,  error) {
	var  [PathMax]byte
	,  := Getcwd([0:])
	if  != nil {
		return "", 
	}
	// Getcwd returns the number of bytes written to buf, including the NUL.
	if  < 1 ||  > len() || [-1] != 0 {
		return "", EINVAL
	}
	// In some cases, Linux can return a path that starts with the
	// "(unreachable)" prefix, which can potentially be a valid relative
	// path. To work around that, return ENOENT if path is not absolute.
	if [0] != '/' {
		return "", ENOENT
	}

	return string([0 : -1]), nil
}

func () ( []int,  error) {
	,  := getgroups(0, nil)
	if  != nil {
		return nil, 
	}
	if  == 0 {
		return nil, nil
	}

	// Sanity check group count. Max is 1<<16 on Linux.
	if  < 0 ||  > 1<<20 {
		return nil, EINVAL
	}

	 := make([]_Gid_t, )
	,  = getgroups(, &[0])
	if  != nil {
		return nil, 
	}
	 = make([]int, )
	for ,  := range [0:] {
		[] = int()
	}
	return
}

var cgo_libc_setgroups unsafe.Pointer // non-nil if cgo linked.

func ( []int) ( error) {
	 := uintptr(len())
	if  == 0 {
		if cgo_libc_setgroups == nil {
			if , ,  := AllThreadsSyscall(_SYS_setgroups, 0, 0, 0);  != 0 {
				 = errnoErr()
			}
			return
		}
		if  := cgocaller(cgo_libc_setgroups, 0, 0);  != 0 {
			 = errnoErr(Errno())
		}
		return
	}

	 := make([]_Gid_t, len())
	for ,  := range  {
		[] = _Gid_t()
	}
	if cgo_libc_setgroups == nil {
		if , ,  := AllThreadsSyscall(_SYS_setgroups, , uintptr(unsafe.Pointer(&[0])), 0);  != 0 {
			 = errnoErr()
		}
		return
	}
	if  := cgocaller(cgo_libc_setgroups, , uintptr(unsafe.Pointer(&[0])));  != 0 {
		 = errnoErr(Errno())
	}
	return
}

type WaitStatus uint32

// Wait status is 7 bits at bottom, either 0 (exited),
// 0x7F (stopped), or a signal number that caused an exit.
// The 0x80 bit is whether there was a core dump.
// An extra number (exit code, signal causing a stop)
// is in the high bits. At least that's the idea.
// There are various irregularities. For example, the
// "continued" status is 0xFFFF, distinguishing itself
// from stopped via the core dump bit.

const (
	mask    = 0x7F
	core    = 0x80
	exited  = 0x00
	stopped = 0x7F
	shift   = 8
)

func ( WaitStatus) () bool { return &mask == exited }

func ( WaitStatus) () bool { return &mask != stopped && &mask != exited }

func ( WaitStatus) () bool { return &0xFF == stopped }

func ( WaitStatus) () bool { return  == 0xFFFF }

func ( WaitStatus) () bool { return .Signaled() && &core != 0 }

func ( WaitStatus) () int {
	if !.Exited() {
		return -1
	}
	return int(>>shift) & 0xFF
}

func ( WaitStatus) () Signal {
	if !.Signaled() {
		return -1
	}
	return Signal( & mask)
}

func ( WaitStatus) () Signal {
	if !.Stopped() {
		return -1
	}
	return Signal(>>shift) & 0xFF
}

func ( WaitStatus) () int {
	if .StopSignal() != SIGTRAP {
		return -1
	}
	return int(>>shift) >> 8
}

//sys	wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)

func ( int,  *WaitStatus,  int,  *Rusage) ( int,  error) {
	var  _C_int
	,  = wait4(, &, , )
	if  != nil {
		* = WaitStatus()
	}
	return
}

func ( string,  uint32) ( error) {
	return Mknod(, |S_IFIFO, 0)
}

func ( *SockaddrInet4) () (unsafe.Pointer, _Socklen, error) {
	if .Port < 0 || .Port > 0xFFFF {
		return nil, 0, EINVAL
	}
	.raw.Family = AF_INET
	 := (*[2]byte)(unsafe.Pointer(&.raw.Port))
	[0] = byte(.Port >> 8)
	[1] = byte(.Port)
	.raw.Addr = .Addr
	return unsafe.Pointer(&.raw), SizeofSockaddrInet4, nil
}

func ( *SockaddrInet6) () (unsafe.Pointer, _Socklen, error) {
	if .Port < 0 || .Port > 0xFFFF {
		return nil, 0, EINVAL
	}
	.raw.Family = AF_INET6
	 := (*[2]byte)(unsafe.Pointer(&.raw.Port))
	[0] = byte(.Port >> 8)
	[1] = byte(.Port)
	.raw.Scope_id = .ZoneId
	.raw.Addr = .Addr
	return unsafe.Pointer(&.raw), SizeofSockaddrInet6, nil
}

func ( *SockaddrUnix) () (unsafe.Pointer, _Socklen, error) {
	 := .Name
	 := len()
	if  > len(.raw.Path) {
		return nil, 0, EINVAL
	}
	if  == len(.raw.Path) && [0] != '@' {
		return nil, 0, EINVAL
	}
	.raw.Family = AF_UNIX
	for  := 0;  < ; ++ {
		.raw.Path[] = int8([])
	}
	// length is family (uint16), name, NUL.
	 := _Socklen(2)
	if  > 0 {
		 += _Socklen() + 1
	}
	if .raw.Path[0] == '@' || (.raw.Path[0] == 0 &&  > 3) {
		// Check sl > 3 so we don't change unnamed socket behavior.
		.raw.Path[0] = 0
		// Don't count trailing NUL for abstract address.
		--
	}

	return unsafe.Pointer(&.raw), , nil
}

type SockaddrLinklayer struct {
	Protocol uint16
	Ifindex  int
	Hatype   uint16
	Pkttype  uint8
	Halen    uint8
	Addr     [8]byte
	raw      RawSockaddrLinklayer
}

func ( *SockaddrLinklayer) () (unsafe.Pointer, _Socklen, error) {
	if .Ifindex < 0 || .Ifindex > 0x7fffffff {
		return nil, 0, EINVAL
	}
	.raw.Family = AF_PACKET
	.raw.Protocol = .Protocol
	.raw.Ifindex = int32(.Ifindex)
	.raw.Hatype = .Hatype
	.raw.Pkttype = .Pkttype
	.raw.Halen = .Halen
	.raw.Addr = .Addr
	return unsafe.Pointer(&.raw), SizeofSockaddrLinklayer, nil
}

type SockaddrNetlink struct {
	Family uint16
	Pad    uint16
	Pid    uint32
	Groups uint32
	raw    RawSockaddrNetlink
}

func ( *SockaddrNetlink) () (unsafe.Pointer, _Socklen, error) {
	.raw.Family = AF_NETLINK
	.raw.Pad = .Pad
	.raw.Pid = .Pid
	.raw.Groups = .Groups
	return unsafe.Pointer(&.raw), SizeofSockaddrNetlink, nil
}

func anyToSockaddr( *RawSockaddrAny) (Sockaddr, error) {
	switch .Addr.Family {
	case AF_NETLINK:
		 := (*RawSockaddrNetlink)(unsafe.Pointer())
		 := new(SockaddrNetlink)
		.Family = .Family
		.Pad = .Pad
		.Pid = .Pid
		.Groups = .Groups
		return , nil

	case AF_PACKET:
		 := (*RawSockaddrLinklayer)(unsafe.Pointer())
		 := new(SockaddrLinklayer)
		.Protocol = .Protocol
		.Ifindex = int(.Ifindex)
		.Hatype = .Hatype
		.Pkttype = .Pkttype
		.Halen = .Halen
		.Addr = .Addr
		return , nil

	case AF_UNIX:
		 := (*RawSockaddrUnix)(unsafe.Pointer())
		 := new(SockaddrUnix)
		if .Path[0] == 0 {
			// "Abstract" Unix domain socket.
			// Rewrite leading NUL as @ for textual display.
			// (This is the standard convention.)
			// Not friendly to overwrite in place,
			// but the callers below don't care.
			.Path[0] = '@'
		}

		// Assume path ends at NUL.
		// This is not technically the Linux semantics for
		// abstract Unix domain sockets--they are supposed
		// to be uninterpreted fixed-size binary blobs--but
		// everyone uses this convention.
		 := 0
		for  < len(.Path) && .Path[] != 0 {
			++
		}
		.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&.Path[0])), ))
		return , nil

	case AF_INET:
		 := (*RawSockaddrInet4)(unsafe.Pointer())
		 := new(SockaddrInet4)
		 := (*[2]byte)(unsafe.Pointer(&.Port))
		.Port = int([0])<<8 + int([1])
		.Addr = .Addr
		return , nil

	case AF_INET6:
		 := (*RawSockaddrInet6)(unsafe.Pointer())
		 := new(SockaddrInet6)
		 := (*[2]byte)(unsafe.Pointer(&.Port))
		.Port = int([0])<<8 + int([1])
		.ZoneId = .Scope_id
		.Addr = .Addr
		return , nil
	}
	return nil, EAFNOSUPPORT
}

func ( int,  int) ( int,  Sockaddr,  error) {
	var  RawSockaddrAny
	var  _Socklen = SizeofSockaddrAny
	,  = accept4(, &, &, )
	if  != nil {
		return
	}
	if  > SizeofSockaddrAny {
		panic("RawSockaddrAny too small")
	}
	,  = anyToSockaddr(&)
	if  != nil {
		Close()
		 = 0
	}
	return
}

func ( int) ( Sockaddr,  error) {
	var  RawSockaddrAny
	var  _Socklen = SizeofSockaddrAny
	if  = getsockname(, &, &);  != nil {
		return
	}
	return anyToSockaddr(&)
}

func (, ,  int) ( [4]byte,  error) {
	 := _Socklen(4)
	 = getsockopt(, , , unsafe.Pointer(&[0]), &)
	return , 
}

func (, ,  int) (*IPMreq, error) {
	var  IPMreq
	 := _Socklen(SizeofIPMreq)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int) (*IPMreqn, error) {
	var  IPMreqn
	 := _Socklen(SizeofIPMreqn)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int) (*IPv6Mreq, error) {
	var  IPv6Mreq
	 := _Socklen(SizeofIPv6Mreq)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int) (*IPv6MTUInfo, error) {
	var  IPv6MTUInfo
	 := _Socklen(SizeofIPv6MTUInfo)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int) (*ICMPv6Filter, error) {
	var  ICMPv6Filter
	 := _Socklen(SizeofICMPv6Filter)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int) (*Ucred, error) {
	var  Ucred
	 := _Socklen(SizeofUcred)
	 := getsockopt(, , , unsafe.Pointer(&), &)
	return &, 
}

func (, ,  int,  *IPMreqn) ( error) {
	return setsockopt(, , , unsafe.Pointer(), unsafe.Sizeof(*))
}

func recvmsgRaw( int, ,  []byte,  int,  *RawSockaddrAny) (,  int,  int,  error) {
	var  Msghdr
	.Name = (*byte)(unsafe.Pointer())
	.Namelen = uint32(SizeofSockaddrAny)
	var  Iovec
	if len() > 0 {
		.Base = &[0]
		.SetLen(len())
	}
	var  byte
	if len() > 0 {
		if len() == 0 {
			var  int
			,  = GetsockoptInt(, SOL_SOCKET, SO_TYPE)
			if  != nil {
				return
			}
			// receive at least one normal byte
			if  != SOCK_DGRAM {
				.Base = &
				.SetLen(1)
			}
		}
		.Control = &[0]
		.SetControllen(len())
	}
	.Iov = &
	.Iovlen = 1
	if ,  = recvmsg(, &, );  != nil {
		return
	}
	 = int(.Controllen)
	 = int(.Flags)
	return
}

func sendmsgN( int, ,  []byte,  unsafe.Pointer,  _Socklen,  int) ( int,  error) {
	var  Msghdr
	.Name = (*byte)()
	.Namelen = uint32()
	var  Iovec
	if len() > 0 {
		.Base = &[0]
		.SetLen(len())
	}
	var  byte
	if len() > 0 {
		if len() == 0 {
			var  int
			,  = GetsockoptInt(, SOL_SOCKET, SO_TYPE)
			if  != nil {
				return 0, 
			}
			// send at least one normal byte
			if  != SOCK_DGRAM {
				.Base = &
				.SetLen(1)
			}
		}
		.Control = &[0]
		.SetControllen(len())
	}
	.Iov = &
	.Iovlen = 1
	if ,  = sendmsg(, &, );  != nil {
		return 0, 
	}
	if len() > 0 && len() == 0 {
		 = 0
	}
	return , nil
}

// BindToDevice binds the socket associated with fd to device.
func ( int,  string) ( error) {
	return SetsockoptString(, SOL_SOCKET, SO_BINDTODEVICE, )
}

//sys	ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
//sys	ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) = SYS_PTRACE

func ptracePeek( int,  int,  uintptr,  []byte) ( int,  error) {
	// The peek requests are machine-size oriented, so we wrap it
	// to retrieve arbitrary-length data.

	// The ptrace syscall differs from glibc's ptrace.
	// Peeks returns the word in *data, not as the return value.

	var  [sizeofPtr]byte

	// Leading edge. PEEKTEXT/PEEKDATA don't require aligned
	// access (PEEKUSER warns that it might), but if we don't
	// align our reads, we might straddle an unmapped page
	// boundary and not get the bytes leading up to the page
	// boundary.
	 := 0
	if %sizeofPtr != 0 {
		 = ptracePtr(, , -%sizeofPtr, unsafe.Pointer(&[0]))
		if  != nil {
			return 0, 
		}
		 += copy(, [%sizeofPtr:])
		 = [:]
	}

	// Remainder.
	for len() > 0 {
		// We use an internal buffer to guarantee alignment.
		// It's not documented if this is necessary, but we're paranoid.
		 = ptracePtr(, , +uintptr(), unsafe.Pointer(&[0]))
		if  != nil {
			return , 
		}
		 := copy(, [0:])
		 += 
		 = [:]
	}

	return , nil
}

func ( int,  uintptr,  []byte) ( int,  error) {
	return ptracePeek(PTRACE_PEEKTEXT, , , )
}

func ( int,  uintptr,  []byte) ( int,  error) {
	return ptracePeek(PTRACE_PEEKDATA, , , )
}

func ptracePoke( int,  int,  int,  uintptr,  []byte) ( int,  error) {
	// As for ptracePeek, we need to align our accesses to deal
	// with the possibility of straddling an invalid page.

	// Leading edge.
	 := 0
	if %sizeofPtr != 0 {
		var  [sizeofPtr]byte
		 = ptracePtr(, , -%sizeofPtr, unsafe.Pointer(&[0]))
		if  != nil {
			return 0, 
		}
		 += copy([%sizeofPtr:], )
		 := *((*uintptr)(unsafe.Pointer(&[0])))
		 = ptrace(, , -%sizeofPtr, )
		if  != nil {
			return 0, 
		}
		 = [:]
	}

	// Interior.
	for len() > sizeofPtr {
		 := *((*uintptr)(unsafe.Pointer(&[0])))
		 = ptrace(, , +uintptr(), )
		if  != nil {
			return , 
		}
		 += sizeofPtr
		 = [sizeofPtr:]
	}

	// Trailing edge.
	if len() > 0 {
		var  [sizeofPtr]byte
		 = ptracePtr(, , +uintptr(), unsafe.Pointer(&[0]))
		if  != nil {
			return , 
		}
		copy([0:], )
		 := *((*uintptr)(unsafe.Pointer(&[0])))
		 = ptrace(, , +uintptr(), )
		if  != nil {
			return , 
		}
		 += len()
	}

	return , nil
}

func ( int,  uintptr,  []byte) ( int,  error) {
	return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, , , )
}

func ( int,  uintptr,  []byte) ( int,  error) {
	return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, , , )
}

const (
	_NT_PRSTATUS = 1
)

func ( int,  *PtraceRegs) ( error) {
	var  Iovec
	.Base = (*byte)(unsafe.Pointer())
	.SetLen(int(unsafe.Sizeof(*)))
	return ptracePtr(PTRACE_GETREGSET, , uintptr(_NT_PRSTATUS), unsafe.Pointer(&))
}

func ( int,  *PtraceRegs) ( error) {
	var  Iovec
	.Base = (*byte)(unsafe.Pointer())
	.SetLen(int(unsafe.Sizeof(*)))
	return ptracePtr(PTRACE_SETREGSET, , uintptr(_NT_PRSTATUS), unsafe.Pointer(&))
}

func ( int,  int) ( error) {
	return ptrace(PTRACE_SETOPTIONS, , 0, uintptr())
}

func ( int) ( uint,  error) {
	var  _C_long
	 = ptracePtr(PTRACE_GETEVENTMSG, , 0, unsafe.Pointer(&))
	 = uint()
	return
}

func ( int,  int) ( error) {
	return ptrace(PTRACE_CONT, , 0, uintptr())
}

func ( int,  int) ( error) {
	return ptrace(PTRACE_SYSCALL, , 0, uintptr())
}

func ( int) ( error) { return ptrace(PTRACE_SINGLESTEP, , 0, 0) }

func ( int) ( error) { return ptrace(PTRACE_ATTACH, , 0, 0) }

func ( int) ( error) { return ptrace(PTRACE_DETACH, , 0, 0) }

//sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)

func ( int) ( error) {
	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, , "")
}

func ( int,  []byte) ( int,  error) {
	return Getdents(, )
}

func direntIno( []byte) (uint64, bool) {
	return readInt(, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
}

func direntReclen( []byte) (uint64, bool) {
	return readInt(, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
}

func direntNamlen( []byte) (uint64, bool) {
	,  := direntReclen()
	if ! {
		return 0, false
	}
	return  - uint64(unsafe.Offsetof(Dirent{}.Name)), true
}

//sys	mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)

func ( string,  string,  string,  uintptr,  string) ( error) {
	// Certain file systems get rather angry and EINVAL if you give
	// them an empty string of data, rather than NULL.
	if  == "" {
		return mount(, , , , nil)
	}
	,  := BytePtrFromString()
	if  != nil {
		return 
	}
	return mount(, , , , )
}

// Sendto
// Recvfrom
// Socketpair

/*
 * Direct access
 */
//sys	Acct(path string) (err error)
//sys	Adjtimex(buf *Timex) (state int, err error)
//sys	Chdir(path string) (err error)
//sys	Chroot(path string) (err error)
//sys	Close(fd int) (err error)
//sys	Dup(oldfd int) (fd int, err error)
//sys	Dup3(oldfd int, newfd int, flags int) (err error)
//sysnb	EpollCreate1(flag int) (fd int, err error)
//sysnb	EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
//sys	Fallocate(fd int, mode uint32, off int64, len int64) (err error)
//sys	Fchdir(fd int) (err error)
//sys	Fchmod(fd int, mode uint32) (err error)
//sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
//sys	fcntl(fd int, cmd int, arg int) (val int, err error)
//sys	Fdatasync(fd int) (err error)
//sys	Flock(fd int, how int) (err error)
//sys	Fsync(fd int) (err error)
//sys	Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
//sysnb	Getpgid(pid int) (pgid int, err error)

func () ( int) {
	, _ = Getpgid(0)
	return
}

//sysnb	Getpid() (pid int)
//sysnb	Getppid() (ppid int)
//sys	Getpriority(which int, who int) (prio int, err error)
//sysnb	Getrusage(who int, rusage *Rusage) (err error)
//sysnb	Gettid() (tid int)
//sys	Getxattr(path string, attr string, dest []byte) (sz int, err error)
//sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
//sysnb	InotifyInit1(flags int) (fd int, err error)
//sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
//sysnb	Kill(pid int, sig Signal) (err error)
//sys	Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
//sys	Listxattr(path string, dest []byte) (sz int, err error)
//sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
//sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
//sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
//sys	PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
//sysnb prlimit1(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
//sys	read(fd int, p []byte) (n int, err error)
//sys	Removexattr(path string, attr string) (err error)
//sys	Setdomainname(p []byte) (err error)
//sys	Sethostname(p []byte) (err error)
//sysnb	Setpgid(pid int, pgid int) (err error)
//sysnb	Setsid() (pid int, err error)
//sysnb	Settimeofday(tv *Timeval) (err error)

// Provided by runtime.syscall_runtime_doAllThreadsSyscall which stops the
// world and invokes the syscall on each OS thread. Once this function returns,
// all threads are in sync.
//
//go:uintptrescapes
func runtime_doAllThreadsSyscall(, , , , , ,  uintptr) (, ,  uintptr)

// AllThreadsSyscall performs a syscall on each OS thread of the Go
// runtime. It first invokes the syscall on one thread. Should that
// invocation fail, it returns immediately with the error status.
// Otherwise, it invokes the syscall on all of the remaining threads
// in parallel. It will terminate the program if it observes any
// invoked syscall's return value differs from that of the first
// invocation.
//
// AllThreadsSyscall is intended for emulating simultaneous
// process-wide state changes that require consistently modifying
// per-thread state of the Go runtime.
//
// AllThreadsSyscall is unaware of any threads that are launched
// explicitly by cgo linked code, so the function always returns
// ENOTSUP in binaries that use cgo.
//
//go:uintptrescapes
func (, , ,  uintptr) (,  uintptr,  Errno) {
	if cgo_libc_setegid != nil {
		return minus1, minus1, ENOTSUP
	}
	, ,  := runtime_doAllThreadsSyscall(, , , , 0, 0, 0)
	return , , Errno()
}

// AllThreadsSyscall6 is like AllThreadsSyscall, but extended to six
// arguments.
//
//go:uintptrescapes
func (, , , , , ,  uintptr) (,  uintptr,  Errno) {
	if cgo_libc_setegid != nil {
		return minus1, minus1, ENOTSUP
	}
	, ,  := runtime_doAllThreadsSyscall(, , , , , , )
	return , , Errno()
}

// linked by runtime.cgocall.go
//
//go:uintptrescapes
func cgocaller(unsafe.Pointer, ...uintptr) uintptr

var cgo_libc_setegid unsafe.Pointer // non-nil if cgo linked.

const minus1 = ^uintptr(0)

func ( int) ( error) {
	if cgo_libc_setegid == nil {
		if , ,  := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(), minus1);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setegid, uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_seteuid unsafe.Pointer // non-nil if cgo linked.

func ( int) ( error) {
	if cgo_libc_seteuid == nil {
		if , ,  := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(), minus1);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_seteuid, uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setgid unsafe.Pointer // non-nil if cgo linked.

func ( int) ( error) {
	if cgo_libc_setgid == nil {
		if , ,  := AllThreadsSyscall(sys_SETGID, uintptr(), 0, 0);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setgid, uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setregid unsafe.Pointer // non-nil if cgo linked.

func (,  int) ( error) {
	if cgo_libc_setregid == nil {
		if , ,  := AllThreadsSyscall(sys_SETREGID, uintptr(), uintptr(), 0);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setregid, uintptr(), uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setresgid unsafe.Pointer // non-nil if cgo linked.

func (, ,  int) ( error) {
	if cgo_libc_setresgid == nil {
		if , ,  := AllThreadsSyscall(sys_SETRESGID, uintptr(), uintptr(), uintptr());  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setresgid, uintptr(), uintptr(), uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setresuid unsafe.Pointer // non-nil if cgo linked.

func (, ,  int) ( error) {
	if cgo_libc_setresuid == nil {
		if , ,  := AllThreadsSyscall(sys_SETRESUID, uintptr(), uintptr(), uintptr());  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setresuid, uintptr(), uintptr(), uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setreuid unsafe.Pointer // non-nil if cgo linked.

func (,  int) ( error) {
	if cgo_libc_setreuid == nil {
		if , ,  := AllThreadsSyscall(sys_SETREUID, uintptr(), uintptr(), 0);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setreuid, uintptr(), uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

var cgo_libc_setuid unsafe.Pointer // non-nil if cgo linked.

func ( int) ( error) {
	if cgo_libc_setuid == nil {
		if , ,  := AllThreadsSyscall(sys_SETUID, uintptr(), 0, 0);  != 0 {
			 = errnoErr()
		}
	} else if  := cgocaller(cgo_libc_setuid, uintptr());  != 0 {
		 = errnoErr(Errno())
	}
	return
}

//sys	Setpriority(which int, who int, prio int) (err error)
//sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
//sys	Sync()
//sysnb	Sysinfo(info *Sysinfo_t) (err error)
//sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
//sysnb	Tgkill(tgid int, tid int, sig Signal) (err error)
//sysnb	Times(tms *Tms) (ticks uintptr, err error)
//sysnb	Umask(mask int) (oldmask int)
//sysnb	Uname(buf *Utsname) (err error)
//sys	Unmount(target string, flags int) (err error) = SYS_UMOUNT2
//sys	Unshare(flags int) (err error)
//sys	write(fd int, p []byte) (n int, err error)
//sys	exitThread(code int) (err error) = SYS_EXIT
//sys	readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ

// mmap varies by architecture; see syscall_linux_*.go.
//sys	munmap(addr uintptr, length uintptr) (err error)

var mapper = &mmapper{
	active: make(map[*byte][]byte),
	mmap:   mmap,
	munmap: munmap,
}

func ( int,  int64,  int,  int,  int) ( []byte,  error) {
	return mapper.Mmap(, , , , )
}

func ( []byte) ( error) {
	return mapper.Munmap()
}

//sys	Madvise(b []byte, advice int) (err error)
//sys	Mprotect(b []byte, prot int) (err error)
//sys	Mlock(b []byte) (err error)
//sys	Munlock(b []byte) (err error)
//sys	Mlockall(flags int) (err error)
//sys	Munlockall() (err error)

// prlimit changes a resource limit. We use a single definition so that
// we can tell StartProcess to not restore the original NOFILE limit.
// This is unexported but can be called from x/sys/unix.
func prlimit( int,  int,  *Rlimit,  *Rlimit) ( error) {
	 = prlimit1(, , , )
	if  == nil &&  != nil &&  == RLIMIT_NOFILE {
		origRlimitNofile.Store(nil)
	}
	return 
}