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