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 TEXT runtime·arc4random_buf_trampoline(SB),NOSPLIT,$0
504 MOVL 8(DI), SI // arg 2 nbytes
505 MOVQ 0(DI), DI // arg 1 buf
506 CALL libc_arc4random_buf(SB)
507 RET
508
509 // syscall calls a function in libc on behalf of the syscall package.
510 // syscall takes a pointer to a struct like:
511 // struct {
512 // fn uintptr
513 // a1 uintptr
514 // a2 uintptr
515 // a3 uintptr
516 // r1 uintptr
517 // r2 uintptr
518 // err uintptr
519 // }
520 // syscall must be called on the g0 stack with the
521 // C calling convention (use libcCall).
522 //
523 // syscall expects a 32-bit result and tests for 32-bit -1
524 // to decide there was an error.
525 TEXT runtime·syscall(SB),NOSPLIT,$16
526 MOVQ (0*8)(DI), CX // fn
527 MOVQ (2*8)(DI), SI // a2
528 MOVQ (3*8)(DI), DX // a3
529 MOVQ DI, (SP)
530 MOVQ (1*8)(DI), DI // a1
531 XORL AX, AX // vararg: say "no float args"
532
533 CALL CX
534
535 MOVQ (SP), DI
536 MOVQ AX, (4*8)(DI) // r1
537 MOVQ DX, (5*8)(DI) // r2
538
539 // Standard libc functions return -1 on error
540 // and set errno.
541 CMPL AX, $-1 // Note: high 32 bits are junk
542 JNE ok
543
544 // Get error code from libc.
545 CALL libc_error(SB)
546 MOVLQSX (AX), AX
547 MOVQ (SP), DI
548 MOVQ AX, (6*8)(DI) // err
549
550 ok:
551 XORL AX, AX // no error (it's ignored anyway)
552 RET
553
554 // syscallX calls a function in libc on behalf of the syscall package.
555 // syscallX takes a pointer to a struct like:
556 // struct {
557 // fn uintptr
558 // a1 uintptr
559 // a2 uintptr
560 // a3 uintptr
561 // r1 uintptr
562 // r2 uintptr
563 // err uintptr
564 // }
565 // syscallX must be called on the g0 stack with the
566 // C calling convention (use libcCall).
567 //
568 // syscallX is like syscall but expects a 64-bit result
569 // and tests for 64-bit -1 to decide there was an error.
570 TEXT runtime·syscallX(SB),NOSPLIT,$16
571 MOVQ (0*8)(DI), CX // fn
572 MOVQ (2*8)(DI), SI // a2
573 MOVQ (3*8)(DI), DX // a3
574 MOVQ DI, (SP)
575 MOVQ (1*8)(DI), DI // a1
576 XORL AX, AX // vararg: say "no float args"
577
578 CALL CX
579
580 MOVQ (SP), DI
581 MOVQ AX, (4*8)(DI) // r1
582 MOVQ DX, (5*8)(DI) // r2
583
584 // Standard libc functions return -1 on error
585 // and set errno.
586 CMPQ AX, $-1
587 JNE ok
588
589 // Get error code from libc.
590 CALL libc_error(SB)
591 MOVLQSX (AX), AX
592 MOVQ (SP), DI
593 MOVQ AX, (6*8)(DI) // err
594
595 ok:
596 XORL AX, AX // no error (it's ignored anyway)
597 RET
598
599 // syscallPtr is like syscallX except that the libc function reports an
600 // error by returning NULL and setting errno.
601 TEXT runtime·syscallPtr(SB),NOSPLIT,$16
602 MOVQ (0*8)(DI), CX // fn
603 MOVQ (2*8)(DI), SI // a2
604 MOVQ (3*8)(DI), DX // a3
605 MOVQ DI, (SP)
606 MOVQ (1*8)(DI), DI // a1
607 XORL AX, AX // vararg: say "no float args"
608
609 CALL CX
610
611 MOVQ (SP), DI
612 MOVQ AX, (4*8)(DI) // r1
613 MOVQ DX, (5*8)(DI) // r2
614
615 // syscallPtr libc functions return NULL on error
616 // and set errno.
617 TESTQ AX, AX
618 JNE ok
619
620 // Get error code from libc.
621 CALL libc_error(SB)
622 MOVLQSX (AX), AX
623 MOVQ (SP), DI
624 MOVQ AX, (6*8)(DI) // err
625
626 ok:
627 XORL AX, AX // no error (it's ignored anyway)
628 RET
629
630 // syscall6 calls a function in libc on behalf of the syscall package.
631 // syscall6 takes a pointer to a struct like:
632 // struct {
633 // fn uintptr
634 // a1 uintptr
635 // a2 uintptr
636 // a3 uintptr
637 // a4 uintptr
638 // a5 uintptr
639 // a6 uintptr
640 // r1 uintptr
641 // r2 uintptr
642 // err uintptr
643 // }
644 // syscall6 must be called on the g0 stack with the
645 // C calling convention (use libcCall).
646 //
647 // syscall6 expects a 32-bit result and tests for 32-bit -1
648 // to decide there was an error.
649 TEXT runtime·syscall6(SB),NOSPLIT,$16
650 MOVQ (0*8)(DI), R11// fn
651 MOVQ (2*8)(DI), SI // a2
652 MOVQ (3*8)(DI), DX // a3
653 MOVQ (4*8)(DI), CX // a4
654 MOVQ (5*8)(DI), R8 // a5
655 MOVQ (6*8)(DI), R9 // a6
656 MOVQ DI, (SP)
657 MOVQ (1*8)(DI), DI // a1
658 XORL AX, AX // vararg: say "no float args"
659
660 CALL R11
661
662 MOVQ (SP), DI
663 MOVQ AX, (7*8)(DI) // r1
664 MOVQ DX, (8*8)(DI) // r2
665
666 CMPL AX, $-1
667 JNE ok
668
669 CALL libc_error(SB)
670 MOVLQSX (AX), AX
671 MOVQ (SP), DI
672 MOVQ AX, (9*8)(DI) // err
673
674 ok:
675 XORL AX, AX // no error (it's ignored anyway)
676 RET
677
678 // syscall6X calls a function in libc on behalf of the syscall package.
679 // syscall6X takes a pointer to a struct like:
680 // struct {
681 // fn uintptr
682 // a1 uintptr
683 // a2 uintptr
684 // a3 uintptr
685 // a4 uintptr
686 // a5 uintptr
687 // a6 uintptr
688 // r1 uintptr
689 // r2 uintptr
690 // err uintptr
691 // }
692 // syscall6X must be called on the g0 stack with the
693 // C calling convention (use libcCall).
694 //
695 // syscall6X is like syscall6 but expects a 64-bit result
696 // and tests for 64-bit -1 to decide there was an error.
697 TEXT runtime·syscall6X(SB),NOSPLIT,$16
698 MOVQ (0*8)(DI), R11// fn
699 MOVQ (2*8)(DI), SI // a2
700 MOVQ (3*8)(DI), DX // a3
701 MOVQ (4*8)(DI), CX // a4
702 MOVQ (5*8)(DI), R8 // a5
703 MOVQ (6*8)(DI), R9 // a6
704 MOVQ DI, (SP)
705 MOVQ (1*8)(DI), DI // a1
706 XORL AX, AX // vararg: say "no float args"
707
708 CALL R11
709
710 MOVQ (SP), DI
711 MOVQ AX, (7*8)(DI) // r1
712 MOVQ DX, (8*8)(DI) // r2
713
714 CMPQ AX, $-1
715 JNE ok
716
717 CALL libc_error(SB)
718 MOVLQSX (AX), AX
719 MOVQ (SP), DI
720 MOVQ AX, (9*8)(DI) // err
721
722 ok:
723 XORL AX, AX // no error (it's ignored anyway)
724 RET
725
726 // syscall9 calls a function in libc on behalf of the syscall package.
727 // syscall9 takes a pointer to a struct like:
728 // struct {
729 // fn uintptr
730 // a1 uintptr
731 // a2 uintptr
732 // a3 uintptr
733 // a4 uintptr
734 // a5 uintptr
735 // a6 uintptr
736 // a7 uintptr
737 // a8 uintptr
738 // a9 uintptr
739 // r1 uintptr
740 // r2 uintptr
741 // err uintptr
742 // }
743 // syscall9 must be called on the g0 stack with the
744 // C calling convention (use libcCall).
745 //
746 // syscall9 expects a 32-bit result and tests for 32-bit -1
747 // to decide there was an error.
748 TEXT runtime·syscall9(SB),NOSPLIT,$16
749 MOVQ (0*8)(DI), R13// fn
750 MOVQ (2*8)(DI), SI // a2
751 MOVQ (3*8)(DI), DX // a3
752 MOVQ (4*8)(DI), CX // a4
753 MOVQ (5*8)(DI), R8 // a5
754 MOVQ (6*8)(DI), R9 // a6
755 MOVQ (7*8)(DI), R10 // a7
756 MOVQ (8*8)(DI), R11 // a8
757 MOVQ (9*8)(DI), R12 // a9
758 MOVQ DI, (SP)
759 MOVQ (1*8)(DI), DI // a1
760 XORL AX, AX // vararg: say "no float args"
761
762 CALL R13
763
764 MOVQ (SP), DI
765 MOVQ AX, (10*8)(DI) // r1
766 MOVQ DX, (11*8)(DI) // r2
767
768 CMPL AX, $-1
769 JNE ok
770
771 CALL libc_error(SB)
772 MOVLQSX (AX), AX
773 MOVQ (SP), DI
774 MOVQ AX, (12*8)(DI) // err
775
776 ok:
777 XORL AX, AX // no error (it's ignored anyway)
778 RET
779
780 // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
781 // takes 5 uintptrs and 1 float64, and only returns one value,
782 // for use with standard C ABI functions.
783 TEXT runtime·syscall_x509(SB),NOSPLIT,$16
784 MOVQ (0*8)(DI), R11// fn
785 MOVQ (2*8)(DI), SI // a2
786 MOVQ (3*8)(DI), DX // a3
787 MOVQ (4*8)(DI), CX // a4
788 MOVQ (5*8)(DI), R8 // a5
789 MOVQ (6*8)(DI), X0 // f1
790 MOVQ DI, (SP)
791 MOVQ (1*8)(DI), DI // a1
792 XORL AX, AX // vararg: say "no float args"
793
794 CALL R11
795
796 MOVQ (SP), DI
797 MOVQ AX, (7*8)(DI) // r1
798
799 XORL AX, AX // no error (it's ignored anyway)
800 RET
801
802 TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
803 CALL libc_issetugid(SB)
804 RET
805
806 // mach_vm_region_trampoline calls mach_vm_region from libc.
807 TEXT runtime·mach_vm_region_trampoline(SB),NOSPLIT,$0
808 MOVQ 0(DI), SI // address
809 MOVQ 8(DI), DX // size
810 MOVL 16(DI), CX // flavor
811 MOVQ 24(DI), R8 // info
812 MOVQ 32(DI), R9 // count
813 MOVQ 40(DI), R10 // object_name
814 MOVQ $libc_mach_task_self_(SB), DI
815 MOVL 0(DI), DI
816 CALL libc_mach_vm_region(SB)
817 RET
818
819 // proc_regionfilename_trampoline calls proc_regionfilename.
820 TEXT runtime·proc_regionfilename_trampoline(SB),NOSPLIT,$0
821 MOVQ 8(DI), SI // address
822 MOVQ 16(DI), DX // buffer
823 MOVQ 24(DI), CX // buffer_size
824 MOVQ 0(DI), DI // pid
825 CALL libc_proc_regionfilename(SB)
826 RET
827
View as plain text