...

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
   503TEXT 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.
   525TEXT 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
   550ok:
   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.
   570TEXT 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
   595ok:
   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.
   601TEXT 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
   626ok:
   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.
   649TEXT 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
   674ok:
   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.
   697TEXT 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
   722ok:
   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.
   748TEXT runtime·syscall9(SB),NOSPLIT,$32
   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	R10, 0(SP)
   757	MOVQ	(8*8)(DI), R11 // a8
   758	MOVQ	R11, 8(SP)
   759	MOVQ	(9*8)(DI), R12 // a9
   760	MOVQ	R12, 16(SP)
   761	MOVQ	DI, 24(SP)
   762	MOVQ	(1*8)(DI), DI // a1
   763	XORL	AX, AX	      // vararg: say "no float args"
   764
   765	CALL	R13
   766
   767	MOVQ	24(SP), DI
   768	MOVQ	AX, (10*8)(DI) // r1
   769	MOVQ	DX, (11*8)(DI) // r2
   770
   771	CMPL	AX, $-1
   772	JNE	ok
   773
   774	CALL	libc_error(SB)
   775	MOVLQSX	(AX), AX
   776	MOVQ	24(SP), DI
   777	MOVQ	AX, (12*8)(DI) // err
   778
   779ok:
   780	XORL	AX, AX        // no error (it's ignored anyway)
   781	RET
   782
   783// syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
   784// takes 5 uintptrs and 1 float64, and only returns one value,
   785// for use with standard C ABI functions.
   786TEXT runtime·syscall_x509(SB),NOSPLIT,$16
   787	MOVQ	(0*8)(DI), R11// fn
   788	MOVQ	(2*8)(DI), SI // a2
   789	MOVQ	(3*8)(DI), DX // a3
   790	MOVQ	(4*8)(DI), CX // a4
   791	MOVQ	(5*8)(DI), R8 // a5
   792	MOVQ	(6*8)(DI), X0 // f1
   793	MOVQ	DI, (SP)
   794	MOVQ	(1*8)(DI), DI // a1
   795	XORL	AX, AX	      // vararg: say "no float args"
   796
   797	CALL	R11
   798
   799	MOVQ	(SP), DI
   800	MOVQ	AX, (7*8)(DI) // r1
   801
   802	XORL	AX, AX        // no error (it's ignored anyway)
   803	RET
   804
   805TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
   806	CALL	libc_issetugid(SB)
   807	RET
   808
   809// mach_vm_region_trampoline calls mach_vm_region from libc.
   810TEXT runtime·mach_vm_region_trampoline(SB),NOSPLIT,$0
   811	MOVQ	0(DI), SI // address
   812	MOVQ	8(DI), DX // size
   813	MOVL	16(DI), CX // flavor
   814	MOVQ	24(DI), R8 // info
   815	MOVQ	32(DI), R9 // count
   816	MOVQ	40(DI), R10 // object_name
   817	MOVQ	$libc_mach_task_self_(SB), DI
   818	MOVL	0(DI), DI
   819	CALL	libc_mach_vm_region(SB)
   820	RET
   821
   822// proc_regionfilename_trampoline calls proc_regionfilename.
   823TEXT runtime·proc_regionfilename_trampoline(SB),NOSPLIT,$0
   824	MOVQ	8(DI), SI // address
   825	MOVQ	16(DI), DX // buffer
   826	MOVQ	24(DI), CX // buffer_size
   827	MOVQ	0(DI), DI // pid
   828	CALL	libc_proc_regionfilename(SB)
   829	RET

View as plain text