Text file
src/runtime/sys_openbsd_arm64.s
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
642
View as plain text