439407aa2c
Only compile the __go_ptrace varargs shim on Linux to avoid compilation failures on some other platforms. The C ptrace function is not entirely portable (e.g., NetBSD has `int data` instead of `void* data`), and so far Linux is the only platform that needs the varargs shim. Additionally, make the types in the ptrace and raw_ptrace function declarations match. This makes it more clear that the only difference between the two is that calls via the former are allowed to block while calls via the latter are not. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/263517
145 lines
4.2 KiB
Go
145 lines
4.2 KiB
Go
// Copyright 2017 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 aix
|
|
|
|
package syscall
|
|
|
|
import (
|
|
"unsafe"
|
|
)
|
|
|
|
// For exec_unix.go.
|
|
const SYS_EXECVE = 0
|
|
|
|
//sys Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
|
|
//open64at(dirfd _C_int, path *byte, flags _C_int, mode Mode_t) _C_int
|
|
|
|
//sys ptrace64(request int, id int64, addr int64, data int, buff uintptr) (err error)
|
|
//ptrace64(request _C_int, id int64, addr int64, data _C_int, buff *byte) _C_int
|
|
|
|
func raw_ptrace(request int, pid int, addr uintptr, data uintptr) Errno {
|
|
if request == _PTRACE_TRACEME {
|
|
// Convert to AIX ptrace call.
|
|
err := ptrace64(_PT_TRACE_ME, 0, 0, 0, 0)
|
|
if err != nil {
|
|
return err.(Errno)
|
|
}
|
|
return 0
|
|
}
|
|
return ENOSYS
|
|
}
|
|
|
|
func ptracePeek(pid int, addr uintptr, out []byte) (count int, err error) {
|
|
n := 0
|
|
for len(out) > 0 {
|
|
bsize := len(out)
|
|
if bsize > 1024 {
|
|
bsize = 1024
|
|
}
|
|
err = ptrace64(_PT_READ_BLOCK, int64(pid), int64(addr), bsize, uintptr(unsafe.Pointer(&out[0])))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
addr += uintptr(bsize)
|
|
n += bsize
|
|
out = out[n:]
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
|
|
return ptracePeek(pid, addr, out)
|
|
}
|
|
|
|
func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
|
|
return ptracePeek(pid, addr, out)
|
|
}
|
|
|
|
func ptracePoke(pid int, addr uintptr, data []byte) (count int, err error) {
|
|
n := 0
|
|
for len(data) > 0 {
|
|
bsize := len(data)
|
|
if bsize > 1024 {
|
|
bsize = 1024
|
|
}
|
|
err = ptrace64(_PT_WRITE_BLOCK, int64(pid), int64(addr), bsize, uintptr(unsafe.Pointer(&data[0])))
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
addr += uintptr(bsize)
|
|
n += bsize
|
|
data = data[n:]
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
|
|
return ptracePoke(pid, addr, data)
|
|
}
|
|
|
|
func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
|
|
return ptracePoke(pid, addr, data)
|
|
}
|
|
|
|
func PtraceCont(pid int, signal int) (err error) {
|
|
return ptrace64(_PT_CONTINUE, int64(pid), 1, signal, 0)
|
|
}
|
|
|
|
func PtraceSingleStep(pid int) (err error) { return ptrace64(_PT_STEP, int64(pid), 1, 0, 0) }
|
|
|
|
func PtraceAttach(pid int) (err error) { return ptrace64(_PT_ATTACH, int64(pid), 0, 0, 0) }
|
|
|
|
func PtraceDetach(pid int) (err error) { return ptrace64(_PT_DETACH, int64(pid), 0, 0, 0) }
|
|
|
|
//sys reboot(how int) (err error)
|
|
//__linux_reboot(how _C_int) _C_int
|
|
func Reboot(how int) (err error) {
|
|
return reboot(how)
|
|
}
|
|
|
|
//sys Acct(path string) (err error)
|
|
//acct(path *byte) _C_int
|
|
|
|
//sys Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
|
|
//faccessat(dirfd _C_int, pathname *byte, mode _C_int, flags _C_int) _C_int
|
|
|
|
//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
|
|
//fchmodat(dirfd _C_int, pathname *byte, mode Mode_t, flags _C_int) _C_int
|
|
|
|
//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
|
|
//fchownat(dirfd _C_int, path *byte, owner Uid_t, group Gid_t, flags _C_int) _C_int
|
|
|
|
//sys Fstatfs(fd int, buf *Statfs_t) (err error)
|
|
//fstatfs64(fd _C_int, buf *Statfs_t) _C_int
|
|
|
|
//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
|
|
//mkdirat(dirfd _C_int, path *byte, mode Mode_t) _C_int
|
|
|
|
//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
|
|
//mknodat(dirfd _C_int, path *byte, mode Mode_t, dev _dev_t) _C_int
|
|
|
|
//sys getdirent(fd int, buf []byte) (n int, err error)
|
|
//getdirent64(fd _C_int, buf *byte, nbyte Size_t) _C_int
|
|
|
|
func ReadDirent(fd int, buf []byte) (n int, err error) {
|
|
return getdirent(fd, buf)
|
|
}
|
|
|
|
//sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
|
|
//renameat(olddirfd _C_int, oldpath *byte, newdirfd _C_int, newpath *byte) _C_int
|
|
|
|
//sys Statfs(path string, buf *Statfs_t) (err error)
|
|
//statfs64(path *byte, buf *Statfs_t) _C_int
|
|
|
|
//sys unlinkat(dirfd int, path string, flags int) (err error)
|
|
//unlinkat(dirfd _C_int, path *byte, flags _C_int) _C_int
|
|
|
|
func Unlinkat(dirfd int, path string) (err error) {
|
|
return unlinkat(dirfd, path, 0)
|
|
}
|
|
|
|
//sys Getkerninfo(op int32, where uintptr, size uintptr, arg int64) (i int32, err error)
|
|
//getkerninfo(op _C_int, where *byte, size *byte, arg _C_long) _C_int
|