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 5package runtime 6 7import ( 8 "internal/abi" 9 "internal/runtime/atomic" 10 "unsafe" 11) 12 13// The X versions of syscall expect the libc call to return a 64-bit result. 14// Otherwise (the non-X version) expects a 32-bit result. 15// This distinction is required because an error is indicated by returning -1, 16// and we need to know whether to check 32 or 64 bits of the result. 17// (Some libc functions that return 32 bits put junk in the upper 32 bits of AX.) 18 19// golang.org/x/sys linknames syscall_syscall 20// (in addition to standard package syscall). 21// Do not remove or change the type signature. 22// 23//go:linkname syscall_syscall syscall.syscall 24//go:nosplit 25func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { 26 args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err} 27 entersyscall() 28 libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&args)) 29 exitsyscall() 30 return args.r1, args.r2, args.err 31} 32func syscall() 33 34//go:linkname syscall_syscallX syscall.syscallX 35//go:nosplit 36func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { 37 args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err} 38 entersyscall() 39 libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallX)), unsafe.Pointer(&args)) 40 exitsyscall() 41 return args.r1, args.r2, args.err 42} 43func syscallX() 44 45// golang.org/x/sys linknames syscall.syscall6 46// (in addition to standard package syscall). 47// Do not remove or change the type signature. 48// 49// syscall.syscall6 is meant for package syscall (and x/sys), 50// but widely used packages access it using linkname. 51// Notable members of the hall of shame include: 52// - github.com/tetratelabs/wazero 53// 54// See go.dev/issue/67401. 55// 56//go:linkname syscall_syscall6 syscall.syscall6 57//go:nosplit 58func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { 59 args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err} 60 entersyscall() 61 libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&args)) 62 exitsyscall() 63 return args.r1, args.r2, args.err 64} 65func syscall6() 66 67// golang.org/x/sys linknames syscall.syscall9 68// (in addition to standard package syscall). 69// Do not remove or change the type signature. 70// 71//go:linkname syscall_syscall9 syscall.syscall9 72//go:nosplit 73//go:cgo_unsafe_args 74func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) { 75 entersyscall() 76 libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall9)), unsafe.Pointer(&fn)) 77 exitsyscall() 78 return 79} 80func syscall9() 81 82//go:linkname syscall_syscall6X syscall.syscall6X 83//go:nosplit 84func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { 85 args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err} 86 entersyscall() 87 libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&args)) 88 exitsyscall() 89 return args.r1, args.r2, args.err 90} 91func syscall6X() 92 93// golang.org/x/sys linknames syscall.syscallPtr 94// (in addition to standard package syscall). 95// Do not remove or change the type signature. 96// 97//go:linkname syscall_syscallPtr syscall.syscallPtr 98//go:nosplit 99func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { 100 args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err} 101 entersyscall() 102 libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallPtr)), unsafe.Pointer(&args)) 103 exitsyscall() 104 return args.r1, args.r2, args.err 105} 106func syscallPtr() 107 108// golang.org/x/sys linknames syscall_rawSyscall 109// (in addition to standard package syscall). 110// Do not remove or change the type signature. 111// 112//go:linkname syscall_rawSyscall syscall.rawSyscall 113//go:nosplit 114func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) { 115 args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err} 116 libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&args)) 117 return args.r1, args.r2, args.err 118} 119 120// golang.org/x/sys linknames syscall_rawSyscall6 121// (in addition to standard package syscall). 122// Do not remove or change the type signature. 123// 124//go:linkname syscall_rawSyscall6 syscall.rawSyscall6 125//go:nosplit 126func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) { 127 args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err} 128 libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&args)) 129 return args.r1, args.r2, args.err 130} 131 132// crypto_x509_syscall is used in crypto/x509/internal/macos to call into Security.framework and CF. 133 134//go:linkname crypto_x509_syscall crypto/x509/internal/macos.syscall 135//go:nosplit 136func crypto_x509_syscall(fn, a1, a2, a3, a4, a5 uintptr, f1 float64) (r1 uintptr) { 137 args := struct { 138 fn, a1, a2, a3, a4, a5 uintptr 139 f1 float64 140 r1 uintptr 141 }{fn, a1, a2, a3, a4, a5, f1, r1} 142 entersyscall() 143 libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall_x509)), unsafe.Pointer(&args)) 144 exitsyscall() 145 return args.r1 146} 147func syscall_x509() 148 149// The *_trampoline functions convert from the Go calling convention to the C calling convention 150// and then call the underlying libc function. They are defined in sys_darwin_$ARCH.s. 151 152//go:nosplit 153//go:cgo_unsafe_args 154func pthread_attr_init(attr *pthreadattr) int32 { 155 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_init_trampoline)), unsafe.Pointer(&attr)) 156 KeepAlive(attr) 157 return ret 158} 159func pthread_attr_init_trampoline() 160 161//go:nosplit 162//go:cgo_unsafe_args 163func pthread_attr_getstacksize(attr *pthreadattr, size *uintptr) int32 { 164 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr)) 165 KeepAlive(attr) 166 KeepAlive(size) 167 return ret 168} 169func pthread_attr_getstacksize_trampoline() 170 171//go:nosplit 172//go:cgo_unsafe_args 173func pthread_attr_setdetachstate(attr *pthreadattr, state int) int32 { 174 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr)) 175 KeepAlive(attr) 176 return ret 177} 178func pthread_attr_setdetachstate_trampoline() 179 180//go:nosplit 181//go:cgo_unsafe_args 182func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32 { 183 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_create_trampoline)), unsafe.Pointer(&attr)) 184 KeepAlive(attr) 185 KeepAlive(arg) // Just for consistency. Arg of course needs to be kept alive for the start function. 186 return ret 187} 188func pthread_create_trampoline() 189 190//go:nosplit 191//go:cgo_unsafe_args 192func raise(sig uint32) { 193 libcCall(unsafe.Pointer(abi.FuncPCABI0(raise_trampoline)), unsafe.Pointer(&sig)) 194} 195func raise_trampoline() 196 197//go:nosplit 198//go:cgo_unsafe_args 199func pthread_self() (t pthread) { 200 libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_self_trampoline)), unsafe.Pointer(&t)) 201 return 202} 203func pthread_self_trampoline() 204 205//go:nosplit 206//go:cgo_unsafe_args 207func pthread_kill(t pthread, sig uint32) { 208 libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_kill_trampoline)), unsafe.Pointer(&t)) 209 return 210} 211func pthread_kill_trampoline() 212 213// osinit_hack is a clumsy hack to work around Apple libc bugs 214// causing fork+exec to hang in the child process intermittently. 215// See go.dev/issue/33565 and go.dev/issue/56784 for a few reports. 216// 217// The stacks obtained from the hung child processes are in 218// libSystem_atfork_child, which is supposed to reinitialize various 219// parts of the C library in the new process. 220// 221// One common stack dies in _notify_fork_child calling _notify_globals 222// (inlined) calling _os_alloc_once, because _os_alloc_once detects that 223// the once lock is held by the parent process and then calls 224// _os_once_gate_corruption_abort. The allocation is setting up the 225// globals for the notification subsystem. See the source code at [1]. 226// To work around this, we can allocate the globals earlier in the Go 227// program's lifetime, before any execs are involved, by calling any 228// notify routine that is exported, calls _notify_globals, and doesn't do 229// anything too expensive otherwise. notify_is_valid_token(0) fits the bill. 230// 231// The other common stack dies in xpc_atfork_child calling 232// _objc_msgSend_uncached which ends up in 233// WAITING_FOR_ANOTHER_THREAD_TO_FINISH_CALLING_+initialize. Of course, 234// whatever thread the child is waiting for is in the parent process and 235// is not going to finish anything in the child process. There is no 236// public source code for these routines, so it is unclear exactly what 237// the problem is. An Apple engineer suggests using xpc_date_create_from_current, 238// which empirically does fix the problem. 239// 240// So osinit_hack_trampoline (in sys_darwin_$GOARCH.s) calls 241// notify_is_valid_token(0) and xpc_date_create_from_current(), which makes the 242// fork+exec hangs stop happening. If Apple fixes the libc bug in 243// some future version of macOS, then we can remove this awful code. 244// 245//go:nosplit 246func osinit_hack() { 247 if GOOS == "darwin" { // not ios 248 libcCall(unsafe.Pointer(abi.FuncPCABI0(osinit_hack_trampoline)), nil) 249 } 250 return 251} 252func osinit_hack_trampoline() 253 254// mmap is used to do low-level memory allocation via mmap. Don't allow stack 255// splits, since this function (used by sysAlloc) is called in a lot of low-level 256// parts of the runtime and callers often assume it won't acquire any locks. 257// 258//go:nosplit 259func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) { 260 args := struct { 261 addr unsafe.Pointer 262 n uintptr 263 prot, flags, fd int32 264 off uint32 265 ret1 unsafe.Pointer 266 ret2 int 267 }{addr, n, prot, flags, fd, off, nil, 0} 268 libcCall(unsafe.Pointer(abi.FuncPCABI0(mmap_trampoline)), unsafe.Pointer(&args)) 269 return args.ret1, args.ret2 270} 271func mmap_trampoline() 272 273//go:nosplit 274//go:cgo_unsafe_args 275func munmap(addr unsafe.Pointer, n uintptr) { 276 libcCall(unsafe.Pointer(abi.FuncPCABI0(munmap_trampoline)), unsafe.Pointer(&addr)) 277 KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address. 278} 279func munmap_trampoline() 280 281//go:nosplit 282//go:cgo_unsafe_args 283func madvise(addr unsafe.Pointer, n uintptr, flags int32) { 284 libcCall(unsafe.Pointer(abi.FuncPCABI0(madvise_trampoline)), unsafe.Pointer(&addr)) 285 KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address. 286} 287func madvise_trampoline() 288 289//go:nosplit 290//go:cgo_unsafe_args 291func mlock(addr unsafe.Pointer, n uintptr) { 292 libcCall(unsafe.Pointer(abi.FuncPCABI0(mlock_trampoline)), unsafe.Pointer(&addr)) 293 KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address. 294} 295func mlock_trampoline() 296 297//go:nosplit 298//go:cgo_unsafe_args 299func read(fd int32, p unsafe.Pointer, n int32) int32 { 300 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd)) 301 KeepAlive(p) 302 return ret 303} 304func read_trampoline() 305 306func pipe() (r, w int32, errno int32) { 307 var p [2]int32 308 errno = libcCall(unsafe.Pointer(abi.FuncPCABI0(pipe_trampoline)), noescape(unsafe.Pointer(&p))) 309 return p[0], p[1], errno 310} 311func pipe_trampoline() 312 313//go:nosplit 314//go:cgo_unsafe_args 315func closefd(fd int32) int32 { 316 return libcCall(unsafe.Pointer(abi.FuncPCABI0(close_trampoline)), unsafe.Pointer(&fd)) 317} 318func close_trampoline() 319 320// This is exported via linkname to assembly in runtime/cgo. 321// 322//go:nosplit 323//go:cgo_unsafe_args 324//go:linkname exit 325func exit(code int32) { 326 libcCall(unsafe.Pointer(abi.FuncPCABI0(exit_trampoline)), unsafe.Pointer(&code)) 327} 328func exit_trampoline() 329 330//go:nosplit 331//go:cgo_unsafe_args 332func usleep(usec uint32) { 333 libcCall(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec)) 334} 335func usleep_trampoline() 336 337//go:nosplit 338//go:cgo_unsafe_args 339func usleep_no_g(usec uint32) { 340 asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec)) 341} 342 343//go:nosplit 344//go:cgo_unsafe_args 345func write1(fd uintptr, p unsafe.Pointer, n int32) int32 { 346 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd)) 347 KeepAlive(p) 348 return ret 349} 350func write_trampoline() 351 352//go:nosplit 353//go:cgo_unsafe_args 354func open(name *byte, mode, perm int32) (ret int32) { 355 ret = libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name)) 356 KeepAlive(name) 357 return 358} 359func open_trampoline() 360 361//go:nosplit 362//go:cgo_unsafe_args 363func nanotime1() int64 { 364 var r struct { 365 t int64 // raw timer 366 numer, denom uint32 // conversion factors. nanoseconds = t * numer / denom. 367 } 368 libcCall(unsafe.Pointer(abi.FuncPCABI0(nanotime_trampoline)), unsafe.Pointer(&r)) 369 // Note: Apple seems unconcerned about overflow here. See 370 // https://developer.apple.com/library/content/qa/qa1398/_index.html 371 // Note also, numer == denom == 1 is common. 372 t := r.t 373 if r.numer != 1 { 374 t *= int64(r.numer) 375 } 376 if r.denom != 1 { 377 t /= int64(r.denom) 378 } 379 return t 380} 381func nanotime_trampoline() 382 383// walltime should be an internal detail, 384// but widely used packages access it using linkname. 385// Notable members of the hall of shame include: 386// - gitee.com/quant1x/gox 387// 388// Do not remove or change the type signature. 389// See go.dev/issue/67401. 390// 391//go:linkname walltime 392//go:nosplit 393//go:cgo_unsafe_args 394func walltime() (int64, int32) { 395 var t timespec 396 libcCall(unsafe.Pointer(abi.FuncPCABI0(walltime_trampoline)), unsafe.Pointer(&t)) 397 return t.tv_sec, int32(t.tv_nsec) 398} 399func walltime_trampoline() 400 401//go:nosplit 402//go:cgo_unsafe_args 403func sigaction(sig uint32, new *usigactiont, old *usigactiont) { 404 libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaction_trampoline)), unsafe.Pointer(&sig)) 405 KeepAlive(new) 406 KeepAlive(old) 407} 408func sigaction_trampoline() 409 410//go:nosplit 411//go:cgo_unsafe_args 412func sigprocmask(how uint32, new *sigset, old *sigset) { 413 libcCall(unsafe.Pointer(abi.FuncPCABI0(sigprocmask_trampoline)), unsafe.Pointer(&how)) 414 KeepAlive(new) 415 KeepAlive(old) 416} 417func sigprocmask_trampoline() 418 419//go:nosplit 420//go:cgo_unsafe_args 421func sigaltstack(new *stackt, old *stackt) { 422 if new != nil && new.ss_flags&_SS_DISABLE != 0 && new.ss_size == 0 { 423 // Despite the fact that Darwin's sigaltstack man page says it ignores the size 424 // when SS_DISABLE is set, it doesn't. sigaltstack returns ENOMEM 425 // if we don't give it a reasonable size. 426 // ref: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20140421/214296.html 427 new.ss_size = 32768 428 } 429 libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaltstack_trampoline)), unsafe.Pointer(&new)) 430 KeepAlive(new) 431 KeepAlive(old) 432} 433func sigaltstack_trampoline() 434 435//go:nosplit 436//go:cgo_unsafe_args 437func raiseproc(sig uint32) { 438 libcCall(unsafe.Pointer(abi.FuncPCABI0(raiseproc_trampoline)), unsafe.Pointer(&sig)) 439} 440func raiseproc_trampoline() 441 442//go:nosplit 443//go:cgo_unsafe_args 444func setitimer(mode int32, new, old *itimerval) { 445 libcCall(unsafe.Pointer(abi.FuncPCABI0(setitimer_trampoline)), unsafe.Pointer(&mode)) 446 KeepAlive(new) 447 KeepAlive(old) 448} 449func setitimer_trampoline() 450 451//go:nosplit 452//go:cgo_unsafe_args 453func sysctl(mib *uint32, miblen uint32, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 { 454 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib)) 455 KeepAlive(mib) 456 KeepAlive(oldp) 457 KeepAlive(oldlenp) 458 KeepAlive(newp) 459 return ret 460} 461func sysctl_trampoline() 462 463//go:nosplit 464//go:cgo_unsafe_args 465func sysctlbyname(name *byte, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 { 466 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctlbyname_trampoline)), unsafe.Pointer(&name)) 467 KeepAlive(name) 468 KeepAlive(oldp) 469 KeepAlive(oldlenp) 470 KeepAlive(newp) 471 return ret 472} 473func sysctlbyname_trampoline() 474 475//go:nosplit 476//go:cgo_unsafe_args 477func fcntl(fd, cmd, arg int32) (ret int32, errno int32) { 478 args := struct { 479 fd, cmd, arg int32 480 ret, errno int32 481 }{fd, cmd, arg, 0, 0} 482 libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&args)) 483 return args.ret, args.errno 484} 485func fcntl_trampoline() 486 487//go:nosplit 488//go:cgo_unsafe_args 489func kqueue() int32 { 490 v := libcCall(unsafe.Pointer(abi.FuncPCABI0(kqueue_trampoline)), nil) 491 return v 492} 493func kqueue_trampoline() 494 495//go:nosplit 496//go:cgo_unsafe_args 497func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 { 498 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq)) 499 KeepAlive(ch) 500 KeepAlive(ev) 501 KeepAlive(ts) 502 return ret 503} 504func kevent_trampoline() 505 506//go:nosplit 507//go:cgo_unsafe_args 508func pthread_mutex_init(m *pthreadmutex, attr *pthreadmutexattr) int32 { 509 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_init_trampoline)), unsafe.Pointer(&m)) 510 KeepAlive(m) 511 KeepAlive(attr) 512 return ret 513} 514func pthread_mutex_init_trampoline() 515 516//go:nosplit 517//go:cgo_unsafe_args 518func pthread_mutex_lock(m *pthreadmutex) int32 { 519 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_lock_trampoline)), unsafe.Pointer(&m)) 520 KeepAlive(m) 521 return ret 522} 523func pthread_mutex_lock_trampoline() 524 525//go:nosplit 526//go:cgo_unsafe_args 527func pthread_mutex_unlock(m *pthreadmutex) int32 { 528 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_unlock_trampoline)), unsafe.Pointer(&m)) 529 KeepAlive(m) 530 return ret 531} 532func pthread_mutex_unlock_trampoline() 533 534//go:nosplit 535//go:cgo_unsafe_args 536func pthread_cond_init(c *pthreadcond, attr *pthreadcondattr) int32 { 537 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_init_trampoline)), unsafe.Pointer(&c)) 538 KeepAlive(c) 539 KeepAlive(attr) 540 return ret 541} 542func pthread_cond_init_trampoline() 543 544//go:nosplit 545//go:cgo_unsafe_args 546func pthread_cond_wait(c *pthreadcond, m *pthreadmutex) int32 { 547 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_wait_trampoline)), unsafe.Pointer(&c)) 548 KeepAlive(c) 549 KeepAlive(m) 550 return ret 551} 552func pthread_cond_wait_trampoline() 553 554//go:nosplit 555//go:cgo_unsafe_args 556func pthread_cond_timedwait_relative_np(c *pthreadcond, m *pthreadmutex, t *timespec) int32 { 557 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c)) 558 KeepAlive(c) 559 KeepAlive(m) 560 KeepAlive(t) 561 return ret 562} 563func pthread_cond_timedwait_relative_np_trampoline() 564 565//go:nosplit 566//go:cgo_unsafe_args 567func pthread_cond_signal(c *pthreadcond) int32 { 568 ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_signal_trampoline)), unsafe.Pointer(&c)) 569 KeepAlive(c) 570 return ret 571} 572func pthread_cond_signal_trampoline() 573 574// Not used on Darwin, but must be defined. 575func exitThread(wait *atomic.Uint32) { 576 throw("exitThread") 577} 578 579//go:nosplit 580func setNonblock(fd int32) { 581 flags, _ := fcntl(fd, _F_GETFL, 0) 582 if flags != -1 { 583 fcntl(fd, _F_SETFL, flags|_O_NONBLOCK) 584 } 585} 586 587func issetugid() int32 { 588 return libcCall(unsafe.Pointer(abi.FuncPCABI0(issetugid_trampoline)), nil) 589} 590func issetugid_trampoline() 591 592// mach_vm_region is used to obtain virtual memory mappings for use by the 593// profiling system and is only exported to runtime/pprof. It is restricted 594// to obtaining mappings for the current process. 595// 596//go:linkname mach_vm_region runtime/pprof.mach_vm_region 597func mach_vm_region(address, region_size *uint64, info unsafe.Pointer) int32 { 598 // kern_return_t mach_vm_region( 599 // vm_map_read_t target_task, 600 // mach_vm_address_t *address, 601 // mach_vm_size_t *size, 602 // vm_region_flavor_t flavor, 603 // vm_region_info_t info, 604 // mach_msg_type_number_t *infoCnt, 605 // mach_port_t *object_name); 606 var count machMsgTypeNumber = _VM_REGION_BASIC_INFO_COUNT_64 607 var object_name machPort 608 args := struct { 609 address *uint64 610 size *uint64 611 flavor machVMRegionFlavour 612 info unsafe.Pointer 613 count *machMsgTypeNumber 614 object_name *machPort 615 }{ 616 address: address, 617 size: region_size, 618 flavor: _VM_REGION_BASIC_INFO_64, 619 info: info, 620 count: &count, 621 object_name: &object_name, 622 } 623 return libcCall(unsafe.Pointer(abi.FuncPCABI0(mach_vm_region_trampoline)), unsafe.Pointer(&args)) 624} 625func mach_vm_region_trampoline() 626 627//go:linkname proc_regionfilename runtime/pprof.proc_regionfilename 628func proc_regionfilename(pid int, address uint64, buf *byte, buflen int64) int32 { 629 args := struct { 630 pid int 631 address uint64 632 buf *byte 633 bufSize int64 634 }{ 635 pid: pid, 636 address: address, 637 buf: buf, 638 bufSize: buflen, 639 } 640 return libcCall(unsafe.Pointer(abi.FuncPCABI0(proc_regionfilename_trampoline)), unsafe.Pointer(&args)) 641} 642func proc_regionfilename_trampoline() 643 644// Tell the linker that the libc_* functions are to be found 645// in a system library, with the libc_ prefix missing. 646 647//go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "/usr/lib/libSystem.B.dylib" 648//go:cgo_import_dynamic libc_pthread_attr_getstacksize pthread_attr_getstacksize "/usr/lib/libSystem.B.dylib" 649//go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "/usr/lib/libSystem.B.dylib" 650//go:cgo_import_dynamic libc_pthread_create pthread_create "/usr/lib/libSystem.B.dylib" 651//go:cgo_import_dynamic libc_pthread_self pthread_self "/usr/lib/libSystem.B.dylib" 652//go:cgo_import_dynamic libc_pthread_kill pthread_kill "/usr/lib/libSystem.B.dylib" 653//go:cgo_import_dynamic libc_exit _exit "/usr/lib/libSystem.B.dylib" 654//go:cgo_import_dynamic libc_raise raise "/usr/lib/libSystem.B.dylib" 655 656//go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib" 657//go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib" 658//go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib" 659//go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib" 660//go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib" 661 662//go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib" 663//go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib" 664//go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib" 665//go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib" 666//go:cgo_import_dynamic libc_error __error "/usr/lib/libSystem.B.dylib" 667//go:cgo_import_dynamic libc_usleep usleep "/usr/lib/libSystem.B.dylib" 668 669//go:cgo_import_dynamic libc_proc_regionfilename proc_regionfilename "/usr/lib/libSystem.B.dylib" 670//go:cgo_import_dynamic libc_mach_task_self_ mach_task_self_ "/usr/lib/libSystem.B.dylib"" 671//go:cgo_import_dynamic libc_mach_vm_region mach_vm_region "/usr/lib/libSystem.B.dylib"" 672//go:cgo_import_dynamic libc_mach_timebase_info mach_timebase_info "/usr/lib/libSystem.B.dylib" 673//go:cgo_import_dynamic libc_mach_absolute_time mach_absolute_time "/usr/lib/libSystem.B.dylib" 674//go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib" 675//go:cgo_import_dynamic libc_sigaction sigaction "/usr/lib/libSystem.B.dylib" 676//go:cgo_import_dynamic libc_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib" 677//go:cgo_import_dynamic libc_sigaltstack sigaltstack "/usr/lib/libSystem.B.dylib" 678//go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib" 679//go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib" 680//go:cgo_import_dynamic libc_setitimer setitimer "/usr/lib/libSystem.B.dylib" 681//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib" 682//go:cgo_import_dynamic libc_sysctlbyname sysctlbyname "/usr/lib/libSystem.B.dylib" 683//go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib" 684//go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib" 685//go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib" 686 687//go:cgo_import_dynamic libc_pthread_mutex_init pthread_mutex_init "/usr/lib/libSystem.B.dylib" 688//go:cgo_import_dynamic libc_pthread_mutex_lock pthread_mutex_lock "/usr/lib/libSystem.B.dylib" 689//go:cgo_import_dynamic libc_pthread_mutex_unlock pthread_mutex_unlock "/usr/lib/libSystem.B.dylib" 690//go:cgo_import_dynamic libc_pthread_cond_init pthread_cond_init "/usr/lib/libSystem.B.dylib" 691//go:cgo_import_dynamic libc_pthread_cond_wait pthread_cond_wait "/usr/lib/libSystem.B.dylib" 692//go:cgo_import_dynamic libc_pthread_cond_timedwait_relative_np pthread_cond_timedwait_relative_np "/usr/lib/libSystem.B.dylib" 693//go:cgo_import_dynamic libc_pthread_cond_signal pthread_cond_signal "/usr/lib/libSystem.B.dylib" 694 695//go:cgo_import_dynamic libc_notify_is_valid_token notify_is_valid_token "/usr/lib/libSystem.B.dylib" 696//go:cgo_import_dynamic libc_xpc_date_create_from_current xpc_date_create_from_current "/usr/lib/libSystem.B.dylib" 697 698//go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib" 699