...
Run Format

Text file src/runtime/sys_nacl_386.s

Documentation: runtime

     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

View as plain text