github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/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 MOVQ SP, BX // callee-saved 53 ANDQ $~15, SP // alignment for x86_64 ABI 54 CALL AX 55 MOVQ BX, SP 56 RET 57 58 // Called using C ABI. 59 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0 60 // Transition from C ABI to Go ABI. 61 PUSH_REGS_HOST_TO_ABI0() 62 63 // Set up ABIInternal environment: g in R14, cleared X15. 64 get_tls(R12) 65 MOVQ g(R12), R14 66 PXOR X15, X15 67 68 // Reserve space for spill slots. 69 NOP SP // disable vet stack checking 70 ADJSP $24 71 72 // Call into the Go signal handler 73 MOVQ DI, AX // sig 74 MOVQ SI, BX // info 75 MOVQ DX, CX // ctx 76 CALL ·sigtrampgo<ABIInternal>(SB) 77 78 ADJSP $-24 79 80 POP_REGS_HOST_TO_ABI0() 81 RET 82 83 // 84 // These trampolines help convert from Go calling convention to C calling convention. 85 // They should be called with asmcgocall. 86 // A pointer to the arguments is passed in DI. 87 // A single int32 result is returned in AX. 88 // (For more results, make an args/results structure.) 89 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 90 MOVQ 0(DI), DI // arg 1 - attr 91 CALL libc_pthread_attr_init(SB) 92 RET 93 94 TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0 95 MOVQ 0(DI), DI // arg 1 - attr 96 CALL libc_pthread_attr_destroy(SB) 97 RET 98 99 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 100 MOVQ 8(DI), SI // arg 2 - stacksize 101 MOVQ 0(DI), DI // arg 1 - attr 102 CALL libc_pthread_attr_getstacksize(SB) 103 RET 104 105 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 106 MOVQ 8(DI), SI // arg 2 - detachstate 107 MOVQ 0(DI), DI // arg 1 - attr 108 CALL libc_pthread_attr_setdetachstate(SB) 109 RET 110 111 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$16 112 MOVQ 0(DI), SI // arg 2 - attr 113 MOVQ 8(DI), DX // arg 3 - start 114 MOVQ 16(DI), CX // arg 4 - arg 115 MOVQ SP, DI // arg 1 - &thread (discarded) 116 CALL libc_pthread_create(SB) 117 RET 118 119 TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0 120 MOVL 8(DI), SI // arg 2 - signal 121 MOVQ $0, DX // arg 3 - tcb 122 MOVL 0(DI), DI // arg 1 - tid 123 CALL libc_thrkill(SB) 124 RET 125 126 TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0 127 MOVL 8(DI), SI // arg 2 - clock_id 128 MOVQ 16(DI), DX // arg 3 - abstime 129 MOVQ 24(DI), CX // arg 4 - lock 130 MOVQ 32(DI), R8 // arg 5 - abort 131 MOVQ 0(DI), DI // arg 1 - id 132 CALL libc_thrsleep(SB) 133 RET 134 135 TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0 136 MOVL 8(DI), SI // arg 2 - count 137 MOVQ 0(DI), DI // arg 1 - id 138 CALL libc_thrwakeup(SB) 139 RET 140 141 TEXT runtime·exit_trampoline(SB),NOSPLIT,$0 142 MOVL 0(DI), DI // arg 1 exit status 143 CALL libc_exit(SB) 144 MOVL $0xf1, 0xf1 // crash 145 RET 146 147 TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0 148 MOVQ DI, BX // BX is caller-save 149 CALL libc_getthrid(SB) 150 MOVL AX, 0(BX) // return value 151 RET 152 153 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 154 MOVL 0(DI), BX // signal 155 CALL libc_getpid(SB) 156 MOVL AX, DI // arg 1 pid 157 MOVL BX, SI // arg 2 signal 158 CALL libc_kill(SB) 159 RET 160 161 TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0 162 CALL libc_sched_yield(SB) 163 RET 164 165 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 166 MOVQ DI, BX 167 MOVQ 0(BX), DI // arg 1 addr 168 MOVQ 8(BX), SI // arg 2 len 169 MOVL 16(BX), DX // arg 3 prot 170 MOVL 20(BX), CX // arg 4 flags 171 MOVL 24(BX), R8 // arg 5 fid 172 MOVL 28(BX), R9 // arg 6 offset 173 CALL libc_mmap(SB) 174 XORL DX, DX 175 CMPQ AX, $-1 176 JNE ok 177 CALL libc_errno(SB) 178 MOVLQSX (AX), DX // errno 179 XORQ AX, AX 180 ok: 181 MOVQ AX, 32(BX) 182 MOVQ DX, 40(BX) 183 RET 184 185 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 186 MOVQ 8(DI), SI // arg 2 len 187 MOVQ 0(DI), DI // arg 1 addr 188 CALL libc_munmap(SB) 189 TESTQ AX, AX 190 JEQ 2(PC) 191 MOVL $0xf1, 0xf1 // crash 192 RET 193 194 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0 195 MOVQ 8(DI), SI // arg 2 len 196 MOVL 16(DI), DX // arg 3 advice 197 MOVQ 0(DI), DI // arg 1 addr 198 CALL libc_madvise(SB) 199 // ignore failure - maybe pages are locked 200 RET 201 202 TEXT runtime·open_trampoline(SB),NOSPLIT,$0 203 MOVL 8(DI), SI // arg 2 - flags 204 MOVL 12(DI), DX // arg 3 - mode 205 MOVQ 0(DI), DI // arg 1 - path 206 XORL AX, AX // vararg: say "no float args" 207 CALL libc_open(SB) 208 RET 209 210 TEXT runtime·close_trampoline(SB),NOSPLIT,$0 211 MOVL 0(DI), DI // arg 1 - fd 212 CALL libc_close(SB) 213 RET 214 215 TEXT runtime·read_trampoline(SB),NOSPLIT,$0 216 MOVQ 8(DI), SI // arg 2 - buf 217 MOVL 16(DI), DX // arg 3 - count 218 MOVL 0(DI), DI // arg 1 - fd 219 CALL libc_read(SB) 220 TESTL AX, AX 221 JGE noerr 222 CALL libc_errno(SB) 223 MOVL (AX), AX // errno 224 NEGL AX // caller expects negative errno value 225 noerr: 226 RET 227 228 TEXT runtime·write_trampoline(SB),NOSPLIT,$0 229 MOVQ 8(DI), SI // arg 2 buf 230 MOVL 16(DI), DX // arg 3 count 231 MOVL 0(DI), DI // arg 1 fd 232 CALL libc_write(SB) 233 TESTL AX, AX 234 JGE noerr 235 CALL libc_errno(SB) 236 MOVL (AX), AX // errno 237 NEGL AX // caller expects negative errno value 238 noerr: 239 RET 240 241 TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0 242 MOVL 8(DI), SI // arg 2 flags 243 MOVQ 0(DI), DI // arg 1 filedes 244 CALL libc_pipe2(SB) 245 TESTL AX, AX 246 JEQ 3(PC) 247 CALL libc_errno(SB) 248 MOVL (AX), AX // errno 249 NEGL AX // caller expects negative errno value 250 RET 251 252 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0 253 MOVQ 8(DI), SI // arg 2 new 254 MOVQ 16(DI), DX // arg 3 old 255 MOVL 0(DI), DI // arg 1 which 256 CALL libc_setitimer(SB) 257 RET 258 259 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 260 MOVL 0(DI), DI // arg 1 usec 261 CALL libc_usleep(SB) 262 RET 263 264 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0 265 MOVL 8(DI), SI // arg 2 miblen 266 MOVQ 16(DI), DX // arg 3 out 267 MOVQ 24(DI), CX // arg 4 size 268 MOVQ 32(DI), R8 // arg 5 dst 269 MOVQ 40(DI), R9 // arg 6 ndst 270 MOVQ 0(DI), DI // arg 1 mib 271 CALL libc_sysctl(SB) 272 RET 273 274 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 275 CALL libc_kqueue(SB) 276 RET 277 278 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0 279 MOVQ 8(DI), SI // arg 2 keventt 280 MOVL 16(DI), DX // arg 3 nch 281 MOVQ 24(DI), CX // arg 4 ev 282 MOVL 32(DI), R8 // arg 5 nev 283 MOVQ 40(DI), R9 // arg 6 ts 284 MOVL 0(DI), DI // arg 1 kq 285 CALL libc_kevent(SB) 286 CMPL AX, $-1 287 JNE ok 288 CALL libc_errno(SB) 289 MOVL (AX), AX // errno 290 NEGL AX // caller expects negative errno value 291 ok: 292 RET 293 294 TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0 295 MOVQ 8(DI), SI // arg 2 tp 296 MOVL 0(DI), DI // arg 1 clock_id 297 CALL libc_clock_gettime(SB) 298 TESTL AX, AX 299 JEQ noerr 300 CALL libc_errno(SB) 301 MOVL (AX), AX // errno 302 NEGL AX // caller expects negative errno value 303 noerr: 304 RET 305 306 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 307 MOVQ DI, BX 308 MOVL 0(BX), DI // arg 1 fd 309 MOVL 4(BX), SI // arg 2 cmd 310 MOVL 8(BX), DX // arg 3 arg 311 XORL AX, AX // vararg: say "no float args" 312 CALL libc_fcntl(SB) 313 XORL DX, DX 314 CMPL AX, $-1 315 JNE noerr 316 CALL libc_errno(SB) 317 MOVL (AX), DX 318 MOVL $-1, AX 319 noerr: 320 MOVL AX, 12(BX) 321 MOVL DX, 16(BX) 322 RET 323 324 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 325 MOVQ 8(DI), SI // arg 2 new 326 MOVQ 16(DI), DX // arg 3 old 327 MOVL 0(DI), DI // arg 1 sig 328 CALL libc_sigaction(SB) 329 TESTL AX, AX 330 JEQ 2(PC) 331 MOVL $0xf1, 0xf1 // crash 332 RET 333 334 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 335 MOVQ 8(DI), SI // arg 2 new 336 MOVQ 16(DI), DX // arg 3 old 337 MOVL 0(DI), DI // arg 1 how 338 CALL libc_pthread_sigmask(SB) 339 TESTL AX, AX 340 JEQ 2(PC) 341 MOVL $0xf1, 0xf1 // crash 342 RET 343 344 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 345 MOVQ 8(DI), SI // arg 2 old 346 MOVQ 0(DI), DI // arg 1 new 347 CALL libc_sigaltstack(SB) 348 TESTQ AX, AX 349 JEQ 2(PC) 350 MOVL $0xf1, 0xf1 // crash 351 RET 352 353 // syscall calls a function in libc on behalf of the syscall package. 354 // syscall takes a pointer to a struct like: 355 // struct { 356 // fn uintptr 357 // a1 uintptr 358 // a2 uintptr 359 // a3 uintptr 360 // r1 uintptr 361 // r2 uintptr 362 // err uintptr 363 // } 364 // syscall must be called on the g0 stack with the 365 // C calling convention (use libcCall). 366 // 367 // syscall expects a 32-bit result and tests for 32-bit -1 368 // to decide there was an error. 369 TEXT runtime·syscall(SB),NOSPLIT,$16 370 MOVQ (0*8)(DI), CX // fn 371 MOVQ (2*8)(DI), SI // a2 372 MOVQ (3*8)(DI), DX // a3 373 MOVQ DI, (SP) 374 MOVQ (1*8)(DI), DI // a1 375 XORL AX, AX // vararg: say "no float args" 376 377 CALL CX 378 379 MOVQ (SP), DI 380 MOVQ AX, (4*8)(DI) // r1 381 MOVQ DX, (5*8)(DI) // r2 382 383 // Standard libc functions return -1 on error 384 // and set errno. 385 CMPL AX, $-1 // Note: high 32 bits are junk 386 JNE ok 387 388 // Get error code from libc. 389 CALL libc_errno(SB) 390 MOVLQSX (AX), AX 391 MOVQ (SP), DI 392 MOVQ AX, (6*8)(DI) // err 393 394 ok: 395 XORL AX, AX // no error (it's ignored anyway) 396 RET 397 398 // syscallX calls a function in libc on behalf of the syscall package. 399 // syscallX takes a pointer to a struct like: 400 // struct { 401 // fn uintptr 402 // a1 uintptr 403 // a2 uintptr 404 // a3 uintptr 405 // r1 uintptr 406 // r2 uintptr 407 // err uintptr 408 // } 409 // syscallX must be called on the g0 stack with the 410 // C calling convention (use libcCall). 411 // 412 // syscallX is like syscall but expects a 64-bit result 413 // and tests for 64-bit -1 to decide there was an error. 414 TEXT runtime·syscallX(SB),NOSPLIT,$16 415 MOVQ (0*8)(DI), CX // fn 416 MOVQ (2*8)(DI), SI // a2 417 MOVQ (3*8)(DI), DX // a3 418 MOVQ DI, (SP) 419 MOVQ (1*8)(DI), DI // a1 420 XORL AX, AX // vararg: say "no float args" 421 422 CALL CX 423 424 MOVQ (SP), DI 425 MOVQ AX, (4*8)(DI) // r1 426 MOVQ DX, (5*8)(DI) // r2 427 428 // Standard libc functions return -1 on error 429 // and set errno. 430 CMPQ AX, $-1 431 JNE ok 432 433 // Get error code from libc. 434 CALL libc_errno(SB) 435 MOVLQSX (AX), AX 436 MOVQ (SP), DI 437 MOVQ AX, (6*8)(DI) // err 438 439 ok: 440 XORL AX, AX // no error (it's ignored anyway) 441 RET 442 443 // syscall6 calls a function in libc on behalf of the syscall package. 444 // syscall6 takes a pointer to a struct like: 445 // struct { 446 // fn uintptr 447 // a1 uintptr 448 // a2 uintptr 449 // a3 uintptr 450 // a4 uintptr 451 // a5 uintptr 452 // a6 uintptr 453 // r1 uintptr 454 // r2 uintptr 455 // err uintptr 456 // } 457 // syscall6 must be called on the g0 stack with the 458 // C calling convention (use libcCall). 459 // 460 // syscall6 expects a 32-bit result and tests for 32-bit -1 461 // to decide there was an error. 462 TEXT runtime·syscall6(SB),NOSPLIT,$16 463 MOVQ (0*8)(DI), R11// fn 464 MOVQ (2*8)(DI), SI // a2 465 MOVQ (3*8)(DI), DX // a3 466 MOVQ (4*8)(DI), CX // a4 467 MOVQ (5*8)(DI), R8 // a5 468 MOVQ (6*8)(DI), R9 // a6 469 MOVQ DI, (SP) 470 MOVQ (1*8)(DI), DI // a1 471 XORL AX, AX // vararg: say "no float args" 472 473 CALL R11 474 475 MOVQ (SP), DI 476 MOVQ AX, (7*8)(DI) // r1 477 MOVQ DX, (8*8)(DI) // r2 478 479 CMPL AX, $-1 480 JNE ok 481 482 CALL libc_errno(SB) 483 MOVLQSX (AX), AX 484 MOVQ (SP), DI 485 MOVQ AX, (9*8)(DI) // err 486 487 ok: 488 XORL AX, AX // no error (it's ignored anyway) 489 RET 490 491 // syscall6X calls a function in libc on behalf of the syscall package. 492 // syscall6X takes a pointer to a struct like: 493 // struct { 494 // fn uintptr 495 // a1 uintptr 496 // a2 uintptr 497 // a3 uintptr 498 // a4 uintptr 499 // a5 uintptr 500 // a6 uintptr 501 // r1 uintptr 502 // r2 uintptr 503 // err uintptr 504 // } 505 // syscall6X must be called on the g0 stack with the 506 // C calling convention (use libcCall). 507 // 508 // syscall6X is like syscall6 but expects a 64-bit result 509 // and tests for 64-bit -1 to decide there was an error. 510 TEXT runtime·syscall6X(SB),NOSPLIT,$16 511 MOVQ (0*8)(DI), R11// fn 512 MOVQ (2*8)(DI), SI // a2 513 MOVQ (3*8)(DI), DX // a3 514 MOVQ (4*8)(DI), CX // a4 515 MOVQ (5*8)(DI), R8 // a5 516 MOVQ (6*8)(DI), R9 // a6 517 MOVQ DI, (SP) 518 MOVQ (1*8)(DI), DI // a1 519 XORL AX, AX // vararg: say "no float args" 520 521 CALL R11 522 523 MOVQ (SP), DI 524 MOVQ AX, (7*8)(DI) // r1 525 MOVQ DX, (8*8)(DI) // r2 526 527 CMPQ AX, $-1 528 JNE ok 529 530 CALL libc_errno(SB) 531 MOVLQSX (AX), AX 532 MOVQ (SP), DI 533 MOVQ AX, (9*8)(DI) // err 534 535 ok: 536 XORL AX, AX // no error (it's ignored anyway) 537 RET 538 539 // syscall10 calls a function in libc on behalf of the syscall package. 540 // syscall10 takes a pointer to a struct like: 541 // struct { 542 // fn uintptr 543 // a1 uintptr 544 // a2 uintptr 545 // a3 uintptr 546 // a4 uintptr 547 // a5 uintptr 548 // a6 uintptr 549 // a7 uintptr 550 // a8 uintptr 551 // a9 uintptr 552 // a10 uintptr 553 // r1 uintptr 554 // r2 uintptr 555 // err uintptr 556 // } 557 // syscall10 must be called on the g0 stack with the 558 // C calling convention (use libcCall). 559 TEXT runtime·syscall10(SB),NOSPLIT,$48 560 // Arguments a1 to a6 get passed in registers, with a7 onwards being 561 // passed via the stack per the x86-64 System V ABI 562 // (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf). 563 MOVQ (7*8)(DI), R10 // a7 564 MOVQ (8*8)(DI), R11 // a8 565 MOVQ (9*8)(DI), R12 // a9 566 MOVQ (10*8)(DI), R13 // a10 567 MOVQ R10, (0*8)(SP) // a7 568 MOVQ R11, (1*8)(SP) // a8 569 MOVQ R12, (2*8)(SP) // a9 570 MOVQ R13, (3*8)(SP) // a10 571 MOVQ (0*8)(DI), R11 // fn 572 MOVQ (2*8)(DI), SI // a2 573 MOVQ (3*8)(DI), DX // a3 574 MOVQ (4*8)(DI), CX // a4 575 MOVQ (5*8)(DI), R8 // a5 576 MOVQ (6*8)(DI), R9 // a6 577 MOVQ DI, (4*8)(SP) 578 MOVQ (1*8)(DI), DI // a1 579 XORL AX, AX // vararg: say "no float args" 580 581 CALL R11 582 583 MOVQ (4*8)(SP), DI 584 MOVQ AX, (11*8)(DI) // r1 585 MOVQ DX, (12*8)(DI) // r2 586 587 CMPL AX, $-1 588 JNE ok 589 590 CALL libc_errno(SB) 591 MOVLQSX (AX), AX 592 MOVQ (4*8)(SP), DI 593 MOVQ AX, (13*8)(DI) // err 594 595 ok: 596 XORL AX, AX // no error (it's ignored anyway) 597 RET 598 599 // syscall10X calls a function in libc on behalf of the syscall package. 600 // syscall10X takes a pointer to a struct like: 601 // struct { 602 // fn uintptr 603 // a1 uintptr 604 // a2 uintptr 605 // a3 uintptr 606 // a4 uintptr 607 // a5 uintptr 608 // a6 uintptr 609 // a7 uintptr 610 // a8 uintptr 611 // a9 uintptr 612 // a10 uintptr 613 // r1 uintptr 614 // r2 uintptr 615 // err uintptr 616 // } 617 // syscall10X must be called on the g0 stack with the 618 // C calling convention (use libcCall). 619 // 620 // syscall10X is like syscall10 but expects a 64-bit result 621 // and tests for 64-bit -1 to decide there was an error. 622 TEXT runtime·syscall10X(SB),NOSPLIT,$48 623 // Arguments a1 to a6 get passed in registers, with a7 onwards being 624 // passed via the stack per the x86-64 System V ABI 625 // (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf). 626 MOVQ (7*8)(DI), R10 // a7 627 MOVQ (8*8)(DI), R11 // a8 628 MOVQ (9*8)(DI), R12 // a9 629 MOVQ (10*8)(DI), R13 // a10 630 MOVQ R10, (0*8)(SP) // a7 631 MOVQ R11, (1*8)(SP) // a8 632 MOVQ R12, (2*8)(SP) // a9 633 MOVQ R13, (3*8)(SP) // a10 634 MOVQ (0*8)(DI), R11 // fn 635 MOVQ (2*8)(DI), SI // a2 636 MOVQ (3*8)(DI), DX // a3 637 MOVQ (4*8)(DI), CX // a4 638 MOVQ (5*8)(DI), R8 // a5 639 MOVQ (6*8)(DI), R9 // a6 640 MOVQ DI, (4*8)(SP) 641 MOVQ (1*8)(DI), DI // a1 642 XORL AX, AX // vararg: say "no float args" 643 644 CALL R11 645 646 MOVQ (4*8)(SP), DI 647 MOVQ AX, (11*8)(DI) // r1 648 MOVQ DX, (12*8)(DI) // r2 649 650 CMPQ AX, $-1 651 JNE ok 652 653 CALL libc_errno(SB) 654 MOVLQSX (AX), AX 655 MOVQ (4*8)(SP), DI 656 MOVQ AX, (13*8)(DI) // err 657 658 ok: 659 XORL AX, AX // no error (it's ignored anyway) 660 RET 661 662 TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0 663 MOVQ DI, BX // BX is caller-save 664 CALL libc_issetugid(SB) 665 MOVL AX, 0(BX) // return value 666 RET