Text file src/runtime/sys_openbsd_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, OpenBSD.
     6  // System calls are implemented in libc/libpthread, this file
     7  // contains trampolines that convert from Go to C calling convention.
     8  // Some direct system call implementations currently remain.
     9  //
    10  
    11  #include "go_asm.h"
    12  #include "go_tls.h"
    13  #include "textflag.h"
    14  #include "cgo/abi_amd64.h"
    15  
    16  #define CLOCK_MONOTONIC	$3
    17  
    18  TEXT runtime·settls(SB),NOSPLIT,$0
    19  	// Nothing to do, pthread already set thread-local storage up.
    20  	RET
    21  
    22  // mstart_stub is the first function executed on a new thread started by pthread_create.
    23  // It just does some low-level setup and then calls mstart.
    24  // Note: called with the C calling convention.
    25  TEXT runtime·mstart_stub(SB),NOSPLIT,$0
    26  	// DI points to the m.
    27  	// We are already on m's g0 stack.
    28  
    29  	// Transition from C ABI to Go ABI.
    30  	PUSH_REGS_HOST_TO_ABI0()
    31  
    32  	// Load g and save to TLS entry.
    33  	// See cmd/link/internal/ld/sym.go:computeTLSOffset.
    34  	MOVQ	m_g0(DI), DX // g
    35  	MOVQ	DX, -8(FS)
    36  
    37  	CALL	runtime·mstart(SB)
    38  
    39  	POP_REGS_HOST_TO_ABI0()
    40  
    41  	// Go is all done with this OS thread.
    42  	// Tell pthread everything is ok (we never join with this thread, so
    43  	// the value here doesn't really matter).
    44  	XORL	AX, AX
    45  	RET
    46  
    47  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
    48  	MOVQ	fn+0(FP),    AX
    49  	MOVL	sig+8(FP),   DI
    50  	MOVQ	info+16(FP), SI
    51  	MOVQ	ctx+24(FP),  DX
    52  	MOVQ	SP, BX		// callee-saved
    53  	ANDQ	$~15, SP	// alignment for x86_64 ABI
    54  	CALL	AX
    55  	MOVQ	BX, SP
    56  	RET
    57  
    58  // Called using C ABI.
    59  TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0
    60  	// Transition from C ABI to Go ABI.
    61  	PUSH_REGS_HOST_TO_ABI0()
    62  
    63  	// Set up ABIInternal environment: g in R14, cleared X15.
    64  	get_tls(R12)
    65  	MOVQ	g(R12), R14
    66  	PXOR	X15, X15
    67  
    68  	// Reserve space for spill slots.
    69  	NOP	SP		// disable vet stack checking
    70  	ADJSP   $24
    71  
    72  	// Call into the Go signal handler
    73  	MOVQ	DI, AX	// sig
    74  	MOVQ	SI, BX	// info
    75  	MOVQ	DX, CX	// ctx
    76  	CALL	·sigtrampgo<ABIInternal>(SB)
    77  
    78  	ADJSP	$-24
    79  
    80  	POP_REGS_HOST_TO_ABI0()
    81  	RET
    82  
    83  //
    84  // These trampolines help convert from Go calling convention to C calling convention.
    85  // They should be called with asmcgocall.
    86  // A pointer to the arguments is passed in DI.
    87  // A single int32 result is returned in AX.
    88  // (For more results, make an args/results structure.)
    89  TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
    90  	MOVQ	0(DI), DI		// arg 1 - attr
    91  	CALL	libc_pthread_attr_init(SB)
    92  	RET
    93  
    94  TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
    95  	MOVQ	0(DI), DI		// arg 1 - attr
    96  	CALL	libc_pthread_attr_destroy(SB)
    97  	RET
    98  
    99  TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
   100  	MOVQ	8(DI), SI		// arg 2 - stacksize
   101  	MOVQ	0(DI), DI		// arg 1 - attr
   102  	CALL	libc_pthread_attr_getstacksize(SB)
   103  	RET
   104  
   105  TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
   106  	MOVQ	8(DI), SI		// arg 2 - detachstate
   107  	MOVQ	0(DI), DI		// arg 1 - attr
   108  	CALL	libc_pthread_attr_setdetachstate(SB)
   109  	RET
   110  
   111  TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$16
   112  	MOVQ	0(DI), SI		// arg 2 - attr
   113  	MOVQ	8(DI), DX		// arg 3 - start
   114  	MOVQ	16(DI), CX		// arg 4 - arg
   115  	MOVQ	SP, DI			// arg 1 - &thread (discarded)
   116  	CALL	libc_pthread_create(SB)
   117  	RET
   118  
   119  TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
   120  	MOVL	8(DI), SI		// arg 2 - signal
   121  	MOVQ	$0, DX			// arg 3 - tcb
   122  	MOVL	0(DI), DI		// arg 1 - tid
   123  	CALL	libc_thrkill(SB)
   124  	RET
   125  
   126  TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
   127  	MOVL	8(DI), SI		// arg 2 - clock_id
   128  	MOVQ	16(DI), DX		// arg 3 - abstime
   129  	MOVQ	24(DI), CX		// arg 4 - lock
   130  	MOVQ	32(DI), R8		// arg 5 - abort
   131  	MOVQ	0(DI), DI		// arg 1 - id
   132  	CALL	libc_thrsleep(SB)
   133  	RET
   134  
   135  TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
   136  	MOVL	8(DI), SI		// arg 2 - count
   137  	MOVQ	0(DI), DI		// arg 1 - id
   138  	CALL	libc_thrwakeup(SB)
   139  	RET
   140  
   141  TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
   142  	MOVL	0(DI), DI		// arg 1 exit status
   143  	CALL	libc_exit(SB)
   144  	MOVL	$0xf1, 0xf1  // crash
   145  	RET
   146  
   147  TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
   148  	MOVQ	DI, BX			// BX is caller-save
   149  	CALL	libc_getthrid(SB)
   150  	MOVL	AX, 0(BX)		// return value
   151  	RET
   152  
   153  TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
   154  	MOVL	0(DI), BX	// signal
   155  	CALL	libc_getpid(SB)
   156  	MOVL	AX, DI		// arg 1 pid
   157  	MOVL	BX, SI		// arg 2 signal
   158  	CALL	libc_kill(SB)
   159  	RET
   160  
   161  TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
   162  	CALL	libc_sched_yield(SB)
   163  	RET
   164  
   165  TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
   166  	MOVQ	DI, BX
   167  	MOVQ	0(BX), DI		// arg 1 addr
   168  	MOVQ	8(BX), SI		// arg 2 len
   169  	MOVL	16(BX), DX		// arg 3 prot
   170  	MOVL	20(BX), CX		// arg 4 flags
   171  	MOVL	24(BX), R8		// arg 5 fid
   172  	MOVL	28(BX), R9		// arg 6 offset
   173  	CALL	libc_mmap(SB)
   174  	XORL	DX, DX
   175  	CMPQ	AX, $-1
   176  	JNE	ok
   177  	CALL	libc_errno(SB)
   178  	MOVLQSX	(AX), DX		// errno
   179  	XORQ	AX, AX
   180  ok:
   181  	MOVQ	AX, 32(BX)
   182  	MOVQ	DX, 40(BX)
   183  	RET
   184  
   185  TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
   186  	MOVQ	8(DI), SI		// arg 2 len
   187  	MOVQ	0(DI), DI		// arg 1 addr
   188  	CALL	libc_munmap(SB)
   189  	TESTQ	AX, AX
   190  	JEQ	2(PC)
   191  	MOVL	$0xf1, 0xf1  // crash
   192  	RET
   193  
   194  TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
   195  	MOVQ	8(DI), SI	// arg 2 len
   196  	MOVL	16(DI), DX	// arg 3 advice
   197  	MOVQ	0(DI), DI	// arg 1 addr
   198  	CALL	libc_madvise(SB)
   199  	// ignore failure - maybe pages are locked
   200  	RET
   201  
   202  TEXT runtime·open_trampoline(SB),NOSPLIT,$0
   203  	MOVL	8(DI), SI		// arg 2 - flags
   204  	MOVL	12(DI), DX		// arg 3 - mode
   205  	MOVQ	0(DI), DI		// arg 1 - path
   206  	XORL	AX, AX			// vararg: say "no float args"
   207  	CALL	libc_open(SB)
   208  	RET
   209  
   210  TEXT runtime·close_trampoline(SB),NOSPLIT,$0
   211  	MOVL	0(DI), DI		// arg 1 - fd
   212  	CALL	libc_close(SB)
   213  	RET
   214  
   215  TEXT runtime·read_trampoline(SB),NOSPLIT,$0
   216  	MOVQ	8(DI), SI		// arg 2 - buf
   217  	MOVL	16(DI), DX		// arg 3 - count
   218  	MOVL	0(DI), DI		// arg 1 - fd
   219  	CALL	libc_read(SB)
   220  	TESTL	AX, AX
   221  	JGE	noerr
   222  	CALL	libc_errno(SB)
   223  	MOVL	(AX), AX		// errno
   224  	NEGL	AX			// caller expects negative errno value
   225  noerr:
   226  	RET
   227  
   228  TEXT runtime·write_trampoline(SB),NOSPLIT,$0
   229  	MOVQ	8(DI), SI		// arg 2 buf
   230  	MOVL	16(DI), DX		// arg 3 count
   231  	MOVL	0(DI), DI		// arg 1 fd
   232  	CALL	libc_write(SB)
   233  	TESTL	AX, AX
   234  	JGE	noerr
   235  	CALL	libc_errno(SB)
   236  	MOVL	(AX), AX		// errno
   237  	NEGL	AX			// caller expects negative errno value
   238  noerr:
   239  	RET
   240  
   241  TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
   242  	MOVL	8(DI), SI		// arg 2 flags
   243  	MOVQ	0(DI), DI		// arg 1 filedes
   244  	CALL	libc_pipe2(SB)
   245  	TESTL	AX, AX
   246  	JEQ	3(PC)
   247  	CALL	libc_errno(SB)
   248  	MOVL	(AX), AX		// errno
   249  	NEGL	AX			// caller expects negative errno value
   250  	RET
   251  
   252  TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
   253  	MOVQ	8(DI), SI		// arg 2 new
   254  	MOVQ	16(DI), DX		// arg 3 old
   255  	MOVL	0(DI), DI		// arg 1 which
   256  	CALL	libc_setitimer(SB)
   257  	RET
   258  
   259  TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   260  	MOVL	0(DI), DI		// arg 1 usec
   261  	CALL	libc_usleep(SB)
   262  	RET
   263  
   264  TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
   265  	MOVL	8(DI), SI		// arg 2 miblen
   266  	MOVQ	16(DI), DX		// arg 3 out
   267  	MOVQ	24(DI), CX		// arg 4 size
   268  	MOVQ	32(DI), R8		// arg 5 dst
   269  	MOVQ	40(DI), R9		// arg 6 ndst
   270  	MOVQ	0(DI), DI		// arg 1 mib
   271  	CALL	libc_sysctl(SB)
   272  	RET
   273  
   274  TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   275  	CALL	libc_kqueue(SB)
   276  	RET
   277  
   278  TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
   279  	MOVQ	8(DI), SI		// arg 2 keventt
   280  	MOVL	16(DI), DX		// arg 3 nch
   281  	MOVQ	24(DI), CX		// arg 4 ev
   282  	MOVL	32(DI), R8		// arg 5 nev
   283  	MOVQ	40(DI), R9		// arg 6 ts
   284  	MOVL	0(DI), DI		// arg 1 kq
   285  	CALL	libc_kevent(SB)
   286  	CMPL	AX, $-1
   287  	JNE	ok
   288  	CALL	libc_errno(SB)
   289  	MOVL	(AX), AX		// errno
   290  	NEGL	AX			// caller expects negative errno value
   291  ok:
   292  	RET
   293  
   294  TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
   295  	MOVQ	8(DI), SI		// arg 2 tp
   296  	MOVL	0(DI), DI		// arg 1 clock_id
   297  	CALL	libc_clock_gettime(SB)
   298  	TESTL	AX, AX
   299  	JEQ	noerr
   300  	CALL	libc_errno(SB)
   301  	MOVL	(AX), AX		// errno
   302  	NEGL	AX			// caller expects negative errno value
   303  noerr:
   304  	RET
   305  
   306  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   307  	MOVQ	DI, BX
   308  	MOVL	0(BX), DI		// arg 1 fd
   309  	MOVL	4(BX), SI		// arg 2 cmd
   310  	MOVL	8(BX), DX		// arg 3 arg
   311  	XORL	AX, AX			// vararg: say "no float args"
   312  	CALL	libc_fcntl(SB)
   313  	XORL	DX, DX
   314  	CMPL	AX, $-1
   315  	JNE	noerr
   316  	CALL	libc_errno(SB)
   317  	MOVL	(AX), DX
   318  	MOVL	$-1, AX
   319  noerr:
   320  	MOVL	AX, 12(BX)
   321  	MOVL	DX, 16(BX)
   322  	RET
   323  
   324  TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
   325  	MOVQ	8(DI), SI		// arg 2 new
   326  	MOVQ	16(DI), DX		// arg 3 old
   327  	MOVL	0(DI), DI		// arg 1 sig
   328  	CALL	libc_sigaction(SB)
   329  	TESTL	AX, AX
   330  	JEQ	2(PC)
   331  	MOVL	$0xf1, 0xf1  // crash
   332  	RET
   333  
   334  TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   335  	MOVQ	8(DI), SI	// arg 2 new
   336  	MOVQ	16(DI), DX	// arg 3 old
   337  	MOVL	0(DI), DI	// arg 1 how
   338  	CALL	libc_pthread_sigmask(SB)
   339  	TESTL	AX, AX
   340  	JEQ	2(PC)
   341  	MOVL	$0xf1, 0xf1  // crash
   342  	RET
   343  
   344  TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   345  	MOVQ	8(DI), SI		// arg 2 old
   346  	MOVQ	0(DI), DI		// arg 1 new
   347  	CALL	libc_sigaltstack(SB)
   348  	TESTQ	AX, AX
   349  	JEQ	2(PC)
   350  	MOVL	$0xf1, 0xf1  // crash
   351  	RET
   352  
   353  // syscall calls a function in libc on behalf of the syscall package.
   354  // syscall takes a pointer to a struct like:
   355  // struct {
   356  //	fn    uintptr
   357  //	a1    uintptr
   358  //	a2    uintptr
   359  //	a3    uintptr
   360  //	r1    uintptr
   361  //	r2    uintptr
   362  //	err   uintptr
   363  // }
   364  // syscall must be called on the g0 stack with the
   365  // C calling convention (use libcCall).
   366  //
   367  // syscall expects a 32-bit result and tests for 32-bit -1
   368  // to decide there was an error.
   369  TEXT runtime·syscall(SB),NOSPLIT,$16
   370  	MOVQ	(0*8)(DI), CX // fn
   371  	MOVQ	(2*8)(DI), SI // a2
   372  	MOVQ	(3*8)(DI), DX // a3
   373  	MOVQ	DI, (SP)
   374  	MOVQ	(1*8)(DI), DI // a1
   375  	XORL	AX, AX	      // vararg: say "no float args"
   376  
   377  	CALL	CX
   378  
   379  	MOVQ	(SP), DI
   380  	MOVQ	AX, (4*8)(DI) // r1
   381  	MOVQ	DX, (5*8)(DI) // r2
   382  
   383  	// Standard libc functions return -1 on error
   384  	// and set errno.
   385  	CMPL	AX, $-1	      // Note: high 32 bits are junk
   386  	JNE	ok
   387  
   388  	// Get error code from libc.
   389  	CALL	libc_errno(SB)
   390  	MOVLQSX	(AX), AX
   391  	MOVQ	(SP), DI
   392  	MOVQ	AX, (6*8)(DI) // err
   393  
   394  ok:
   395  	XORL	AX, AX        // no error (it's ignored anyway)
   396  	RET
   397  
   398  // syscallX calls a function in libc on behalf of the syscall package.
   399  // syscallX takes a pointer to a struct like:
   400  // struct {
   401  //	fn    uintptr
   402  //	a1    uintptr
   403  //	a2    uintptr
   404  //	a3    uintptr
   405  //	r1    uintptr
   406  //	r2    uintptr
   407  //	err   uintptr
   408  // }
   409  // syscallX must be called on the g0 stack with the
   410  // C calling convention (use libcCall).
   411  //
   412  // syscallX is like syscall but expects a 64-bit result
   413  // and tests for 64-bit -1 to decide there was an error.
   414  TEXT runtime·syscallX(SB),NOSPLIT,$16
   415  	MOVQ	(0*8)(DI), CX // fn
   416  	MOVQ	(2*8)(DI), SI // a2
   417  	MOVQ	(3*8)(DI), DX // a3
   418  	MOVQ	DI, (SP)
   419  	MOVQ	(1*8)(DI), DI // a1
   420  	XORL	AX, AX	      // vararg: say "no float args"
   421  
   422  	CALL	CX
   423  
   424  	MOVQ	(SP), DI
   425  	MOVQ	AX, (4*8)(DI) // r1
   426  	MOVQ	DX, (5*8)(DI) // r2
   427  
   428  	// Standard libc functions return -1 on error
   429  	// and set errno.
   430  	CMPQ	AX, $-1
   431  	JNE	ok
   432  
   433  	// Get error code from libc.
   434  	CALL	libc_errno(SB)
   435  	MOVLQSX	(AX), AX
   436  	MOVQ	(SP), DI
   437  	MOVQ	AX, (6*8)(DI) // err
   438  
   439  ok:
   440  	XORL	AX, AX        // no error (it's ignored anyway)
   441  	RET
   442  
   443  // syscall6 calls a function in libc on behalf of the syscall package.
   444  // syscall6 takes a pointer to a struct like:
   445  // struct {
   446  //	fn    uintptr
   447  //	a1    uintptr
   448  //	a2    uintptr
   449  //	a3    uintptr
   450  //	a4    uintptr
   451  //	a5    uintptr
   452  //	a6    uintptr
   453  //	r1    uintptr
   454  //	r2    uintptr
   455  //	err   uintptr
   456  // }
   457  // syscall6 must be called on the g0 stack with the
   458  // C calling convention (use libcCall).
   459  //
   460  // syscall6 expects a 32-bit result and tests for 32-bit -1
   461  // to decide there was an error.
   462  TEXT runtime·syscall6(SB),NOSPLIT,$16
   463  	MOVQ	(0*8)(DI), R11// fn
   464  	MOVQ	(2*8)(DI), SI // a2
   465  	MOVQ	(3*8)(DI), DX // a3
   466  	MOVQ	(4*8)(DI), CX // a4
   467  	MOVQ	(5*8)(DI), R8 // a5
   468  	MOVQ	(6*8)(DI), R9 // a6
   469  	MOVQ	DI, (SP)
   470  	MOVQ	(1*8)(DI), DI // a1
   471  	XORL	AX, AX	      // vararg: say "no float args"
   472  
   473  	CALL	R11
   474  
   475  	MOVQ	(SP), DI
   476  	MOVQ	AX, (7*8)(DI) // r1
   477  	MOVQ	DX, (8*8)(DI) // r2
   478  
   479  	CMPL	AX, $-1
   480  	JNE	ok
   481  
   482  	CALL	libc_errno(SB)
   483  	MOVLQSX	(AX), AX
   484  	MOVQ	(SP), DI
   485  	MOVQ	AX, (9*8)(DI) // err
   486  
   487  ok:
   488  	XORL	AX, AX        // no error (it's ignored anyway)
   489  	RET
   490  
   491  // syscall6X calls a function in libc on behalf of the syscall package.
   492  // syscall6X takes a pointer to a struct like:
   493  // struct {
   494  //	fn    uintptr
   495  //	a1    uintptr
   496  //	a2    uintptr
   497  //	a3    uintptr
   498  //	a4    uintptr
   499  //	a5    uintptr
   500  //	a6    uintptr
   501  //	r1    uintptr
   502  //	r2    uintptr
   503  //	err   uintptr
   504  // }
   505  // syscall6X must be called on the g0 stack with the
   506  // C calling convention (use libcCall).
   507  //
   508  // syscall6X is like syscall6 but expects a 64-bit result
   509  // and tests for 64-bit -1 to decide there was an error.
   510  TEXT runtime·syscall6X(SB),NOSPLIT,$16
   511  	MOVQ	(0*8)(DI), R11// fn
   512  	MOVQ	(2*8)(DI), SI // a2
   513  	MOVQ	(3*8)(DI), DX // a3
   514  	MOVQ	(4*8)(DI), CX // a4
   515  	MOVQ	(5*8)(DI), R8 // a5
   516  	MOVQ	(6*8)(DI), R9 // a6
   517  	MOVQ	DI, (SP)
   518  	MOVQ	(1*8)(DI), DI // a1
   519  	XORL	AX, AX	      // vararg: say "no float args"
   520  
   521  	CALL	R11
   522  
   523  	MOVQ	(SP), DI
   524  	MOVQ	AX, (7*8)(DI) // r1
   525  	MOVQ	DX, (8*8)(DI) // r2
   526  
   527  	CMPQ	AX, $-1
   528  	JNE	ok
   529  
   530  	CALL	libc_errno(SB)
   531  	MOVLQSX	(AX), AX
   532  	MOVQ	(SP), DI
   533  	MOVQ	AX, (9*8)(DI) // err
   534  
   535  ok:
   536  	XORL	AX, AX        // no error (it's ignored anyway)
   537  	RET
   538  
   539  // syscall10 calls a function in libc on behalf of the syscall package.
   540  // syscall10 takes a pointer to a struct like:
   541  // struct {
   542  //	fn    uintptr
   543  //	a1    uintptr
   544  //	a2    uintptr
   545  //	a3    uintptr
   546  //	a4    uintptr
   547  //	a5    uintptr
   548  //	a6    uintptr
   549  //	a7    uintptr
   550  //	a8    uintptr
   551  //	a9    uintptr
   552  //	a10   uintptr
   553  //	r1    uintptr
   554  //	r2    uintptr
   555  //	err   uintptr
   556  // }
   557  // syscall10 must be called on the g0 stack with the
   558  // C calling convention (use libcCall).
   559  TEXT runtime·syscall10(SB),NOSPLIT,$48
   560  	// Arguments a1 to a6 get passed in registers, with a7 onwards being
   561  	// passed via the stack per the x86-64 System V ABI
   562  	// (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
   563  	MOVQ	(7*8)(DI), R10	// a7
   564  	MOVQ	(8*8)(DI), R11	// a8
   565  	MOVQ	(9*8)(DI), R12	// a9
   566  	MOVQ	(10*8)(DI), R13	// a10
   567  	MOVQ	R10, (0*8)(SP)	// a7
   568  	MOVQ	R11, (1*8)(SP)	// a8
   569  	MOVQ	R12, (2*8)(SP)	// a9
   570  	MOVQ	R13, (3*8)(SP)	// a10
   571  	MOVQ	(0*8)(DI), R11	// fn
   572  	MOVQ	(2*8)(DI), SI	// a2
   573  	MOVQ	(3*8)(DI), DX	// a3
   574  	MOVQ	(4*8)(DI), CX	// a4
   575  	MOVQ	(5*8)(DI), R8	// a5
   576  	MOVQ	(6*8)(DI), R9	// a6
   577  	MOVQ	DI, (4*8)(SP)
   578  	MOVQ	(1*8)(DI), DI	// a1
   579  	XORL	AX, AX	     	// vararg: say "no float args"
   580  
   581  	CALL	R11
   582  
   583  	MOVQ	(4*8)(SP), DI
   584  	MOVQ	AX, (11*8)(DI) // r1
   585  	MOVQ	DX, (12*8)(DI) // r2
   586  
   587  	CMPL	AX, $-1
   588  	JNE	ok
   589  
   590  	CALL	libc_errno(SB)
   591  	MOVLQSX	(AX), AX
   592  	MOVQ	(4*8)(SP), DI
   593  	MOVQ	AX, (13*8)(DI) // err
   594  
   595  ok:
   596  	XORL	AX, AX        // no error (it's ignored anyway)
   597  	RET
   598  
   599  // syscall10X calls a function in libc on behalf of the syscall package.
   600  // syscall10X 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  //	a7    uintptr
   610  //	a8    uintptr
   611  //	a9    uintptr
   612  //	a10   uintptr
   613  //	r1    uintptr
   614  //	r2    uintptr
   615  //	err   uintptr
   616  // }
   617  // syscall10X must be called on the g0 stack with the
   618  // C calling convention (use libcCall).
   619  //
   620  // syscall10X is like syscall10 but expects a 64-bit result
   621  // and tests for 64-bit -1 to decide there was an error.
   622  TEXT runtime·syscall10X(SB),NOSPLIT,$48
   623  	// Arguments a1 to a6 get passed in registers, with a7 onwards being
   624  	// passed via the stack per the x86-64 System V ABI
   625  	// (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
   626  	MOVQ	(7*8)(DI), R10	// a7
   627  	MOVQ	(8*8)(DI), R11	// a8
   628  	MOVQ	(9*8)(DI), R12	// a9
   629  	MOVQ	(10*8)(DI), R13	// a10
   630  	MOVQ	R10, (0*8)(SP)	// a7
   631  	MOVQ	R11, (1*8)(SP)	// a8
   632  	MOVQ	R12, (2*8)(SP)	// a9
   633  	MOVQ	R13, (3*8)(SP)	// a10
   634  	MOVQ	(0*8)(DI), R11	// fn
   635  	MOVQ	(2*8)(DI), SI	// a2
   636  	MOVQ	(3*8)(DI), DX	// a3
   637  	MOVQ	(4*8)(DI), CX	// a4
   638  	MOVQ	(5*8)(DI), R8	// a5
   639  	MOVQ	(6*8)(DI), R9	// a6
   640  	MOVQ	DI, (4*8)(SP)
   641  	MOVQ	(1*8)(DI), DI	// a1
   642  	XORL	AX, AX	     	// vararg: say "no float args"
   643  
   644  	CALL	R11
   645  
   646  	MOVQ	(4*8)(SP), DI
   647  	MOVQ	AX, (11*8)(DI) // r1
   648  	MOVQ	DX, (12*8)(DI) // r2
   649  
   650  	CMPQ	AX, $-1
   651  	JNE	ok
   652  
   653  	CALL	libc_errno(SB)
   654  	MOVLQSX	(AX), AX
   655  	MOVQ	(4*8)(SP), DI
   656  	MOVQ	AX, (13*8)(DI) // err
   657  
   658  ok:
   659  	XORL	AX, AX        // no error (it's ignored anyway)
   660  	RET
   661  
   662  TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
   663  	MOVQ	DI, BX			// BX is caller-save
   664  	CALL	libc_issetugid(SB)
   665  	MOVL	AX, 0(BX)		// return value
   666  	RET
   667  

View as plain text