github.com/code-reading/golang@v0.0.0-20220303082512-ba5bc0e589a3/go/src/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 // archHonorsR2 captures the fact that r2 is honored by the 10 // runtime.GOARCH. Syscall conventions are generally r1, r2, err := 11 // syscall(trap, ...). Not all architectures define r2 in their 12 // ABI. See "man syscall". 13 const archHonorsR2 = true 14 15 const _SYS_setgroups = SYS_SETGROUPS32 16 17 func setTimespec(sec, nsec int64) Timespec { 18 return Timespec{Sec: int32(sec), Nsec: int32(nsec)} 19 } 20 21 func setTimeval(sec, usec int64) Timeval { 22 return Timeval{Sec: int32(sec), Usec: int32(usec)} 23 } 24 25 //sysnb pipe(p *[2]_C_int) (err error) 26 27 func Pipe(p []int) (err error) { 28 if len(p) != 2 { 29 return EINVAL 30 } 31 var pp [2]_C_int 32 err = pipe(&pp) 33 if err == nil { 34 p[0] = int(pp[0]) 35 p[1] = int(pp[1]) 36 } 37 return 38 } 39 40 //sysnb pipe2(p *[2]_C_int, flags int) (err error) 41 42 func Pipe2(p []int, flags int) (err error) { 43 if len(p) != 2 { 44 return EINVAL 45 } 46 var pp [2]_C_int 47 err = pipe2(&pp, flags) 48 if err == nil { 49 p[0] = int(pp[0]) 50 p[1] = int(pp[1]) 51 } 52 return 53 } 54 55 // 64-bit file system and 32-bit uid calls 56 // (386 default is 32-bit file system and 16-bit uid). 57 //sys Dup2(oldfd int, newfd int) (err error) 58 //sysnb EpollCreate(size int) (fd int, err error) 59 //sys Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32 60 //sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64 61 //sys fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64 62 //sys Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64 63 //sysnb Getegid() (egid int) = SYS_GETEGID32 64 //sysnb Geteuid() (euid int) = SYS_GETEUID32 65 //sysnb Getgid() (gid int) = SYS_GETGID32 66 //sysnb Getuid() (uid int) = SYS_GETUID32 67 //sysnb InotifyInit() (fd int, err error) 68 //sys Ioperm(from int, num int, on int) (err error) 69 //sys Iopl(level int) (err error) 70 //sys Pause() (err error) 71 //sys Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64 72 //sys Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64 73 //sys Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) 74 //sys sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64 75 //sys Setfsgid(gid int) (err error) = SYS_SETFSGID32 76 //sys Setfsuid(uid int) (err error) = SYS_SETFSUID32 77 //sys Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) 78 //sys SyncFileRange(fd int, off int64, n int64, flags int) (err error) 79 //sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64 80 //sys Ustat(dev int, ubuf *Ustat_t) (err error) 81 //sysnb getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32 82 //sys Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT 83 84 //sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) 85 //sys EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) 86 87 func Stat(path string, stat *Stat_t) (err error) { 88 return fstatat(_AT_FDCWD, path, stat, 0) 89 } 90 91 func Lchown(path string, uid int, gid int) (err error) { 92 return Fchownat(_AT_FDCWD, path, uid, gid, _AT_SYMLINK_NOFOLLOW) 93 } 94 95 func Lstat(path string, stat *Stat_t) (err error) { 96 return fstatat(_AT_FDCWD, path, stat, _AT_SYMLINK_NOFOLLOW) 97 } 98 99 func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) { 100 page := uintptr(offset / 4096) 101 if offset != int64(page)*4096 { 102 return 0, EINVAL 103 } 104 return mmap2(addr, length, prot, flags, fd, page) 105 } 106 107 type rlimit32 struct { 108 Cur uint32 109 Max uint32 110 } 111 112 //sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT 113 114 const rlimInf32 = ^uint32(0) 115 const rlimInf64 = ^uint64(0) 116 117 func Getrlimit(resource int, rlim *Rlimit) (err error) { 118 err = prlimit(0, resource, nil, rlim) 119 if err != ENOSYS { 120 return err 121 } 122 123 rl := rlimit32{} 124 err = getrlimit(resource, &rl) 125 if err != nil { 126 return 127 } 128 129 if rl.Cur == rlimInf32 { 130 rlim.Cur = rlimInf64 131 } else { 132 rlim.Cur = uint64(rl.Cur) 133 } 134 135 if rl.Max == rlimInf32 { 136 rlim.Max = rlimInf64 137 } else { 138 rlim.Max = uint64(rl.Max) 139 } 140 return 141 } 142 143 //sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT 144 145 func Setrlimit(resource int, rlim *Rlimit) (err error) { 146 err = prlimit(0, resource, rlim, nil) 147 if err != ENOSYS { 148 return err 149 } 150 151 rl := rlimit32{} 152 if rlim.Cur == rlimInf64 { 153 rl.Cur = rlimInf32 154 } else if rlim.Cur < uint64(rlimInf32) { 155 rl.Cur = uint32(rlim.Cur) 156 } else { 157 return EINVAL 158 } 159 if rlim.Max == rlimInf64 { 160 rl.Max = rlimInf32 161 } else if rlim.Max < uint64(rlimInf32) { 162 rl.Max = uint32(rlim.Max) 163 } else { 164 return EINVAL 165 } 166 167 return setrlimit(resource, &rl) 168 } 169 170 // Underlying system call writes to newoffset via pointer. 171 // Implemented in assembly to avoid allocation. 172 func seek(fd int, offset int64, whence int) (newoffset int64, err Errno) 173 174 func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { 175 newoffset, errno := seek(fd, offset, whence) 176 if errno != 0 { 177 return 0, errno 178 } 179 return newoffset, nil 180 } 181 182 //sys futimesat(dirfd int, path string, times *[2]Timeval) (err error) 183 //sysnb Gettimeofday(tv *Timeval) (err error) 184 //sysnb Time(t *Time_t) (tt Time_t, err error) 185 //sys Utime(path string, buf *Utimbuf) (err error) 186 //sys utimes(path string, times *[2]Timeval) (err error) 187 188 // On x86 Linux, all the socket calls go through an extra indirection, 189 // I think because the 5-register system call interface can't handle 190 // the 6-argument calls like sendto and recvfrom. Instead the 191 // arguments to the underlying system call are the number below 192 // and a pointer to an array of uintptr. We hide the pointer in the 193 // socketcall assembly to avoid allocation on every system call. 194 195 const ( 196 // see linux/net.h 197 _SOCKET = 1 198 _BIND = 2 199 _CONNECT = 3 200 _LISTEN = 4 201 _ACCEPT = 5 202 _GETSOCKNAME = 6 203 _GETPEERNAME = 7 204 _SOCKETPAIR = 8 205 _SEND = 9 206 _RECV = 10 207 _SENDTO = 11 208 _RECVFROM = 12 209 _SHUTDOWN = 13 210 _SETSOCKOPT = 14 211 _GETSOCKOPT = 15 212 _SENDMSG = 16 213 _RECVMSG = 17 214 _ACCEPT4 = 18 215 _RECVMMSG = 19 216 _SENDMMSG = 20 217 ) 218 219 func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno) 220 func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno) 221 222 func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { 223 fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) 224 if e != 0 { 225 err = e 226 } 227 return 228 } 229 230 func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) { 231 fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) 232 if e != 0 { 233 err = e 234 } 235 return 236 } 237 238 func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { 239 _, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) 240 if e != 0 { 241 err = e 242 } 243 return 244 } 245 246 func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { 247 _, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) 248 if e != 0 { 249 err = e 250 } 251 return 252 } 253 254 func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) { 255 _, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0) 256 if e != 0 { 257 err = e 258 } 259 return 260 } 261 262 func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { 263 _, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) 264 if e != 0 { 265 err = e 266 } 267 return 268 } 269 270 func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { 271 _, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) 272 if e != 0 { 273 err = e 274 } 275 return 276 } 277 278 func socket(domain int, typ int, proto int) (fd int, err error) { 279 fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0) 280 if e != 0 { 281 err = e 282 } 283 return 284 } 285 286 func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { 287 _, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) 288 if e != 0 { 289 err = e 290 } 291 return 292 } 293 294 func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { 295 _, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0) 296 if e != 0 { 297 err = e 298 } 299 return 300 } 301 302 func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) { 303 var base uintptr 304 if len(p) > 0 { 305 base = uintptr(unsafe.Pointer(&p[0])) 306 } 307 n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) 308 if e != 0 { 309 err = e 310 } 311 return 312 } 313 314 func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) { 315 var base uintptr 316 if len(p) > 0 { 317 base = uintptr(unsafe.Pointer(&p[0])) 318 } 319 _, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen)) 320 if e != 0 { 321 err = e 322 } 323 return 324 } 325 326 func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { 327 n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) 328 if e != 0 { 329 err = e 330 } 331 return 332 } 333 334 func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { 335 n, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) 336 if e != 0 { 337 err = e 338 } 339 return 340 } 341 342 func Listen(s int, n int) (err error) { 343 _, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0) 344 if e != 0 { 345 err = e 346 } 347 return 348 } 349 350 func Shutdown(s, how int) (err error) { 351 _, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0) 352 if e != 0 { 353 err = e 354 } 355 return 356 } 357 358 func Fstatfs(fd int, buf *Statfs_t) (err error) { 359 _, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf))) 360 if e != 0 { 361 err = e 362 } 363 return 364 } 365 366 func Statfs(path string, buf *Statfs_t) (err error) { 367 pathp, err := BytePtrFromString(path) 368 if err != nil { 369 return err 370 } 371 _, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf))) 372 if e != 0 { 373 err = e 374 } 375 return 376 } 377 378 func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) } 379 380 func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) } 381 382 func (iov *Iovec) SetLen(length int) { 383 iov.Len = uint32(length) 384 } 385 386 func (msghdr *Msghdr) SetControllen(length int) { 387 msghdr.Controllen = uint32(length) 388 } 389 390 func (cmsg *Cmsghdr) SetLen(length int) { 391 cmsg.Len = uint32(length) 392 } 393 394 func rawVforkSyscall(trap, a1 uintptr) (r1 uintptr, err Errno)