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 // 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
653
View as plain text