github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/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  #include "go_asm.h"
     6  #include "go_tls.h"
     7  #include "textflag.h"
     8  #include "syscall_nacl.h"
     9  
    10  #define NACL_SYSCALL(code) \
    11  	MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
    12  
    13  TEXT runtime·exit(SB),NOSPLIT,$4
    14  	MOVL code+0(FP), AX
    15  	MOVL AX, 0(SP)
    16  	NACL_SYSCALL(SYS_exit)
    17  	JMP 0(PC)
    18  
    19  // func exitThread(wait *uint32)
    20  TEXT runtime·exitThread(SB),NOSPLIT,$4-4
    21  	MOVL wait+0(FP), AX
    22  	// SYS_thread_exit will clear *wait when the stack is free.
    23  	MOVL AX, 0(SP)
    24  	NACL_SYSCALL(SYS_thread_exit)
    25  	JMP 0(PC)
    26  
    27  TEXT runtime·open(SB),NOSPLIT,$12
    28  	MOVL name+0(FP), AX
    29  	MOVL AX, 0(SP)
    30  	MOVL mode+4(FP), AX
    31  	MOVL AX, 4(SP)
    32  	MOVL perm+8(FP), AX
    33  	MOVL AX, 8(SP)
    34  	NACL_SYSCALL(SYS_open)
    35  	MOVL AX, ret+12(FP)
    36  	RET
    37  
    38  TEXT runtime·closefd(SB),NOSPLIT,$4
    39  	MOVL fd+0(FP), AX
    40  	MOVL AX, 0(SP)
    41  	NACL_SYSCALL(SYS_close)
    42  	MOVL AX, ret+4(FP)
    43  	RET
    44  
    45  TEXT runtime·read(SB),NOSPLIT,$12
    46  	MOVL fd+0(FP), AX
    47  	MOVL AX, 0(SP)
    48  	MOVL p+4(FP), AX
    49  	MOVL AX, 4(SP)
    50  	MOVL n+8(FP), AX
    51  	MOVL AX, 8(SP)
    52  	NACL_SYSCALL(SYS_read)
    53  	MOVL AX, ret+12(FP)
    54  	RET
    55  
    56  TEXT syscall·naclWrite(SB), NOSPLIT, $16-16
    57  	MOVL arg1+0(FP), DI
    58  	MOVL arg2+4(FP), SI
    59  	MOVL arg3+8(FP), DX
    60  	MOVL DI, 0(SP)
    61  	MOVL SI, 4(SP)
    62  	MOVL DX, 8(SP)
    63  	CALL runtime·write(SB)
    64  	MOVL AX, ret+16(FP)
    65  	RET
    66  
    67  TEXT runtime·write(SB),NOSPLIT,$12
    68  	MOVL fd+0(FP), AX
    69  	MOVL AX, 0(SP)
    70  	MOVL p+4(FP), AX
    71  	MOVL AX, 4(SP)
    72  	MOVL n+8(FP), AX
    73  	MOVL AX, 8(SP)
    74  	NACL_SYSCALL(SYS_write)
    75  	MOVL AX, ret+12(FP)
    76  	RET
    77  
    78  TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$8
    79  	MOVL p+0(FP), AX
    80  	MOVL AX, 0(SP)
    81  	MOVL size+4(FP), AX
    82  	MOVL AX, 4(SP)
    83  	NACL_SYSCALL(SYS_exception_stack)
    84  	MOVL AX, ret+8(FP)
    85  	RET
    86  
    87  TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$8
    88  	MOVL fn+0(FP), AX
    89  	MOVL AX, 0(SP)
    90  	MOVL arg+4(FP), AX
    91  	MOVL AX, 4(SP)
    92  	NACL_SYSCALL(SYS_exception_handler)
    93  	MOVL AX, ret+8(FP)
    94  	RET
    95  
    96  TEXT runtime·nacl_sem_create(SB),NOSPLIT,$4
    97  	MOVL flag+0(FP), AX
    98  	MOVL AX, 0(SP)
    99  	NACL_SYSCALL(SYS_sem_create)
   100  	MOVL AX, ret+4(FP)
   101  	RET
   102  
   103  TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$4
   104  	MOVL sem+0(FP), AX
   105  	MOVL AX, 0(SP)
   106  	NACL_SYSCALL(SYS_sem_wait)
   107  	MOVL AX, ret+4(FP)
   108  	RET
   109  
   110  TEXT runtime·nacl_sem_post(SB),NOSPLIT,$4
   111  	MOVL sem+0(FP), AX
   112  	MOVL AX, 0(SP)
   113  	NACL_SYSCALL(SYS_sem_post)
   114  	MOVL AX, ret+4(FP)
   115  	RET
   116  
   117  TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$4
   118  	MOVL flag+0(FP), AX
   119  	MOVL AX, 0(SP)
   120  	NACL_SYSCALL(SYS_mutex_create)
   121  	MOVL AX, ret+4(FP)
   122  	RET
   123  
   124  TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$4
   125  	MOVL mutex+0(FP), AX
   126  	MOVL AX, 0(SP)
   127  	NACL_SYSCALL(SYS_mutex_lock)
   128  	MOVL AX, ret+4(FP)
   129  	RET
   130  
   131  TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$4
   132  	MOVL mutex+0(FP), AX
   133  	MOVL AX, 0(SP)
   134  	NACL_SYSCALL(SYS_mutex_trylock)
   135  	MOVL AX, ret+4(FP)
   136  	RET
   137  
   138  TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$4
   139  	MOVL mutex+0(FP), AX
   140  	MOVL AX, 0(SP)
   141  	NACL_SYSCALL(SYS_mutex_unlock)
   142  	MOVL AX, ret+4(FP)
   143  	RET
   144  
   145  TEXT runtime·nacl_cond_create(SB),NOSPLIT,$4
   146  	MOVL flag+0(FP), AX
   147  	MOVL AX, 0(SP)
   148  	NACL_SYSCALL(SYS_cond_create)
   149  	MOVL AX, ret+4(FP)
   150  	RET
   151  
   152  TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$8
   153  	MOVL cond+0(FP), AX
   154  	MOVL AX, 0(SP)
   155  	MOVL n+4(FP), AX
   156  	MOVL AX, 4(SP)
   157  	NACL_SYSCALL(SYS_cond_wait)
   158  	MOVL AX, ret+8(FP)
   159  	RET
   160  
   161  TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$4
   162  	MOVL cond+0(FP), AX
   163  	MOVL AX, 0(SP)
   164  	NACL_SYSCALL(SYS_cond_signal)
   165  	MOVL AX, ret+4(FP)
   166  	RET
   167  
   168  TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$4
   169  	MOVL cond+0(FP), AX
   170  	MOVL AX, 0(SP)
   171  	NACL_SYSCALL(SYS_cond_broadcast)
   172  	MOVL AX, ret+4(FP)
   173  	RET
   174  
   175  TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$12
   176  	MOVL cond+0(FP), AX
   177  	MOVL AX, 0(SP)
   178  	MOVL lock+4(FP), AX
   179  	MOVL AX, 4(SP)
   180  	MOVL ts+8(FP), AX
   181  	MOVL AX, 8(SP)
   182  	NACL_SYSCALL(SYS_cond_timed_wait_abs)
   183  	MOVL AX, ret+12(FP)
   184  	RET
   185  
   186  TEXT runtime·nacl_thread_create(SB),NOSPLIT,$16
   187  	MOVL fn+0(FP), AX
   188  	MOVL AX, 0(SP)
   189  	MOVL stk+4(FP), AX
   190  	MOVL AX, 4(SP)
   191  	MOVL tls+8(FP), AX
   192  	MOVL AX, 8(SP)
   193  	MOVL xx+12(FP), AX
   194  	MOVL AX, 12(SP)
   195  	NACL_SYSCALL(SYS_thread_create)
   196  	MOVL AX, ret+16(FP)
   197  	RET
   198  
   199  TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
   200  	JMP runtime·mstart(SB)
   201  
   202  TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$8
   203  	MOVL ts+0(FP), AX
   204  	MOVL AX, 0(SP)
   205  	MOVL extra+4(FP), AX
   206  	MOVL AX, 4(SP)
   207  	NACL_SYSCALL(SYS_nanosleep)
   208  	MOVL AX, ret+8(FP)
   209  	RET
   210  
   211  TEXT runtime·osyield(SB),NOSPLIT,$0
   212  	NACL_SYSCALL(SYS_sched_yield)
   213  	RET
   214  
   215  TEXT runtime·mmap(SB),NOSPLIT,$32
   216  	MOVL	addr+0(FP), AX
   217  	MOVL	AX, 0(SP)
   218  	MOVL	n+4(FP), AX
   219  	MOVL	AX, 4(SP)
   220  	MOVL	prot+8(FP), AX
   221  	MOVL	AX, 8(SP)
   222  	MOVL	flags+12(FP), AX
   223  	MOVL	AX, 12(SP)
   224  	MOVL	fd+16(FP), AX
   225  	MOVL	AX, 16(SP)
   226  	MOVL	off+20(FP), AX
   227  	MOVL	AX, 24(SP)
   228  	MOVL	$0, 28(SP)
   229  	LEAL	24(SP), AX
   230  	MOVL	AX, 20(SP)
   231  	NACL_SYSCALL(SYS_mmap)
   232  	CMPL	AX, $-4095
   233  	JNA	ok
   234  	NEGL	AX
   235  	MOVL	$0, p+24(FP)
   236  	MOVL	AX, err+28(FP)
   237  	RET
   238  ok:
   239  	MOVL	AX, p+24(FP)
   240  	MOVL	$0, err+28(FP)
   241  	RET
   242  
   243  TEXT runtime·walltime(SB),NOSPLIT,$20
   244  	MOVL $0, 0(SP) // real time clock
   245  	LEAL 8(SP), AX
   246  	MOVL AX, 4(SP) // timespec
   247  	NACL_SYSCALL(SYS_clock_gettime)
   248  	MOVL 8(SP), AX // low 32 sec
   249  	MOVL 12(SP), CX // high 32 sec
   250  	MOVL 16(SP), BX // nsec
   251  
   252  	// sec is in AX, nsec in BX
   253  	MOVL	AX, sec_lo+0(FP)
   254  	MOVL	CX, sec_hi+4(FP)
   255  	MOVL	BX, nsec+8(FP)
   256  	RET
   257  
   258  TEXT syscall·now(SB),NOSPLIT,$0
   259  	JMP runtime·walltime(SB)
   260  
   261  TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$8
   262  	MOVL arg1+0(FP), AX
   263  	MOVL AX, 0(SP)
   264  	MOVL arg2+4(FP), AX
   265  	MOVL AX, 4(SP)
   266  	NACL_SYSCALL(SYS_clock_gettime)
   267  	MOVL AX, ret+8(FP)
   268  	RET
   269  	
   270  TEXT runtime·nanotime(SB),NOSPLIT,$20
   271  	MOVL $0, 0(SP) // real time clock
   272  	LEAL 8(SP), AX
   273  	MOVL AX, 4(SP) // timespec
   274  	NACL_SYSCALL(SYS_clock_gettime)
   275  	MOVL 8(SP), AX // low 32 sec
   276  	MOVL 16(SP), BX // nsec
   277  
   278  	// sec is in AX, nsec in BX
   279  	// convert to DX:AX nsec
   280  	MOVL	$1000000000, CX
   281  	MULL	CX
   282  	ADDL	BX, AX
   283  	ADCL	$0, DX
   284  
   285  	MOVL	AX, ret_lo+0(FP)
   286  	MOVL	DX, ret_hi+4(FP)
   287  	RET
   288  
   289  TEXT runtime·setldt(SB),NOSPLIT,$8
   290  	MOVL	addr+4(FP), BX // aka base
   291  	ADDL	$0x8, BX
   292  	MOVL	BX, 0(SP)
   293  	NACL_SYSCALL(SYS_tls_init)
   294  	RET
   295  
   296  TEXT runtime·sigtramp(SB),NOSPLIT,$0
   297  	get_tls(CX)
   298  
   299  	// check that g exists
   300  	MOVL	g(CX), DI
   301  	CMPL	DI, $0
   302  	JNE	6(PC)
   303  	MOVL	$11, BX
   304  	MOVL	$0, 0(SP)
   305  	MOVL	$runtime·badsignal(SB), AX
   306  	CALL	AX
   307  	JMP 	ret
   308  
   309  	// save g
   310  	MOVL	DI, 20(SP)
   311  	
   312  	// g = m->gsignal
   313  	MOVL	g_m(DI), BX
   314  	MOVL	m_gsignal(BX), BX
   315  	MOVL	BX, g(CX)
   316  	
   317  	// copy arguments for sighandler
   318  	MOVL	$11, 0(SP) // signal
   319  	MOVL	$0, 4(SP) // siginfo
   320  	LEAL	ctxt+4(FP), AX
   321  	MOVL	AX, 8(SP) // context
   322  	MOVL	DI, 12(SP) // g
   323  
   324  	CALL	runtime·sighandler(SB)
   325  
   326  	// restore g
   327  	get_tls(CX)
   328  	MOVL	20(SP), BX
   329  	MOVL	BX, g(CX)
   330  
   331  ret:
   332  	// Enable exceptions again.
   333  	NACL_SYSCALL(SYS_exception_clear_flag)
   334  
   335  	// NaCl has abdicated its traditional operating system responsibility
   336  	// and declined to implement 'sigreturn'. Instead the only way to return
   337  	// to the execution of our program is to restore the registers ourselves.
   338  	// Unfortunately, that is impossible to do with strict fidelity, because
   339  	// there is no way to do the final update of PC that ends the sequence
   340  	// without either (1) jumping to a register, in which case the register ends
   341  	// holding the PC value instead of its intended value or (2) storing the PC
   342  	// on the stack and using RET, which imposes the requirement that SP is
   343  	// valid and that is okay to smash the word below it. The second would
   344  	// normally be the lesser of the two evils, except that on NaCl, the linker
   345  	// must rewrite RET into "POP reg; AND $~31, reg; JMP reg", so either way
   346  	// we are going to lose a register as a result of the incoming signal.
   347  	// Similarly, there is no way to restore EFLAGS; the usual way is to use
   348  	// POPFL, but NaCl rejects that instruction. We could inspect the bits and
   349  	// execute a sequence of instructions designed to recreate those flag
   350  	// settings, but that's a lot of work.
   351  	//
   352  	// Thankfully, Go's signal handlers never try to return directly to the
   353  	// executing code, so all the registers and EFLAGS are dead and can be
   354  	// smashed. The only registers that matter are the ones that are setting
   355  	// up for the simulated call that the signal handler has created.
   356  	// Today those registers are just PC and SP, but in case additional registers
   357  	// are relevant in the future (for example DX is the Go func context register)
   358  	// we restore as many registers as possible.
   359  	// 
   360  	// We smash BP, because that's what the linker smashes during RET.
   361  	//
   362  	LEAL	ctxt+4(FP), BP
   363  	ADDL	$64, BP
   364  	MOVL	0(BP), AX
   365  	MOVL	4(BP), CX
   366  	MOVL	8(BP), DX
   367  	MOVL	12(BP), BX
   368  	MOVL	16(BP), SP
   369  	// 20(BP) is saved BP, never to be seen again
   370  	MOVL	24(BP), SI
   371  	MOVL	28(BP), DI
   372  	// 36(BP) is saved EFLAGS, never to be seen again
   373  	MOVL	32(BP), BP // saved PC
   374  	JMP	BP
   375  
   376  // func getRandomData([]byte)
   377  TEXT runtime·getRandomData(SB),NOSPLIT,$8-12
   378  	MOVL arg_base+0(FP), AX
   379  	MOVL AX, 0(SP)
   380  	MOVL arg_len+4(FP), AX
   381  	MOVL AX, 4(SP)
   382  	NACL_SYSCALL(SYS_get_random_bytes)
   383  	RET