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  }