github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/sys_darwin_arm64.s (about) 1 // Copyright 2015 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 // System calls and other sys.stuff for ARM64, Darwin 6 // System calls are implemented in libSystem, this file contains 7 // trampolines that convert from Go to C calling convention. 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 #include "cgo/abi_arm64.h" 13 14 #define CLOCK_REALTIME 0 15 16 TEXT notok<>(SB),NOSPLIT,$0 17 MOVD $0, R8 18 MOVD R8, (R8) 19 B 0(PC) 20 21 TEXT runtime·open_trampoline(SB),NOSPLIT,$0 22 SUB $16, RSP 23 MOVW 8(R0), R1 // arg 2 flags 24 MOVW 12(R0), R2 // arg 3 mode 25 MOVW R2, (RSP) // arg 3 is variadic, pass on stack 26 MOVD 0(R0), R0 // arg 1 pathname 27 BL libc_open(SB) 28 ADD $16, RSP 29 RET 30 31 TEXT runtime·close_trampoline(SB),NOSPLIT,$0 32 MOVW 0(R0), R0 // arg 1 fd 33 BL libc_close(SB) 34 RET 35 36 TEXT runtime·write_trampoline(SB),NOSPLIT,$0 37 MOVD 8(R0), R1 // arg 2 buf 38 MOVW 16(R0), R2 // arg 3 count 39 MOVW 0(R0), R0 // arg 1 fd 40 BL libc_write(SB) 41 MOVD $-1, R1 42 CMP R0, R1 43 BNE noerr 44 BL libc_error(SB) 45 MOVW (R0), R0 46 NEG R0, R0 // caller expects negative errno value 47 noerr: 48 RET 49 50 TEXT runtime·read_trampoline(SB),NOSPLIT,$0 51 MOVD 8(R0), R1 // arg 2 buf 52 MOVW 16(R0), R2 // arg 3 count 53 MOVW 0(R0), R0 // arg 1 fd 54 BL libc_read(SB) 55 MOVD $-1, R1 56 CMP R0, R1 57 BNE noerr 58 BL libc_error(SB) 59 MOVW (R0), R0 60 NEG R0, R0 // caller expects negative errno value 61 noerr: 62 RET 63 64 TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0 65 BL libc_pipe(SB) // pointer already in R0 66 CMP $0, R0 67 BEQ 3(PC) 68 BL libc_error(SB) // return negative errno value 69 NEG R0, R0 70 RET 71 72 TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0 73 MOVW 0(R0), R0 74 BL libc_exit(SB) 75 MOVD $1234, R0 76 MOVD $1002, R1 77 MOVD R0, (R1) // fail hard 78 79 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 80 MOVD 0(R0), R19 // signal 81 BL libc_getpid(SB) 82 // arg 1 pid already in R0 from getpid 83 MOVD R19, R1 // arg 2 signal 84 BL libc_kill(SB) 85 RET 86 87 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 88 MOVD R0, R19 89 MOVD 0(R19), R0 // arg 1 addr 90 MOVD 8(R19), R1 // arg 2 len 91 MOVW 16(R19), R2 // arg 3 prot 92 MOVW 20(R19), R3 // arg 4 flags 93 MOVW 24(R19), R4 // arg 5 fd 94 MOVW 28(R19), R5 // arg 6 off 95 BL libc_mmap(SB) 96 MOVD $0, R1 97 MOVD $-1, R2 98 CMP R0, R2 99 BNE ok 100 BL libc_error(SB) 101 MOVW (R0), R1 102 MOVD $0, R0 103 ok: 104 MOVD R0, 32(R19) // ret 1 p 105 MOVD R1, 40(R19) // ret 2 err 106 RET 107 108 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 109 MOVD 8(R0), R1 // arg 2 len 110 MOVD 0(R0), R0 // arg 1 addr 111 BL libc_munmap(SB) 112 CMP $0, R0 113 BEQ 2(PC) 114 BL notok<>(SB) 115 RET 116 117 TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0 118 MOVD 8(R0), R1 // arg 2 len 119 MOVW 16(R0), R2 // arg 3 advice 120 MOVD 0(R0), R0 // arg 1 addr 121 BL libc_madvise(SB) 122 RET 123 124 TEXT runtime·mlock_trampoline(SB),NOSPLIT,$0 125 MOVD 8(R0), R1 // arg 2 len 126 MOVD 0(R0), R0 // arg 1 addr 127 BL libc_mlock(SB) 128 RET 129 130 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0 131 MOVD 8(R0), R1 // arg 2 new 132 MOVD 16(R0), R2 // arg 3 old 133 MOVW 0(R0), R0 // arg 1 which 134 BL libc_setitimer(SB) 135 RET 136 137 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0 138 MOVD R0, R1 // arg 2 timespec 139 MOVW $CLOCK_REALTIME, R0 // arg 1 clock_id 140 BL libc_clock_gettime(SB) 141 RET 142 143 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size) 144 145 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40 146 MOVD R0, R19 147 BL libc_mach_absolute_time(SB) 148 MOVD R0, 0(R19) 149 MOVW timebase<>+machTimebaseInfo_numer(SB), R20 150 MOVD $timebase<>+machTimebaseInfo_denom(SB), R21 151 LDARW (R21), R21 // atomic read 152 CMP $0, R21 153 BNE initialized 154 155 SUB $(machTimebaseInfo__size+15)/16*16, RSP 156 MOVD RSP, R0 157 BL libc_mach_timebase_info(SB) 158 MOVW machTimebaseInfo_numer(RSP), R20 159 MOVW machTimebaseInfo_denom(RSP), R21 160 ADD $(machTimebaseInfo__size+15)/16*16, RSP 161 162 MOVW R20, timebase<>+machTimebaseInfo_numer(SB) 163 MOVD $timebase<>+machTimebaseInfo_denom(SB), R22 164 STLRW R21, (R22) // atomic write 165 166 initialized: 167 MOVW R20, 8(R19) 168 MOVW R21, 12(R19) 169 RET 170 171 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 172 MOVW sig+8(FP), R0 173 MOVD info+16(FP), R1 174 MOVD ctx+24(FP), R2 175 MOVD fn+0(FP), R11 176 BL (R11) 177 RET 178 179 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$176 180 // Save callee-save registers in the case of signal forwarding. 181 // Please refer to https://golang.org/issue/31827 . 182 SAVE_R19_TO_R28(8*4) 183 SAVE_F8_TO_F15(8*14) 184 185 // Save arguments. 186 MOVW R0, (8*1)(RSP) // sig 187 MOVD R1, (8*2)(RSP) // info 188 MOVD R2, (8*3)(RSP) // ctx 189 190 // this might be called in external code context, 191 // where g is not set. 192 BL runtime·load_g(SB) 193 194 #ifdef GOOS_ios 195 MOVD RSP, R6 196 CMP $0, g 197 BEQ nog 198 // iOS always use the main stack to run the signal handler. 199 // We need to switch to gsignal ourselves. 200 MOVD g_m(g), R11 201 MOVD m_gsignal(R11), R5 202 MOVD (g_stack+stack_hi)(R5), R6 203 204 nog: 205 // Restore arguments. 206 MOVW (8*1)(RSP), R0 207 MOVD (8*2)(RSP), R1 208 MOVD (8*3)(RSP), R2 209 210 // Reserve space for args and the stack pointer on the 211 // gsignal stack. 212 SUB $48, R6 213 // Save stack pointer. 214 MOVD RSP, R4 215 MOVD R4, (8*4)(R6) 216 // Switch to gsignal stack. 217 MOVD R6, RSP 218 219 // Save arguments. 220 MOVW R0, (8*1)(RSP) 221 MOVD R1, (8*2)(RSP) 222 MOVD R2, (8*3)(RSP) 223 #endif 224 225 // Call sigtrampgo. 226 MOVD $runtime·sigtrampgo(SB), R11 227 BL (R11) 228 229 #ifdef GOOS_ios 230 // Switch to old stack. 231 MOVD (8*4)(RSP), R5 232 MOVD R5, RSP 233 #endif 234 235 // Restore callee-save registers. 236 RESTORE_R19_TO_R28(8*4) 237 RESTORE_F8_TO_F15(8*14) 238 239 RET 240 241 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 242 JMP runtime·sigtramp(SB) 243 244 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 245 MOVD 8(R0), R1 // arg 2 new 246 MOVD 16(R0), R2 // arg 3 old 247 MOVW 0(R0), R0 // arg 1 how 248 BL libc_pthread_sigmask(SB) 249 CMP $0, R0 250 BEQ 2(PC) 251 BL notok<>(SB) 252 RET 253 254 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 255 MOVD 8(R0), R1 // arg 2 new 256 MOVD 16(R0), R2 // arg 3 old 257 MOVW 0(R0), R0 // arg 1 how 258 BL libc_sigaction(SB) 259 CMP $0, R0 260 BEQ 2(PC) 261 BL notok<>(SB) 262 RET 263 264 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 265 MOVW 0(R0), R0 // arg 1 usec 266 BL libc_usleep(SB) 267 RET 268 269 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0 270 MOVW 8(R0), R1 // arg 2 miblen 271 MOVD 16(R0), R2 // arg 3 oldp 272 MOVD 24(R0), R3 // arg 4 oldlenp 273 MOVD 32(R0), R4 // arg 5 newp 274 MOVD 40(R0), R5 // arg 6 newlen 275 MOVD 0(R0), R0 // arg 1 mib 276 BL libc_sysctl(SB) 277 RET 278 279 TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0 280 MOVD 8(R0), R1 // arg 2 oldp 281 MOVD 16(R0), R2 // arg 3 oldlenp 282 MOVD 24(R0), R3 // arg 4 newp 283 MOVD 32(R0), R4 // arg 5 newlen 284 MOVD 0(R0), R0 // arg 1 name 285 BL libc_sysctlbyname(SB) 286 RET 287 288 289 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 290 BL libc_kqueue(SB) 291 RET 292 293 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0 294 MOVD 8(R0), R1 // arg 2 keventt 295 MOVW 16(R0), R2 // arg 3 nch 296 MOVD 24(R0), R3 // arg 4 ev 297 MOVW 32(R0), R4 // arg 5 nev 298 MOVD 40(R0), R5 // arg 6 ts 299 MOVW 0(R0), R0 // arg 1 kq 300 BL libc_kevent(SB) 301 MOVD $-1, R2 302 CMP R0, R2 303 BNE ok 304 BL libc_error(SB) 305 MOVW (R0), R0 // errno 306 NEG R0, R0 // caller wants it as a negative error code 307 ok: 308 RET 309 310 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 311 SUB $16, RSP 312 MOVD R0, R19 313 MOVW 0(R19), R0 // arg 1 fd 314 MOVW 4(R19), R1 // arg 2 cmd 315 MOVW 8(R19), R2 // arg 3 arg 316 MOVW R2, (RSP) // arg 3 is variadic, pass on stack 317 BL libc_fcntl(SB) 318 MOVD $0, R1 319 MOVD $-1, R2 320 CMP R0, R2 321 BNE noerr 322 BL libc_error(SB) 323 MOVW (R0), R1 324 MOVW $-1, R0 325 noerr: 326 MOVW R0, 12(R19) 327 MOVW R1, 16(R19) 328 ADD $16, RSP 329 RET 330 331 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 332 #ifdef GOOS_ios 333 // sigaltstack on iOS is not supported and will always 334 // run the signal handler on the main stack, so our sigtramp has 335 // to do the stack switch ourselves. 336 MOVW $43, R0 337 BL libc_exit(SB) 338 #else 339 MOVD 8(R0), R1 // arg 2 old 340 MOVD 0(R0), R0 // arg 1 new 341 CALL libc_sigaltstack(SB) 342 CBZ R0, 2(PC) 343 BL notok<>(SB) 344 #endif 345 RET 346 347 // Thread related functions 348 349 // mstart_stub is the first function executed on a new thread started by pthread_create. 350 // It just does some low-level setup and then calls mstart. 351 // Note: called with the C calling convention. 352 TEXT runtime·mstart_stub(SB),NOSPLIT,$160 353 // R0 points to the m. 354 // We are already on m's g0 stack. 355 356 // Save callee-save registers. 357 SAVE_R19_TO_R28(8) 358 SAVE_F8_TO_F15(88) 359 360 MOVD m_g0(R0), g 361 BL ·save_g(SB) 362 363 BL runtime·mstart(SB) 364 365 // Restore callee-save registers. 366 RESTORE_R19_TO_R28(8) 367 RESTORE_F8_TO_F15(88) 368 369 // Go is all done with this OS thread. 370 // Tell pthread everything is ok (we never join with this thread, so 371 // the value here doesn't really matter). 372 MOVD $0, R0 373 374 RET 375 376 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 377 MOVD 0(R0), R0 // arg 1 attr 378 BL libc_pthread_attr_init(SB) 379 RET 380 381 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 382 MOVD 8(R0), R1 // arg 2 size 383 MOVD 0(R0), R0 // arg 1 attr 384 BL libc_pthread_attr_getstacksize(SB) 385 RET 386 387 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 388 MOVD 8(R0), R1 // arg 2 state 389 MOVD 0(R0), R0 // arg 1 attr 390 BL libc_pthread_attr_setdetachstate(SB) 391 RET 392 393 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0 394 SUB $16, RSP 395 MOVD 0(R0), R1 // arg 2 state 396 MOVD 8(R0), R2 // arg 3 start 397 MOVD 16(R0), R3 // arg 4 arg 398 MOVD RSP, R0 // arg 1 &threadid (which we throw away) 399 BL libc_pthread_create(SB) 400 ADD $16, RSP 401 RET 402 403 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0 404 MOVW 0(R0), R0 // arg 1 sig 405 BL libc_raise(SB) 406 RET 407 408 TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0 409 MOVD 8(R0), R1 // arg 2 attr 410 MOVD 0(R0), R0 // arg 1 mutex 411 BL libc_pthread_mutex_init(SB) 412 RET 413 414 TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0 415 MOVD 0(R0), R0 // arg 1 mutex 416 BL libc_pthread_mutex_lock(SB) 417 RET 418 419 TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0 420 MOVD 0(R0), R0 // arg 1 mutex 421 BL libc_pthread_mutex_unlock(SB) 422 RET 423 424 TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0 425 MOVD 8(R0), R1 // arg 2 attr 426 MOVD 0(R0), R0 // arg 1 cond 427 BL libc_pthread_cond_init(SB) 428 RET 429 430 TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0 431 MOVD 8(R0), R1 // arg 2 mutex 432 MOVD 0(R0), R0 // arg 1 cond 433 BL libc_pthread_cond_wait(SB) 434 RET 435 436 TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0 437 MOVD 8(R0), R1 // arg 2 mutex 438 MOVD 16(R0), R2 // arg 3 timeout 439 MOVD 0(R0), R0 // arg 1 cond 440 BL libc_pthread_cond_timedwait_relative_np(SB) 441 RET 442 443 TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0 444 MOVD 0(R0), R0 // arg 1 cond 445 BL libc_pthread_cond_signal(SB) 446 RET 447 448 TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0 449 MOVD R0, R19 // R19 is callee-save 450 BL libc_pthread_self(SB) 451 MOVD R0, 0(R19) // return value 452 RET 453 454 TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0 455 MOVD 8(R0), R1 // arg 2 sig 456 MOVD 0(R0), R0 // arg 1 thread 457 BL libc_pthread_kill(SB) 458 RET 459 460 TEXT runtime·pthread_key_create_trampoline(SB),NOSPLIT,$0 461 MOVD 8(R0), R1 // arg 2 destructor 462 MOVD 0(R0), R0 // arg 1 *key 463 BL libc_pthread_key_create(SB) 464 RET 465 466 TEXT runtime·pthread_setspecific_trampoline(SB),NOSPLIT,$0 467 MOVD 8(R0), R1 // arg 2 value 468 MOVD 0(R0), R0 // arg 1 key 469 BL libc_pthread_setspecific(SB) 470 RET 471 472 TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0 473 MOVD $0, R0 // arg 1 val 474 BL libc_notify_is_valid_token(SB) 475 BL libc_xpc_date_create_from_current(SB) 476 RET 477 478 // syscall calls a function in libc on behalf of the syscall package. 479 // syscall takes a pointer to a struct like: 480 // struct { 481 // fn uintptr 482 // a1 uintptr 483 // a2 uintptr 484 // a3 uintptr 485 // r1 uintptr 486 // r2 uintptr 487 // err uintptr 488 // } 489 // syscall must be called on the g0 stack with the 490 // C calling convention (use libcCall). 491 TEXT runtime·syscall(SB),NOSPLIT,$0 492 SUB $16, RSP // push structure pointer 493 MOVD R0, 8(RSP) 494 495 MOVD 0(R0), R12 // fn 496 MOVD 16(R0), R1 // a2 497 MOVD 24(R0), R2 // a3 498 MOVD 8(R0), R0 // a1 499 500 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. 501 // (Because ios decided not to adhere to the standard arm64 calling convention, sigh...) 502 // The only libSystem calls we support that are vararg are open, fcntl, and ioctl, 503 // which are all of the form fn(x, y, ...). So we just need to put the 3rd arg 504 // on the stack as well. 505 // If we ever have other vararg libSystem calls, we might need to handle more cases. 506 MOVD R2, (RSP) 507 508 BL (R12) 509 510 MOVD 8(RSP), R2 // pop structure pointer 511 ADD $16, RSP 512 MOVD R0, 32(R2) // save r1 513 MOVD R1, 40(R2) // save r2 514 CMPW $-1, R0 515 BNE ok 516 SUB $16, RSP // push structure pointer 517 MOVD R2, 8(RSP) 518 BL libc_error(SB) 519 MOVW (R0), R0 520 MOVD 8(RSP), R2 // pop structure pointer 521 ADD $16, RSP 522 MOVD R0, 48(R2) // save err 523 ok: 524 RET 525 526 // syscallX calls a function in libc on behalf of the syscall package. 527 // syscallX takes a pointer to a struct like: 528 // struct { 529 // fn uintptr 530 // a1 uintptr 531 // a2 uintptr 532 // a3 uintptr 533 // r1 uintptr 534 // r2 uintptr 535 // err uintptr 536 // } 537 // syscallX must be called on the g0 stack with the 538 // C calling convention (use libcCall). 539 TEXT runtime·syscallX(SB),NOSPLIT,$0 540 SUB $16, RSP // push structure pointer 541 MOVD R0, (RSP) 542 543 MOVD 0(R0), R12 // fn 544 MOVD 16(R0), R1 // a2 545 MOVD 24(R0), R2 // a3 546 MOVD 8(R0), R0 // a1 547 BL (R12) 548 549 MOVD (RSP), R2 // pop structure pointer 550 ADD $16, RSP 551 MOVD R0, 32(R2) // save r1 552 MOVD R1, 40(R2) // save r2 553 CMP $-1, R0 554 BNE ok 555 SUB $16, RSP // push structure pointer 556 MOVD R2, (RSP) 557 BL libc_error(SB) 558 MOVW (R0), R0 559 MOVD (RSP), R2 // pop structure pointer 560 ADD $16, RSP 561 MOVD R0, 48(R2) // save err 562 ok: 563 RET 564 565 // syscallPtr is like syscallX except that the libc function reports an 566 // error by returning NULL and setting errno. 567 TEXT runtime·syscallPtr(SB),NOSPLIT,$0 568 SUB $16, RSP // push structure pointer 569 MOVD R0, (RSP) 570 571 MOVD 0(R0), R12 // fn 572 MOVD 16(R0), R1 // a2 573 MOVD 24(R0), R2 // a3 574 MOVD 8(R0), R0 // a1 575 BL (R12) 576 577 MOVD (RSP), R2 // pop structure pointer 578 ADD $16, RSP 579 MOVD R0, 32(R2) // save r1 580 MOVD R1, 40(R2) // save r2 581 CMP $0, R0 582 BNE ok 583 SUB $16, RSP // push structure pointer 584 MOVD R2, (RSP) 585 BL libc_error(SB) 586 MOVW (R0), R0 587 MOVD (RSP), R2 // pop structure pointer 588 ADD $16, RSP 589 MOVD R0, 48(R2) // save err 590 ok: 591 RET 592 593 // syscall6 calls a function in libc on behalf of the syscall package. 594 // syscall6 takes a pointer to a struct like: 595 // struct { 596 // fn uintptr 597 // a1 uintptr 598 // a2 uintptr 599 // a3 uintptr 600 // a4 uintptr 601 // a5 uintptr 602 // a6 uintptr 603 // r1 uintptr 604 // r2 uintptr 605 // err uintptr 606 // } 607 // syscall6 must be called on the g0 stack with the 608 // C calling convention (use libcCall). 609 TEXT runtime·syscall6(SB),NOSPLIT,$0 610 SUB $16, RSP // push structure pointer 611 MOVD R0, 8(RSP) 612 613 MOVD 0(R0), R12 // fn 614 MOVD 16(R0), R1 // a2 615 MOVD 24(R0), R2 // a3 616 MOVD 32(R0), R3 // a4 617 MOVD 40(R0), R4 // a5 618 MOVD 48(R0), R5 // a6 619 MOVD 8(R0), R0 // a1 620 621 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. 622 // See syscall above. The only function this applies to is openat, for which the 4th 623 // arg must be on the stack. 624 MOVD R3, (RSP) 625 626 BL (R12) 627 628 MOVD 8(RSP), R2 // pop structure pointer 629 ADD $16, RSP 630 MOVD R0, 56(R2) // save r1 631 MOVD R1, 64(R2) // save r2 632 CMPW $-1, R0 633 BNE ok 634 SUB $16, RSP // push structure pointer 635 MOVD R2, 8(RSP) 636 BL libc_error(SB) 637 MOVW (R0), R0 638 MOVD 8(RSP), R2 // pop structure pointer 639 ADD $16, RSP 640 MOVD R0, 72(R2) // save err 641 ok: 642 RET 643 644 // syscall6X calls a function in libc on behalf of the syscall package. 645 // syscall6X takes a pointer to a struct like: 646 // struct { 647 // fn uintptr 648 // a1 uintptr 649 // a2 uintptr 650 // a3 uintptr 651 // a4 uintptr 652 // a5 uintptr 653 // a6 uintptr 654 // r1 uintptr 655 // r2 uintptr 656 // err uintptr 657 // } 658 // syscall6X must be called on the g0 stack with the 659 // C calling convention (use libcCall). 660 TEXT runtime·syscall6X(SB),NOSPLIT,$0 661 SUB $16, RSP // push structure pointer 662 MOVD R0, (RSP) 663 664 MOVD 0(R0), R12 // fn 665 MOVD 16(R0), R1 // a2 666 MOVD 24(R0), R2 // a3 667 MOVD 32(R0), R3 // a4 668 MOVD 40(R0), R4 // a5 669 MOVD 48(R0), R5 // a6 670 MOVD 8(R0), R0 // a1 671 BL (R12) 672 673 MOVD (RSP), R2 // pop structure pointer 674 ADD $16, RSP 675 MOVD R0, 56(R2) // save r1 676 MOVD R1, 64(R2) // save r2 677 CMP $-1, R0 678 BNE ok 679 SUB $16, RSP // push structure pointer 680 MOVD R2, (RSP) 681 BL libc_error(SB) 682 MOVW (R0), R0 683 MOVD (RSP), R2 // pop structure pointer 684 ADD $16, RSP 685 MOVD R0, 72(R2) // save err 686 ok: 687 RET 688 689 // syscall9 calls a function in libc on behalf of the syscall package. 690 // syscall9 takes a pointer to a struct like: 691 // struct { 692 // fn uintptr 693 // a1 uintptr 694 // a2 uintptr 695 // a3 uintptr 696 // a4 uintptr 697 // a5 uintptr 698 // a6 uintptr 699 // a7 uintptr 700 // a8 uintptr 701 // a9 uintptr 702 // r1 uintptr 703 // r2 uintptr 704 // err uintptr 705 // } 706 // syscall9 must be called on the g0 stack with the 707 // C calling convention (use libcCall). 708 TEXT runtime·syscall9(SB),NOSPLIT,$0 709 SUB $16, RSP // push structure pointer 710 MOVD R0, 8(RSP) 711 712 MOVD 0(R0), R12 // fn 713 MOVD 16(R0), R1 // a2 714 MOVD 24(R0), R2 // a3 715 MOVD 32(R0), R3 // a4 716 MOVD 40(R0), R4 // a5 717 MOVD 48(R0), R5 // a6 718 MOVD 56(R0), R6 // a7 719 MOVD 64(R0), R7 // a8 720 MOVD 72(R0), R8 // a9 721 MOVD 8(R0), R0 // a1 722 723 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. 724 // See syscall above. The only function this applies to is openat, for which the 4th 725 // arg must be on the stack. 726 MOVD R3, (RSP) 727 728 BL (R12) 729 730 MOVD 8(RSP), R2 // pop structure pointer 731 ADD $16, RSP 732 MOVD R0, 80(R2) // save r1 733 MOVD R1, 88(R2) // save r2 734 CMPW $-1, R0 735 BNE ok 736 SUB $16, RSP // push structure pointer 737 MOVD R2, 8(RSP) 738 BL libc_error(SB) 739 MOVW (R0), R0 740 MOVD 8(RSP), R2 // pop structure pointer 741 ADD $16, RSP 742 MOVD R0, 96(R2) // save err 743 ok: 744 RET 745 746 // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors, 747 // takes 5 uintptrs and 1 float64, and only returns one value, 748 // for use with standard C ABI functions. 749 TEXT runtime·syscall_x509(SB),NOSPLIT,$0 750 SUB $16, RSP // push structure pointer 751 MOVD R0, (RSP) 752 753 MOVD 0(R0), R12 // fn 754 MOVD 16(R0), R1 // a2 755 MOVD 24(R0), R2 // a3 756 MOVD 32(R0), R3 // a4 757 MOVD 40(R0), R4 // a5 758 FMOVD 48(R0), F0 // f1 759 MOVD 8(R0), R0 // a1 760 BL (R12) 761 762 MOVD (RSP), R2 // pop structure pointer 763 ADD $16, RSP 764 MOVD R0, 56(R2) // save r1 765 RET 766 767 TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0 768 BL libc_issetugid(SB) 769 RET 770 771 // mach_vm_region_trampoline calls mach_vm_region from libc. 772 TEXT runtime·mach_vm_region_trampoline(SB),NOSPLIT,$0 773 MOVD 0(R0), R1 // address 774 MOVD 8(R0), R2 // size 775 MOVW 16(R0), R3 // flavor 776 MOVD 24(R0), R4 // info 777 MOVD 32(R0), R5 // count 778 MOVD 40(R0), R6 // object_name 779 MOVD $libc_mach_task_self_(SB), R0 780 MOVW 0(R0), R0 781 BL libc_mach_vm_region(SB) 782 RET 783 784 // proc_regionfilename_trampoline calls proc_regionfilename for 785 // the current process. 786 TEXT runtime·proc_regionfilename_trampoline(SB),NOSPLIT,$0 787 MOVD 8(R0), R1 // address 788 MOVD 16(R0), R2 // buffer 789 MOVD 24(R0), R3 // buffer_size 790 MOVD 0(R0), R0 // pid 791 BL libc_proc_regionfilename(SB) 792 RET