Text file
src/runtime/sys_darwin_amd64.s
Documentation: runtime
1// Copyright 2009 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 AMD64, 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_amd64.h"
13
14#define CLOCK_REALTIME 0
15
16// Exit the entire program (like C exit)
17TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
18 MOVL 0(DI), DI // arg 1 exit status
19 CALL libc_exit(SB)
20 MOVL $0xf1, 0xf1 // crash
21 RET
22
23TEXT runtime·open_trampoline(SB),NOSPLIT,$0
24 MOVL 8(DI), SI // arg 2 flags
25 MOVL 12(DI), DX // arg 3 mode
26 MOVQ 0(DI), DI // arg 1 pathname
27 XORL AX, AX // vararg: say "no float args"
28 CALL libc_open(SB)
29 RET
30
31TEXT runtime·close_trampoline(SB),NOSPLIT,$0
32 MOVL 0(DI), DI // arg 1 fd
33 CALL libc_close(SB)
34 RET
35
36TEXT runtime·read_trampoline(SB),NOSPLIT,$0
37 MOVQ 8(DI), SI // arg 2 buf
38 MOVL 16(DI), DX // arg 3 count
39 MOVL 0(DI), DI // arg 1 fd
40 CALL libc_read(SB)
41 TESTL AX, AX
42 JGE noerr
43 CALL libc_error(SB)
44 MOVL (AX), AX
45 NEGL AX // caller expects negative errno value
46noerr:
47 RET
48
49TEXT runtime·write_trampoline(SB),NOSPLIT,$0
50 MOVQ 8(DI), SI // arg 2 buf
51 MOVL 16(DI), DX // arg 3 count
52 MOVQ 0(DI), DI // arg 1 fd
53 CALL libc_write(SB)
54 TESTL AX, AX
55 JGE noerr
56 CALL libc_error(SB)
57 MOVL (AX), AX
58 NEGL AX // caller expects negative errno value
59noerr:
60 RET
61
62TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0
63 CALL libc_pipe(SB) // pointer already in DI
64 TESTL AX, AX
65 JEQ 3(PC)
66 CALL libc_error(SB) // return negative errno value
67 NEGL AX
68 RET
69
70TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
71 MOVQ 8(DI), SI // arg 2 new
72 MOVQ 16(DI), DX // arg 3 old
73 MOVL 0(DI), DI // arg 1 which
74 CALL libc_setitimer(SB)
75 RET
76
77TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
78 MOVQ 8(DI), SI // arg 2 len
79 MOVL 16(DI), DX // arg 3 advice
80 MOVQ 0(DI), DI // arg 1 addr
81 CALL libc_madvise(SB)
82 // ignore failure - maybe pages are locked
83 RET
84
85TEXT runtime·mlock_trampoline(SB), NOSPLIT, $0
86 UNDEF // unimplemented
87
88GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
89
90TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
91 MOVQ DI, BX
92 CALL libc_mach_absolute_time(SB)
93 MOVQ AX, 0(BX)
94 MOVL timebase<>+machTimebaseInfo_numer(SB), SI
95 MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
96 TESTL DI, DI
97 JNE initialized
98
99 SUBQ $(machTimebaseInfo__size+15)/16*16, SP
100 MOVQ SP, DI
101 CALL libc_mach_timebase_info(SB)
102 MOVL machTimebaseInfo_numer(SP), SI
103 MOVL machTimebaseInfo_denom(SP), DI
104 ADDQ $(machTimebaseInfo__size+15)/16*16, SP
105
106 MOVL SI, timebase<>+machTimebaseInfo_numer(SB)
107 MOVL DI, AX
108 XCHGL AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write
109
110initialized:
111 MOVL SI, 8(BX)
112 MOVL DI, 12(BX)
113 RET
114
115TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
116 MOVQ DI, SI // arg 2 timespec
117 MOVL $CLOCK_REALTIME, DI // arg 1 clock_id
118 CALL libc_clock_gettime(SB)
119 RET
120
121TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
122 MOVQ 8(DI), SI // arg 2 new
123 MOVQ 16(DI), DX // arg 3 old
124 MOVL 0(DI), DI // arg 1 sig
125 CALL libc_sigaction(SB)
126 TESTL AX, AX
127 JEQ 2(PC)
128 MOVL $0xf1, 0xf1 // crash
129 RET
130
131TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
132 MOVQ 8(DI), SI // arg 2 new
133 MOVQ 16(DI), DX // arg 3 old
134 MOVL 0(DI), DI // arg 1 how
135 CALL libc_pthread_sigmask(SB)
136 TESTL AX, AX
137 JEQ 2(PC)
138 MOVL $0xf1, 0xf1 // crash
139 RET
140
141TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
142 MOVQ 8(DI), SI // arg 2 old
143 MOVQ 0(DI), DI // arg 1 new
144 CALL libc_sigaltstack(SB)
145 TESTQ AX, AX
146 JEQ 2(PC)
147 MOVL $0xf1, 0xf1 // crash
148 RET
149
150TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
151 MOVL 0(DI), BX // signal
152 CALL libc_getpid(SB)
153 MOVL AX, DI // arg 1 pid
154 MOVL BX, SI // arg 2 signal
155 CALL libc_kill(SB)
156 RET
157
158TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
159 MOVQ fn+0(FP), AX
160 MOVL sig+8(FP), DI
161 MOVQ info+16(FP), SI
162 MOVQ ctx+24(FP), DX
163 MOVQ SP, BX // callee-saved
164 ANDQ $~15, SP // alignment for x86_64 ABI
165 CALL AX
166 MOVQ BX, SP
167 RET
168
169// This is the function registered during sigaction and is invoked when
170// a signal is received. It just redirects to the Go function sigtrampgo.
171// Called using C ABI.
172TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0
173 // Transition from C ABI to Go ABI.
174 PUSH_REGS_HOST_TO_ABI0()
175
176 // Set up ABIInternal environment: g in R14, cleared X15.
177 get_tls(R12)
178 MOVQ g(R12), R14
179 PXOR X15, X15
180
181 // Reserve space for spill slots.
182 NOP SP // disable vet stack checking
183 ADJSP $24
184
185 // Call into the Go signal handler
186 MOVQ DI, AX // sig
187 MOVQ SI, BX // info
188 MOVQ DX, CX // ctx
189 CALL ·sigtrampgo<ABIInternal>(SB)
190
191 ADJSP $-24
192
193 POP_REGS_HOST_TO_ABI0()
194 RET
195
196// Called using C ABI.
197TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT|NOFRAME,$0
198 // Transition from C ABI to Go ABI.
199 PUSH_REGS_HOST_TO_ABI0()
200
201 // Call into the Go signal handler
202 NOP SP // disable vet stack checking
203 ADJSP $24
204 MOVL DI, 0(SP) // sig
205 MOVQ SI, 8(SP) // info
206 MOVQ DX, 16(SP) // ctx
207 CALL ·sigprofNonGo(SB)
208 ADJSP $-24
209
210 POP_REGS_HOST_TO_ABI0()
211 RET
212
213// Used instead of sigtramp in programs that use cgo.
214// Arguments from kernel are in DI, SI, DX.
215TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
216 // If no traceback function, do usual sigtramp.
217 MOVQ runtime·cgoTraceback(SB), AX
218 TESTQ AX, AX
219 JZ sigtramp
220
221 // If no traceback support function, which means that
222 // runtime/cgo was not linked in, do usual sigtramp.
223 MOVQ _cgo_callers(SB), AX
224 TESTQ AX, AX
225 JZ sigtramp
226
227 // Figure out if we are currently in a cgo call.
228 // If not, just do usual sigtramp.
229 get_tls(CX)
230 MOVQ g(CX),AX
231 TESTQ AX, AX
232 JZ sigtrampnog // g == nil
233 MOVQ g_m(AX), AX
234 TESTQ AX, AX
235 JZ sigtramp // g.m == nil
236 MOVL m_ncgo(AX), CX
237 TESTL CX, CX
238 JZ sigtramp // g.m.ncgo == 0
239 MOVQ m_curg(AX), CX
240 TESTQ CX, CX
241 JZ sigtramp // g.m.curg == nil
242 MOVQ g_syscallsp(CX), CX
243 TESTQ CX, CX
244 JZ sigtramp // g.m.curg.syscallsp == 0
245 MOVQ m_cgoCallers(AX), R8
246 TESTQ R8, R8
247 JZ sigtramp // g.m.cgoCallers == nil
248 MOVL m_cgoCallersUse(AX), CX
249 TESTL CX, CX
250 JNZ sigtramp // g.m.cgoCallersUse != 0
251
252 // Jump to a function in runtime/cgo.
253 // That function, written in C, will call the user's traceback
254 // function with proper unwind info, and will then call back here.
255 // The first three arguments, and the fifth, are already in registers.
256 // Set the two remaining arguments now.
257 MOVQ runtime·cgoTraceback(SB), CX
258 MOVQ $runtime·sigtramp(SB), R9
259 MOVQ _cgo_callers(SB), AX
260 JMP AX
261
262sigtramp:
263 JMP runtime·sigtramp(SB)
264
265sigtrampnog:
266 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
267 // stack trace.
268 CMPL DI, $27 // 27 == SIGPROF
269 JNZ sigtramp
270
271 // Lock sigprofCallersUse.
272 MOVL $0, AX
273 MOVL $1, CX
274 MOVQ $runtime·sigprofCallersUse(SB), R11
275 LOCK
276 CMPXCHGL CX, 0(R11)
277 JNZ sigtramp // Skip stack trace if already locked.
278
279 // Jump to the traceback function in runtime/cgo.
280 // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
281 // the arguments to the Go calling convention.
282 // First three arguments to traceback function are in registers already.
283 MOVQ runtime·cgoTraceback(SB), CX
284 MOVQ $runtime·sigprofCallers(SB), R8
285 MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
286 MOVQ _cgo_callers(SB), AX
287 JMP AX
288
289TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
290 MOVQ DI, BX
291 MOVQ 0(BX), DI // arg 1 addr
292 MOVQ 8(BX), SI // arg 2 len
293 MOVL 16(BX), DX // arg 3 prot
294 MOVL 20(BX), CX // arg 4 flags
295 MOVL 24(BX), R8 // arg 5 fid
296 MOVL 28(BX), R9 // arg 6 offset
297 CALL libc_mmap(SB)
298 XORL DX, DX
299 CMPQ AX, $-1
300 JNE ok
301 CALL libc_error(SB)
302 MOVLQSX (AX), DX // errno
303 XORL AX, AX
304ok:
305 MOVQ AX, 32(BX)
306 MOVQ DX, 40(BX)
307 RET
308
309TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
310 MOVQ 8(DI), SI // arg 2 len
311 MOVQ 0(DI), DI // arg 1 addr
312 CALL libc_munmap(SB)
313 TESTQ AX, AX
314 JEQ 2(PC)
315 MOVL $0xf1, 0xf1 // crash
316 RET
317
318TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
319 MOVL 0(DI), DI // arg 1 usec
320 CALL libc_usleep(SB)
321 RET
322
323TEXT runtime·settls(SB),NOSPLIT,$32
324 // Nothing to do on Darwin, pthread already set thread-local storage up.
325 RET
326
327TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
328 MOVL 8(DI), SI // arg 2 miblen
329 MOVQ 16(DI), DX // arg 3 oldp
330 MOVQ 24(DI), CX // arg 4 oldlenp
331 MOVQ 32(DI), R8 // arg 5 newp
332 MOVQ 40(DI), R9 // arg 6 newlen
333 MOVQ 0(DI), DI // arg 1 mib
334 CALL libc_sysctl(SB)
335 RET
336
337TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0
338 MOVQ 8(DI), SI // arg 2 oldp
339 MOVQ 16(DI), DX // arg 3 oldlenp
340 MOVQ 24(DI), CX // arg 4 newp
341 MOVQ 32(DI), R8 // arg 5 newlen
342 MOVQ 0(DI), DI // arg 1 name
343 CALL libc_sysctlbyname(SB)
344 RET
345
346TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
347 CALL libc_kqueue(SB)
348 RET
349
350TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
351 MOVQ 8(DI), SI // arg 2 keventt
352 MOVL 16(DI), DX // arg 3 nch
353 MOVQ 24(DI), CX // arg 4 ev
354 MOVL 32(DI), R8 // arg 5 nev
355 MOVQ 40(DI), R9 // arg 6 ts
356 MOVL 0(DI), DI // arg 1 kq
357 CALL libc_kevent(SB)
358 CMPL AX, $-1
359 JNE ok
360 CALL libc_error(SB)
361 MOVLQSX (AX), AX // errno
362 NEGQ AX // caller wants it as a negative error code
363ok:
364 RET
365
366TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
367 MOVQ DI, BX
368 MOVL 0(BX), DI // arg 1 fd
369 MOVL 4(BX), SI // arg 2 cmd
370 MOVL 8(BX), DX // arg 3 arg
371 XORL AX, AX // vararg: say "no float args"
372 CALL libc_fcntl(SB)
373 XORL DX, DX
374 CMPQ AX, $-1
375 JNE noerr
376 CALL libc_error(SB)
377 MOVL (AX), DX
378 MOVL $-1, AX
379noerr:
380 MOVL AX, 12(BX)
381 MOVL DX, 16(BX)
382 RET
383
384// mstart_stub is the first function executed on a new thread started by pthread_create.
385// It just does some low-level setup and then calls mstart.
386// Note: called with the C calling convention.
387TEXT runtime·mstart_stub(SB),NOSPLIT|NOFRAME,$0
388 // DI points to the m.
389 // We are already on m's g0 stack.
390
391 // Transition from C ABI to Go ABI.
392 PUSH_REGS_HOST_TO_ABI0()
393
394 MOVQ m_g0(DI), DX // g
395
396 // Initialize TLS entry.
397 // See cmd/link/internal/ld/sym.go:computeTLSOffset.
398 MOVQ DX, 0x30(GS)
399
400 CALL runtime·mstart(SB)
401
402 POP_REGS_HOST_TO_ABI0()
403
404 // Go is all done with this OS thread.
405 // Tell pthread everything is ok (we never join with this thread, so
406 // the value here doesn't really matter).
407 XORL AX, AX
408 RET
409
410// These trampolines help convert from Go calling convention to C calling convention.
411// They should be called with asmcgocall.
412// A pointer to the arguments is passed in DI.
413// A single int32 result is returned in AX.
414// (For more results, make an args/results structure.)
415TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
416 MOVQ 0(DI), DI // arg 1 attr
417 CALL libc_pthread_attr_init(SB)
418 RET
419
420TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
421 MOVQ 8(DI), SI // arg 2 size
422 MOVQ 0(DI), DI // arg 1 attr
423 CALL libc_pthread_attr_getstacksize(SB)
424 RET
425
426TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
427 MOVQ 8(DI), SI // arg 2 state
428 MOVQ 0(DI), DI // arg 1 attr
429 CALL libc_pthread_attr_setdetachstate(SB)
430 RET
431
432TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$16
433 MOVQ 0(DI), SI // arg 2 attr
434 MOVQ 8(DI), DX // arg 3 start
435 MOVQ 16(DI), CX // arg 4 arg
436 MOVQ SP, DI // arg 1 &threadid (which we throw away)
437 CALL libc_pthread_create(SB)
438 RET
439
440TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
441 MOVL 0(DI), DI // arg 1 signal
442 CALL libc_raise(SB)
443 RET
444
445TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
446 MOVQ 8(DI), SI // arg 2 attr
447 MOVQ 0(DI), DI // arg 1 mutex
448 CALL libc_pthread_mutex_init(SB)
449 RET
450
451TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
452 MOVQ 0(DI), DI // arg 1 mutex
453 CALL libc_pthread_mutex_lock(SB)
454 RET
455
456TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
457 MOVQ 0(DI), DI // arg 1 mutex
458 CALL libc_pthread_mutex_unlock(SB)
459 RET
460
461TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
462 MOVQ 8(DI), SI // arg 2 attr
463 MOVQ 0(DI), DI // arg 1 cond
464 CALL libc_pthread_cond_init(SB)
465 RET
466
467TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
468 MOVQ 8(DI), SI // arg 2 mutex
469 MOVQ 0(DI), DI // arg 1 cond
470 CALL libc_pthread_cond_wait(SB)
471 RET
472
473TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
474 MOVQ 8(DI), SI // arg 2 mutex
475 MOVQ 16(DI), DX // arg 3 timeout
476 MOVQ 0(DI), DI // arg 1 cond
477 CALL libc_pthread_cond_timedwait_relative_np(SB)
478 RET
479
480TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
481 MOVQ 0(DI), DI // arg 1 cond
482 CALL libc_pthread_cond_signal(SB)
483 RET
484
485TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
486 MOVQ DI, BX // BX is caller-save
487 CALL libc_pthread_self(SB)
488 MOVQ AX, 0(BX) // return value
489 RET
490
491TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
492 MOVQ 8(DI), SI // arg 2 sig
493 MOVQ 0(DI), DI // arg 1 thread
494 CALL libc_pthread_kill(SB)
495 RET
496
497TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
498 MOVQ $0, DI // arg 1 val
499 CALL libc_notify_is_valid_token(SB)
500 CALL libc_xpc_date_create_from_current(SB)
501 RET
502
503// syscall calls a function in libc on behalf of the syscall package.
504// syscall takes a pointer to a struct like:
505// struct {
506// fn uintptr
507// a1 uintptr
508// a2 uintptr
509// a3 uintptr
510// r1 uintptr
511// r2 uintptr
512// err uintptr
513// }
514// syscall must be called on the g0 stack with the
515// C calling convention (use libcCall).
516//
517// syscall expects a 32-bit result and tests for 32-bit -1
518// to decide there was an error.
519TEXT runtime·syscall(SB),NOSPLIT,$16
520 MOVQ (0*8)(DI), CX // fn
521 MOVQ (2*8)(DI), SI // a2
522 MOVQ (3*8)(DI), DX // a3
523 MOVQ DI, (SP)
524 MOVQ (1*8)(DI), DI // a1
525 XORL AX, AX // vararg: say "no float args"
526
527 CALL CX
528
529 MOVQ (SP), DI
530 MOVQ AX, (4*8)(DI) // r1
531 MOVQ DX, (5*8)(DI) // r2
532
533 // Standard libc functions return -1 on error
534 // and set errno.
535 CMPL AX, $-1 // Note: high 32 bits are junk
536 JNE ok
537
538 // Get error code from libc.
539 CALL libc_error(SB)
540 MOVLQSX (AX), AX
541 MOVQ (SP), DI
542 MOVQ AX, (6*8)(DI) // err
543
544ok:
545 XORL AX, AX // no error (it's ignored anyway)
546 RET
547
548// syscallX calls a function in libc on behalf of the syscall package.
549// syscallX takes a pointer to a struct like:
550// struct {
551// fn uintptr
552// a1 uintptr
553// a2 uintptr
554// a3 uintptr
555// r1 uintptr
556// r2 uintptr
557// err uintptr
558// }
559// syscallX must be called on the g0 stack with the
560// C calling convention (use libcCall).
561//
562// syscallX is like syscall but expects a 64-bit result
563// and tests for 64-bit -1 to decide there was an error.
564TEXT runtime·syscallX(SB),NOSPLIT,$16
565 MOVQ (0*8)(DI), CX // fn
566 MOVQ (2*8)(DI), SI // a2
567 MOVQ (3*8)(DI), DX // a3
568 MOVQ DI, (SP)
569 MOVQ (1*8)(DI), DI // a1
570 XORL AX, AX // vararg: say "no float args"
571
572 CALL CX
573
574 MOVQ (SP), DI
575 MOVQ AX, (4*8)(DI) // r1
576 MOVQ DX, (5*8)(DI) // r2
577
578 // Standard libc functions return -1 on error
579 // and set errno.
580 CMPQ AX, $-1
581 JNE ok
582
583 // Get error code from libc.
584 CALL libc_error(SB)
585 MOVLQSX (AX), AX
586 MOVQ (SP), DI
587 MOVQ AX, (6*8)(DI) // err
588
589ok:
590 XORL AX, AX // no error (it's ignored anyway)
591 RET
592
593// syscallPtr is like syscallX except that the libc function reports an
594// error by returning NULL and setting errno.
595TEXT runtime·syscallPtr(SB),NOSPLIT,$16
596 MOVQ (0*8)(DI), CX // fn
597 MOVQ (2*8)(DI), SI // a2
598 MOVQ (3*8)(DI), DX // a3
599 MOVQ DI, (SP)
600 MOVQ (1*8)(DI), DI // a1
601 XORL AX, AX // vararg: say "no float args"
602
603 CALL CX
604
605 MOVQ (SP), DI
606 MOVQ AX, (4*8)(DI) // r1
607 MOVQ DX, (5*8)(DI) // r2
608
609 // syscallPtr libc functions return NULL on error
610 // and set errno.
611 TESTQ AX, AX
612 JNE ok
613
614 // Get error code from libc.
615 CALL libc_error(SB)
616 MOVLQSX (AX), AX
617 MOVQ (SP), DI
618 MOVQ AX, (6*8)(DI) // err
619
620ok:
621 XORL AX, AX // no error (it's ignored anyway)
622 RET
623
624// syscall6 calls a function in libc on behalf of the syscall package.
625// syscall6 takes a pointer to a struct like:
626// struct {
627// fn uintptr
628// a1 uintptr
629// a2 uintptr
630// a3 uintptr
631// a4 uintptr
632// a5 uintptr
633// a6 uintptr
634// r1 uintptr
635// r2 uintptr
636// err uintptr
637// }
638// syscall6 must be called on the g0 stack with the
639// C calling convention (use libcCall).
640//
641// syscall6 expects a 32-bit result and tests for 32-bit -1
642// to decide there was an error.
643TEXT runtime·syscall6(SB),NOSPLIT,$16
644 MOVQ (0*8)(DI), R11// fn
645 MOVQ (2*8)(DI), SI // a2
646 MOVQ (3*8)(DI), DX // a3
647 MOVQ (4*8)(DI), CX // a4
648 MOVQ (5*8)(DI), R8 // a5
649 MOVQ (6*8)(DI), R9 // a6
650 MOVQ DI, (SP)
651 MOVQ (1*8)(DI), DI // a1
652 XORL AX, AX // vararg: say "no float args"
653
654 CALL R11
655
656 MOVQ (SP), DI
657 MOVQ AX, (7*8)(DI) // r1
658 MOVQ DX, (8*8)(DI) // r2
659
660 CMPL AX, $-1
661 JNE ok
662
663 CALL libc_error(SB)
664 MOVLQSX (AX), AX
665 MOVQ (SP), DI
666 MOVQ AX, (9*8)(DI) // err
667
668ok:
669 XORL AX, AX // no error (it's ignored anyway)
670 RET
671
672// syscall6X calls a function in libc on behalf of the syscall package.
673// syscall6X takes a pointer to a struct like:
674// struct {
675// fn uintptr
676// a1 uintptr
677// a2 uintptr
678// a3 uintptr
679// a4 uintptr
680// a5 uintptr
681// a6 uintptr
682// r1 uintptr
683// r2 uintptr
684// err uintptr
685// }
686// syscall6X must be called on the g0 stack with the
687// C calling convention (use libcCall).
688//
689// syscall6X is like syscall6 but expects a 64-bit result
690// and tests for 64-bit -1 to decide there was an error.
691TEXT runtime·syscall6X(SB),NOSPLIT,$16
692 MOVQ (0*8)(DI), R11// fn
693 MOVQ (2*8)(DI), SI // a2
694 MOVQ (3*8)(DI), DX // a3
695 MOVQ (4*8)(DI), CX // a4
696 MOVQ (5*8)(DI), R8 // a5
697 MOVQ (6*8)(DI), R9 // a6
698 MOVQ DI, (SP)
699 MOVQ (1*8)(DI), DI // a1
700 XORL AX, AX // vararg: say "no float args"
701
702 CALL R11
703
704 MOVQ (SP), DI
705 MOVQ AX, (7*8)(DI) // r1
706 MOVQ DX, (8*8)(DI) // r2
707
708 CMPQ AX, $-1
709 JNE ok
710
711 CALL libc_error(SB)
712 MOVLQSX (AX), AX
713 MOVQ (SP), DI
714 MOVQ AX, (9*8)(DI) // err
715
716ok:
717 XORL AX, AX // no error (it's ignored anyway)
718 RET
719
720// syscall9 calls a function in libc on behalf of the syscall package.
721// syscall9 takes a pointer to a struct like:
722// struct {
723// fn uintptr
724// a1 uintptr
725// a2 uintptr
726// a3 uintptr
727// a4 uintptr
728// a5 uintptr
729// a6 uintptr
730// a7 uintptr
731// a8 uintptr
732// a9 uintptr
733// r1 uintptr
734// r2 uintptr
735// err uintptr
736// }
737// syscall9 must be called on the g0 stack with the
738// C calling convention (use libcCall).
739//
740// syscall9 expects a 32-bit result and tests for 32-bit -1
741// to decide there was an error.
742TEXT runtime·syscall9(SB),NOSPLIT,$16
743 MOVQ (0*8)(DI), R13// fn
744 MOVQ (2*8)(DI), SI // a2
745 MOVQ (3*8)(DI), DX // a3
746 MOVQ (4*8)(DI), CX // a4
747 MOVQ (5*8)(DI), R8 // a5
748 MOVQ (6*8)(DI), R9 // a6
749 MOVQ (7*8)(DI), R10 // a7
750 MOVQ (8*8)(DI), R11 // a8
751 MOVQ (9*8)(DI), R12 // a9
752 MOVQ DI, (SP)
753 MOVQ (1*8)(DI), DI // a1
754 XORL AX, AX // vararg: say "no float args"
755
756 CALL R13
757
758 MOVQ (SP), DI
759 MOVQ AX, (10*8)(DI) // r1
760 MOVQ DX, (11*8)(DI) // r2
761
762 CMPL AX, $-1
763 JNE ok
764
765 CALL libc_error(SB)
766 MOVLQSX (AX), AX
767 MOVQ (SP), DI
768 MOVQ AX, (12*8)(DI) // err
769
770ok:
771 XORL AX, AX // no error (it's ignored anyway)
772 RET
773
774// syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
775// takes 5 uintptrs and 1 float64, and only returns one value,
776// for use with standard C ABI functions.
777TEXT runtime·syscall_x509(SB),NOSPLIT,$16
778 MOVQ (0*8)(DI), R11// fn
779 MOVQ (2*8)(DI), SI // a2
780 MOVQ (3*8)(DI), DX // a3
781 MOVQ (4*8)(DI), CX // a4
782 MOVQ (5*8)(DI), R8 // a5
783 MOVQ (6*8)(DI), X0 // f1
784 MOVQ DI, (SP)
785 MOVQ (1*8)(DI), DI // a1
786 XORL AX, AX // vararg: say "no float args"
787
788 CALL R11
789
790 MOVQ (SP), DI
791 MOVQ AX, (7*8)(DI) // r1
792
793 XORL AX, AX // no error (it's ignored anyway)
794 RET
795
796TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
797 CALL libc_issetugid(SB)
798 RET
799
800// mach_vm_region_trampoline calls mach_vm_region from libc.
801TEXT runtime·mach_vm_region_trampoline(SB),NOSPLIT,$0
802 MOVQ 0(DI), SI // address
803 MOVQ 8(DI), DX // size
804 MOVL 16(DI), CX // flavor
805 MOVQ 24(DI), R8 // info
806 MOVQ 32(DI), R9 // count
807 MOVQ 40(DI), R10 // object_name
808 MOVQ $libc_mach_task_self_(SB), DI
809 MOVL 0(DI), DI
810 CALL libc_mach_vm_region(SB)
811 RET
812
813// proc_regionfilename_trampoline calls proc_regionfilename.
814TEXT runtime·proc_regionfilename_trampoline(SB),NOSPLIT,$0
815 MOVQ 8(DI), SI // address
816 MOVQ 16(DI), DX // buffer
817 MOVQ 24(DI), CX // buffer_size
818 MOVQ 0(DI), DI // pid
819 CALL libc_proc_regionfilename(SB)
820 RET
View as plain text