github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/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 13 TEXT notok<>(SB),NOSPLIT,$0 14 MOVD $0, R8 15 MOVD R8, (R8) 16 B 0(PC) 17 18 TEXT runtime·open_trampoline(SB),NOSPLIT,$0 19 SUB $16, RSP 20 MOVW 8(R0), R1 // arg 2 flags 21 MOVW 12(R0), R2 // arg 3 mode 22 MOVW R2, (RSP) // arg 3 is variadic, pass on stack 23 MOVD 0(R0), R0 // arg 1 pathname 24 BL libc_open(SB) 25 ADD $16, RSP 26 RET 27 28 TEXT runtime·close_trampoline(SB),NOSPLIT,$0 29 MOVW 0(R0), R0 // arg 1 fd 30 BL libc_close(SB) 31 RET 32 33 TEXT runtime·write_trampoline(SB),NOSPLIT,$0 34 MOVD 8(R0), R1 // arg 2 buf 35 MOVW 16(R0), R2 // arg 3 count 36 MOVW 0(R0), R0 // arg 1 fd 37 BL libc_write(SB) 38 RET 39 40 TEXT runtime·read_trampoline(SB),NOSPLIT,$0 41 MOVD 8(R0), R1 // arg 2 buf 42 MOVW 16(R0), R2 // arg 3 count 43 MOVW 0(R0), R0 // arg 1 fd 44 BL libc_read(SB) 45 RET 46 47 TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0 48 MOVW 0(R0), R0 49 BL libc_exit(SB) 50 MOVD $1234, R0 51 MOVD $1002, R1 52 MOVD R0, (R1) // fail hard 53 54 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 55 MOVD 0(R0), R19 // signal 56 BL libc_getpid(SB) 57 // arg 1 pid already in R0 from getpid 58 MOVD R19, R1 // arg 2 signal 59 BL libc_kill(SB) 60 RET 61 62 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 63 MOVD R0, R19 64 MOVD 0(R19), R0 // arg 1 addr 65 MOVD 8(R19), R1 // arg 2 len 66 MOVW 16(R19), R2 // arg 3 prot 67 MOVW 20(R19), R3 // arg 4 flags 68 MOVW 24(R19), R4 // arg 5 fd 69 MOVW 28(R19), R5 // arg 6 off 70 BL libc_mmap(SB) 71 MOVD $0, R1 72 MOVD $-1, R2 73 CMP R0, R2 74 BNE ok 75 BL libc_error(SB) 76 MOVW (R0), R1 77 MOVD $0, R0 78 ok: 79 MOVD R0, 32(R19) // ret 1 p 80 MOVD R1, 40(R19) // ret 2 err 81 RET 82 83 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 84 MOVD 8(R0), R1 // arg 2 len 85 MOVD 0(R0), R0 // arg 1 addr 86 BL libc_munmap(SB) 87 CMP $0, R0 88 BEQ 2(PC) 89 BL notok<>(SB) 90 RET 91 92 TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0 93 MOVD 8(R0), R1 // arg 2 len 94 MOVW 16(R0), R2 // arg 3 advice 95 MOVD 0(R0), R0 // arg 1 addr 96 BL libc_madvise(SB) 97 RET 98 99 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0 100 MOVD 8(R0), R1 // arg 2 new 101 MOVD 16(R0), R2 // arg 3 old 102 MOVW 0(R0), R0 // arg 1 which 103 BL libc_setitimer(SB) 104 RET 105 106 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0 107 // R0 already has *timeval 108 MOVD $0, R1 // no timezone needed 109 BL libc_gettimeofday(SB) 110 RET 111 112 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size) 113 114 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40 115 MOVD R0, R19 116 BL libc_mach_absolute_time(SB) 117 MOVD R0, 0(R19) 118 MOVW timebase<>+machTimebaseInfo_numer(SB), R20 119 MOVD $timebase<>+machTimebaseInfo_denom(SB), R21 120 LDARW (R21), R21 // atomic read 121 CMP $0, R21 122 BNE initialized 123 124 SUB $(machTimebaseInfo__size+15)/16*16, RSP 125 MOVD RSP, R0 126 BL libc_mach_timebase_info(SB) 127 MOVW machTimebaseInfo_numer(RSP), R20 128 MOVW machTimebaseInfo_denom(RSP), R21 129 ADD $(machTimebaseInfo__size+15)/16*16, RSP 130 131 MOVW R20, timebase<>+machTimebaseInfo_numer(SB) 132 MOVD $timebase<>+machTimebaseInfo_denom(SB), R22 133 STLRW R21, (R22) // atomic write 134 135 initialized: 136 MOVW R20, 8(R19) 137 MOVW R21, 12(R19) 138 RET 139 140 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 141 MOVW sig+8(FP), R0 142 MOVD info+16(FP), R1 143 MOVD ctx+24(FP), R2 144 MOVD fn+0(FP), R11 145 BL (R11) 146 RET 147 148 TEXT runtime·sigtramp(SB),NOSPLIT,$0 149 // Reserve space for callee-save registers and arguments. 150 SUB $(8*16), RSP 151 152 // Save callee-save registers. 153 MOVD R19, (8*4)(RSP) 154 MOVD R20, (8*5)(RSP) 155 MOVD R21, (8*6)(RSP) 156 MOVD R22, (8*7)(RSP) 157 MOVD R23, (8*8)(RSP) 158 MOVD R24, (8*9)(RSP) 159 MOVD R25, (8*10)(RSP) 160 MOVD R26, (8*11)(RSP) 161 MOVD R27, (8*12)(RSP) 162 MOVD g, (8*13)(RSP) 163 MOVD R29, (8*14)(RSP) 164 165 // Save arguments. 166 MOVW R0, (8*1)(RSP) // sig 167 MOVD R1, (8*2)(RSP) // info 168 MOVD R2, (8*3)(RSP) // ctx 169 170 // this might be called in external code context, 171 // where g is not set. 172 MOVB runtime·iscgo(SB), R0 173 CMP $0, R0 174 BEQ 2(PC) 175 BL runtime·load_g(SB) 176 177 MOVD RSP, R6 178 CMP $0, g 179 BEQ nog 180 // iOS always use the main stack to run the signal handler. 181 // We need to switch to gsignal ourselves. 182 MOVD g_m(g), R11 183 MOVD m_gsignal(R11), R5 184 MOVD (g_stack+stack_hi)(R5), R6 185 186 nog: 187 // Restore arguments. 188 MOVW (8*1)(RSP), R0 189 MOVD (8*2)(RSP), R1 190 MOVD (8*3)(RSP), R2 191 192 // Reserve space for args and the stack pointer on the 193 // gsignal stack. 194 SUB $48, R6 195 // Save stack pointer. 196 MOVD RSP, R4 197 MOVD R4, (8*4)(R6) 198 // Switch to gsignal stack. 199 MOVD R6, RSP 200 201 // Call sigtrampgo. 202 MOVW R0, (8*1)(RSP) 203 MOVD R1, (8*2)(RSP) 204 MOVD R2, (8*3)(RSP) 205 MOVD $runtime·sigtrampgo(SB), R11 206 BL (R11) 207 208 // Switch to old stack. 209 MOVD (8*4)(RSP), R5 210 MOVD R5, RSP 211 212 // Restore callee-save registers. 213 MOVD (8*4)(RSP), R19 214 MOVD (8*5)(RSP), R20 215 MOVD (8*6)(RSP), R21 216 MOVD (8*7)(RSP), R22 217 MOVD (8*8)(RSP), R23 218 MOVD (8*9)(RSP), R24 219 MOVD (8*10)(RSP), R25 220 MOVD (8*11)(RSP), R26 221 MOVD (8*12)(RSP), R27 222 MOVD (8*13)(RSP), g 223 MOVD (8*14)(RSP), R29 224 225 ADD $(8*16), RSP 226 227 RET 228 229 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 230 JMP runtime·sigtramp(SB) 231 232 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 233 MOVD 8(R0), R1 // arg 2 new 234 MOVD 16(R0), R2 // arg 3 old 235 MOVW 0(R0), R0 // arg 1 how 236 BL libc_pthread_sigmask(SB) 237 CMP $0, R0 238 BEQ 2(PC) 239 BL notok<>(SB) 240 RET 241 242 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 243 MOVD 8(R0), R1 // arg 2 new 244 MOVD 16(R0), R2 // arg 3 old 245 MOVW 0(R0), R0 // arg 1 how 246 BL libc_sigaction(SB) 247 CMP $0, R0 248 BEQ 2(PC) 249 BL notok<>(SB) 250 RET 251 252 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 253 MOVW 0(R0), R0 // arg 1 usec 254 BL libc_usleep(SB) 255 RET 256 257 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0 258 MOVW 8(R0), R1 // arg 2 miblen 259 MOVD 16(R0), R2 // arg 3 out 260 MOVD 24(R0), R3 // arg 4 size 261 MOVD 32(R0), R4 // arg 5 dst 262 MOVD 40(R0), R5 // arg 6 ndst 263 MOVD 0(R0), R0 // arg 1 mib 264 BL libc_sysctl(SB) 265 RET 266 267 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 268 BL libc_kqueue(SB) 269 RET 270 271 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0 272 MOVD 8(R0), R1 // arg 2 keventt 273 MOVW 16(R0), R2 // arg 3 nch 274 MOVD 24(R0), R3 // arg 4 ev 275 MOVW 32(R0), R4 // arg 5 nev 276 MOVD 40(R0), R5 // arg 6 ts 277 MOVW 0(R0), R0 // arg 1 kq 278 BL libc_kevent(SB) 279 MOVD $-1, R2 280 CMP R0, R2 281 BNE ok 282 BL libc_error(SB) 283 MOVW (R0), R0 // errno 284 NEG R0, R0 // caller wants it as a negative error code 285 ok: 286 RET 287 288 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 289 SUB $16, RSP 290 MOVW 4(R0), R1 // arg 2 cmd 291 MOVW 8(R0), R2 // arg 3 arg 292 MOVW R2, (RSP) // arg 3 is variadic, pass on stack 293 MOVW 0(R0), R0 // arg 1 fd 294 BL libc_fcntl(SB) 295 ADD $16, RSP 296 RET 297 298 // sigaltstack on iOS is not supported and will always 299 // run the signal handler on the main stack, so our sigtramp has 300 // to do the stack switch ourselves. 301 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 302 MOVW $43, R0 303 BL libc_exit(SB) 304 RET 305 306 // Thread related functions 307 // Note: On darwin/arm64, the runtime always use runtime/cgo to 308 // create threads, so all thread related functions will just exit with a 309 // unique status. 310 311 TEXT runtime·mstart_stub(SB),NOSPLIT,$0 312 MOVW $44, R0 313 BL libc_exit(SB) 314 RET 315 316 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 317 MOVW $45, R0 318 BL libc_exit(SB) 319 RET 320 321 TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0 322 MOVW $46, R0 323 BL libc_exit(SB) 324 RET 325 326 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 327 MOVW $47, R0 328 BL libc_exit(SB) 329 RET 330 331 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0 332 MOVW $48, R0 333 BL libc_exit(SB) 334 RET 335 336 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0 337 MOVW 0(R0), R0 // arg 1 sig 338 BL libc_raise(SB) 339 RET 340 341 TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0 342 MOVD 8(R0), R1 // arg 2 attr 343 MOVD 0(R0), R0 // arg 1 mutex 344 BL libc_pthread_mutex_init(SB) 345 RET 346 347 TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0 348 MOVD 0(R0), R0 // arg 1 mutex 349 BL libc_pthread_mutex_lock(SB) 350 RET 351 352 TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0 353 MOVD 0(R0), R0 // arg 1 mutex 354 BL libc_pthread_mutex_unlock(SB) 355 RET 356 357 TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0 358 MOVD 8(R0), R1 // arg 2 attr 359 MOVD 0(R0), R0 // arg 1 cond 360 BL libc_pthread_cond_init(SB) 361 RET 362 363 TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0 364 MOVD 8(R0), R1 // arg 2 mutex 365 MOVD 0(R0), R0 // arg 1 cond 366 BL libc_pthread_cond_wait(SB) 367 RET 368 369 TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0 370 MOVD 8(R0), R1 // arg 2 mutex 371 MOVD 16(R0), R2 // arg 3 timeout 372 MOVD 0(R0), R0 // arg 1 cond 373 BL libc_pthread_cond_timedwait_relative_np(SB) 374 RET 375 376 TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0 377 MOVD 0(R0), R0 // arg 1 cond 378 BL libc_pthread_cond_signal(SB) 379 RET 380 381 // syscall calls a function in libc on behalf of the syscall package. 382 // syscall takes a pointer to a struct like: 383 // struct { 384 // fn uintptr 385 // a1 uintptr 386 // a2 uintptr 387 // a3 uintptr 388 // r1 uintptr 389 // r2 uintptr 390 // err uintptr 391 // } 392 // syscall must be called on the g0 stack with the 393 // C calling convention (use libcCall). 394 TEXT runtime·syscall(SB),NOSPLIT,$0 395 SUB $16, RSP // push structure pointer 396 MOVD R0, 8(RSP) 397 398 MOVD 0(R0), R12 // fn 399 MOVD 16(R0), R1 // a2 400 MOVD 24(R0), R2 // a3 401 MOVD 8(R0), R0 // a1 402 403 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. 404 // (Because ios decided not to adhere to the standard arm64 calling convention, sigh...) 405 // The only libSystem calls we support that are vararg are open, fcntl, and ioctl, 406 // which are all of the form fn(x, y, ...). So we just need to put the 3rd arg 407 // on the stack as well. 408 // If we ever have other vararg libSystem calls, we might need to handle more cases. 409 MOVD R2, (RSP) 410 411 BL (R12) 412 413 MOVD 8(RSP), R2 // pop structure pointer 414 ADD $16, RSP 415 MOVD R0, 32(R2) // save r1 416 MOVD R1, 40(R2) // save r2 417 CMPW $-1, R0 418 BNE ok 419 SUB $16, RSP // push structure pointer 420 MOVD R2, 8(RSP) 421 BL libc_error(SB) 422 MOVW (R0), R0 423 MOVD 8(RSP), R2 // pop structure pointer 424 ADD $16, RSP 425 MOVD R0, 48(R2) // save err 426 ok: 427 RET 428 429 // syscallX calls a function in libc on behalf of the syscall package. 430 // syscallX takes a pointer to a struct like: 431 // struct { 432 // fn uintptr 433 // a1 uintptr 434 // a2 uintptr 435 // a3 uintptr 436 // r1 uintptr 437 // r2 uintptr 438 // err uintptr 439 // } 440 // syscallX must be called on the g0 stack with the 441 // C calling convention (use libcCall). 442 TEXT runtime·syscallX(SB),NOSPLIT,$0 443 SUB $16, RSP // push structure pointer 444 MOVD R0, (RSP) 445 446 MOVD 0(R0), R12 // fn 447 MOVD 16(R0), R1 // a2 448 MOVD 24(R0), R2 // a3 449 MOVD 8(R0), R0 // a1 450 BL (R12) 451 452 MOVD (RSP), R2 // pop structure pointer 453 ADD $16, RSP 454 MOVD R0, 32(R2) // save r1 455 MOVD R1, 40(R2) // save r2 456 CMP $-1, R0 457 BNE ok 458 SUB $16, RSP // push structure pointer 459 MOVD R2, (RSP) 460 BL libc_error(SB) 461 MOVW (R0), R0 462 MOVD (RSP), R2 // pop structure pointer 463 ADD $16, RSP 464 MOVD R0, 48(R2) // save err 465 ok: 466 RET 467 468 // syscallXPtr is like syscallX except that the libc function reports an 469 // error by returning NULL. 470 TEXT runtime·syscallXPtr(SB),NOSPLIT,$0 471 SUB $16, RSP // push structure pointer 472 MOVD R0, (RSP) 473 474 MOVD 0(R0), R12 // fn 475 MOVD 16(R0), R1 // a2 476 MOVD 24(R0), R2 // a3 477 MOVD 8(R0), R0 // a1 478 BL (R12) 479 480 MOVD (RSP), R2 // pop structure pointer 481 ADD $16, RSP 482 MOVD R0, 32(R2) // save r1 483 MOVD R1, 40(R2) // save r2 484 CMP $0, R0 485 BNE ok 486 SUB $16, RSP // push structure pointer 487 MOVD R2, (RSP) 488 BL libc_error(SB) 489 MOVW (R0), R0 490 MOVD (RSP), R2 // pop structure pointer 491 ADD $16, RSP 492 MOVD R0, 48(R2) // save err 493 ok: 494 RET 495 496 // syscall6 calls a function in libc on behalf of the syscall package. 497 // syscall6 takes a pointer to a struct like: 498 // struct { 499 // fn uintptr 500 // a1 uintptr 501 // a2 uintptr 502 // a3 uintptr 503 // a4 uintptr 504 // a5 uintptr 505 // a6 uintptr 506 // r1 uintptr 507 // r2 uintptr 508 // err uintptr 509 // } 510 // syscall6 must be called on the g0 stack with the 511 // C calling convention (use libcCall). 512 TEXT runtime·syscall6(SB),NOSPLIT,$0 513 SUB $16, RSP // push structure pointer 514 MOVD R0, 8(RSP) 515 516 MOVD 0(R0), R12 // fn 517 MOVD 16(R0), R1 // a2 518 MOVD 24(R0), R2 // a3 519 MOVD 32(R0), R3 // a4 520 MOVD 40(R0), R4 // a5 521 MOVD 48(R0), R5 // a6 522 MOVD 8(R0), R0 // a1 523 524 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. 525 // See syscall above. The only function this applies to is openat, for which the 4th 526 // arg must be on the stack. 527 MOVD R3, (RSP) 528 529 BL (R12) 530 531 MOVD 8(RSP), R2 // pop structure pointer 532 ADD $16, RSP 533 MOVD R0, 56(R2) // save r1 534 MOVD R1, 64(R2) // save r2 535 CMPW $-1, R0 536 BNE ok 537 SUB $16, RSP // push structure pointer 538 MOVD R2, 8(RSP) 539 BL libc_error(SB) 540 MOVW (R0), R0 541 MOVD 8(RSP), R2 // pop structure pointer 542 ADD $16, RSP 543 MOVD R0, 72(R2) // save err 544 ok: 545 RET 546 547 // syscall6X calls a function in libc on behalf of the syscall package. 548 // syscall6X takes a pointer to a struct like: 549 // struct { 550 // fn uintptr 551 // a1 uintptr 552 // a2 uintptr 553 // a3 uintptr 554 // a4 uintptr 555 // a5 uintptr 556 // a6 uintptr 557 // r1 uintptr 558 // r2 uintptr 559 // err uintptr 560 // } 561 // syscall6X must be called on the g0 stack with the 562 // C calling convention (use libcCall). 563 TEXT runtime·syscall6X(SB),NOSPLIT,$0 564 SUB $16, RSP // push structure pointer 565 MOVD R0, (RSP) 566 567 MOVD 0(R0), R12 // fn 568 MOVD 16(R0), R1 // a2 569 MOVD 24(R0), R2 // a3 570 MOVD 32(R0), R3 // a4 571 MOVD 40(R0), R4 // a5 572 MOVD 48(R0), R5 // a6 573 MOVD 8(R0), R0 // a1 574 BL (R12) 575 576 MOVD (RSP), R2 // pop structure pointer 577 ADD $16, RSP 578 MOVD R0, 56(R2) // save r1 579 MOVD R1, 64(R2) // save r2 580 CMP $-1, R0 581 BNE ok 582 SUB $16, RSP // push structure pointer 583 MOVD R2, (RSP) 584 BL libc_error(SB) 585 MOVW (R0), R0 586 MOVD (RSP), R2 // pop structure pointer 587 ADD $16, RSP 588 MOVD R0, 72(R2) // save err 589 ok: 590 RET