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