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 AMD64, Linux 7 // 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 #define SYS_read 0 14 #define SYS_write 1 15 #define SYS_open 2 16 #define SYS_close 3 17 #define SYS_mmap 9 18 #define SYS_munmap 11 19 #define SYS_brk 12 20 #define SYS_rt_sigaction 13 21 #define SYS_rt_sigprocmask 14 22 #define SYS_rt_sigreturn 15 23 #define SYS_access 21 24 #define SYS_sched_yield 24 25 #define SYS_mincore 27 26 #define SYS_madvise 28 27 #define SYS_setittimer 38 28 #define SYS_getpid 39 29 #define SYS_socket 41 30 #define SYS_connect 42 31 #define SYS_clone 56 32 #define SYS_exit 60 33 #define SYS_kill 62 34 #define SYS_fcntl 72 35 #define SYS_getrlimit 97 36 #define SYS_sigaltstack 131 37 #define SYS_arch_prctl 158 38 #define SYS_gettid 186 39 #define SYS_tkill 200 40 #define SYS_futex 202 41 #define SYS_sched_getaffinity 204 42 #define SYS_epoll_create 213 43 #define SYS_exit_group 231 44 #define SYS_epoll_wait 232 45 #define SYS_epoll_ctl 233 46 #define SYS_pselect6 270 47 #define SYS_epoll_create1 291 48 49 TEXT runtimeexit(SB),NOSPLIT,$0-4 50 MOVL code+0(FP), DI 51 MOVL $SYS_exit_group, AX 52 SYSCALL 53 RET 54 55 // func exitThread(wait *uint32) 56 TEXT runtimeexitThread(SB),NOSPLIT,$0-8 57 MOVQ wait+0(FP), AX 58 // We're done using the stack. 59 MOVL $0, (AX) 60 MOVL $0, DI // exit code 61 MOVL $SYS_exit, AX 62 SYSCALL 63 // We may not even have a stack any more. 64 INT $3 65 JMP 0(PC) 66 67 TEXT runtimeopen(SB),NOSPLIT,$0-20 68 MOVQ name+0(FP), DI 69 MOVL mode+8(FP), SI 70 MOVL perm+12(FP), DX 71 MOVL $SYS_open, AX 72 SYSCALL 73 CMPQ AX, $0xfffffffffffff001 74 JLS 2(PC) 75 MOVL $-1, AX 76 MOVL AX, ret+16(FP) 77 RET 78 79 TEXT runtimeclosefd(SB),NOSPLIT,$0-12 80 MOVL fd+0(FP), DI 81 MOVL $SYS_close, AX 82 SYSCALL 83 CMPQ AX, $0xfffffffffffff001 84 JLS 2(PC) 85 MOVL $-1, AX 86 MOVL AX, ret+8(FP) 87 RET 88 89 TEXT runtimewrite(SB),NOSPLIT,$0-28 90 MOVQ fd+0(FP), DI 91 MOVQ p+8(FP), SI 92 MOVL n+16(FP), DX 93 MOVL $SYS_write, AX 94 SYSCALL 95 CMPQ AX, $0xfffffffffffff001 96 JLS 2(PC) 97 MOVL $-1, AX 98 MOVL AX, ret+24(FP) 99 RET 100 101 TEXT runtimeread(SB),NOSPLIT,$0-28 102 MOVL fd+0(FP), DI 103 MOVQ p+8(FP), SI 104 MOVL n+16(FP), DX 105 MOVL $SYS_read, AX 106 SYSCALL 107 CMPQ AX, $0xfffffffffffff001 108 JLS 2(PC) 109 MOVL $-1, AX 110 MOVL AX, ret+24(FP) 111 RET 112 113 TEXT runtimegetrlimit(SB),NOSPLIT,$0-20 114 MOVL kind+0(FP), DI 115 MOVQ limit+8(FP), SI 116 MOVL $SYS_getrlimit, AX 117 SYSCALL 118 MOVL AX, ret+16(FP) 119 RET 120 121 TEXT runtimeusleep(SB),NOSPLIT,$16 122 MOVL $0, DX 123 MOVL usec+0(FP), AX 124 MOVL $1000000, CX 125 DIVL CX 126 MOVQ AX, 0(SP) 127 MOVL $1000, AX // usec to nsec 128 MULL DX 129 MOVQ AX, 8(SP) 130 131 // pselect6(0, 0, 0, 0, &ts, 0) 132 MOVL $0, DI 133 MOVL $0, SI 134 MOVL $0, DX 135 MOVL $0, R10 136 MOVQ SP, R8 137 MOVL $0, R9 138 MOVL $SYS_pselect6, AX 139 SYSCALL 140 RET 141 142 TEXT runtimegettid(SB),NOSPLIT,$0-4 143 MOVL $SYS_gettid, AX 144 SYSCALL 145 MOVL AX, ret+0(FP) 146 RET 147 148 TEXT runtimeraise(SB),NOSPLIT,$0 149 MOVL $SYS_gettid, AX 150 SYSCALL 151 MOVL AX, DI // arg 1 tid 152 MOVL sig+0(FP), SI // arg 2 153 MOVL $SYS_tkill, AX 154 SYSCALL 155 RET 156 157 TEXT runtimeraiseproc(SB),NOSPLIT,$0 158 MOVL $SYS_getpid, AX 159 SYSCALL 160 MOVL AX, DI // arg 1 pid 161 MOVL sig+0(FP), SI // arg 2 162 MOVL $SYS_kill, AX 163 SYSCALL 164 RET 165 166 TEXT runtimesetitimer(SB),NOSPLIT,$0-24 167 MOVL mode+0(FP), DI 168 MOVQ new+8(FP), SI 169 MOVQ old+16(FP), DX 170 MOVL $SYS_setittimer, AX 171 SYSCALL 172 RET 173 174 TEXT runtimemincore(SB),NOSPLIT,$0-28 175 MOVQ addr+0(FP), DI 176 MOVQ n+8(FP), SI 177 MOVQ dst+16(FP), DX 178 MOVL $SYS_mincore, AX 179 SYSCALL 180 MOVL AX, ret+24(FP) 181 RET 182 183 // func walltime() (sec int64, nsec int32) 184 TEXT runtimewalltime(SB),NOSPLIT,$0-12 185 // We don't know how much stack space the VDSO code will need, 186 // so switch to g0. 187 // In particular, a kernel configured with CONFIG_OPTIMIZE_INLINING=n 188 // and hardening can use a full page of stack space in gettime_sym 189 // due to stack probes inserted to avoid stack/heap collisions. 190 // See issue #20427. 191 192 MOVQ SP, BP // Save old SP; BP unchanged by C code. 193 194 get_tls(CX) 195 MOVQ g(CX), AX 196 MOVQ g_m(AX), CX 197 MOVQ m_curg(CX), DX 198 199 CMPQ AX, DX // Only switch if on curg. 200 JNE noswitch 201 202 MOVQ m_g0(CX), DX 203 MOVQ (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack 204 205 noswitch: 206 SUBQ $16, SP // Space for results 207 ANDQ $~15, SP // Align for C code 208 209 MOVQ runtime__vdso_clock_gettime_sym(SB), AX 210 CMPQ AX, $0 211 JEQ fallback 212 MOVL $0, DI // CLOCK_REALTIME 213 LEAQ 0(SP), SI 214 CALL AX 215 MOVQ 0(SP), AX // sec 216 MOVQ 8(SP), DX // nsec 217 MOVQ BP, SP // Restore real SP 218 MOVQ AX, sec+0(FP) 219 MOVL DX, nsec+8(FP) 220 RET 221 fallback: 222 LEAQ 0(SP), DI 223 MOVQ $0, SI 224 MOVQ runtime__vdso_gettimeofday_sym(SB), AX 225 CALL AX 226 MOVQ 0(SP), AX // sec 227 MOVL 8(SP), DX // usec 228 IMULQ $1000, DX 229 MOVQ BP, SP // Restore real SP 230 MOVQ AX, sec+0(FP) 231 MOVL DX, nsec+8(FP) 232 RET 233 234 TEXT runtimenanotime(SB),NOSPLIT,$0-8 235 // Switch to g0 stack. See comment above in runtimewalltime. 236 237 MOVQ SP, BP // Save old SP; BX unchanged by C code. 238 239 get_tls(CX) 240 MOVQ g(CX), AX 241 MOVQ g_m(AX), CX 242 MOVQ m_curg(CX), DX 243 244 CMPQ AX, DX // Only switch if on curg. 245 JNE noswitch 246 247 MOVQ m_g0(CX), DX 248 MOVQ (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack 249 250 noswitch: 251 SUBQ $16, SP // Space for results 252 ANDQ $~15, SP // Align for C code 253 254 MOVQ runtime__vdso_clock_gettime_sym(SB), AX 255 CMPQ AX, $0 256 JEQ fallback 257 MOVL $1, DI // CLOCK_MONOTONIC 258 LEAQ 0(SP), SI 259 CALL AX 260 MOVQ 0(SP), AX // sec 261 MOVQ 8(SP), DX // nsec 262 MOVQ BP, SP // Restore real SP 263 // sec is in AX, nsec in DX 264 // return nsec in AX 265 IMULQ $1000000000, AX 266 ADDQ DX, AX 267 MOVQ AX, ret+0(FP) 268 RET 269 fallback: 270 LEAQ 0(SP), DI 271 MOVQ $0, SI 272 MOVQ runtime__vdso_gettimeofday_sym(SB), AX 273 CALL AX 274 MOVQ 0(SP), AX // sec 275 MOVL 8(SP), DX // usec 276 MOVQ BP, SP // Restore real SP 277 IMULQ $1000, DX 278 // sec is in AX, nsec in DX 279 // return nsec in AX 280 IMULQ $1000000000, AX 281 ADDQ DX, AX 282 MOVQ AX, ret+0(FP) 283 RET 284 285 TEXT runtimertsigprocmask(SB),NOSPLIT,$0-28 286 MOVL how+0(FP), DI 287 MOVQ new+8(FP), SI 288 MOVQ old+16(FP), DX 289 MOVL size+24(FP), R10 290 MOVL $SYS_rt_sigprocmask, AX 291 SYSCALL 292 CMPQ AX, $0xfffffffffffff001 293 JLS 2(PC) 294 MOVL $0xf1, 0xf1 // crash 295 RET 296 297 TEXT runtimesysSigaction(SB),NOSPLIT,$0-36 298 MOVQ sig+0(FP), DI 299 MOVQ new+8(FP), SI 300 MOVQ old+16(FP), DX 301 MOVQ size+24(FP), R10 302 MOVL $SYS_rt_sigaction, AX 303 SYSCALL 304 MOVL AX, ret+32(FP) 305 RET 306 307 // Call the function stored in _cgo_sigaction using the GCC calling convention. 308 TEXT runtimecallCgoSigaction(SB),NOSPLIT,$16 309 MOVQ sig+0(FP), DI 310 MOVQ new+8(FP), SI 311 MOVQ old+16(FP), DX 312 MOVQ _cgo_sigaction(SB), AX 313 MOVQ SP, BX // callee-saved 314 ANDQ $~15, SP // alignment as per amd64 psABI 315 CALL AX 316 MOVQ BX, SP 317 MOVL AX, ret+24(FP) 318 RET 319 320 TEXT runtimesigfwd(SB),NOSPLIT,$0-32 321 MOVQ fn+0(FP), AX 322 MOVL sig+8(FP), DI 323 MOVQ info+16(FP), SI 324 MOVQ ctx+24(FP), DX 325 PUSHQ BP 326 MOVQ SP, BP 327 ANDQ $~15, SP // alignment for x86_64 ABI 328 CALL AX 329 MOVQ BP, SP 330 POPQ BP 331 RET 332 333 TEXT runtimesigtramp(SB),NOSPLIT,$72 334 // Save callee-saved C registers, since the caller may be a C signal handler. 335 MOVQ BX, bx-8(SP) 336 MOVQ BP, bp-16(SP) // save in case GOEXPERIMENT=noframepointer is set 337 MOVQ R12, r12-24(SP) 338 MOVQ R13, r13-32(SP) 339 MOVQ R14, r14-40(SP) 340 MOVQ R15, r15-48(SP) 341 // We don't save mxcsr or the x87 control word because sigtrampgo doesn't 342 // modify them. 343 344 MOVQ DX, ctx-56(SP) 345 MOVQ SI, info-64(SP) 346 MOVQ DI, signum-72(SP) 347 MOVQ $runtimesigtrampgo(SB), AX 348 CALL AX 349 350 MOVQ r15-48(SP), R15 351 MOVQ r14-40(SP), R14 352 MOVQ r13-32(SP), R13 353 MOVQ r12-24(SP), R12 354 MOVQ bp-16(SP), BP 355 MOVQ bx-8(SP), BX 356 RET 357 358 // Used instead of sigtramp in programs that use cgo. 359 // Arguments from kernel are in DI, SI, DX. 360 TEXT runtimecgoSigtramp(SB),NOSPLIT,$0 361 // If no traceback function, do usual sigtramp. 362 MOVQ runtimecgoTraceback(SB), AX 363 TESTQ AX, AX 364 JZ sigtramp 365 366 // If no traceback support function, which means that 367 // runtime/cgo was not linked in, do usual sigtramp. 368 MOVQ _cgo_callers(SB), AX 369 TESTQ AX, AX 370 JZ sigtramp 371 372 // Figure out if we are currently in a cgo call. 373 // If not, just do usual sigtramp. 374 get_tls(CX) 375 MOVQ g(CX),AX 376 TESTQ AX, AX 377 JZ sigtrampnog // g == nil 378 MOVQ g_m(AX), AX 379 TESTQ AX, AX 380 JZ sigtramp // g.m == nil 381 MOVL m_ncgo(AX), CX 382 TESTL CX, CX 383 JZ sigtramp // g.m.ncgo == 0 384 MOVQ m_curg(AX), CX 385 TESTQ CX, CX 386 JZ sigtramp // g.m.curg == nil 387 MOVQ g_syscallsp(CX), CX 388 TESTQ CX, CX 389 JZ sigtramp // g.m.curg.syscallsp == 0 390 MOVQ m_cgoCallers(AX), R8 391 TESTQ R8, R8 392 JZ sigtramp // g.m.cgoCallers == nil 393 MOVL m_cgoCallersUse(AX), CX 394 TESTL CX, CX 395 JNZ sigtramp // g.m.cgoCallersUse != 0 396 397 // Jump to a function in runtime/cgo. 398 // That function, written in C, will call the user's traceback 399 // function with proper unwind info, and will then call back here. 400 // The first three arguments, and the fifth, are already in registers. 401 // Set the two remaining arguments now. 402 MOVQ runtimecgoTraceback(SB), CX 403 MOVQ $runtimesigtramp(SB), R9 404 MOVQ _cgo_callers(SB), AX 405 JMP AX 406 407 sigtramp: 408 JMP runtimesigtramp(SB) 409 410 sigtrampnog: 411 // Signal arrived on a non-Go thread. If this is SIGPROF, get a 412 // stack trace. 413 CMPL DI, $27 // 27 == SIGPROF 414 JNZ sigtramp 415 416 // Lock sigprofCallersUse. 417 MOVL $0, AX 418 MOVL $1, CX 419 MOVQ $runtimesigprofCallersUse(SB), R11 420 LOCK 421 CMPXCHGL CX, 0(R11) 422 JNZ sigtramp // Skip stack trace if already locked. 423 424 // Jump to the traceback function in runtime/cgo. 425 // It will call back to sigprofNonGo, which will ignore the 426 // arguments passed in registers. 427 // First three arguments to traceback function are in registers already. 428 MOVQ runtimecgoTraceback(SB), CX 429 MOVQ $runtimesigprofCallers(SB), R8 430 MOVQ $runtimesigprofNonGo(SB), R9 431 MOVQ _cgo_callers(SB), AX 432 JMP AX 433 434 // For cgo unwinding to work, this function must look precisely like 435 // the one in glibc. The glibc source code is: 436 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/sigaction.c 437 // The code that cares about the precise instructions used is: 438 // https://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/i386/linux-unwind.h?revision=219188&view=markup 439 TEXT runtimesigreturn(SB),NOSPLIT,$0 440 MOVQ $SYS_rt_sigreturn, AX 441 SYSCALL 442 INT $3 // not reached 443 444 TEXT runtimesysMmap(SB),NOSPLIT,$0 445 MOVQ addr+0(FP), DI 446 MOVQ n+8(FP), SI 447 MOVL prot+16(FP), DX 448 MOVL flags+20(FP), R10 449 MOVL fd+24(FP), R8 450 MOVL off+28(FP), R9 451 452 MOVL $SYS_mmap, AX 453 SYSCALL 454 CMPQ AX, $0xfffffffffffff001 455 JLS ok 456 NOTQ AX 457 INCQ AX 458 MOVQ $0, p+32(FP) 459 MOVQ AX, err+40(FP) 460 RET 461 ok: 462 MOVQ AX, p+32(FP) 463 MOVQ $0, err+40(FP) 464 RET 465 466 // Call the function stored in _cgo_mmap using the GCC calling convention. 467 // This must be called on the system stack. 468 TEXT runtimecallCgoMmap(SB),NOSPLIT,$16 469 MOVQ addr+0(FP), DI 470 MOVQ n+8(FP), SI 471 MOVL prot+16(FP), DX 472 MOVL flags+20(FP), CX 473 MOVL fd+24(FP), R8 474 MOVL off+28(FP), R9 475 MOVQ _cgo_mmap(SB), AX 476 MOVQ SP, BX 477 ANDQ $~15, SP // alignment as per amd64 psABI 478 MOVQ BX, 0(SP) 479 CALL AX 480 MOVQ 0(SP), SP 481 MOVQ AX, ret+32(FP) 482 RET 483 484 TEXT runtimesysMunmap(SB),NOSPLIT,$0 485 MOVQ addr+0(FP), DI 486 MOVQ n+8(FP), SI 487 MOVQ $SYS_munmap, AX 488 SYSCALL 489 CMPQ AX, $0xfffffffffffff001 490 JLS 2(PC) 491 MOVL $0xf1, 0xf1 // crash 492 RET 493 494 // Call the function stored in _cgo_munmap using the GCC calling convention. 495 // This must be called on the system stack. 496 TEXT runtimecallCgoMunmap(SB),NOSPLIT,$16-16 497 MOVQ addr+0(FP), DI 498 MOVQ n+8(FP), SI 499 MOVQ _cgo_munmap(SB), AX 500 MOVQ SP, BX 501 ANDQ $~15, SP // alignment as per amd64 psABI 502 MOVQ BX, 0(SP) 503 CALL AX 504 MOVQ 0(SP), SP 505 RET 506 507 TEXT runtimemadvise(SB),NOSPLIT,$0 508 MOVQ addr+0(FP), DI 509 MOVQ n+8(FP), SI 510 MOVL flags+16(FP), DX 511 MOVQ $SYS_madvise, AX 512 SYSCALL 513 // ignore failure - maybe pages are locked 514 RET 515 516 // int64 futex(int32 *uaddr, int32 op, int32 val, 517 // struct timespec *timeout, int32 *uaddr2, int32 val2); 518 TEXT runtimefutex(SB),NOSPLIT,$0 519 MOVQ addr+0(FP), DI 520 MOVL op+8(FP), SI 521 MOVL val+12(FP), DX 522 MOVQ ts+16(FP), R10 523 MOVQ addr2+24(FP), R8 524 MOVL val3+32(FP), R9 525 MOVL $SYS_futex, AX 526 SYSCALL 527 MOVL AX, ret+40(FP) 528 RET 529 530 // int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 531 TEXT runtimeclone(SB),NOSPLIT,$0 532 MOVL flags+0(FP), DI 533 MOVQ stk+8(FP), SI 534 MOVQ $0, DX 535 MOVQ $0, R10 536 537 // Copy mp, gp, fn off parent stack for use by child. 538 // Careful: Linux system call clobbers CX and R11. 539 MOVQ mp+16(FP), R8 540 MOVQ gp+24(FP), R9 541 MOVQ fn+32(FP), R12 542 543 MOVL $SYS_clone, AX 544 SYSCALL 545 546 // In parent, return. 547 CMPQ AX, $0 548 JEQ 3(PC) 549 MOVL AX, ret+40(FP) 550 RET 551 552 // In child, on new stack. 553 MOVQ SI, SP 554 555 // If g or m are nil, skip Go-related setup. 556 CMPQ R8, $0 // m 557 JEQ nog 558 CMPQ R9, $0 // g 559 JEQ nog 560 561 // Initialize m->procid to Linux tid 562 MOVL $SYS_gettid, AX 563 SYSCALL 564 MOVQ AX, m_procid(R8) 565 566 // Set FS to point at m->tls. 567 LEAQ m_tls(R8), DI 568 CALL runtimesettls(SB) 569 570 // In child, set up new stack 571 get_tls(CX) 572 MOVQ R8, g_m(R9) 573 MOVQ R9, g(CX) 574 CALL runtimestackcheck(SB) 575 576 nog: 577 // Call fn 578 CALL R12 579 580 // It shouldn't return. If it does, exit that thread. 581 MOVL $111, DI 582 MOVL $SYS_exit, AX 583 SYSCALL 584 JMP -3(PC) // keep exiting 585 586 TEXT runtimesigaltstack(SB),NOSPLIT,$-8 587 MOVQ new+0(FP), DI 588 MOVQ old+8(FP), SI 589 MOVQ $SYS_sigaltstack, AX 590 SYSCALL 591 CMPQ AX, $0xfffffffffffff001 592 JLS 2(PC) 593 MOVL $0xf1, 0xf1 // crash 594 RET 595 596 // set tls base to DI 597 TEXT runtimesettls(SB),NOSPLIT,$32 598 #ifdef GOOS_android 599 // Same as in sys_darwin_386.s:/ugliness, different constant. 600 // DI currently holds m->tls, which must be fs:0x1d0. 601 // See cgo/gcc_android_amd64.c for the derivation of the constant. 602 SUBQ $0x1d0, DI // In android, the tls base 603 #else 604 ADDQ $8, DI // ELF wants to use -8(FS) 605 #endif 606 MOVQ DI, SI 607 MOVQ $0x1002, DI // ARCH_SET_FS 608 MOVQ $SYS_arch_prctl, AX 609 SYSCALL 610 CMPQ AX, $0xfffffffffffff001 611 JLS 2(PC) 612 MOVL $0xf1, 0xf1 // crash 613 RET 614 615 TEXT runtimeosyield(SB),NOSPLIT,$0 616 MOVL $SYS_sched_yield, AX 617 SYSCALL 618 RET 619 620 TEXT runtimesched_getaffinity(SB),NOSPLIT,$0 621 MOVQ pid+0(FP), DI 622 MOVQ len+8(FP), SI 623 MOVQ buf+16(FP), DX 624 MOVL $SYS_sched_getaffinity, AX 625 SYSCALL 626 MOVL AX, ret+24(FP) 627 RET 628 629 // int32 runtimeepollcreate(int32 size); 630 TEXT runtimeepollcreate(SB),NOSPLIT,$0 631 MOVL size+0(FP), DI 632 MOVL $SYS_epoll_create, AX 633 SYSCALL 634 MOVL AX, ret+8(FP) 635 RET 636 637 // int32 runtimeepollcreate1(int32 flags); 638 TEXT runtimeepollcreate1(SB),NOSPLIT,$0 639 MOVL flags+0(FP), DI 640 MOVL $SYS_epoll_create1, AX 641 SYSCALL 642 MOVL AX, ret+8(FP) 643 RET 644 645 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 646 TEXT runtimeepollctl(SB),NOSPLIT,$0 647 MOVL epfd+0(FP), DI 648 MOVL op+4(FP), SI 649 MOVL fd+8(FP), DX 650 MOVQ ev+16(FP), R10 651 MOVL $SYS_epoll_ctl, AX 652 SYSCALL 653 MOVL AX, ret+24(FP) 654 RET 655 656 // int32 runtimeepollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 657 TEXT runtimeepollwait(SB),NOSPLIT,$0 658 MOVL epfd+0(FP), DI 659 MOVQ ev+8(FP), SI 660 MOVL nev+16(FP), DX 661 MOVL timeout+20(FP), R10 662 MOVL $SYS_epoll_wait, AX 663 SYSCALL 664 MOVL AX, ret+24(FP) 665 RET 666 667 // void runtimecloseonexec(int32 fd); 668 TEXT runtimecloseonexec(SB),NOSPLIT,$0 669 MOVL fd+0(FP), DI // fd 670 MOVQ $2, SI // F_SETFD 671 MOVQ $1, DX // FD_CLOEXEC 672 MOVL $SYS_fcntl, AX 673 SYSCALL 674 RET 675 676 677 // int access(const char *name, int mode) 678 TEXT runtimeaccess(SB),NOSPLIT,$0 679 MOVQ name+0(FP), DI 680 MOVL mode+8(FP), SI 681 MOVL $SYS_access, AX 682 SYSCALL 683 MOVL AX, ret+16(FP) 684 RET 685 686 // int connect(int fd, const struct sockaddr *addr, socklen_t addrlen) 687 TEXT runtimeconnect(SB),NOSPLIT,$0-28 688 MOVL fd+0(FP), DI 689 MOVQ addr+8(FP), SI 690 MOVL len+16(FP), DX 691 MOVL $SYS_connect, AX 692 SYSCALL 693 MOVL AX, ret+24(FP) 694 RET 695 696 // int socket(int domain, int type, int protocol) 697 TEXT runtimesocket(SB),NOSPLIT,$0-20 698 MOVL domain+0(FP), DI 699 MOVL typ+4(FP), SI 700 MOVL prot+8(FP), DX 701 MOVL $SYS_socket, AX 702 SYSCALL 703 MOVL AX, ret+16(FP) 704 RET 705 706 // func sbrk0() uintptr 707 TEXT runtimesbrk0(SB),NOSPLIT,$0-8 708 // Implemented as brk(NULL). 709 MOVQ $0, DI 710 MOVL $SYS_brk, AX 711 SYSCALL 712 MOVQ AX, ret+0(FP) 713 RET 714