github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/syscall/syscall_linux_386.go (about) 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. 4 5 package syscall 6 7 import "unsafe" 8 9 func Getpagesize() int { return 4096 } 10 11 func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 12 13 func NsecToTimespec(nsec int64) (ts Timespec) { 14 ts.Sec = int32(nsec / 1e9) 15 ts.Nsec = int32(nsec % 1e9) 16 return 17 } 18 19 func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } 20 21 func NsecToTimeval(nsec int64) (tv Timeval) { 22 nsec += 999 // round up to microsecond 23 tv.Sec = int32(nsec / 1e9) 24 tv.Usec = int32(nsec % 1e9 / 1e3) 25 return 26 } 27 28 // 64-bit file system and 32-bit uid calls 29 // (386 default is 32-bit file system and 16-bit uid). 30 //sys Chown(path string, uid int, gid int) (err error) = SYS_CHOWN32 31 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 32 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 33 //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 34 //sysnb Getegid() (egid int) = SYS_GETEGID32 35 //sysnb Geteuid() (euid int) = SYS_GETEUID32 36 //sysnb Getgid() (gid int) = SYS_GETGID32 37 //sysnb Getuid() (uid int) = SYS_GETUID32 38 //sys Ioperm(from int, num int, on int) (err error) 39 //sys Iopl(level int) (err error) 40 //sys Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32 41 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 42 //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 43 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 44 //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 45 //sys Setfsgid(gid int) (err error) = SYS_SETFSGID32 46 //sys Setfsuid(uid int) (err error) = SYS_SETFSUID32 47 //sysnb Setgid(gid int) (err error) = SYS_SETGID32 48 //sysnb Setregid(rgid int, egid int) (err error) = SYS_SETREGID32 49 //sysnb Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32 50 //sysnb Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32 51 //sysnb Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32 52 //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) 53 //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 54 //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) 55 //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 56 //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32 57 //sysnb setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32 58 //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT 59 60 //sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) 61 62 func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { 63 page := uintptr(offset / 4096) 64 if offset != int64(page)*4096 { 65 return 0, EINVAL 66 } 67 return mmap2(addr, length, prot, flags, fd, page) 68 } 69 70 type rlimit32 struct { 71 Cur uint32 72 Max uint32 73 } 74 75 //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT 76 77 const rlimInf32 = ^uint32(0) 78 const rlimInf64 = ^uint64(0) 79 80 func Getrlimit(resource int, rlim *Rlimit) (err error) { 81 err = prlimit(0, resource, nil, rlim) 82 if err != ENOSYS { 83 return err 84 } 85 86 rl := rlimit32{} 87 err = getrlimit(resource, &rl) 88 if err != nil { 89 return 90 } 91 92 if rl.Cur == rlimInf32 { 93 rlim.Cur = rlimInf64 94 } else { 95 rlim.Cur = uint64(rl.Cur) 96 } 97 98 if rl.Max == rlimInf32 { 99 rlim.Max = rlimInf64 100 } else { 101 rlim.Max = uint64(rl.Max) 102 } 103 return 104 } 105 106 //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT 107 108 func Setrlimit(resource int, rlim *Rlimit) (err error) { 109 err = prlimit(0, resource, rlim, nil) 110 if err != ENOSYS { 111 return err 112 } 113 114 rl := rlimit32{} 115 if rlim.Cur == rlimInf64 { 116 rl.Cur = rlimInf32 117 } else if rlim.Cur < uint64(rlimInf32) { 118 rl.Cur = uint32(rlim.Cur) 119 } else { 120 return EINVAL 121 } 122 if rlim.Max == rlimInf64 { 123 rl.Max = rlimInf32 124 } else if rlim.Max < uint64(rlimInf32) { 125 rl.Max = uint32(rlim.Max) 126 } else { 127 return EINVAL 128 } 129 130 return setrlimit(resource, &rl) 131 } 132 133 // Underlying system call writes to newoffset via pointer. 134 // Implemented in assembly to avoid allocation. 135 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) 136 137 // Vsyscalls on amd64. 138 //sysnb Gettimeofday(tv *Timeval) (err error) 139 //sysnb Time(t *Time_t) (tt Time_t, err error) 140 141 // On x86 Linux, all the socket calls go through an extra indirection, 142 // I think because the 5-register system call interface can't handle 143 // the 6-argument calls like sendto and recvfrom. Instead the 144 // arguments to the underlying system call are the number below 145 // and a pointer to an array of uintptr. We hide the pointer in the 146 // socketcall assembly to avoid allocation on every system call. 147 148 const ( 149 // see linux/net.h 150 _SOCKET = 1 151 _BIND = 2 152 _CONNECT = 3 153 _LISTEN = 4 154 _ACCEPT = 5 155 _GETSOCKNAME = 6 156 _GETPEERNAME = 7 157 _SOCKETPAIR = 8 158 _SEND = 9 159 _RECV = 10 160 _SENDTO = 11 161 _RECVFROM = 12 162 _SHUTDOWN = 13 163 _SETSOCKOPT = 14 164 _GETSOCKOPT = 15 165 _SENDMSG = 16 166 _RECVMSG = 17 167 _ACCEPT4 = 18 168 _RECVMMSG = 19 169 _SENDMMSG = 20 170 ) 171 172 func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno) 173 func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno) 174 175 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { 176 fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) 177 if e != 0 { 178 err = e 179 } 180 return 181 } 182 183 func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { 184 fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) 185 if e != 0 { 186 err = e 187 } 188 return 189 } 190 191 func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { 192 _, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) 193 if e != 0 { 194 err = e 195 } 196 return 197 } 198 199 func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { 200 _, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) 201 if e != 0 { 202 err = e 203 } 204 return 205 } 206 207 func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) { 208 _, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0) 209 if e != 0 { 210 err = e 211 } 212 return 213 } 214 215 func bind(s int, addr uintptr, addrlen _Socklen) (err error) { 216 _, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) 217 if e != 0 { 218 err = e 219 } 220 return 221 } 222 223 func connect(s int, addr uintptr, addrlen _Socklen) (err error) { 224 _, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) 225 if e != 0 { 226 err = e 227 } 228 return 229 } 230 231 func socket(domain int, typ int, proto int) (fd int, err error) { 232 fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0) 233 if e != 0 { 234 err = e 235 } 236 return 237 } 238 239 func getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) { 240 _, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) 241 if e != 0 { 242 err = e 243 } 244 return 245 } 246 247 func setsockopt(s int, level int, name int, val uintptr, vallen uintptr) (err error) { 248 _, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), val, vallen, 0) 249 if e != 0 { 250 err = e 251 } 252 return 253 } 254 255 func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { 256 var base uintptr 257 if len(p) > 0 { 258 base = uintptr(unsafe.Pointer(&p[0])) 259 } 260 n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) 261 if e != 0 { 262 err = e 263 } 264 return 265 } 266 267 func sendto(s int, p []byte, flags int, to uintptr, addrlen _Socklen) (err error) { 268 var base uintptr 269 if len(p) > 0 { 270 base = uintptr(unsafe.Pointer(&p[0])) 271 } 272 _, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), to, uintptr(addrlen)) 273 if e != 0 { 274 err = e 275 } 276 return 277 } 278 279 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { 280 n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) 281 if e != 0 { 282 err = e 283 } 284 return 285 } 286 287 func sendmsg(s int, msg *Msghdr, flags int) (err error) { 288 _, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) 289 if e != 0 { 290 err = e 291 } 292 return 293 } 294 295 func Listen(s int, n int) (err error) { 296 _, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0) 297 if e != 0 { 298 err = e 299 } 300 return 301 } 302 303 func Shutdown(s, how int) (err error) { 304 _, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0) 305 if e != 0 { 306 err = e 307 } 308 return 309 } 310 311 func Fstatfs(fd int, buf *Statfs_t) (err error) { 312 _, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf))) 313 if e != 0 { 314 err = e 315 } 316 return 317 } 318 319 func Statfs(path string, buf *Statfs_t) (err error) { 320 pathp, err := BytePtrFromString(path) 321 if err != nil { 322 return err 323 } 324 _, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf))) 325 if e != 0 { 326 err = e 327 } 328 return 329 } 330 331 func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) } 332 333 func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) } 334 335 func (iov *Iovec) SetLen(length int) { 336 iov.Len = uint32(length) 337 } 338 339 func (msghdr *Msghdr) SetControllen(length int) { 340 msghdr.Controllen = uint32(length) 341 } 342 343 func (cmsg *Cmsghdr) SetLen(length int) { 344 cmsg.Len = uint32(length) 345 }