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