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