| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // |
| // System calls and other sys.stuff for 386, Linux |
| // |
| |
| #include "386/asm.h" |
| |
| // http://code.google.com/p/nativeclient/source/browse/trunk/src/native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h |
| #define SYS_exit 30 |
| #define SYS_mmap 21 |
| #define SYS_munmap 22 |
| #define SYS_thread_create 80 |
| #define SYS_thread_exit 81 |
| #define SYS_tls_init 82 |
| #define SYS_write 13 |
| #define SYS_close 11 |
| #define SYS_mutex_create 70 |
| #define SYS_mutex_lock 71 |
| #define SYS_mutex_unlock 73 |
| #define SYS_gettimeofday 40 |
| #define SYS_dyncode_copy 104 |
| |
| |
| #define SYSCALL(x) $(0x10000+SYS_/**/x * 32) |
| |
| TEXT runtime·exit(SB),7,$4 |
| MOVL code+0(FP), AX |
| MOVL AX, 0(SP) |
| CALL SYSCALL(exit) |
| INT $3 // not reached |
| RET |
| |
| TEXT runtime·exit1(SB),7,$4 |
| MOVL code+0(FP), AX |
| MOVL AX, 0(SP) |
| CALL SYSCALL(thread_exit) |
| INT $3 // not reached |
| RET |
| |
| TEXT runtime·write(SB),7,$0 |
| JMP SYSCALL(write) |
| |
| TEXT runtime·close(SB),7,$0 |
| JMP SYSCALL(close) |
| |
| TEXT runtime·mutex_create(SB),7,$0 |
| JMP SYSCALL(mutex_create) |
| |
| TEXT runtime·mutex_lock(SB),7,$0 |
| JMP SYSCALL(mutex_lock) |
| |
| TEXT runtime·mutex_unlock(SB),7,$0 |
| JMP SYSCALL(mutex_unlock) |
| |
| TEXT runtime·thread_create(SB),7,$0 |
| JMP SYSCALL(thread_create) |
| |
| TEXT runtime·dyncode_copy(SB),7,$0 |
| JMP SYSCALL(dyncode_copy) |
| |
| // For Native Client: a simple no-op function. |
| // Inserting a call to this no-op is a simple way |
| // to trigger an alignment. |
| TEXT runtime·naclnop(SB),7,$0 |
| RET |
| |
| TEXT runtime·mmap(SB),7,$24 |
| MOVL a1+0(FP), BX |
| MOVL a2+4(FP), CX // round up to 64 kB boundary; silences nacl warning |
| ADDL $(64*1024-1), CX |
| ANDL $~(64*1024-1), CX |
| MOVL a3+8(FP), DX |
| MOVL a4+12(FP), SI |
| MOVL a5+16(FP), DI |
| MOVL a6+20(FP), BP |
| MOVL BX, 0(SP) |
| MOVL CX, 4(SP) |
| MOVL DX, 8(SP) |
| MOVL SI, 12(SP) |
| MOVL DI, 16(SP) |
| MOVL BP, 20(SP) |
| CALL SYSCALL(mmap) |
| CMPL AX, $0xfffff001 |
| JLS 6(PC) |
| MOVL $1, 0(SP) |
| MOVL $runtime·mmap_failed(SB), 4(SP) |
| MOVL $12, 8(SP) // "mmap failed\n" |
| CALL SYSCALL(write) |
| INT $3 |
| RET |
| |
| TEXT runtime·munmap(SB),7,$0 |
| JMP SYSCALL(munmap) |
| |
| TEXT runtime·gettime(SB),7,$32 |
| LEAL 8(SP), BX |
| MOVL BX, 0(SP) |
| MOVL $0, 4(SP) |
| CALL SYSCALL(gettimeofday) |
| |
| MOVL 8(SP), BX // sec |
| MOVL sec+0(FP), DI |
| MOVL BX, (DI) |
| MOVL $0, 4(DI) // zero extend 32 -> 64 bits |
| |
| MOVL 12(SP), BX // usec |
| MOVL usec+4(FP), DI |
| MOVL BX, (DI) |
| RET |
| |
| // setldt(int entry, int address, int limit) |
| TEXT runtime·setldt(SB),7,$32 |
| // entry is ignored - nacl tells us the |
| // segment selector to use and stores it in GS. |
| MOVL address+4(FP), BX |
| MOVL limit+8(FP), CX |
| MOVL BX, 0(SP) |
| MOVL CX, 4(SP) |
| CALL SYSCALL(tls_init) |
| CMPL AX, $0xfffff001 |
| JLS 6(PC) |
| MOVL $1, 0(SP) |
| MOVL $runtime·tls_init_failed(SB), 4(SP) |
| MOVL $16, 8(SP) // "tls_init failed\n" |
| CALL SYSCALL(write) |
| INT $3 |
| RET |
| |
| // There's no good way (yet?) to get stack traces out of a |
| // broken NaCl process, so if something goes wrong, |
| // print an error string before dying. |
| |
| DATA runtime·mmap_failed(SB)/8, $"mmap fai" |
| DATA mmap_failed+8(SB)/4, $"led\n" |
| GLOBL runtime·mmap_failed(SB), $12 |
| |
| DATA runtime·tls_init_failed(SB)/8, $"tls_init" |
| DATA tls_init_failed+8(SB)/8, $" failed\n" |
| GLOBL runtime·tls_init_failed(SB), $16 |