github.com/stingnevermore/go@v0.0.0-20180120041312-3810f5bfed72/src/runtime/sys_darwin_amd64.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 AMD64, Darwin 7 // See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228 8 // or /usr/include/sys/syscall.h (on a Mac) for system call numbers. 9 // 10 // The low 24 bits are the system call number. 11 // The high 8 bits specify the kind of system call: 1=Mach, 2=BSD, 3=Machine-Dependent. 12 // 13 14 #include "go_asm.h" 15 #include "go_tls.h" 16 #include "textflag.h" 17 18 // Exit the entire program (like C exit) 19 TEXT runtime·exit(SB),NOSPLIT,$0 20 MOVL code+0(FP), DI // arg 1 exit status 21 MOVL $(0x2000000+1), AX // syscall entry 22 SYSCALL 23 MOVL $0xf1, 0xf1 // crash 24 RET 25 26 // Exit this OS thread (like pthread_exit, which eventually 27 // calls __bsdthread_terminate). 28 TEXT exit1<>(SB),NOSPLIT,$0 29 // Because of exitThread below, this must not use the stack. 30 // __bsdthread_terminate takes 4 word-size arguments. 31 // Set them all to 0. (None are an exit status.) 32 MOVL $0, DI 33 MOVL $0, SI 34 MOVL $0, DX 35 MOVL $0, R10 36 MOVL $(0x2000000+361), AX // syscall entry 37 SYSCALL 38 MOVL $0xf1, 0xf1 // crash 39 RET 40 41 // func exitThread(wait *uint32) 42 TEXT runtime·exitThread(SB),NOSPLIT,$0-8 43 MOVQ wait+0(FP), AX 44 // We're done using the stack. 45 MOVL $0, (AX) 46 JMP exit1<>(SB) 47 48 TEXT runtime·open(SB),NOSPLIT,$0 49 MOVQ name+0(FP), DI // arg 1 pathname 50 MOVL mode+8(FP), SI // arg 2 flags 51 MOVL perm+12(FP), DX // arg 3 mode 52 MOVL $(0x2000000+5), AX // syscall entry 53 SYSCALL 54 JCC 2(PC) 55 MOVL $-1, AX 56 MOVL AX, ret+16(FP) 57 RET 58 59 TEXT runtime·closefd(SB),NOSPLIT,$0 60 MOVL fd+0(FP), DI // arg 1 fd 61 MOVL $(0x2000000+6), AX // syscall entry 62 SYSCALL 63 JCC 2(PC) 64 MOVL $-1, AX 65 MOVL AX, ret+8(FP) 66 RET 67 68 TEXT runtime·read(SB),NOSPLIT,$0 69 MOVL fd+0(FP), DI // arg 1 fd 70 MOVQ p+8(FP), SI // arg 2 buf 71 MOVL n+16(FP), DX // arg 3 count 72 MOVL $(0x2000000+3), AX // syscall entry 73 SYSCALL 74 JCC 2(PC) 75 MOVL $-1, AX 76 MOVL AX, ret+24(FP) 77 RET 78 79 TEXT runtime·write(SB),NOSPLIT,$0 80 MOVQ fd+0(FP), DI // arg 1 fd 81 MOVQ p+8(FP), SI // arg 2 buf 82 MOVL n+16(FP), DX // arg 3 count 83 MOVL $(0x2000000+4), AX // syscall entry 84 SYSCALL 85 JCC 2(PC) 86 MOVL $-1, AX 87 MOVL AX, ret+24(FP) 88 RET 89 90 TEXT runtime·raise(SB),NOSPLIT,$0 91 // Ideally we'd send the signal to the current thread, 92 // not the whole process, but that's too hard on OS X. 93 JMP runtime·raiseproc(SB) 94 95 TEXT runtime·raiseproc(SB),NOSPLIT,$24 96 MOVL $(0x2000000+20), AX // getpid 97 SYSCALL 98 MOVQ AX, DI // arg 1 - pid 99 MOVL sig+0(FP), SI // arg 2 - signal 100 MOVL $1, DX // arg 3 - posix 101 MOVL $(0x2000000+37), AX // kill 102 SYSCALL 103 RET 104 105 TEXT runtime·setitimer(SB), NOSPLIT, $0 106 MOVL mode+0(FP), DI 107 MOVQ new+8(FP), SI 108 MOVQ old+16(FP), DX 109 MOVL $(0x2000000+83), AX // syscall entry 110 SYSCALL 111 RET 112 113 TEXT runtime·madvise(SB), NOSPLIT, $0 114 MOVQ addr+0(FP), DI // arg 1 addr 115 MOVQ n+8(FP), SI // arg 2 len 116 MOVL flags+16(FP), DX // arg 3 advice 117 MOVL $(0x2000000+75), AX // syscall entry madvise 118 SYSCALL 119 // ignore failure - maybe pages are locked 120 RET 121 122 // OS X comm page time offsets 123 // https://opensource.apple.com/source/xnu/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h 124 125 #define nt_tsc_base 0x50 126 #define nt_scale 0x58 127 #define nt_shift 0x5c 128 #define nt_ns_base 0x60 129 #define nt_generation 0x68 130 #define gtod_generation 0x6c // obsolete since Darwin v17 (High Sierra) 131 #define gtod_ns_base 0x70 // obsolete since Darwin v17 (High Sierra) 132 #define gtod_sec_base 0x78 // obsolete since Darwin v17 (High Sierra) 133 134 #define v17_gtod_ns_base 0xd0 135 #define v17_gtod_sec_ofs 0xd8 136 #define v17_gtod_frac_ofs 0xe0 137 #define v17_gtod_scale 0xe8 138 #define v17_gtod_tkspersec 0xf0 139 140 TEXT runtime·nanotime(SB),NOSPLIT,$0-8 141 MOVQ $0x7fffffe00000, BP /* comm page base */ 142 // Loop trying to take a consistent snapshot 143 // of the time parameters. 144 timeloop: 145 MOVL nt_generation(BP), R9 146 TESTL R9, R9 147 JZ timeloop 148 RDTSC 149 MOVQ nt_tsc_base(BP), R10 150 MOVL nt_scale(BP), R11 151 MOVQ nt_ns_base(BP), R12 152 CMPL nt_generation(BP), R9 153 JNE timeloop 154 155 // Gathered all the data we need. Compute monotonic time: 156 // ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base 157 // The multiply and shift extracts the top 64 bits of the 96-bit product. 158 SHLQ $32, DX 159 ADDQ DX, AX 160 SUBQ R10, AX 161 MULQ R11 162 SHRQ $32, AX:DX 163 ADDQ R12, AX 164 MOVQ runtime·startNano(SB), CX 165 SUBQ CX, AX 166 MOVQ AX, ret+0(FP) 167 RET 168 169 TEXT time·now(SB), NOSPLIT, $32-24 170 // Note: The 32 bytes of stack frame requested on the TEXT line 171 // are used in the systime fallback, as the timeval address 172 // filled in by the system call. 173 MOVQ $0x7fffffe00000, BP /* comm page base */ 174 CMPQ runtime·darwinVersion(SB), $17 175 JB legacy /* sierra and older */ 176 177 // This is the new code, for macOS High Sierra (Darwin v17) and newer. 178 v17: 179 // Loop trying to take a consistent snapshot 180 // of the time parameters. 181 timeloop17: 182 MOVQ v17_gtod_ns_base(BP), R12 183 184 MOVL nt_generation(BP), CX 185 TESTL CX, CX 186 JZ timeloop17 187 RDTSC 188 MOVQ nt_tsc_base(BP), SI 189 MOVL nt_scale(BP), DI 190 MOVQ nt_ns_base(BP), BX 191 CMPL nt_generation(BP), CX 192 JNE timeloop17 193 194 MOVQ v17_gtod_sec_ofs(BP), R8 195 MOVQ v17_gtod_frac_ofs(BP), R9 196 MOVQ v17_gtod_scale(BP), R10 197 MOVQ v17_gtod_tkspersec(BP), R11 198 CMPQ v17_gtod_ns_base(BP), R12 199 JNE timeloop17 200 201 // Compute monotonic time 202 // mono = ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base 203 // The multiply and shift extracts the top 64 bits of the 96-bit product. 204 SHLQ $32, DX 205 ADDQ DX, AX 206 SUBQ SI, AX 207 MULQ DI 208 SHRQ $32, AX:DX 209 ADDQ BX, AX 210 211 // Subtract startNano base to return the monotonic runtime timer 212 // which is an offset from process boot. 213 MOVQ AX, BX 214 MOVQ runtime·startNano(SB), CX 215 SUBQ CX, BX 216 MOVQ BX, monotonic+16(FP) 217 218 // Now compute the 128-bit wall time: 219 // wall = ((mono - gtod_ns_base) * gtod_scale) + gtod_offs 220 // The parameters are updated every second, so if we found them 221 // outdated (that is, more than one second is passed from the ns base), 222 // fallback to the syscall. 223 TESTQ R12, R12 224 JZ systime 225 SUBQ R12, AX 226 CMPQ R11, AX 227 JB systime 228 MULQ R10 229 ADDQ R9, AX 230 ADCQ R8, DX 231 232 // Convert the 128-bit wall time into (sec,nsec). 233 // High part (seconds) is already good to go, while low part 234 // (fraction of seconds) must be converted to nanoseconds. 235 MOVQ DX, sec+0(FP) 236 MOVQ $1000000000, CX 237 MULQ CX 238 MOVQ DX, nsec+8(FP) 239 RET 240 241 // This is the legacy code needed for macOS Sierra (Darwin v16) and older. 242 legacy: 243 // Loop trying to take a consistent snapshot 244 // of the time parameters. 245 timeloop: 246 MOVL gtod_generation(BP), R8 247 MOVL nt_generation(BP), R9 248 TESTL R9, R9 249 JZ timeloop 250 RDTSC 251 MOVQ nt_tsc_base(BP), R10 252 MOVL nt_scale(BP), R11 253 MOVQ nt_ns_base(BP), R12 254 CMPL nt_generation(BP), R9 255 JNE timeloop 256 MOVQ gtod_ns_base(BP), R13 257 MOVQ gtod_sec_base(BP), R14 258 CMPL gtod_generation(BP), R8 259 JNE timeloop 260 261 // Gathered all the data we need. Compute: 262 // monotonic_time = ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base 263 // The multiply and shift extracts the top 64 bits of the 96-bit product. 264 SHLQ $32, DX 265 ADDQ DX, AX 266 SUBQ R10, AX 267 MULQ R11 268 SHRQ $32, AX:DX 269 ADDQ R12, AX 270 MOVQ AX, BX 271 MOVQ runtime·startNano(SB), CX 272 SUBQ CX, BX 273 MOVQ BX, monotonic+16(FP) 274 275 // Compute: 276 // wall_time = monotonic time - gtod_ns_base + gtod_sec_base*1e9 277 // or, if gtod_generation==0, invoke the system call. 278 TESTL R8, R8 279 JZ systime 280 SUBQ R13, AX 281 IMULQ $1000000000, R14 282 ADDQ R14, AX 283 284 // Split wall time into sec, nsec. 285 // generated code for 286 // func f(x uint64) (uint64, uint64) { return x/1e9, x%1e9 } 287 // adapted to reduce duplication 288 MOVQ AX, CX 289 SHRQ $9, AX 290 MOVQ $19342813113834067, DX 291 MULQ DX 292 SHRQ $11, DX 293 MOVQ DX, sec+0(FP) 294 IMULQ $1000000000, DX 295 SUBQ DX, CX 296 MOVL CX, nsec+8(FP) 297 RET 298 299 systime: 300 // Fall back to system call (usually first call in this thread). 301 MOVQ SP, DI 302 MOVQ $0, SI 303 MOVQ $0, DX // required as of Sierra; Issue 16570 304 MOVL $(0x2000000+116), AX // gettimeofday 305 SYSCALL 306 CMPQ AX, $0 307 JNE inreg 308 MOVQ 0(SP), AX 309 MOVL 8(SP), DX 310 inreg: 311 // sec is in AX, usec in DX 312 IMULQ $1000, DX 313 MOVQ AX, sec+0(FP) 314 MOVL DX, nsec+8(FP) 315 RET 316 317 TEXT runtime·sigprocmask(SB),NOSPLIT,$0 318 MOVL how+0(FP), DI 319 MOVQ new+8(FP), SI 320 MOVQ old+16(FP), DX 321 MOVL $(0x2000000+329), AX // pthread_sigmask (on OS X, sigprocmask==entire process) 322 SYSCALL 323 JCC 2(PC) 324 MOVL $0xf1, 0xf1 // crash 325 RET 326 327 TEXT runtime·sigaction(SB),NOSPLIT,$0-24 328 MOVL mode+0(FP), DI // arg 1 sig 329 MOVQ new+8(FP), SI // arg 2 act 330 MOVQ old+16(FP), DX // arg 3 oact 331 MOVQ old+16(FP), CX // arg 3 oact 332 MOVQ old+16(FP), R10 // arg 3 oact 333 MOVL $(0x2000000+46), AX // syscall entry 334 SYSCALL 335 JCC 2(PC) 336 MOVL $0xf1, 0xf1 // crash 337 RET 338 339 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 340 MOVQ fn+0(FP), AX 341 MOVL sig+8(FP), DI 342 MOVQ info+16(FP), SI 343 MOVQ ctx+24(FP), DX 344 PUSHQ BP 345 MOVQ SP, BP 346 ANDQ $~15, SP // alignment for x86_64 ABI 347 CALL AX 348 MOVQ BP, SP 349 POPQ BP 350 RET 351 352 TEXT runtime·sigtramp(SB),NOSPLIT,$40 353 MOVL SI, 24(SP) // save infostyle for sigreturn below 354 MOVQ R8, 32(SP) // save ctx 355 MOVL DX, 0(SP) // sig 356 MOVQ CX, 8(SP) // info 357 MOVQ R8, 16(SP) // ctx 358 MOVQ $runtime·sigtrampgo(SB), AX 359 CALL AX 360 MOVQ 32(SP), DI // ctx 361 MOVL 24(SP), SI // infostyle 362 MOVL $(0x2000000+184), AX 363 SYSCALL 364 INT $3 // not reached 365 366 TEXT runtime·mmap(SB),NOSPLIT,$0 367 MOVQ addr+0(FP), DI // arg 1 addr 368 MOVQ n+8(FP), SI // arg 2 len 369 MOVL prot+16(FP), DX // arg 3 prot 370 MOVL flags+20(FP), R10 // arg 4 flags 371 MOVL fd+24(FP), R8 // arg 5 fid 372 MOVL off+28(FP), R9 // arg 6 offset 373 MOVL $(0x2000000+197), AX // syscall entry 374 SYSCALL 375 JCC ok 376 MOVQ $0, p+32(FP) 377 MOVQ AX, err+40(FP) 378 RET 379 ok: 380 MOVQ AX, p+32(FP) 381 MOVQ $0, err+40(FP) 382 RET 383 384 TEXT runtime·munmap(SB),NOSPLIT,$0 385 MOVQ addr+0(FP), DI // arg 1 addr 386 MOVQ n+8(FP), SI // arg 2 len 387 MOVL $(0x2000000+73), AX // syscall entry 388 SYSCALL 389 JCC 2(PC) 390 MOVL $0xf1, 0xf1 // crash 391 RET 392 393 TEXT runtime·sigaltstack(SB),NOSPLIT,$0 394 MOVQ new+0(FP), DI 395 MOVQ old+8(FP), SI 396 MOVQ $(0x2000000+53), AX 397 SYSCALL 398 JCC 2(PC) 399 MOVL $0xf1, 0xf1 // crash 400 RET 401 402 TEXT runtime·usleep(SB),NOSPLIT,$16 403 MOVL $0, DX 404 MOVL usec+0(FP), AX 405 MOVL $1000000, CX 406 DIVL CX 407 MOVQ AX, 0(SP) // sec 408 MOVL DX, 8(SP) // usec 409 410 // select(0, 0, 0, 0, &tv) 411 MOVL $0, DI 412 MOVL $0, SI 413 MOVL $0, DX 414 MOVL $0, R10 415 MOVQ SP, R8 416 MOVL $(0x2000000+93), AX 417 SYSCALL 418 RET 419 420 // func bsdthread_create(stk, arg unsafe.Pointer, fn uintptr) int32 421 TEXT runtime·bsdthread_create(SB),NOSPLIT,$0 422 // Set up arguments to bsdthread_create system call. 423 // The ones in quotes pass through to the thread callback 424 // uninterpreted, so we can put whatever we want there. 425 MOVQ fn+16(FP), DI 426 MOVQ arg+8(FP), SI 427 MOVQ stk+0(FP), DX 428 MOVQ $0x01000000, R8 // flags = PTHREAD_START_CUSTOM 429 MOVQ $0, R9 // paranoia 430 MOVQ $0, R10 // paranoia, "pthread" 431 MOVQ $(0x2000000+360), AX // bsdthread_create 432 SYSCALL 433 JCC 4(PC) 434 NEGQ AX 435 MOVL AX, ret+24(FP) 436 RET 437 MOVL $0, AX 438 MOVL AX, ret+24(FP) 439 RET 440 441 // The thread that bsdthread_create creates starts executing here, 442 // because we registered this function using bsdthread_register 443 // at startup. 444 // DI = "pthread" 445 // SI = mach thread port 446 // DX = "func" (= fn) 447 // CX = "arg" (= m) 448 // R8 = stack 449 // R9 = flags (= 0) 450 // SP = stack - C_64_REDZONE_LEN (= stack - 128) 451 TEXT runtime·bsdthread_start(SB),NOSPLIT,$0 452 MOVQ R8, SP // empirically, SP is very wrong but R8 is right 453 454 PUSHQ DX 455 PUSHQ CX 456 PUSHQ SI 457 458 // set up thread local storage pointing at m->tls. 459 LEAQ m_tls(CX), DI 460 CALL runtime·settls(SB) 461 462 POPQ SI 463 POPQ CX 464 POPQ DX 465 466 get_tls(BX) 467 MOVQ SI, m_procid(CX) // thread port is m->procid 468 MOVQ m_g0(CX), AX 469 MOVQ AX, g(BX) 470 MOVQ CX, g_m(AX) 471 CALL runtime·stackcheck(SB) // smashes AX, CX 472 CALL DX // fn 473 CALL exit1<>(SB) 474 RET 475 476 // func bsdthread_register() int32 477 // registers callbacks for threadstart (see bsdthread_create above 478 // and wqthread and pthsize (not used). returns 0 on success. 479 TEXT runtime·bsdthread_register(SB),NOSPLIT,$0 480 MOVQ $runtime·bsdthread_start(SB), DI // threadstart 481 MOVQ $0, SI // wqthread, not used by us 482 MOVQ $0, DX // pthsize, not used by us 483 MOVQ $0, R10 // dummy_value [sic] 484 MOVQ $0, R8 // targetconc_ptr 485 MOVQ $0, R9 // dispatchqueue_offset 486 MOVQ $(0x2000000+366), AX // bsdthread_register 487 SYSCALL 488 JCC 4(PC) 489 NEGQ AX 490 MOVL AX, ret+0(FP) 491 RET 492 MOVL $0, AX 493 MOVL AX, ret+0(FP) 494 RET 495 496 // Mach system calls use 0x1000000 instead of the BSD's 0x2000000. 497 498 // func mach_msg_trap(h unsafe.Pointer, op int32, send_size, rcv_size, rcv_name, timeout, notify uint32) int32 499 TEXT runtime·mach_msg_trap(SB),NOSPLIT,$0 500 MOVQ h+0(FP), DI 501 MOVL op+8(FP), SI 502 MOVL send_size+12(FP), DX 503 MOVL rcv_size+16(FP), R10 504 MOVL rcv_name+20(FP), R8 505 MOVL timeout+24(FP), R9 506 MOVL notify+28(FP), R11 507 PUSHQ R11 // seventh arg, on stack 508 MOVL $(0x1000000+31), AX // mach_msg_trap 509 SYSCALL 510 POPQ R11 511 MOVL AX, ret+32(FP) 512 RET 513 514 TEXT runtime·mach_task_self(SB),NOSPLIT,$0 515 MOVL $(0x1000000+28), AX // task_self_trap 516 SYSCALL 517 MOVL AX, ret+0(FP) 518 RET 519 520 TEXT runtime·mach_thread_self(SB),NOSPLIT,$0 521 MOVL $(0x1000000+27), AX // thread_self_trap 522 SYSCALL 523 MOVL AX, ret+0(FP) 524 RET 525 526 TEXT runtime·mach_reply_port(SB),NOSPLIT,$0 527 MOVL $(0x1000000+26), AX // mach_reply_port 528 SYSCALL 529 MOVL AX, ret+0(FP) 530 RET 531 532 // Mach provides trap versions of the semaphore ops, 533 // instead of requiring the use of RPC. 534 535 // func mach_semaphore_wait(sema uint32) int32 536 TEXT runtime·mach_semaphore_wait(SB),NOSPLIT,$0 537 MOVL sema+0(FP), DI 538 MOVL $(0x1000000+36), AX // semaphore_wait_trap 539 SYSCALL 540 MOVL AX, ret+8(FP) 541 RET 542 543 // func mach_semaphore_timedwait(sema, sec, nsec uint32) int32 544 TEXT runtime·mach_semaphore_timedwait(SB),NOSPLIT,$0 545 MOVL sema+0(FP), DI 546 MOVL sec+4(FP), SI 547 MOVL nsec+8(FP), DX 548 MOVL $(0x1000000+38), AX // semaphore_timedwait_trap 549 SYSCALL 550 MOVL AX, ret+16(FP) 551 RET 552 553 // func mach_semaphore_signal(sema uint32) int32 554 TEXT runtime·mach_semaphore_signal(SB),NOSPLIT,$0 555 MOVL sema+0(FP), DI 556 MOVL $(0x1000000+33), AX // semaphore_signal_trap 557 SYSCALL 558 MOVL AX, ret+8(FP) 559 RET 560 561 // func mach_semaphore_signal_all(sema uint32) int32 562 TEXT runtime·mach_semaphore_signal_all(SB),NOSPLIT,$0 563 MOVL sema+0(FP), DI 564 MOVL $(0x1000000+34), AX // semaphore_signal_all_trap 565 SYSCALL 566 MOVL AX, ret+8(FP) 567 RET 568 569 // set tls base to DI 570 TEXT runtime·settls(SB),NOSPLIT,$32 571 /* 572 * Same as in sys_darwin_386.s:/ugliness, different constant. 573 * See cgo/gcc_darwin_amd64.c for the derivation 574 * of the constant. 575 */ 576 SUBQ $0x8a0, DI 577 578 MOVL $(0x3000000+3), AX // thread_fast_set_cthread_self - machdep call #3 579 SYSCALL 580 RET 581 582 TEXT runtime·sysctl(SB),NOSPLIT,$0 583 MOVQ mib+0(FP), DI 584 MOVL miblen+8(FP), SI 585 MOVQ out+16(FP), DX 586 MOVQ size+24(FP), R10 587 MOVQ dst+32(FP), R8 588 MOVQ ndst+40(FP), R9 589 MOVL $(0x2000000+202), AX // syscall entry 590 SYSCALL 591 JCC 4(PC) 592 NEGQ AX 593 MOVL AX, ret+48(FP) 594 RET 595 MOVL $0, AX 596 MOVL AX, ret+48(FP) 597 RET 598 599 // func kqueue() int32 600 TEXT runtime·kqueue(SB),NOSPLIT,$0 601 MOVQ $0, DI 602 MOVQ $0, SI 603 MOVQ $0, DX 604 MOVL $(0x2000000+362), AX 605 SYSCALL 606 JCC 2(PC) 607 NEGQ AX 608 MOVL AX, ret+0(FP) 609 RET 610 611 // func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 612 TEXT runtime·kevent(SB),NOSPLIT,$0 613 MOVL kq+0(FP), DI 614 MOVQ ch+8(FP), SI 615 MOVL nch+16(FP), DX 616 MOVQ ev+24(FP), R10 617 MOVL nev+32(FP), R8 618 MOVQ ts+40(FP), R9 619 MOVL $(0x2000000+363), AX 620 SYSCALL 621 JCC 2(PC) 622 NEGQ AX 623 MOVL AX, ret+48(FP) 624 RET 625 626 // func closeonexec(fd int32) 627 TEXT runtime·closeonexec(SB),NOSPLIT,$0 628 MOVL fd+0(FP), DI // fd 629 MOVQ $2, SI // F_SETFD 630 MOVQ $1, DX // FD_CLOEXEC 631 MOVL $(0x2000000+92), AX // fcntl 632 SYSCALL 633 RET