github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/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 MOVW 4(R0), R1 // arg 2 - cmd 305 MOVW 8(R0), R2 // arg 3 - arg 306 MOVW 0(R0), R0 // arg 1 - fd 307 MOVD $0, R3 // vararg 308 CALL libc_fcntl(SB) 309 RET 310 311 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 312 MOVD 8(R0), R1 // arg 2 - new 313 MOVD 16(R0), R2 // arg 3 - old 314 MOVW 0(R0), R0 // arg 1 - sig 315 CALL libc_sigaction(SB) 316 CMP $-1, R0 317 BNE 3(PC) 318 MOVD $0, R0 // crash on syscall failure 319 MOVD R0, (R0) 320 RET 321 322 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 323 MOVD 8(R0), R1 // arg 2 - new 324 MOVD 16(R0), R2 // arg 3 - old 325 MOVW 0(R0), R0 // arg 1 - how 326 CALL libc_pthread_sigmask(SB) 327 CMP $-1, R0 328 BNE 3(PC) 329 MOVD $0, R0 // crash on syscall failure 330 MOVD R0, (R0) 331 RET 332 333 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 334 MOVD 8(R0), R1 // arg 2 - old 335 MOVD 0(R0), R0 // arg 1 - new 336 CALL libc_sigaltstack(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 // syscall calls a function in libc on behalf of the syscall package. 344 // syscall takes a pointer to a struct like: 345 // struct { 346 // fn uintptr 347 // a1 uintptr 348 // a2 uintptr 349 // a3 uintptr 350 // r1 uintptr 351 // r2 uintptr 352 // err uintptr 353 // } 354 // syscall must be called on the g0 stack with the 355 // C calling convention (use libcCall). 356 // 357 // syscall expects a 32-bit result and tests for 32-bit -1 358 // to decide there was an error. 359 TEXT runtime·syscall(SB),NOSPLIT,$0 360 MOVD R0, R19 // pointer to args 361 362 MOVD (0*8)(R19), R11 // fn 363 MOVD (1*8)(R19), R0 // a1 364 MOVD (2*8)(R19), R1 // a2 365 MOVD (3*8)(R19), R2 // a3 366 MOVD $0, R3 // vararg 367 368 CALL R11 369 370 MOVD R0, (4*8)(R19) // r1 371 MOVD R1, (5*8)(R19) // r2 372 373 // Standard libc functions return -1 on error 374 // and set errno. 375 CMPW $-1, R0 376 BNE ok 377 378 // Get error code from libc. 379 CALL libc_errno(SB) 380 MOVW (R0), R0 381 MOVD R0, (6*8)(R19) // err 382 383 ok: 384 RET 385 386 // syscallX calls a function in libc on behalf of the syscall package. 387 // syscallX takes a pointer to a struct like: 388 // struct { 389 // fn uintptr 390 // a1 uintptr 391 // a2 uintptr 392 // a3 uintptr 393 // r1 uintptr 394 // r2 uintptr 395 // err uintptr 396 // } 397 // syscallX must be called on the g0 stack with the 398 // C calling convention (use libcCall). 399 // 400 // syscallX is like syscall but expects a 64-bit result 401 // and tests for 64-bit -1 to decide there was an error. 402 TEXT runtime·syscallX(SB),NOSPLIT,$0 403 MOVD R0, R19 // pointer to args 404 405 MOVD (0*8)(R19), R11 // fn 406 MOVD (1*8)(R19), R0 // a1 407 MOVD (2*8)(R19), R1 // a2 408 MOVD (3*8)(R19), R2 // a3 409 MOVD $0, R3 // vararg 410 411 CALL R11 412 413 MOVD R0, (4*8)(R19) // r1 414 MOVD R1, (5*8)(R19) // r2 415 416 // Standard libc functions return -1 on error 417 // and set errno. 418 CMP $-1, R0 419 BNE ok 420 421 // Get error code from libc. 422 CALL libc_errno(SB) 423 MOVW (R0), R0 424 MOVD R0, (6*8)(R19) // err 425 426 ok: 427 RET 428 429 // syscall6 calls a function in libc on behalf of the syscall package. 430 // syscall6 takes a pointer to a struct like: 431 // struct { 432 // fn uintptr 433 // a1 uintptr 434 // a2 uintptr 435 // a3 uintptr 436 // a4 uintptr 437 // a5 uintptr 438 // a6 uintptr 439 // r1 uintptr 440 // r2 uintptr 441 // err uintptr 442 // } 443 // syscall6 must be called on the g0 stack with the 444 // C calling convention (use libcCall). 445 // 446 // syscall6 expects a 32-bit result and tests for 32-bit -1 447 // to decide there was an error. 448 TEXT runtime·syscall6(SB),NOSPLIT,$0 449 MOVD R0, R19 // pointer to args 450 451 MOVD (0*8)(R19), R11 // fn 452 MOVD (1*8)(R19), R0 // a1 453 MOVD (2*8)(R19), R1 // a2 454 MOVD (3*8)(R19), R2 // a3 455 MOVD (4*8)(R19), R3 // a4 456 MOVD (5*8)(R19), R4 // a5 457 MOVD (6*8)(R19), R5 // a6 458 MOVD $0, R6 // vararg 459 460 CALL R11 461 462 MOVD R0, (7*8)(R19) // r1 463 MOVD R1, (8*8)(R19) // r2 464 465 // Standard libc functions return -1 on error 466 // and set errno. 467 CMPW $-1, R0 468 BNE ok 469 470 // Get error code from libc. 471 CALL libc_errno(SB) 472 MOVW (R0), R0 473 MOVD R0, (9*8)(R19) // err 474 475 ok: 476 RET 477 478 // syscall6X calls a function in libc on behalf of the syscall package. 479 // syscall6X takes a pointer to a struct like: 480 // struct { 481 // fn uintptr 482 // a1 uintptr 483 // a2 uintptr 484 // a3 uintptr 485 // a4 uintptr 486 // a5 uintptr 487 // a6 uintptr 488 // r1 uintptr 489 // r2 uintptr 490 // err uintptr 491 // } 492 // syscall6X must be called on the g0 stack with the 493 // C calling convention (use libcCall). 494 // 495 // syscall6X is like syscall6 but expects a 64-bit result 496 // and tests for 64-bit -1 to decide there was an error. 497 TEXT runtime·syscall6X(SB),NOSPLIT,$0 498 MOVD R0, R19 // pointer to args 499 500 MOVD (0*8)(R19), R11 // fn 501 MOVD (1*8)(R19), R0 // a1 502 MOVD (2*8)(R19), R1 // a2 503 MOVD (3*8)(R19), R2 // a3 504 MOVD (4*8)(R19), R3 // a4 505 MOVD (5*8)(R19), R4 // a5 506 MOVD (6*8)(R19), R5 // a6 507 MOVD $0, R6 // vararg 508 509 CALL R11 510 511 MOVD R0, (7*8)(R19) // r1 512 MOVD R1, (8*8)(R19) // r2 513 514 // Standard libc functions return -1 on error 515 // and set errno. 516 CMP $-1, R0 517 BNE ok 518 519 // Get error code from libc. 520 CALL libc_errno(SB) 521 MOVW (R0), R0 522 MOVD R0, (9*8)(R19) // err 523 524 ok: 525 RET 526 527 // syscall10 calls a function in libc on behalf of the syscall package. 528 // syscall10 takes a pointer to a struct like: 529 // struct { 530 // fn uintptr 531 // a1 uintptr 532 // a2 uintptr 533 // a3 uintptr 534 // a4 uintptr 535 // a5 uintptr 536 // a6 uintptr 537 // a7 uintptr 538 // a8 uintptr 539 // a9 uintptr 540 // a10 uintptr 541 // r1 uintptr 542 // r2 uintptr 543 // err uintptr 544 // } 545 // syscall10 must be called on the g0 stack with the 546 // C calling convention (use libcCall). 547 TEXT runtime·syscall10(SB),NOSPLIT,$0 548 MOVD R0, R19 // pointer to args 549 550 MOVD (0*8)(R19), R11 // fn 551 MOVD (1*8)(R19), R0 // a1 552 MOVD (2*8)(R19), R1 // a2 553 MOVD (3*8)(R19), R2 // a3 554 MOVD (4*8)(R19), R3 // a4 555 MOVD (5*8)(R19), R4 // a5 556 MOVD (6*8)(R19), R5 // a6 557 MOVD (7*8)(R19), R6 // a7 558 MOVD (8*8)(R19), R7 // a8 559 MOVD (9*8)(R19), R8 // a9 560 MOVD (10*8)(R19), R9 // a10 561 MOVD $0, R10 // vararg 562 563 CALL R11 564 565 MOVD R0, (11*8)(R19) // r1 566 MOVD R1, (12*8)(R19) // r2 567 568 // Standard libc functions return -1 on error 569 // and set errno. 570 CMPW $-1, R0 571 BNE ok 572 573 // Get error code from libc. 574 CALL libc_errno(SB) 575 MOVW (R0), R0 576 MOVD R0, (13*8)(R19) // err 577 578 ok: 579 RET 580 581 // syscall10X calls a function in libc on behalf of the syscall package. 582 // syscall10X takes a pointer to a struct like: 583 // struct { 584 // fn uintptr 585 // a1 uintptr 586 // a2 uintptr 587 // a3 uintptr 588 // a4 uintptr 589 // a5 uintptr 590 // a6 uintptr 591 // a7 uintptr 592 // a8 uintptr 593 // a9 uintptr 594 // a10 uintptr 595 // r1 uintptr 596 // r2 uintptr 597 // err uintptr 598 // } 599 // syscall10X must be called on the g0 stack with the 600 // C calling convention (use libcCall). 601 // 602 // syscall10X is like syscall10 but expects a 64-bit result 603 // and tests for 64-bit -1 to decide there was an error. 604 TEXT runtime·syscall10X(SB),NOSPLIT,$0 605 MOVD R0, R19 // pointer to args 606 607 MOVD (0*8)(R19), R11 // fn 608 MOVD (1*8)(R19), R0 // a1 609 MOVD (2*8)(R19), R1 // a2 610 MOVD (3*8)(R19), R2 // a3 611 MOVD (4*8)(R19), R3 // a4 612 MOVD (5*8)(R19), R4 // a5 613 MOVD (6*8)(R19), R5 // a6 614 MOVD (7*8)(R19), R6 // a7 615 MOVD (8*8)(R19), R7 // a8 616 MOVD (9*8)(R19), R8 // a9 617 MOVD (10*8)(R19), R9 // a10 618 MOVD $0, R10 // vararg 619 620 CALL R11 621 622 MOVD R0, (11*8)(R19) // r1 623 MOVD R1, (12*8)(R19) // r2 624 625 // Standard libc functions return -1 on error 626 // and set errno. 627 CMP $-1, R0 628 BNE ok 629 630 // Get error code from libc. 631 CALL libc_errno(SB) 632 MOVW (R0), R0 633 MOVD R0, (13*8)(R19) // err 634 635 ok: 636 RET