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