Text file
src/runtime/sys_openbsd_arm64.s
Documentation: runtime
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.
22TEXT 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
46TEXT 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
54TEXT 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.)
82TEXT 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
87TEXT 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
92TEXT 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
98TEXT 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
104TEXT 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
114TEXT 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
121TEXT 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
130TEXT 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
136TEXT 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
143TEXT 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
149TEXT 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
156TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
157 CALL libc_sched_yield(SB)
158 RET
159
160TEXT 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
175noerr:
176 MOVD R0, 32(R19)
177 MOVD R1, 40(R19)
178 RET
179
180TEXT 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
190TEXT 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
198TEXT 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
206TEXT runtime·close_trampoline(SB),NOSPLIT,$0
207 MOVD 0(R0), R0 // arg 1 - fd
208 CALL libc_close(SB)
209 RET
210
211TEXT 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
221noerr:
222 RET
223
224TEXT 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
234noerr:
235 RET
236
237TEXT 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
246noerr:
247 RET
248
249TEXT 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
256TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
257 MOVD 0(R0), R0 // arg 1 - usec
258 CALL libc_usleep(SB)
259 RET
260
261TEXT 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
271TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
272 CALL libc_kqueue(SB)
273 RET
274
275TEXT 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
288noerr:
289 RET
290
291TEXT 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
300noerr:
301 RET
302
303TEXT 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
316noerr:
317 MOVW R0, 12(R19)
318 MOVW R1, 16(R19)
319 RET
320
321TEXT 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
332TEXT 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
343TEXT 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.
369TEXT 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
393ok:
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.
412TEXT 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
436ok:
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.
458TEXT 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
485ok:
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.
507TEXT 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
534ok:
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).
557TEXT 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
588ok:
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.
614TEXT 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
645ok:
646 RET
647
648TEXT 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
View as plain text