github.com/stingnevermore/go@v0.0.0-20180120041312-3810f5bfed72/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