github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/go/syscall/syscall_unix.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  // +build darwin dragonfly freebsd linux netbsd openbsd solaris
     6  
     7  package syscall
     8  
     9  import (
    10  	"runtime"
    11  	"sync"
    12  	"unsafe"
    13  )
    14  
    15  var (
    16  	Stdin  = 0
    17  	Stdout = 1
    18  	Stderr = 2
    19  )
    20  
    21  //extern syscall
    22  func c_syscall32(trap int32, a1, a2, a3, a4, a5, a6 int32) int32
    23  
    24  //extern syscall
    25  func c_syscall64(trap int64, a1, a2, a3, a4, a5, a6 int64) int64
    26  
    27  const (
    28  	darwin64Bit    = runtime.GOOS == "darwin" && sizeofPtr == 8
    29  	dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8
    30  	netbsd32Bit    = runtime.GOOS == "netbsd" && sizeofPtr == 4
    31  )
    32  
    33  // Do a system call.  We look at the size of uintptr to see how to pass
    34  // the arguments, so that we don't pass a 64-bit value when the function
    35  // expects a 32-bit one.
    36  func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
    37  	Entersyscall()
    38  	SetErrno(0)
    39  	var r uintptr
    40  	if unsafe.Sizeof(r) == 4 {
    41  		r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0)
    42  		r = uintptr(r1)
    43  	} else {
    44  		r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), 0, 0, 0)
    45  		r = uintptr(r1)
    46  	}
    47  	err = GetErrno()
    48  	Exitsyscall()
    49  	return r, 0, err
    50  }
    51  
    52  func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
    53  	Entersyscall()
    54  	SetErrno(0)
    55  	var r uintptr
    56  	if unsafe.Sizeof(r) == 4 {
    57  		r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
    58  			int32(a4), int32(a5), int32(a6))
    59  		r = uintptr(r1)
    60  	} else {
    61  		r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
    62  			int64(a4), int64(a5), int64(a6))
    63  		r = uintptr(r1)
    64  	}
    65  	err = GetErrno()
    66  	Exitsyscall()
    67  	return r, 0, err
    68  }
    69  
    70  func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
    71  	var r uintptr
    72  	SetErrno(0)
    73  	if unsafe.Sizeof(r) == 4 {
    74  		r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3), 0, 0, 0)
    75  		r = uintptr(r1)
    76  	} else {
    77  		r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3), 0, 0, 0)
    78  		r = uintptr(r1)
    79  	}
    80  	err = GetErrno()
    81  	return r, 0, err
    82  }
    83  
    84  func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
    85  	var r uintptr
    86  	SetErrno(0)
    87  	if unsafe.Sizeof(r) == 4 {
    88  		r1 := c_syscall32(int32(trap), int32(a1), int32(a2), int32(a3),
    89  			int32(a4), int32(a5), int32(a6))
    90  		r = uintptr(r1)
    91  	} else {
    92  		r1 := c_syscall64(int64(trap), int64(a1), int64(a2), int64(a3),
    93  			int64(a4), int64(a5), int64(a6))
    94  		r = uintptr(r1)
    95  	}
    96  	err = GetErrno()
    97  	return r, 0, err
    98  }
    99  
   100  // Mmap manager, for use by operating system-specific implementations.
   101  // Gccgo only has one implementation but we do this to correspond to gc.
   102  
   103  type mmapper struct {
   104  	sync.Mutex
   105  	active map[*byte][]byte // active mappings; key is last byte in mapping
   106  	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
   107  	munmap func(addr uintptr, length uintptr) error
   108  }
   109  
   110  func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
   111  	if length <= 0 {
   112  		return nil, EINVAL
   113  	}
   114  
   115  	// Map the requested memory.
   116  	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
   117  	if errno != nil {
   118  		return nil, errno
   119  	}
   120  
   121  	// Slice memory layout
   122  	var sl = struct {
   123  		addr uintptr
   124  		len  int
   125  		cap  int
   126  	}{addr, length, length}
   127  
   128  	// Use unsafe to turn sl into a []byte.
   129  	b := *(*[]byte)(unsafe.Pointer(&sl))
   130  
   131  	// Register mapping in m and return it.
   132  	p := &b[cap(b)-1]
   133  	m.Lock()
   134  	defer m.Unlock()
   135  	m.active[p] = b
   136  	return b, nil
   137  }
   138  
   139  func (m *mmapper) Munmap(data []byte) (err error) {
   140  	if len(data) == 0 || len(data) != cap(data) {
   141  		return EINVAL
   142  	}
   143  
   144  	// Find the base of the mapping.
   145  	p := &data[cap(data)-1]
   146  	m.Lock()
   147  	defer m.Unlock()
   148  	b := m.active[p]
   149  	if b == nil || &b[0] != &data[0] {
   150  		return EINVAL
   151  	}
   152  
   153  	// Unmap the memory and update m.
   154  	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
   155  		return errno
   156  	}
   157  	delete(m.active, p)
   158  	return nil
   159  }
   160  
   161  var mapper = &mmapper{
   162  	active: make(map[*byte][]byte),
   163  	mmap:   mmap,
   164  	munmap: munmap,
   165  }
   166  
   167  func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
   168  	return mapper.Mmap(fd, offset, length, prot, flags)
   169  }
   170  
   171  func Munmap(b []byte) (err error) {
   172  	return mapper.Munmap(b)
   173  }
   174  
   175  // Do the interface allocations only once for common
   176  // Errno values.
   177  var (
   178  	errEAGAIN error = EAGAIN
   179  	errEINVAL error = EINVAL
   180  	errENOENT error = ENOENT
   181  )
   182  
   183  // errnoErr returns common boxed Errno values, to prevent
   184  // allocations at runtime.
   185  func errnoErr(e Errno) error {
   186  	switch e {
   187  	case 0:
   188  		return nil
   189  	case EAGAIN:
   190  		return errEAGAIN
   191  	case EINVAL:
   192  		return errEINVAL
   193  	case ENOENT:
   194  		return errENOENT
   195  	}
   196  	return e
   197  }
   198  
   199  // A Signal is a number describing a process signal.
   200  // It implements the os.Signal interface.
   201  type Signal int
   202  
   203  func (s Signal) Signal() {}
   204  
   205  func Signame(s Signal) string
   206  
   207  func (s Signal) String() string {
   208  	return Signame(s)
   209  }
   210  
   211  func Read(fd int, p []byte) (n int, err error) {
   212  	n, err = read(fd, p)
   213  	if raceenabled {
   214  		if n > 0 {
   215  			raceWriteRange(unsafe.Pointer(&p[0]), n)
   216  		}
   217  		if err == nil {
   218  			raceAcquire(unsafe.Pointer(&ioSync))
   219  		}
   220  	}
   221  	return
   222  }
   223  
   224  func Write(fd int, p []byte) (n int, err error) {
   225  	if raceenabled {
   226  		raceReleaseMerge(unsafe.Pointer(&ioSync))
   227  	}
   228  	n, err = write(fd, p)
   229  	if raceenabled && n > 0 {
   230  		raceReadRange(unsafe.Pointer(&p[0]), n)
   231  	}
   232  	return
   233  }
   234  
   235  var ioSync int64