Black Lives Matter. Support the Equal Justice Initiative.

Text file src/runtime/sys_openbsd_amd64.s

Documentation: runtime

     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  	PUSHQ	BP
    53  	MOVQ	SP, BP
    54  	ANDQ	$~15, SP     // alignment for x86_64 ABI
    55  	CALL	AX
    56  	MOVQ	BP, SP
    57  	POPQ	BP
    58  	RET
    59  
    60  // Called using C ABI.
    61  TEXT runtime·sigtramp<ABIInternal>(SB),NOSPLIT,$0
    62  	// Transition from C ABI to Go ABI.
    63  	PUSH_REGS_HOST_TO_ABI0()
    64  
    65  	// Call into the Go signal handler
    66  	NOP	SP		// disable vet stack checking
    67          ADJSP   $24
    68  	MOVQ	DI, 0(SP)	// sig
    69  	MOVQ	SI, 8(SP)	// info
    70  	MOVQ	DX, 16(SP)	// ctx
    71  	CALL	·sigtrampgo(SB)
    72  	ADJSP	$-24
    73  
    74          POP_REGS_HOST_TO_ABI0()
    75  	RET
    76  
    77  //
    78  // These trampolines help convert from Go calling convention to C calling convention.
    79  // They should be called with asmcgocall.
    80  // A pointer to the arguments is passed in DI.
    81  // A single int32 result is returned in AX.
    82  // (For more results, make an args/results structure.)
    83  TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
    84  	PUSHQ	BP
    85  	MOVQ	SP, BP
    86  	MOVQ	0(DI), DI		// arg 1 - attr
    87  	CALL	libc_pthread_attr_init(SB)
    88  	POPQ	BP
    89  	RET
    90  
    91  TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
    92  	PUSHQ	BP
    93  	MOVQ	SP, BP
    94  	MOVQ	0(DI), DI		// arg 1 - attr
    95  	CALL	libc_pthread_attr_destroy(SB)
    96  	POPQ	BP
    97  	RET
    98  
    99  TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
   100  	PUSHQ	BP
   101  	MOVQ	SP, BP
   102  	MOVQ	8(DI), SI		// arg 2 - stacksize
   103  	MOVQ	0(DI), DI		// arg 1 - attr
   104  	CALL	libc_pthread_attr_getstacksize(SB)
   105  	POPQ	BP
   106  	RET
   107  
   108  TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
   109  	PUSHQ	BP
   110  	MOVQ	SP, BP
   111  	MOVQ	8(DI), SI		// arg 2 - detachstate
   112  	MOVQ	0(DI), DI		// arg 1 - attr
   113  	CALL	libc_pthread_attr_setdetachstate(SB)
   114  	POPQ	BP
   115  	RET
   116  
   117  TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
   118  	PUSHQ	BP
   119  	MOVQ	SP, BP
   120  	SUBQ	$16, SP
   121  	MOVQ	0(DI), SI		// arg 2 - attr
   122  	MOVQ	8(DI), DX		// arg 3 - start
   123  	MOVQ	16(DI), CX		// arg 4 - arg
   124  	MOVQ	SP, DI			// arg 1 - &thread (discarded)
   125  	CALL	libc_pthread_create(SB)
   126  	MOVQ	BP, SP
   127  	POPQ	BP
   128  	RET
   129  
   130  TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
   131  	PUSHQ	BP
   132  	MOVQ	SP, BP
   133  	MOVL	8(DI), SI		// arg 2 - signal
   134  	MOVQ	$0, DX			// arg 3 - tcb
   135  	MOVL	0(DI), DI		// arg 1 - tid
   136  	CALL	libc_thrkill(SB)
   137  	POPQ	BP
   138  	RET
   139  
   140  TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
   141  	PUSHQ	BP
   142  	MOVQ	SP, BP
   143  	MOVL	8(DI), SI		// arg 2 - clock_id
   144  	MOVQ	16(DI), DX		// arg 3 - abstime
   145  	MOVQ	24(DI), CX		// arg 4 - lock
   146  	MOVQ	32(DI), R8		// arg 5 - abort
   147  	MOVQ	0(DI), DI		// arg 1 - id
   148  	CALL	libc_thrsleep(SB)
   149  	POPQ	BP
   150  	RET
   151  
   152  TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
   153  	PUSHQ	BP
   154  	MOVQ	SP, BP
   155  	MOVL	8(DI), SI		// arg 2 - count
   156  	MOVQ	0(DI), DI		// arg 1 - id
   157  	CALL	libc_thrwakeup(SB)
   158  	POPQ	BP
   159  	RET
   160  
   161  TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
   162  	PUSHQ	BP
   163  	MOVQ	SP, BP
   164  	MOVL	0(DI), DI		// arg 1 exit status
   165  	CALL	libc_exit(SB)
   166  	MOVL	$0xf1, 0xf1  // crash
   167  	POPQ	BP
   168  	RET
   169  
   170  TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
   171  	PUSHQ	BP
   172  	MOVQ	SP, BP
   173  	MOVQ	DI, BX			// BX is caller-save
   174  	CALL	libc_getthrid(SB)
   175  	MOVL	AX, 0(BX)		// return value
   176  	POPQ	BP
   177  	RET
   178  
   179  TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
   180  	PUSHQ	BP
   181  	MOVQ	SP, BP
   182  	MOVL	0(DI), BX	// signal
   183  	CALL	libc_getpid(SB)
   184  	MOVL	AX, DI		// arg 1 pid
   185  	MOVL	BX, SI		// arg 2 signal
   186  	CALL	libc_kill(SB)
   187  	POPQ	BP
   188  	RET
   189  
   190  TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
   191  	PUSHQ	BP
   192  	MOVQ	SP, BP
   193  	CALL	libc_sched_yield(SB)
   194  	POPQ	BP
   195  	RET
   196  
   197  TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
   198  	PUSHQ	BP			// make a frame; keep stack aligned
   199  	MOVQ	SP, BP
   200  	MOVQ	DI, BX
   201  	MOVQ	0(BX), DI		// arg 1 addr
   202  	MOVQ	8(BX), SI		// arg 2 len
   203  	MOVL	16(BX), DX		// arg 3 prot
   204  	MOVL	20(BX), CX		// arg 4 flags
   205  	MOVL	24(BX), R8		// arg 5 fid
   206  	MOVL	28(BX), R9		// arg 6 offset
   207  	CALL	libc_mmap(SB)
   208  	XORL	DX, DX
   209  	CMPQ	AX, $-1
   210  	JNE	ok
   211  	CALL	libc_errno(SB)
   212  	MOVLQSX	(AX), DX		// errno
   213  	XORQ	AX, AX
   214  ok:
   215  	MOVQ	AX, 32(BX)
   216  	MOVQ	DX, 40(BX)
   217  	POPQ	BP
   218  	RET
   219  
   220  TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
   221  	PUSHQ	BP
   222  	MOVQ	SP, BP
   223  	MOVQ	8(DI), SI		// arg 2 len
   224  	MOVQ	0(DI), DI		// arg 1 addr
   225  	CALL	libc_munmap(SB)
   226  	TESTQ	AX, AX
   227  	JEQ	2(PC)
   228  	MOVL	$0xf1, 0xf1  // crash
   229  	POPQ	BP
   230  	RET
   231  
   232  TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
   233  	PUSHQ	BP
   234  	MOVQ	SP, BP
   235  	MOVQ	8(DI), SI	// arg 2 len
   236  	MOVL	16(DI), DX	// arg 3 advice
   237  	MOVQ	0(DI), DI	// arg 1 addr
   238  	CALL	libc_madvise(SB)
   239  	// ignore failure - maybe pages are locked
   240  	POPQ	BP
   241  	RET
   242  
   243  TEXT runtime·open_trampoline(SB),NOSPLIT,$0
   244  	PUSHQ	BP
   245  	MOVQ	SP, BP
   246  	MOVL	8(DI), SI		// arg 2 - flags
   247  	MOVL	12(DI), DX		// arg 3 - mode
   248  	MOVQ	0(DI), DI		// arg 1 - path
   249  	XORL	AX, AX			// vararg: say "no float args"
   250  	CALL	libc_open(SB)
   251  	POPQ	BP
   252  	RET
   253  
   254  TEXT runtime·close_trampoline(SB),NOSPLIT,$0
   255  	PUSHQ	BP
   256  	MOVQ	SP, BP
   257  	MOVL	0(DI), DI		// arg 1 - fd
   258  	CALL	libc_close(SB)
   259  	POPQ	BP
   260  	RET
   261  
   262  TEXT runtime·read_trampoline(SB),NOSPLIT,$0
   263  	PUSHQ	BP
   264  	MOVQ	SP, BP
   265  	MOVQ	8(DI), SI		// arg 2 - buf
   266  	MOVL	16(DI), DX		// arg 3 - count
   267  	MOVL	0(DI), DI		// arg 1 - fd
   268  	CALL	libc_read(SB)
   269  	TESTL	AX, AX
   270  	JGE	noerr
   271  	CALL	libc_errno(SB)
   272  	MOVL	(AX), AX		// errno
   273  	NEGL	AX			// caller expects negative errno value
   274  noerr:
   275  	POPQ	BP
   276  	RET
   277  
   278  TEXT runtime·write_trampoline(SB),NOSPLIT,$0
   279  	PUSHQ	BP
   280  	MOVQ	SP, BP
   281  	MOVQ	8(DI), SI		// arg 2 buf
   282  	MOVL	16(DI), DX		// arg 3 count
   283  	MOVL	0(DI), DI		// arg 1 fd
   284  	CALL	libc_write(SB)
   285  	TESTL	AX, AX
   286  	JGE	noerr
   287  	CALL	libc_errno(SB)
   288  	MOVL	(AX), AX		// errno
   289  	NEGL	AX			// caller expects negative errno value
   290  noerr:
   291  	POPQ	BP
   292  	RET
   293  
   294  TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
   295  	PUSHQ	BP
   296  	MOVQ	SP, BP
   297  	MOVL	8(DI), SI		// arg 2 flags
   298  	MOVQ	0(DI), DI		// arg 1 filedes
   299  	CALL	libc_pipe2(SB)
   300  	TESTL	AX, AX
   301  	JEQ	3(PC)
   302  	CALL	libc_errno(SB)
   303  	MOVL	(AX), AX		// errno
   304  	NEGL	AX			// caller expects negative errno value
   305  	POPQ	BP
   306  	RET
   307  
   308  TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
   309  	PUSHQ	BP
   310  	MOVQ	SP, BP
   311  	MOVQ	8(DI), SI		// arg 2 new
   312  	MOVQ	16(DI), DX		// arg 3 old
   313  	MOVL	0(DI), DI		// arg 1 which
   314  	CALL	libc_setitimer(SB)
   315  	POPQ	BP
   316  	RET
   317  
   318  TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   319  	PUSHQ	BP
   320  	MOVQ	SP, BP
   321  	MOVL	0(DI), DI		// arg 1 usec
   322  	CALL	libc_usleep(SB)
   323  	POPQ	BP
   324  	RET
   325  
   326  TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
   327  	PUSHQ	BP
   328  	MOVQ	SP, BP
   329  	MOVL	8(DI), SI		// arg 2 miblen
   330  	MOVQ	16(DI), DX		// arg 3 out
   331  	MOVQ	24(DI), CX		// arg 4 size
   332  	MOVQ	32(DI), R8		// arg 5 dst
   333  	MOVQ	40(DI), R9		// arg 6 ndst
   334  	MOVQ	0(DI), DI		// arg 1 mib
   335  	CALL	libc_sysctl(SB)
   336  	POPQ	BP
   337  	RET
   338  
   339  TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   340  	PUSHQ	BP
   341  	MOVQ	SP, BP
   342  	CALL	libc_kqueue(SB)
   343  	POPQ	BP
   344  	RET
   345  
   346  TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
   347  	PUSHQ	BP
   348  	MOVQ	SP, BP
   349  	MOVQ	8(DI), SI		// arg 2 keventt
   350  	MOVL	16(DI), DX		// arg 3 nch
   351  	MOVQ	24(DI), CX		// arg 4 ev
   352  	MOVL	32(DI), R8		// arg 5 nev
   353  	MOVQ	40(DI), R9		// arg 6 ts
   354  	MOVL	0(DI), DI		// arg 1 kq
   355  	CALL	libc_kevent(SB)
   356  	CMPL	AX, $-1
   357  	JNE	ok
   358  	CALL	libc_errno(SB)
   359  	MOVL	(AX), AX		// errno
   360  	NEGL	AX			// caller expects negative errno value
   361  ok:
   362  	POPQ	BP
   363  	RET
   364  
   365  TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
   366  	PUSHQ	BP			// make a frame; keep stack aligned
   367  	MOVQ	SP, BP
   368  	MOVQ	8(DI), SI		// arg 2 tp
   369  	MOVL	0(DI), DI		// arg 1 clock_id
   370  	CALL	libc_clock_gettime(SB)
   371  	TESTL	AX, AX
   372  	JEQ	2(PC)
   373  	MOVL	$0xf1, 0xf1  // crash
   374  	POPQ	BP
   375  	RET
   376  
   377  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   378  	PUSHQ	BP
   379  	MOVQ	SP, BP
   380  	MOVL	4(DI), SI		// arg 2 cmd
   381  	MOVL	8(DI), DX		// arg 3 arg
   382  	MOVL	0(DI), DI		// arg 1 fd
   383  	XORL	AX, AX			// vararg: say "no float args"
   384  	CALL	libc_fcntl(SB)
   385  	POPQ	BP
   386  	RET
   387  
   388  TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
   389  	PUSHQ	BP
   390  	MOVQ	SP, BP
   391  	MOVQ	8(DI), SI		// arg 2 new
   392  	MOVQ	16(DI), DX		// arg 3 old
   393  	MOVL	0(DI), DI		// arg 1 sig
   394  	CALL	libc_sigaction(SB)
   395  	TESTL	AX, AX
   396  	JEQ	2(PC)
   397  	MOVL	$0xf1, 0xf1  // crash
   398  	POPQ	BP
   399  	RET
   400  
   401  TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   402  	PUSHQ	BP
   403  	MOVQ	SP, BP
   404  	MOVQ	8(DI), SI	// arg 2 new
   405  	MOVQ	16(DI), DX	// arg 3 old
   406  	MOVL	0(DI), DI	// arg 1 how
   407  	CALL	libc_pthread_sigmask(SB)
   408  	TESTL	AX, AX
   409  	JEQ	2(PC)
   410  	MOVL	$0xf1, 0xf1  // crash
   411  	POPQ	BP
   412  	RET
   413  
   414  TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   415  	PUSHQ	BP
   416  	MOVQ	SP, BP
   417  	MOVQ	8(DI), SI		// arg 2 old
   418  	MOVQ	0(DI), DI		// arg 1 new
   419  	CALL	libc_sigaltstack(SB)
   420  	TESTQ	AX, AX
   421  	JEQ	2(PC)
   422  	MOVL	$0xf1, 0xf1  // crash
   423  	POPQ	BP
   424  	RET
   425  
   426  // syscall calls a function in libc on behalf of the syscall package.
   427  // syscall takes a pointer to a struct like:
   428  // struct {
   429  //	fn    uintptr
   430  //	a1    uintptr
   431  //	a2    uintptr
   432  //	a3    uintptr
   433  //	r1    uintptr
   434  //	r2    uintptr
   435  //	err   uintptr
   436  // }
   437  // syscall must be called on the g0 stack with the
   438  // C calling convention (use libcCall).
   439  //
   440  // syscall expects a 32-bit result and tests for 32-bit -1
   441  // to decide there was an error.
   442  TEXT runtime·syscall(SB),NOSPLIT,$0
   443  	PUSHQ	BP
   444  	MOVQ	SP, BP
   445  	SUBQ	$16, SP
   446  	MOVQ	(0*8)(DI), CX // fn
   447  	MOVQ	(2*8)(DI), SI // a2
   448  	MOVQ	(3*8)(DI), DX // a3
   449  	MOVQ	DI, (SP)
   450  	MOVQ	(1*8)(DI), DI // a1
   451  	XORL	AX, AX	      // vararg: say "no float args"
   452  
   453  	CALL	CX
   454  
   455  	MOVQ	(SP), DI
   456  	MOVQ	AX, (4*8)(DI) // r1
   457  	MOVQ	DX, (5*8)(DI) // r2
   458  
   459  	// Standard libc functions return -1 on error
   460  	// and set errno.
   461  	CMPL	AX, $-1	      // Note: high 32 bits are junk
   462  	JNE	ok
   463  
   464  	// Get error code from libc.
   465  	CALL	libc_errno(SB)
   466  	MOVLQSX	(AX), AX
   467  	MOVQ	(SP), DI
   468  	MOVQ	AX, (6*8)(DI) // err
   469  
   470  ok:
   471  	XORL	AX, AX        // no error (it's ignored anyway)
   472  	MOVQ	BP, SP
   473  	POPQ	BP
   474  	RET
   475  
   476  // syscallX calls a function in libc on behalf of the syscall package.
   477  // syscallX takes a pointer to a struct like:
   478  // struct {
   479  //	fn    uintptr
   480  //	a1    uintptr
   481  //	a2    uintptr
   482  //	a3    uintptr
   483  //	r1    uintptr
   484  //	r2    uintptr
   485  //	err   uintptr
   486  // }
   487  // syscallX must be called on the g0 stack with the
   488  // C calling convention (use libcCall).
   489  //
   490  // syscallX is like syscall but expects a 64-bit result
   491  // and tests for 64-bit -1 to decide there was an error.
   492  TEXT runtime·syscallX(SB),NOSPLIT,$0
   493  	PUSHQ	BP
   494  	MOVQ	SP, BP
   495  	SUBQ	$16, SP
   496  	MOVQ	(0*8)(DI), CX // fn
   497  	MOVQ	(2*8)(DI), SI // a2
   498  	MOVQ	(3*8)(DI), DX // a3
   499  	MOVQ	DI, (SP)
   500  	MOVQ	(1*8)(DI), DI // a1
   501  	XORL	AX, AX	      // vararg: say "no float args"
   502  
   503  	CALL	CX
   504  
   505  	MOVQ	(SP), DI
   506  	MOVQ	AX, (4*8)(DI) // r1
   507  	MOVQ	DX, (5*8)(DI) // r2
   508  
   509  	// Standard libc functions return -1 on error
   510  	// and set errno.
   511  	CMPQ	AX, $-1
   512  	JNE	ok
   513  
   514  	// Get error code from libc.
   515  	CALL	libc_errno(SB)
   516  	MOVLQSX	(AX), AX
   517  	MOVQ	(SP), DI
   518  	MOVQ	AX, (6*8)(DI) // err
   519  
   520  ok:
   521  	XORL	AX, AX        // no error (it's ignored anyway)
   522  	MOVQ	BP, SP
   523  	POPQ	BP
   524  	RET
   525  
   526  // syscall6 calls a function in libc on behalf of the syscall package.
   527  // syscall6 takes a pointer to a struct like:
   528  // struct {
   529  //	fn    uintptr
   530  //	a1    uintptr
   531  //	a2    uintptr
   532  //	a3    uintptr
   533  //	a4    uintptr
   534  //	a5    uintptr
   535  //	a6    uintptr
   536  //	r1    uintptr
   537  //	r2    uintptr
   538  //	err   uintptr
   539  // }
   540  // syscall6 must be called on the g0 stack with the
   541  // C calling convention (use libcCall).
   542  //
   543  // syscall6 expects a 32-bit result and tests for 32-bit -1
   544  // to decide there was an error.
   545  TEXT runtime·syscall6(SB),NOSPLIT,$0
   546  	PUSHQ	BP
   547  	MOVQ	SP, BP
   548  	SUBQ	$16, SP
   549  	MOVQ	(0*8)(DI), R11// fn
   550  	MOVQ	(2*8)(DI), SI // a2
   551  	MOVQ	(3*8)(DI), DX // a3
   552  	MOVQ	(4*8)(DI), CX // a4
   553  	MOVQ	(5*8)(DI), R8 // a5
   554  	MOVQ	(6*8)(DI), R9 // a6
   555  	MOVQ	DI, (SP)
   556  	MOVQ	(1*8)(DI), DI // a1
   557  	XORL	AX, AX	      // vararg: say "no float args"
   558  
   559  	CALL	R11
   560  
   561  	MOVQ	(SP), DI
   562  	MOVQ	AX, (7*8)(DI) // r1
   563  	MOVQ	DX, (8*8)(DI) // r2
   564  
   565  	CMPL	AX, $-1
   566  	JNE	ok
   567  
   568  	CALL	libc_errno(SB)
   569  	MOVLQSX	(AX), AX
   570  	MOVQ	(SP), DI
   571  	MOVQ	AX, (9*8)(DI) // err
   572  
   573  ok:
   574  	XORL	AX, AX        // no error (it's ignored anyway)
   575  	MOVQ	BP, SP
   576  	POPQ	BP
   577  	RET
   578  
   579  // syscall6X calls a function in libc on behalf of the syscall package.
   580  // syscall6X takes a pointer to a struct like:
   581  // struct {
   582  //	fn    uintptr
   583  //	a1    uintptr
   584  //	a2    uintptr
   585  //	a3    uintptr
   586  //	a4    uintptr
   587  //	a5    uintptr
   588  //	a6    uintptr
   589  //	r1    uintptr
   590  //	r2    uintptr
   591  //	err   uintptr
   592  // }
   593  // syscall6X must be called on the g0 stack with the
   594  // C calling convention (use libcCall).
   595  //
   596  // syscall6X is like syscall6 but expects a 64-bit result
   597  // and tests for 64-bit -1 to decide there was an error.
   598  TEXT runtime·syscall6X(SB),NOSPLIT,$0
   599  	PUSHQ	BP
   600  	MOVQ	SP, BP
   601  	SUBQ	$16, SP
   602  	MOVQ	(0*8)(DI), R11// fn
   603  	MOVQ	(2*8)(DI), SI // a2
   604  	MOVQ	(3*8)(DI), DX // a3
   605  	MOVQ	(4*8)(DI), CX // a4
   606  	MOVQ	(5*8)(DI), R8 // a5
   607  	MOVQ	(6*8)(DI), R9 // a6
   608  	MOVQ	DI, (SP)
   609  	MOVQ	(1*8)(DI), DI // a1
   610  	XORL	AX, AX	      // vararg: say "no float args"
   611  
   612  	CALL	R11
   613  
   614  	MOVQ	(SP), DI
   615  	MOVQ	AX, (7*8)(DI) // r1
   616  	MOVQ	DX, (8*8)(DI) // r2
   617  
   618  	CMPQ	AX, $-1
   619  	JNE	ok
   620  
   621  	CALL	libc_errno(SB)
   622  	MOVLQSX	(AX), AX
   623  	MOVQ	(SP), DI
   624  	MOVQ	AX, (9*8)(DI) // err
   625  
   626  ok:
   627  	XORL	AX, AX        // no error (it's ignored anyway)
   628  	MOVQ	BP, SP
   629  	POPQ	BP
   630  	RET
   631  
   632  // syscall10 calls a function in libc on behalf of the syscall package.
   633  // syscall10 takes a pointer to a struct like:
   634  // struct {
   635  //	fn    uintptr
   636  //	a1    uintptr
   637  //	a2    uintptr
   638  //	a3    uintptr
   639  //	a4    uintptr
   640  //	a5    uintptr
   641  //	a6    uintptr
   642  //	a7    uintptr
   643  //	a8    uintptr
   644  //	a9    uintptr
   645  //	a10   uintptr
   646  //	r1    uintptr
   647  //	r2    uintptr
   648  //	err   uintptr
   649  // }
   650  // syscall10 must be called on the g0 stack with the
   651  // C calling convention (use libcCall).
   652  TEXT runtime·syscall10(SB),NOSPLIT,$0
   653  	PUSHQ	BP
   654  	MOVQ	SP, BP
   655  	SUBQ    $48, SP
   656  
   657  	// Arguments a1 to a6 get passed in registers, with a7 onwards being
   658  	// passed via the stack per the x86-64 System V ABI
   659  	// (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
   660  	MOVQ	(7*8)(DI), R10	// a7
   661  	MOVQ	(8*8)(DI), R11	// a8
   662  	MOVQ	(9*8)(DI), R12	// a9
   663  	MOVQ	(10*8)(DI), R13	// a10
   664  	MOVQ	R10, (0*8)(SP)	// a7
   665  	MOVQ	R11, (1*8)(SP)	// a8
   666  	MOVQ	R12, (2*8)(SP)	// a9
   667  	MOVQ	R13, (3*8)(SP)	// a10
   668  	MOVQ	(0*8)(DI), R11	// fn
   669  	MOVQ	(2*8)(DI), SI	// a2
   670  	MOVQ	(3*8)(DI), DX	// a3
   671  	MOVQ	(4*8)(DI), CX	// a4
   672  	MOVQ	(5*8)(DI), R8	// a5
   673  	MOVQ	(6*8)(DI), R9	// a6
   674  	MOVQ	DI, (4*8)(SP)
   675  	MOVQ	(1*8)(DI), DI	// a1
   676  	XORL	AX, AX	     	// vararg: say "no float args"
   677  
   678  	CALL	R11
   679  
   680  	MOVQ	(4*8)(SP), DI
   681  	MOVQ	AX, (11*8)(DI) // r1
   682  	MOVQ	DX, (12*8)(DI) // r2
   683  
   684  	CMPL	AX, $-1
   685  	JNE	ok
   686  
   687  	CALL	libc_errno(SB)
   688  	MOVLQSX	(AX), AX
   689  	MOVQ	(4*8)(SP), DI
   690  	MOVQ	AX, (13*8)(DI) // err
   691  
   692  ok:
   693  	XORL	AX, AX        // no error (it's ignored anyway)
   694  	MOVQ	BP, SP
   695  	POPQ	BP
   696  	RET
   697  
   698  // syscall10X calls a function in libc on behalf of the syscall package.
   699  // syscall10X takes a pointer to a struct like:
   700  // struct {
   701  //	fn    uintptr
   702  //	a1    uintptr
   703  //	a2    uintptr
   704  //	a3    uintptr
   705  //	a4    uintptr
   706  //	a5    uintptr
   707  //	a6    uintptr
   708  //	a7    uintptr
   709  //	a8    uintptr
   710  //	a9    uintptr
   711  //	a10   uintptr
   712  //	r1    uintptr
   713  //	r2    uintptr
   714  //	err   uintptr
   715  // }
   716  // syscall10X must be called on the g0 stack with the
   717  // C calling convention (use libcCall).
   718  //
   719  // syscall10X is like syscall10 but expects a 64-bit result
   720  // and tests for 64-bit -1 to decide there was an error.
   721  TEXT runtime·syscall10X(SB),NOSPLIT,$0
   722  	PUSHQ	BP
   723  	MOVQ	SP, BP
   724  	SUBQ    $48, SP
   725  
   726  	// Arguments a1 to a6 get passed in registers, with a7 onwards being
   727  	// passed via the stack per the x86-64 System V ABI
   728  	// (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
   729  	MOVQ	(7*8)(DI), R10	// a7
   730  	MOVQ	(8*8)(DI), R11	// a8
   731  	MOVQ	(9*8)(DI), R12	// a9
   732  	MOVQ	(10*8)(DI), R13	// a10
   733  	MOVQ	R10, (0*8)(SP)	// a7
   734  	MOVQ	R11, (1*8)(SP)	// a8
   735  	MOVQ	R12, (2*8)(SP)	// a9
   736  	MOVQ	R13, (3*8)(SP)	// a10
   737  	MOVQ	(0*8)(DI), R11	// fn
   738  	MOVQ	(2*8)(DI), SI	// a2
   739  	MOVQ	(3*8)(DI), DX	// a3
   740  	MOVQ	(4*8)(DI), CX	// a4
   741  	MOVQ	(5*8)(DI), R8	// a5
   742  	MOVQ	(6*8)(DI), R9	// a6
   743  	MOVQ	DI, (4*8)(SP)
   744  	MOVQ	(1*8)(DI), DI	// a1
   745  	XORL	AX, AX	     	// vararg: say "no float args"
   746  
   747  	CALL	R11
   748  
   749  	MOVQ	(4*8)(SP), DI
   750  	MOVQ	AX, (11*8)(DI) // r1
   751  	MOVQ	DX, (12*8)(DI) // r2
   752  
   753  	CMPQ	AX, $-1
   754  	JNE	ok
   755  
   756  	CALL	libc_errno(SB)
   757  	MOVLQSX	(AX), AX
   758  	MOVQ	(4*8)(SP), DI
   759  	MOVQ	AX, (13*8)(DI) // err
   760  
   761  ok:
   762  	XORL	AX, AX        // no error (it's ignored anyway)
   763  	MOVQ	BP, SP
   764  	POPQ	BP
   765  	RET
   766  

View as plain text