github.com/c9s/go@v0.0.0-20180120015821-984e81f64e0c/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 // Most linux systems use glibc's dynamic linker, which puts the 14 // __kernel_vsyscall vdso helper at 0x10(GS) for easy access from position 15 // independent code and setldt in runtime does the same in the statically 16 // linked case. However, systems that use alternative libc such as Android's 17 // bionic and musl, do not save the helper anywhere, and so the only way to 18 // invoke a syscall from position independent code is boring old int $0x80 19 // (which is also what syscall wrappers in bionic/musl use). 20 // 21 // The benchmarks also showed that using int $0x80 is as fast as calling 22 // *%gs:0x10 except on AMD Opteron. See https://golang.org/cl/19833 23 // for the benchmark program and raw data. 24 //#define INVOKE_SYSCALL CALL 0x10(GS) // non-portable 25 #define INVOKE_SYSCALL INT $0x80 26 27 #define SYS_exit 1 28 #define SYS_read 3 29 #define SYS_write 4 30 #define SYS_open 5 31 #define SYS_close 6 32 #define SYS_getpid 20 33 #define SYS_access 33 34 #define SYS_kill 37 35 #define SYS_brk 45 36 #define SYS_fcntl 55 37 #define SYS_munmap 91 38 #define SYS_socketcall 102 39 #define SYS_setittimer 104 40 #define SYS_clone 120 41 #define SYS_sched_yield 158 42 #define SYS_rt_sigreturn 173 43 #define SYS_rt_sigaction 174 44 #define SYS_rt_sigprocmask 175 45 #define SYS_sigaltstack 186 46 #define SYS_ugetrlimit 191 47 #define SYS_mmap2 192 48 #define SYS_mincore 218 49 #define SYS_madvise 219 50 #define SYS_gettid 224 51 #define SYS_tkill 238 52 #define SYS_futex 240 53 #define SYS_sched_getaffinity 242 54 #define SYS_set_thread_area 243 55 #define SYS_exit_group 252 56 #define SYS_epoll_create 254 57 #define SYS_epoll_ctl 255 58 #define SYS_epoll_wait 256 59 #define SYS_clock_gettime 265 60 #define SYS_pselect6 308 61 #define SYS_epoll_create1 329 62 63 TEXT runtime·exit(SB),NOSPLIT,$0 64 MOVL $SYS_exit_group, AX 65 MOVL code+0(FP), BX 66 INVOKE_SYSCALL 67 INT $3 // not reached 68 RET 69 70 TEXT exit1<>(SB),NOSPLIT,$0 71 MOVL $SYS_exit, AX 72 MOVL code+0(FP), BX 73 INVOKE_SYSCALL 74 INT $3 // not reached 75 RET 76 77 // func exitThread(wait *uint32) 78 TEXT runtime·exitThread(SB),NOSPLIT,$0-4 79 MOVL wait+0(FP), AX 80 // We're done using the stack. 81 MOVL $0, (AX) 82 MOVL $1, AX // exit (just this thread) 83 MOVL $0, BX // exit code 84 INT $0x80 // no stack; must not use CALL 85 // We may not even have a stack any more. 86 INT $3 87 JMP 0(PC) 88 89 TEXT runtime·open(SB),NOSPLIT,$0 90 MOVL $SYS_open, AX 91 MOVL name+0(FP), BX 92 MOVL mode+4(FP), CX 93 MOVL perm+8(FP), DX 94 INVOKE_SYSCALL 95 CMPL AX, $0xfffff001 96 JLS 2(PC) 97 MOVL $-1, AX 98 MOVL AX, ret+12(FP) 99 RET 100 101 TEXT runtime·closefd(SB),NOSPLIT,$0 102 MOVL $SYS_close, AX 103 MOVL fd+0(FP), BX 104 INVOKE_SYSCALL 105 CMPL AX, $0xfffff001 106 JLS 2(PC) 107 MOVL $-1, AX 108 MOVL AX, ret+4(FP) 109 RET 110 111 TEXT runtime·write(SB),NOSPLIT,$0 112 MOVL $SYS_write, AX 113 MOVL fd+0(FP), BX 114 MOVL p+4(FP), CX 115 MOVL n+8(FP), DX 116 INVOKE_SYSCALL 117 CMPL AX, $0xfffff001 118 JLS 2(PC) 119 MOVL $-1, AX 120 MOVL AX, ret+12(FP) 121 RET 122 123 TEXT runtime·read(SB),NOSPLIT,$0 124 MOVL $SYS_read, AX 125 MOVL fd+0(FP), BX 126 MOVL p+4(FP), CX 127 MOVL n+8(FP), DX 128 INVOKE_SYSCALL 129 CMPL AX, $0xfffff001 130 JLS 2(PC) 131 MOVL $-1, AX 132 MOVL AX, ret+12(FP) 133 RET 134 135 TEXT runtime·getrlimit(SB),NOSPLIT,$0 136 MOVL $SYS_ugetrlimit, AX 137 MOVL kind+0(FP), BX 138 MOVL limit+4(FP), CX 139 INVOKE_SYSCALL 140 MOVL AX, ret+8(FP) 141 RET 142 143 TEXT runtime·usleep(SB),NOSPLIT,$8 144 MOVL $0, DX 145 MOVL usec+0(FP), AX 146 MOVL $1000000, CX 147 DIVL CX 148 MOVL AX, 0(SP) 149 MOVL $1000, AX // usec to nsec 150 MULL DX 151 MOVL AX, 4(SP) 152 153 // pselect6(0, 0, 0, 0, &ts, 0) 154 MOVL $SYS_pselect6, AX 155 MOVL $0, BX 156 MOVL $0, CX 157 MOVL $0, DX 158 MOVL $0, SI 159 LEAL 0(SP), DI 160 MOVL $0, BP 161 INVOKE_SYSCALL 162 RET 163 164 TEXT runtime·gettid(SB),NOSPLIT,$0-4 165 MOVL $SYS_gettid, AX 166 INVOKE_SYSCALL 167 MOVL AX, ret+0(FP) 168 RET 169 170 TEXT runtime·raise(SB),NOSPLIT,$12 171 MOVL $SYS_gettid, AX 172 INVOKE_SYSCALL 173 MOVL AX, BX // arg 1 tid 174 MOVL sig+0(FP), CX // arg 2 signal 175 MOVL $SYS_tkill, AX 176 INVOKE_SYSCALL 177 RET 178 179 TEXT runtime·raiseproc(SB),NOSPLIT,$12 180 MOVL $SYS_getpid, AX 181 INVOKE_SYSCALL 182 MOVL AX, BX // arg 1 pid 183 MOVL sig+0(FP), CX // arg 2 signal 184 MOVL $SYS_kill, AX 185 INVOKE_SYSCALL 186 RET 187 188 TEXT runtime·setitimer(SB),NOSPLIT,$0-12 189 MOVL $SYS_setittimer, AX 190 MOVL mode+0(FP), BX 191 MOVL new+4(FP), CX 192 MOVL old+8(FP), DX 193 INVOKE_SYSCALL 194 RET 195 196 TEXT runtime·mincore(SB),NOSPLIT,$0-16 197 MOVL $SYS_mincore, AX 198 MOVL addr+0(FP), BX 199 MOVL n+4(FP), CX 200 MOVL dst+8(FP), DX 201 INVOKE_SYSCALL 202 MOVL AX, ret+12(FP) 203 RET 204 205 // func walltime() (sec int64, nsec int32) 206 TEXT runtime·walltime(SB), NOSPLIT, $0-12 207 // We don't know how much stack space the VDSO code will need, 208 // so switch to g0. 209 210 MOVL SP, BP // Save old SP; BP unchanged by C code. 211 212 get_tls(CX) 213 MOVL g(CX), AX 214 MOVL g_m(AX), CX 215 MOVL m_curg(CX), DX 216 217 CMPL AX, DX // Only switch if on curg. 218 JNE noswitch 219 220 MOVL m_g0(CX), DX 221 MOVL (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack 222 223 noswitch: 224 SUBL $16, SP // Space for results 225 ANDL $~15, SP // Align for C code 226 227 // Stack layout, depending on call path: 228 // x(SP) vDSO INVOKE_SYSCALL 229 // 12 ts.tv_nsec ts.tv_nsec 230 // 8 ts.tv_sec ts.tv_sec 231 // 4 &ts - 232 // 0 CLOCK_<id> - 233 234 MOVL runtime·__vdso_clock_gettime_sym(SB), AX 235 CMPL AX, $0 236 JEQ fallback 237 238 LEAL 8(SP), BX // &ts (struct timespec) 239 MOVL BX, 4(SP) 240 MOVL $0, 0(SP) // CLOCK_REALTIME 241 CALL AX 242 JMP finish 243 244 fallback: 245 MOVL $SYS_clock_gettime, AX 246 MOVL $0, BX // CLOCK_REALTIME 247 LEAL 8(SP), CX 248 INVOKE_SYSCALL 249 250 finish: 251 MOVL 8(SP), AX // sec 252 MOVL 12(SP), BX // nsec 253 254 MOVL BP, SP // Restore real SP 255 256 // sec is in AX, nsec in BX 257 MOVL AX, sec_lo+0(FP) 258 MOVL $0, sec_hi+4(FP) 259 MOVL BX, nsec+8(FP) 260 RET 261 262 // int64 nanotime(void) so really 263 // void nanotime(int64 *nsec) 264 TEXT runtime·nanotime(SB), NOSPLIT, $0-8 265 // Switch to g0 stack. See comment above in runtime·walltime. 266 267 MOVL SP, BP // Save old SP; BP unchanged by C code. 268 269 get_tls(CX) 270 MOVL g(CX), AX 271 MOVL g_m(AX), CX 272 MOVL m_curg(CX), DX 273 274 CMPL AX, DX // Only switch if on curg. 275 JNE noswitch 276 277 MOVL m_g0(CX), DX 278 MOVL (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack 279 280 noswitch: 281 SUBL $16, SP // Space for results 282 ANDL $~15, SP // Align for C code 283 284 MOVL runtime·__vdso_clock_gettime_sym(SB), AX 285 CMPL AX, $0 286 JEQ fallback 287 288 LEAL 8(SP), BX // &ts (struct timespec) 289 MOVL BX, 4(SP) 290 MOVL $1, 0(SP) // CLOCK_MONOTONIC 291 CALL AX 292 JMP finish 293 294 fallback: 295 MOVL $SYS_clock_gettime, AX 296 MOVL $1, BX // CLOCK_MONOTONIC 297 LEAL 8(SP), CX 298 INVOKE_SYSCALL 299 300 finish: 301 MOVL 8(SP), AX // sec 302 MOVL 12(SP), BX // nsec 303 304 MOVL BP, SP // Restore real SP 305 306 // sec is in AX, nsec in BX 307 // convert to DX:AX nsec 308 MOVL $1000000000, CX 309 MULL CX 310 ADDL BX, AX 311 ADCL $0, DX 312 313 MOVL AX, ret_lo+0(FP) 314 MOVL DX, ret_hi+4(FP) 315 RET 316 317 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0 318 MOVL $SYS_rt_sigprocmask, AX 319 MOVL how+0(FP), BX 320 MOVL new+4(FP), CX 321 MOVL old+8(FP), DX 322 MOVL size+12(FP), SI 323 INVOKE_SYSCALL 324 CMPL AX, $0xfffff001 325 JLS 2(PC) 326 INT $3 327 RET 328 329 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0 330 MOVL $SYS_rt_sigaction, AX 331 MOVL sig+0(FP), BX 332 MOVL new+4(FP), CX 333 MOVL old+8(FP), DX 334 MOVL size+12(FP), SI 335 INVOKE_SYSCALL 336 MOVL AX, ret+16(FP) 337 RET 338 339 TEXT runtime·sigfwd(SB),NOSPLIT,$12-16 340 MOVL fn+0(FP), AX 341 MOVL sig+4(FP), BX 342 MOVL info+8(FP), CX 343 MOVL ctx+12(FP), DX 344 MOVL SP, SI 345 SUBL $32, SP 346 ANDL $-15, SP // align stack: handler might be a C function 347 MOVL BX, 0(SP) 348 MOVL CX, 4(SP) 349 MOVL DX, 8(SP) 350 MOVL SI, 12(SP) // save SI: handler might be a Go function 351 CALL AX 352 MOVL 12(SP), AX 353 MOVL AX, SP 354 RET 355 356 TEXT runtime·sigtramp(SB),NOSPLIT,$28 357 // Save callee-saved C registers, since the caller may be a C signal handler. 358 MOVL BX, bx-4(SP) 359 MOVL BP, bp-8(SP) 360 MOVL SI, si-12(SP) 361 MOVL DI, di-16(SP) 362 // We don't save mxcsr or the x87 control word because sigtrampgo doesn't 363 // modify them. 364 365 MOVL sig+0(FP), BX 366 MOVL BX, 0(SP) 367 MOVL info+4(FP), BX 368 MOVL BX, 4(SP) 369 MOVL ctx+8(FP), BX 370 MOVL BX, 8(SP) 371 CALL runtime·sigtrampgo(SB) 372 373 MOVL di-16(SP), DI 374 MOVL si-12(SP), SI 375 MOVL bp-8(SP), BP 376 MOVL bx-4(SP), BX 377 RET 378 379 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 380 JMP runtime·sigtramp(SB) 381 382 TEXT runtime·sigreturn(SB),NOSPLIT,$0 383 MOVL $SYS_rt_sigreturn, AX 384 // Sigreturn expects same SP as signal handler, 385 // so cannot CALL 0x10(GS) here. 386 INT $0x80 387 INT $3 // not reached 388 RET 389 390 TEXT runtime·mmap(SB),NOSPLIT,$0 391 MOVL $SYS_mmap2, AX 392 MOVL addr+0(FP), BX 393 MOVL n+4(FP), CX 394 MOVL prot+8(FP), DX 395 MOVL flags+12(FP), SI 396 MOVL fd+16(FP), DI 397 MOVL off+20(FP), BP 398 SHRL $12, BP 399 INVOKE_SYSCALL 400 CMPL AX, $0xfffff001 401 JLS ok 402 NOTL AX 403 INCL AX 404 MOVL $0, p+24(FP) 405 MOVL AX, err+28(FP) 406 RET 407 ok: 408 MOVL AX, p+24(FP) 409 MOVL $0, err+28(FP) 410 RET 411 412 TEXT runtime·munmap(SB),NOSPLIT,$0 413 MOVL $SYS_munmap, AX 414 MOVL addr+0(FP), BX 415 MOVL n+4(FP), CX 416 INVOKE_SYSCALL 417 CMPL AX, $0xfffff001 418 JLS 2(PC) 419 INT $3 420 RET 421 422 TEXT runtime·madvise(SB),NOSPLIT,$0 423 MOVL $SYS_madvise, AX 424 MOVL addr+0(FP), BX 425 MOVL n+4(FP), CX 426 MOVL flags+8(FP), DX 427 INVOKE_SYSCALL 428 // ignore failure - maybe pages are locked 429 RET 430 431 // int32 futex(int32 *uaddr, int32 op, int32 val, 432 // struct timespec *timeout, int32 *uaddr2, int32 val2); 433 TEXT runtime·futex(SB),NOSPLIT,$0 434 MOVL $SYS_futex, AX 435 MOVL addr+0(FP), BX 436 MOVL op+4(FP), CX 437 MOVL val+8(FP), DX 438 MOVL ts+12(FP), SI 439 MOVL addr2+16(FP), DI 440 MOVL val3+20(FP), BP 441 INVOKE_SYSCALL 442 MOVL AX, ret+24(FP) 443 RET 444 445 // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void)); 446 TEXT runtime·clone(SB),NOSPLIT,$0 447 MOVL $SYS_clone, AX 448 MOVL flags+0(FP), BX 449 MOVL stk+4(FP), CX 450 MOVL $0, DX // parent tid ptr 451 MOVL $0, DI // child tid ptr 452 453 // Copy mp, gp, fn off parent stack for use by child. 454 SUBL $16, CX 455 MOVL mp+8(FP), SI 456 MOVL SI, 0(CX) 457 MOVL gp+12(FP), SI 458 MOVL SI, 4(CX) 459 MOVL fn+16(FP), SI 460 MOVL SI, 8(CX) 461 MOVL $1234, 12(CX) 462 463 // cannot use CALL 0x10(GS) here, because the stack changes during the 464 // system call (after CALL 0x10(GS), the child is still using the 465 // parent's stack when executing its RET instruction). 466 INT $0x80 467 468 // In parent, return. 469 CMPL AX, $0 470 JEQ 3(PC) 471 MOVL AX, ret+20(FP) 472 RET 473 474 // Paranoia: check that SP is as we expect. 475 MOVL 12(SP), BP 476 CMPL BP, $1234 477 JEQ 2(PC) 478 INT $3 479 480 // Initialize AX to Linux tid 481 MOVL $SYS_gettid, AX 482 INVOKE_SYSCALL 483 484 MOVL 0(SP), BX // m 485 MOVL 4(SP), DX // g 486 MOVL 8(SP), SI // fn 487 488 CMPL BX, $0 489 JEQ nog 490 CMPL DX, $0 491 JEQ nog 492 493 MOVL AX, m_procid(BX) // save tid as m->procid 494 495 // set up ldt 7+id to point at m->tls. 496 LEAL m_tls(BX), BP 497 MOVL m_id(BX), DI 498 ADDL $7, DI // m0 is LDT#7. count up. 499 // setldt(tls#, &tls, sizeof tls) 500 PUSHAL // save registers 501 PUSHL $32 // sizeof tls 502 PUSHL BP // &tls 503 PUSHL DI // tls # 504 CALL runtime·setldt(SB) 505 POPL AX 506 POPL AX 507 POPL AX 508 POPAL 509 510 // Now segment is established. Initialize m, g. 511 get_tls(AX) 512 MOVL DX, g(AX) 513 MOVL BX, g_m(DX) 514 515 CALL runtime·stackcheck(SB) // smashes AX, CX 516 MOVL 0(DX), DX // paranoia; check they are not nil 517 MOVL 0(BX), BX 518 519 // more paranoia; check that stack splitting code works 520 PUSHAL 521 CALL runtime·emptyfunc(SB) 522 POPAL 523 524 nog: 525 CALL SI // fn() 526 CALL exit1<>(SB) 527 MOVL $0x1234, 0x1005 528 529 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 530 MOVL $SYS_sigaltstack, AX 531 MOVL new+0(FP), BX 532 MOVL old+4(FP), CX 533 INVOKE_SYSCALL 534 CMPL AX, $0xfffff001 535 JLS 2(PC) 536 INT $3 537 RET 538 539 // <asm-i386/ldt.h> 540 // struct user_desc { 541 // unsigned int entry_number; 542 // unsigned long base_addr; 543 // unsigned int limit; 544 // unsigned int seg_32bit:1; 545 // unsigned int contents:2; 546 // unsigned int read_exec_only:1; 547 // unsigned int limit_in_pages:1; 548 // unsigned int seg_not_present:1; 549 // unsigned int useable:1; 550 // }; 551 #define SEG_32BIT 0x01 552 // contents are the 2 bits 0x02 and 0x04. 553 #define CONTENTS_DATA 0x00 554 #define CONTENTS_STACK 0x02 555 #define CONTENTS_CODE 0x04 556 #define READ_EXEC_ONLY 0x08 557 #define LIMIT_IN_PAGES 0x10 558 #define SEG_NOT_PRESENT 0x20 559 #define USEABLE 0x40 560 561 // `-1` means the kernel will pick a TLS entry on the first setldt call, 562 // which happens during runtime init, and that we'll store back the saved 563 // entry and reuse that on subsequent calls when creating new threads. 564 DATA runtime·tls_entry_number+0(SB)/4, $-1 565 GLOBL runtime·tls_entry_number(SB), NOPTR, $4 566 567 // setldt(int entry, int address, int limit) 568 // We use set_thread_area, which mucks with the GDT, instead of modify_ldt, 569 // which would modify the LDT, but is disabled on some kernels. 570 // The name, setldt, is a misnomer, although we leave this name as it is for 571 // the compatibility with other platforms. 572 TEXT runtime·setldt(SB),NOSPLIT,$32 573 MOVL address+4(FP), DX // base address 574 575 #ifdef GOOS_android 576 /* 577 * Same as in sys_darwin_386.s:/ugliness, different constant. 578 * address currently holds m->tls, which must be %gs:0xf8. 579 * See cgo/gcc_android_386.c for the derivation of the constant. 580 */ 581 SUBL $0xf8, DX 582 MOVL DX, 0(DX) 583 #else 584 /* 585 * When linking against the system libraries, 586 * we use its pthread_create and let it set up %gs 587 * for us. When we do that, the private storage 588 * we get is not at 0(GS), but -4(GS). 589 * To insulate the rest of the tool chain from this 590 * ugliness, 8l rewrites 0(TLS) into -4(GS) for us. 591 * To accommodate that rewrite, we translate 592 * the address here and bump the limit to 0xffffffff (no limit) 593 * so that -4(GS) maps to 0(address). 594 * Also, the final 0(GS) (current 4(DX)) has to point 595 * to itself, to mimic ELF. 596 */ 597 ADDL $0x4, DX // address 598 MOVL DX, 0(DX) 599 #endif 600 601 // get entry number 602 MOVL runtime·tls_entry_number(SB), CX 603 604 // set up user_desc 605 LEAL 16(SP), AX // struct user_desc 606 MOVL CX, 0(AX) // unsigned int entry_number 607 MOVL DX, 4(AX) // unsigned long base_addr 608 MOVL $0xfffff, 8(AX) // unsigned int limit 609 MOVL $(SEG_32BIT|LIMIT_IN_PAGES|USEABLE|CONTENTS_DATA), 12(AX) // flag bits 610 611 // call set_thread_area 612 MOVL AX, BX // user_desc 613 MOVL $SYS_set_thread_area, AX 614 // We can't call this via 0x10(GS) because this is called from setldt0 to set that up. 615 INT $0x80 616 617 // breakpoint on error 618 CMPL AX, $0xfffff001 619 JLS 2(PC) 620 INT $3 621 622 // read allocated entry number back out of user_desc 623 LEAL 16(SP), AX // get our user_desc back 624 MOVL 0(AX), AX 625 626 // store entry number if the kernel allocated it 627 CMPL CX, $-1 628 JNE 2(PC) 629 MOVL AX, runtime·tls_entry_number(SB) 630 631 // compute segment selector - (entry*8+3) 632 SHLL $3, AX 633 ADDL $3, AX 634 MOVW AX, GS 635 636 RET 637 638 TEXT runtime·osyield(SB),NOSPLIT,$0 639 MOVL $SYS_sched_yield, AX 640 INVOKE_SYSCALL 641 RET 642 643 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 644 MOVL $SYS_sched_getaffinity, AX 645 MOVL pid+0(FP), BX 646 MOVL len+4(FP), CX 647 MOVL buf+8(FP), DX 648 INVOKE_SYSCALL 649 MOVL AX, ret+12(FP) 650 RET 651 652 // int32 runtime·epollcreate(int32 size); 653 TEXT runtime·epollcreate(SB),NOSPLIT,$0 654 MOVL $SYS_epoll_create, AX 655 MOVL size+0(FP), BX 656 INVOKE_SYSCALL 657 MOVL AX, ret+4(FP) 658 RET 659 660 // int32 runtime·epollcreate1(int32 flags); 661 TEXT runtime·epollcreate1(SB),NOSPLIT,$0 662 MOVL $SYS_epoll_create1, AX 663 MOVL flags+0(FP), BX 664 INVOKE_SYSCALL 665 MOVL AX, ret+4(FP) 666 RET 667 668 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 669 TEXT runtime·epollctl(SB),NOSPLIT,$0 670 MOVL $SYS_epoll_ctl, AX 671 MOVL epfd+0(FP), BX 672 MOVL op+4(FP), CX 673 MOVL fd+8(FP), DX 674 MOVL ev+12(FP), SI 675 INVOKE_SYSCALL 676 MOVL AX, ret+16(FP) 677 RET 678 679 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 680 TEXT runtime·epollwait(SB),NOSPLIT,$0 681 MOVL $SYS_epoll_wait, AX 682 MOVL epfd+0(FP), BX 683 MOVL ev+4(FP), CX 684 MOVL nev+8(FP), DX 685 MOVL timeout+12(FP), SI 686 INVOKE_SYSCALL 687 MOVL AX, ret+16(FP) 688 RET 689 690 // void runtime·closeonexec(int32 fd); 691 TEXT runtime·closeonexec(SB),NOSPLIT,$0 692 MOVL $SYS_fcntl, AX 693 MOVL fd+0(FP), BX // fd 694 MOVL $2, CX // F_SETFD 695 MOVL $1, DX // FD_CLOEXEC 696 INVOKE_SYSCALL 697 RET 698 699 // int access(const char *name, int mode) 700 TEXT runtime·access(SB),NOSPLIT,$0 701 MOVL $SYS_access, AX 702 MOVL name+0(FP), BX 703 MOVL mode+4(FP), CX 704 INVOKE_SYSCALL 705 MOVL AX, ret+8(FP) 706 RET 707 708 // int connect(int fd, const struct sockaddr *addr, socklen_t addrlen) 709 TEXT runtime·connect(SB),NOSPLIT,$0-16 710 // connect is implemented as socketcall(NR_socket, 3, *(rest of args)) 711 // stack already should have fd, addr, addrlen. 712 MOVL $SYS_socketcall, AX 713 MOVL $3, BX // connect 714 LEAL fd+0(FP), CX 715 INVOKE_SYSCALL 716 MOVL AX, ret+12(FP) 717 RET 718 719 // int socket(int domain, int type, int protocol) 720 TEXT runtime·socket(SB),NOSPLIT,$0-16 721 // socket is implemented as socketcall(NR_socket, 1, *(rest of args)) 722 // stack already should have domain, type, protocol. 723 MOVL $SYS_socketcall, AX 724 MOVL $1, BX // socket 725 LEAL domain+0(FP), CX 726 INVOKE_SYSCALL 727 MOVL AX, ret+12(FP) 728 RET 729 730 // func sbrk0() uintptr 731 TEXT runtime·sbrk0(SB),NOSPLIT,$0-4 732 // Implemented as brk(NULL). 733 MOVL $SYS_brk, AX 734 MOVL $0, BX // NULL 735 INVOKE_SYSCALL 736 MOVL AX, ret+0(FP) 737 RET