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