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 runtimeexit(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 runtimeexit1(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 runtimeopen(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 runtimeclosefd(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 runtimewrite(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 runtimeread(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 runtimegetrlimit(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 runtimeusleep(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 runtimegettid(SB),NOSPLIT,$0-4 98 MOVL $186, AX // syscall - gettid 99 SYSCALL 100 MOVL AX, ret+0(FP) 101 RET 102 103 TEXT runtimeraise(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 runtimeraiseproc(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 runtimesetitimer(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 runtimemincore(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 timenow(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 runtimenanotime(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 runtimertsigprocmask(SB),NOSPLIT,$0-28 200 MOVL sig+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 runtimert_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 runtimesigfwd(SB),NOSPLIT,$0-32 222 MOVL sig+8(FP), DI 223 MOVQ info+16(FP), SI 224 MOVQ ctx+24(FP), DX 225 MOVQ fn+0(FP), AX 226 CALL AX 227 RET 228 229 TEXT runtimesigtramp(SB),NOSPLIT,$24 230 MOVQ DI, 0(SP) // signum 231 MOVQ SI, 8(SP) // info 232 MOVQ DX, 16(SP) // ctx 233 MOVQ $runtimesigtrampgo(SB), AX 234 CALL AX 235 RET 236 237 TEXT runtimesigreturn(SB),NOSPLIT,$0 238 MOVL $15, AX // rt_sigreturn 239 SYSCALL 240 INT $3 // not reached 241 242 TEXT runtimemmap(SB),NOSPLIT,$0 243 MOVQ addr+0(FP), DI 244 MOVQ n+8(FP), SI 245 MOVL prot+16(FP), DX 246 MOVL flags+20(FP), R10 247 MOVL fd+24(FP), R8 248 MOVL off+28(FP), R9 249 250 MOVL $9, AX // mmap 251 SYSCALL 252 CMPQ AX, $0xfffffffffffff001 253 JLS 3(PC) 254 NOTQ AX 255 INCQ AX 256 MOVQ AX, ret+32(FP) 257 RET 258 259 TEXT runtimemunmap(SB),NOSPLIT,$0 260 MOVQ addr+0(FP), DI 261 MOVQ n+8(FP), SI 262 MOVQ $11, AX // munmap 263 SYSCALL 264 CMPQ AX, $0xfffffffffffff001 265 JLS 2(PC) 266 MOVL $0xf1, 0xf1 // crash 267 RET 268 269 TEXT runtimemadvise(SB),NOSPLIT,$0 270 MOVQ addr+0(FP), DI 271 MOVQ n+8(FP), SI 272 MOVL flags+16(FP), DX 273 MOVQ $28, AX // madvise 274 SYSCALL 275 // ignore failure - maybe pages are locked 276 RET 277 278 // int64 futex(int32 *uaddr, int32 op, int32 val, 279 // struct timespec *timeout, int32 *uaddr2, int32 val2); 280 TEXT runtimefutex(SB),NOSPLIT,$0 281 MOVQ addr+0(FP), DI 282 MOVL op+8(FP), SI 283 MOVL val+12(FP), DX 284 MOVQ ts+16(FP), R10 285 MOVQ addr2+24(FP), R8 286 MOVL val3+32(FP), R9 287 MOVL $202, AX 288 SYSCALL 289 MOVL AX, ret+40(FP) 290 RET 291 292 // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void)); 293 TEXT runtimeclone(SB),NOSPLIT,$0 294 MOVL flags+0(FP), DI 295 MOVQ stack+8(FP), SI 296 MOVQ $0, DX 297 MOVQ $0, R10 298 299 // Copy mp, gp, fn off parent stack for use by child. 300 // Careful: Linux system call clobbers CX and R11. 301 MOVQ mp+16(FP), R8 302 MOVQ gp+24(FP), R9 303 MOVQ fn+32(FP), R12 304 305 MOVL $56, AX 306 SYSCALL 307 308 // In parent, return. 309 CMPQ AX, $0 310 JEQ 3(PC) 311 MOVL AX, ret+40(FP) 312 RET 313 314 // In child, on new stack. 315 MOVQ SI, SP 316 317 // If g or m are nil, skip Go-related setup. 318 CMPQ R8, $0 // m 319 JEQ nog 320 CMPQ R9, $0 // g 321 JEQ nog 322 323 // Initialize m->procid to Linux tid 324 MOVL $186, AX // gettid 325 SYSCALL 326 MOVQ AX, m_procid(R8) 327 328 // Set FS to point at m->tls. 329 LEAQ m_tls(R8), DI 330 CALL runtimesettls(SB) 331 332 // In child, set up new stack 333 get_tls(CX) 334 MOVQ R8, g_m(R9) 335 MOVQ R9, g(CX) 336 CALL runtimestackcheck(SB) 337 338 nog: 339 // Call fn 340 CALL R12 341 342 // It shouldn't return. If it does, exit that thread. 343 MOVL $111, DI 344 MOVL $60, AX 345 SYSCALL 346 JMP -3(PC) // keep exiting 347 348 TEXT runtimesigaltstack(SB),NOSPLIT,$-8 349 MOVQ new+8(SP), DI 350 MOVQ old+16(SP), SI 351 MOVQ $131, AX 352 SYSCALL 353 CMPQ AX, $0xfffffffffffff001 354 JLS 2(PC) 355 MOVL $0xf1, 0xf1 // crash 356 RET 357 358 // set tls base to DI 359 TEXT runtimesettls(SB),NOSPLIT,$32 360 ADDQ $8, DI // ELF wants to use -8(FS) 361 362 MOVQ DI, SI 363 MOVQ $0x1002, DI // ARCH_SET_FS 364 MOVQ $158, AX // arch_prctl 365 SYSCALL 366 CMPQ AX, $0xfffffffffffff001 367 JLS 2(PC) 368 MOVL $0xf1, 0xf1 // crash 369 RET 370 371 TEXT runtimeosyield(SB),NOSPLIT,$0 372 MOVL $24, AX 373 SYSCALL 374 RET 375 376 TEXT runtimesched_getaffinity(SB),NOSPLIT,$0 377 MOVQ pid+0(FP), DI 378 MOVQ len+8(FP), SI 379 MOVQ buf+16(FP), DX 380 MOVL $204, AX // syscall entry 381 SYSCALL 382 MOVL AX, ret+24(FP) 383 RET 384 385 // int32 runtimeepollcreate(int32 size); 386 TEXT runtimeepollcreate(SB),NOSPLIT,$0 387 MOVL size+0(FP), DI 388 MOVL $213, AX // syscall entry 389 SYSCALL 390 MOVL AX, ret+8(FP) 391 RET 392 393 // int32 runtimeepollcreate1(int32 flags); 394 TEXT runtimeepollcreate1(SB),NOSPLIT,$0 395 MOVL flags+0(FP), DI 396 MOVL $291, AX // syscall entry 397 SYSCALL 398 MOVL AX, ret+8(FP) 399 RET 400 401 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 402 TEXT runtimeepollctl(SB),NOSPLIT,$0 403 MOVL epfd+0(FP), DI 404 MOVL op+4(FP), SI 405 MOVL fd+8(FP), DX 406 MOVQ ev+16(FP), R10 407 MOVL $233, AX // syscall entry 408 SYSCALL 409 MOVL AX, ret+24(FP) 410 RET 411 412 // int32 runtimeepollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 413 TEXT runtimeepollwait(SB),NOSPLIT,$0 414 MOVL epfd+0(FP), DI 415 MOVQ ev+8(FP), SI 416 MOVL nev+16(FP), DX 417 MOVL timeout+20(FP), R10 418 MOVL $232, AX // syscall entry 419 SYSCALL 420 MOVL AX, ret+24(FP) 421 RET 422 423 // void runtimecloseonexec(int32 fd); 424 TEXT runtimecloseonexec(SB),NOSPLIT,$0 425 MOVL fd+0(FP), DI // fd 426 MOVQ $2, SI // F_SETFD 427 MOVQ $1, DX // FD_CLOEXEC 428 MOVL $72, AX // fcntl 429 SYSCALL 430 RET 431