github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/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 // System calls and other sys.stuff for AMD64, Darwin 6 // System calls are implemented in libSystem, this file contains 7 // trampolines that convert from Go to C calling convention. 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 // Exit the entire program (like C exit) 14 TEXT runtime·exit_trampoline(SB),NOSPLIT,$0 15 PUSHQ BP 16 MOVQ SP, BP 17 MOVL 0(DI), DI // arg 1 exit status 18 CALL libc_exit(SB) 19 MOVL $0xf1, 0xf1 // crash 20 POPQ BP 21 RET 22 23 TEXT runtime·open_trampoline(SB),NOSPLIT,$0 24 PUSHQ BP 25 MOVQ SP, BP 26 MOVL 8(DI), SI // arg 2 flags 27 MOVL 12(DI), DX // arg 3 mode 28 MOVQ 0(DI), DI // arg 1 pathname 29 CALL libc_open(SB) 30 POPQ BP 31 RET 32 33 TEXT runtime·close_trampoline(SB),NOSPLIT,$0 34 PUSHQ BP 35 MOVQ SP, BP 36 MOVL 0(DI), DI // arg 1 fd 37 CALL libc_close(SB) 38 POPQ BP 39 RET 40 41 TEXT runtime·read_trampoline(SB),NOSPLIT,$0 42 PUSHQ BP 43 MOVQ SP, BP 44 MOVQ 8(DI), SI // arg 2 buf 45 MOVL 16(DI), DX // arg 3 count 46 MOVL 0(DI), DI // arg 1 fd 47 CALL libc_read(SB) 48 POPQ BP 49 RET 50 51 TEXT runtime·write_trampoline(SB),NOSPLIT,$0 52 PUSHQ BP 53 MOVQ SP, BP 54 MOVQ 8(DI), SI // arg 2 buf 55 MOVL 16(DI), DX // arg 3 count 56 MOVQ 0(DI), DI // arg 1 fd 57 CALL libc_write(SB) 58 POPQ BP 59 RET 60 61 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0 62 PUSHQ BP 63 MOVQ SP, BP 64 MOVQ 8(DI), SI // arg 2 new 65 MOVQ 16(DI), DX // arg 3 old 66 MOVL 0(DI), DI // arg 1 which 67 CALL libc_setitimer(SB) 68 POPQ BP 69 RET 70 71 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0 72 PUSHQ BP 73 MOVQ SP, BP 74 MOVQ 8(DI), SI // arg 2 len 75 MOVL 16(DI), DX // arg 3 advice 76 MOVQ 0(DI), DI // arg 1 addr 77 CALL libc_madvise(SB) 78 // ignore failure - maybe pages are locked 79 POPQ BP 80 RET 81 82 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size) 83 84 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0 85 PUSHQ BP 86 MOVQ SP, BP 87 MOVQ DI, BX 88 CALL libc_mach_absolute_time(SB) 89 MOVQ AX, 0(BX) 90 MOVL timebase<>+machTimebaseInfo_numer(SB), SI 91 MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read 92 TESTL DI, DI 93 JNE initialized 94 95 SUBQ $(machTimebaseInfo__size+15)/16*16, SP 96 MOVQ SP, DI 97 CALL libc_mach_timebase_info(SB) 98 MOVL machTimebaseInfo_numer(SP), SI 99 MOVL machTimebaseInfo_denom(SP), DI 100 ADDQ $(machTimebaseInfo__size+15)/16*16, SP 101 102 MOVL SI, timebase<>+machTimebaseInfo_numer(SB) 103 MOVL DI, AX 104 XCHGL AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write 105 106 initialized: 107 MOVL SI, 8(BX) 108 MOVL DI, 12(BX) 109 MOVQ BP, SP 110 POPQ BP 111 RET 112 113 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0 114 PUSHQ BP // make a frame; keep stack aligned 115 MOVQ SP, BP 116 // DI already has *timeval 117 XORL SI, SI // no timezone needed 118 CALL libc_gettimeofday(SB) 119 POPQ BP 120 RET 121 122 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 123 PUSHQ BP 124 MOVQ SP, BP 125 MOVQ 8(DI), SI // arg 2 new 126 MOVQ 16(DI), DX // arg 3 old 127 MOVL 0(DI), DI // arg 1 sig 128 CALL libc_sigaction(SB) 129 TESTL AX, AX 130 JEQ 2(PC) 131 MOVL $0xf1, 0xf1 // crash 132 POPQ BP 133 RET 134 135 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 136 PUSHQ BP 137 MOVQ SP, BP 138 MOVQ 8(DI), SI // arg 2 new 139 MOVQ 16(DI), DX // arg 3 old 140 MOVL 0(DI), DI // arg 1 how 141 CALL libc_pthread_sigmask(SB) 142 TESTL AX, AX 143 JEQ 2(PC) 144 MOVL $0xf1, 0xf1 // crash 145 POPQ BP 146 RET 147 148 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 149 PUSHQ BP 150 MOVQ SP, BP 151 MOVQ 8(DI), SI // arg 2 old 152 MOVQ 0(DI), DI // arg 1 new 153 CALL libc_sigaltstack(SB) 154 TESTQ AX, AX 155 JEQ 2(PC) 156 MOVL $0xf1, 0xf1 // crash 157 POPQ BP 158 RET 159 160 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 161 PUSHQ BP 162 MOVQ SP, BP 163 MOVL 0(DI), BX // signal 164 CALL libc_getpid(SB) 165 MOVL AX, DI // arg 1 pid 166 MOVL BX, SI // arg 2 signal 167 CALL libc_kill(SB) 168 POPQ BP 169 RET 170 171 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 172 MOVQ fn+0(FP), AX 173 MOVL sig+8(FP), DI 174 MOVQ info+16(FP), SI 175 MOVQ ctx+24(FP), DX 176 PUSHQ BP 177 MOVQ SP, BP 178 ANDQ $~15, SP // alignment for x86_64 ABI 179 CALL AX 180 MOVQ BP, SP 181 POPQ BP 182 RET 183 184 // This is the function registered during sigaction and is invoked when 185 // a signal is received. It just redirects to the Go function sigtrampgo. 186 TEXT runtime·sigtramp(SB),NOSPLIT,$0 187 // This runs on the signal stack, so we have lots of stack available. 188 // We allocate our own stack space, because if we tell the linker 189 // how much we're using, the NOSPLIT check fails. 190 PUSHQ BP 191 MOVQ SP, BP 192 SUBQ $64, SP 193 194 // Save callee-save registers. 195 MOVQ BX, 24(SP) 196 MOVQ R12, 32(SP) 197 MOVQ R13, 40(SP) 198 MOVQ R14, 48(SP) 199 MOVQ R15, 56(SP) 200 201 // Call into the Go signal handler 202 MOVL DI, 0(SP) // sig 203 MOVQ SI, 8(SP) // info 204 MOVQ DX, 16(SP) // ctx 205 CALL runtime·sigtrampgo(SB) 206 207 // Restore callee-save registers. 208 MOVQ 24(SP), BX 209 MOVQ 32(SP), R12 210 MOVQ 40(SP), R13 211 MOVQ 48(SP), R14 212 MOVQ 56(SP), R15 213 214 MOVQ BP, SP 215 POPQ BP 216 RET 217 218 // Used instead of sigtramp in programs that use cgo. 219 // Arguments from kernel are in DI, SI, DX. 220 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 221 // If no traceback function, do usual sigtramp. 222 MOVQ runtime·cgoTraceback(SB), AX 223 TESTQ AX, AX 224 JZ sigtramp 225 226 // If no traceback support function, which means that 227 // runtime/cgo was not linked in, do usual sigtramp. 228 MOVQ _cgo_callers(SB), AX 229 TESTQ AX, AX 230 JZ sigtramp 231 232 // Figure out if we are currently in a cgo call. 233 // If not, just do usual sigtramp. 234 get_tls(CX) 235 MOVQ g(CX),AX 236 TESTQ AX, AX 237 JZ sigtrampnog // g == nil 238 MOVQ g_m(AX), AX 239 TESTQ AX, AX 240 JZ sigtramp // g.m == nil 241 MOVL m_ncgo(AX), CX 242 TESTL CX, CX 243 JZ sigtramp // g.m.ncgo == 0 244 MOVQ m_curg(AX), CX 245 TESTQ CX, CX 246 JZ sigtramp // g.m.curg == nil 247 MOVQ g_syscallsp(CX), CX 248 TESTQ CX, CX 249 JZ sigtramp // g.m.curg.syscallsp == 0 250 MOVQ m_cgoCallers(AX), R8 251 TESTQ R8, R8 252 JZ sigtramp // g.m.cgoCallers == nil 253 MOVL m_cgoCallersUse(AX), CX 254 TESTL CX, CX 255 JNZ sigtramp // g.m.cgoCallersUse != 0 256 257 // Jump to a function in runtime/cgo. 258 // That function, written in C, will call the user's traceback 259 // function with proper unwind info, and will then call back here. 260 // The first three arguments, and the fifth, are already in registers. 261 // Set the two remaining arguments now. 262 MOVQ runtime·cgoTraceback(SB), CX 263 MOVQ $runtime·sigtramp(SB), R9 264 MOVQ _cgo_callers(SB), AX 265 JMP AX 266 267 sigtramp: 268 JMP runtime·sigtramp(SB) 269 270 sigtrampnog: 271 // Signal arrived on a non-Go thread. If this is SIGPROF, get a 272 // stack trace. 273 CMPL DI, $27 // 27 == SIGPROF 274 JNZ sigtramp 275 276 // Lock sigprofCallersUse. 277 MOVL $0, AX 278 MOVL $1, CX 279 MOVQ $runtime·sigprofCallersUse(SB), R11 280 LOCK 281 CMPXCHGL CX, 0(R11) 282 JNZ sigtramp // Skip stack trace if already locked. 283 284 // Jump to the traceback function in runtime/cgo. 285 // It will call back to sigprofNonGo, which will ignore the 286 // arguments passed in registers. 287 // First three arguments to traceback function are in registers already. 288 MOVQ runtime·cgoTraceback(SB), CX 289 MOVQ $runtime·sigprofCallers(SB), R8 290 MOVQ $runtime·sigprofNonGo(SB), R9 291 MOVQ _cgo_callers(SB), AX 292 JMP AX 293 294 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 295 PUSHQ BP // make a frame; keep stack aligned 296 MOVQ SP, BP 297 MOVQ DI, BX 298 MOVQ 0(BX), DI // arg 1 addr 299 MOVQ 8(BX), SI // arg 2 len 300 MOVL 16(BX), DX // arg 3 prot 301 MOVL 20(BX), CX // arg 4 flags 302 MOVL 24(BX), R8 // arg 5 fid 303 MOVL 28(BX), R9 // arg 6 offset 304 CALL libc_mmap(SB) 305 XORL DX, DX 306 CMPQ AX, $-1 307 JNE ok 308 CALL libc_error(SB) 309 MOVLQSX (AX), DX // errno 310 XORL AX, AX 311 ok: 312 MOVQ AX, 32(BX) 313 MOVQ DX, 40(BX) 314 POPQ BP 315 RET 316 317 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 318 PUSHQ BP 319 MOVQ SP, BP 320 MOVQ 8(DI), SI // arg 2 len 321 MOVQ 0(DI), DI // arg 1 addr 322 CALL libc_munmap(SB) 323 TESTQ AX, AX 324 JEQ 2(PC) 325 MOVL $0xf1, 0xf1 // crash 326 POPQ BP 327 RET 328 329 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 330 PUSHQ BP 331 MOVQ SP, BP 332 MOVL 0(DI), DI // arg 1 usec 333 CALL libc_usleep(SB) 334 POPQ BP 335 RET 336 337 TEXT runtime·settls(SB),NOSPLIT,$32 338 // Nothing to do on Darwin, pthread already set thread-local storage up. 339 RET 340 341 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0 342 PUSHQ BP 343 MOVQ SP, BP 344 MOVL 8(DI), SI // arg 2 miblen 345 MOVQ 16(DI), DX // arg 3 out 346 MOVQ 24(DI), CX // arg 4 size 347 MOVQ 32(DI), R8 // arg 5 dst 348 MOVQ 40(DI), R9 // arg 6 ndst 349 MOVQ 0(DI), DI // arg 1 mib 350 CALL libc_sysctl(SB) 351 POPQ BP 352 RET 353 354 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 355 PUSHQ BP 356 MOVQ SP, BP 357 CALL libc_kqueue(SB) 358 POPQ BP 359 RET 360 361 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0 362 PUSHQ BP 363 MOVQ SP, BP 364 MOVQ 8(DI), SI // arg 2 keventt 365 MOVL 16(DI), DX // arg 3 nch 366 MOVQ 24(DI), CX // arg 4 ev 367 MOVL 32(DI), R8 // arg 5 nev 368 MOVQ 40(DI), R9 // arg 6 ts 369 MOVL 0(DI), DI // arg 1 kq 370 CALL libc_kevent(SB) 371 CMPQ AX, $-1 372 JNE ok 373 CALL libc_error(SB) 374 MOVLQSX (AX), AX // errno 375 NEGQ AX // caller wants it as a negative error code 376 ok: 377 POPQ BP 378 RET 379 380 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 381 PUSHQ BP 382 MOVQ SP, BP 383 MOVL 4(DI), SI // arg 2 cmd 384 MOVL 8(DI), DX // arg 3 arg 385 MOVL 0(DI), DI // arg 1 fd 386 CALL libc_fcntl(SB) 387 POPQ BP 388 RET 389 390 // mstart_stub is the first function executed on a new thread started by pthread_create. 391 // It just does some low-level setup and then calls mstart. 392 // Note: called with the C calling convention. 393 TEXT runtime·mstart_stub(SB),NOSPLIT,$0 394 // DI points to the m. 395 // We are already on m's g0 stack. 396 397 // Save callee-save registers. 398 SUBQ $40, SP 399 MOVQ BX, 0(SP) 400 MOVQ R12, 8(SP) 401 MOVQ R13, 16(SP) 402 MOVQ R14, 24(SP) 403 MOVQ R15, 32(SP) 404 405 MOVQ m_g0(DI), DX // g 406 407 // Initialize TLS entry. 408 // See cmd/link/internal/ld/sym.go:computeTLSOffset. 409 MOVQ DX, 0x30(GS) 410 411 // Someday the convention will be D is always cleared. 412 CLD 413 414 CALL runtime·mstart(SB) 415 416 // Restore callee-save registers. 417 MOVQ 0(SP), BX 418 MOVQ 8(SP), R12 419 MOVQ 16(SP), R13 420 MOVQ 24(SP), R14 421 MOVQ 32(SP), R15 422 423 // Go is all done with this OS thread. 424 // Tell pthread everything is ok (we never join with this thread, so 425 // the value here doesn't really matter). 426 XORL AX, AX 427 428 ADDQ $40, SP 429 RET 430 431 // These trampolines help convert from Go calling convention to C calling convention. 432 // They should be called with asmcgocall. 433 // A pointer to the arguments is passed in DI. 434 // A single int32 result is returned in AX. 435 // (For more results, make an args/results structure.) 436 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 437 PUSHQ BP // make frame, keep stack 16-byte aligned. 438 MOVQ SP, BP 439 MOVQ 0(DI), DI // arg 1 attr 440 CALL libc_pthread_attr_init(SB) 441 POPQ BP 442 RET 443 444 TEXT runtime·pthread_attr_setstacksize_trampoline(SB),NOSPLIT,$0 445 PUSHQ BP 446 MOVQ SP, BP 447 MOVQ 8(DI), SI // arg 2 size 448 MOVQ 0(DI), DI // arg 1 attr 449 CALL libc_pthread_attr_setstacksize(SB) 450 POPQ BP 451 RET 452 453 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 454 PUSHQ BP 455 MOVQ SP, BP 456 MOVQ 8(DI), SI // arg 2 state 457 MOVQ 0(DI), DI // arg 1 attr 458 CALL libc_pthread_attr_setdetachstate(SB) 459 POPQ BP 460 RET 461 462 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0 463 PUSHQ BP 464 MOVQ SP, BP 465 SUBQ $16, SP 466 MOVQ 0(DI), SI // arg 2 attr 467 MOVQ 8(DI), DX // arg 3 start 468 MOVQ 16(DI), CX // arg 4 arg 469 MOVQ SP, DI // arg 1 &threadid (which we throw away) 470 CALL libc_pthread_create(SB) 471 MOVQ BP, SP 472 POPQ BP 473 RET 474 475 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0 476 PUSHQ BP 477 MOVQ SP, BP 478 MOVL 0(DI), DI // arg 1 signal 479 CALL libc_raise(SB) 480 POPQ BP 481 RET 482 483 TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0 484 PUSHQ BP 485 MOVQ SP, BP 486 MOVQ 8(DI), SI // arg 2 attr 487 MOVQ 0(DI), DI // arg 1 mutex 488 CALL libc_pthread_mutex_init(SB) 489 POPQ BP 490 RET 491 492 TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0 493 PUSHQ BP 494 MOVQ SP, BP 495 MOVQ 0(DI), DI // arg 1 mutex 496 CALL libc_pthread_mutex_lock(SB) 497 POPQ BP 498 RET 499 500 TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0 501 PUSHQ BP 502 MOVQ SP, BP 503 MOVQ 0(DI), DI // arg 1 mutex 504 CALL libc_pthread_mutex_unlock(SB) 505 POPQ BP 506 RET 507 508 TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0 509 PUSHQ BP 510 MOVQ SP, BP 511 MOVQ 8(DI), SI // arg 2 attr 512 MOVQ 0(DI), DI // arg 1 cond 513 CALL libc_pthread_cond_init(SB) 514 POPQ BP 515 RET 516 517 TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0 518 PUSHQ BP 519 MOVQ SP, BP 520 MOVQ 8(DI), SI // arg 2 mutex 521 MOVQ 0(DI), DI // arg 1 cond 522 CALL libc_pthread_cond_wait(SB) 523 POPQ BP 524 RET 525 526 TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0 527 PUSHQ BP 528 MOVQ SP, BP 529 MOVQ 8(DI), SI // arg 2 mutex 530 MOVQ 16(DI), DX // arg 3 timeout 531 MOVQ 0(DI), DI // arg 1 cond 532 CALL libc_pthread_cond_timedwait_relative_np(SB) 533 POPQ BP 534 RET 535 536 TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0 537 PUSHQ BP 538 MOVQ SP, BP 539 MOVQ 0(DI), DI // arg 1 cond 540 CALL libc_pthread_cond_signal(SB) 541 POPQ BP 542 RET