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  	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(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	noerr
   373  	CALL	libc_errno(SB)
   374  	MOVL	(AX), AX		// errno
   375  	NEGL	AX			// caller expects negative errno value
   376  noerr:
   377  	POPQ	BP
   378  	RET
   379  
   380  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   381  	PUSHQ	BP
   382  	MOVQ	SP, BP
   383  	MOVL	4(DI), SI		// arg 2 cmd
   384  	MOVL	8(DI), DX		// arg 3 arg
   385  	MOVL	0(DI), DI		// arg 1 fd
   386  	XORL	AX, AX			// vararg: say "no float args"
   387  	CALL	libc_fcntl(SB)
   388  	POPQ	BP
   389  	RET
   390  
   391  TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
   392  	PUSHQ	BP
   393  	MOVQ	SP, BP
   394  	MOVQ	8(DI), SI		// arg 2 new
   395  	MOVQ	16(DI), DX		// arg 3 old
   396  	MOVL	0(DI), DI		// arg 1 sig
   397  	CALL	libc_sigaction(SB)
   398  	TESTL	AX, AX
   399  	JEQ	2(PC)
   400  	MOVL	$0xf1, 0xf1  // crash
   401  	POPQ	BP
   402  	RET
   403  
   404  TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   405  	PUSHQ	BP
   406  	MOVQ	SP, BP
   407  	MOVQ	8(DI), SI	// arg 2 new
   408  	MOVQ	16(DI), DX	// arg 3 old
   409  	MOVL	0(DI), DI	// arg 1 how
   410  	CALL	libc_pthread_sigmask(SB)
   411  	TESTL	AX, AX
   412  	JEQ	2(PC)
   413  	MOVL	$0xf1, 0xf1  // crash
   414  	POPQ	BP
   415  	RET
   416  
   417  TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   418  	PUSHQ	BP
   419  	MOVQ	SP, BP
   420  	MOVQ	8(DI), SI		// arg 2 old
   421  	MOVQ	0(DI), DI		// arg 1 new
   422  	CALL	libc_sigaltstack(SB)
   423  	TESTQ	AX, AX
   424  	JEQ	2(PC)
   425  	MOVL	$0xf1, 0xf1  // crash
   426  	POPQ	BP
   427  	RET
   428  
   429  // syscall calls a function in libc on behalf of the syscall package.
   430  // syscall takes a pointer to a struct like:
   431  // struct {
   432  //	fn    uintptr
   433  //	a1    uintptr
   434  //	a2    uintptr
   435  //	a3    uintptr
   436  //	r1    uintptr
   437  //	r2    uintptr
   438  //	err   uintptr
   439  // }
   440  // syscall must be called on the g0 stack with the
   441  // C calling convention (use libcCall).
   442  //
   443  // syscall expects a 32-bit result and tests for 32-bit -1
   444  // to decide there was an error.
   445  TEXT runtime·syscall(SB),NOSPLIT,$0
   446  	PUSHQ	BP
   447  	MOVQ	SP, BP
   448  	SUBQ	$16, SP
   449  	MOVQ	(0*8)(DI), CX // fn
   450  	MOVQ	(2*8)(DI), SI // a2
   451  	MOVQ	(3*8)(DI), DX // a3
   452  	MOVQ	DI, (SP)
   453  	MOVQ	(1*8)(DI), DI // a1
   454  	XORL	AX, AX	      // vararg: say "no float args"
   455  
   456  	CALL	CX
   457  
   458  	MOVQ	(SP), DI
   459  	MOVQ	AX, (4*8)(DI) // r1
   460  	MOVQ	DX, (5*8)(DI) // r2
   461  
   462  	// Standard libc functions return -1 on error
   463  	// and set errno.
   464  	CMPL	AX, $-1	      // Note: high 32 bits are junk
   465  	JNE	ok
   466  
   467  	// Get error code from libc.
   468  	CALL	libc_errno(SB)
   469  	MOVLQSX	(AX), AX
   470  	MOVQ	(SP), DI
   471  	MOVQ	AX, (6*8)(DI) // err
   472  
   473  ok:
   474  	XORL	AX, AX        // no error (it's ignored anyway)
   475  	MOVQ	BP, SP
   476  	POPQ	BP
   477  	RET
   478  
   479  // syscallX calls a function in libc on behalf of the syscall package.
   480  // syscallX takes a pointer to a struct like:
   481  // struct {
   482  //	fn    uintptr
   483  //	a1    uintptr
   484  //	a2    uintptr
   485  //	a3    uintptr
   486  //	r1    uintptr
   487  //	r2    uintptr
   488  //	err   uintptr
   489  // }
   490  // syscallX must be called on the g0 stack with the
   491  // C calling convention (use libcCall).
   492  //
   493  // syscallX is like syscall but expects a 64-bit result
   494  // and tests for 64-bit -1 to decide there was an error.
   495  TEXT runtime·syscallX(SB),NOSPLIT,$0
   496  	PUSHQ	BP
   497  	MOVQ	SP, BP
   498  	SUBQ	$16, SP
   499  	MOVQ	(0*8)(DI), CX // fn
   500  	MOVQ	(2*8)(DI), SI // a2
   501  	MOVQ	(3*8)(DI), DX // a3
   502  	MOVQ	DI, (SP)
   503  	MOVQ	(1*8)(DI), DI // a1
   504  	XORL	AX, AX	      // vararg: say "no float args"
   505  
   506  	CALL	CX
   507  
   508  	MOVQ	(SP), DI
   509  	MOVQ	AX, (4*8)(DI) // r1
   510  	MOVQ	DX, (5*8)(DI) // r2
   511  
   512  	// Standard libc functions return -1 on error
   513  	// and set errno.
   514  	CMPQ	AX, $-1
   515  	JNE	ok
   516  
   517  	// Get error code from libc.
   518  	CALL	libc_errno(SB)
   519  	MOVLQSX	(AX), AX
   520  	MOVQ	(SP), DI
   521  	MOVQ	AX, (6*8)(DI) // err
   522  
   523  ok:
   524  	XORL	AX, AX        // no error (it's ignored anyway)
   525  	MOVQ	BP, SP
   526  	POPQ	BP
   527  	RET
   528  
   529  // syscall6 calls a function in libc on behalf of the syscall package.
   530  // syscall6 takes a pointer to a struct like:
   531  // struct {
   532  //	fn    uintptr
   533  //	a1    uintptr
   534  //	a2    uintptr
   535  //	a3    uintptr
   536  //	a4    uintptr
   537  //	a5    uintptr
   538  //	a6    uintptr
   539  //	r1    uintptr
   540  //	r2    uintptr
   541  //	err   uintptr
   542  // }
   543  // syscall6 must be called on the g0 stack with the
   544  // C calling convention (use libcCall).
   545  //
   546  // syscall6 expects a 32-bit result and tests for 32-bit -1
   547  // to decide there was an error.
   548  TEXT runtime·syscall6(SB),NOSPLIT,$0
   549  	PUSHQ	BP
   550  	MOVQ	SP, BP
   551  	SUBQ	$16, SP
   552  	MOVQ	(0*8)(DI), R11// fn
   553  	MOVQ	(2*8)(DI), SI // a2
   554  	MOVQ	(3*8)(DI), DX // a3
   555  	MOVQ	(4*8)(DI), CX // a4
   556  	MOVQ	(5*8)(DI), R8 // a5
   557  	MOVQ	(6*8)(DI), R9 // a6
   558  	MOVQ	DI, (SP)
   559  	MOVQ	(1*8)(DI), DI // a1
   560  	XORL	AX, AX	      // vararg: say "no float args"
   561  
   562  	CALL	R11
   563  
   564  	MOVQ	(SP), DI
   565  	MOVQ	AX, (7*8)(DI) // r1
   566  	MOVQ	DX, (8*8)(DI) // r2
   567  
   568  	CMPL	AX, $-1
   569  	JNE	ok
   570  
   571  	CALL	libc_errno(SB)
   572  	MOVLQSX	(AX), AX
   573  	MOVQ	(SP), DI
   574  	MOVQ	AX, (9*8)(DI) // err
   575  
   576  ok:
   577  	XORL	AX, AX        // no error (it's ignored anyway)
   578  	MOVQ	BP, SP
   579  	POPQ	BP
   580  	RET
   581  
   582  // syscall6X calls a function in libc on behalf of the syscall package.
   583  // syscall6X takes a pointer to a struct like:
   584  // struct {
   585  //	fn    uintptr
   586  //	a1    uintptr
   587  //	a2    uintptr
   588  //	a3    uintptr
   589  //	a4    uintptr
   590  //	a5    uintptr
   591  //	a6    uintptr
   592  //	r1    uintptr
   593  //	r2    uintptr
   594  //	err   uintptr
   595  // }
   596  // syscall6X must be called on the g0 stack with the
   597  // C calling convention (use libcCall).
   598  //
   599  // syscall6X is like syscall6 but expects a 64-bit result
   600  // and tests for 64-bit -1 to decide there was an error.
   601  TEXT runtime·syscall6X(SB),NOSPLIT,$0
   602  	PUSHQ	BP
   603  	MOVQ	SP, BP
   604  	SUBQ	$16, SP
   605  	MOVQ	(0*8)(DI), R11// fn
   606  	MOVQ	(2*8)(DI), SI // a2
   607  	MOVQ	(3*8)(DI), DX // a3
   608  	MOVQ	(4*8)(DI), CX // a4
   609  	MOVQ	(5*8)(DI), R8 // a5
   610  	MOVQ	(6*8)(DI), R9 // a6
   611  	MOVQ	DI, (SP)
   612  	MOVQ	(1*8)(DI), DI // a1
   613  	XORL	AX, AX	      // vararg: say "no float args"
   614  
   615  	CALL	R11
   616  
   617  	MOVQ	(SP), DI
   618  	MOVQ	AX, (7*8)(DI) // r1
   619  	MOVQ	DX, (8*8)(DI) // r2
   620  
   621  	CMPQ	AX, $-1
   622  	JNE	ok
   623  
   624  	CALL	libc_errno(SB)
   625  	MOVLQSX	(AX), AX
   626  	MOVQ	(SP), DI
   627  	MOVQ	AX, (9*8)(DI) // err
   628  
   629  ok:
   630  	XORL	AX, AX        // no error (it's ignored anyway)
   631  	MOVQ	BP, SP
   632  	POPQ	BP
   633  	RET
   634  
   635  // syscall10 calls a function in libc on behalf of the syscall package.
   636  // syscall10 takes a pointer to a struct like:
   637  // struct {
   638  //	fn    uintptr
   639  //	a1    uintptr
   640  //	a2    uintptr
   641  //	a3    uintptr
   642  //	a4    uintptr
   643  //	a5    uintptr
   644  //	a6    uintptr
   645  //	a7    uintptr
   646  //	a8    uintptr
   647  //	a9    uintptr
   648  //	a10   uintptr
   649  //	r1    uintptr
   650  //	r2    uintptr
   651  //	err   uintptr
   652  // }
   653  // syscall10 must be called on the g0 stack with the
   654  // C calling convention (use libcCall).
   655  TEXT runtime·syscall10(SB),NOSPLIT,$0
   656  	PUSHQ	BP
   657  	MOVQ	SP, BP
   658  	SUBQ    $48, SP
   659  
   660  	// Arguments a1 to a6 get passed in registers, with a7 onwards being
   661  	// passed via the stack per the x86-64 System V ABI
   662  	// (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
   663  	MOVQ	(7*8)(DI), R10	// a7
   664  	MOVQ	(8*8)(DI), R11	// a8
   665  	MOVQ	(9*8)(DI), R12	// a9
   666  	MOVQ	(10*8)(DI), R13	// a10
   667  	MOVQ	R10, (0*8)(SP)	// a7
   668  	MOVQ	R11, (1*8)(SP)	// a8
   669  	MOVQ	R12, (2*8)(SP)	// a9
   670  	MOVQ	R13, (3*8)(SP)	// a10
   671  	MOVQ	(0*8)(DI), R11	// fn
   672  	MOVQ	(2*8)(DI), SI	// a2
   673  	MOVQ	(3*8)(DI), DX	// a3
   674  	MOVQ	(4*8)(DI), CX	// a4
   675  	MOVQ	(5*8)(DI), R8	// a5
   676  	MOVQ	(6*8)(DI), R9	// a6
   677  	MOVQ	DI, (4*8)(SP)
   678  	MOVQ	(1*8)(DI), DI	// a1
   679  	XORL	AX, AX	     	// vararg: say "no float args"
   680  
   681  	CALL	R11
   682  
   683  	MOVQ	(4*8)(SP), DI
   684  	MOVQ	AX, (11*8)(DI) // r1
   685  	MOVQ	DX, (12*8)(DI) // r2
   686  
   687  	CMPL	AX, $-1
   688  	JNE	ok
   689  
   690  	CALL	libc_errno(SB)
   691  	MOVLQSX	(AX), AX
   692  	MOVQ	(4*8)(SP), DI
   693  	MOVQ	AX, (13*8)(DI) // err
   694  
   695  ok:
   696  	XORL	AX, AX        // no error (it's ignored anyway)
   697  	MOVQ	BP, SP
   698  	POPQ	BP
   699  	RET
   700  
   701  // syscall10X calls a function in libc on behalf of the syscall package.
   702  // syscall10X takes a pointer to a struct like:
   703  // struct {
   704  //	fn    uintptr
   705  //	a1    uintptr
   706  //	a2    uintptr
   707  //	a3    uintptr
   708  //	a4    uintptr
   709  //	a5    uintptr
   710  //	a6    uintptr
   711  //	a7    uintptr
   712  //	a8    uintptr
   713  //	a9    uintptr
   714  //	a10   uintptr
   715  //	r1    uintptr
   716  //	r2    uintptr
   717  //	err   uintptr
   718  // }
   719  // syscall10X must be called on the g0 stack with the
   720  // C calling convention (use libcCall).
   721  //
   722  // syscall10X is like syscall10 but expects a 64-bit result
   723  // and tests for 64-bit -1 to decide there was an error.
   724  TEXT runtime·syscall10X(SB),NOSPLIT,$0
   725  	PUSHQ	BP
   726  	MOVQ	SP, BP
   727  	SUBQ    $48, SP
   728  
   729  	// Arguments a1 to a6 get passed in registers, with a7 onwards being
   730  	// passed via the stack per the x86-64 System V ABI
   731  	// (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
   732  	MOVQ	(7*8)(DI), R10	// a7
   733  	MOVQ	(8*8)(DI), R11	// a8
   734  	MOVQ	(9*8)(DI), R12	// a9
   735  	MOVQ	(10*8)(DI), R13	// a10
   736  	MOVQ	R10, (0*8)(SP)	// a7
   737  	MOVQ	R11, (1*8)(SP)	// a8
   738  	MOVQ	R12, (2*8)(SP)	// a9
   739  	MOVQ	R13, (3*8)(SP)	// a10
   740  	MOVQ	(0*8)(DI), R11	// fn
   741  	MOVQ	(2*8)(DI), SI	// a2
   742  	MOVQ	(3*8)(DI), DX	// a3
   743  	MOVQ	(4*8)(DI), CX	// a4
   744  	MOVQ	(5*8)(DI), R8	// a5
   745  	MOVQ	(6*8)(DI), R9	// a6
   746  	MOVQ	DI, (4*8)(SP)
   747  	MOVQ	(1*8)(DI), DI	// a1
   748  	XORL	AX, AX	     	// vararg: say "no float args"
   749  
   750  	CALL	R11
   751  
   752  	MOVQ	(4*8)(SP), DI
   753  	MOVQ	AX, (11*8)(DI) // r1
   754  	MOVQ	DX, (12*8)(DI) // r2
   755  
   756  	CMPQ	AX, $-1
   757  	JNE	ok
   758  
   759  	CALL	libc_errno(SB)
   760  	MOVLQSX	(AX), AX
   761  	MOVQ	(4*8)(SP), DI
   762  	MOVQ	AX, (13*8)(DI) // err
   763  
   764  ok:
   765  	XORL	AX, AX        // no error (it's ignored anyway)
   766  	MOVQ	BP, SP
   767  	POPQ	BP
   768  	RET
   769  

View as plain text