1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // GNU/Linux library calls.
13 //sysnb raw_ptrace(request int, pid int, addr *byte, data *byte) (err Errno)
14 //ptrace(request _C_int, pid Pid_t, addr *byte, data *byte) _C_long
16 func ptracePeek(req
int, pid
int, addr
uintptr, out
[]byte) (count
int, err error
) {
17 // The peek requests are machine-size oriented, so we wrap it
18 // to retrieve arbitrary-length data.
20 // The ptrace syscall differs from glibc's ptrace.
21 // Peeks returns the word in *data, not as the return value.
23 var buf
[sizeofPtr
]byte
25 // Leading edge. PEEKTEXT/PEEKDATA don't require aligned
26 // access (PEEKUSER warns that it might), but if we don't
27 // align our reads, we might straddle an unmapped page
28 // boundary and not get the bytes leading up to the page
31 if addr%sizeofPtr
!= 0 {
32 err
= ptrace(req
, pid
, addr
-addr%sizeofPtr
, uintptr(unsafe
.Pointer(&buf
[0])))
36 n
+= copy(out
, buf
[addr%sizeofPtr
:])
42 // We use an internal buffer to gaurantee alignment.
43 // It's not documented if this is necessary, but we're paranoid.
44 err
= ptrace(req
, pid
, addr
+uintptr(n
), uintptr(unsafe
.Pointer(&buf
[0])))
48 copied
:= copy(out
, buf
[0:])
56 func PtracePeekText(pid
int, addr
uintptr, out
[]byte) (count
int, err error
) {
57 return ptracePeek(PTRACE_PEEKTEXT
, pid
, addr
, out
)
60 func PtracePeekData(pid
int, addr
uintptr, out
[]byte) (count
int, err error
) {
61 return ptracePeek(PTRACE_PEEKDATA
, pid
, addr
, out
)
64 func ptracePoke(pokeReq
int, peekReq
int, pid
int, addr
uintptr, data
[]byte) (count
int, err error
) {
65 // As for ptracePeek, we need to align our accesses to deal
66 // with the possibility of straddling an invalid page.
70 if addr%sizeofPtr
!= 0 {
71 var buf
[sizeofPtr
]byte
72 err
= ptrace(peekReq
, pid
, addr
-addr%sizeofPtr
, uintptr(unsafe
.Pointer(&buf
[0])))
76 n
+= copy(buf
[addr%sizeofPtr
:], data
)
77 word
:= *((*uintptr)(unsafe
.Pointer(&buf
[0])))
78 err
= ptrace(pokeReq
, pid
, addr
-addr%sizeofPtr
, word
)
86 for len(data
) > int(sizeofPtr
) {
87 word
:= *((*uintptr)(unsafe
.Pointer(&data
[0])))
88 err
= ptrace(pokeReq
, pid
, addr
+uintptr(n
), word
)
93 data
= data
[sizeofPtr
:]
98 var buf
[sizeofPtr
]byte
99 err
= ptrace(peekReq
, pid
, addr
+uintptr(n
), uintptr(unsafe
.Pointer(&buf
[0])))
104 word
:= *((*uintptr)(unsafe
.Pointer(&buf
[0])))
105 err
= ptrace(pokeReq
, pid
, addr
+uintptr(n
), word
)
115 func PtracePokeText(pid
int, addr
uintptr, data
[]byte) (count
int, err error
) {
116 return ptracePoke(PTRACE_POKETEXT
, PTRACE_PEEKTEXT
, pid
, addr
, data
)
119 func PtracePokeData(pid
int, addr
uintptr, data
[]byte) (count
int, err error
) {
120 return ptracePoke(PTRACE_POKEDATA
, PTRACE_PEEKDATA
, pid
, addr
, data
)
123 func PtraceSetOptions(pid
int, options
int) (err error
) {
124 return ptrace(PTRACE_SETOPTIONS
, pid
, 0, uintptr(options
))
127 func PtraceGetEventMsg(pid
int) (msg
uint, err error
) {
129 err
= ptrace(PTRACE_GETEVENTMSG
, pid
, 0, uintptr(unsafe
.Pointer(&data
)))
134 func PtraceCont(pid
int, signal
int) (err error
) {
135 return ptrace(PTRACE_CONT
, pid
, 0, uintptr(signal
))
138 func PtraceSingleStep(pid
int) (err error
) { return ptrace(PTRACE_SINGLESTEP
, pid
, 0, 0) }
140 func PtraceAttach(pid
int) (err error
) { return ptrace(PTRACE_ATTACH
, pid
, 0, 0) }
142 func PtraceDetach(pid
int) (err error
) { return ptrace(PTRACE_DETACH
, pid
, 0, 0) }
144 //sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
145 //reboot(magic1 _C_uint, magic2 _C_uint, cmd _C_int, arg *byte) _C_int
146 func Reboot(cmd
int) (err error
) {
147 return reboot(LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, cmd
, "")
150 //sys Acct(path string) (err error)
151 //acct(path *byte) _C_int
153 //sys Adjtimex(buf *Timex) (state int, err error)
154 //adjtimex(buf *Timex) _C_int
156 //sys Fstatfs(fd int, buf *Statfs_t) (err error)
157 //fstatfs64(fd _C_int, buf *Statfs_t) _C_int
159 func Gettid() (tid
int) {
160 r1
, _
, _
:= Syscall(SYS_GETTID
, 0, 0, 0)
164 //sys Getxattr(path string, attr string, dest []byte) (sz int, err error)
165 //getxattr(path *byte, attr *byte, buf *byte, count Size_t) Ssize_t
167 //sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
168 //inotify_add_watch(fd _C_int, pathname *byte, mask uint32) _C_int
170 //sysnb InotifyInit() (fd int, err error)
171 //inotify_init() _C_int
173 //sysnb InotifyInit1(flags int) (fd int, err error)
174 //inotify_init1(flags _C_int) _C_int
176 //sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
177 //inotify_rm_watch(fd _C_int, wd uint32) _C_int
179 //sys Klogctl(typ int, buf []byte) (n int, err error)
180 //klogctl(typ _C_int, bufp *byte, len _C_int) _C_int
182 //sys Listxattr(path string, dest []byte) (sz int, err error)
183 //listxattr(path *byte, list *byte, size Size_t) Ssize_t
185 //sys PivotRoot(newroot string, putold string) (err error)
186 //pivot_root(newroot *byte, putold *byte) _C_int
188 //sys Removexattr(path string, attr string) (err error)
189 //removexattr(path *byte, name *byte) _C_int
191 //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
192 //renameat(olddirfd _C_int, oldpath *byte, newdirfd _C_int, newpath *byte) _C_int
194 //sys Setfsgid(gid int) (err error)
195 //setfsgid(gid Gid_t) _C_int
197 //sys Setfsuid(uid int) (err error)
198 //setfsuid(uid Uid_t) _C_int
200 //sysnb Setresgid(rgid int, egid int, sgid int) (err error)
201 //setresgid(rgid Gid_t, egid Gid_t, sgid Gid_t) _C_int
203 //sysnb Setresuid(ruid int, eguid int, suid int) (err error)
204 //setresuid(ruid Uid_t, euid Uid_t, suid Uid_t) _C_int
206 //sys Setxattr(path string, attr string, data []byte, flags int) (err error)
207 //setxattr(path *byte, name *byte, value *byte, size Size_t, flags _C_int) _C_int
209 //sys splice(rfd int, roff *_loff_t, wfd int, woff *_loff_t, len int, flags int) (n int64, err error)
210 //splice(rfd _C_int, roff *_loff_t, wfd _C_int, woff *_loff_t, len Size_t, flags _C_uint) Ssize_t
211 func Splice(rfd
int, roff
*int64, wfd
int, woff
*int64, len int, flags
int) (n
int64, err error
) {
215 lroff
= _loff_t(*roff
)
221 lwoff
= _loff_t(*woff
)
224 n
, err
= splice(rfd
, plroff
, wfd
, plwoff
, len, flags
)
234 //sys Statfs(path string, buf *Statfs_t) (err error)
235 //statfs64(path *byte, buf *Statfs_t) _C_int
237 //sysnb Sysinfo(info *Sysinfo_t) (err error)
238 //sysinfo(info *Sysinfo_t) _C_int
240 //sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
241 //tee(rfd _C_int, wfd _C_int, len Size_t, flags _C_uint) Ssize_t
243 func Tgkill(tgid
int, tid
int, sig Signal
) error
{
244 r1
, _
, errno
:= Syscall(SYS_TGKILL
, uintptr(tgid
), uintptr(tid
), uintptr(sig
))
251 //sys unlinkat(dirfd int, path string, flags int) (err error)
252 //unlinkat(dirfd _C_int, path *byte, flags _C_int) _C_int
254 func Unlinkat(dirfd
int, path
string) (err error
) {
255 return unlinkat(dirfd
, path
, 0)
258 //sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
259 //umount2(target *byte, flags _C_int) _C_int
261 //sys Unshare(flags int) (err error)
262 //unshare(flags _C_int) _C_int