github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/runtime/sys_darwin_amd64.s (about)

     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  
    13  // Exit the entire program (like C exit)
    14  TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
    15  	PUSHQ	BP
    16  	MOVQ	SP, BP
    17  	MOVL	0(DI), DI		// arg 1 exit status
    18  	CALL	libc_exit(SB)
    19  	MOVL	$0xf1, 0xf1  // crash
    20  	POPQ	BP
    21  	RET
    22  
    23  TEXT runtime·open_trampoline(SB),NOSPLIT,$0
    24  	PUSHQ	BP
    25  	MOVQ	SP, BP
    26  	MOVL	8(DI), SI		// arg 2 flags
    27  	MOVL	12(DI), DX		// arg 3 mode
    28  	MOVQ	0(DI), DI		// arg 1 pathname
    29  	CALL	libc_open(SB)
    30  	POPQ	BP
    31  	RET
    32  
    33  TEXT runtime·close_trampoline(SB),NOSPLIT,$0
    34  	PUSHQ	BP
    35  	MOVQ	SP, BP
    36  	MOVL	0(DI), DI		// arg 1 fd
    37  	CALL	libc_close(SB)
    38  	POPQ	BP
    39  	RET
    40  
    41  TEXT runtime·read_trampoline(SB),NOSPLIT,$0
    42  	PUSHQ	BP
    43  	MOVQ	SP, BP
    44  	MOVQ	8(DI), SI		// arg 2 buf
    45  	MOVL	16(DI), DX		// arg 3 count
    46  	MOVL	0(DI), DI		// arg 1 fd
    47  	CALL	libc_read(SB)
    48  	POPQ	BP
    49  	RET
    50  
    51  TEXT runtime·write_trampoline(SB),NOSPLIT,$0
    52  	PUSHQ	BP
    53  	MOVQ	SP, BP
    54  	MOVQ	8(DI), SI		// arg 2 buf
    55  	MOVL	16(DI), DX		// arg 3 count
    56  	MOVQ	0(DI), DI		// arg 1 fd
    57  	CALL	libc_write(SB)
    58  	POPQ	BP
    59  	RET
    60  
    61  TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
    62  	PUSHQ	BP
    63  	MOVQ	SP, BP
    64  	MOVQ	8(DI), SI		// arg 2 new
    65  	MOVQ	16(DI), DX		// arg 3 old
    66  	MOVL	0(DI), DI		// arg 1 which
    67  	CALL	libc_setitimer(SB)
    68  	POPQ	BP
    69  	RET
    70  
    71  TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
    72  	PUSHQ	BP
    73  	MOVQ	SP, BP
    74  	MOVQ	8(DI), SI	// arg 2 len
    75  	MOVL	16(DI), DX	// arg 3 advice
    76  	MOVQ	0(DI), DI	// arg 1 addr
    77  	CALL	libc_madvise(SB)
    78  	// ignore failure - maybe pages are locked
    79  	POPQ	BP
    80  	RET
    81  
    82  GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
    83  
    84  TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
    85  	PUSHQ	BP
    86  	MOVQ	SP, BP
    87  	MOVQ	DI, BX
    88  	CALL	libc_mach_absolute_time(SB)
    89  	MOVQ	AX, 0(BX)
    90  	MOVL	timebase<>+machTimebaseInfo_numer(SB), SI
    91  	MOVL	timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
    92  	TESTL	DI, DI
    93  	JNE	initialized
    94  
    95  	SUBQ	$(machTimebaseInfo__size+15)/16*16, SP
    96  	MOVQ	SP, DI
    97  	CALL	libc_mach_timebase_info(SB)
    98  	MOVL	machTimebaseInfo_numer(SP), SI
    99  	MOVL	machTimebaseInfo_denom(SP), DI
   100  	ADDQ	$(machTimebaseInfo__size+15)/16*16, SP
   101  
   102  	MOVL	SI, timebase<>+machTimebaseInfo_numer(SB)
   103  	MOVL	DI, AX
   104  	XCHGL	AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write
   105  
   106  initialized:
   107  	MOVL	SI, 8(BX)
   108  	MOVL	DI, 12(BX)
   109  	MOVQ	BP, SP
   110  	POPQ	BP
   111  	RET
   112  
   113  TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
   114  	PUSHQ	BP			// make a frame; keep stack aligned
   115  	MOVQ	SP, BP
   116  	// DI already has *timeval
   117  	XORL	SI, SI // no timezone needed
   118  	CALL	libc_gettimeofday(SB)
   119  	POPQ	BP
   120  	RET
   121  
   122  TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
   123  	PUSHQ	BP
   124  	MOVQ	SP, BP
   125  	MOVQ	8(DI), SI		// arg 2 new
   126  	MOVQ	16(DI), DX		// arg 3 old
   127  	MOVL	0(DI), DI		// arg 1 sig
   128  	CALL	libc_sigaction(SB)
   129  	TESTL	AX, AX
   130  	JEQ	2(PC)
   131  	MOVL	$0xf1, 0xf1  // crash
   132  	POPQ	BP
   133  	RET
   134  
   135  TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   136  	PUSHQ	BP
   137  	MOVQ	SP, BP
   138  	MOVQ	8(DI), SI	// arg 2 new
   139  	MOVQ	16(DI), DX	// arg 3 old
   140  	MOVL	0(DI), DI	// arg 1 how
   141  	CALL	libc_pthread_sigmask(SB)
   142  	TESTL	AX, AX
   143  	JEQ	2(PC)
   144  	MOVL	$0xf1, 0xf1  // crash
   145  	POPQ	BP
   146  	RET
   147  
   148  TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   149  	PUSHQ	BP
   150  	MOVQ	SP, BP
   151  	MOVQ	8(DI), SI		// arg 2 old
   152  	MOVQ	0(DI), DI		// arg 1 new
   153  	CALL	libc_sigaltstack(SB)
   154  	TESTQ	AX, AX
   155  	JEQ	2(PC)
   156  	MOVL	$0xf1, 0xf1  // crash
   157  	POPQ	BP
   158  	RET
   159  
   160  TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
   161  	PUSHQ	BP
   162  	MOVQ	SP, BP
   163  	MOVL	0(DI), BX	// signal
   164  	CALL	libc_getpid(SB)
   165  	MOVL	AX, DI		// arg 1 pid
   166  	MOVL	BX, SI		// arg 2 signal
   167  	CALL	libc_kill(SB)
   168  	POPQ	BP
   169  	RET
   170  
   171  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   172  	MOVQ	fn+0(FP),    AX
   173  	MOVL	sig+8(FP),   DI
   174  	MOVQ	info+16(FP), SI
   175  	MOVQ	ctx+24(FP),  DX
   176  	PUSHQ	BP
   177  	MOVQ	SP, BP
   178  	ANDQ	$~15, SP     // alignment for x86_64 ABI
   179  	CALL	AX
   180  	MOVQ	BP, SP
   181  	POPQ	BP
   182  	RET
   183  
   184  // This is the function registered during sigaction and is invoked when
   185  // a signal is received. It just redirects to the Go function sigtrampgo.
   186  TEXT runtime·sigtramp(SB),NOSPLIT,$0
   187  	// This runs on the signal stack, so we have lots of stack available.
   188  	// We allocate our own stack space, because if we tell the linker
   189  	// how much we're using, the NOSPLIT check fails.
   190  	PUSHQ	BP
   191  	MOVQ	SP, BP
   192  	SUBQ	$64, SP
   193  
   194  	// Save callee-save registers.
   195  	MOVQ	BX, 24(SP)
   196  	MOVQ	R12, 32(SP)
   197  	MOVQ	R13, 40(SP)
   198  	MOVQ	R14, 48(SP)
   199  	MOVQ	R15, 56(SP)
   200  
   201  	// Call into the Go signal handler
   202  	MOVL	DI, 0(SP)  // sig
   203  	MOVQ	SI, 8(SP)  // info
   204  	MOVQ	DX, 16(SP) // ctx
   205  	CALL runtime·sigtrampgo(SB)
   206  
   207  	// Restore callee-save registers.
   208  	MOVQ	24(SP), BX
   209  	MOVQ	32(SP), R12
   210  	MOVQ	40(SP), R13
   211  	MOVQ	48(SP), R14
   212  	MOVQ	56(SP), R15
   213  
   214  	MOVQ	BP, SP
   215  	POPQ	BP
   216  	RET
   217  
   218  // Used instead of sigtramp in programs that use cgo.
   219  // Arguments from kernel are in DI, SI, DX.
   220  TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
   221  	// If no traceback function, do usual sigtramp.
   222  	MOVQ	runtime·cgoTraceback(SB), AX
   223  	TESTQ	AX, AX
   224  	JZ	sigtramp
   225  
   226  	// If no traceback support function, which means that
   227  	// runtime/cgo was not linked in, do usual sigtramp.
   228  	MOVQ	_cgo_callers(SB), AX
   229  	TESTQ	AX, AX
   230  	JZ	sigtramp
   231  
   232  	// Figure out if we are currently in a cgo call.
   233  	// If not, just do usual sigtramp.
   234  	get_tls(CX)
   235  	MOVQ	g(CX),AX
   236  	TESTQ	AX, AX
   237  	JZ	sigtrampnog     // g == nil
   238  	MOVQ	g_m(AX), AX
   239  	TESTQ	AX, AX
   240  	JZ	sigtramp        // g.m == nil
   241  	MOVL	m_ncgo(AX), CX
   242  	TESTL	CX, CX
   243  	JZ	sigtramp        // g.m.ncgo == 0
   244  	MOVQ	m_curg(AX), CX
   245  	TESTQ	CX, CX
   246  	JZ	sigtramp        // g.m.curg == nil
   247  	MOVQ	g_syscallsp(CX), CX
   248  	TESTQ	CX, CX
   249  	JZ	sigtramp        // g.m.curg.syscallsp == 0
   250  	MOVQ	m_cgoCallers(AX), R8
   251  	TESTQ	R8, R8
   252  	JZ	sigtramp        // g.m.cgoCallers == nil
   253  	MOVL	m_cgoCallersUse(AX), CX
   254  	TESTL	CX, CX
   255  	JNZ	sigtramp	// g.m.cgoCallersUse != 0
   256  
   257  	// Jump to a function in runtime/cgo.
   258  	// That function, written in C, will call the user's traceback
   259  	// function with proper unwind info, and will then call back here.
   260  	// The first three arguments, and the fifth, are already in registers.
   261  	// Set the two remaining arguments now.
   262  	MOVQ	runtime·cgoTraceback(SB), CX
   263  	MOVQ	$runtime·sigtramp(SB), R9
   264  	MOVQ	_cgo_callers(SB), AX
   265  	JMP	AX
   266  
   267  sigtramp:
   268  	JMP	runtime·sigtramp(SB)
   269  
   270  sigtrampnog:
   271  	// Signal arrived on a non-Go thread. If this is SIGPROF, get a
   272  	// stack trace.
   273  	CMPL	DI, $27 // 27 == SIGPROF
   274  	JNZ	sigtramp
   275  
   276  	// Lock sigprofCallersUse.
   277  	MOVL	$0, AX
   278  	MOVL	$1, CX
   279  	MOVQ	$runtime·sigprofCallersUse(SB), R11
   280  	LOCK
   281  	CMPXCHGL	CX, 0(R11)
   282  	JNZ	sigtramp  // Skip stack trace if already locked.
   283  
   284  	// Jump to the traceback function in runtime/cgo.
   285  	// It will call back to sigprofNonGo, which will ignore the
   286  	// arguments passed in registers.
   287  	// First three arguments to traceback function are in registers already.
   288  	MOVQ	runtime·cgoTraceback(SB), CX
   289  	MOVQ	$runtime·sigprofCallers(SB), R8
   290  	MOVQ	$runtime·sigprofNonGo(SB), R9
   291  	MOVQ	_cgo_callers(SB), AX
   292  	JMP	AX
   293  
   294  TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
   295  	PUSHQ	BP			// make a frame; keep stack aligned
   296  	MOVQ	SP, BP
   297  	MOVQ	DI, BX
   298  	MOVQ	0(BX), DI		// arg 1 addr
   299  	MOVQ	8(BX), SI		// arg 2 len
   300  	MOVL	16(BX), DX		// arg 3 prot
   301  	MOVL	20(BX), CX		// arg 4 flags
   302  	MOVL	24(BX), R8		// arg 5 fid
   303  	MOVL	28(BX), R9		// arg 6 offset
   304  	CALL	libc_mmap(SB)
   305  	XORL	DX, DX
   306  	CMPQ	AX, $-1
   307  	JNE	ok
   308  	CALL	libc_error(SB)
   309  	MOVLQSX	(AX), DX		// errno
   310  	XORL	AX, AX
   311  ok:
   312  	MOVQ	AX, 32(BX)
   313  	MOVQ	DX, 40(BX)
   314  	POPQ	BP
   315  	RET
   316  
   317  TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
   318  	PUSHQ	BP
   319  	MOVQ	SP, BP
   320  	MOVQ	8(DI), SI		// arg 2 len
   321  	MOVQ	0(DI), DI		// arg 1 addr
   322  	CALL	libc_munmap(SB)
   323  	TESTQ	AX, AX
   324  	JEQ	2(PC)
   325  	MOVL	$0xf1, 0xf1  // crash
   326  	POPQ	BP
   327  	RET
   328  
   329  TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   330  	PUSHQ	BP
   331  	MOVQ	SP, BP
   332  	MOVL	0(DI), DI	// arg 1 usec
   333  	CALL	libc_usleep(SB)
   334  	POPQ	BP
   335  	RET
   336  
   337  TEXT runtime·settls(SB),NOSPLIT,$32
   338  	// Nothing to do on Darwin, pthread already set thread-local storage up.
   339  	RET
   340  
   341  TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
   342  	PUSHQ	BP
   343  	MOVQ	SP, BP
   344  	MOVL	8(DI), SI		// arg 2 miblen
   345  	MOVQ	16(DI), DX		// arg 3 out
   346  	MOVQ	24(DI), CX		// arg 4 size
   347  	MOVQ	32(DI), R8		// arg 5 dst
   348  	MOVQ	40(DI), R9		// arg 6 ndst
   349  	MOVQ	0(DI), DI		// arg 1 mib
   350  	CALL	libc_sysctl(SB)
   351  	POPQ	BP
   352  	RET
   353  
   354  TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   355  	PUSHQ	BP
   356  	MOVQ	SP, BP
   357  	CALL	libc_kqueue(SB)
   358  	POPQ	BP
   359  	RET
   360  
   361  TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
   362  	PUSHQ	BP
   363  	MOVQ	SP, BP
   364  	MOVQ	8(DI), SI		// arg 2 keventt
   365  	MOVL	16(DI), DX		// arg 3 nch
   366  	MOVQ	24(DI), CX		// arg 4 ev
   367  	MOVL	32(DI), R8		// arg 5 nev
   368  	MOVQ	40(DI), R9		// arg 6 ts
   369  	MOVL	0(DI), DI		// arg 1 kq
   370  	CALL	libc_kevent(SB)
   371  	CMPQ	AX, $-1
   372  	JNE	ok
   373  	CALL	libc_error(SB)
   374  	MOVLQSX	(AX), AX		// errno
   375  	NEGQ	AX			// caller wants it as a negative error code
   376  ok:
   377  	POPQ	BP
   378  	RET
   379  
   380  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   381  	PUSHQ	BP
   382  	MOVQ	SP, BP
   383  	MOVL	4(DI), SI		// arg 2 cmd
   384  	MOVL	8(DI), DX		// arg 3 arg
   385  	MOVL	0(DI), DI		// arg 1 fd
   386  	CALL	libc_fcntl(SB)
   387  	POPQ	BP
   388  	RET
   389  
   390  // mstart_stub is the first function executed on a new thread started by pthread_create.
   391  // It just does some low-level setup and then calls mstart.
   392  // Note: called with the C calling convention.
   393  TEXT runtime·mstart_stub(SB),NOSPLIT,$0
   394  	// DI points to the m.
   395  	// We are already on m's g0 stack.
   396  
   397  	// Save callee-save registers.
   398  	SUBQ	$40, SP
   399  	MOVQ	BX, 0(SP)
   400  	MOVQ	R12, 8(SP)
   401  	MOVQ	R13, 16(SP)
   402  	MOVQ	R14, 24(SP)
   403  	MOVQ	R15, 32(SP)
   404  
   405  	MOVQ	m_g0(DI), DX // g
   406  
   407  	// Initialize TLS entry.
   408  	// See cmd/link/internal/ld/sym.go:computeTLSOffset.
   409  	MOVQ	DX, 0x30(GS)
   410  
   411  	// Someday the convention will be D is always cleared.
   412  	CLD
   413  
   414  	CALL	runtime·mstart(SB)
   415  
   416  	// Restore callee-save registers.
   417  	MOVQ	0(SP), BX
   418  	MOVQ	8(SP), R12
   419  	MOVQ	16(SP), R13
   420  	MOVQ	24(SP), R14
   421  	MOVQ	32(SP), R15
   422  
   423  	// Go is all done with this OS thread.
   424  	// Tell pthread everything is ok (we never join with this thread, so
   425  	// the value here doesn't really matter).
   426  	XORL	AX, AX
   427  
   428  	ADDQ	$40, SP
   429  	RET
   430  
   431  // These trampolines help convert from Go calling convention to C calling convention.
   432  // They should be called with asmcgocall.
   433  // A pointer to the arguments is passed in DI.
   434  // A single int32 result is returned in AX.
   435  // (For more results, make an args/results structure.)
   436  TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
   437  	PUSHQ	BP	// make frame, keep stack 16-byte aligned.
   438  	MOVQ	SP, BP
   439  	MOVQ	0(DI), DI // arg 1 attr
   440  	CALL	libc_pthread_attr_init(SB)
   441  	POPQ	BP
   442  	RET
   443  
   444  TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0
   445  	PUSHQ	BP
   446  	MOVQ	SP, BP
   447  	MOVQ	8(DI), SI	// arg 2 size
   448  	MOVQ	0(DI), DI	// arg 1 attr
   449  	CALL	libc_pthread_attr_setstacksize(SB)
   450  	POPQ	BP
   451  	RET
   452  
   453  TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
   454  	PUSHQ	BP
   455  	MOVQ	SP, BP
   456  	MOVQ	8(DI), SI	// arg 2 state
   457  	MOVQ	0(DI), DI	// arg 1 attr
   458  	CALL	libc_pthread_attr_setdetachstate(SB)
   459  	POPQ	BP
   460  	RET
   461  
   462  TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
   463  	PUSHQ	BP
   464  	MOVQ	SP, BP
   465  	SUBQ	$16, SP
   466  	MOVQ	0(DI), SI	// arg 2 attr
   467  	MOVQ	8(DI), DX	// arg 3 start
   468  	MOVQ	16(DI), CX	// arg 4 arg
   469  	MOVQ	SP, DI		// arg 1 &threadid (which we throw away)
   470  	CALL	libc_pthread_create(SB)
   471  	MOVQ	BP, SP
   472  	POPQ	BP
   473  	RET
   474  
   475  TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
   476  	PUSHQ	BP
   477  	MOVQ	SP, BP
   478  	MOVL	0(DI), DI	// arg 1 signal
   479  	CALL	libc_raise(SB)
   480  	POPQ	BP
   481  	RET
   482  
   483  TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
   484  	PUSHQ	BP
   485  	MOVQ	SP, BP
   486  	MOVQ	8(DI), SI	// arg 2 attr
   487  	MOVQ	0(DI), DI	// arg 1 mutex
   488  	CALL	libc_pthread_mutex_init(SB)
   489  	POPQ	BP
   490  	RET
   491  
   492  TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
   493  	PUSHQ	BP
   494  	MOVQ	SP, BP
   495  	MOVQ	0(DI), DI	// arg 1 mutex
   496  	CALL	libc_pthread_mutex_lock(SB)
   497  	POPQ	BP
   498  	RET
   499  
   500  TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
   501  	PUSHQ	BP
   502  	MOVQ	SP, BP
   503  	MOVQ	0(DI), DI	// arg 1 mutex
   504  	CALL	libc_pthread_mutex_unlock(SB)
   505  	POPQ	BP
   506  	RET
   507  
   508  TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
   509  	PUSHQ	BP
   510  	MOVQ	SP, BP
   511  	MOVQ	8(DI), SI	// arg 2 attr
   512  	MOVQ	0(DI), DI	// arg 1 cond
   513  	CALL	libc_pthread_cond_init(SB)
   514  	POPQ	BP
   515  	RET
   516  
   517  TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
   518  	PUSHQ	BP
   519  	MOVQ	SP, BP
   520  	MOVQ	8(DI), SI	// arg 2 mutex
   521  	MOVQ	0(DI), DI	// arg 1 cond
   522  	CALL	libc_pthread_cond_wait(SB)
   523  	POPQ	BP
   524  	RET
   525  
   526  TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
   527  	PUSHQ	BP
   528  	MOVQ	SP, BP
   529  	MOVQ	8(DI), SI	// arg 2 mutex
   530  	MOVQ	16(DI), DX	// arg 3 timeout
   531  	MOVQ	0(DI), DI	// arg 1 cond
   532  	CALL	libc_pthread_cond_timedwait_relative_np(SB)
   533  	POPQ	BP
   534  	RET
   535  
   536  TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
   537  	PUSHQ	BP
   538  	MOVQ	SP, BP
   539  	MOVQ	0(DI), DI	// arg 1 cond
   540  	CALL	libc_pthread_cond_signal(SB)
   541  	POPQ	BP
   542  	RET