Text file
src/runtime/sys_darwin_arm64.s
1 // Copyright 2015 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, Darwin
6 // System calls are implemented in libSystem, this file contains
7 // trampolines that convert from Go to C calling convention.
8
9 #include "go_asm.h"
10 #include "go_tls.h"
11 #include "textflag.h"
12 #include "cgo/abi_arm64.h"
13
14 #define CLOCK_REALTIME 0
15
16 TEXT notok<>(SB),NOSPLIT,$0
17 MOVD $0, R8
18 MOVD R8, (R8)
19 B 0(PC)
20
21 TEXT runtime·open_trampoline(SB),NOSPLIT,$0
22 SUB $16, RSP
23 MOVW 8(R0), R1 // arg 2 flags
24 MOVW 12(R0), R2 // arg 3 mode
25 MOVW R2, (RSP) // arg 3 is variadic, pass on stack
26 MOVD 0(R0), R0 // arg 1 pathname
27 BL libc_open(SB)
28 ADD $16, RSP
29 RET
30
31 TEXT runtime·close_trampoline(SB),NOSPLIT,$0
32 MOVW 0(R0), R0 // arg 1 fd
33 BL libc_close(SB)
34 RET
35
36 TEXT runtime·write_trampoline(SB),NOSPLIT,$0
37 MOVD 8(R0), R1 // arg 2 buf
38 MOVW 16(R0), R2 // arg 3 count
39 MOVW 0(R0), R0 // arg 1 fd
40 BL libc_write(SB)
41 MOVD $-1, R1
42 CMP R0, R1
43 BNE noerr
44 BL libc_error(SB)
45 MOVW (R0), R0
46 NEG R0, R0 // caller expects negative errno value
47 noerr:
48 RET
49
50 TEXT runtime·read_trampoline(SB),NOSPLIT,$0
51 MOVD 8(R0), R1 // arg 2 buf
52 MOVW 16(R0), R2 // arg 3 count
53 MOVW 0(R0), R0 // arg 1 fd
54 BL libc_read(SB)
55 MOVD $-1, R1
56 CMP R0, R1
57 BNE noerr
58 BL libc_error(SB)
59 MOVW (R0), R0
60 NEG R0, R0 // caller expects negative errno value
61 noerr:
62 RET
63
64 TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0
65 BL libc_pipe(SB) // pointer already in R0
66 CMP $0, R0
67 BEQ 3(PC)
68 BL libc_error(SB) // return negative errno value
69 NEG R0, R0
70 RET
71
72 TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0
73 MOVW 0(R0), R0
74 BL libc_exit(SB)
75 MOVD $1234, R0
76 MOVD $1002, R1
77 MOVD R0, (R1) // fail hard
78
79 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
80 MOVD 0(R0), R19 // signal
81 BL libc_getpid(SB)
82 // arg 1 pid already in R0 from getpid
83 MOVD R19, R1 // arg 2 signal
84 BL libc_kill(SB)
85 RET
86
87 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
88 MOVD R0, R19
89 MOVD 0(R19), R0 // arg 1 addr
90 MOVD 8(R19), R1 // arg 2 len
91 MOVW 16(R19), R2 // arg 3 prot
92 MOVW 20(R19), R3 // arg 4 flags
93 MOVW 24(R19), R4 // arg 5 fd
94 MOVW 28(R19), R5 // arg 6 off
95 BL libc_mmap(SB)
96 MOVD $0, R1
97 MOVD $-1, R2
98 CMP R0, R2
99 BNE ok
100 BL libc_error(SB)
101 MOVW (R0), R1
102 MOVD $0, R0
103 ok:
104 MOVD R0, 32(R19) // ret 1 p
105 MOVD R1, 40(R19) // ret 2 err
106 RET
107
108 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
109 MOVD 8(R0), R1 // arg 2 len
110 MOVD 0(R0), R0 // arg 1 addr
111 BL libc_munmap(SB)
112 CMP $0, R0
113 BEQ 2(PC)
114 BL notok<>(SB)
115 RET
116
117 TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0
118 MOVD 8(R0), R1 // arg 2 len
119 MOVW 16(R0), R2 // arg 3 advice
120 MOVD 0(R0), R0 // arg 1 addr
121 BL libc_madvise(SB)
122 RET
123
124 TEXT runtime·mlock_trampoline(SB),NOSPLIT,$0
125 MOVD 8(R0), R1 // arg 2 len
126 MOVD 0(R0), R0 // arg 1 addr
127 BL libc_mlock(SB)
128 RET
129
130 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
131 MOVD 8(R0), R1 // arg 2 new
132 MOVD 16(R0), R2 // arg 3 old
133 MOVW 0(R0), R0 // arg 1 which
134 BL libc_setitimer(SB)
135 RET
136
137 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
138 MOVD R0, R1 // arg 2 timespec
139 MOVW $CLOCK_REALTIME, R0 // arg 1 clock_id
140 BL libc_clock_gettime(SB)
141 RET
142
143 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
144
145 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40
146 MOVD R0, R19
147 BL libc_mach_absolute_time(SB)
148 MOVD R0, 0(R19)
149 MOVW timebase<>+machTimebaseInfo_numer(SB), R20
150 MOVD $timebase<>+machTimebaseInfo_denom(SB), R21
151 LDARW (R21), R21 // atomic read
152 CMP $0, R21
153 BNE initialized
154
155 SUB $(machTimebaseInfo__size+15)/16*16, RSP
156 MOVD RSP, R0
157 BL libc_mach_timebase_info(SB)
158 MOVW machTimebaseInfo_numer(RSP), R20
159 MOVW machTimebaseInfo_denom(RSP), R21
160 ADD $(machTimebaseInfo__size+15)/16*16, RSP
161
162 MOVW R20, timebase<>+machTimebaseInfo_numer(SB)
163 MOVD $timebase<>+machTimebaseInfo_denom(SB), R22
164 STLRW R21, (R22) // atomic write
165
166 initialized:
167 MOVW R20, 8(R19)
168 MOVW R21, 12(R19)
169 RET
170
171 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
172 MOVW sig+8(FP), R0
173 MOVD info+16(FP), R1
174 MOVD ctx+24(FP), R2
175 MOVD fn+0(FP), R11
176 BL (R11)
177 RET
178
179 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$176
180 // Save callee-save registers in the case of signal forwarding.
181 // Please refer to https://golang.org/issue/31827 .
182 SAVE_R19_TO_R28(8*4)
183 SAVE_F8_TO_F15(8*14)
184
185 // Save arguments.
186 MOVW R0, (8*1)(RSP) // sig
187 MOVD R1, (8*2)(RSP) // info
188 MOVD R2, (8*3)(RSP) // ctx
189
190 // this might be called in external code context,
191 // where g is not set.
192 BL runtime·load_g(SB)
193
194 #ifdef GOOS_ios
195 MOVD RSP, R6
196 CMP $0, g
197 BEQ nog
198 // iOS always use the main stack to run the signal handler.
199 // We need to switch to gsignal ourselves.
200 MOVD g_m(g), R11
201 MOVD m_gsignal(R11), R5
202 MOVD (g_stack+stack_hi)(R5), R6
203
204 nog:
205 // Restore arguments.
206 MOVW (8*1)(RSP), R0
207 MOVD (8*2)(RSP), R1
208 MOVD (8*3)(RSP), R2
209
210 // Reserve space for args and the stack pointer on the
211 // gsignal stack.
212 SUB $48, R6
213 // Save stack pointer.
214 MOVD RSP, R4
215 MOVD R4, (8*4)(R6)
216 // Switch to gsignal stack.
217 MOVD R6, RSP
218
219 // Save arguments.
220 MOVW R0, (8*1)(RSP)
221 MOVD R1, (8*2)(RSP)
222 MOVD R2, (8*3)(RSP)
223 #endif
224
225 // Call sigtrampgo.
226 MOVD $runtime·sigtrampgo(SB), R11
227 BL (R11)
228
229 #ifdef GOOS_ios
230 // Switch to old stack.
231 MOVD (8*4)(RSP), R5
232 MOVD R5, RSP
233 #endif
234
235 // Restore callee-save registers.
236 RESTORE_R19_TO_R28(8*4)
237 RESTORE_F8_TO_F15(8*14)
238
239 RET
240
241 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
242 JMP runtime·sigtramp(SB)
243
244 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
245 MOVD 8(R0), R1 // arg 2 new
246 MOVD 16(R0), R2 // arg 3 old
247 MOVW 0(R0), R0 // arg 1 how
248 BL libc_pthread_sigmask(SB)
249 CMP $0, R0
250 BEQ 2(PC)
251 BL notok<>(SB)
252 RET
253
254 TEXT runtime·sigaction_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 how
258 BL libc_sigaction(SB)
259 CMP $0, R0
260 BEQ 2(PC)
261 BL notok<>(SB)
262 RET
263
264 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
265 MOVW 0(R0), R0 // arg 1 usec
266 BL libc_usleep(SB)
267 RET
268
269 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
270 MOVW 8(R0), R1 // arg 2 miblen
271 MOVD 16(R0), R2 // arg 3 oldp
272 MOVD 24(R0), R3 // arg 4 oldlenp
273 MOVD 32(R0), R4 // arg 5 newp
274 MOVD 40(R0), R5 // arg 6 newlen
275 MOVD 0(R0), R0 // arg 1 mib
276 BL libc_sysctl(SB)
277 RET
278
279 TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0
280 MOVD 8(R0), R1 // arg 2 oldp
281 MOVD 16(R0), R2 // arg 3 oldlenp
282 MOVD 24(R0), R3 // arg 4 newp
283 MOVD 32(R0), R4 // arg 5 newlen
284 MOVD 0(R0), R0 // arg 1 name
285 BL libc_sysctlbyname(SB)
286 RET
287
288
289 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
290 BL libc_kqueue(SB)
291 RET
292
293 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
294 MOVD 8(R0), R1 // arg 2 keventt
295 MOVW 16(R0), R2 // arg 3 nch
296 MOVD 24(R0), R3 // arg 4 ev
297 MOVW 32(R0), R4 // arg 5 nev
298 MOVD 40(R0), R5 // arg 6 ts
299 MOVW 0(R0), R0 // arg 1 kq
300 BL libc_kevent(SB)
301 MOVD $-1, R2
302 CMP R0, R2
303 BNE ok
304 BL libc_error(SB)
305 MOVW (R0), R0 // errno
306 NEG R0, R0 // caller wants it as a negative error code
307 ok:
308 RET
309
310 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
311 SUB $16, RSP
312 MOVD R0, R19
313 MOVW 0(R19), R0 // arg 1 fd
314 MOVW 4(R19), R1 // arg 2 cmd
315 MOVW 8(R19), R2 // arg 3 arg
316 MOVW R2, (RSP) // arg 3 is variadic, pass on stack
317 BL libc_fcntl(SB)
318 MOVD $0, R1
319 MOVD $-1, R2
320 CMP R0, R2
321 BNE noerr
322 BL libc_error(SB)
323 MOVW (R0), R1
324 MOVW $-1, R0
325 noerr:
326 MOVW R0, 12(R19)
327 MOVW R1, 16(R19)
328 ADD $16, RSP
329 RET
330
331 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
332 #ifdef GOOS_ios
333 // sigaltstack on iOS is not supported and will always
334 // run the signal handler on the main stack, so our sigtramp has
335 // to do the stack switch ourselves.
336 MOVW $43, R0
337 BL libc_exit(SB)
338 #else
339 MOVD 8(R0), R1 // arg 2 old
340 MOVD 0(R0), R0 // arg 1 new
341 CALL libc_sigaltstack(SB)
342 CBZ R0, 2(PC)
343 BL notok<>(SB)
344 #endif
345 RET
346
347 // Thread related functions
348
349 // mstart_stub is the first function executed on a new thread started by pthread_create.
350 // It just does some low-level setup and then calls mstart.
351 // Note: called with the C calling convention.
352 TEXT runtime·mstart_stub(SB),NOSPLIT,$160
353 // R0 points to the m.
354 // We are already on m's g0 stack.
355
356 // Save callee-save registers.
357 SAVE_R19_TO_R28(8)
358 SAVE_F8_TO_F15(88)
359
360 MOVD m_g0(R0), g
361 BL ·save_g(SB)
362
363 BL runtime·mstart(SB)
364
365 // Restore callee-save registers.
366 RESTORE_R19_TO_R28(8)
367 RESTORE_F8_TO_F15(88)
368
369 // Go is all done with this OS thread.
370 // Tell pthread everything is ok (we never join with this thread, so
371 // the value here doesn't really matter).
372 MOVD $0, R0
373
374 RET
375
376 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
377 MOVD 0(R0), R0 // arg 1 attr
378 BL libc_pthread_attr_init(SB)
379 RET
380
381 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
382 MOVD 8(R0), R1 // arg 2 size
383 MOVD 0(R0), R0 // arg 1 attr
384 BL libc_pthread_attr_getstacksize(SB)
385 RET
386
387 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
388 MOVD 8(R0), R1 // arg 2 state
389 MOVD 0(R0), R0 // arg 1 attr
390 BL libc_pthread_attr_setdetachstate(SB)
391 RET
392
393 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
394 SUB $16, RSP
395 MOVD 0(R0), R1 // arg 2 state
396 MOVD 8(R0), R2 // arg 3 start
397 MOVD 16(R0), R3 // arg 4 arg
398 MOVD RSP, R0 // arg 1 &threadid (which we throw away)
399 BL libc_pthread_create(SB)
400 ADD $16, RSP
401 RET
402
403 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
404 MOVW 0(R0), R0 // arg 1 sig
405 BL libc_raise(SB)
406 RET
407
408 TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
409 MOVD 8(R0), R1 // arg 2 attr
410 MOVD 0(R0), R0 // arg 1 mutex
411 BL libc_pthread_mutex_init(SB)
412 RET
413
414 TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
415 MOVD 0(R0), R0 // arg 1 mutex
416 BL libc_pthread_mutex_lock(SB)
417 RET
418
419 TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
420 MOVD 0(R0), R0 // arg 1 mutex
421 BL libc_pthread_mutex_unlock(SB)
422 RET
423
424 TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
425 MOVD 8(R0), R1 // arg 2 attr
426 MOVD 0(R0), R0 // arg 1 cond
427 BL libc_pthread_cond_init(SB)
428 RET
429
430 TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
431 MOVD 8(R0), R1 // arg 2 mutex
432 MOVD 0(R0), R0 // arg 1 cond
433 BL libc_pthread_cond_wait(SB)
434 RET
435
436 TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
437 MOVD 8(R0), R1 // arg 2 mutex
438 MOVD 16(R0), R2 // arg 3 timeout
439 MOVD 0(R0), R0 // arg 1 cond
440 BL libc_pthread_cond_timedwait_relative_np(SB)
441 RET
442
443 TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
444 MOVD 0(R0), R0 // arg 1 cond
445 BL libc_pthread_cond_signal(SB)
446 RET
447
448 TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
449 MOVD R0, R19 // R19 is callee-save
450 BL libc_pthread_self(SB)
451 MOVD R0, 0(R19) // return value
452 RET
453
454 TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
455 MOVD 8(R0), R1 // arg 2 sig
456 MOVD 0(R0), R0 // arg 1 thread
457 BL libc_pthread_kill(SB)
458 RET
459
460 TEXT runtime·pthread_key_create_trampoline(SB),NOSPLIT,$0
461 MOVD 8(R0), R1 // arg 2 destructor
462 MOVD 0(R0), R0 // arg 1 *key
463 BL libc_pthread_key_create(SB)
464 RET
465
466 TEXT runtime·pthread_setspecific_trampoline(SB),NOSPLIT,$0
467 MOVD 8(R0), R1 // arg 2 value
468 MOVD 0(R0), R0 // arg 1 key
469 BL libc_pthread_setspecific(SB)
470 RET
471
472 TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
473 MOVD $0, R0 // arg 1 val
474 BL libc_notify_is_valid_token(SB)
475 BL libc_xpc_date_create_from_current(SB)
476 RET
477
478 TEXT runtime·arc4random_buf_trampoline(SB),NOSPLIT,$0
479 MOVW 8(R0), R1 // arg 2 nbytes
480 MOVD 0(R0), R0 // arg 1 buf
481 BL libc_arc4random_buf(SB)
482 RET
483
484 // syscall calls a function in libc on behalf of the syscall package.
485 // syscall takes a pointer to a struct like:
486 // struct {
487 // fn uintptr
488 // a1 uintptr
489 // a2 uintptr
490 // a3 uintptr
491 // r1 uintptr
492 // r2 uintptr
493 // err uintptr
494 // }
495 // syscall must be called on the g0 stack with the
496 // C calling convention (use libcCall).
497 TEXT runtime·syscall(SB),NOSPLIT,$0
498 SUB $16, RSP // push structure pointer
499 MOVD R0, 8(RSP)
500
501 MOVD 0(R0), R12 // fn
502 MOVD 16(R0), R1 // a2
503 MOVD 24(R0), R2 // a3
504 MOVD 8(R0), R0 // a1
505
506 // If fn is declared as vararg, we have to pass the vararg arguments on the stack.
507 // (Because ios decided not to adhere to the standard arm64 calling convention, sigh...)
508 // The only libSystem calls we support that are vararg are open, fcntl, and ioctl,
509 // which are all of the form fn(x, y, ...). So we just need to put the 3rd arg
510 // on the stack as well.
511 // If we ever have other vararg libSystem calls, we might need to handle more cases.
512 MOVD R2, (RSP)
513
514 BL (R12)
515
516 MOVD 8(RSP), R2 // pop structure pointer
517 ADD $16, RSP
518 MOVD R0, 32(R2) // save r1
519 MOVD R1, 40(R2) // save r2
520 CMPW $-1, R0
521 BNE ok
522 SUB $16, RSP // push structure pointer
523 MOVD R2, 8(RSP)
524 BL libc_error(SB)
525 MOVW (R0), R0
526 MOVD 8(RSP), R2 // pop structure pointer
527 ADD $16, RSP
528 MOVD R0, 48(R2) // save err
529 ok:
530 RET
531
532 // syscallX calls a function in libc on behalf of the syscall package.
533 // syscallX takes a pointer to a struct like:
534 // struct {
535 // fn uintptr
536 // a1 uintptr
537 // a2 uintptr
538 // a3 uintptr
539 // r1 uintptr
540 // r2 uintptr
541 // err uintptr
542 // }
543 // syscallX must be called on the g0 stack with the
544 // C calling convention (use libcCall).
545 TEXT runtime·syscallX(SB),NOSPLIT,$0
546 SUB $16, RSP // push structure pointer
547 MOVD R0, (RSP)
548
549 MOVD 0(R0), R12 // fn
550 MOVD 16(R0), R1 // a2
551 MOVD 24(R0), R2 // a3
552 MOVD 8(R0), R0 // a1
553 BL (R12)
554
555 MOVD (RSP), R2 // pop structure pointer
556 ADD $16, RSP
557 MOVD R0, 32(R2) // save r1
558 MOVD R1, 40(R2) // save r2
559 CMP $-1, R0
560 BNE ok
561 SUB $16, RSP // push structure pointer
562 MOVD R2, (RSP)
563 BL libc_error(SB)
564 MOVW (R0), R0
565 MOVD (RSP), R2 // pop structure pointer
566 ADD $16, RSP
567 MOVD R0, 48(R2) // save err
568 ok:
569 RET
570
571 // syscallPtr is like syscallX except that the libc function reports an
572 // error by returning NULL and setting errno.
573 TEXT runtime·syscallPtr(SB),NOSPLIT,$0
574 SUB $16, RSP // push structure pointer
575 MOVD R0, (RSP)
576
577 MOVD 0(R0), R12 // fn
578 MOVD 16(R0), R1 // a2
579 MOVD 24(R0), R2 // a3
580 MOVD 8(R0), R0 // a1
581 BL (R12)
582
583 MOVD (RSP), R2 // pop structure pointer
584 ADD $16, RSP
585 MOVD R0, 32(R2) // save r1
586 MOVD R1, 40(R2) // save r2
587 CMP $0, R0
588 BNE ok
589 SUB $16, RSP // push structure pointer
590 MOVD R2, (RSP)
591 BL libc_error(SB)
592 MOVW (R0), R0
593 MOVD (RSP), R2 // pop structure pointer
594 ADD $16, RSP
595 MOVD R0, 48(R2) // save err
596 ok:
597 RET
598
599 // syscall6 calls a function in libc on behalf of the syscall package.
600 // syscall6 takes a pointer to a struct like:
601 // struct {
602 // fn uintptr
603 // a1 uintptr
604 // a2 uintptr
605 // a3 uintptr
606 // a4 uintptr
607 // a5 uintptr
608 // a6 uintptr
609 // r1 uintptr
610 // r2 uintptr
611 // err uintptr
612 // }
613 // syscall6 must be called on the g0 stack with the
614 // C calling convention (use libcCall).
615 TEXT runtime·syscall6(SB),NOSPLIT,$0
616 SUB $16, RSP // push structure pointer
617 MOVD R0, 8(RSP)
618
619 MOVD 0(R0), R12 // fn
620 MOVD 16(R0), R1 // a2
621 MOVD 24(R0), R2 // a3
622 MOVD 32(R0), R3 // a4
623 MOVD 40(R0), R4 // a5
624 MOVD 48(R0), R5 // a6
625 MOVD 8(R0), R0 // a1
626
627 // If fn is declared as vararg, we have to pass the vararg arguments on the stack.
628 // See syscall above. The only function this applies to is openat, for which the 4th
629 // arg must be on the stack.
630 MOVD R3, (RSP)
631
632 BL (R12)
633
634 MOVD 8(RSP), R2 // pop structure pointer
635 ADD $16, RSP
636 MOVD R0, 56(R2) // save r1
637 MOVD R1, 64(R2) // save r2
638 CMPW $-1, R0
639 BNE ok
640 SUB $16, RSP // push structure pointer
641 MOVD R2, 8(RSP)
642 BL libc_error(SB)
643 MOVW (R0), R0
644 MOVD 8(RSP), R2 // pop structure pointer
645 ADD $16, RSP
646 MOVD R0, 72(R2) // save err
647 ok:
648 RET
649
650 // syscall6X calls a function in libc on behalf of the syscall package.
651 // syscall6X takes a pointer to a struct like:
652 // struct {
653 // fn uintptr
654 // a1 uintptr
655 // a2 uintptr
656 // a3 uintptr
657 // a4 uintptr
658 // a5 uintptr
659 // a6 uintptr
660 // r1 uintptr
661 // r2 uintptr
662 // err uintptr
663 // }
664 // syscall6X must be called on the g0 stack with the
665 // C calling convention (use libcCall).
666 TEXT runtime·syscall6X(SB),NOSPLIT,$0
667 SUB $16, RSP // push structure pointer
668 MOVD R0, (RSP)
669
670 MOVD 0(R0), R12 // fn
671 MOVD 16(R0), R1 // a2
672 MOVD 24(R0), R2 // a3
673 MOVD 32(R0), R3 // a4
674 MOVD 40(R0), R4 // a5
675 MOVD 48(R0), R5 // a6
676 MOVD 8(R0), R0 // a1
677 BL (R12)
678
679 MOVD (RSP), R2 // pop structure pointer
680 ADD $16, RSP
681 MOVD R0, 56(R2) // save r1
682 MOVD R1, 64(R2) // save r2
683 CMP $-1, R0
684 BNE ok
685 SUB $16, RSP // push structure pointer
686 MOVD R2, (RSP)
687 BL libc_error(SB)
688 MOVW (R0), R0
689 MOVD (RSP), R2 // pop structure pointer
690 ADD $16, RSP
691 MOVD R0, 72(R2) // save err
692 ok:
693 RET
694
695 // syscall9 calls a function in libc on behalf of the syscall package.
696 // syscall9 takes a pointer to a struct like:
697 // struct {
698 // fn uintptr
699 // a1 uintptr
700 // a2 uintptr
701 // a3 uintptr
702 // a4 uintptr
703 // a5 uintptr
704 // a6 uintptr
705 // a7 uintptr
706 // a8 uintptr
707 // a9 uintptr
708 // r1 uintptr
709 // r2 uintptr
710 // err uintptr
711 // }
712 // syscall9 must be called on the g0 stack with the
713 // C calling convention (use libcCall).
714 TEXT runtime·syscall9(SB),NOSPLIT,$0
715 SUB $16, RSP // push structure pointer
716 MOVD R0, 8(RSP)
717
718 MOVD 0(R0), R12 // fn
719 MOVD 16(R0), R1 // a2
720 MOVD 24(R0), R2 // a3
721 MOVD 32(R0), R3 // a4
722 MOVD 40(R0), R4 // a5
723 MOVD 48(R0), R5 // a6
724 MOVD 56(R0), R6 // a7
725 MOVD 64(R0), R7 // a8
726 MOVD 72(R0), R8 // a9
727 MOVD 8(R0), R0 // a1
728
729 // If fn is declared as vararg, we have to pass the vararg arguments on the stack.
730 // See syscall above. The only function this applies to is openat, for which the 4th
731 // arg must be on the stack.
732 MOVD R3, (RSP)
733
734 BL (R12)
735
736 MOVD 8(RSP), R2 // pop structure pointer
737 ADD $16, RSP
738 MOVD R0, 80(R2) // save r1
739 MOVD R1, 88(R2) // save r2
740 CMPW $-1, R0
741 BNE ok
742 SUB $16, RSP // push structure pointer
743 MOVD R2, 8(RSP)
744 BL libc_error(SB)
745 MOVW (R0), R0
746 MOVD 8(RSP), R2 // pop structure pointer
747 ADD $16, RSP
748 MOVD R0, 96(R2) // save err
749 ok:
750 RET
751
752 // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
753 // takes 5 uintptrs and 1 float64, and only returns one value,
754 // for use with standard C ABI functions.
755 TEXT runtime·syscall_x509(SB),NOSPLIT,$0
756 SUB $16, RSP // push structure pointer
757 MOVD R0, (RSP)
758
759 MOVD 0(R0), R12 // fn
760 MOVD 16(R0), R1 // a2
761 MOVD 24(R0), R2 // a3
762 MOVD 32(R0), R3 // a4
763 MOVD 40(R0), R4 // a5
764 FMOVD 48(R0), F0 // f1
765 MOVD 8(R0), R0 // a1
766 BL (R12)
767
768 MOVD (RSP), R2 // pop structure pointer
769 ADD $16, RSP
770 MOVD R0, 56(R2) // save r1
771 RET
772
773 TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
774 BL libc_issetugid(SB)
775 RET
776
777 // mach_vm_region_trampoline calls mach_vm_region from libc.
778 TEXT runtime·mach_vm_region_trampoline(SB),NOSPLIT,$0
779 MOVD 0(R0), R1 // address
780 MOVD 8(R0), R2 // size
781 MOVW 16(R0), R3 // flavor
782 MOVD 24(R0), R4 // info
783 MOVD 32(R0), R5 // count
784 MOVD 40(R0), R6 // object_name
785 MOVD $libc_mach_task_self_(SB), R0
786 MOVW 0(R0), R0
787 BL libc_mach_vm_region(SB)
788 RET
789
790 // proc_regionfilename_trampoline calls proc_regionfilename for
791 // the current process.
792 TEXT runtime·proc_regionfilename_trampoline(SB),NOSPLIT,$0
793 MOVD 8(R0), R1 // address
794 MOVD 16(R0), R2 // buffer
795 MOVD 24(R0), R3 // buffer_size
796 MOVD 0(R0), R0 // pid
797 BL libc_proc_regionfilename(SB)
798 RET
799
View as plain text