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