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  // syscall calls a function in libc on behalf of the syscall package.
   479  // syscall takes a pointer to a struct like:
   480  // struct {
   481  //	fn    uintptr
   482  //	a1    uintptr
   483  //	a2    uintptr
   484  //	a3    uintptr
   485  //	r1    uintptr
   486  //	r2    uintptr
   487  //	err   uintptr
   488  // }
   489  // syscall must be called on the g0 stack with the
   490  // C calling convention (use libcCall).
   491  TEXT runtime·syscall(SB),NOSPLIT,$0
   492  	SUB	$16, RSP	// push structure pointer
   493  	MOVD	R0, 8(RSP)
   494  
   495  	MOVD	0(R0), R12	// fn
   496  	MOVD	16(R0), R1	// a2
   497  	MOVD	24(R0), R2	// a3
   498  	MOVD	8(R0), R0	// a1
   499  
   500  	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   501  	// (Because ios decided not to adhere to the standard arm64 calling convention, sigh...)
   502  	// The only libSystem calls we support that are vararg are open, fcntl, and ioctl,
   503  	// which are all of the form fn(x, y, ...). So we just need to put the 3rd arg
   504  	// on the stack as well.
   505  	// If we ever have other vararg libSystem calls, we might need to handle more cases.
   506  	MOVD	R2, (RSP)
   507  
   508  	BL	(R12)
   509  
   510  	MOVD	8(RSP), R2	// pop structure pointer
   511  	ADD	$16, RSP
   512  	MOVD	R0, 32(R2)	// save r1
   513  	MOVD	R1, 40(R2)	// save r2
   514  	CMPW	$-1, R0
   515  	BNE	ok
   516  	SUB	$16, RSP	// push structure pointer
   517  	MOVD	R2, 8(RSP)
   518  	BL	libc_error(SB)
   519  	MOVW	(R0), R0
   520  	MOVD	8(RSP), R2	// pop structure pointer
   521  	ADD	$16, RSP
   522  	MOVD	R0, 48(R2)	// save err
   523  ok:
   524  	RET
   525  
   526  // syscallX calls a function in libc on behalf of the syscall package.
   527  // syscallX takes a pointer to a struct like:
   528  // struct {
   529  //	fn    uintptr
   530  //	a1    uintptr
   531  //	a2    uintptr
   532  //	a3    uintptr
   533  //	r1    uintptr
   534  //	r2    uintptr
   535  //	err   uintptr
   536  // }
   537  // syscallX must be called on the g0 stack with the
   538  // C calling convention (use libcCall).
   539  TEXT runtime·syscallX(SB),NOSPLIT,$0
   540  	SUB	$16, RSP	// push structure pointer
   541  	MOVD	R0, (RSP)
   542  
   543  	MOVD	0(R0), R12	// fn
   544  	MOVD	16(R0), R1	// a2
   545  	MOVD	24(R0), R2	// a3
   546  	MOVD	8(R0), R0	// a1
   547  	BL	(R12)
   548  
   549  	MOVD	(RSP), R2	// pop structure pointer
   550  	ADD	$16, RSP
   551  	MOVD	R0, 32(R2)	// save r1
   552  	MOVD	R1, 40(R2)	// save r2
   553  	CMP	$-1, R0
   554  	BNE	ok
   555  	SUB	$16, RSP	// push structure pointer
   556  	MOVD	R2, (RSP)
   557  	BL	libc_error(SB)
   558  	MOVW	(R0), R0
   559  	MOVD	(RSP), R2	// pop structure pointer
   560  	ADD	$16, RSP
   561  	MOVD	R0, 48(R2)	// save err
   562  ok:
   563  	RET
   564  
   565  // syscallPtr is like syscallX except that the libc function reports an
   566  // error by returning NULL and setting errno.
   567  TEXT runtime·syscallPtr(SB),NOSPLIT,$0
   568  	SUB	$16, RSP	// push structure pointer
   569  	MOVD	R0, (RSP)
   570  
   571  	MOVD	0(R0), R12	// fn
   572  	MOVD	16(R0), R1	// a2
   573  	MOVD	24(R0), R2	// a3
   574  	MOVD	8(R0), R0	// a1
   575  	BL	(R12)
   576  
   577  	MOVD	(RSP), R2	// pop structure pointer
   578  	ADD	$16, RSP
   579  	MOVD	R0, 32(R2)	// save r1
   580  	MOVD	R1, 40(R2)	// save r2
   581  	CMP	$0, R0
   582  	BNE	ok
   583  	SUB	$16, RSP	// push structure pointer
   584  	MOVD	R2, (RSP)
   585  	BL	libc_error(SB)
   586  	MOVW	(R0), R0
   587  	MOVD	(RSP), R2	// pop structure pointer
   588  	ADD	$16, RSP
   589  	MOVD	R0, 48(R2)	// save err
   590  ok:
   591  	RET
   592  
   593  // syscall6 calls a function in libc on behalf of the syscall package.
   594  // syscall6 takes a pointer to a struct like:
   595  // struct {
   596  //	fn    uintptr
   597  //	a1    uintptr
   598  //	a2    uintptr
   599  //	a3    uintptr
   600  //	a4    uintptr
   601  //	a5    uintptr
   602  //	a6    uintptr
   603  //	r1    uintptr
   604  //	r2    uintptr
   605  //	err   uintptr
   606  // }
   607  // syscall6 must be called on the g0 stack with the
   608  // C calling convention (use libcCall).
   609  TEXT runtime·syscall6(SB),NOSPLIT,$0
   610  	SUB	$16, RSP	// push structure pointer
   611  	MOVD	R0, 8(RSP)
   612  
   613  	MOVD	0(R0), R12	// fn
   614  	MOVD	16(R0), R1	// a2
   615  	MOVD	24(R0), R2	// a3
   616  	MOVD	32(R0), R3	// a4
   617  	MOVD	40(R0), R4	// a5
   618  	MOVD	48(R0), R5	// a6
   619  	MOVD	8(R0), R0	// a1
   620  
   621  	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   622  	// See syscall above. The only function this applies to is openat, for which the 4th
   623  	// arg must be on the stack.
   624  	MOVD	R3, (RSP)
   625  
   626  	BL	(R12)
   627  
   628  	MOVD	8(RSP), R2	// pop structure pointer
   629  	ADD	$16, RSP
   630  	MOVD	R0, 56(R2)	// save r1
   631  	MOVD	R1, 64(R2)	// save r2
   632  	CMPW	$-1, R0
   633  	BNE	ok
   634  	SUB	$16, RSP	// push structure pointer
   635  	MOVD	R2, 8(RSP)
   636  	BL	libc_error(SB)
   637  	MOVW	(R0), R0
   638  	MOVD	8(RSP), R2	// pop structure pointer
   639  	ADD	$16, RSP
   640  	MOVD	R0, 72(R2)	// save err
   641  ok:
   642  	RET
   643  
   644  // syscall6X calls a function in libc on behalf of the syscall package.
   645  // syscall6X takes a pointer to a struct like:
   646  // struct {
   647  //	fn    uintptr
   648  //	a1    uintptr
   649  //	a2    uintptr
   650  //	a3    uintptr
   651  //	a4    uintptr
   652  //	a5    uintptr
   653  //	a6    uintptr
   654  //	r1    uintptr
   655  //	r2    uintptr
   656  //	err   uintptr
   657  // }
   658  // syscall6X must be called on the g0 stack with the
   659  // C calling convention (use libcCall).
   660  TEXT runtime·syscall6X(SB),NOSPLIT,$0
   661  	SUB	$16, RSP	// push structure pointer
   662  	MOVD	R0, (RSP)
   663  
   664  	MOVD	0(R0), R12	// fn
   665  	MOVD	16(R0), R1	// a2
   666  	MOVD	24(R0), R2	// a3
   667  	MOVD	32(R0), R3	// a4
   668  	MOVD	40(R0), R4	// a5
   669  	MOVD	48(R0), R5	// a6
   670  	MOVD	8(R0), R0	// a1
   671  	BL	(R12)
   672  
   673  	MOVD	(RSP), R2	// pop structure pointer
   674  	ADD	$16, RSP
   675  	MOVD	R0, 56(R2)	// save r1
   676  	MOVD	R1, 64(R2)	// save r2
   677  	CMP	$-1, R0
   678  	BNE	ok
   679  	SUB	$16, RSP	// push structure pointer
   680  	MOVD	R2, (RSP)
   681  	BL	libc_error(SB)
   682  	MOVW	(R0), R0
   683  	MOVD	(RSP), R2	// pop structure pointer
   684  	ADD	$16, RSP
   685  	MOVD	R0, 72(R2)	// save err
   686  ok:
   687  	RET
   688  
   689  // syscall9 calls a function in libc on behalf of the syscall package.
   690  // syscall9 takes a pointer to a struct like:
   691  // struct {
   692  //	fn    uintptr
   693  //	a1    uintptr
   694  //	a2    uintptr
   695  //	a3    uintptr
   696  //	a4    uintptr
   697  //	a5    uintptr
   698  //	a6    uintptr
   699  //	a7    uintptr
   700  //	a8    uintptr
   701  //	a9    uintptr
   702  //	r1    uintptr
   703  //	r2    uintptr
   704  //	err   uintptr
   705  // }
   706  // syscall9 must be called on the g0 stack with the
   707  // C calling convention (use libcCall).
   708  TEXT runtime·syscall9(SB),NOSPLIT,$0
   709  	SUB	$16, RSP	// push structure pointer
   710  	MOVD	R0, 8(RSP)
   711  
   712  	MOVD	0(R0), R12	// fn
   713  	MOVD	16(R0), R1	// a2
   714  	MOVD	24(R0), R2	// a3
   715  	MOVD	32(R0), R3	// a4
   716  	MOVD	40(R0), R4	// a5
   717  	MOVD	48(R0), R5	// a6
   718  	MOVD	56(R0), R6	// a7
   719  	MOVD	64(R0), R7	// a8
   720  	MOVD	72(R0), R8	// a9
   721  	MOVD	8(R0), R0	// a1
   722  
   723  	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   724  	// See syscall above. The only function this applies to is openat, for which the 4th
   725  	// arg must be on the stack.
   726  	MOVD	R3, (RSP)
   727  
   728  	BL	(R12)
   729  
   730  	MOVD	8(RSP), R2	// pop structure pointer
   731  	ADD	$16, RSP
   732  	MOVD	R0, 80(R2)	// save r1
   733  	MOVD	R1, 88(R2)	// save r2
   734  	CMPW	$-1, R0
   735  	BNE	ok
   736  	SUB	$16, RSP	// push structure pointer
   737  	MOVD	R2, 8(RSP)
   738  	BL	libc_error(SB)
   739  	MOVW	(R0), R0
   740  	MOVD	8(RSP), R2	// pop structure pointer
   741  	ADD	$16, RSP
   742  	MOVD	R0, 96(R2)	// save err
   743  ok:
   744  	RET
   745  
   746  // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
   747  // takes 5 uintptrs and 1 float64, and only returns one value,
   748  // for use with standard C ABI functions.
   749  TEXT runtime·syscall_x509(SB),NOSPLIT,$0
   750  	SUB	$16, RSP	// push structure pointer
   751  	MOVD	R0, (RSP)
   752  
   753  	MOVD	0(R0), R12	// fn
   754  	MOVD	16(R0), R1	// a2
   755  	MOVD	24(R0), R2	// a3
   756  	MOVD	32(R0), R3	// a4
   757  	MOVD	40(R0), R4	// a5
   758  	FMOVD	48(R0), F0	// f1
   759  	MOVD	8(R0), R0	// a1
   760  	BL	(R12)
   761  
   762  	MOVD	(RSP), R2	// pop structure pointer
   763  	ADD	$16, RSP
   764  	MOVD	R0, 56(R2)	// save r1
   765  	RET
   766  
   767  TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
   768  	BL	libc_issetugid(SB)
   769  	RET
   770  
   771  // mach_vm_region_trampoline calls mach_vm_region from libc.
   772  TEXT runtime·mach_vm_region_trampoline(SB),NOSPLIT,$0
   773  	MOVD	0(R0), R1	// address
   774  	MOVD	8(R0), R2	// size
   775  	MOVW	16(R0), R3	// flavor
   776  	MOVD	24(R0), R4	// info
   777  	MOVD	32(R0), R5	// count
   778  	MOVD	40(R0), R6  // object_name
   779  	MOVD	$libc_mach_task_self_(SB), R0
   780  	MOVW	0(R0), R0
   781  	BL	libc_mach_vm_region(SB)
   782  	RET
   783  
   784  // proc_regionfilename_trampoline calls proc_regionfilename for
   785  // the current process.
   786  TEXT runtime·proc_regionfilename_trampoline(SB),NOSPLIT,$0
   787  	MOVD	8(R0), R1	// address
   788  	MOVD	16(R0), R2	// buffer
   789  	MOVD	24(R0), R3	// buffer_size
   790  	MOVD	0(R0), R0 // pid
   791  	BL	libc_proc_regionfilename(SB)
   792  	RET
   793  

View as plain text