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