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 16TEXT notok<>(SB),NOSPLIT,$0 17 MOVD $0, R8 18 MOVD R8, (R8) 19 B 0(PC) 20 21TEXT 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 31TEXT runtime·close_trampoline(SB),NOSPLIT,$0 32 MOVW 0(R0), R0 // arg 1 fd 33 BL libc_close(SB) 34 RET 35 36TEXT 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 47noerr: 48 RET 49 50TEXT 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 61noerr: 62 RET 63 64TEXT 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 72TEXT 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 79TEXT 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 87TEXT 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 103ok: 104 MOVD R0, 32(R19) // ret 1 p 105 MOVD R1, 40(R19) // ret 2 err 106 RET 107 108TEXT 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 117TEXT 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 124TEXT 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 130TEXT 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 137TEXT 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 143GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size) 144 145TEXT 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 166initialized: 167 MOVW R20, 8(R19) 168 MOVW R21, 12(R19) 169 RET 170 171TEXT 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 179TEXT 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 204nog: 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 241TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 242 JMP runtime·sigtramp(SB) 243 244TEXT 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 254TEXT 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 264TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 265 MOVW 0(R0), R0 // arg 1 usec 266 BL libc_usleep(SB) 267 RET 268 269TEXT 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 279TEXT 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 289TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 290 BL libc_kqueue(SB) 291 RET 292 293TEXT 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 307ok: 308 RET 309 310TEXT 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 325noerr: 326 MOVW R0, 12(R19) 327 MOVW R1, 16(R19) 328 ADD $16, RSP 329 RET 330 331TEXT 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. 352TEXT 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 376TEXT 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 381TEXT 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 387TEXT 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 393TEXT 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 403TEXT runtime·raise_trampoline(SB),NOSPLIT,$0 404 MOVW 0(R0), R0 // arg 1 sig 405 BL libc_raise(SB) 406 RET 407 408TEXT 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 414TEXT 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 419TEXT 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 424TEXT 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 430TEXT 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 436TEXT 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 443TEXT 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 448TEXT 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 454TEXT 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 460TEXT 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 466TEXT 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 472TEXT 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). 491TEXT 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 523ok: 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). 539TEXT 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 562ok: 563 RET 564 565// syscallPtr is like syscallX except that the libc function reports an 566// error by returning NULL and setting errno. 567TEXT 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 590ok: 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). 609TEXT 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 641ok: 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). 660TEXT 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 686ok: 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). 708TEXT 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 743ok: 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. 749TEXT 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 767TEXT 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. 772TEXT 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. 786TEXT 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 793