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