github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/runtime/sys_openbsd_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, OpenBSD. 6 // System calls are implemented in libc/libpthread, this file 7 // contains trampolines that convert from Go to C calling convention. 8 // Some direct system call implementations currently remain. 9 // 10 11 #include "go_asm.h" 12 #include "go_tls.h" 13 #include "textflag.h" 14 #include "cgo/abi_amd64.h" 15 16 #define CLOCK_MONOTONIC $3 17 18 TEXT runtime·settls(SB),NOSPLIT,$0 19 // Nothing to do, pthread already set thread-local storage up. 20 RET 21 22 // mstart_stub is the first function executed on a new thread started by pthread_create. 23 // It just does some low-level setup and then calls mstart. 24 // Note: called with the C calling convention. 25 TEXT runtime·mstart_stub(SB),NOSPLIT,$0 26 // DI points to the m. 27 // We are already on m's g0 stack. 28 29 // Transition from C ABI to Go ABI. 30 PUSH_REGS_HOST_TO_ABI0() 31 32 // Load g and save to TLS entry. 33 // See cmd/link/internal/ld/sym.go:computeTLSOffset. 34 MOVQ m_g0(DI), DX // g 35 MOVQ DX, -8(FS) 36 37 CALL runtime·mstart(SB) 38 39 POP_REGS_HOST_TO_ABI0() 40 41 // Go is all done with this OS thread. 42 // Tell pthread everything is ok (we never join with this thread, so 43 // the value here doesn't really matter). 44 XORL AX, AX 45 RET 46 47 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 48 MOVQ fn+0(FP), AX 49 MOVL sig+8(FP), DI 50 MOVQ info+16(FP), SI 51 MOVQ ctx+24(FP), DX 52 PUSHQ BP 53 MOVQ SP, BP 54 ANDQ $~15, SP // alignment for x86_64 ABI 55 CALL AX 56 MOVQ BP, SP 57 POPQ BP 58 RET 59 60 // Called using C ABI. 61 TEXT runtime·sigtramp(SB),NOSPLIT,$0 62 // Transition from C ABI to Go ABI. 63 PUSH_REGS_HOST_TO_ABI0() 64 65 // Call into the Go signal handler 66 NOP SP // disable vet stack checking 67 ADJSP $24 68 MOVQ DI, 0(SP) // sig 69 MOVQ SI, 8(SP) // info 70 MOVQ DX, 16(SP) // ctx 71 CALL ·sigtrampgo(SB) 72 ADJSP $-24 73 74 POP_REGS_HOST_TO_ABI0() 75 RET 76 77 // 78 // These trampolines help convert from Go calling convention to C calling convention. 79 // They should be called with asmcgocall. 80 // A pointer to the arguments is passed in DI. 81 // A single int32 result is returned in AX. 82 // (For more results, make an args/results structure.) 83 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 84 PUSHQ BP 85 MOVQ SP, BP 86 MOVQ 0(DI), DI // arg 1 - attr 87 CALL libc_pthread_attr_init(SB) 88 POPQ BP 89 RET 90 91 TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0 92 PUSHQ BP 93 MOVQ SP, BP 94 MOVQ 0(DI), DI // arg 1 - attr 95 CALL libc_pthread_attr_destroy(SB) 96 POPQ BP 97 RET 98 99 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 100 PUSHQ BP 101 MOVQ SP, BP 102 MOVQ 8(DI), SI // arg 2 - stacksize 103 MOVQ 0(DI), DI // arg 1 - attr 104 CALL libc_pthread_attr_getstacksize(SB) 105 POPQ BP 106 RET 107 108 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 109 PUSHQ BP 110 MOVQ SP, BP 111 MOVQ 8(DI), SI // arg 2 - detachstate 112 MOVQ 0(DI), DI // arg 1 - attr 113 CALL libc_pthread_attr_setdetachstate(SB) 114 POPQ BP 115 RET 116 117 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0 118 PUSHQ BP 119 MOVQ SP, BP 120 SUBQ $16, SP 121 MOVQ 0(DI), SI // arg 2 - attr 122 MOVQ 8(DI), DX // arg 3 - start 123 MOVQ 16(DI), CX // arg 4 - arg 124 MOVQ SP, DI // arg 1 - &thread (discarded) 125 CALL libc_pthread_create(SB) 126 MOVQ BP, SP 127 POPQ BP 128 RET 129 130 TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0 131 PUSHQ BP 132 MOVQ SP, BP 133 MOVL 8(DI), SI // arg 2 - signal 134 MOVQ $0, DX // arg 3 - tcb 135 MOVL 0(DI), DI // arg 1 - tid 136 CALL libc_thrkill(SB) 137 POPQ BP 138 RET 139 140 TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0 141 PUSHQ BP 142 MOVQ SP, BP 143 MOVL 8(DI), SI // arg 2 - clock_id 144 MOVQ 16(DI), DX // arg 3 - abstime 145 MOVQ 24(DI), CX // arg 4 - lock 146 MOVQ 32(DI), R8 // arg 5 - abort 147 MOVQ 0(DI), DI // arg 1 - id 148 CALL libc_thrsleep(SB) 149 POPQ BP 150 RET 151 152 TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0 153 PUSHQ BP 154 MOVQ SP, BP 155 MOVL 8(DI), SI // arg 2 - count 156 MOVQ 0(DI), DI // arg 1 - id 157 CALL libc_thrwakeup(SB) 158 POPQ BP 159 RET 160 161 TEXT runtime·exit_trampoline(SB),NOSPLIT,$0 162 PUSHQ BP 163 MOVQ SP, BP 164 MOVL 0(DI), DI // arg 1 exit status 165 CALL libc_exit(SB) 166 MOVL $0xf1, 0xf1 // crash 167 POPQ BP 168 RET 169 170 TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0 171 PUSHQ BP 172 MOVQ SP, BP 173 MOVQ DI, BX // BX is caller-save 174 CALL libc_getthrid(SB) 175 MOVL AX, 0(BX) // return value 176 POPQ BP 177 RET 178 179 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 180 PUSHQ BP 181 MOVQ SP, BP 182 MOVL 0(DI), BX // signal 183 CALL libc_getpid(SB) 184 MOVL AX, DI // arg 1 pid 185 MOVL BX, SI // arg 2 signal 186 CALL libc_kill(SB) 187 POPQ BP 188 RET 189 190 TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0 191 PUSHQ BP 192 MOVQ SP, BP 193 CALL libc_sched_yield(SB) 194 POPQ BP 195 RET 196 197 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 198 PUSHQ BP // make a frame; keep stack aligned 199 MOVQ SP, BP 200 MOVQ DI, BX 201 MOVQ 0(BX), DI // arg 1 addr 202 MOVQ 8(BX), SI // arg 2 len 203 MOVL 16(BX), DX // arg 3 prot 204 MOVL 20(BX), CX // arg 4 flags 205 MOVL 24(BX), R8 // arg 5 fid 206 MOVL 28(BX), R9 // arg 6 offset 207 CALL libc_mmap(SB) 208 XORL DX, DX 209 CMPQ AX, $-1 210 JNE ok 211 CALL libc_errno(SB) 212 MOVLQSX (AX), DX // errno 213 XORQ AX, AX 214 ok: 215 MOVQ AX, 32(BX) 216 MOVQ DX, 40(BX) 217 POPQ BP 218 RET 219 220 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 221 PUSHQ BP 222 MOVQ SP, BP 223 MOVQ 8(DI), SI // arg 2 len 224 MOVQ 0(DI), DI // arg 1 addr 225 CALL libc_munmap(SB) 226 TESTQ AX, AX 227 JEQ 2(PC) 228 MOVL $0xf1, 0xf1 // crash 229 POPQ BP 230 RET 231 232 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0 233 PUSHQ BP 234 MOVQ SP, BP 235 MOVQ 8(DI), SI // arg 2 len 236 MOVL 16(DI), DX // arg 3 advice 237 MOVQ 0(DI), DI // arg 1 addr 238 CALL libc_madvise(SB) 239 // ignore failure - maybe pages are locked 240 POPQ BP 241 RET 242 243 TEXT runtime·open_trampoline(SB),NOSPLIT,$0 244 PUSHQ BP 245 MOVQ SP, BP 246 MOVL 8(DI), SI // arg 2 - flags 247 MOVL 12(DI), DX // arg 3 - mode 248 MOVQ 0(DI), DI // arg 1 - path 249 XORL AX, AX // vararg: say "no float args" 250 CALL libc_open(SB) 251 POPQ BP 252 RET 253 254 TEXT runtime·close_trampoline(SB),NOSPLIT,$0 255 PUSHQ BP 256 MOVQ SP, BP 257 MOVL 0(DI), DI // arg 1 - fd 258 CALL libc_close(SB) 259 POPQ BP 260 RET 261 262 TEXT runtime·read_trampoline(SB),NOSPLIT,$0 263 PUSHQ BP 264 MOVQ SP, BP 265 MOVQ 8(DI), SI // arg 2 - buf 266 MOVL 16(DI), DX // arg 3 - count 267 MOVL 0(DI), DI // arg 1 - fd 268 CALL libc_read(SB) 269 TESTL AX, AX 270 JGE noerr 271 CALL libc_errno(SB) 272 MOVL (AX), AX // errno 273 NEGL AX // caller expects negative errno value 274 noerr: 275 POPQ BP 276 RET 277 278 TEXT runtime·write_trampoline(SB),NOSPLIT,$0 279 PUSHQ BP 280 MOVQ SP, BP 281 MOVQ 8(DI), SI // arg 2 buf 282 MOVL 16(DI), DX // arg 3 count 283 MOVL 0(DI), DI // arg 1 fd 284 CALL libc_write(SB) 285 TESTL AX, AX 286 JGE noerr 287 CALL libc_errno(SB) 288 MOVL (AX), AX // errno 289 NEGL AX // caller expects negative errno value 290 noerr: 291 POPQ BP 292 RET 293 294 TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0 295 PUSHQ BP 296 MOVQ SP, BP 297 MOVL 8(DI), SI // arg 2 flags 298 MOVQ 0(DI), DI // arg 1 filedes 299 CALL libc_pipe2(SB) 300 TESTL AX, AX 301 JEQ 3(PC) 302 CALL libc_errno(SB) 303 MOVL (AX), AX // errno 304 NEGL AX // caller expects negative errno value 305 POPQ BP 306 RET 307 308 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0 309 PUSHQ BP 310 MOVQ SP, BP 311 MOVQ 8(DI), SI // arg 2 new 312 MOVQ 16(DI), DX // arg 3 old 313 MOVL 0(DI), DI // arg 1 which 314 CALL libc_setitimer(SB) 315 POPQ BP 316 RET 317 318 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 319 PUSHQ BP 320 MOVQ SP, BP 321 MOVL 0(DI), DI // arg 1 usec 322 CALL libc_usleep(SB) 323 POPQ BP 324 RET 325 326 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0 327 PUSHQ BP 328 MOVQ SP, BP 329 MOVL 8(DI), SI // arg 2 miblen 330 MOVQ 16(DI), DX // arg 3 out 331 MOVQ 24(DI), CX // arg 4 size 332 MOVQ 32(DI), R8 // arg 5 dst 333 MOVQ 40(DI), R9 // arg 6 ndst 334 MOVQ 0(DI), DI // arg 1 mib 335 CALL libc_sysctl(SB) 336 POPQ BP 337 RET 338 339 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 340 PUSHQ BP 341 MOVQ SP, BP 342 CALL libc_kqueue(SB) 343 POPQ BP 344 RET 345 346 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0 347 PUSHQ BP 348 MOVQ SP, BP 349 MOVQ 8(DI), SI // arg 2 keventt 350 MOVL 16(DI), DX // arg 3 nch 351 MOVQ 24(DI), CX // arg 4 ev 352 MOVL 32(DI), R8 // arg 5 nev 353 MOVQ 40(DI), R9 // arg 6 ts 354 MOVL 0(DI), DI // arg 1 kq 355 CALL libc_kevent(SB) 356 CMPL AX, $-1 357 JNE ok 358 CALL libc_errno(SB) 359 MOVL (AX), AX // errno 360 NEGL AX // caller expects negative errno value 361 ok: 362 POPQ BP 363 RET 364 365 TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0 366 PUSHQ BP // make a frame; keep stack aligned 367 MOVQ SP, BP 368 MOVQ 8(DI), SI // arg 2 tp 369 MOVL 0(DI), DI // arg 1 clock_id 370 CALL libc_clock_gettime(SB) 371 TESTL AX, AX 372 JEQ noerr 373 CALL libc_errno(SB) 374 MOVL (AX), AX // errno 375 NEGL AX // caller expects negative errno value 376 noerr: 377 POPQ BP 378 RET 379 380 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 381 PUSHQ BP 382 MOVQ SP, BP 383 MOVL 4(DI), SI // arg 2 cmd 384 MOVL 8(DI), DX // arg 3 arg 385 MOVL 0(DI), DI // arg 1 fd 386 XORL AX, AX // vararg: say "no float args" 387 CALL libc_fcntl(SB) 388 POPQ BP 389 RET 390 391 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 392 PUSHQ BP 393 MOVQ SP, BP 394 MOVQ 8(DI), SI // arg 2 new 395 MOVQ 16(DI), DX // arg 3 old 396 MOVL 0(DI), DI // arg 1 sig 397 CALL libc_sigaction(SB) 398 TESTL AX, AX 399 JEQ 2(PC) 400 MOVL $0xf1, 0xf1 // crash 401 POPQ BP 402 RET 403 404 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 405 PUSHQ BP 406 MOVQ SP, BP 407 MOVQ 8(DI), SI // arg 2 new 408 MOVQ 16(DI), DX // arg 3 old 409 MOVL 0(DI), DI // arg 1 how 410 CALL libc_pthread_sigmask(SB) 411 TESTL AX, AX 412 JEQ 2(PC) 413 MOVL $0xf1, 0xf1 // crash 414 POPQ BP 415 RET 416 417 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 418 PUSHQ BP 419 MOVQ SP, BP 420 MOVQ 8(DI), SI // arg 2 old 421 MOVQ 0(DI), DI // arg 1 new 422 CALL libc_sigaltstack(SB) 423 TESTQ AX, AX 424 JEQ 2(PC) 425 MOVL $0xf1, 0xf1 // crash 426 POPQ BP 427 RET 428 429 // syscall calls a function in libc on behalf of the syscall package. 430 // syscall 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 // syscall must be called on the g0 stack with the 441 // C calling convention (use libcCall). 442 // 443 // syscall expects a 32-bit result and tests for 32-bit -1 444 // to decide there was an error. 445 TEXT runtime·syscall(SB),NOSPLIT,$0 446 PUSHQ BP 447 MOVQ SP, BP 448 SUBQ $16, SP 449 MOVQ (0*8)(DI), CX // fn 450 MOVQ (2*8)(DI), SI // a2 451 MOVQ (3*8)(DI), DX // a3 452 MOVQ DI, (SP) 453 MOVQ (1*8)(DI), DI // a1 454 XORL AX, AX // vararg: say "no float args" 455 456 CALL CX 457 458 MOVQ (SP), DI 459 MOVQ AX, (4*8)(DI) // r1 460 MOVQ DX, (5*8)(DI) // r2 461 462 // Standard libc functions return -1 on error 463 // and set errno. 464 CMPL AX, $-1 // Note: high 32 bits are junk 465 JNE ok 466 467 // Get error code from libc. 468 CALL libc_errno(SB) 469 MOVLQSX (AX), AX 470 MOVQ (SP), DI 471 MOVQ AX, (6*8)(DI) // err 472 473 ok: 474 XORL AX, AX // no error (it's ignored anyway) 475 MOVQ BP, SP 476 POPQ BP 477 RET 478 479 // syscallX calls a function in libc on behalf of the syscall package. 480 // syscallX takes a pointer to a struct like: 481 // struct { 482 // fn uintptr 483 // a1 uintptr 484 // a2 uintptr 485 // a3 uintptr 486 // r1 uintptr 487 // r2 uintptr 488 // err uintptr 489 // } 490 // syscallX must be called on the g0 stack with the 491 // C calling convention (use libcCall). 492 // 493 // syscallX is like syscall but expects a 64-bit result 494 // and tests for 64-bit -1 to decide there was an error. 495 TEXT runtime·syscallX(SB),NOSPLIT,$0 496 PUSHQ BP 497 MOVQ SP, BP 498 SUBQ $16, SP 499 MOVQ (0*8)(DI), CX // fn 500 MOVQ (2*8)(DI), SI // a2 501 MOVQ (3*8)(DI), DX // a3 502 MOVQ DI, (SP) 503 MOVQ (1*8)(DI), DI // a1 504 XORL AX, AX // vararg: say "no float args" 505 506 CALL CX 507 508 MOVQ (SP), DI 509 MOVQ AX, (4*8)(DI) // r1 510 MOVQ DX, (5*8)(DI) // r2 511 512 // Standard libc functions return -1 on error 513 // and set errno. 514 CMPQ AX, $-1 515 JNE ok 516 517 // Get error code from libc. 518 CALL libc_errno(SB) 519 MOVLQSX (AX), AX 520 MOVQ (SP), DI 521 MOVQ AX, (6*8)(DI) // err 522 523 ok: 524 XORL AX, AX // no error (it's ignored anyway) 525 MOVQ BP, SP 526 POPQ BP 527 RET 528 529 // syscall6 calls a function in libc on behalf of the syscall package. 530 // syscall6 takes a pointer to a struct like: 531 // struct { 532 // fn uintptr 533 // a1 uintptr 534 // a2 uintptr 535 // a3 uintptr 536 // a4 uintptr 537 // a5 uintptr 538 // a6 uintptr 539 // r1 uintptr 540 // r2 uintptr 541 // err uintptr 542 // } 543 // syscall6 must be called on the g0 stack with the 544 // C calling convention (use libcCall). 545 // 546 // syscall6 expects a 32-bit result and tests for 32-bit -1 547 // to decide there was an error. 548 TEXT runtime·syscall6(SB),NOSPLIT,$0 549 PUSHQ BP 550 MOVQ SP, BP 551 SUBQ $16, SP 552 MOVQ (0*8)(DI), R11// fn 553 MOVQ (2*8)(DI), SI // a2 554 MOVQ (3*8)(DI), DX // a3 555 MOVQ (4*8)(DI), CX // a4 556 MOVQ (5*8)(DI), R8 // a5 557 MOVQ (6*8)(DI), R9 // a6 558 MOVQ DI, (SP) 559 MOVQ (1*8)(DI), DI // a1 560 XORL AX, AX // vararg: say "no float args" 561 562 CALL R11 563 564 MOVQ (SP), DI 565 MOVQ AX, (7*8)(DI) // r1 566 MOVQ DX, (8*8)(DI) // r2 567 568 CMPL AX, $-1 569 JNE ok 570 571 CALL libc_errno(SB) 572 MOVLQSX (AX), AX 573 MOVQ (SP), DI 574 MOVQ AX, (9*8)(DI) // err 575 576 ok: 577 XORL AX, AX // no error (it's ignored anyway) 578 MOVQ BP, SP 579 POPQ BP 580 RET 581 582 // syscall6X calls a function in libc on behalf of the syscall package. 583 // syscall6X takes a pointer to a struct like: 584 // struct { 585 // fn uintptr 586 // a1 uintptr 587 // a2 uintptr 588 // a3 uintptr 589 // a4 uintptr 590 // a5 uintptr 591 // a6 uintptr 592 // r1 uintptr 593 // r2 uintptr 594 // err uintptr 595 // } 596 // syscall6X must be called on the g0 stack with the 597 // C calling convention (use libcCall). 598 // 599 // syscall6X is like syscall6 but expects a 64-bit result 600 // and tests for 64-bit -1 to decide there was an error. 601 TEXT runtime·syscall6X(SB),NOSPLIT,$0 602 PUSHQ BP 603 MOVQ SP, BP 604 SUBQ $16, SP 605 MOVQ (0*8)(DI), R11// fn 606 MOVQ (2*8)(DI), SI // a2 607 MOVQ (3*8)(DI), DX // a3 608 MOVQ (4*8)(DI), CX // a4 609 MOVQ (5*8)(DI), R8 // a5 610 MOVQ (6*8)(DI), R9 // a6 611 MOVQ DI, (SP) 612 MOVQ (1*8)(DI), DI // a1 613 XORL AX, AX // vararg: say "no float args" 614 615 CALL R11 616 617 MOVQ (SP), DI 618 MOVQ AX, (7*8)(DI) // r1 619 MOVQ DX, (8*8)(DI) // r2 620 621 CMPQ AX, $-1 622 JNE ok 623 624 CALL libc_errno(SB) 625 MOVLQSX (AX), AX 626 MOVQ (SP), DI 627 MOVQ AX, (9*8)(DI) // err 628 629 ok: 630 XORL AX, AX // no error (it's ignored anyway) 631 MOVQ BP, SP 632 POPQ BP 633 RET 634 635 // syscall10 calls a function in libc on behalf of the syscall package. 636 // syscall10 takes a pointer to a struct like: 637 // struct { 638 // fn uintptr 639 // a1 uintptr 640 // a2 uintptr 641 // a3 uintptr 642 // a4 uintptr 643 // a5 uintptr 644 // a6 uintptr 645 // a7 uintptr 646 // a8 uintptr 647 // a9 uintptr 648 // a10 uintptr 649 // r1 uintptr 650 // r2 uintptr 651 // err uintptr 652 // } 653 // syscall10 must be called on the g0 stack with the 654 // C calling convention (use libcCall). 655 TEXT runtime·syscall10(SB),NOSPLIT,$0 656 PUSHQ BP 657 MOVQ SP, BP 658 SUBQ $48, SP 659 660 // Arguments a1 to a6 get passed in registers, with a7 onwards being 661 // passed via the stack per the x86-64 System V ABI 662 // (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf). 663 MOVQ (7*8)(DI), R10 // a7 664 MOVQ (8*8)(DI), R11 // a8 665 MOVQ (9*8)(DI), R12 // a9 666 MOVQ (10*8)(DI), R13 // a10 667 MOVQ R10, (0*8)(SP) // a7 668 MOVQ R11, (1*8)(SP) // a8 669 MOVQ R12, (2*8)(SP) // a9 670 MOVQ R13, (3*8)(SP) // a10 671 MOVQ (0*8)(DI), R11 // fn 672 MOVQ (2*8)(DI), SI // a2 673 MOVQ (3*8)(DI), DX // a3 674 MOVQ (4*8)(DI), CX // a4 675 MOVQ (5*8)(DI), R8 // a5 676 MOVQ (6*8)(DI), R9 // a6 677 MOVQ DI, (4*8)(SP) 678 MOVQ (1*8)(DI), DI // a1 679 XORL AX, AX // vararg: say "no float args" 680 681 CALL R11 682 683 MOVQ (4*8)(SP), DI 684 MOVQ AX, (11*8)(DI) // r1 685 MOVQ DX, (12*8)(DI) // r2 686 687 CMPL AX, $-1 688 JNE ok 689 690 CALL libc_errno(SB) 691 MOVLQSX (AX), AX 692 MOVQ (4*8)(SP), DI 693 MOVQ AX, (13*8)(DI) // err 694 695 ok: 696 XORL AX, AX // no error (it's ignored anyway) 697 MOVQ BP, SP 698 POPQ BP 699 RET 700 701 // syscall10X calls a function in libc on behalf of the syscall package. 702 // syscall10X takes a pointer to a struct like: 703 // struct { 704 // fn uintptr 705 // a1 uintptr 706 // a2 uintptr 707 // a3 uintptr 708 // a4 uintptr 709 // a5 uintptr 710 // a6 uintptr 711 // a7 uintptr 712 // a8 uintptr 713 // a9 uintptr 714 // a10 uintptr 715 // r1 uintptr 716 // r2 uintptr 717 // err uintptr 718 // } 719 // syscall10X must be called on the g0 stack with the 720 // C calling convention (use libcCall). 721 // 722 // syscall10X is like syscall10 but expects a 64-bit result 723 // and tests for 64-bit -1 to decide there was an error. 724 TEXT runtime·syscall10X(SB),NOSPLIT,$0 725 PUSHQ BP 726 MOVQ SP, BP 727 SUBQ $48, SP 728 729 // Arguments a1 to a6 get passed in registers, with a7 onwards being 730 // passed via the stack per the x86-64 System V ABI 731 // (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf). 732 MOVQ (7*8)(DI), R10 // a7 733 MOVQ (8*8)(DI), R11 // a8 734 MOVQ (9*8)(DI), R12 // a9 735 MOVQ (10*8)(DI), R13 // a10 736 MOVQ R10, (0*8)(SP) // a7 737 MOVQ R11, (1*8)(SP) // a8 738 MOVQ R12, (2*8)(SP) // a9 739 MOVQ R13, (3*8)(SP) // a10 740 MOVQ (0*8)(DI), R11 // fn 741 MOVQ (2*8)(DI), SI // a2 742 MOVQ (3*8)(DI), DX // a3 743 MOVQ (4*8)(DI), CX // a4 744 MOVQ (5*8)(DI), R8 // a5 745 MOVQ (6*8)(DI), R9 // a6 746 MOVQ DI, (4*8)(SP) 747 MOVQ (1*8)(DI), DI // a1 748 XORL AX, AX // vararg: say "no float args" 749 750 CALL R11 751 752 MOVQ (4*8)(SP), DI 753 MOVQ AX, (11*8)(DI) // r1 754 MOVQ DX, (12*8)(DI) // r2 755 756 CMPQ AX, $-1 757 JNE ok 758 759 CALL libc_errno(SB) 760 MOVLQSX (AX), AX 761 MOVQ (4*8)(SP), DI 762 MOVQ AX, (13*8)(DI) // err 763 764 ok: 765 XORL AX, AX // no error (it's ignored anyway) 766 MOVQ BP, SP 767 POPQ BP 768 RET