github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/runtime/sys_nacl_386.s (about)

     1  // Copyright 2013 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  // NaCl system calls are mediated through an "outer sandbox."  System calls are
     6  // internally implemented by branching to a stub in the system call table
     7  // located at address 0x10000+32*number.
     8  //
     9  // However, the system call interface isn't part of the public NaCl API, and it
    10  // is subject to change.  The officially supported interface is the NaCl IRT
    11  // (for "integrated runtime"), which must be manually linked.  If the IRT is
    12  // available, a lookup function is passed via the Elf aux vector, for fetching
    13  // the function pointers corresponding to each of the IRT functions.
    14  //
    15  // For now, we support both mechanisms.	 If the IRT is available, we use it.
    16  // Otherwise, we invoke the raw system calls directly.	The two interfaces are
    17  // similar; the IRT is really just a thin wrapper around the system calls,
    18  // changing the signature somewhat.  For example, the raw system calls use
    19  // return values to pass back results in some cases.
    20  //
    21  //	 // Raw syscall.
    22  //	 int fd = NACL_SYSCALL(SYS_open)(pathname, oflag, mode);
    23  //	 if (fd < 0) { ...error... }
    24  //
    25  // In contrast, the IRT uses return values only for error codes.  Results are
    26  // returned through result parameters.
    27  //
    28  //	 // IRT syscall.
    29  //	 int fd;
    30  //	 int code = (*irt_filename[IRT_FILENAME_OPEN])(pathname, oflag, mode, &fd);
    31  //	 if (code != 0) { ...error... }
    32  //
    33  // Whether raw or IRT, the system call that is invoked runs in the same address
    34  // space as the caller, using the caller's stack.  Since the stack requirements
    35  // for the syscall aren't known, the wrappers here switch from the goroutine
    36  // stack to the main thread stack, invoke the system call, then switch back to
    37  // the original stack.	The basic form of these wrappers is as follows.
    38  //
    39  //	 switch to main thread stack
    40  //	 if !irt_is_enabled
    41  //	     invoke raw syscall
    42  //	 else
    43  //	     invoke IRT syscall
    44  //	 switch back to original stack
    45  //
    46  // One of the reasons for supporting raw syscalls is for the Go playground.  At
    47  // some point, we may want to consider requiring the IRT for the playground,
    48  // removing support for raw syscalls.
    49  
    50  #include "zasm_GOOS_GOARCH.h"
    51  #include "textflag.h"
    52  #include "syscall_nacl.h"
    53  #include "irt_nacl.h"
    54  
    55  #define NACL_SYSCALL(code) \
    56  	MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
    57  
    58  // Swap stacks so that the caller runs on the main m->g0 stack.
    59  // On return, SP is the main m->g0 stack, BP holds the original stack frame, and
    60  // the current stack contains contains the original SP at 0(SP).
    61  TEXT runtime·nacl_swapstack(SB),NOSPLIT,$0
    62  	LEAL	4(SP), BP
    63  
    64  	get_tls(CX)
    65  	CMPL	CX, $0
    66  	JE	nss_return  // Not a Go-managed thread. Do not switch stack.
    67  
    68  	MOVL	g(CX), DI
    69  	MOVL	g_m(DI), DI
    70  	MOVL	m_g0(DI), SI
    71  	CMPL	g(CX), SI
    72  	JE	nss_return  // Executing on m->g0 already.
    73  
    74  	// Switch to m->g0 stack.
    75  	MOVL	(g_sched+gobuf_sp)(SI), SI
    76  	LEAL	-4(SI), SP
    77  
    78  nss_return:
    79  	MOVL	-4(BP), AX
    80  	MOVL	BP, (SP)
    81  	ADDL	$4, BP
    82  	JMP	AX
    83  
    84  // Restore the original stack.	Must not modify AX.
    85  TEXT runtime·nacl_restorestack(SB),NOSPLIT,$0
    86  	MOVL	(SP), BX
    87  	MOVL	4(SP), SP
    88  	JMP	BX
    89  
    90  // Begin a NaCl IRT call.  Execute call on the main m->g0 stack.
    91  // On return, SP is the main m->g0 stack, BP holds the original stack frame, and
    92  // the current stack contains the original SP at 0(SP).	 Call runtime·entersyscall
    93  // only if the stack is switched and the current P is set.
    94  TEXT runtime·nacl_entersyscall(SB),NOSPLIT,$0-0
    95  	MOVL	$0, AX	// AX is set to true only if runtime·entersyscall was called.
    96  	MOVL	SP, BP
    97  
    98  	get_tls(CX)
    99  	TESTL	CX, CX
   100  	JZ	nen_return  // Not a Go-managed thread. Do not switch stack.
   101  
   102  	MOVL	g(CX), DI
   103  	MOVL	g_m(DI), DI
   104  	MOVL	m_g0(DI), SI
   105  	CMPL	g(CX), SI
   106  	JE	nen_return  // Executing on m->g0 already.
   107  
   108  	MOVL	m_p(DI), DX
   109  	TESTL	DX, DX
   110  	JZ	nen_swapstack  // Not a goroutine.
   111  
   112  	CALL	runtime·entersyscall(SB)
   113  	MOVL	$1, AX
   114  	MOVL	SP, BP
   115  	get_tls(CX)
   116  	MOVL	g(CX), DI
   117  	MOVL	g_m(DI), DI
   118  	MOVL	m_g0(DI), SI
   119  
   120  nen_swapstack:
   121  	// Switch to m->g0 stack.
   122  	MOVL	(g_sched+gobuf_sp)(SI), SI
   123  	LEAL	-4(SI), SP
   124  
   125  nen_return:
   126  	SUBL	$8, SP
   127  	MOVL	(BP), CX
   128  	MOVL	BP, (SP)
   129  	MOVL	AX, 4(SP)
   130  	ADDL	$8, BP
   131  	JMP	CX
   132  
   133  // Finish a NaCl IRT call.  Restores the stack, and calls runtime·exitsyscall,
   134  // but only if runtime·entersyscall was called on entry.  Must not modify AX.
   135  TEXT runtime·nacl_exitsyscall(SB),NOSPLIT,$0-0
   136  	MOVL	8(SP), BX
   137  	TESTL	BX, BX
   138  	JZ	nex_return
   139  	MOVL	(SP), BX
   140  	MOVL	4(SP), SP
   141  	MOVL	BX, (SP)
   142  	CALL	runtime·nacl_wrap_exitsyscall(SB)
   143  	RET
   144  nex_return:	
   145  	MOVL	(SP), BX
   146  	MOVL	4(SP), SP
   147  	MOVL	BX, (SP)
   148  	RET
   149  
   150  TEXT runtime·nacl_wrap_exitsyscall(SB),NOSPLIT,$4
   151  	MOVL	AX, (SP)
   152  	CALL	runtime·exitsyscall(SB)
   153  	MOVL	(SP), AX
   154  	RET
   155  
   156  TEXT runtime·exit(SB),NOSPLIT,$0
   157  	CALL	runtime·nacl_swapstack(SB)
   158  	SUBL	$4, SP
   159  	MOVL	0(BP), AX
   160  	MOVL	AX, 0(SP)
   161  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   162  	JNE	exit_irt
   163  	NACL_SYSCALL(SYS_exit)
   164  	MOVL	$0x13, 0x13  // crash
   165  exit_irt:
   166  	MOVL	runtime·nacl_irt_basic_v0_1+(IRT_BASIC_EXIT*4)(SB), AX
   167  	CALL	AX
   168  	MOVL	$0x14, 0x14  // crash
   169  
   170  TEXT runtime·exit1(SB),NOSPLIT,$0
   171  	CALL	runtime·nacl_swapstack(SB)
   172  	SUBL	$4, SP
   173  	MOVL	0(BP), AX
   174  	MOVL	AX, 0(SP)
   175  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   176  	JNE	exit1_irt
   177  	NACL_SYSCALL(SYS_thread_exit)
   178  	MOVL	$0x15, 0x15 // crash
   179  exit1_irt:
   180  	MOVL	runtime·nacl_irt_thread_v0_1+(IRT_THREAD_EXIT*4)(SB), AX
   181  	CALL	AX
   182  	MOVL	$0x16, 0x16 // crash
   183  
   184  TEXT runtime·open(SB),NOSPLIT,$0
   185  	CALL	runtime·nacl_entersyscall(SB)
   186  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   187  	JNE	open_irt
   188  	SUBL	$12, SP
   189  	MOVL	0(BP), AX  // pathname
   190  	MOVL	AX, 0(SP)
   191  	MOVL	4(BP), AX  // oflag
   192  	MOVL	AX, 4(SP)
   193  	MOVL	8(BP), AX  // cmode
   194  	MOVL	AX, 8(SP)
   195  	NACL_SYSCALL(SYS_open)
   196  	ADDL	$12, SP
   197  	CALL	runtime·nacl_exitsyscall(SB)
   198  	MOVL	AX, ret+12(FP)
   199  	RET
   200  open_irt:
   201  	SUBL	$20, SP
   202  	MOVL	0(BP), AX  // pathname
   203  	MOVL	AX, 0(SP)
   204  	MOVL	4(BP), AX  // oflag
   205  	MOVL	AX, 4(SP)
   206  	MOVL	8(BP), AX  // cmode
   207  	MOVL	AX, 8(SP)
   208  	LEAL	16(SP), AX  // &fd
   209  	MOVL	AX, 12(SP)
   210  	MOVL	runtime·nacl_irt_filename_v0_1+(IRT_FILENAME_OPEN*4)(SB), AX
   211  	CALL	AX
   212  	NEGL	AX
   213  	JNZ	open_done
   214  	MOVL	16(SP), AX
   215  open_done:
   216  	ADDL	$20, SP
   217  	CALL	runtime·nacl_exitsyscall(SB)
   218  	MOVL	AX, ret+12(FP)
   219  	RET
   220  
   221  TEXT runtime·close(SB),NOSPLIT,$0
   222  	CALL	runtime·nacl_entersyscall(SB)
   223  	SUBL	$4, SP
   224  	MOVL	0(BP), AX
   225  	MOVL	AX, 0(SP)
   226  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   227  	JNE	close_irt
   228  	NACL_SYSCALL(SYS_close)
   229  	JMP	close_done
   230  close_irt:
   231  	MOVL	runtime·nacl_irt_fdio_v0_1+(IRT_FDIO_CLOSE*4)(SB), AX
   232  	CALL	AX
   233  	NEGL	AX
   234  close_done:
   235  	ADDL	$4, SP
   236  	CALL	runtime·nacl_exitsyscall(SB)
   237  	MOVL	AX, ret+4(FP)
   238  	RET
   239  
   240  TEXT runtime·read(SB),NOSPLIT,$0
   241  	CALL	runtime·nacl_entersyscall(SB)
   242  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   243  	JNE	read_irt
   244  	SUBL	$12, SP
   245  	MOVL	0(BP), AX  // fd
   246  	MOVL	AX, 0(SP)
   247  	MOVL	4(BP), AX  // buf
   248  	MOVL	AX, 4(SP)
   249  	MOVL	8(BP), AX  // count
   250  	MOVL	AX, 8(SP)
   251  	NACL_SYSCALL(SYS_read)
   252  	ADDL	$12, SP
   253  	CALL	runtime·nacl_exitsyscall(SB)
   254  	MOVL	AX, ret+12(FP)
   255  	RET
   256  read_irt:
   257  	SUBL	$20, SP
   258  	MOVL	0(BP), AX  // fd
   259  	MOVL	AX, 0(SP)
   260  	MOVL	4(BP), AX  // buf
   261  	MOVL	AX, 4(SP)
   262  	MOVL	8(BP), AX  // count
   263  	MOVL	AX, 8(SP)
   264  	LEAL	16(SP), AX  // nread
   265  	MOVL	AX, 12(SP)
   266  	MOVL	runtime·nacl_irt_fdio_v0_1+(IRT_FDIO_READ*4)(SB), AX
   267  	CALL	AX
   268  	NEGL	AX
   269  	JNZ	read_done
   270  	MOVL	16(SP), AX
   271  read_done:
   272  	ADDL	$20, SP
   273  	CALL	runtime·nacl_exitsyscall(SB)
   274  	MOVL	AX, ret+12(FP)
   275  	RET
   276  
   277  TEXT syscall·naclWrite(SB), NOSPLIT, $16-16
   278  	MOVL arg1+0(FP), DI
   279  	MOVL arg2+4(FP), SI
   280  	MOVL arg3+8(FP), DX
   281  	MOVL DI, 0(SP)
   282  	MOVL SI, 4(SP)
   283  	MOVL DX, 8(SP)
   284  	CALL runtime·write(SB)
   285  	MOVL AX, ret+16(FP)
   286  	RET
   287  
   288  TEXT runtime·write(SB),NOSPLIT,$0
   289  	CALL	runtime·nacl_entersyscall(SB)
   290  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   291  	JNE	write_irt
   292  	SUBL	$12, SP
   293  	MOVL	0(BP), AX  // fd
   294  	MOVL	AX, 0(SP)
   295  	MOVL	4(BP), AX  // buf
   296  	MOVL	AX, 4(SP)
   297  	MOVL	8(BP), AX  // count
   298  	MOVL	AX, 8(SP)
   299  	NACL_SYSCALL(SYS_write)
   300  	ADDL	$12, SP
   301  	CALL	runtime·nacl_exitsyscall(SB)
   302  	MOVL	AX, ret+12(FP)
   303  	RET
   304  write_irt:
   305  	SUBL	$20, SP
   306  	MOVL	0(BP), AX  // fd
   307  	MOVL	AX, 0(SP)
   308  	MOVL	4(BP), AX  // buf
   309  	MOVL	AX, 4(SP)
   310  	MOVL	8(BP), AX  // count
   311  	MOVL	AX, 8(SP)
   312  	LEAL	16(SP), AX  // nwrite
   313  	MOVL	AX, 12(SP)
   314  	MOVL	runtime·nacl_irt_fdio_v0_1+(IRT_FDIO_WRITE*4)(SB), AX
   315  	CALL	AX
   316  	NEGL	AX
   317  	JNZ	write_done
   318  	MOVL	16(SP), AX
   319  write_done:
   320  	ADDL	$20, SP
   321  	CALL	runtime·nacl_exitsyscall(SB)
   322  	MOVL	AX, ret+12(FP)
   323  	RET
   324  
   325  TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$0
   326  	CALL	runtime·nacl_swapstack(SB)
   327  	SUBL	$8, SP
   328  	MOVL	0(BP), AX  // stack
   329  	MOVL	AX, 0(SP)
   330  	MOVL	4(BP), AX  // size
   331  	MOVL	AX, 4(SP)
   332  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   333  	JNE	nacl_exception_stack_irt
   334  	NACL_SYSCALL(SYS_exception_stack)
   335  	JMP	nacl_exception_stack_done
   336  nacl_exception_stack_irt:
   337  	MOVL	runtime·nacl_irt_exception_handling_v0_1+(IRT_EXCEPTION_STACK*4)(SB), AX
   338  	CALL	AX
   339  	NEGL	AX
   340  nacl_exception_stack_done:
   341  	ADDL	$8, SP
   342  	CALL	runtime·nacl_restorestack(SB)
   343  	MOVL	AX, ret+8(FP)
   344  	RET
   345  
   346  TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$0
   347  	CALL	runtime·nacl_swapstack(SB)
   348  	SUBL	$8, SP
   349  	MOVL	0(BP), AX  // handler
   350  	MOVL	AX, 0(SP)
   351  	MOVL	4(BP), AX  // *old_handler
   352  	MOVL	AX, 4(SP)
   353  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   354  	JNE	nacl_exception_handler_irt
   355  	NACL_SYSCALL(SYS_exception_handler)
   356  	JMP	nacl_exception_handler_done
   357  nacl_exception_handler_irt:
   358  	MOVL	runtime·nacl_irt_exception_handling_v0_1+(IRT_EXCEPTION_HANDLER*4)(SB), AX
   359  	CALL	AX
   360  	NEGL	AX
   361  nacl_exception_handler_done:
   362  	ADDL	$8, SP
   363  	CALL	runtime·nacl_restorestack(SB)
   364  	MOVL	AX, ret+8(FP)
   365  	RET
   366  
   367  TEXT runtime·nacl_sem_create(SB),NOSPLIT,$0
   368  	CALL	runtime·nacl_entersyscall(SB)
   369  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   370  	JNE	sem_create_irt
   371  	SUBL	$4, SP
   372  	MOVL	0(BP), AX  // value
   373  	MOVL	AX, 0(SP)
   374  	NACL_SYSCALL(SYS_sem_create)
   375  	ADDL	$4, SP
   376  	CALL	runtime·nacl_exitsyscall(SB)
   377  	MOVL	AX, ret+4(FP)
   378  	RET
   379  sem_create_irt:
   380  	SUBL	$12, SP
   381  	LEAL	8(SP), AX  // *sem_handle
   382  	MOVL	AX, 0(SP)
   383  	MOVL	4(BP), AX  // value
   384  	MOVL	AX, 4(SP)
   385  	MOVL	runtime·nacl_irt_sem_v0_1+(IRT_SEM_CREATE*4)(SB), AX
   386  	CALL	AX
   387  	NEGL	AX
   388  	JNZ	sem_create_done
   389  	MOVL	8(SP), AX
   390  sem_create_done:
   391  	ADDL	$12, SP
   392  	CALL	runtime·nacl_exitsyscall(SB)
   393  	MOVL	AX, ret+4(FP)
   394  	RET
   395  
   396  TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$0
   397  	CALL	runtime·nacl_entersyscall(SB)
   398  	SUBL	$4, SP
   399  	MOVL	0(BP), AX  // sem_handle
   400  	MOVL	AX, 0(SP)
   401  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   402  	JNE	sem_wait_irt
   403  	NACL_SYSCALL(SYS_sem_wait)
   404  	JMP	sem_wait_done
   405  sem_wait_irt:
   406  	MOVL	runtime·nacl_irt_sem_v0_1+(IRT_SEM_WAIT*4)(SB), AX
   407  	CALL	AX
   408  	NEGL	AX
   409  sem_wait_done:
   410  	ADDL	$4, SP
   411  	CALL	runtime·nacl_exitsyscall(SB)
   412  	MOVL	AX, ret+4(FP)
   413  	RET
   414  
   415  TEXT runtime·nacl_sem_post(SB),NOSPLIT,$0
   416  	CALL	runtime·nacl_entersyscall(SB)
   417  	SUBL	$4, SP
   418  	MOVL	0(BP), AX  // sem_handle
   419  	MOVL	AX, 0(SP)
   420  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   421  	JNE	sem_post_irt
   422  	NACL_SYSCALL(SYS_sem_post)
   423  	JMP	sem_post_done
   424  sem_post_irt:
   425  	MOVL	runtime·nacl_irt_sem_v0_1+(IRT_SEM_POST*4)(SB), AX
   426  	CALL	AX
   427  	NEGL	AX
   428  sem_post_done:
   429  	ADDL	$4, SP
   430  	CALL	runtime·nacl_exitsyscall(SB)
   431  	MOVL	AX, ret+4(FP)
   432  	RET
   433  
   434  TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$0
   435  	CALL	runtime·nacl_entersyscall(SB)
   436  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   437  	JNE	mutex_create_irt
   438  	SUBL	$4, SP
   439  	MOVL	0(BP), AX  // flag
   440  	MOVL	AX, (SP)
   441  	NACL_SYSCALL(SYS_mutex_create)
   442  	ADDL	$4, SP
   443  	CALL	runtime·nacl_exitsyscall(SB)
   444  	MOVL	AX, ret+4(FP)
   445  	RET
   446  mutex_create_irt:
   447  	SUBL	$8, SP
   448  	LEAL	4(SP), AX  // *mutex_handle
   449  	MOVL	AX, 0(SP)
   450  	MOVL	runtime·nacl_irt_mutex_v0_1+(IRT_MUTEX_CREATE*4)(SB), AX
   451  	CALL	AX
   452  	NEGL	AX
   453  	JNZ	mutex_create_done
   454  	MOVL	4(SP), AX
   455  mutex_create_done:
   456  	ADDL	$8, SP
   457  	CALL	runtime·nacl_exitsyscall(SB)
   458  	MOVL	AX, ret+4(FP)
   459  	RET
   460  
   461  TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$0
   462  	CALL	runtime·nacl_entersyscall(SB)
   463  	SUBL	$4, SP
   464  	MOVL	0(BP), AX  // mutex_handle
   465  	MOVL	AX, 0(SP)
   466  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   467  	JNE	mutex_lock_irt
   468  	NACL_SYSCALL(SYS_mutex_lock)
   469  	JMP	mutex_lock_done
   470  mutex_lock_irt:
   471  	MOVL	runtime·nacl_irt_mutex_v0_1+(IRT_MUTEX_LOCK*4)(SB), AX
   472  	CALL	AX
   473  	NEGL	AX
   474  mutex_lock_done:
   475  	ADDL	$4, SP
   476  	CALL	runtime·nacl_exitsyscall(SB)
   477  	MOVL	AX, ret+4(FP)
   478  	RET
   479  
   480  TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$0
   481  	CALL	runtime·nacl_entersyscall(SB)
   482  	SUBL	$4, SP
   483  	MOVL	0(BP), AX  // mutex_handle
   484  	MOVL	AX, 0(SP)
   485  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   486  	JNE	mutex_trylock_irt
   487  	NACL_SYSCALL(SYS_mutex_trylock)
   488  	JMP	mutex_trylock_done
   489  mutex_trylock_irt:
   490  	MOVL	runtime·nacl_irt_mutex_v0_1+(IRT_MUTEX_TRYLOCK*4)(SB), AX
   491  	CALL	AX
   492  	NEGL	AX
   493  mutex_trylock_done:
   494  	ADDL	$4, SP
   495  	CALL	runtime·nacl_exitsyscall(SB)
   496  	MOVL	AX, ret+4(FP)
   497  	RET
   498  
   499  TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$0
   500  	CALL	runtime·nacl_entersyscall(SB)
   501  	SUBL	$4, SP
   502  	MOVL	0(BP), AX  // mutex_handle
   503  	MOVL	AX, 0(SP)
   504  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   505  	JNE	mutex_unlock_irt
   506  	NACL_SYSCALL(SYS_mutex_unlock)
   507  	JMP	mutex_unlock_done
   508  mutex_unlock_irt:
   509  	MOVL	runtime·nacl_irt_mutex_v0_1+(IRT_MUTEX_UNLOCK*4)(SB), AX
   510  	CALL	AX
   511  	NEGL	AX
   512  mutex_unlock_done:
   513  	ADDL	$4, SP
   514  	CALL	runtime·nacl_exitsyscall(SB)
   515  	MOVL	AX, ret+4(FP)
   516  	RET
   517  
   518  TEXT runtime·nacl_cond_create(SB),NOSPLIT,$0
   519  	CALL	runtime·nacl_entersyscall(SB)
   520  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   521  	JNE	cond_create_irt
   522  	SUBL	$4, SP
   523  	MOVL	0(BP), AX  // flag
   524  	MOVL	AX, (SP)
   525  	NACL_SYSCALL(SYS_cond_create)
   526  	ADDL	$4, SP
   527  	CALL	runtime·nacl_exitsyscall(SB)
   528  	MOVL	AX, ret+4(FP)
   529  	RET
   530  cond_create_irt:
   531  	SUBL	$8, SP
   532  	LEAL	4(SP), AX  // *cond_handle
   533  	MOVL	AX, 0(SP)
   534  	MOVL	runtime·nacl_irt_cond_v0_1+(IRT_COND_CREATE*4)(SB), AX
   535  	CALL	AX
   536  	NEGL	AX
   537  	JNZ	cond_create_done
   538  	MOVL	4(SP), AX
   539  cond_create_done:
   540  	ADDL	$8, SP
   541  	CALL	runtime·nacl_exitsyscall(SB)
   542  	MOVL	AX, ret+4(FP)
   543  	RET
   544  
   545  TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$0
   546  	CALL	runtime·nacl_entersyscall(SB)
   547  	SUBL	$8, SP
   548  	MOVL	0(BP), AX  // cond_handle
   549  	MOVL	AX, 0(SP)
   550  	MOVL	4(BP), AX  // mutex_handle
   551  	MOVL	AX, 4(SP)
   552  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   553  	JNE	cond_wait_irt
   554  	NACL_SYSCALL(SYS_cond_wait)
   555  	JMP	cond_wait_done
   556  cond_wait_irt:
   557  	MOVL	runtime·nacl_irt_cond_v0_1+(IRT_COND_WAIT*4)(SB), AX
   558  	CALL	AX
   559  	NEGL	AX
   560  cond_wait_done:
   561  	ADDL	$8, SP
   562  	CALL	runtime·nacl_exitsyscall(SB)
   563  	MOVL	AX, ret+8(FP)
   564  	RET
   565  
   566  TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$0
   567  	CALL	runtime·nacl_entersyscall(SB)
   568  	SUBL	$4, SP
   569  	MOVL	0(BP), AX  // cond_handle
   570  	MOVL	AX, 0(SP)
   571  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   572  	JNE	cond_signal_irt
   573  	NACL_SYSCALL(SYS_cond_signal)
   574  	JMP	cond_signal_done
   575  cond_signal_irt:
   576  	MOVL	runtime·nacl_irt_cond_v0_1+(IRT_COND_SIGNAL*4)(SB), AX
   577  	CALL	AX
   578  	NEGL	AX
   579  cond_signal_done:
   580  	ADDL	$4, SP
   581  	CALL	runtime·nacl_exitsyscall(SB)
   582  	MOVL	AX, ret+4(FP)
   583  	RET
   584  
   585  TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$0
   586  	CALL	runtime·nacl_entersyscall(SB)
   587  	SUBL	$4, SP
   588  	MOVL	0(BP), AX  // cond_handle
   589  	MOVL	AX, 0(SP)
   590  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   591  	JNE	cond_broadcast_irt
   592  	NACL_SYSCALL(SYS_cond_broadcast)
   593  	JMP	cond_broadcast_done
   594  cond_broadcast_irt:
   595  	MOVL	runtime·nacl_irt_cond_v0_1+(IRT_COND_BROADCAST*4)(SB), AX
   596  	CALL	AX
   597  	NEGL	AX
   598  cond_broadcast_done:
   599  	ADDL	$4, SP
   600  	CALL	runtime·nacl_exitsyscall(SB)
   601  	MOVL	AX, ret+4(FP)
   602  	RET
   603  
   604  TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$0
   605  	CALL	runtime·nacl_entersyscall(SB)
   606  	SUBL	$12, SP
   607  	MOVL	0(BP), AX  // cond_handle
   608  	MOVL	AX, 0(SP)
   609  	MOVL	4(BP), AX  // mutex_handle
   610  	MOVL	AX, 4(SP)
   611  	MOVL	8(BP), AX  // abstime
   612  	MOVL	AX, 8(SP)
   613  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   614  	JNE	cond_timed_wait_abs_irt
   615  	NACL_SYSCALL(SYS_cond_timed_wait_abs)
   616  	JMP	cond_timed_wait_abs_done
   617  cond_timed_wait_abs_irt:
   618  	MOVL	runtime·nacl_irt_cond_v0_1+(IRT_COND_TIMED_WAIT_ABS*4)(SB), AX
   619  	CALL	AX
   620  	NEGL	AX
   621  cond_timed_wait_abs_done:
   622  	ADDL	$12, SP
   623  	CALL	runtime·nacl_exitsyscall(SB)
   624  	MOVL	AX, ret+12(FP)
   625  	RET
   626  
   627  TEXT runtime·nacl_thread_create(SB),NOSPLIT,$0
   628  	CALL	runtime·nacl_entersyscall(SB)
   629  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   630  	JNE	thread_create_irt
   631  	SUBL	$16, SP
   632  	MOVL	0(BP), AX  // start_func
   633  	MOVL	AX, 0(SP)
   634  	MOVL	4(BP), AX  // stack
   635  	MOVL	AX, 4(SP)
   636  	MOVL	8(BP), AX  // tls
   637  	MOVL	AX, 8(SP)
   638  	MOVL	12(BP), AX  // tp
   639  	MOVL	AX, 12(SP)
   640  	NACL_SYSCALL(SYS_thread_create)
   641  	ADDL	$16, SP
   642  	CALL	runtime·nacl_exitsyscall(SB)
   643  	MOVL	AX, ret+16(FP)
   644  	RET
   645  thread_create_irt:
   646  	SUBL	$12, SP
   647  	MOVL	0(BP), AX  // start_func
   648  	MOVL	AX, 0(SP)
   649  	MOVL	4(BP), AX  // stack
   650  	MOVL	AX, 4(SP)
   651  	MOVL	8(BP), AX  // thread_ptr
   652  	MOVL	AX, 8(SP)
   653  	MOVL	runtime·nacl_irt_thread_v0_1+(IRT_THREAD_CREATE*4)(SB), AX
   654  	CALL	AX
   655  	NEGL	AX
   656  	ADDL	$12, SP
   657  	CALL	runtime·nacl_exitsyscall(SB)
   658  	MOVL	AX, ret+16(FP)
   659  	RET
   660  
   661  TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
   662  	JMP runtime·mstart(SB)
   663  
   664  TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$0
   665  	CALL	runtime·nacl_entersyscall(SB)
   666  	SUBL	$8, SP
   667  	MOVL	0(BP), AX  // req
   668  	MOVL	AX, 0(SP)
   669  	MOVL	4(BP), AX  // rem
   670  	MOVL	AX, 4(SP)
   671  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   672  	JNE	nanosleep_irt
   673  	NACL_SYSCALL(SYS_nanosleep)
   674  	JMP	nanosleep_done
   675  nanosleep_irt:
   676  	MOVL	runtime·nacl_irt_basic_v0_1+(IRT_BASIC_NANOSLEEP*4)(SB), AX
   677  	CALL	AX
   678  	NEGL	AX
   679  nanosleep_done:
   680  	ADDL	$8, SP
   681  	CALL	runtime·nacl_exitsyscall(SB)
   682  	MOVL	AX, ret+8(FP)
   683  	RET
   684  
   685  TEXT runtime·osyield(SB),NOSPLIT,$0
   686  	CALL	runtime·nacl_entersyscall(SB)
   687  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   688  	JNE	osyield_irt
   689  	NACL_SYSCALL(SYS_sched_yield)
   690  	JMP	osyield_done
   691  osyield_irt:
   692  	MOVL	runtime·nacl_irt_basic_v0_1+(IRT_BASIC_SCHED_YIELD*4)(SB), AX
   693  	CALL	AX
   694  osyield_done:
   695  	CALL	runtime·nacl_exitsyscall(SB)
   696  	RET
   697  
   698  TEXT runtime·mmap(SB),NOSPLIT,$0
   699  	CALL	runtime·nacl_entersyscall(SB)
   700  	SUBL	$32, SP
   701  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   702  	JNE	mmap_irt
   703  	MOVL	0(BP), AX  // addr
   704  	MOVL	AX, 0(SP)
   705  	MOVL	4(BP), AX  // len
   706  	MOVL	AX, 4(SP)
   707  	MOVL	8(BP), AX  // prot
   708  	MOVL	AX, 8(SP)
   709  	MOVL	12(BP), AX  // flags
   710  	MOVL	AX, 12(SP)
   711  	MOVL	16(BP), AX  // fd
   712  	MOVL	AX, 16(SP)
   713  	MOVL	20(BP), AX  // off
   714  	MOVL	AX, 24(SP)
   715  	MOVL	$0, 28(SP)  // sign-extend
   716  	LEAL	24(SP), AX  // &off
   717  	MOVL	AX, 20(SP)
   718  	NACL_SYSCALL(SYS_mmap)
   719  	JMP	mmap_done
   720  mmap_irt:
   721  	MOVL	0(BP), AX  // addr
   722  	MOVL	AX, 28(SP)
   723  	LEAL	28(SP), AX  // &addr
   724  	MOVL	AX, 0(SP)
   725  	MOVL	4(BP), AX  // len
   726  	MOVL	AX, 4(SP)
   727  	MOVL	8(BP), AX  // prot
   728  	MOVL	AX, 8(SP)
   729  	MOVL	12(BP), AX  // flags
   730  	MOVL	AX, 12(SP)
   731  	MOVL	16(BP), AX  // fd
   732  	MOVL	AX, 16(SP)
   733  	MOVL	20(BP), AX  // off
   734  	MOVL	AX, 20(SP)
   735  	MOVL	$0, 24(SP)  // sign-extend
   736  	MOVL	runtime·nacl_irt_memory_v0_3+(IRT_MEMORY_MMAP*4)(SB), AX
   737  	CALL	AX
   738  	NEGL	AX
   739  	JNZ	mmap_done
   740  	MOVL	28(SP), AX
   741  mmap_done:
   742  	ADDL	$32, SP
   743  	CALL	runtime·nacl_exitsyscall(SB)
   744  	MOVL	AX, ret+24(FP)
   745  	RET
   746  
   747  TEXT time·now(SB),NOSPLIT,$0
   748  	CALL	runtime·nacl_swapstack(SB)
   749  	SUBL	$24, SP
   750  	MOVL	BP, 20(SP)
   751  	MOVL	$0, 0(SP) // real time clock
   752  	LEAL	8(SP), AX
   753  	MOVL	AX, 4(SP) // timespec
   754  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   755  	JNE	now_irt
   756  	NACL_SYSCALL(SYS_clock_gettime)
   757  	JMP	now_done
   758  now_irt:
   759  	MOVL	runtime·nacl_irt_clock_v0_1+(IRT_CLOCK_GETTIME*4)(SB), AX
   760  	CALL	AX
   761  now_done:
   762  	MOVL	8(SP), AX // low 32 sec
   763  	MOVL	12(SP), CX // high 32 sec
   764  	MOVL	16(SP), BX // nsec
   765  
   766  	// sec is in AX, nsec in BX
   767  	MOVL	20(SP), BP
   768  	MOVL	AX, 0(BP)
   769  	MOVL	CX, 4(BP)
   770  	MOVL	BX, 8(BP)
   771  	ADDL	$24, SP
   772  	CALL	runtime·nacl_restorestack(SB)
   773  	RET
   774  
   775  TEXT syscall·now(SB),NOSPLIT,$0
   776  	JMP time·now(SB)
   777  
   778  TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$0
   779  	CALL	runtime·nacl_swapstack(SB)
   780  	SUBL	$8, SP
   781  	MOVL	0(BP), AX  // clk_id
   782  	MOVL	AX, 0(SP)
   783  	MOVL	4(BP), AX  // *tp
   784  	MOVL	AX, 4(SP)
   785  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   786  	JNE	clock_gettime_irt
   787  	NACL_SYSCALL(SYS_clock_gettime)
   788  	JMP	clock_gettime_done
   789  clock_gettime_irt:
   790  	MOVL	runtime·nacl_irt_clock_v0_1+(IRT_CLOCK_GETTIME*4)(SB), AX
   791  	CALL	AX
   792  	NEGL	AX
   793  clock_gettime_done:
   794  	ADDL	$8, SP
   795  	CALL	runtime·nacl_restorestack(SB)
   796  	MOVL	AX, ret+8(FP)
   797  	RET
   798  
   799  TEXT runtime·nanotime(SB),NOSPLIT,$0
   800  	CALL	runtime·nacl_swapstack(SB)
   801  	SUBL	$20, SP
   802  	MOVL	$0, 0(SP) // real time clock
   803  	LEAL	8(SP), AX
   804  	MOVL	AX, 4(SP) // timespec
   805  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   806  	JNE	nanotime_irt
   807  	NACL_SYSCALL(SYS_clock_gettime)
   808  	JMP	nanotime_done
   809  nanotime_irt:
   810  	MOVL	runtime·nacl_irt_clock_v0_1+(IRT_CLOCK_GETTIME*4)(SB), AX
   811  	CALL	AX
   812  nanotime_done:
   813  	MOVL	8(SP), AX // low 32 sec
   814  	MOVL	16(SP), BX // nsec
   815  
   816  	// sec is in AX, nsec in BX
   817  	// convert to DX:AX nsec
   818  	MOVL	$1000000000, CX
   819  	MULL	CX
   820  	ADDL	BX, AX
   821  	ADCL	$0, DX
   822  	ADDL	$20, SP
   823  	CALL	runtime·nacl_restorestack(SB)
   824  	MOVL	AX, 4(SP)
   825  	MOVL	DX, 8(SP)
   826  	RET
   827  
   828  TEXT runtime·setldt(SB),NOSPLIT,$8
   829  	MOVL	addr+4(FP), BX // aka base
   830  	ADDL	$0x8, BX
   831  	MOVL	BX, 0(SP)
   832  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   833  	JNE	setldt_irt
   834  	NACL_SYSCALL(SYS_tls_init)
   835  	RET
   836  setldt_irt:
   837  	MOVL	runtime·nacl_irt_tls_v0_1+(IRT_TLS_INIT*4)(SB), AX
   838  	CALL	AX
   839  	NEGL	AX
   840  	RET
   841  
   842  TEXT runtime·sigtramp(SB),NOSPLIT,$24
   843  	get_tls(CX)
   844  
   845  	// check that g exists
   846  	MOVL	g(CX), DI
   847  	CMPL	DI, $0
   848  	JNE	6(PC)
   849  	MOVL	$11, BX
   850  	MOVL	$0, 0(SP)
   851  	MOVL	$runtime·badsignal(SB), AX
   852  	CALL	AX
   853  	JMP	sigtramp_ret
   854  
   855  	// save g
   856  	MOVL	DI, 20(SP)
   857  
   858  	// g = m->gsignal
   859  	MOVL	g_m(DI), BX
   860  	MOVL	m_gsignal(BX), BX
   861  	MOVL	BX, g(CX)
   862  
   863  	// copy arguments for sighandler
   864  	MOVL	$11, 0(SP) // signal
   865  	MOVL	$0, 4(SP) // siginfo
   866  	LEAL	ctxt+4(FP), AX
   867  	MOVL	AX, 8(SP) // context
   868  	MOVL	DI, 12(SP) // g
   869  
   870  	CALL	runtime·sighandler(SB)
   871  
   872  	// restore g
   873  	get_tls(CX)
   874  	MOVL	20(SP), BX
   875  	MOVL	BX, g(CX)
   876  
   877  sigtramp_ret:
   878  	// Enable exceptions again.
   879  	CMPL	runtime·nacl_irt_is_enabled(SB), $0
   880  	JNE	sigtramp_irt
   881  	NACL_SYSCALL(SYS_exception_clear_flag)
   882  	JMP	sigtramp_ret2
   883  sigtramp_irt:
   884  	MOVL	runtime·nacl_irt_exception_handling_v0_1+(IRT_EXCEPTION_CLEAR*4)(SB), AX
   885  	CALL	AX
   886  sigtramp_ret2:
   887  
   888  	// NaCl has abdicated its traditional operating system responsibility
   889  	// and declined to implement 'sigreturn'. Instead the only way to return
   890  	// to the execution of our program is to restore the registers ourselves.
   891  	// Unfortunately, that is impossible to do with strict fidelity, because
   892  	// there is no way to do the final update of PC that ends the sequence
   893  	// without either (1) jumping to a register, in which case the register ends
   894  	// holding the PC value instead of its intended value or (2) storing the PC
   895  	// on the stack and using RET, which imposes the requirement that SP is
   896  	// valid and that is okay to smash the word below it. The second would
   897  	// normally be the lesser of the two evils, except that on NaCl, the linker
   898  	// must rewrite RET into "POP reg; AND $~31, reg; JMP reg", so either way
   899  	// we are going to lose a register as a result of the incoming signal.
   900  	// Similarly, there is no way to restore EFLAGS; the usual way is to use
   901  	// POPFL, but NaCl rejects that instruction. We could inspect the bits and
   902  	// execute a sequence of instructions designed to recreate those flag
   903  	// settings, but that's a lot of work.
   904  	//
   905  	// Thankfully, Go's signal handlers never try to return directly to the
   906  	// executing code, so all the registers and EFLAGS are dead and can be
   907  	// smashed. The only registers that matter are the ones that are setting
   908  	// up for the simulated call that the signal handler has created.
   909  	// Today those registers are just PC and SP, but in case additional registers
   910  	// are relevant in the future (for example DX is the Go func context register)
   911  	// we restore as many registers as possible.
   912  	//
   913  	// We smash BP, because that's what the linker smashes during RET.
   914  	//
   915  	LEAL	ctxt+4(FP), BP
   916  	ADDL	$64, BP
   917  	MOVL	0(BP), AX
   918  	MOVL	4(BP), CX
   919  	MOVL	8(BP), DX
   920  	MOVL	12(BP), BX
   921  	MOVL	16(BP), SP
   922  	// 20(BP) is saved BP, never to be seen again
   923  	MOVL	24(BP), SI
   924  	MOVL	28(BP), DI
   925  	// 36(BP) is saved EFLAGS, never to be seen again
   926  	MOVL	32(BP), BP // saved PC
   927  	JMP	BP
   928  
   929  #define AT_SYSINFO	32
   930  TEXT runtime·nacl_sysinfo(SB),NOSPLIT,$16
   931  	// nacl_irt_query is passed via Elf aux vector, which starts at
   932  	// argv[argc + envc + 2];
   933  	//
   934  	// typedef struct {
   935  	//   int32 a_type;	/* Entry type */
   936  	//   union {
   937  	//    int32 a_val;	/* Integer value */
   938  	//   } a_un;
   939  	// } Elf32_auxv_t;
   940  	//
   941  	MOVL	di+0(FP), DI
   942  	LEAL	12(DI), BX	// argv
   943  	MOVL	8(DI), AX	// argc
   944  	ADDL	4(DI), AX	// envc
   945  	ADDL	$2, AX
   946  	LEAL	(BX)(AX*4), BX	// BX = &argv[argc + envc + 2]
   947  	MOVL	BX, runtime·nacl_irt_query(SB)
   948  auxloop:
   949  	MOVL	0(BX), DX	// DX = BX->a_type
   950  	CMPL	DX, $0
   951  	JE	no_irt
   952  	CMPL	DX, $AT_SYSINFO
   953  	JEQ	auxfound
   954  	ADDL	$8, BX
   955  	JMP	auxloop
   956  auxfound:
   957  	MOVL	4(BX), BX
   958  	MOVL	BX, runtime·nacl_irt_query(SB)
   959  	LEAL	runtime·nacl_irt_entries(SB), BX
   960  queryloop:
   961  	MOVL	0(BX), AX	// name
   962  	TESTL	AX, AX
   963  	JE	irt_done
   964  	MOVL	AX, 0(SP)
   965  	MOVL	4(BX), AX	// funtab
   966  	MOVL	AX, 4(SP)
   967  	MOVL	8(BX), AX	// size
   968  	MOVL	AX, 8(SP)
   969  	ADDL	$16, BX
   970  	MOVL	runtime·nacl_irt_query(SB), AX
   971  	CALL	AX
   972  	TESTL	AX, AX
   973  	JNE	queryloop
   974  	CMPL	-4(BX), $0	// is_required
   975  	JE	queryloop
   976  	CALL	runtime·crash(SB)
   977  no_irt:
   978  	MOVL	$0, runtime·nacl_irt_is_enabled(SB)
   979  	RET
   980  irt_done:
   981  	MOVL	$1, runtime·nacl_irt_is_enabled(SB)
   982  	RET