github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/runtime/sys_darwin_amd64.s (about) 1 // Copyright 2009 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 AMD64, 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_amd64.h" 13 14 #define CLOCK_REALTIME 0 15 16 // Exit the entire program (like C exit) 17 TEXT runtime·exit_trampoline(SB),NOSPLIT,$0 18 PUSHQ BP 19 MOVQ SP, BP 20 MOVL 0(DI), DI // arg 1 exit status 21 CALL libc_exit(SB) 22 MOVL $0xf1, 0xf1 // crash 23 POPQ BP 24 RET 25 26 TEXT runtime·open_trampoline(SB),NOSPLIT,$0 27 PUSHQ BP 28 MOVQ SP, BP 29 MOVL 8(DI), SI // arg 2 flags 30 MOVL 12(DI), DX // arg 3 mode 31 MOVQ 0(DI), DI // arg 1 pathname 32 XORL AX, AX // vararg: say "no float args" 33 CALL libc_open(SB) 34 POPQ BP 35 RET 36 37 TEXT runtime·close_trampoline(SB),NOSPLIT,$0 38 PUSHQ BP 39 MOVQ SP, BP 40 MOVL 0(DI), DI // arg 1 fd 41 CALL libc_close(SB) 42 POPQ BP 43 RET 44 45 TEXT runtime·read_trampoline(SB),NOSPLIT,$0 46 PUSHQ BP 47 MOVQ SP, BP 48 MOVQ 8(DI), SI // arg 2 buf 49 MOVL 16(DI), DX // arg 3 count 50 MOVL 0(DI), DI // arg 1 fd 51 CALL libc_read(SB) 52 TESTL AX, AX 53 JGE noerr 54 CALL libc_error(SB) 55 MOVL (AX), AX 56 NEGL AX // caller expects negative errno value 57 noerr: 58 POPQ BP 59 RET 60 61 TEXT runtime·write_trampoline(SB),NOSPLIT,$0 62 PUSHQ BP 63 MOVQ SP, BP 64 MOVQ 8(DI), SI // arg 2 buf 65 MOVL 16(DI), DX // arg 3 count 66 MOVQ 0(DI), DI // arg 1 fd 67 CALL libc_write(SB) 68 TESTL AX, AX 69 JGE noerr 70 CALL libc_error(SB) 71 MOVL (AX), AX 72 NEGL AX // caller expects negative errno value 73 noerr: 74 POPQ BP 75 RET 76 77 TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0 78 PUSHQ BP 79 MOVQ SP, BP 80 CALL libc_pipe(SB) // pointer already in DI 81 TESTL AX, AX 82 JEQ 3(PC) 83 CALL libc_error(SB) // return negative errno value 84 NEGL AX 85 POPQ BP 86 RET 87 88 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0 89 PUSHQ BP 90 MOVQ SP, BP 91 MOVQ 8(DI), SI // arg 2 new 92 MOVQ 16(DI), DX // arg 3 old 93 MOVL 0(DI), DI // arg 1 which 94 CALL libc_setitimer(SB) 95 POPQ BP 96 RET 97 98 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0 99 PUSHQ BP 100 MOVQ SP, BP 101 MOVQ 8(DI), SI // arg 2 len 102 MOVL 16(DI), DX // arg 3 advice 103 MOVQ 0(DI), DI // arg 1 addr 104 CALL libc_madvise(SB) 105 // ignore failure - maybe pages are locked 106 POPQ BP 107 RET 108 109 TEXT runtime·mlock_trampoline(SB), NOSPLIT, $0 110 UNDEF // unimplemented 111 112 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size) 113 114 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0 115 PUSHQ BP 116 MOVQ SP, BP 117 MOVQ DI, BX 118 CALL libc_mach_absolute_time(SB) 119 MOVQ AX, 0(BX) 120 MOVL timebase<>+machTimebaseInfo_numer(SB), SI 121 MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read 122 TESTL DI, DI 123 JNE initialized 124 125 SUBQ $(machTimebaseInfo__size+15)/16*16, SP 126 MOVQ SP, DI 127 CALL libc_mach_timebase_info(SB) 128 MOVL machTimebaseInfo_numer(SP), SI 129 MOVL machTimebaseInfo_denom(SP), DI 130 ADDQ $(machTimebaseInfo__size+15)/16*16, SP 131 132 MOVL SI, timebase<>+machTimebaseInfo_numer(SB) 133 MOVL DI, AX 134 XCHGL AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write 135 136 initialized: 137 MOVL SI, 8(BX) 138 MOVL DI, 12(BX) 139 MOVQ BP, SP 140 POPQ BP 141 RET 142 143 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0 144 PUSHQ BP // make a frame; keep stack aligned 145 MOVQ SP, BP 146 MOVQ DI, SI // arg 2 timespec 147 MOVL $CLOCK_REALTIME, DI // arg 1 clock_id 148 CALL libc_clock_gettime(SB) 149 POPQ BP 150 RET 151 152 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 153 PUSHQ BP 154 MOVQ SP, BP 155 MOVQ 8(DI), SI // arg 2 new 156 MOVQ 16(DI), DX // arg 3 old 157 MOVL 0(DI), DI // arg 1 sig 158 CALL libc_sigaction(SB) 159 TESTL AX, AX 160 JEQ 2(PC) 161 MOVL $0xf1, 0xf1 // crash 162 POPQ BP 163 RET 164 165 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 166 PUSHQ BP 167 MOVQ SP, BP 168 MOVQ 8(DI), SI // arg 2 new 169 MOVQ 16(DI), DX // arg 3 old 170 MOVL 0(DI), DI // arg 1 how 171 CALL libc_pthread_sigmask(SB) 172 TESTL AX, AX 173 JEQ 2(PC) 174 MOVL $0xf1, 0xf1 // crash 175 POPQ BP 176 RET 177 178 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 179 PUSHQ BP 180 MOVQ SP, BP 181 MOVQ 8(DI), SI // arg 2 old 182 MOVQ 0(DI), DI // arg 1 new 183 CALL libc_sigaltstack(SB) 184 TESTQ AX, AX 185 JEQ 2(PC) 186 MOVL $0xf1, 0xf1 // crash 187 POPQ BP 188 RET 189 190 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 191 PUSHQ BP 192 MOVQ SP, BP 193 MOVL 0(DI), BX // signal 194 CALL libc_getpid(SB) 195 MOVL AX, DI // arg 1 pid 196 MOVL BX, SI // arg 2 signal 197 CALL libc_kill(SB) 198 POPQ BP 199 RET 200 201 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 202 MOVQ fn+0(FP), AX 203 MOVL sig+8(FP), DI 204 MOVQ info+16(FP), SI 205 MOVQ ctx+24(FP), DX 206 PUSHQ BP 207 MOVQ SP, BP 208 ANDQ $~15, SP // alignment for x86_64 ABI 209 CALL AX 210 MOVQ BP, SP 211 POPQ BP 212 RET 213 214 // This is the function registered during sigaction and is invoked when 215 // a signal is received. It just redirects to the Go function sigtrampgo. 216 // Called using C ABI. 217 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$0 218 // Transition from C ABI to Go ABI. 219 PUSH_REGS_HOST_TO_ABI0() 220 221 // Set up ABIInternal environment: g in R14, cleared X15. 222 get_tls(R12) 223 MOVQ g(R12), R14 224 PXOR X15, X15 225 226 // Reserve space for spill slots. 227 NOP SP // disable vet stack checking 228 ADJSP $24 229 230 // Call into the Go signal handler 231 MOVQ DI, AX // sig 232 MOVQ SI, BX // info 233 MOVQ DX, CX // ctx 234 CALL ·sigtrampgo<ABIInternal>(SB) 235 236 ADJSP $-24 237 238 POP_REGS_HOST_TO_ABI0() 239 RET 240 241 // Called using C ABI. 242 TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0 243 // Transition from C ABI to Go ABI. 244 PUSH_REGS_HOST_TO_ABI0() 245 246 // Call into the Go signal handler 247 NOP SP // disable vet stack checking 248 ADJSP $24 249 MOVL DI, 0(SP) // sig 250 MOVQ SI, 8(SP) // info 251 MOVQ DX, 16(SP) // ctx 252 CALL ·sigprofNonGo(SB) 253 ADJSP $-24 254 255 POP_REGS_HOST_TO_ABI0() 256 RET 257 258 // Used instead of sigtramp in programs that use cgo. 259 // Arguments from kernel are in DI, SI, DX. 260 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 261 // If no traceback function, do usual sigtramp. 262 MOVQ runtime·cgoTraceback(SB), AX 263 TESTQ AX, AX 264 JZ sigtramp 265 266 // If no traceback support function, which means that 267 // runtime/cgo was not linked in, do usual sigtramp. 268 MOVQ _cgo_callers(SB), AX 269 TESTQ AX, AX 270 JZ sigtramp 271 272 // Figure out if we are currently in a cgo call. 273 // If not, just do usual sigtramp. 274 get_tls(CX) 275 MOVQ g(CX),AX 276 TESTQ AX, AX 277 JZ sigtrampnog // g == nil 278 MOVQ g_m(AX), AX 279 TESTQ AX, AX 280 JZ sigtramp // g.m == nil 281 MOVL m_ncgo(AX), CX 282 TESTL CX, CX 283 JZ sigtramp // g.m.ncgo == 0 284 MOVQ m_curg(AX), CX 285 TESTQ CX, CX 286 JZ sigtramp // g.m.curg == nil 287 MOVQ g_syscallsp(CX), CX 288 TESTQ CX, CX 289 JZ sigtramp // g.m.curg.syscallsp == 0 290 MOVQ m_cgoCallers(AX), R8 291 TESTQ R8, R8 292 JZ sigtramp // g.m.cgoCallers == nil 293 MOVL m_cgoCallersUse(AX), CX 294 TESTL CX, CX 295 JNZ sigtramp // g.m.cgoCallersUse != 0 296 297 // Jump to a function in runtime/cgo. 298 // That function, written in C, will call the user's traceback 299 // function with proper unwind info, and will then call back here. 300 // The first three arguments, and the fifth, are already in registers. 301 // Set the two remaining arguments now. 302 MOVQ runtime·cgoTraceback(SB), CX 303 MOVQ $runtime·sigtramp(SB), R9 304 MOVQ _cgo_callers(SB), AX 305 JMP AX 306 307 sigtramp: 308 JMP runtime·sigtramp(SB) 309 310 sigtrampnog: 311 // Signal arrived on a non-Go thread. If this is SIGPROF, get a 312 // stack trace. 313 CMPL DI, $27 // 27 == SIGPROF 314 JNZ sigtramp 315 316 // Lock sigprofCallersUse. 317 MOVL $0, AX 318 MOVL $1, CX 319 MOVQ $runtime·sigprofCallersUse(SB), R11 320 LOCK 321 CMPXCHGL CX, 0(R11) 322 JNZ sigtramp // Skip stack trace if already locked. 323 324 // Jump to the traceback function in runtime/cgo. 325 // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert 326 // the arguments to the Go calling convention. 327 // First three arguments to traceback function are in registers already. 328 MOVQ runtime·cgoTraceback(SB), CX 329 MOVQ $runtime·sigprofCallers(SB), R8 330 MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9 331 MOVQ _cgo_callers(SB), AX 332 JMP AX 333 334 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 335 PUSHQ BP // make a frame; keep stack aligned 336 MOVQ SP, BP 337 MOVQ DI, BX 338 MOVQ 0(BX), DI // arg 1 addr 339 MOVQ 8(BX), SI // arg 2 len 340 MOVL 16(BX), DX // arg 3 prot 341 MOVL 20(BX), CX // arg 4 flags 342 MOVL 24(BX), R8 // arg 5 fid 343 MOVL 28(BX), R9 // arg 6 offset 344 CALL libc_mmap(SB) 345 XORL DX, DX 346 CMPQ AX, $-1 347 JNE ok 348 CALL libc_error(SB) 349 MOVLQSX (AX), DX // errno 350 XORL AX, AX 351 ok: 352 MOVQ AX, 32(BX) 353 MOVQ DX, 40(BX) 354 POPQ BP 355 RET 356 357 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 358 PUSHQ BP 359 MOVQ SP, BP 360 MOVQ 8(DI), SI // arg 2 len 361 MOVQ 0(DI), DI // arg 1 addr 362 CALL libc_munmap(SB) 363 TESTQ AX, AX 364 JEQ 2(PC) 365 MOVL $0xf1, 0xf1 // crash 366 POPQ BP 367 RET 368 369 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 370 PUSHQ BP 371 MOVQ SP, BP 372 MOVL 0(DI), DI // arg 1 usec 373 CALL libc_usleep(SB) 374 POPQ BP 375 RET 376 377 TEXT runtime·settls(SB),NOSPLIT,$32 378 // Nothing to do on Darwin, pthread already set thread-local storage up. 379 RET 380 381 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0 382 PUSHQ BP 383 MOVQ SP, BP 384 MOVL 8(DI), SI // arg 2 miblen 385 MOVQ 16(DI), DX // arg 3 oldp 386 MOVQ 24(DI), CX // arg 4 oldlenp 387 MOVQ 32(DI), R8 // arg 5 newp 388 MOVQ 40(DI), R9 // arg 6 newlen 389 MOVQ 0(DI), DI // arg 1 mib 390 CALL libc_sysctl(SB) 391 POPQ BP 392 RET 393 394 TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0 395 PUSHQ BP 396 MOVQ SP, BP 397 MOVQ 8(DI), SI // arg 2 oldp 398 MOVQ 16(DI), DX // arg 3 oldlenp 399 MOVQ 24(DI), CX // arg 4 newp 400 MOVQ 32(DI), R8 // arg 5 newlen 401 MOVQ 0(DI), DI // arg 1 name 402 CALL libc_sysctlbyname(SB) 403 POPQ BP 404 RET 405 406 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 407 PUSHQ BP 408 MOVQ SP, BP 409 CALL libc_kqueue(SB) 410 POPQ BP 411 RET 412 413 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0 414 PUSHQ BP 415 MOVQ SP, BP 416 MOVQ 8(DI), SI // arg 2 keventt 417 MOVL 16(DI), DX // arg 3 nch 418 MOVQ 24(DI), CX // arg 4 ev 419 MOVL 32(DI), R8 // arg 5 nev 420 MOVQ 40(DI), R9 // arg 6 ts 421 MOVL 0(DI), DI // arg 1 kq 422 CALL libc_kevent(SB) 423 CMPL AX, $-1 424 JNE ok 425 CALL libc_error(SB) 426 MOVLQSX (AX), AX // errno 427 NEGQ AX // caller wants it as a negative error code 428 ok: 429 POPQ BP 430 RET 431 432 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 433 PUSHQ BP 434 MOVQ SP, BP 435 MOVL 4(DI), SI // arg 2 cmd 436 MOVL 8(DI), DX // arg 3 arg 437 MOVL 0(DI), DI // arg 1 fd 438 XORL AX, AX // vararg: say "no float args" 439 CALL libc_fcntl(SB) 440 POPQ BP 441 RET 442 443 // mstart_stub is the first function executed on a new thread started by pthread_create. 444 // It just does some low-level setup and then calls mstart. 445 // Note: called with the C calling convention. 446 TEXT runtime·mstart_stub(SB),NOSPLIT,$0 447 // DI points to the m. 448 // We are already on m's g0 stack. 449 450 // Transition from C ABI to Go ABI. 451 PUSH_REGS_HOST_TO_ABI0() 452 453 MOVQ m_g0(DI), DX // g 454 455 // Initialize TLS entry. 456 // See cmd/link/internal/ld/sym.go:computeTLSOffset. 457 MOVQ DX, 0x30(GS) 458 459 CALL runtime·mstart(SB) 460 461 POP_REGS_HOST_TO_ABI0() 462 463 // Go is all done with this OS thread. 464 // Tell pthread everything is ok (we never join with this thread, so 465 // the value here doesn't really matter). 466 XORL AX, AX 467 RET 468 469 // These trampolines help convert from Go calling convention to C calling convention. 470 // They should be called with asmcgocall. 471 // A pointer to the arguments is passed in DI. 472 // A single int32 result is returned in AX. 473 // (For more results, make an args/results structure.) 474 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 475 PUSHQ BP // make frame, keep stack 16-byte aligned. 476 MOVQ SP, BP 477 MOVQ 0(DI), DI // arg 1 attr 478 CALL libc_pthread_attr_init(SB) 479 POPQ BP 480 RET 481 482 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 483 PUSHQ BP 484 MOVQ SP, BP 485 MOVQ 8(DI), SI // arg 2 size 486 MOVQ 0(DI), DI // arg 1 attr 487 CALL libc_pthread_attr_getstacksize(SB) 488 POPQ BP 489 RET 490 491 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 492 PUSHQ BP 493 MOVQ SP, BP 494 MOVQ 8(DI), SI // arg 2 state 495 MOVQ 0(DI), DI // arg 1 attr 496 CALL libc_pthread_attr_setdetachstate(SB) 497 POPQ BP 498 RET 499 500 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0 501 PUSHQ BP 502 MOVQ SP, BP 503 SUBQ $16, SP 504 MOVQ 0(DI), SI // arg 2 attr 505 MOVQ 8(DI), DX // arg 3 start 506 MOVQ 16(DI), CX // arg 4 arg 507 MOVQ SP, DI // arg 1 &threadid (which we throw away) 508 CALL libc_pthread_create(SB) 509 MOVQ BP, SP 510 POPQ BP 511 RET 512 513 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0 514 PUSHQ BP 515 MOVQ SP, BP 516 MOVL 0(DI), DI // arg 1 signal 517 CALL libc_raise(SB) 518 POPQ BP 519 RET 520 521 TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0 522 PUSHQ BP 523 MOVQ SP, BP 524 MOVQ 8(DI), SI // arg 2 attr 525 MOVQ 0(DI), DI // arg 1 mutex 526 CALL libc_pthread_mutex_init(SB) 527 POPQ BP 528 RET 529 530 TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0 531 PUSHQ BP 532 MOVQ SP, BP 533 MOVQ 0(DI), DI // arg 1 mutex 534 CALL libc_pthread_mutex_lock(SB) 535 POPQ BP 536 RET 537 538 TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0 539 PUSHQ BP 540 MOVQ SP, BP 541 MOVQ 0(DI), DI // arg 1 mutex 542 CALL libc_pthread_mutex_unlock(SB) 543 POPQ BP 544 RET 545 546 TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0 547 PUSHQ BP 548 MOVQ SP, BP 549 MOVQ 8(DI), SI // arg 2 attr 550 MOVQ 0(DI), DI // arg 1 cond 551 CALL libc_pthread_cond_init(SB) 552 POPQ BP 553 RET 554 555 TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0 556 PUSHQ BP 557 MOVQ SP, BP 558 MOVQ 8(DI), SI // arg 2 mutex 559 MOVQ 0(DI), DI // arg 1 cond 560 CALL libc_pthread_cond_wait(SB) 561 POPQ BP 562 RET 563 564 TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0 565 PUSHQ BP 566 MOVQ SP, BP 567 MOVQ 8(DI), SI // arg 2 mutex 568 MOVQ 16(DI), DX // arg 3 timeout 569 MOVQ 0(DI), DI // arg 1 cond 570 CALL libc_pthread_cond_timedwait_relative_np(SB) 571 POPQ BP 572 RET 573 574 TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0 575 PUSHQ BP 576 MOVQ SP, BP 577 MOVQ 0(DI), DI // arg 1 cond 578 CALL libc_pthread_cond_signal(SB) 579 POPQ BP 580 RET 581 582 TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0 583 PUSHQ BP 584 MOVQ SP, BP 585 MOVQ DI, BX // BX is caller-save 586 CALL libc_pthread_self(SB) 587 MOVQ AX, 0(BX) // return value 588 POPQ BP 589 RET 590 591 TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0 592 PUSHQ BP 593 MOVQ SP, BP 594 MOVQ 8(DI), SI // arg 2 sig 595 MOVQ 0(DI), DI // arg 1 thread 596 CALL libc_pthread_kill(SB) 597 POPQ BP 598 RET 599 600 // syscall calls a function in libc on behalf of the syscall package. 601 // syscall takes a pointer to a struct like: 602 // struct { 603 // fn uintptr 604 // a1 uintptr 605 // a2 uintptr 606 // a3 uintptr 607 // r1 uintptr 608 // r2 uintptr 609 // err uintptr 610 // } 611 // syscall must be called on the g0 stack with the 612 // C calling convention (use libcCall). 613 // 614 // syscall expects a 32-bit result and tests for 32-bit -1 615 // to decide there was an error. 616 TEXT runtime·syscall(SB),NOSPLIT,$0 617 PUSHQ BP 618 MOVQ SP, BP 619 SUBQ $16, SP 620 MOVQ (0*8)(DI), CX // fn 621 MOVQ (2*8)(DI), SI // a2 622 MOVQ (3*8)(DI), DX // a3 623 MOVQ DI, (SP) 624 MOVQ (1*8)(DI), DI // a1 625 XORL AX, AX // vararg: say "no float args" 626 627 CALL CX 628 629 MOVQ (SP), DI 630 MOVQ AX, (4*8)(DI) // r1 631 MOVQ DX, (5*8)(DI) // r2 632 633 // Standard libc functions return -1 on error 634 // and set errno. 635 CMPL AX, $-1 // Note: high 32 bits are junk 636 JNE ok 637 638 // Get error code from libc. 639 CALL libc_error(SB) 640 MOVLQSX (AX), AX 641 MOVQ (SP), DI 642 MOVQ AX, (6*8)(DI) // err 643 644 ok: 645 XORL AX, AX // no error (it's ignored anyway) 646 MOVQ BP, SP 647 POPQ BP 648 RET 649 650 // syscallX calls a function in libc on behalf of the syscall package. 651 // syscallX takes a pointer to a struct like: 652 // struct { 653 // fn uintptr 654 // a1 uintptr 655 // a2 uintptr 656 // a3 uintptr 657 // r1 uintptr 658 // r2 uintptr 659 // err uintptr 660 // } 661 // syscallX must be called on the g0 stack with the 662 // C calling convention (use libcCall). 663 // 664 // syscallX is like syscall but expects a 64-bit result 665 // and tests for 64-bit -1 to decide there was an error. 666 TEXT runtime·syscallX(SB),NOSPLIT,$0 667 PUSHQ BP 668 MOVQ SP, BP 669 SUBQ $16, SP 670 MOVQ (0*8)(DI), CX // fn 671 MOVQ (2*8)(DI), SI // a2 672 MOVQ (3*8)(DI), DX // a3 673 MOVQ DI, (SP) 674 MOVQ (1*8)(DI), DI // a1 675 XORL AX, AX // vararg: say "no float args" 676 677 CALL CX 678 679 MOVQ (SP), DI 680 MOVQ AX, (4*8)(DI) // r1 681 MOVQ DX, (5*8)(DI) // r2 682 683 // Standard libc functions return -1 on error 684 // and set errno. 685 CMPQ AX, $-1 686 JNE ok 687 688 // Get error code from libc. 689 CALL libc_error(SB) 690 MOVLQSX (AX), AX 691 MOVQ (SP), DI 692 MOVQ AX, (6*8)(DI) // err 693 694 ok: 695 XORL AX, AX // no error (it's ignored anyway) 696 MOVQ BP, SP 697 POPQ BP 698 RET 699 700 // syscallPtr is like syscallX except that the libc function reports an 701 // error by returning NULL and setting errno. 702 TEXT runtime·syscallPtr(SB),NOSPLIT,$0 703 PUSHQ BP 704 MOVQ SP, BP 705 SUBQ $16, SP 706 MOVQ (0*8)(DI), CX // fn 707 MOVQ (2*8)(DI), SI // a2 708 MOVQ (3*8)(DI), DX // a3 709 MOVQ DI, (SP) 710 MOVQ (1*8)(DI), DI // a1 711 XORL AX, AX // vararg: say "no float args" 712 713 CALL CX 714 715 MOVQ (SP), DI 716 MOVQ AX, (4*8)(DI) // r1 717 MOVQ DX, (5*8)(DI) // r2 718 719 // syscallPtr libc functions return NULL on error 720 // and set errno. 721 TESTQ AX, AX 722 JNE ok 723 724 // Get error code from libc. 725 CALL libc_error(SB) 726 MOVLQSX (AX), AX 727 MOVQ (SP), DI 728 MOVQ AX, (6*8)(DI) // err 729 730 ok: 731 XORL AX, AX // no error (it's ignored anyway) 732 MOVQ BP, SP 733 POPQ BP 734 RET 735 736 // syscall6 calls a function in libc on behalf of the syscall package. 737 // syscall6 takes a pointer to a struct like: 738 // struct { 739 // fn uintptr 740 // a1 uintptr 741 // a2 uintptr 742 // a3 uintptr 743 // a4 uintptr 744 // a5 uintptr 745 // a6 uintptr 746 // r1 uintptr 747 // r2 uintptr 748 // err uintptr 749 // } 750 // syscall6 must be called on the g0 stack with the 751 // C calling convention (use libcCall). 752 // 753 // syscall6 expects a 32-bit result and tests for 32-bit -1 754 // to decide there was an error. 755 TEXT runtime·syscall6(SB),NOSPLIT,$0 756 PUSHQ BP 757 MOVQ SP, BP 758 SUBQ $16, SP 759 MOVQ (0*8)(DI), R11// fn 760 MOVQ (2*8)(DI), SI // a2 761 MOVQ (3*8)(DI), DX // a3 762 MOVQ (4*8)(DI), CX // a4 763 MOVQ (5*8)(DI), R8 // a5 764 MOVQ (6*8)(DI), R9 // a6 765 MOVQ DI, (SP) 766 MOVQ (1*8)(DI), DI // a1 767 XORL AX, AX // vararg: say "no float args" 768 769 CALL R11 770 771 MOVQ (SP), DI 772 MOVQ AX, (7*8)(DI) // r1 773 MOVQ DX, (8*8)(DI) // r2 774 775 CMPL AX, $-1 776 JNE ok 777 778 CALL libc_error(SB) 779 MOVLQSX (AX), AX 780 MOVQ (SP), DI 781 MOVQ AX, (9*8)(DI) // err 782 783 ok: 784 XORL AX, AX // no error (it's ignored anyway) 785 MOVQ BP, SP 786 POPQ BP 787 RET 788 789 // syscall6X calls a function in libc on behalf of the syscall package. 790 // syscall6X takes a pointer to a struct like: 791 // struct { 792 // fn uintptr 793 // a1 uintptr 794 // a2 uintptr 795 // a3 uintptr 796 // a4 uintptr 797 // a5 uintptr 798 // a6 uintptr 799 // r1 uintptr 800 // r2 uintptr 801 // err uintptr 802 // } 803 // syscall6X must be called on the g0 stack with the 804 // C calling convention (use libcCall). 805 // 806 // syscall6X is like syscall6 but expects a 64-bit result 807 // and tests for 64-bit -1 to decide there was an error. 808 TEXT runtime·syscall6X(SB),NOSPLIT,$0 809 PUSHQ BP 810 MOVQ SP, BP 811 SUBQ $16, SP 812 MOVQ (0*8)(DI), R11// fn 813 MOVQ (2*8)(DI), SI // a2 814 MOVQ (3*8)(DI), DX // a3 815 MOVQ (4*8)(DI), CX // a4 816 MOVQ (5*8)(DI), R8 // a5 817 MOVQ (6*8)(DI), R9 // a6 818 MOVQ DI, (SP) 819 MOVQ (1*8)(DI), DI // a1 820 XORL AX, AX // vararg: say "no float args" 821 822 CALL R11 823 824 MOVQ (SP), DI 825 MOVQ AX, (7*8)(DI) // r1 826 MOVQ DX, (8*8)(DI) // r2 827 828 CMPQ AX, $-1 829 JNE ok 830 831 CALL libc_error(SB) 832 MOVLQSX (AX), AX 833 MOVQ (SP), DI 834 MOVQ AX, (9*8)(DI) // err 835 836 ok: 837 XORL AX, AX // no error (it's ignored anyway) 838 MOVQ BP, SP 839 POPQ BP 840 RET 841 842 // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors, 843 // takes 5 uintptrs and 1 float64, and only returns one value, 844 // for use with standard C ABI functions. 845 TEXT runtime·syscall_x509(SB),NOSPLIT,$0 846 PUSHQ BP 847 MOVQ SP, BP 848 SUBQ $16, SP 849 MOVQ (0*8)(DI), R11// fn 850 MOVQ (2*8)(DI), SI // a2 851 MOVQ (3*8)(DI), DX // a3 852 MOVQ (4*8)(DI), CX // a4 853 MOVQ (5*8)(DI), R8 // a5 854 MOVQ (6*8)(DI), X0 // f1 855 MOVQ DI, (SP) 856 MOVQ (1*8)(DI), DI // a1 857 XORL AX, AX // vararg: say "no float args" 858 859 CALL R11 860 861 MOVQ (SP), DI 862 MOVQ AX, (7*8)(DI) // r1 863 864 XORL AX, AX // no error (it's ignored anyway) 865 MOVQ BP, SP 866 POPQ BP 867 RET