github.com/spotify/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/runtime/sys_freebsd_amd64.s (about)

     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, FreeBSD
     6  // /usr/src/sys/kern/syscalls.master for syscall numbers.
     7  //
     8  
     9  #include "zasm_GOOS_GOARCH.h"
    10  #include "../../cmd/ld/textflag.h"
    11  
    12  // FreeBSD 8, FreeBSD 9, and older versions that I have checked
    13  // do not restore R10 on exit from a "restarted" system call
    14  // if you use the SYSCALL instruction. This means that, for example,
    15  // if a signal arrives while the wait4 system call is executing,
    16  // the wait4 internally returns ERESTART, which makes the kernel
    17  // back up the PC to execute the SYSCALL instruction a second time.
    18  // However, since the kernel does not restore R10, the fourth
    19  // argument to the system call has been lost. (FreeBSD 9 also fails
    20  // to restore the fifth and sixth arguments, R8 and R9, although
    21  // some earlier versions did restore those correctly.)
    22  // The broken code is in fast_syscall in FreeBSD's amd64/amd64/exception.S.
    23  // It restores only DI, SI, DX, AX, and RFLAGS on system call return.
    24  // http://fxr.watson.org/fxr/source/amd64/amd64/exception.S?v=FREEBSD91#L399
    25  //
    26  // The INT $0x80 system call path (int0x80_syscall in FreeBSD's 
    27  // amd64/ia32/ia32_exception.S) does not have this problem,
    28  // but it expects the third argument in R10. Instead of rewriting
    29  // all the assembly in this file, #define SYSCALL to a safe simulation
    30  // using INT $0x80.
    31  //
    32  // INT $0x80 is a little slower than SYSCALL, but correctness wins.
    33  //
    34  // See golang.org/issue/6372.
    35  #define SYSCALL MOVQ R10, CX; INT $0x80
    36  	
    37  TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
    38  	MOVQ 8(SP), DI
    39  	MOVL 16(SP), SI
    40  	MOVL 20(SP), DX
    41  	MOVQ 24(SP), R10
    42  	MOVQ 32(SP), R8
    43  	MOVL $454, AX
    44  	SYSCALL
    45  	RET
    46  
    47  TEXT runtime·thr_new(SB),NOSPLIT,$0
    48  	MOVQ 8(SP), DI
    49  	MOVQ 16(SP), SI
    50  	MOVL $455, AX
    51  	SYSCALL
    52  	RET
    53  
    54  TEXT runtime·thr_start(SB),NOSPLIT,$0
    55  	MOVQ	DI, R13 // m
    56  
    57  	// set up FS to point at m->tls
    58  	LEAQ	m_tls(R13), DI
    59  	CALL	runtime·settls(SB)	// smashes DI
    60  
    61  	// set up m, g
    62  	get_tls(CX)
    63  	MOVQ	R13, m(CX)
    64  	MOVQ	m_g0(R13), DI
    65  	MOVQ	DI, g(CX)
    66  
    67  	CALL	runtime·stackcheck(SB)
    68  	CALL	runtime·mstart(SB)
    69  
    70  	MOVQ 0, AX			// crash (not reached)
    71  
    72  // Exit the entire program (like C exit)
    73  TEXT runtime·exit(SB),NOSPLIT,$-8
    74  	MOVL	8(SP), DI		// arg 1 exit status
    75  	MOVL	$1, AX
    76  	SYSCALL
    77  	MOVL	$0xf1, 0xf1  // crash
    78  	RET
    79  
    80  TEXT runtime·exit1(SB),NOSPLIT,$-8
    81  	MOVQ	8(SP), DI		// arg 1 exit status
    82  	MOVL	$431, AX
    83  	SYSCALL
    84  	MOVL	$0xf1, 0xf1  // crash
    85  	RET
    86  
    87  TEXT runtime·open(SB),NOSPLIT,$-8
    88  	MOVQ	8(SP), DI		// arg 1 pathname
    89  	MOVL	16(SP), SI		// arg 2 flags
    90  	MOVL	20(SP), DX		// arg 3 mode
    91  	MOVL	$5, AX
    92  	SYSCALL
    93  	RET
    94  
    95  TEXT runtime·close(SB),NOSPLIT,$-8
    96  	MOVL	8(SP), DI		// arg 1 fd
    97  	MOVL	$6, AX
    98  	SYSCALL
    99  	RET
   100  
   101  TEXT runtime·read(SB),NOSPLIT,$-8
   102  	MOVL	8(SP), DI		// arg 1 fd
   103  	MOVQ	16(SP), SI		// arg 2 buf
   104  	MOVL	24(SP), DX		// arg 3 count
   105  	MOVL	$3, AX
   106  	SYSCALL
   107  	RET
   108  
   109  TEXT runtime·write(SB),NOSPLIT,$-8
   110  	MOVL	8(SP), DI		// arg 1 fd
   111  	MOVQ	16(SP), SI		// arg 2 buf
   112  	MOVL	24(SP), DX		// arg 3 count
   113  	MOVL	$4, AX
   114  	SYSCALL
   115  	RET
   116  
   117  TEXT runtime·getrlimit(SB),NOSPLIT,$-8
   118  	MOVL	8(SP), DI
   119  	MOVQ	16(SP), SI
   120  	MOVL	$194, AX
   121  	SYSCALL
   122  	RET
   123  
   124  TEXT runtime·raise(SB),NOSPLIT,$16
   125  	// thr_self(&8(SP))
   126  	LEAQ	8(SP), DI	// arg 1 &8(SP)
   127  	MOVL	$432, AX
   128  	SYSCALL
   129  	// thr_kill(self, SIGPIPE)
   130  	MOVQ	8(SP), DI	// arg 1 id
   131  	MOVL	sig+0(FP), SI	// arg 2
   132  	MOVL	$433, AX
   133  	SYSCALL
   134  	RET
   135  
   136  TEXT runtime·setitimer(SB), NOSPLIT, $-8
   137  	MOVL	8(SP), DI
   138  	MOVQ	16(SP), SI
   139  	MOVQ	24(SP), DX
   140  	MOVL	$83, AX
   141  	SYSCALL
   142  	RET
   143  
   144  // func now() (sec int64, nsec int32)
   145  TEXT time·now(SB), NOSPLIT, $32
   146  	MOVL	$232, AX
   147  	MOVQ	$0, DI
   148  	LEAQ	8(SP), SI
   149  	SYSCALL
   150  	MOVQ	8(SP), AX	// sec
   151  	MOVQ	16(SP), DX	// nsec
   152  
   153  	// sec is in AX, nsec in DX
   154  	MOVQ	AX, sec+0(FP)
   155  	MOVL	DX, nsec+8(FP)
   156  	RET
   157  
   158  TEXT runtime·nanotime(SB), NOSPLIT, $32
   159  	MOVL	$232, AX
   160  	MOVQ	$0, DI
   161  	LEAQ	8(SP), SI
   162  	SYSCALL
   163  	MOVQ	8(SP), AX	// sec
   164  	MOVQ	16(SP), DX	// nsec
   165  
   166  	// sec is in AX, nsec in DX
   167  	// return nsec in AX
   168  	IMULQ	$1000000000, AX
   169  	ADDQ	DX, AX
   170  	RET
   171  
   172  TEXT runtime·sigaction(SB),NOSPLIT,$-8
   173  	MOVL	8(SP), DI		// arg 1 sig
   174  	MOVQ	16(SP), SI		// arg 2 act
   175  	MOVQ	24(SP), DX		// arg 3 oact
   176  	MOVL	$416, AX
   177  	SYSCALL
   178  	JCC	2(PC)
   179  	MOVL	$0xf1, 0xf1  // crash
   180  	RET
   181  
   182  TEXT runtime·sigtramp(SB),NOSPLIT,$64
   183  	get_tls(BX)
   184  
   185  	// check that m exists
   186  	MOVQ	m(BX), BP
   187  	CMPQ	BP, $0
   188  	JNE	5(PC)
   189  	MOVQ	DI, 0(SP)
   190  	MOVQ	$runtime·badsignal(SB), AX
   191  	CALL	AX
   192  	RET
   193  
   194  	// save g
   195  	MOVQ	g(BX), R10
   196  	MOVQ	R10, 40(SP)
   197  	
   198  	// g = m->signal
   199  	MOVQ	m_gsignal(BP), BP
   200  	MOVQ	BP, g(BX)
   201  	
   202  	MOVQ	DI, 0(SP)
   203  	MOVQ	SI, 8(SP)
   204  	MOVQ	DX, 16(SP)
   205  	MOVQ	R10, 24(SP)
   206  
   207  	CALL	runtime·sighandler(SB)
   208  
   209  	// restore g
   210  	get_tls(BX)
   211  	MOVQ	40(SP), R10
   212  	MOVQ	R10, g(BX)
   213  	RET
   214  
   215  TEXT runtime·mmap(SB),NOSPLIT,$0
   216  	MOVQ	8(SP), DI		// arg 1 addr
   217  	MOVQ	16(SP), SI		// arg 2 len
   218  	MOVL	24(SP), DX		// arg 3 prot
   219  	MOVL	28(SP), R10		// arg 4 flags
   220  	MOVL	32(SP), R8		// arg 5 fid
   221  	MOVL	36(SP), R9		// arg 6 offset
   222  	MOVL	$477, AX
   223  	SYSCALL
   224  	RET
   225  
   226  TEXT runtime·munmap(SB),NOSPLIT,$0
   227  	MOVQ	8(SP), DI		// arg 1 addr
   228  	MOVQ	16(SP), SI		// arg 2 len
   229  	MOVL	$73, AX
   230  	SYSCALL
   231  	JCC	2(PC)
   232  	MOVL	$0xf1, 0xf1  // crash
   233  	RET
   234  
   235  TEXT runtime·madvise(SB),NOSPLIT,$0
   236  	MOVQ	8(SP), DI
   237  	MOVQ	16(SP), SI
   238  	MOVQ	24(SP), DX
   239  	MOVQ	$75, AX	// madvise
   240  	SYSCALL
   241  	// ignore failure - maybe pages are locked
   242  	RET
   243  	
   244  TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
   245  	MOVQ	new+8(SP), DI
   246  	MOVQ	old+16(SP), SI
   247  	MOVQ	$53, AX
   248  	SYSCALL
   249  	JCC	2(PC)
   250  	MOVL	$0xf1, 0xf1  // crash
   251  	RET
   252  
   253  TEXT runtime·usleep(SB),NOSPLIT,$16
   254  	MOVL	$0, DX
   255  	MOVL	usec+0(FP), AX
   256  	MOVL	$1000000, CX
   257  	DIVL	CX
   258  	MOVQ	AX, 0(SP)		// tv_sec
   259  	MOVL	$1000, AX
   260  	MULL	DX
   261  	MOVQ	AX, 8(SP)		// tv_nsec
   262  
   263  	MOVQ	SP, DI			// arg 1 - rqtp
   264  	MOVQ	$0, SI			// arg 2 - rmtp
   265  	MOVL	$240, AX		// sys_nanosleep
   266  	SYSCALL
   267  	RET
   268  
   269  // set tls base to DI
   270  TEXT runtime·settls(SB),NOSPLIT,$8
   271  	ADDQ	$16, DI	// adjust for ELF: wants to use -16(FS) and -8(FS) for g and m
   272  	MOVQ	DI, 0(SP)
   273  	MOVQ	SP, SI
   274  	MOVQ	$129, DI	// AMD64_SET_FSBASE
   275  	MOVQ	$165, AX	// sysarch
   276  	SYSCALL
   277  	JCC	2(PC)
   278  	MOVL	$0xf1, 0xf1  // crash
   279  	RET
   280  
   281  TEXT runtime·sysctl(SB),NOSPLIT,$0
   282  	MOVQ	8(SP), DI		// arg 1 - name
   283  	MOVL	16(SP), SI		// arg 2 - namelen
   284  	MOVQ	24(SP), DX		// arg 3 - oldp
   285  	MOVQ	32(SP), R10		// arg 4 - oldlenp
   286  	MOVQ	40(SP), R8		// arg 5 - newp
   287  	MOVQ	48(SP), R9		// arg 6 - newlen
   288  	MOVQ	$202, AX		// sys___sysctl
   289  	SYSCALL
   290  	JCC 3(PC)
   291  	NEGQ	AX
   292  	RET
   293  	MOVL	$0, AX
   294  	RET
   295  
   296  TEXT runtime·osyield(SB),NOSPLIT,$-4
   297  	MOVL	$331, AX		// sys_sched_yield
   298  	SYSCALL
   299  	RET
   300  
   301  TEXT runtime·sigprocmask(SB),NOSPLIT,$0
   302  	MOVL	$3, DI			// arg 1 - how (SIG_SETMASK)
   303  	MOVQ	8(SP), SI		// arg 2 - set
   304  	MOVQ	16(SP), DX		// arg 3 - oset
   305  	MOVL	$340, AX		// sys_sigprocmask
   306  	SYSCALL
   307  	JAE	2(PC)
   308  	MOVL	$0xf1, 0xf1  // crash
   309  	RET
   310  
   311  // int32 runtime·kqueue(void);
   312  TEXT runtime·kqueue(SB),NOSPLIT,$0
   313  	MOVQ	$0, DI
   314  	MOVQ	$0, SI
   315  	MOVQ	$0, DX
   316  	MOVL	$362, AX
   317  	SYSCALL
   318  	JCC	2(PC)
   319  	NEGQ	AX
   320  	RET
   321  
   322  // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
   323  TEXT runtime·kevent(SB),NOSPLIT,$0
   324  	MOVL	8(SP), DI
   325  	MOVQ	16(SP), SI
   326  	MOVL	24(SP), DX
   327  	MOVQ	32(SP), R10
   328  	MOVL	40(SP), R8
   329  	MOVQ	48(SP), R9
   330  	MOVL	$363, AX
   331  	SYSCALL
   332  	JCC	2(PC)
   333  	NEGQ	AX
   334  	RET
   335  
   336  // void runtime·closeonexec(int32 fd);
   337  TEXT runtime·closeonexec(SB),NOSPLIT,$0
   338  	MOVL	8(SP), DI	// fd
   339  	MOVQ	$2, SI		// F_SETFD
   340  	MOVQ	$1, DX		// FD_CLOEXEC
   341  	MOVL	$92, AX		// fcntl
   342  	SYSCALL
   343  	RET