github.com/lzhfromustc/gofuzz@v0.0.0-20211116160056-151b3108bbd1/runtime/sys_openbsd_arm64.s (about) 1 // Copyright 2019 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 arm64, 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 15 #define CLOCK_REALTIME $0 16 #define CLOCK_MONOTONIC $3 17 18 // mstart_stub is the first function executed on a new thread started by pthread_create. 19 // It just does some low-level setup and then calls mstart. 20 // Note: called with the C calling convention. 21 TEXT runtime·mstart_stub(SB),NOSPLIT,$160 22 // R0 points to the m. 23 // We are already on m's g0 stack. 24 25 // Save callee-save registers. 26 MOVD R19, 8(RSP) 27 MOVD R20, 16(RSP) 28 MOVD R21, 24(RSP) 29 MOVD R22, 32(RSP) 30 MOVD R23, 40(RSP) 31 MOVD R24, 48(RSP) 32 MOVD R25, 56(RSP) 33 MOVD R26, 64(RSP) 34 MOVD R27, 72(RSP) 35 MOVD g, 80(RSP) 36 MOVD R29, 88(RSP) 37 FMOVD F8, 96(RSP) 38 FMOVD F9, 104(RSP) 39 FMOVD F10, 112(RSP) 40 FMOVD F11, 120(RSP) 41 FMOVD F12, 128(RSP) 42 FMOVD F13, 136(RSP) 43 FMOVD F14, 144(RSP) 44 FMOVD F15, 152(RSP) 45 46 MOVD m_g0(R0), g 47 BL runtime·save_g(SB) 48 49 BL runtime·mstart(SB) 50 51 // Restore callee-save registers. 52 MOVD 8(RSP), R19 53 MOVD 16(RSP), R20 54 MOVD 24(RSP), R21 55 MOVD 32(RSP), R22 56 MOVD 40(RSP), R23 57 MOVD 48(RSP), R24 58 MOVD 56(RSP), R25 59 MOVD 64(RSP), R26 60 MOVD 72(RSP), R27 61 MOVD 80(RSP), g 62 MOVD 88(RSP), R29 63 FMOVD 96(RSP), F8 64 FMOVD 104(RSP), F9 65 FMOVD 112(RSP), F10 66 FMOVD 120(RSP), F11 67 FMOVD 128(RSP), F12 68 FMOVD 136(RSP), F13 69 FMOVD 144(RSP), F14 70 FMOVD 152(RSP), F15 71 72 // Go is all done with this OS thread. 73 // Tell pthread everything is ok (we never join with this thread, so 74 // the value here doesn't really matter). 75 MOVD $0, R0 76 77 RET 78 79 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 80 MOVW sig+8(FP), R0 81 MOVD info+16(FP), R1 82 MOVD ctx+24(FP), R2 83 MOVD fn+0(FP), R11 84 BL (R11) // Alignment for ELF ABI? 85 RET 86 87 TEXT runtime·sigtramp(SB),NOSPLIT,$192 88 // Save callee-save registers in the case of signal forwarding. 89 // Please refer to https://golang.org/issue/31827 . 90 MOVD R19, 8*4(RSP) 91 MOVD R20, 8*5(RSP) 92 MOVD R21, 8*6(RSP) 93 MOVD R22, 8*7(RSP) 94 MOVD R23, 8*8(RSP) 95 MOVD R24, 8*9(RSP) 96 MOVD R25, 8*10(RSP) 97 MOVD R26, 8*11(RSP) 98 MOVD R27, 8*12(RSP) 99 MOVD g, 8*13(RSP) 100 MOVD R29, 8*14(RSP) 101 FMOVD F8, 8*15(RSP) 102 FMOVD F9, 8*16(RSP) 103 FMOVD F10, 8*17(RSP) 104 FMOVD F11, 8*18(RSP) 105 FMOVD F12, 8*19(RSP) 106 FMOVD F13, 8*20(RSP) 107 FMOVD F14, 8*21(RSP) 108 FMOVD F15, 8*22(RSP) 109 110 // If called from an external code context, g will not be set. 111 // Save R0, since runtime·load_g will clobber it. 112 MOVW R0, 8(RSP) // signum 113 BL runtime·load_g(SB) 114 115 MOVD R1, 16(RSP) 116 MOVD R2, 24(RSP) 117 BL runtime·sigtrampgo(SB) 118 119 // Restore callee-save registers. 120 MOVD 8*4(RSP), R19 121 MOVD 8*5(RSP), R20 122 MOVD 8*6(RSP), R21 123 MOVD 8*7(RSP), R22 124 MOVD 8*8(RSP), R23 125 MOVD 8*9(RSP), R24 126 MOVD 8*10(RSP), R25 127 MOVD 8*11(RSP), R26 128 MOVD 8*12(RSP), R27 129 MOVD 8*13(RSP), g 130 MOVD 8*14(RSP), R29 131 FMOVD 8*15(RSP), F8 132 FMOVD 8*16(RSP), F9 133 FMOVD 8*17(RSP), F10 134 FMOVD 8*18(RSP), F11 135 FMOVD 8*19(RSP), F12 136 FMOVD 8*20(RSP), F13 137 FMOVD 8*21(RSP), F14 138 FMOVD 8*22(RSP), F15 139 140 RET 141 142 // 143 // These trampolines help convert from Go calling convention to C calling convention. 144 // They should be called with asmcgocall. 145 // A pointer to the arguments is passed in R0. 146 // A single int32 result is returned in R0. 147 // (For more results, make an args/results structure.) 148 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 149 MOVD 0(R0), R0 // arg 1 - attr 150 CALL libc_pthread_attr_init(SB) 151 RET 152 153 TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0 154 MOVD 0(R0), R0 // arg 1 - attr 155 CALL libc_pthread_attr_destroy(SB) 156 RET 157 158 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 159 MOVD 8(R0), R1 // arg 2 - size 160 MOVD 0(R0), R0 // arg 1 - attr 161 CALL libc_pthread_attr_getstacksize(SB) 162 RET 163 164 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 165 MOVD 8(R0), R1 // arg 2 - state 166 MOVD 0(R0), R0 // arg 1 - attr 167 CALL libc_pthread_attr_setdetachstate(SB) 168 RET 169 170 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0 171 MOVD 0(R0), R1 // arg 2 - attr 172 MOVD 8(R0), R2 // arg 3 - start 173 MOVD 16(R0), R3 // arg 4 - arg 174 SUB $16, RSP 175 MOVD RSP, R0 // arg 1 - &threadid (discard) 176 CALL libc_pthread_create(SB) 177 ADD $16, RSP 178 RET 179 180 TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0 181 MOVW 8(R0), R1 // arg 2 - signal 182 MOVD $0, R2 // arg 3 - tcb 183 MOVW 0(R0), R0 // arg 1 - tid 184 CALL libc_thrkill(SB) 185 RET 186 187 TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0 188 MOVW 8(R0), R1 // arg 2 - clock_id 189 MOVD 16(R0), R2 // arg 3 - abstime 190 MOVD 24(R0), R3 // arg 4 - lock 191 MOVD 32(R0), R4 // arg 5 - abort 192 MOVD 0(R0), R0 // arg 1 - id 193 CALL libc_thrsleep(SB) 194 RET 195 196 TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0 197 MOVW 8(R0), R1 // arg 2 - count 198 MOVD 0(R0), R0 // arg 1 - id 199 CALL libc_thrwakeup(SB) 200 RET 201 202 TEXT runtime·exit_trampoline(SB),NOSPLIT,$0 203 MOVW 0(R0), R0 // arg 1 - status 204 CALL libc_exit(SB) 205 MOVD $0, R0 // crash on failure 206 MOVD R0, (R0) 207 RET 208 209 TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0 210 MOVD R0, R19 // pointer to args 211 CALL libc_getthrid(SB) 212 MOVW R0, 0(R19) // return value 213 RET 214 215 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 216 MOVD R0, R19 // pointer to args 217 CALL libc_getpid(SB) // arg 1 - pid 218 MOVW 0(R19), R1 // arg 2 - signal 219 CALL libc_kill(SB) 220 RET 221 222 TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0 223 CALL libc_sched_yield(SB) 224 RET 225 226 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 227 MOVD R0, R19 // pointer to args 228 MOVD 0(R19), R0 // arg 1 - addr 229 MOVD 8(R19), R1 // arg 2 - len 230 MOVW 16(R19), R2 // arg 3 - prot 231 MOVW 20(R19), R3 // arg 4 - flags 232 MOVW 24(R19), R4 // arg 5 - fid 233 MOVW 28(R19), R5 // arg 6 - offset 234 CALL libc_mmap(SB) 235 MOVD $0, R1 236 CMP $-1, R0 237 BNE noerr 238 CALL libc_errno(SB) 239 MOVW (R0), R1 // errno 240 MOVD $0, R0 241 noerr: 242 MOVD R0, 32(R19) 243 MOVD R1, 40(R19) 244 RET 245 246 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 247 MOVD 8(R0), R1 // arg 2 - len 248 MOVD 0(R0), R0 // arg 1 - addr 249 CALL libc_munmap(SB) 250 CMP $-1, R0 251 BNE 3(PC) 252 MOVD $0, R0 // crash on failure 253 MOVD R0, (R0) 254 RET 255 256 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0 257 MOVD 8(R0), R1 // arg 2 - len 258 MOVW 16(R0), R2 // arg 3 - advice 259 MOVD 0(R0), R0 // arg 1 - addr 260 CALL libc_madvise(SB) 261 // ignore failure - maybe pages are locked 262 RET 263 264 TEXT runtime·open_trampoline(SB),NOSPLIT,$0 265 MOVW 8(R0), R1 // arg 2 - flags 266 MOVW 12(R0), R2 // arg 3 - mode 267 MOVD 0(R0), R0 // arg 1 - path 268 MOVD $0, R3 // varargs 269 CALL libc_open(SB) 270 RET 271 272 TEXT runtime·close_trampoline(SB),NOSPLIT,$0 273 MOVD 0(R0), R0 // arg 1 - fd 274 CALL libc_close(SB) 275 RET 276 277 TEXT runtime·read_trampoline(SB),NOSPLIT,$0 278 MOVD 8(R0), R1 // arg 2 - buf 279 MOVW 16(R0), R2 // arg 3 - count 280 MOVW 0(R0), R0 // arg 1 - fd 281 CALL libc_read(SB) 282 CMP $-1, R0 283 BNE noerr 284 CALL libc_errno(SB) 285 MOVW (R0), R0 // errno 286 NEG R0, R0 // caller expects negative errno value 287 noerr: 288 RET 289 290 TEXT runtime·write_trampoline(SB),NOSPLIT,$0 291 MOVD 8(R0), R1 // arg 2 - buf 292 MOVW 16(R0), R2 // arg 3 - count 293 MOVW 0(R0), R0 // arg 1 - fd 294 CALL libc_write(SB) 295 CMP $-1, R0 296 BNE noerr 297 CALL libc_errno(SB) 298 MOVW (R0), R0 // errno 299 NEG R0, R0 // caller expects negative errno value 300 noerr: 301 RET 302 303 TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0 304 MOVW 8(R0), R1 // arg 2 - flags 305 MOVD 0(R0), R0 // arg 1 - filedes 306 CALL libc_pipe2(SB) 307 CMP $-1, R0 308 BNE noerr 309 CALL libc_errno(SB) 310 MOVW (R0), R0 // errno 311 NEG R0, R0 // caller expects negative errno value 312 noerr: 313 RET 314 315 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0 316 MOVD 8(R0), R1 // arg 2 - new 317 MOVD 16(R0), R2 // arg 3 - old 318 MOVW 0(R0), R0 // arg 1 - which 319 CALL libc_setitimer(SB) 320 RET 321 322 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 323 MOVD 0(R0), R0 // arg 1 - usec 324 CALL libc_usleep(SB) 325 RET 326 327 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0 328 MOVW 8(R0), R1 // arg 2 - miblen 329 MOVD 16(R0), R2 // arg 3 - out 330 MOVD 24(R0), R3 // arg 4 - size 331 MOVD 32(R0), R4 // arg 5 - dst 332 MOVD 40(R0), R5 // arg 6 - ndst 333 MOVD 0(R0), R0 // arg 1 - mib 334 CALL libc_sysctl(SB) 335 RET 336 337 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 338 CALL libc_kqueue(SB) 339 RET 340 341 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0 342 MOVD 8(R0), R1 // arg 2 - keventt 343 MOVW 16(R0), R2 // arg 3 - nch 344 MOVD 24(R0), R3 // arg 4 - ev 345 MOVW 32(R0), R4 // arg 5 - nev 346 MOVD 40(R0), R5 // arg 6 - ts 347 MOVW 0(R0), R0 // arg 1 - kq 348 CALL libc_kevent(SB) 349 CMP $-1, R0 350 BNE noerr 351 CALL libc_errno(SB) 352 MOVW (R0), R0 // errno 353 NEG R0, R0 // caller expects negative errno value 354 noerr: 355 RET 356 357 TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0 358 MOVD 8(R0), R1 // arg 2 - tp 359 MOVD 0(R0), R0 // arg 1 - clock_id 360 CALL libc_clock_gettime(SB) 361 CMP $-1, R0 362 BNE 3(PC) 363 MOVD $0, R0 // crash on failure 364 MOVD R0, (R0) 365 RET 366 367 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 368 MOVW 4(R0), R1 // arg 2 - cmd 369 MOVW 8(R0), R2 // arg 3 - arg 370 MOVW 0(R0), R0 // arg 1 - fd 371 MOVD $0, R3 // vararg 372 CALL libc_fcntl(SB) 373 RET 374 375 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 376 MOVD 8(R0), R1 // arg 2 - new 377 MOVD 16(R0), R2 // arg 3 - old 378 MOVW 0(R0), R0 // arg 1 - sig 379 CALL libc_sigaction(SB) 380 CMP $-1, R0 381 BNE 3(PC) 382 MOVD $0, R0 // crash on syscall failure 383 MOVD R0, (R0) 384 RET 385 386 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 387 MOVD 8(R0), R1 // arg 2 - new 388 MOVD 16(R0), R2 // arg 3 - old 389 MOVW 0(R0), R0 // arg 1 - how 390 CALL libc_pthread_sigmask(SB) 391 CMP $-1, R0 392 BNE 3(PC) 393 MOVD $0, R0 // crash on syscall failure 394 MOVD R0, (R0) 395 RET 396 397 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 398 MOVD 8(R0), R1 // arg 2 - old 399 MOVD 0(R0), R0 // arg 1 - new 400 CALL libc_sigaltstack(SB) 401 CMP $-1, R0 402 BNE 3(PC) 403 MOVD $0, R0 // crash on syscall failure 404 MOVD R0, (R0) 405 RET 406 407 // syscall calls a function in libc on behalf of the syscall package. 408 // syscall takes a pointer to a struct like: 409 // struct { 410 // fn uintptr 411 // a1 uintptr 412 // a2 uintptr 413 // a3 uintptr 414 // r1 uintptr 415 // r2 uintptr 416 // err uintptr 417 // } 418 // syscall must be called on the g0 stack with the 419 // C calling convention (use libcCall). 420 // 421 // syscall expects a 32-bit result and tests for 32-bit -1 422 // to decide there was an error. 423 TEXT runtime·syscall(SB),NOSPLIT,$0 424 MOVD R0, R19 // pointer to args 425 426 MOVD (0*8)(R19), R11 // fn 427 MOVD (1*8)(R19), R0 // a1 428 MOVD (2*8)(R19), R1 // a2 429 MOVD (3*8)(R19), R2 // a3 430 MOVD $0, R3 // vararg 431 432 CALL R11 433 434 MOVD R0, (4*8)(R19) // r1 435 MOVD R1, (5*8)(R19) // r2 436 437 // Standard libc functions return -1 on error 438 // and set errno. 439 CMPW $-1, R0 440 BNE ok 441 442 // Get error code from libc. 443 CALL libc_errno(SB) 444 MOVW (R0), R0 445 MOVD R0, (6*8)(R19) // err 446 447 ok: 448 RET 449 450 // syscallX calls a function in libc on behalf of the syscall package. 451 // syscallX takes a pointer to a struct like: 452 // struct { 453 // fn uintptr 454 // a1 uintptr 455 // a2 uintptr 456 // a3 uintptr 457 // r1 uintptr 458 // r2 uintptr 459 // err uintptr 460 // } 461 // syscallX must be called on the g0 stack with the 462 // C calling convention (use libcCall). 463 // 464 // syscallX is like syscall but expects a 64-bit result 465 // and tests for 64-bit -1 to decide there was an error. 466 TEXT runtime·syscallX(SB),NOSPLIT,$0 467 MOVD R0, R19 // pointer to args 468 469 MOVD (0*8)(R19), R11 // fn 470 MOVD (1*8)(R19), R0 // a1 471 MOVD (2*8)(R19), R1 // a2 472 MOVD (3*8)(R19), R2 // a3 473 MOVD $0, R3 // vararg 474 475 CALL R11 476 477 MOVD R0, (4*8)(R19) // r1 478 MOVD R1, (5*8)(R19) // r2 479 480 // Standard libc functions return -1 on error 481 // and set errno. 482 CMP $-1, R0 483 BNE ok 484 485 // Get error code from libc. 486 CALL libc_errno(SB) 487 MOVW (R0), R0 488 MOVD R0, (6*8)(R19) // err 489 490 ok: 491 RET 492 493 // syscall6 calls a function in libc on behalf of the syscall package. 494 // syscall6 takes a pointer to a struct like: 495 // struct { 496 // fn uintptr 497 // a1 uintptr 498 // a2 uintptr 499 // a3 uintptr 500 // a4 uintptr 501 // a5 uintptr 502 // a6 uintptr 503 // r1 uintptr 504 // r2 uintptr 505 // err uintptr 506 // } 507 // syscall6 must be called on the g0 stack with the 508 // C calling convention (use libcCall). 509 // 510 // syscall6 expects a 32-bit result and tests for 32-bit -1 511 // to decide there was an error. 512 TEXT runtime·syscall6(SB),NOSPLIT,$0 513 MOVD R0, R19 // pointer to args 514 515 MOVD (0*8)(R19), R11 // fn 516 MOVD (1*8)(R19), R0 // a1 517 MOVD (2*8)(R19), R1 // a2 518 MOVD (3*8)(R19), R2 // a3 519 MOVD (4*8)(R19), R3 // a4 520 MOVD (5*8)(R19), R4 // a5 521 MOVD (6*8)(R19), R5 // a6 522 MOVD $0, R6 // vararg 523 524 CALL R11 525 526 MOVD R0, (7*8)(R19) // r1 527 MOVD R1, (8*8)(R19) // r2 528 529 // Standard libc functions return -1 on error 530 // and set errno. 531 CMPW $-1, R0 532 BNE ok 533 534 // Get error code from libc. 535 CALL libc_errno(SB) 536 MOVW (R0), R0 537 MOVD R0, (9*8)(R19) // err 538 539 ok: 540 RET 541 542 // syscall6X calls a function in libc on behalf of the syscall package. 543 // syscall6X takes a pointer to a struct like: 544 // struct { 545 // fn uintptr 546 // a1 uintptr 547 // a2 uintptr 548 // a3 uintptr 549 // a4 uintptr 550 // a5 uintptr 551 // a6 uintptr 552 // r1 uintptr 553 // r2 uintptr 554 // err uintptr 555 // } 556 // syscall6X must be called on the g0 stack with the 557 // C calling convention (use libcCall). 558 // 559 // syscall6X is like syscall6 but expects a 64-bit result 560 // and tests for 64-bit -1 to decide there was an error. 561 TEXT runtime·syscall6X(SB),NOSPLIT,$0 562 MOVD R0, R19 // pointer to args 563 564 MOVD (0*8)(R19), R11 // fn 565 MOVD (1*8)(R19), R0 // a1 566 MOVD (2*8)(R19), R1 // a2 567 MOVD (3*8)(R19), R2 // a3 568 MOVD (4*8)(R19), R3 // a4 569 MOVD (5*8)(R19), R4 // a5 570 MOVD (6*8)(R19), R5 // a6 571 MOVD $0, R6 // vararg 572 573 CALL R11 574 575 MOVD R0, (7*8)(R19) // r1 576 MOVD R1, (8*8)(R19) // r2 577 578 // Standard libc functions return -1 on error 579 // and set errno. 580 CMP $-1, R0 581 BNE ok 582 583 // Get error code from libc. 584 CALL libc_errno(SB) 585 MOVW (R0), R0 586 MOVD R0, (9*8)(R19) // err 587 588 ok: 589 RET 590 591 // syscall10 calls a function in libc on behalf of the syscall package. 592 // syscall10 takes a pointer to a struct like: 593 // struct { 594 // fn uintptr 595 // a1 uintptr 596 // a2 uintptr 597 // a3 uintptr 598 // a4 uintptr 599 // a5 uintptr 600 // a6 uintptr 601 // a7 uintptr 602 // a8 uintptr 603 // a9 uintptr 604 // a10 uintptr 605 // r1 uintptr 606 // r2 uintptr 607 // err uintptr 608 // } 609 // syscall10 must be called on the g0 stack with the 610 // C calling convention (use libcCall). 611 TEXT runtime·syscall10(SB),NOSPLIT,$0 612 MOVD R0, R19 // pointer to args 613 614 MOVD (0*8)(R19), R11 // fn 615 MOVD (1*8)(R19), R0 // a1 616 MOVD (2*8)(R19), R1 // a2 617 MOVD (3*8)(R19), R2 // a3 618 MOVD (4*8)(R19), R3 // a4 619 MOVD (5*8)(R19), R4 // a5 620 MOVD (6*8)(R19), R5 // a6 621 MOVD (7*8)(R19), R6 // a7 622 MOVD (8*8)(R19), R7 // a8 623 MOVD (9*8)(R19), R8 // a9 624 MOVD (10*8)(R19), R9 // a10 625 MOVD $0, R10 // vararg 626 627 CALL R11 628 629 MOVD R0, (11*8)(R19) // r1 630 MOVD R1, (12*8)(R19) // r2 631 632 // Standard libc functions return -1 on error 633 // and set errno. 634 CMPW $-1, R0 635 BNE ok 636 637 // Get error code from libc. 638 CALL libc_errno(SB) 639 MOVW (R0), R0 640 MOVD R0, (13*8)(R19) // err 641 642 ok: 643 RET 644 645 // syscall10X calls a function in libc on behalf of the syscall package. 646 // syscall10X takes a pointer to a struct like: 647 // struct { 648 // fn uintptr 649 // a1 uintptr 650 // a2 uintptr 651 // a3 uintptr 652 // a4 uintptr 653 // a5 uintptr 654 // a6 uintptr 655 // a7 uintptr 656 // a8 uintptr 657 // a9 uintptr 658 // a10 uintptr 659 // r1 uintptr 660 // r2 uintptr 661 // err uintptr 662 // } 663 // syscall10X must be called on the g0 stack with the 664 // C calling convention (use libcCall). 665 // 666 // syscall10X is like syscall10 but expects a 64-bit result 667 // and tests for 64-bit -1 to decide there was an error. 668 TEXT runtime·syscall10X(SB),NOSPLIT,$0 669 MOVD R0, R19 // pointer to args 670 671 MOVD (0*8)(R19), R11 // fn 672 MOVD (1*8)(R19), R0 // a1 673 MOVD (2*8)(R19), R1 // a2 674 MOVD (3*8)(R19), R2 // a3 675 MOVD (4*8)(R19), R3 // a4 676 MOVD (5*8)(R19), R4 // a5 677 MOVD (6*8)(R19), R5 // a6 678 MOVD (7*8)(R19), R6 // a7 679 MOVD (8*8)(R19), R7 // a8 680 MOVD (9*8)(R19), R8 // a9 681 MOVD (10*8)(R19), R9 // a10 682 MOVD $0, R10 // vararg 683 684 CALL R11 685 686 MOVD R0, (11*8)(R19) // r1 687 MOVD R1, (12*8)(R19) // r2 688 689 // Standard libc functions return -1 on error 690 // and set errno. 691 CMP $-1, R0 692 BNE ok 693 694 // Get error code from libc. 695 CALL libc_errno(SB) 696 MOVW (R0), R0 697 MOVD R0, (13*8)(R19) // err 698 699 ok: 700 RET