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