Text file src/runtime/sys_darwin_arm64.s

     1  // Copyright 2015 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 ARM64, 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_arm64.h"
    13  
    14  #define CLOCK_REALTIME		0
    15  
    16  TEXT notok<>(SB),NOSPLIT,$0
    17  	MOVD	$0, R8
    18  	MOVD	R8, (R8)
    19  	B	0(PC)
    20  
    21  TEXT runtime·open_trampoline(SB),NOSPLIT,$0
    22  	SUB	$16, RSP
    23  	MOVW	8(R0), R1	// arg 2 flags
    24  	MOVW	12(R0), R2	// arg 3 mode
    25  	MOVW	R2, (RSP)	// arg 3 is variadic, pass on stack
    26  	MOVD	0(R0), R0	// arg 1 pathname
    27  	BL	libc_open(SB)
    28  	ADD	$16, RSP
    29  	RET
    30  
    31  TEXT runtime·close_trampoline(SB),NOSPLIT,$0
    32  	MOVW	0(R0), R0	// arg 1 fd
    33  	BL	libc_close(SB)
    34  	RET
    35  
    36  TEXT runtime·write_trampoline(SB),NOSPLIT,$0
    37  	MOVD	8(R0), R1	// arg 2 buf
    38  	MOVW	16(R0), R2	// arg 3 count
    39  	MOVW	0(R0), R0	// arg 1 fd
    40  	BL	libc_write(SB)
    41  	MOVD	$-1, R1
    42  	CMP	R0, R1
    43  	BNE	noerr
    44  	BL	libc_error(SB)
    45  	MOVW	(R0), R0
    46  	NEG	R0, R0		// caller expects negative errno value
    47  noerr:
    48  	RET
    49  
    50  TEXT runtime·read_trampoline(SB),NOSPLIT,$0
    51  	MOVD	8(R0), R1	// arg 2 buf
    52  	MOVW	16(R0), R2	// arg 3 count
    53  	MOVW	0(R0), R0	// arg 1 fd
    54  	BL	libc_read(SB)
    55  	MOVD	$-1, R1
    56  	CMP	R0, R1
    57  	BNE	noerr
    58  	BL	libc_error(SB)
    59  	MOVW	(R0), R0
    60  	NEG	R0, R0		// caller expects negative errno value
    61  noerr:
    62  	RET
    63  
    64  TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0
    65  	BL	libc_pipe(SB)	// pointer already in R0
    66  	CMP	$0, R0
    67  	BEQ	3(PC)
    68  	BL	libc_error(SB)	// return negative errno value
    69  	NEG	R0, R0
    70  	RET
    71  
    72  TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0
    73  	MOVW	0(R0), R0
    74  	BL	libc_exit(SB)
    75  	MOVD	$1234, R0
    76  	MOVD	$1002, R1
    77  	MOVD	R0, (R1)	// fail hard
    78  
    79  TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
    80  	MOVD	0(R0), R19	// signal
    81  	BL	libc_getpid(SB)
    82  	// arg 1 pid already in R0 from getpid
    83  	MOVD	R19, R1	// arg 2 signal
    84  	BL	libc_kill(SB)
    85  	RET
    86  
    87  TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
    88  	MOVD	R0, R19
    89  	MOVD	0(R19), R0	// arg 1 addr
    90  	MOVD	8(R19), R1	// arg 2 len
    91  	MOVW	16(R19), R2	// arg 3 prot
    92  	MOVW	20(R19), R3	// arg 4 flags
    93  	MOVW	24(R19), R4	// arg 5 fd
    94  	MOVW	28(R19), R5	// arg 6 off
    95  	BL	libc_mmap(SB)
    96  	MOVD	$0, R1
    97  	MOVD	$-1, R2
    98  	CMP	R0, R2
    99  	BNE	ok
   100  	BL	libc_error(SB)
   101  	MOVW	(R0), R1
   102  	MOVD	$0, R0
   103  ok:
   104  	MOVD	R0, 32(R19) // ret 1 p
   105  	MOVD	R1, 40(R19)	// ret 2 err
   106  	RET
   107  
   108  TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
   109  	MOVD	8(R0), R1	// arg 2 len
   110  	MOVD	0(R0), R0	// arg 1 addr
   111  	BL	libc_munmap(SB)
   112  	CMP	$0, R0
   113  	BEQ	2(PC)
   114  	BL	notok<>(SB)
   115  	RET
   116  
   117  TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0
   118  	MOVD	8(R0), R1	// arg 2 len
   119  	MOVW	16(R0), R2	// arg 3 advice
   120  	MOVD	0(R0), R0	// arg 1 addr
   121  	BL	libc_madvise(SB)
   122  	RET
   123  
   124  TEXT runtime·mlock_trampoline(SB),NOSPLIT,$0
   125  	MOVD	8(R0), R1	// arg 2 len
   126  	MOVD	0(R0), R0	// arg 1 addr
   127  	BL	libc_mlock(SB)
   128  	RET
   129  
   130  TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
   131  	MOVD	8(R0), R1	// arg 2 new
   132  	MOVD	16(R0), R2	// arg 3 old
   133  	MOVW	0(R0), R0	// arg 1 which
   134  	BL	libc_setitimer(SB)
   135  	RET
   136  
   137  TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
   138  	MOVD	R0, R1			// arg 2 timespec
   139  	MOVW	$CLOCK_REALTIME, R0 	// arg 1 clock_id
   140  	BL	libc_clock_gettime(SB)
   141  	RET
   142  
   143  GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
   144  
   145  TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40
   146  	MOVD	R0, R19
   147  	BL	libc_mach_absolute_time(SB)
   148  	MOVD	R0, 0(R19)
   149  	MOVW	timebase<>+machTimebaseInfo_numer(SB), R20
   150  	MOVD	$timebase<>+machTimebaseInfo_denom(SB), R21
   151  	LDARW	(R21), R21	// atomic read
   152  	CMP	$0, R21
   153  	BNE	initialized
   154  
   155  	SUB	$(machTimebaseInfo__size+15)/16*16, RSP
   156  	MOVD	RSP, R0
   157  	BL	libc_mach_timebase_info(SB)
   158  	MOVW	machTimebaseInfo_numer(RSP), R20
   159  	MOVW	machTimebaseInfo_denom(RSP), R21
   160  	ADD	$(machTimebaseInfo__size+15)/16*16, RSP
   161  
   162  	MOVW	R20, timebase<>+machTimebaseInfo_numer(SB)
   163  	MOVD	$timebase<>+machTimebaseInfo_denom(SB), R22
   164  	STLRW	R21, (R22)	// atomic write
   165  
   166  initialized:
   167  	MOVW	R20, 8(R19)
   168  	MOVW	R21, 12(R19)
   169  	RET
   170  
   171  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   172  	MOVW	sig+8(FP), R0
   173  	MOVD	info+16(FP), R1
   174  	MOVD	ctx+24(FP), R2
   175  	MOVD	fn+0(FP), R11
   176  	BL	(R11)
   177  	RET
   178  
   179  TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$176
   180  	// Save callee-save registers in the case of signal forwarding.
   181  	// Please refer to https://golang.org/issue/31827 .
   182  	SAVE_R19_TO_R28(8*4)
   183  	SAVE_F8_TO_F15(8*14)
   184  
   185  	// Save arguments.
   186  	MOVW	R0, (8*1)(RSP)	// sig
   187  	MOVD	R1, (8*2)(RSP)	// info
   188  	MOVD	R2, (8*3)(RSP)	// ctx
   189  
   190  	// this might be called in external code context,
   191  	// where g is not set.
   192  	BL	runtime·load_g(SB)
   193  
   194  #ifdef GOOS_ios
   195  	MOVD	RSP, R6
   196  	CMP	$0, g
   197  	BEQ	nog
   198  	// iOS always use the main stack to run the signal handler.
   199  	// We need to switch to gsignal ourselves.
   200  	MOVD	g_m(g), R11
   201  	MOVD	m_gsignal(R11), R5
   202  	MOVD	(g_stack+stack_hi)(R5), R6
   203  
   204  nog:
   205  	// Restore arguments.
   206  	MOVW	(8*1)(RSP), R0
   207  	MOVD	(8*2)(RSP), R1
   208  	MOVD	(8*3)(RSP), R2
   209  
   210  	// Reserve space for args and the stack pointer on the
   211  	// gsignal stack.
   212  	SUB	$48, R6
   213  	// Save stack pointer.
   214  	MOVD	RSP, R4
   215  	MOVD	R4, (8*4)(R6)
   216  	// Switch to gsignal stack.
   217  	MOVD	R6, RSP
   218  
   219  	// Save arguments.
   220  	MOVW	R0, (8*1)(RSP)
   221  	MOVD	R1, (8*2)(RSP)
   222  	MOVD	R2, (8*3)(RSP)
   223  #endif
   224  
   225  	// Call sigtrampgo.
   226  	MOVD	$runtime·sigtrampgo(SB), R11
   227  	BL	(R11)
   228  
   229  #ifdef GOOS_ios
   230  	// Switch to old stack.
   231  	MOVD	(8*4)(RSP), R5
   232  	MOVD	R5, RSP
   233  #endif
   234  
   235  	// Restore callee-save registers.
   236  	RESTORE_R19_TO_R28(8*4)
   237  	RESTORE_F8_TO_F15(8*14)
   238  
   239  	RET
   240  
   241  TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
   242  	JMP	runtime·sigtramp(SB)
   243  
   244  TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   245  	MOVD	8(R0), R1	// arg 2 new
   246  	MOVD	16(R0), R2	// arg 3 old
   247  	MOVW	0(R0), R0	// arg 1 how
   248  	BL	libc_pthread_sigmask(SB)
   249  	CMP	$0, R0
   250  	BEQ	2(PC)
   251  	BL	notok<>(SB)
   252  	RET
   253  
   254  TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
   255  	MOVD	8(R0), R1	// arg 2 new
   256  	MOVD	16(R0), R2	// arg 3 old
   257  	MOVW	0(R0), R0	// arg 1 how
   258  	BL	libc_sigaction(SB)
   259  	CMP	$0, R0
   260  	BEQ	2(PC)
   261  	BL	notok<>(SB)
   262  	RET
   263  
   264  TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   265  	MOVW	0(R0), R0	// arg 1 usec
   266  	BL	libc_usleep(SB)
   267  	RET
   268  
   269  TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
   270  	MOVW	8(R0), R1	// arg 2 miblen
   271  	MOVD	16(R0), R2	// arg 3 oldp
   272  	MOVD	24(R0), R3	// arg 4 oldlenp
   273  	MOVD	32(R0), R4	// arg 5 newp
   274  	MOVD	40(R0), R5	// arg 6 newlen
   275  	MOVD	0(R0), R0	// arg 1 mib
   276  	BL	libc_sysctl(SB)
   277  	RET
   278  
   279  TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0
   280  	MOVD	8(R0), R1	// arg 2 oldp
   281  	MOVD	16(R0), R2	// arg 3 oldlenp
   282  	MOVD	24(R0), R3	// arg 4 newp
   283  	MOVD	32(R0), R4	// arg 5 newlen
   284  	MOVD	0(R0), R0	// arg 1 name
   285  	BL	libc_sysctlbyname(SB)
   286  	RET
   287  
   288  
   289  TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   290  	BL	libc_kqueue(SB)
   291  	RET
   292  
   293  TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
   294  	MOVD	8(R0), R1	// arg 2 keventt
   295  	MOVW	16(R0), R2	// arg 3 nch
   296  	MOVD	24(R0), R3	// arg 4 ev
   297  	MOVW	32(R0), R4	// arg 5 nev
   298  	MOVD	40(R0), R5	// arg 6 ts
   299  	MOVW	0(R0), R0	// arg 1 kq
   300  	BL	libc_kevent(SB)
   301  	MOVD	$-1, R2
   302  	CMP	R0, R2
   303  	BNE	ok
   304  	BL	libc_error(SB)
   305  	MOVW	(R0), R0	// errno
   306  	NEG	R0, R0	// caller wants it as a negative error code
   307  ok:
   308  	RET
   309  
   310  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   311  	SUB	$16, RSP
   312  	MOVD	R0, R19
   313  	MOVW	0(R19), R0	// arg 1 fd
   314  	MOVW	4(R19), R1	// arg 2 cmd
   315  	MOVW	8(R19), R2	// arg 3 arg
   316  	MOVW	R2, (RSP)	// arg 3 is variadic, pass on stack
   317  	BL	libc_fcntl(SB)
   318  	MOVD	$0, R1
   319  	MOVD	$-1, R2
   320  	CMP	R0, R2
   321  	BNE	noerr
   322  	BL	libc_error(SB)
   323  	MOVW	(R0), R1
   324  	MOVW	$-1, R0
   325  noerr:
   326  	MOVW	R0, 12(R19)
   327  	MOVW	R1, 16(R19)
   328  	ADD	$16, RSP
   329  	RET
   330  
   331  TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   332  #ifdef GOOS_ios
   333  	// sigaltstack on iOS is not supported and will always
   334  	// run the signal handler on the main stack, so our sigtramp has
   335  	// to do the stack switch ourselves.
   336  	MOVW	$43, R0
   337  	BL	libc_exit(SB)
   338  #else
   339  	MOVD	8(R0), R1		// arg 2 old
   340  	MOVD	0(R0), R0		// arg 1 new
   341  	CALL	libc_sigaltstack(SB)
   342  	CBZ	R0, 2(PC)
   343  	BL	notok<>(SB)
   344  #endif
   345  	RET
   346  
   347  // Thread related functions
   348  
   349  // mstart_stub is the first function executed on a new thread started by pthread_create.
   350  // It just does some low-level setup and then calls mstart.
   351  // Note: called with the C calling convention.
   352  TEXT runtime·mstart_stub(SB),NOSPLIT,$160
   353  	// R0 points to the m.
   354  	// We are already on m's g0 stack.
   355  
   356  	// Save callee-save registers.
   357  	SAVE_R19_TO_R28(8)
   358  	SAVE_F8_TO_F15(88)
   359  
   360  	MOVD	m_g0(R0), g
   361  	BL	·save_g(SB)
   362  
   363  	BL	runtime·mstart(SB)
   364  
   365  	// Restore callee-save registers.
   366  	RESTORE_R19_TO_R28(8)
   367  	RESTORE_F8_TO_F15(88)
   368  
   369  	// Go is all done with this OS thread.
   370  	// Tell pthread everything is ok (we never join with this thread, so
   371  	// the value here doesn't really matter).
   372  	MOVD	$0, R0
   373  
   374  	RET
   375  
   376  TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
   377  	MOVD	0(R0), R0	// arg 1 attr
   378  	BL	libc_pthread_attr_init(SB)
   379  	RET
   380  
   381  TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
   382  	MOVD	8(R0), R1	// arg 2 size
   383  	MOVD	0(R0), R0	// arg 1 attr
   384  	BL	libc_pthread_attr_getstacksize(SB)
   385  	RET
   386  
   387  TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
   388  	MOVD	8(R0), R1	// arg 2 state
   389  	MOVD	0(R0), R0	// arg 1 attr
   390  	BL	libc_pthread_attr_setdetachstate(SB)
   391  	RET
   392  
   393  TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
   394  	SUB	$16, RSP
   395  	MOVD	0(R0), R1	// arg 2 state
   396  	MOVD	8(R0), R2	// arg 3 start
   397  	MOVD	16(R0), R3	// arg 4 arg
   398  	MOVD	RSP, R0 	// arg 1 &threadid (which we throw away)
   399  	BL	libc_pthread_create(SB)
   400  	ADD	$16, RSP
   401  	RET
   402  
   403  TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
   404  	MOVW	0(R0), R0	// arg 1 sig
   405  	BL	libc_raise(SB)
   406  	RET
   407  
   408  TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
   409  	MOVD	8(R0), R1	// arg 2 attr
   410  	MOVD	0(R0), R0	// arg 1 mutex
   411  	BL	libc_pthread_mutex_init(SB)
   412  	RET
   413  
   414  TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
   415  	MOVD	0(R0), R0	// arg 1 mutex
   416  	BL	libc_pthread_mutex_lock(SB)
   417  	RET
   418  
   419  TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
   420  	MOVD	0(R0), R0	// arg 1 mutex
   421  	BL	libc_pthread_mutex_unlock(SB)
   422  	RET
   423  
   424  TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
   425  	MOVD	8(R0), R1	// arg 2 attr
   426  	MOVD	0(R0), R0	// arg 1 cond
   427  	BL	libc_pthread_cond_init(SB)
   428  	RET
   429  
   430  TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
   431  	MOVD	8(R0), R1	// arg 2 mutex
   432  	MOVD	0(R0), R0	// arg 1 cond
   433  	BL	libc_pthread_cond_wait(SB)
   434  	RET
   435  
   436  TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
   437  	MOVD	8(R0), R1	// arg 2 mutex
   438  	MOVD	16(R0), R2	// arg 3 timeout
   439  	MOVD	0(R0), R0	// arg 1 cond
   440  	BL	libc_pthread_cond_timedwait_relative_np(SB)
   441  	RET
   442  
   443  TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
   444  	MOVD	0(R0), R0	// arg 1 cond
   445  	BL	libc_pthread_cond_signal(SB)
   446  	RET
   447  
   448  TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
   449  	MOVD	R0, R19		// R19 is callee-save
   450  	BL	libc_pthread_self(SB)
   451  	MOVD	R0, 0(R19)	// return value
   452  	RET
   453  
   454  TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
   455  	MOVD	8(R0), R1	// arg 2 sig
   456  	MOVD	0(R0), R0	// arg 1 thread
   457  	BL	libc_pthread_kill(SB)
   458  	RET
   459  
   460  TEXT runtime·pthread_key_create_trampoline(SB),NOSPLIT,$0
   461  	MOVD	8(R0), R1	// arg 2 destructor
   462  	MOVD	0(R0), R0	// arg 1 *key
   463  	BL	libc_pthread_key_create(SB)
   464  	RET
   465  
   466  TEXT runtime·pthread_setspecific_trampoline(SB),NOSPLIT,$0
   467  	MOVD	8(R0), R1	// arg 2 value
   468  	MOVD	0(R0), R0	// arg 1 key
   469  	BL	libc_pthread_setspecific(SB)
   470  	RET
   471  
   472  TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
   473  	MOVD	$0, R0	// arg 1 val
   474  	BL	libc_notify_is_valid_token(SB)
   475  	BL	libc_xpc_date_create_from_current(SB)
   476  	RET
   477  
   478  TEXT runtime·arc4random_buf_trampoline(SB),NOSPLIT,$0
   479  	MOVW	8(R0), R1	// arg 2 nbytes
   480  	MOVD	0(R0), R0	// arg 1 buf
   481  	BL	libc_arc4random_buf(SB)
   482  	RET
   483  
   484  // syscall calls a function in libc on behalf of the syscall package.
   485  // syscall takes a pointer to a struct like:
   486  // struct {
   487  //	fn    uintptr
   488  //	a1    uintptr
   489  //	a2    uintptr
   490  //	a3    uintptr
   491  //	r1    uintptr
   492  //	r2    uintptr
   493  //	err   uintptr
   494  // }
   495  // syscall must be called on the g0 stack with the
   496  // C calling convention (use libcCall).
   497  TEXT runtime·syscall(SB),NOSPLIT,$0
   498  	SUB	$16, RSP	// push structure pointer
   499  	MOVD	R0, 8(RSP)
   500  
   501  	MOVD	0(R0), R12	// fn
   502  	MOVD	16(R0), R1	// a2
   503  	MOVD	24(R0), R2	// a3
   504  	MOVD	8(R0), R0	// a1
   505  
   506  	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   507  	// (Because ios decided not to adhere to the standard arm64 calling convention, sigh...)
   508  	// The only libSystem calls we support that are vararg are open, fcntl, and ioctl,
   509  	// which are all of the form fn(x, y, ...). So we just need to put the 3rd arg
   510  	// on the stack as well.
   511  	// If we ever have other vararg libSystem calls, we might need to handle more cases.
   512  	MOVD	R2, (RSP)
   513  
   514  	BL	(R12)
   515  
   516  	MOVD	8(RSP), R2	// pop structure pointer
   517  	ADD	$16, RSP
   518  	MOVD	R0, 32(R2)	// save r1
   519  	MOVD	R1, 40(R2)	// save r2
   520  	CMPW	$-1, R0
   521  	BNE	ok
   522  	SUB	$16, RSP	// push structure pointer
   523  	MOVD	R2, 8(RSP)
   524  	BL	libc_error(SB)
   525  	MOVW	(R0), R0
   526  	MOVD	8(RSP), R2	// pop structure pointer
   527  	ADD	$16, RSP
   528  	MOVD	R0, 48(R2)	// save err
   529  ok:
   530  	RET
   531  
   532  // syscallX calls a function in libc on behalf of the syscall package.
   533  // syscallX takes a pointer to a struct like:
   534  // struct {
   535  //	fn    uintptr
   536  //	a1    uintptr
   537  //	a2    uintptr
   538  //	a3    uintptr
   539  //	r1    uintptr
   540  //	r2    uintptr
   541  //	err   uintptr
   542  // }
   543  // syscallX must be called on the g0 stack with the
   544  // C calling convention (use libcCall).
   545  TEXT runtime·syscallX(SB),NOSPLIT,$0
   546  	SUB	$16, RSP	// push structure pointer
   547  	MOVD	R0, (RSP)
   548  
   549  	MOVD	0(R0), R12	// fn
   550  	MOVD	16(R0), R1	// a2
   551  	MOVD	24(R0), R2	// a3
   552  	MOVD	8(R0), R0	// a1
   553  	BL	(R12)
   554  
   555  	MOVD	(RSP), R2	// pop structure pointer
   556  	ADD	$16, RSP
   557  	MOVD	R0, 32(R2)	// save r1
   558  	MOVD	R1, 40(R2)	// save r2
   559  	CMP	$-1, R0
   560  	BNE	ok
   561  	SUB	$16, RSP	// push structure pointer
   562  	MOVD	R2, (RSP)
   563  	BL	libc_error(SB)
   564  	MOVW	(R0), R0
   565  	MOVD	(RSP), R2	// pop structure pointer
   566  	ADD	$16, RSP
   567  	MOVD	R0, 48(R2)	// save err
   568  ok:
   569  	RET
   570  
   571  // syscallPtr is like syscallX except that the libc function reports an
   572  // error by returning NULL and setting errno.
   573  TEXT runtime·syscallPtr(SB),NOSPLIT,$0
   574  	SUB	$16, RSP	// push structure pointer
   575  	MOVD	R0, (RSP)
   576  
   577  	MOVD	0(R0), R12	// fn
   578  	MOVD	16(R0), R1	// a2
   579  	MOVD	24(R0), R2	// a3
   580  	MOVD	8(R0), R0	// a1
   581  	BL	(R12)
   582  
   583  	MOVD	(RSP), R2	// pop structure pointer
   584  	ADD	$16, RSP
   585  	MOVD	R0, 32(R2)	// save r1
   586  	MOVD	R1, 40(R2)	// save r2
   587  	CMP	$0, R0
   588  	BNE	ok
   589  	SUB	$16, RSP	// push structure pointer
   590  	MOVD	R2, (RSP)
   591  	BL	libc_error(SB)
   592  	MOVW	(R0), R0
   593  	MOVD	(RSP), R2	// pop structure pointer
   594  	ADD	$16, RSP
   595  	MOVD	R0, 48(R2)	// save err
   596  ok:
   597  	RET
   598  
   599  // syscall6 calls a function in libc on behalf of the syscall package.
   600  // syscall6 takes a pointer to a struct like:
   601  // struct {
   602  //	fn    uintptr
   603  //	a1    uintptr
   604  //	a2    uintptr
   605  //	a3    uintptr
   606  //	a4    uintptr
   607  //	a5    uintptr
   608  //	a6    uintptr
   609  //	r1    uintptr
   610  //	r2    uintptr
   611  //	err   uintptr
   612  // }
   613  // syscall6 must be called on the g0 stack with the
   614  // C calling convention (use libcCall).
   615  TEXT runtime·syscall6(SB),NOSPLIT,$0
   616  	SUB	$16, RSP	// push structure pointer
   617  	MOVD	R0, 8(RSP)
   618  
   619  	MOVD	0(R0), R12	// fn
   620  	MOVD	16(R0), R1	// a2
   621  	MOVD	24(R0), R2	// a3
   622  	MOVD	32(R0), R3	// a4
   623  	MOVD	40(R0), R4	// a5
   624  	MOVD	48(R0), R5	// a6
   625  	MOVD	8(R0), R0	// a1
   626  
   627  	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   628  	// See syscall above. The only function this applies to is openat, for which the 4th
   629  	// arg must be on the stack.
   630  	MOVD	R3, (RSP)
   631  
   632  	BL	(R12)
   633  
   634  	MOVD	8(RSP), R2	// pop structure pointer
   635  	ADD	$16, RSP
   636  	MOVD	R0, 56(R2)	// save r1
   637  	MOVD	R1, 64(R2)	// save r2
   638  	CMPW	$-1, R0
   639  	BNE	ok
   640  	SUB	$16, RSP	// push structure pointer
   641  	MOVD	R2, 8(RSP)
   642  	BL	libc_error(SB)
   643  	MOVW	(R0), R0
   644  	MOVD	8(RSP), R2	// pop structure pointer
   645  	ADD	$16, RSP
   646  	MOVD	R0, 72(R2)	// save err
   647  ok:
   648  	RET
   649  
   650  // syscall6X calls a function in libc on behalf of the syscall package.
   651  // syscall6X takes a pointer to a struct like:
   652  // struct {
   653  //	fn    uintptr
   654  //	a1    uintptr
   655  //	a2    uintptr
   656  //	a3    uintptr
   657  //	a4    uintptr
   658  //	a5    uintptr
   659  //	a6    uintptr
   660  //	r1    uintptr
   661  //	r2    uintptr
   662  //	err   uintptr
   663  // }
   664  // syscall6X must be called on the g0 stack with the
   665  // C calling convention (use libcCall).
   666  TEXT runtime·syscall6X(SB),NOSPLIT,$0
   667  	SUB	$16, RSP	// push structure pointer
   668  	MOVD	R0, (RSP)
   669  
   670  	MOVD	0(R0), R12	// fn
   671  	MOVD	16(R0), R1	// a2
   672  	MOVD	24(R0), R2	// a3
   673  	MOVD	32(R0), R3	// a4
   674  	MOVD	40(R0), R4	// a5
   675  	MOVD	48(R0), R5	// a6
   676  	MOVD	8(R0), R0	// a1
   677  	BL	(R12)
   678  
   679  	MOVD	(RSP), R2	// pop structure pointer
   680  	ADD	$16, RSP
   681  	MOVD	R0, 56(R2)	// save r1
   682  	MOVD	R1, 64(R2)	// save r2
   683  	CMP	$-1, R0
   684  	BNE	ok
   685  	SUB	$16, RSP	// push structure pointer
   686  	MOVD	R2, (RSP)
   687  	BL	libc_error(SB)
   688  	MOVW	(R0), R0
   689  	MOVD	(RSP), R2	// pop structure pointer
   690  	ADD	$16, RSP
   691  	MOVD	R0, 72(R2)	// save err
   692  ok:
   693  	RET
   694  
   695  // syscall9 calls a function in libc on behalf of the syscall package.
   696  // syscall9 takes a pointer to a struct like:
   697  // struct {
   698  //	fn    uintptr
   699  //	a1    uintptr
   700  //	a2    uintptr
   701  //	a3    uintptr
   702  //	a4    uintptr
   703  //	a5    uintptr
   704  //	a6    uintptr
   705  //	a7    uintptr
   706  //	a8    uintptr
   707  //	a9    uintptr
   708  //	r1    uintptr
   709  //	r2    uintptr
   710  //	err   uintptr
   711  // }
   712  // syscall9 must be called on the g0 stack with the
   713  // C calling convention (use libcCall).
   714  TEXT runtime·syscall9(SB),NOSPLIT,$0
   715  	SUB	$16, RSP	// push structure pointer
   716  	MOVD	R0, 8(RSP)
   717  
   718  	MOVD	0(R0), R12	// fn
   719  	MOVD	16(R0), R1	// a2
   720  	MOVD	24(R0), R2	// a3
   721  	MOVD	32(R0), R3	// a4
   722  	MOVD	40(R0), R4	// a5
   723  	MOVD	48(R0), R5	// a6
   724  	MOVD	56(R0), R6	// a7
   725  	MOVD	64(R0), R7	// a8
   726  	MOVD	72(R0), R8	// a9
   727  	MOVD	8(R0), R0	// a1
   728  
   729  	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   730  	// See syscall above. The only function this applies to is openat, for which the 4th
   731  	// arg must be on the stack.
   732  	MOVD	R3, (RSP)
   733  
   734  	BL	(R12)
   735  
   736  	MOVD	8(RSP), R2	// pop structure pointer
   737  	ADD	$16, RSP
   738  	MOVD	R0, 80(R2)	// save r1
   739  	MOVD	R1, 88(R2)	// save r2
   740  	CMPW	$-1, R0
   741  	BNE	ok
   742  	SUB	$16, RSP	// push structure pointer
   743  	MOVD	R2, 8(RSP)
   744  	BL	libc_error(SB)
   745  	MOVW	(R0), R0
   746  	MOVD	8(RSP), R2	// pop structure pointer
   747  	ADD	$16, RSP
   748  	MOVD	R0, 96(R2)	// save err
   749  ok:
   750  	RET
   751  
   752  // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
   753  // takes 5 uintptrs and 1 float64, and only returns one value,
   754  // for use with standard C ABI functions.
   755  TEXT runtime·syscall_x509(SB),NOSPLIT,$0
   756  	SUB	$16, RSP	// push structure pointer
   757  	MOVD	R0, (RSP)
   758  
   759  	MOVD	0(R0), R12	// fn
   760  	MOVD	16(R0), R1	// a2
   761  	MOVD	24(R0), R2	// a3
   762  	MOVD	32(R0), R3	// a4
   763  	MOVD	40(R0), R4	// a5
   764  	FMOVD	48(R0), F0	// f1
   765  	MOVD	8(R0), R0	// a1
   766  	BL	(R12)
   767  
   768  	MOVD	(RSP), R2	// pop structure pointer
   769  	ADD	$16, RSP
   770  	MOVD	R0, 56(R2)	// save r1
   771  	RET
   772  
   773  TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
   774  	BL	libc_issetugid(SB)
   775  	RET
   776  
   777  // mach_vm_region_trampoline calls mach_vm_region from libc.
   778  TEXT runtime·mach_vm_region_trampoline(SB),NOSPLIT,$0
   779  	MOVD	0(R0), R1	// address
   780  	MOVD	8(R0), R2	// size
   781  	MOVW	16(R0), R3	// flavor
   782  	MOVD	24(R0), R4	// info
   783  	MOVD	32(R0), R5	// count
   784  	MOVD	40(R0), R6  // object_name
   785  	MOVD	$libc_mach_task_self_(SB), R0
   786  	MOVW	0(R0), R0
   787  	BL	libc_mach_vm_region(SB)
   788  	RET
   789  
   790  // proc_regionfilename_trampoline calls proc_regionfilename for
   791  // the current process.
   792  TEXT runtime·proc_regionfilename_trampoline(SB),NOSPLIT,$0
   793  	MOVD	8(R0), R1	// address
   794  	MOVD	16(R0), R2	// buffer
   795  	MOVD	24(R0), R3	// buffer_size
   796  	MOVD	0(R0), R0 // pid
   797  	BL	libc_proc_regionfilename(SB)
   798  	RET
   799  

View as plain text