Text file
src/runtime/sys_darwin_amd64.s
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)
17 TEXT 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
23 TEXT 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
31 TEXT runtime·close_trampoline(SB),NOSPLIT,$0
32 MOVL 0(DI), DI // arg 1 fd
33 CALL libc_close(SB)
34 RET
35
36 TEXT 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
46 noerr:
47 RET
48
49 TEXT 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
59 noerr:
60 RET
61
62 TEXT 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
70 TEXT 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
77 TEXT 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
85 TEXT runtime·mlock_trampoline(SB), NOSPLIT, $0
86 UNDEF // unimplemented
87
88 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
89
90 TEXT 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
110 initialized:
111 MOVL SI, 8(BX)
112 MOVL DI, 12(BX)
113 RET
114
115 TEXT 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
121 TEXT 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
131 TEXT 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
141 TEXT 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
150 TEXT 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
158 TEXT 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.
172 TEXT 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.
197 TEXT 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.
215 TEXT 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
262 sigtramp:
263 JMP runtime·sigtramp(SB)
264
265 sigtrampnog:
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
289 TEXT 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
304 ok:
305 MOVQ AX, 32(BX)
306 MOVQ DX, 40(BX)
307 RET
308
309 TEXT 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
318 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
319 MOVL 0(DI), DI // arg 1 usec
320 CALL libc_usleep(SB)
321 RET
322
323 TEXT runtime·settls(SB),NOSPLIT,$32
324 // Nothing to do on Darwin, pthread already set thread-local storage up.
325 RET
326
327 TEXT 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
337 TEXT 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
346 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
347 CALL libc_kqueue(SB)
348 RET
349
350 TEXT 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
363 ok:
364 RET
365
366 TEXT 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
379 noerr:
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.
387 TEXT 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.)
415 TEXT 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
420 TEXT 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
426 TEXT 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
432 TEXT 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
440 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
441 MOVL 0(DI), DI // arg 1 signal
442 CALL libc_raise(SB)
443 RET
444
445 TEXT 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
451 TEXT 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
456 TEXT 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
461 TEXT 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
467 TEXT 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
473 TEXT 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
480 TEXT 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
485 TEXT 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
491 TEXT 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
497 TEXT 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.
519 TEXT 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
544 ok:
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.
564 TEXT 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
589 ok:
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.
595 TEXT 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
620 ok:
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.
643 TEXT 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
668 ok:
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.
691 TEXT 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
716 ok:
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.
742 TEXT 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
770 ok:
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.
777 TEXT 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
796 TEXT 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.
801 TEXT 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.
814 TEXT 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
821
View as plain text