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