github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/runtime/os2_aix.go (about) 1 // Copyright 2018 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 // This file contains main runtime AIX syscalls. 6 // Pollset syscalls are in netpoll_aix.go. 7 // The implementation is based on Solaris and Windows. 8 // Each syscall is made by calling its libc symbol using asmcgocall and asmsyscall6 9 // asssembly functions. 10 11 package runtime 12 13 import ( 14 "unsafe" 15 ) 16 17 // Symbols imported for __start function. 18 19 //go:cgo_import_dynamic libc___n_pthreads __n_pthreads "libpthread.a/shr_xpg5_64.o" 20 //go:cgo_import_dynamic libc___mod_init __mod_init "libc.a/shr_64.o" 21 //go:linkname libc___n_pthreads libc___n_pthread 22 //go:linkname libc___mod_init libc___mod_init 23 24 var ( 25 libc___n_pthread, 26 libc___mod_init libFunc 27 ) 28 29 // Syscalls 30 31 //go:cgo_import_dynamic libc__Errno _Errno "libc.a/shr_64.o" 32 //go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.a/shr_64.o" 33 //go:cgo_import_dynamic libc_close close "libc.a/shr_64.o" 34 //go:cgo_import_dynamic libc_exit exit "libc.a/shr_64.o" 35 //go:cgo_import_dynamic libc_getpid getpid "libc.a/shr_64.o" 36 //go:cgo_import_dynamic libc_kill kill "libc.a/shr_64.o" 37 //go:cgo_import_dynamic libc_madvise madvise "libc.a/shr_64.o" 38 //go:cgo_import_dynamic libc_malloc malloc "libc.a/shr_64.o" 39 //go:cgo_import_dynamic libc_mmap mmap "libc.a/shr_64.o" 40 //go:cgo_import_dynamic libc_munmap munmap "libc.a/shr_64.o" 41 //go:cgo_import_dynamic libc_open open "libc.a/shr_64.o" 42 //go:cgo_import_dynamic libc_pipe pipe "libc.a/shr_64.o" 43 //go:cgo_import_dynamic libc_raise raise "libc.a/shr_64.o" 44 //go:cgo_import_dynamic libc_read read "libc.a/shr_64.o" 45 //go:cgo_import_dynamic libc_sched_yield sched_yield "libc.a/shr_64.o" 46 //go:cgo_import_dynamic libc_sem_init sem_init "libc.a/shr_64.o" 47 //go:cgo_import_dynamic libc_sem_post sem_post "libc.a/shr_64.o" 48 //go:cgo_import_dynamic libc_sem_timedwait sem_timedwait "libc.a/shr_64.o" 49 //go:cgo_import_dynamic libc_sem_wait sem_wait "libc.a/shr_64.o" 50 //go:cgo_import_dynamic libc_setitimer setitimer "libc.a/shr_64.o" 51 //go:cgo_import_dynamic libc_sigaction sigaction "libc.a/shr_64.o" 52 //go:cgo_import_dynamic libc_sigaltstack sigaltstack "libc.a/shr_64.o" 53 //go:cgo_import_dynamic libc_sysconf sysconf "libc.a/shr_64.o" 54 //go:cgo_import_dynamic libc_usleep usleep "libc.a/shr_64.o" 55 //go:cgo_import_dynamic libc_write write "libc.a/shr_64.o" 56 57 //go:cgo_import_dynamic libpthread___pth_init __pth_init "libpthread.a/shr_xpg5_64.o" 58 //go:cgo_import_dynamic libpthread_attr_destroy pthread_attr_destroy "libpthread.a/shr_xpg5_64.o" 59 //go:cgo_import_dynamic libpthread_attr_init pthread_attr_init "libpthread.a/shr_xpg5_64.o" 60 //go:cgo_import_dynamic libpthread_attr_getstacksize pthread_attr_getstacksize "libpthread.a/shr_xpg5_64.o" 61 //go:cgo_import_dynamic libpthread_attr_setstacksize pthread_attr_setstacksize "libpthread.a/shr_xpg5_64.o" 62 //go:cgo_import_dynamic libpthread_attr_setdetachstate pthread_attr_setdetachstate "libpthread.a/shr_xpg5_64.o" 63 //go:cgo_import_dynamic libpthread_attr_setstackaddr pthread_attr_setstackaddr "libpthread.a/shr_xpg5_64.o" 64 //go:cgo_import_dynamic libpthread_create pthread_create "libpthread.a/shr_xpg5_64.o" 65 //go:cgo_import_dynamic libpthread_sigthreadmask sigthreadmask "libpthread.a/shr_xpg5_64.o" 66 67 //go:linkname libc__Errno libc__Errno 68 //go:linkname libc_clock_gettime libc_clock_gettime 69 //go:linkname libc_close libc_close 70 //go:linkname libc_exit libc_exit 71 //go:linkname libc_getpid libc_getpid 72 //go:linkname libc_kill libc_kill 73 //go:linkname libc_madvise libc_madvise 74 //go:linkname libc_malloc libc_malloc 75 //go:linkname libc_mmap libc_mmap 76 //go:linkname libc_munmap libc_munmap 77 //go:linkname libc_open libc_open 78 //go:linkname libc_pipe libc_pipe 79 //go:linkname libc_raise libc_raise 80 //go:linkname libc_read libc_read 81 //go:linkname libc_sched_yield libc_sched_yield 82 //go:linkname libc_sem_init libc_sem_init 83 //go:linkname libc_sem_post libc_sem_post 84 //go:linkname libc_sem_timedwait libc_sem_timedwait 85 //go:linkname libc_sem_wait libc_sem_wait 86 //go:linkname libc_setitimer libc_setitimer 87 //go:linkname libc_sigaction libc_sigaction 88 //go:linkname libc_sigaltstack libc_sigaltstack 89 //go:linkname libc_sysconf libc_sysconf 90 //go:linkname libc_usleep libc_usleep 91 //go:linkname libc_write libc_write 92 93 //go:linkname libpthread___pth_init libpthread___pth_init 94 //go:linkname libpthread_attr_destroy libpthread_attr_destroy 95 //go:linkname libpthread_attr_init libpthread_attr_init 96 //go:linkname libpthread_attr_getstacksize libpthread_attr_getstacksize 97 //go:linkname libpthread_attr_setstacksize libpthread_attr_setstacksize 98 //go:linkname libpthread_attr_setdetachstate libpthread_attr_setdetachstate 99 //go:linkname libpthread_attr_setstackaddr libpthread_attr_setstackaddr 100 //go:linkname libpthread_create libpthread_create 101 //go:linkname libpthread_sigthreadmask libpthread_sigthreadmask 102 103 var ( 104 //libc 105 libc__Errno, 106 libc_clock_gettime, 107 libc_close, 108 libc_exit, 109 libc_getpid, 110 libc_kill, 111 libc_madvise, 112 libc_malloc, 113 libc_mmap, 114 libc_munmap, 115 libc_open, 116 libc_pipe, 117 libc_raise, 118 libc_read, 119 libc_sched_yield, 120 libc_sem_init, 121 libc_sem_post, 122 libc_sem_timedwait, 123 libc_sem_wait, 124 libc_setitimer, 125 libc_sigaction, 126 libc_sigaltstack, 127 libc_sysconf, 128 libc_usleep, 129 libc_write, 130 //libpthread 131 libpthread___pth_init, 132 libpthread_attr_destroy, 133 libpthread_attr_init, 134 libpthread_attr_getstacksize, 135 libpthread_attr_setstacksize, 136 libpthread_attr_setdetachstate, 137 libpthread_attr_setstackaddr, 138 libpthread_create, 139 libpthread_sigthreadmask libFunc 140 ) 141 142 type libFunc uintptr 143 144 // asmsyscall6 calls the libc symbol using a C convention. 145 // It's defined in sys_aix_ppc64.go. 146 var asmsyscall6 libFunc 147 148 //go:nowritebarrier 149 //go:nosplit 150 func syscall0(fn *libFunc) (r, err uintptr) { 151 c := &getg().m.libcall 152 c.fn = uintptr(unsafe.Pointer(fn)) 153 c.n = 0 154 c.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes 155 156 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c)) 157 158 return c.r1, c.err 159 } 160 161 //go:nowritebarrier 162 //go:nosplit 163 func syscall1(fn *libFunc, a0 uintptr) (r, err uintptr) { 164 c := &getg().m.libcall 165 c.fn = uintptr(unsafe.Pointer(fn)) 166 c.n = 1 167 c.args = uintptr(noescape(unsafe.Pointer(&a0))) 168 169 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c)) 170 171 return c.r1, c.err 172 } 173 174 //go:nowritebarrier 175 //go:nosplit 176 func syscall2(fn *libFunc, a0, a1 uintptr) (r, err uintptr) { 177 c := &getg().m.libcall 178 c.fn = uintptr(unsafe.Pointer(fn)) 179 c.n = 2 180 c.args = uintptr(noescape(unsafe.Pointer(&a0))) 181 182 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c)) 183 184 return c.r1, c.err 185 } 186 187 //go:nowritebarrier 188 //go:nosplit 189 func syscall3(fn *libFunc, a0, a1, a2 uintptr) (r, err uintptr) { 190 c := &getg().m.libcall 191 c.fn = uintptr(unsafe.Pointer(fn)) 192 c.n = 3 193 c.args = uintptr(noescape(unsafe.Pointer(&a0))) 194 195 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c)) 196 197 return c.r1, c.err 198 } 199 200 //go:nowritebarrier 201 //go:nosplit 202 func syscall4(fn *libFunc, a0, a1, a2, a3 uintptr) (r, err uintptr) { 203 c := &getg().m.libcall 204 c.fn = uintptr(unsafe.Pointer(fn)) 205 c.n = 4 206 c.args = uintptr(noescape(unsafe.Pointer(&a0))) 207 208 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c)) 209 210 return c.r1, c.err 211 } 212 213 //go:nowritebarrier 214 //go:nosplit 215 func syscall5(fn *libFunc, a0, a1, a2, a3, a4 uintptr) (r, err uintptr) { 216 c := &getg().m.libcall 217 c.fn = uintptr(unsafe.Pointer(fn)) 218 c.n = 5 219 c.args = uintptr(noescape(unsafe.Pointer(&a0))) 220 221 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c)) 222 223 return c.r1, c.err 224 } 225 226 //go:nowritebarrier 227 //go:nosplit 228 func syscall6(fn *libFunc, a0, a1, a2, a3, a4, a5 uintptr) (r, err uintptr) { 229 c := &getg().m.libcall 230 c.fn = uintptr(unsafe.Pointer(fn)) 231 c.n = 6 232 c.args = uintptr(noescape(unsafe.Pointer(&a0))) 233 234 asmcgocall(unsafe.Pointer(&asmsyscall6), unsafe.Pointer(c)) 235 236 return c.r1, c.err 237 } 238 239 //go:nosplit 240 func exit(code int32) { 241 syscall1(&libc_exit, uintptr(code)) 242 } 243 244 //go:nosplit 245 func write(fd uintptr, p unsafe.Pointer, n int32) int32 { 246 r, _ := syscall3(&libc_write, uintptr(fd), uintptr(p), uintptr(n)) 247 return int32(r) 248 249 } 250 251 //go:nosplit 252 func read(fd int32, p unsafe.Pointer, n int32) int32 { 253 r, _ := syscall3(&libc_read, uintptr(fd), uintptr(p), uintptr(n)) 254 return int32(r) 255 } 256 257 //go:nosplit 258 func open(name *byte, mode, perm int32) int32 { 259 r, _ := syscall3(&libc_open, uintptr(unsafe.Pointer(name)), uintptr(mode), uintptr(perm)) 260 return int32(r) 261 } 262 263 //go:nosplit 264 func closefd(fd int32) int32 { 265 r, _ := syscall1(&libc_close, uintptr(fd)) 266 return int32(r) 267 } 268 269 //go:nosplit 270 func pipe(fd *int32) int32 { 271 r, _ := syscall1(&libc_pipe, uintptr(unsafe.Pointer(fd))) 272 return int32(r) 273 } 274 275 // mmap calls the mmap system call. 276 // We only pass the lower 32 bits of file offset to the 277 // assembly routine; the higher bits (if required), should be provided 278 // by the assembly routine as 0. 279 // The err result is an OS error code such as ENOMEM. 280 //go:nosplit 281 func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int) { 282 r, err0 := syscall6(&libc_mmap, uintptr(addr), uintptr(n), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off)) 283 return unsafe.Pointer(r), int(err0) 284 } 285 286 //go:nosplit 287 func munmap(addr unsafe.Pointer, n uintptr) { 288 r, err := syscall2(&libc_munmap, uintptr(addr), uintptr(n)) 289 if int32(r) == -1 { 290 println("syscall munmap failed: ", hex(err)) 291 throw("syscall munmap") 292 } 293 } 294 295 //go:nosplit 296 func madvise(addr unsafe.Pointer, n uintptr, flags int32) { 297 r, err := syscall3(&libc_madvise, uintptr(addr), uintptr(n), uintptr(flags)) 298 if int32(r) == -1 { 299 println("syscall madvise failed: ", hex(err)) 300 throw("syscall madvise") 301 } 302 } 303 304 //go:nosplit 305 func sigaction(sig uintptr, new, old *sigactiont) { 306 r, err := syscall3(&libc_sigaction, sig, uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old))) 307 if int32(r) == -1 { 308 println("Sigaction failed for sig: ", sig, " with error:", hex(err)) 309 throw("syscall sigaction") 310 } 311 } 312 313 //go:nosplit 314 func sigaltstack(new, old *stackt) { 315 r, err := syscall2(&libc_sigaltstack, uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old))) 316 if int32(r) == -1 { 317 println("syscall sigaltstack failed: ", hex(err)) 318 throw("syscall sigaltstack") 319 } 320 } 321 322 //go:nosplit 323 func usleep(us uint32) { 324 r, err := syscall1(&libc_usleep, uintptr(us)) 325 if int32(r) == -1 { 326 println("syscall usleep failed: ", hex(err)) 327 throw("syscall usleep") 328 } 329 } 330 331 //go:nosplit 332 func clock_gettime(clockid int32, tp *timespec) int32 { 333 r, _ := syscall2(&libc_clock_gettime, uintptr(clockid), uintptr(unsafe.Pointer(tp))) 334 return int32(r) 335 } 336 337 //go:nosplit 338 func setitimer(mode int32, new, old *itimerval) { 339 r, err := syscall3(&libc_setitimer, uintptr(mode), uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old))) 340 if int32(r) == -1 { 341 println("syscall setitimer failed: ", hex(err)) 342 throw("syscall setitimer") 343 } 344 } 345 346 //go:nosplit 347 func malloc(size uintptr) unsafe.Pointer { 348 r, _ := syscall1(&libc_malloc, size) 349 return unsafe.Pointer(r) 350 } 351 352 //go:nosplit 353 func sem_init(sem *semt, pshared int32, value uint32) int32 { 354 r, _ := syscall3(&libc_sem_init, uintptr(unsafe.Pointer(sem)), uintptr(pshared), uintptr(value)) 355 return int32(r) 356 } 357 358 //go:nosplit 359 func sem_wait(sem *semt) (int32, int32) { 360 r, err := syscall1(&libc_sem_wait, uintptr(unsafe.Pointer(sem))) 361 return int32(r), int32(err) 362 } 363 364 //go:nosplit 365 func sem_post(sem *semt) int32 { 366 r, _ := syscall1(&libc_sem_post, uintptr(unsafe.Pointer(sem))) 367 return int32(r) 368 } 369 370 //go:nosplit 371 func sem_timedwait(sem *semt, timeout *timespec) (int32, int32) { 372 r, err := syscall2(&libc_sem_timedwait, uintptr(unsafe.Pointer(sem)), uintptr(unsafe.Pointer(timeout))) 373 return int32(r), int32(err) 374 } 375 376 //go:nosplit 377 func raise(sig uint32) { 378 r, err := syscall1(&libc_raise, uintptr(sig)) 379 if int32(r) == -1 { 380 println("syscall raise failed: ", hex(err)) 381 throw("syscall raise") 382 } 383 } 384 385 //go:nosplit 386 func raiseproc(sig uint32) { 387 pid, err := syscall0(&libc_getpid) 388 if int32(pid) == -1 { 389 println("syscall getpid failed: ", hex(err)) 390 throw("syscall raiseproc") 391 } 392 393 syscall2(&libc_kill, pid, uintptr(sig)) 394 } 395 396 func osyield1() 397 398 //go:nosplit 399 func osyield() { 400 _g_ := getg() 401 402 // Check the validity of m because we might be called in cgo callback 403 // path early enough where there isn't a m available yet. 404 if _g_ != nil && _g_.m != nil { 405 r, err := syscall0(&libc_sched_yield) 406 if int32(r) == -1 { 407 println("syscall osyield failed: ", hex(err)) 408 throw("syscall osyield") 409 } 410 return 411 } 412 osyield1() 413 } 414 415 //go:nosplit 416 func sysconf(name int32) uintptr { 417 r, _ := syscall1(&libc_sysconf, uintptr(name)) 418 if int32(r) == -1 { 419 throw("syscall sysconf") 420 } 421 return r 422 423 } 424 425 // pthread functions returns its error code in the main return value 426 // Therefore, err returns by syscall means nothing and must not be used 427 428 //go:nosplit 429 func pthread_attr_destroy(attr *pthread_attr) int32 { 430 r, _ := syscall1(&libpthread_attr_destroy, uintptr(unsafe.Pointer(attr))) 431 return int32(r) 432 } 433 434 //go:nosplit 435 func pthread_attr_init(attr *pthread_attr) int32 { 436 r, _ := syscall1(&libpthread_attr_init, uintptr(unsafe.Pointer(attr))) 437 return int32(r) 438 } 439 440 //go:nosplit 441 func pthread_attr_setdetachstate(attr *pthread_attr, state int32) int32 { 442 r, _ := syscall2(&libpthread_attr_setdetachstate, uintptr(unsafe.Pointer(attr)), uintptr(state)) 443 return int32(r) 444 } 445 446 //go:nosplit 447 func pthread_attr_setstackaddr(attr *pthread_attr, stk unsafe.Pointer) int32 { 448 r, _ := syscall2(&libpthread_attr_setstackaddr, uintptr(unsafe.Pointer(attr)), uintptr(stk)) 449 return int32(r) 450 } 451 452 //go:nosplit 453 func pthread_attr_getstacksize(attr *pthread_attr, size *uint64) int32 { 454 r, _ := syscall2(&libpthread_attr_getstacksize, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(size))) 455 return int32(r) 456 } 457 458 //go:nosplit 459 func pthread_attr_setstacksize(attr *pthread_attr, size uint64) int32 { 460 r, _ := syscall2(&libpthread_attr_setstacksize, uintptr(unsafe.Pointer(attr)), uintptr(size)) 461 return int32(r) 462 } 463 464 //go:nosplit 465 func pthread_create(tid *pthread, attr *pthread_attr, fn *funcDescriptor, arg unsafe.Pointer) int32 { 466 r, _ := syscall4(&libpthread_create, uintptr(unsafe.Pointer(tid)), uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(fn)), uintptr(arg)) 467 return int32(r) 468 } 469 470 // On multi-thread program, sigprocmask must not be called. 471 // It's replaced by sigthreadmask. 472 //go:nosplit 473 func sigprocmask(how int32, new, old *sigset) { 474 r, err := syscall3(&libpthread_sigthreadmask, uintptr(how), uintptr(unsafe.Pointer(new)), uintptr(unsafe.Pointer(old))) 475 if int32(r) != 0 { 476 println("syscall sigthreadmask failed: ", hex(err)) 477 throw("syscall sigthreadmask") 478 } 479 }