github.com/sanprasirt/go@v0.0.0-20170607001320-a027466e4b6d/src/runtime/sys_linux_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, Linux 7 // 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 TEXT runtime·exit(SB),NOSPLIT,$0-4 14 MOVL code+0(FP), DI 15 MOVL $231, AX // exitgroup - force all os threads to exit 16 SYSCALL 17 RET 18 19 TEXT runtime·exit1(SB),NOSPLIT,$0-4 20 MOVL code+0(FP), DI 21 MOVL $60, AX // exit - exit the current os thread 22 SYSCALL 23 RET 24 25 TEXT runtime·open(SB),NOSPLIT,$0-20 26 MOVQ name+0(FP), DI 27 MOVL mode+8(FP), SI 28 MOVL perm+12(FP), DX 29 MOVL $2, AX // syscall entry 30 SYSCALL 31 CMPQ AX, $0xfffffffffffff001 32 JLS 2(PC) 33 MOVL $-1, AX 34 MOVL AX, ret+16(FP) 35 RET 36 37 TEXT runtime·closefd(SB),NOSPLIT,$0-12 38 MOVL fd+0(FP), DI 39 MOVL $3, AX // syscall entry 40 SYSCALL 41 CMPQ AX, $0xfffffffffffff001 42 JLS 2(PC) 43 MOVL $-1, AX 44 MOVL AX, ret+8(FP) 45 RET 46 47 TEXT runtime·write(SB),NOSPLIT,$0-28 48 MOVQ fd+0(FP), DI 49 MOVQ p+8(FP), SI 50 MOVL n+16(FP), DX 51 MOVL $1, AX // syscall entry 52 SYSCALL 53 CMPQ AX, $0xfffffffffffff001 54 JLS 2(PC) 55 MOVL $-1, AX 56 MOVL AX, ret+24(FP) 57 RET 58 59 TEXT runtime·read(SB),NOSPLIT,$0-28 60 MOVL fd+0(FP), DI 61 MOVQ p+8(FP), SI 62 MOVL n+16(FP), DX 63 MOVL $0, AX // syscall entry 64 SYSCALL 65 CMPQ AX, $0xfffffffffffff001 66 JLS 2(PC) 67 MOVL $-1, AX 68 MOVL AX, ret+24(FP) 69 RET 70 71 TEXT runtime·getrlimit(SB),NOSPLIT,$0-20 72 MOVL kind+0(FP), DI 73 MOVQ limit+8(FP), SI 74 MOVL $97, AX // syscall entry 75 SYSCALL 76 MOVL AX, ret+16(FP) 77 RET 78 79 TEXT runtime·usleep(SB),NOSPLIT,$16 80 MOVL $0, DX 81 MOVL usec+0(FP), AX 82 MOVL $1000000, CX 83 DIVL CX 84 MOVQ AX, 0(SP) 85 MOVL $1000, AX // usec to nsec 86 MULL DX 87 MOVQ AX, 8(SP) 88 89 // pselect6(0, 0, 0, 0, &ts, 0) 90 MOVL $0, DI 91 MOVL $0, SI 92 MOVL $0, DX 93 MOVL $0, R10 94 MOVQ SP, R8 95 MOVL $0, R9 96 MOVL $270, AX 97 SYSCALL 98 RET 99 100 TEXT runtime·gettid(SB),NOSPLIT,$0-4 101 MOVL $186, AX // syscall - gettid 102 SYSCALL 103 MOVL AX, ret+0(FP) 104 RET 105 106 TEXT runtime·raise(SB),NOSPLIT,$0 107 MOVL $186, AX // syscall - gettid 108 SYSCALL 109 MOVL AX, DI // arg 1 tid 110 MOVL sig+0(FP), SI // arg 2 111 MOVL $200, AX // syscall - tkill 112 SYSCALL 113 RET 114 115 TEXT runtime·raiseproc(SB),NOSPLIT,$0 116 MOVL $39, AX // syscall - getpid 117 SYSCALL 118 MOVL AX, DI // arg 1 pid 119 MOVL sig+0(FP), SI // arg 2 120 MOVL $62, AX // syscall - kill 121 SYSCALL 122 RET 123 124 TEXT runtime·setitimer(SB),NOSPLIT,$0-24 125 MOVL mode+0(FP), DI 126 MOVQ new+8(FP), SI 127 MOVQ old+16(FP), DX 128 MOVL $38, AX // syscall entry 129 SYSCALL 130 RET 131 132 TEXT runtime·mincore(SB),NOSPLIT,$0-28 133 MOVQ addr+0(FP), DI 134 MOVQ n+8(FP), SI 135 MOVQ dst+16(FP), DX 136 MOVL $27, AX // syscall entry 137 SYSCALL 138 MOVL AX, ret+24(FP) 139 RET 140 141 // func walltime() (sec int64, nsec int32) 142 TEXT runtime·walltime(SB),NOSPLIT,$16 143 // Be careful. We're calling a function with gcc calling convention here. 144 // We're guaranteed 128 bytes on entry, and we've taken 16, and the 145 // call uses another 8. 146 // That leaves 104 for the gettime code to use. Hope that's enough! 147 MOVQ runtime·__vdso_clock_gettime_sym(SB), AX 148 CMPQ AX, $0 149 JEQ fallback 150 MOVL $0, DI // CLOCK_REALTIME 151 LEAQ 0(SP), SI 152 CALL AX 153 MOVQ 0(SP), AX // sec 154 MOVQ 8(SP), DX // nsec 155 MOVQ AX, sec+0(FP) 156 MOVL DX, nsec+8(FP) 157 RET 158 fallback: 159 LEAQ 0(SP), DI 160 MOVQ $0, SI 161 MOVQ runtime·__vdso_gettimeofday_sym(SB), AX 162 CALL AX 163 MOVQ 0(SP), AX // sec 164 MOVL 8(SP), DX // usec 165 IMULQ $1000, DX 166 MOVQ AX, sec+0(FP) 167 MOVL DX, nsec+8(FP) 168 RET 169 170 TEXT runtime·nanotime(SB),NOSPLIT,$16 171 // Duplicate time.now here to avoid using up precious stack space. 172 // See comment above in time.now. 173 MOVQ runtime·__vdso_clock_gettime_sym(SB), AX 174 CMPQ AX, $0 175 JEQ fallback 176 MOVL $1, DI // CLOCK_MONOTONIC 177 LEAQ 0(SP), SI 178 CALL AX 179 MOVQ 0(SP), AX // sec 180 MOVQ 8(SP), DX // nsec 181 // sec is in AX, nsec in DX 182 // return nsec in AX 183 IMULQ $1000000000, AX 184 ADDQ DX, AX 185 MOVQ AX, ret+0(FP) 186 RET 187 fallback: 188 LEAQ 0(SP), DI 189 MOVQ $0, SI 190 MOVQ runtime·__vdso_gettimeofday_sym(SB), AX 191 CALL AX 192 MOVQ 0(SP), AX // sec 193 MOVL 8(SP), DX // usec 194 IMULQ $1000, DX 195 // sec is in AX, nsec in DX 196 // return nsec in AX 197 IMULQ $1000000000, AX 198 ADDQ DX, AX 199 MOVQ AX, ret+0(FP) 200 RET 201 202 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-28 203 MOVL how+0(FP), DI 204 MOVQ new+8(FP), SI 205 MOVQ old+16(FP), DX 206 MOVL size+24(FP), R10 207 MOVL $14, AX // syscall entry 208 SYSCALL 209 CMPQ AX, $0xfffffffffffff001 210 JLS 2(PC) 211 MOVL $0xf1, 0xf1 // crash 212 RET 213 214 TEXT runtime·sysSigaction(SB),NOSPLIT,$0-36 215 MOVQ sig+0(FP), DI 216 MOVQ new+8(FP), SI 217 MOVQ old+16(FP), DX 218 MOVQ size+24(FP), R10 219 MOVL $13, AX // syscall entry 220 SYSCALL 221 MOVL AX, ret+32(FP) 222 RET 223 224 // Call the function stored in _cgo_sigaction using the GCC calling convention. 225 TEXT runtime·callCgoSigaction(SB),NOSPLIT,$16 226 MOVQ sig+0(FP), DI 227 MOVQ new+8(FP), SI 228 MOVQ old+16(FP), DX 229 MOVQ _cgo_sigaction(SB), AX 230 MOVQ SP, BX // callee-saved 231 ANDQ $~15, SP // alignment as per amd64 psABI 232 CALL AX 233 MOVQ BX, SP 234 MOVL AX, ret+24(FP) 235 RET 236 237 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 238 MOVQ fn+0(FP), AX 239 MOVL sig+8(FP), DI 240 MOVQ info+16(FP), SI 241 MOVQ ctx+24(FP), DX 242 PUSHQ BP 243 MOVQ SP, BP 244 ANDQ $~15, SP // alignment for x86_64 ABI 245 CALL AX 246 MOVQ BP, SP 247 POPQ BP 248 RET 249 250 TEXT runtime·sigtramp(SB),NOSPLIT,$72 251 // Save callee-saved C registers, since the caller may be a C signal handler. 252 MOVQ BX, bx-8(SP) 253 MOVQ BP, bp-16(SP) // save in case GOEXPERIMENT=noframepointer is set 254 MOVQ R12, r12-24(SP) 255 MOVQ R13, r13-32(SP) 256 MOVQ R14, r14-40(SP) 257 MOVQ R15, r15-48(SP) 258 // We don't save mxcsr or the x87 control word because sigtrampgo doesn't 259 // modify them. 260 261 MOVQ DX, ctx-56(SP) 262 MOVQ SI, info-64(SP) 263 MOVQ DI, signum-72(SP) 264 MOVQ $runtime·sigtrampgo(SB), AX 265 CALL AX 266 267 MOVQ r15-48(SP), R15 268 MOVQ r14-40(SP), R14 269 MOVQ r13-32(SP), R13 270 MOVQ r12-24(SP), R12 271 MOVQ bp-16(SP), BP 272 MOVQ bx-8(SP), BX 273 RET 274 275 // Used instead of sigtramp in programs that use cgo. 276 // Arguments from kernel are in DI, SI, DX. 277 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 278 // If no traceback function, do usual sigtramp. 279 MOVQ runtime·cgoTraceback(SB), AX 280 TESTQ AX, AX 281 JZ sigtramp 282 283 // If no traceback support function, which means that 284 // runtime/cgo was not linked in, do usual sigtramp. 285 MOVQ _cgo_callers(SB), AX 286 TESTQ AX, AX 287 JZ sigtramp 288 289 // Figure out if we are currently in a cgo call. 290 // If not, just do usual sigtramp. 291 get_tls(CX) 292 MOVQ g(CX),AX 293 TESTQ AX, AX 294 JZ sigtrampnog // g == nil 295 MOVQ g_m(AX), AX 296 TESTQ AX, AX 297 JZ sigtramp // g.m == nil 298 MOVL m_ncgo(AX), CX 299 TESTL CX, CX 300 JZ sigtramp // g.m.ncgo == 0 301 MOVQ m_curg(AX), CX 302 TESTQ CX, CX 303 JZ sigtramp // g.m.curg == nil 304 MOVQ g_syscallsp(CX), CX 305 TESTQ CX, CX 306 JZ sigtramp // g.m.curg.syscallsp == 0 307 MOVQ m_cgoCallers(AX), R8 308 TESTQ R8, R8 309 JZ sigtramp // g.m.cgoCallers == nil 310 MOVL m_cgoCallersUse(AX), CX 311 TESTL CX, CX 312 JNZ sigtramp // g.m.cgoCallersUse != 0 313 314 // Jump to a function in runtime/cgo. 315 // That function, written in C, will call the user's traceback 316 // function with proper unwind info, and will then call back here. 317 // The first three arguments, and the fifth, are already in registers. 318 // Set the two remaining arguments now. 319 MOVQ runtime·cgoTraceback(SB), CX 320 MOVQ $runtime·sigtramp(SB), R9 321 MOVQ _cgo_callers(SB), AX 322 JMP AX 323 324 sigtramp: 325 JMP runtime·sigtramp(SB) 326 327 sigtrampnog: 328 // Signal arrived on a non-Go thread. If this is SIGPROF, get a 329 // stack trace. 330 CMPL DI, $27 // 27 == SIGPROF 331 JNZ sigtramp 332 333 // Lock sigprofCallersUse. 334 MOVL $0, AX 335 MOVL $1, CX 336 MOVQ $runtime·sigprofCallersUse(SB), R11 337 LOCK 338 CMPXCHGL CX, 0(R11) 339 JNZ sigtramp // Skip stack trace if already locked. 340 341 // Jump to the traceback function in runtime/cgo. 342 // It will call back to sigprofNonGo, which will ignore the 343 // arguments passed in registers. 344 // First three arguments to traceback function are in registers already. 345 MOVQ runtime·cgoTraceback(SB), CX 346 MOVQ $runtime·sigprofCallers(SB), R8 347 MOVQ $runtime·sigprofNonGo(SB), R9 348 MOVQ _cgo_callers(SB), AX 349 JMP AX 350 351 // For cgo unwinding to work, this function must look precisely like 352 // the one in glibc. The glibc source code is: 353 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/sigaction.c 354 // The code that cares about the precise instructions used is: 355 // https://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/i386/linux-unwind.h?revision=219188&view=markup 356 TEXT runtime·sigreturn(SB),NOSPLIT,$0 357 MOVQ $15, AX // rt_sigreturn 358 SYSCALL 359 INT $3 // not reached 360 361 TEXT runtime·sysMmap(SB),NOSPLIT,$0 362 MOVQ addr+0(FP), DI 363 MOVQ n+8(FP), SI 364 MOVL prot+16(FP), DX 365 MOVL flags+20(FP), R10 366 MOVL fd+24(FP), R8 367 MOVL off+28(FP), R9 368 369 MOVL $9, AX // mmap 370 SYSCALL 371 CMPQ AX, $0xfffffffffffff001 372 JLS 3(PC) 373 NOTQ AX 374 INCQ AX 375 MOVQ AX, ret+32(FP) 376 RET 377 378 // Call the function stored in _cgo_mmap using the GCC calling convention. 379 // This must be called on the system stack. 380 TEXT runtime·callCgoMmap(SB),NOSPLIT,$16 381 MOVQ addr+0(FP), DI 382 MOVQ n+8(FP), SI 383 MOVL prot+16(FP), DX 384 MOVL flags+20(FP), CX 385 MOVL fd+24(FP), R8 386 MOVL off+28(FP), R9 387 MOVQ _cgo_mmap(SB), AX 388 MOVQ SP, BX 389 ANDQ $~15, SP // alignment as per amd64 psABI 390 MOVQ BX, 0(SP) 391 CALL AX 392 MOVQ 0(SP), SP 393 MOVQ AX, ret+32(FP) 394 RET 395 396 TEXT runtime·sysMunmap(SB),NOSPLIT,$0 397 MOVQ addr+0(FP), DI 398 MOVQ n+8(FP), SI 399 MOVQ $11, AX // munmap 400 SYSCALL 401 CMPQ AX, $0xfffffffffffff001 402 JLS 2(PC) 403 MOVL $0xf1, 0xf1 // crash 404 RET 405 406 // Call the function stored in _cgo_munmap using the GCC calling convention. 407 // This must be called on the system stack. 408 TEXT runtime·callCgoMunmap(SB),NOSPLIT,$16-16 409 MOVQ addr+0(FP), DI 410 MOVQ n+8(FP), SI 411 MOVQ _cgo_munmap(SB), AX 412 MOVQ SP, BX 413 ANDQ $~15, SP // alignment as per amd64 psABI 414 MOVQ BX, 0(SP) 415 CALL AX 416 MOVQ 0(SP), SP 417 RET 418 419 TEXT runtime·madvise(SB),NOSPLIT,$0 420 MOVQ addr+0(FP), DI 421 MOVQ n+8(FP), SI 422 MOVL flags+16(FP), DX 423 MOVQ $28, AX // madvise 424 SYSCALL 425 // ignore failure - maybe pages are locked 426 RET 427 428 // int64 futex(int32 *uaddr, int32 op, int32 val, 429 // struct timespec *timeout, int32 *uaddr2, int32 val2); 430 TEXT runtime·futex(SB),NOSPLIT,$0 431 MOVQ addr+0(FP), DI 432 MOVL op+8(FP), SI 433 MOVL val+12(FP), DX 434 MOVQ ts+16(FP), R10 435 MOVQ addr2+24(FP), R8 436 MOVL val3+32(FP), R9 437 MOVL $202, AX 438 SYSCALL 439 MOVL AX, ret+40(FP) 440 RET 441 442 // int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 443 TEXT runtime·clone(SB),NOSPLIT,$0 444 MOVL flags+0(FP), DI 445 MOVQ stk+8(FP), SI 446 MOVQ $0, DX 447 MOVQ $0, R10 448 449 // Copy mp, gp, fn off parent stack for use by child. 450 // Careful: Linux system call clobbers CX and R11. 451 MOVQ mp+16(FP), R8 452 MOVQ gp+24(FP), R9 453 MOVQ fn+32(FP), R12 454 455 MOVL $56, AX 456 SYSCALL 457 458 // In parent, return. 459 CMPQ AX, $0 460 JEQ 3(PC) 461 MOVL AX, ret+40(FP) 462 RET 463 464 // In child, on new stack. 465 MOVQ SI, SP 466 467 // If g or m are nil, skip Go-related setup. 468 CMPQ R8, $0 // m 469 JEQ nog 470 CMPQ R9, $0 // g 471 JEQ nog 472 473 // Initialize m->procid to Linux tid 474 MOVL $186, AX // gettid 475 SYSCALL 476 MOVQ AX, m_procid(R8) 477 478 // Set FS to point at m->tls. 479 LEAQ m_tls(R8), DI 480 CALL runtime·settls(SB) 481 482 // In child, set up new stack 483 get_tls(CX) 484 MOVQ R8, g_m(R9) 485 MOVQ R9, g(CX) 486 CALL runtime·stackcheck(SB) 487 488 nog: 489 // Call fn 490 CALL R12 491 492 // It shouldn't return. If it does, exit that thread. 493 MOVL $111, DI 494 MOVL $60, AX 495 SYSCALL 496 JMP -3(PC) // keep exiting 497 498 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 499 MOVQ new+0(FP), DI 500 MOVQ old+8(FP), SI 501 MOVQ $131, AX 502 SYSCALL 503 CMPQ AX, $0xfffffffffffff001 504 JLS 2(PC) 505 MOVL $0xf1, 0xf1 // crash 506 RET 507 508 // set tls base to DI 509 TEXT runtime·settls(SB),NOSPLIT,$32 510 #ifdef GOOS_android 511 // Same as in sys_darwin_386.s:/ugliness, different constant. 512 // DI currently holds m->tls, which must be fs:0x1d0. 513 // See cgo/gcc_android_amd64.c for the derivation of the constant. 514 SUBQ $0x1d0, DI // In android, the tls base 515 #else 516 ADDQ $8, DI // ELF wants to use -8(FS) 517 #endif 518 MOVQ DI, SI 519 MOVQ $0x1002, DI // ARCH_SET_FS 520 MOVQ $158, AX // arch_prctl 521 SYSCALL 522 CMPQ AX, $0xfffffffffffff001 523 JLS 2(PC) 524 MOVL $0xf1, 0xf1 // crash 525 RET 526 527 TEXT runtime·osyield(SB),NOSPLIT,$0 528 MOVL $24, AX 529 SYSCALL 530 RET 531 532 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 533 MOVQ pid+0(FP), DI 534 MOVQ len+8(FP), SI 535 MOVQ buf+16(FP), DX 536 MOVL $204, AX // syscall entry 537 SYSCALL 538 MOVL AX, ret+24(FP) 539 RET 540 541 // int32 runtime·epollcreate(int32 size); 542 TEXT runtime·epollcreate(SB),NOSPLIT,$0 543 MOVL size+0(FP), DI 544 MOVL $213, AX // syscall entry 545 SYSCALL 546 MOVL AX, ret+8(FP) 547 RET 548 549 // int32 runtime·epollcreate1(int32 flags); 550 TEXT runtime·epollcreate1(SB),NOSPLIT,$0 551 MOVL flags+0(FP), DI 552 MOVL $291, AX // syscall entry 553 SYSCALL 554 MOVL AX, ret+8(FP) 555 RET 556 557 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 558 TEXT runtime·epollctl(SB),NOSPLIT,$0 559 MOVL epfd+0(FP), DI 560 MOVL op+4(FP), SI 561 MOVL fd+8(FP), DX 562 MOVQ ev+16(FP), R10 563 MOVL $233, AX // syscall entry 564 SYSCALL 565 MOVL AX, ret+24(FP) 566 RET 567 568 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 569 TEXT runtime·epollwait(SB),NOSPLIT,$0 570 MOVL epfd+0(FP), DI 571 MOVQ ev+8(FP), SI 572 MOVL nev+16(FP), DX 573 MOVL timeout+20(FP), R10 574 MOVL $232, AX // syscall entry 575 SYSCALL 576 MOVL AX, ret+24(FP) 577 RET 578 579 // void runtime·closeonexec(int32 fd); 580 TEXT runtime·closeonexec(SB),NOSPLIT,$0 581 MOVL fd+0(FP), DI // fd 582 MOVQ $2, SI // F_SETFD 583 MOVQ $1, DX // FD_CLOEXEC 584 MOVL $72, AX // fcntl 585 SYSCALL 586 RET 587 588 589 // int access(const char *name, int mode) 590 TEXT runtime·access(SB),NOSPLIT,$0 591 MOVQ name+0(FP), DI 592 MOVL mode+8(FP), SI 593 MOVL $21, AX // syscall entry 594 SYSCALL 595 MOVL AX, ret+16(FP) 596 RET 597 598 // int connect(int fd, const struct sockaddr *addr, socklen_t addrlen) 599 TEXT runtime·connect(SB),NOSPLIT,$0-28 600 MOVL fd+0(FP), DI 601 MOVQ addr+8(FP), SI 602 MOVL len+16(FP), DX 603 MOVL $42, AX // syscall entry 604 SYSCALL 605 MOVL AX, ret+24(FP) 606 RET 607 608 // int socket(int domain, int type, int protocol) 609 TEXT runtime·socket(SB),NOSPLIT,$0-20 610 MOVL domain+0(FP), DI 611 MOVL typ+4(FP), SI 612 MOVL prot+8(FP), DX 613 MOVL $41, AX // syscall entry 614 SYSCALL 615 MOVL AX, ret+16(FP) 616 RET 617 618 // func sbrk0() uintptr 619 TEXT runtime·sbrk0(SB),NOSPLIT,$0-8 620 // Implemented as brk(NULL). 621 MOVQ $0, DI 622 MOVL $12, AX // syscall entry 623 SYSCALL 624 MOVQ AX, ret+0(FP) 625 RET