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