github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/runtime/sys_linux_386.s (about) 1 // Copyright 2009 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 // 6 // System calls and other sys.stuff for 386, Linux 7 // 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 TEXT runtime·exit(SB),NOSPLIT,$0 14 MOVL $252, AX // syscall number 15 MOVL code+0(FP), BX 16 CALL *runtime·_vdso(SB) 17 INT $3 // not reached 18 RET 19 20 TEXT runtime·exit1(SB),NOSPLIT,$0 21 MOVL $1, AX // exit - exit the current os thread 22 MOVL code+0(FP), BX 23 CALL *runtime·_vdso(SB) 24 INT $3 // not reached 25 RET 26 27 TEXT runtime·open(SB),NOSPLIT,$0 28 MOVL $5, AX // syscall - open 29 MOVL name+0(FP), BX 30 MOVL mode+4(FP), CX 31 MOVL perm+8(FP), DX 32 CALL *runtime·_vdso(SB) 33 MOVL AX, ret+12(FP) 34 RET 35 36 TEXT runtime·close(SB),NOSPLIT,$0 37 MOVL $6, AX // syscall - close 38 MOVL fd+0(FP), BX 39 CALL *runtime·_vdso(SB) 40 MOVL AX, ret+4(FP) 41 RET 42 43 TEXT runtime·write(SB),NOSPLIT,$0 44 MOVL $4, AX // syscall - write 45 MOVL fd+0(FP), BX 46 MOVL p+4(FP), CX 47 MOVL n+8(FP), DX 48 CALL *runtime·_vdso(SB) 49 MOVL AX, ret+12(FP) 50 RET 51 52 TEXT runtime·read(SB),NOSPLIT,$0 53 MOVL $3, AX // syscall - read 54 MOVL fd+0(FP), BX 55 MOVL p+4(FP), CX 56 MOVL n+8(FP), DX 57 CALL *runtime·_vdso(SB) 58 MOVL AX, ret+12(FP) 59 RET 60 61 TEXT runtime·getrlimit(SB),NOSPLIT,$0 62 MOVL $191, AX // syscall - ugetrlimit 63 MOVL kind+0(FP), BX 64 MOVL limit+4(FP), CX 65 CALL *runtime·_vdso(SB) 66 MOVL AX, ret+8(FP) 67 RET 68 69 TEXT runtime·usleep(SB),NOSPLIT,$8 70 MOVL $0, DX 71 MOVL usec+0(FP), AX 72 MOVL $1000000, CX 73 DIVL CX 74 MOVL AX, 0(SP) 75 MOVL DX, 4(SP) 76 77 // select(0, 0, 0, 0, &tv) 78 MOVL $142, AX 79 MOVL $0, BX 80 MOVL $0, CX 81 MOVL $0, DX 82 MOVL $0, SI 83 LEAL 0(SP), DI 84 CALL *runtime·_vdso(SB) 85 RET 86 87 TEXT runtime·raise(SB),NOSPLIT,$12 88 MOVL $224, AX // syscall - gettid 89 CALL *runtime·_vdso(SB) 90 MOVL AX, BX // arg 1 tid 91 MOVL sig+0(FP), CX // arg 2 signal 92 MOVL $238, AX // syscall - tkill 93 CALL *runtime·_vdso(SB) 94 RET 95 96 TEXT runtime·setitimer(SB),NOSPLIT,$0-12 97 MOVL $104, AX // syscall - setitimer 98 MOVL mode+0(FP), BX 99 MOVL new+4(FP), CX 100 MOVL old+8(FP), DX 101 CALL *runtime·_vdso(SB) 102 RET 103 104 TEXT runtime·mincore(SB),NOSPLIT,$0-16 105 MOVL $218, AX // syscall - mincore 106 MOVL addr+0(FP), BX 107 MOVL n+4(FP), CX 108 MOVL dst+8(FP), DX 109 CALL *runtime·_vdso(SB) 110 MOVL AX, ret+12(FP) 111 RET 112 113 // func now() (sec int64, nsec int32) 114 TEXT time·now(SB), NOSPLIT, $32 115 MOVL $265, AX // syscall - clock_gettime 116 MOVL $0, BX // CLOCK_REALTIME 117 LEAL 8(SP), CX 118 MOVL $0, DX 119 CALL *runtime·_vdso(SB) 120 MOVL 8(SP), AX // sec 121 MOVL 12(SP), BX // nsec 122 123 // sec is in AX, nsec in BX 124 MOVL AX, sec+0(FP) 125 MOVL $0, sec+4(FP) 126 MOVL BX, nsec+8(FP) 127 RET 128 129 // int64 nanotime(void) so really 130 // void nanotime(int64 *nsec) 131 TEXT runtime·nanotime(SB), NOSPLIT, $32 132 MOVL $265, AX // syscall - clock_gettime 133 MOVL $1, BX // CLOCK_MONOTONIC 134 LEAL 8(SP), CX 135 MOVL $0, DX 136 CALL *runtime·_vdso(SB) 137 MOVL 8(SP), AX // sec 138 MOVL 12(SP), BX // nsec 139 140 // sec is in AX, nsec in BX 141 // convert to DX:AX nsec 142 MOVL $1000000000, CX 143 MULL CX 144 ADDL BX, AX 145 ADCL $0, DX 146 147 MOVL AX, ret_lo+0(FP) 148 MOVL DX, ret_hi+4(FP) 149 RET 150 151 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0 152 MOVL $175, AX // syscall entry 153 MOVL sig+0(FP), BX 154 MOVL new+4(FP), CX 155 MOVL old+8(FP), DX 156 MOVL size+12(FP), SI 157 CALL *runtime·_vdso(SB) 158 CMPL AX, $0xfffff001 159 JLS 2(PC) 160 INT $3 161 RET 162 163 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0 164 MOVL $174, AX // syscall - rt_sigaction 165 MOVL sig+0(FP), BX 166 MOVL new+4(FP), CX 167 MOVL old+8(FP), DX 168 MOVL size+12(FP), SI 169 CALL *runtime·_vdso(SB) 170 MOVL AX, ret+16(FP) 171 RET 172 173 TEXT runtime·sigtramp(SB),NOSPLIT,$44 174 get_tls(CX) 175 176 // check that g exists 177 MOVL g(CX), DI 178 CMPL DI, $0 179 JNE 6(PC) 180 MOVL sig+0(FP), BX 181 MOVL BX, 0(SP) 182 MOVL $runtime·badsignal(SB), AX 183 CALL AX 184 RET 185 186 // save g 187 MOVL DI, 20(SP) 188 189 // g = m->gsignal 190 MOVL g_m(DI), BX 191 MOVL m_gsignal(BX), BX 192 MOVL BX, g(CX) 193 194 // copy arguments for call to sighandler 195 MOVL sig+0(FP), BX 196 MOVL BX, 0(SP) 197 MOVL info+4(FP), BX 198 MOVL BX, 4(SP) 199 MOVL context+8(FP), BX 200 MOVL BX, 8(SP) 201 MOVL DI, 12(SP) 202 203 CALL runtime·sighandler(SB) 204 205 // restore g 206 get_tls(CX) 207 MOVL 20(SP), BX 208 MOVL BX, g(CX) 209 210 RET 211 212 TEXT runtime·sigreturn(SB),NOSPLIT,$0 213 MOVL $173, AX // rt_sigreturn 214 // Sigreturn expects same SP as signal handler, 215 // so cannot CALL *runtime._vsdo(SB) here. 216 INT $0x80 217 INT $3 // not reached 218 RET 219 220 TEXT runtime·mmap(SB),NOSPLIT,$0 221 MOVL $192, AX // mmap2 222 MOVL addr+0(FP), BX 223 MOVL n+4(FP), CX 224 MOVL prot+8(FP), DX 225 MOVL flags+12(FP), SI 226 MOVL fd+16(FP), DI 227 MOVL off+20(FP), BP 228 SHRL $12, BP 229 CALL *runtime·_vdso(SB) 230 CMPL AX, $0xfffff001 231 JLS 3(PC) 232 NOTL AX 233 INCL AX 234 MOVL AX, ret+24(FP) 235 RET 236 237 TEXT runtime·munmap(SB),NOSPLIT,$0 238 MOVL $91, AX // munmap 239 MOVL addr+0(FP), BX 240 MOVL n+4(FP), CX 241 CALL *runtime·_vdso(SB) 242 CMPL AX, $0xfffff001 243 JLS 2(PC) 244 INT $3 245 RET 246 247 TEXT runtime·madvise(SB),NOSPLIT,$0 248 MOVL $219, AX // madvise 249 MOVL addr+0(FP), BX 250 MOVL n+4(FP), CX 251 MOVL flags+8(FP), DX 252 CALL *runtime·_vdso(SB) 253 // ignore failure - maybe pages are locked 254 RET 255 256 // int32 futex(int32 *uaddr, int32 op, int32 val, 257 // struct timespec *timeout, int32 *uaddr2, int32 val2); 258 TEXT runtime·futex(SB),NOSPLIT,$0 259 MOVL $240, AX // futex 260 MOVL addr+0(FP), BX 261 MOVL op+4(FP), CX 262 MOVL val+8(FP), DX 263 MOVL ts+12(FP), SI 264 MOVL addr2+16(FP), DI 265 MOVL val3+20(FP), BP 266 CALL *runtime·_vdso(SB) 267 MOVL AX, ret+24(FP) 268 RET 269 270 // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void)); 271 TEXT runtime·clone(SB),NOSPLIT,$0 272 MOVL $120, AX // clone 273 MOVL flags+4(SP), BX 274 MOVL stack+8(SP), CX 275 MOVL $0, DX // parent tid ptr 276 MOVL $0, DI // child tid ptr 277 278 // Copy mp, gp, fn off parent stack for use by child. 279 SUBL $16, CX 280 MOVL mm+12(SP), SI 281 MOVL SI, 0(CX) 282 MOVL gg+16(SP), SI 283 MOVL SI, 4(CX) 284 MOVL fn+20(SP), SI 285 MOVL SI, 8(CX) 286 MOVL $1234, 12(CX) 287 288 // cannot use CALL *runtime·_vdso(SB) here, because 289 // the stack changes during the system call (after 290 // CALL *runtime·_vdso(SB), the child is still using 291 // the parent's stack when executing its RET instruction). 292 INT $0x80 293 294 // In parent, return. 295 CMPL AX, $0 296 JEQ 3(PC) 297 MOVL AX, ret+20(FP) 298 RET 299 300 // Paranoia: check that SP is as we expect. 301 MOVL mm+8(FP), BP 302 CMPL BP, $1234 303 JEQ 2(PC) 304 INT $3 305 306 // Initialize AX to Linux tid 307 MOVL $224, AX 308 CALL *runtime·_vdso(SB) 309 310 // In child on new stack. Reload registers (paranoia). 311 MOVL 0(SP), BX // m 312 MOVL flags+0(FP), DX // g 313 MOVL stk+4(FP), SI // fn 314 315 MOVL AX, m_procid(BX) // save tid as m->procid 316 317 // set up ldt 7+id to point at m->tls. 318 // newosproc left the id in tls[0]. 319 LEAL m_tls(BX), BP 320 MOVL 0(BP), DI 321 ADDL $7, DI // m0 is LDT#7. count up. 322 // setldt(tls#, &tls, sizeof tls) 323 PUSHAL // save registers 324 PUSHL $32 // sizeof tls 325 PUSHL BP // &tls 326 PUSHL DI // tls # 327 CALL runtime·setldt(SB) 328 POPL AX 329 POPL AX 330 POPL AX 331 POPAL 332 333 // Now segment is established. Initialize m, g. 334 get_tls(AX) 335 MOVL DX, g(AX) 336 MOVL BX, g_m(DX) 337 338 CALL runtime·stackcheck(SB) // smashes AX, CX 339 MOVL 0(DX), DX // paranoia; check they are not nil 340 MOVL 0(BX), BX 341 342 // more paranoia; check that stack splitting code works 343 PUSHAL 344 CALL runtime·emptyfunc(SB) 345 POPAL 346 347 CALL SI // fn() 348 CALL runtime·exit1(SB) 349 MOVL $0x1234, 0x1005 350 351 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 352 MOVL $186, AX // sigaltstack 353 MOVL new+4(SP), BX 354 MOVL old+8(SP), CX 355 CALL *runtime·_vdso(SB) 356 CMPL AX, $0xfffff001 357 JLS 2(PC) 358 INT $3 359 RET 360 361 // <asm-i386/ldt.h> 362 // struct user_desc { 363 // unsigned int entry_number; 364 // unsigned long base_addr; 365 // unsigned int limit; 366 // unsigned int seg_32bit:1; 367 // unsigned int contents:2; 368 // unsigned int read_exec_only:1; 369 // unsigned int limit_in_pages:1; 370 // unsigned int seg_not_present:1; 371 // unsigned int useable:1; 372 // }; 373 #define SEG_32BIT 0x01 374 // contents are the 2 bits 0x02 and 0x04. 375 #define CONTENTS_DATA 0x00 376 #define CONTENTS_STACK 0x02 377 #define CONTENTS_CODE 0x04 378 #define READ_EXEC_ONLY 0x08 379 #define LIMIT_IN_PAGES 0x10 380 #define SEG_NOT_PRESENT 0x20 381 #define USEABLE 0x40 382 383 // setldt(int entry, int address, int limit) 384 TEXT runtime·setldt(SB),NOSPLIT,$32 385 MOVL entry+0(FP), BX // entry 386 MOVL address+4(FP), CX // base address 387 388 /* 389 * When linking against the system libraries, 390 * we use its pthread_create and let it set up %gs 391 * for us. When we do that, the private storage 392 * we get is not at 0(GS), 4(GS), but -8(GS), -4(GS). 393 * To insulate the rest of the tool chain from this 394 * ugliness, 8l rewrites 0(TLS) into -8(GS) for us. 395 * To accommodate that rewrite, we translate 396 * the address here and bump the limit to 0xffffffff (no limit) 397 * so that -8(GS) maps to 0(address). 398 * Also, the final 0(GS) (current 8(CX)) has to point 399 * to itself, to mimic ELF. 400 */ 401 ADDL $0x8, CX // address 402 MOVL CX, 0(CX) 403 404 // set up user_desc 405 LEAL 16(SP), AX // struct user_desc 406 MOVL BX, 0(AX) 407 MOVL CX, 4(AX) 408 MOVL $0xfffff, 8(AX) 409 MOVL $(SEG_32BIT|LIMIT_IN_PAGES|USEABLE|CONTENTS_DATA), 12(AX) // flag bits 410 411 // call modify_ldt 412 MOVL $1, BX // func = 1 (write) 413 MOVL AX, CX // user_desc 414 MOVL $16, DX // sizeof(user_desc) 415 MOVL $123, AX // syscall - modify_ldt 416 CALL *runtime·_vdso(SB) 417 418 // breakpoint on error 419 CMPL AX, $0xfffff001 420 JLS 2(PC) 421 INT $3 422 423 // compute segment selector - (entry*8+7) 424 MOVL entry+0(FP), AX 425 SHLL $3, AX 426 ADDL $7, AX 427 MOVW AX, GS 428 429 RET 430 431 TEXT runtime·osyield(SB),NOSPLIT,$0 432 MOVL $158, AX 433 CALL *runtime·_vdso(SB) 434 RET 435 436 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 437 MOVL $242, AX // syscall - sched_getaffinity 438 MOVL pid+0(FP), BX 439 MOVL len+4(FP), CX 440 MOVL buf+8(FP), DX 441 CALL *runtime·_vdso(SB) 442 MOVL AX, ret+12(FP) 443 RET 444 445 // int32 runtime·epollcreate(int32 size); 446 TEXT runtime·epollcreate(SB),NOSPLIT,$0 447 MOVL $254, AX 448 MOVL size+0(FP), BX 449 CALL *runtime·_vdso(SB) 450 MOVL AX, ret+4(FP) 451 RET 452 453 // int32 runtime·epollcreate1(int32 flags); 454 TEXT runtime·epollcreate1(SB),NOSPLIT,$0 455 MOVL $329, AX 456 MOVL flags+0(FP), BX 457 CALL *runtime·_vdso(SB) 458 MOVL AX, ret+4(FP) 459 RET 460 461 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 462 TEXT runtime·epollctl(SB),NOSPLIT,$0 463 MOVL $255, AX 464 MOVL epfd+0(FP), BX 465 MOVL op+4(FP), CX 466 MOVL fd+8(FP), DX 467 MOVL ev+12(FP), SI 468 CALL *runtime·_vdso(SB) 469 MOVL AX, ret+16(FP) 470 RET 471 472 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 473 TEXT runtime·epollwait(SB),NOSPLIT,$0 474 MOVL $256, AX 475 MOVL epfd+0(FP), BX 476 MOVL ev+4(FP), CX 477 MOVL nev+8(FP), DX 478 MOVL timeout+12(FP), SI 479 CALL *runtime·_vdso(SB) 480 MOVL AX, ret+16(FP) 481 RET 482 483 // void runtime·closeonexec(int32 fd); 484 TEXT runtime·closeonexec(SB),NOSPLIT,$0 485 MOVL $55, AX // fcntl 486 MOVL fd+0(FP), BX // fd 487 MOVL $2, CX // F_SETFD 488 MOVL $1, DX // FD_CLOEXEC 489 CALL *runtime·_vdso(SB) 490 RET