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, OpenBSD 6 // /usr/src/sys/kern/syscalls.master for syscall numbers. 7 // 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 #define CLOCK_MONOTONIC $3 14 15 // int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void)); 16 TEXT runtimetfork(SB),NOSPLIT,$32 17 18 // Copy mp, gp and fn off parent stack for use by child. 19 MOVQ mm+16(FP), R8 20 MOVQ gg+24(FP), R9 21 MOVQ fn+32(FP), R12 22 23 MOVQ param+0(FP), DI 24 MOVQ psize+8(FP), SI 25 MOVL $8, AX // sys___tfork 26 SYSCALL 27 28 // Return if tfork syscall failed. 29 JCC 4(PC) 30 NEGQ AX 31 MOVL AX, ret+40(FP) 32 RET 33 34 // In parent, return. 35 CMPL AX, $0 36 JEQ 3(PC) 37 MOVL AX, ret+40(FP) 38 RET 39 40 // Set FS to point at m->tls. 41 LEAQ m_tls(R8), DI 42 CALL runtimesettls(SB) 43 44 // In child, set up new stack. 45 get_tls(CX) 46 MOVQ R8, g_m(R9) 47 MOVQ R9, g(CX) 48 CALL runtimestackcheck(SB) 49 50 // Call fn 51 CALL R12 52 53 // It shouldn't return. If it does, exit 54 MOVQ $0, DI // arg 1 - notdead 55 MOVL $302, AX // sys___threxit 56 SYSCALL 57 JMP -3(PC) // keep exiting 58 59 TEXT runtimeosyield(SB),NOSPLIT,$0 60 MOVL $298, AX // sys_sched_yield 61 SYSCALL 62 RET 63 64 TEXT runtimethrsleep(SB),NOSPLIT,$0 65 MOVQ ident+0(FP), DI // arg 1 - ident 66 MOVL clock_id+8(FP), SI // arg 2 - clock_id 67 MOVQ tsp+16(FP), DX // arg 3 - tp 68 MOVQ lock+24(FP), R10 // arg 4 - lock 69 MOVQ abort+32(FP), R8 // arg 5 - abort 70 MOVL $94, AX // sys___thrsleep 71 SYSCALL 72 MOVL AX, ret+40(FP) 73 RET 74 75 TEXT runtimethrwakeup(SB),NOSPLIT,$0 76 MOVQ ident+0(FP), DI // arg 1 - ident 77 MOVL n+8(FP), SI // arg 2 - n 78 MOVL $301, AX // sys___thrwakeup 79 SYSCALL 80 MOVL AX, ret+16(FP) 81 RET 82 83 // Exit the entire program (like C exit) 84 TEXT runtimeexit(SB),NOSPLIT,$-8 85 MOVL code+0(FP), DI // arg 1 - exit status 86 MOVL $1, AX // sys_exit 87 SYSCALL 88 MOVL $0xf1, 0xf1 // crash 89 RET 90 91 TEXT runtimeexit1(SB),NOSPLIT,$-8 92 MOVQ $0, DI // arg 1 - notdead 93 MOVL $302, AX // sys___threxit 94 SYSCALL 95 MOVL $0xf1, 0xf1 // crash 96 RET 97 98 TEXT runtimeopen(SB),NOSPLIT,$-8 99 MOVQ name+0(FP), DI // arg 1 pathname 100 MOVL mode+8(FP), SI // arg 2 flags 101 MOVL perm+12(FP), DX // arg 3 mode 102 MOVL $5, AX 103 SYSCALL 104 JCC 2(PC) 105 MOVL $-1, AX 106 MOVL AX, ret+16(FP) 107 RET 108 109 TEXT runtimeclosefd(SB),NOSPLIT,$-8 110 MOVL fd+0(FP), DI // arg 1 fd 111 MOVL $6, AX 112 SYSCALL 113 JCC 2(PC) 114 MOVL $-1, AX 115 MOVL AX, ret+8(FP) 116 RET 117 118 TEXT runtimeread(SB),NOSPLIT,$-8 119 MOVL fd+0(FP), DI // arg 1 fd 120 MOVQ p+8(FP), SI // arg 2 buf 121 MOVL n+16(FP), DX // arg 3 count 122 MOVL $3, AX 123 SYSCALL 124 JCC 2(PC) 125 MOVL $-1, AX 126 MOVL AX, ret+24(FP) 127 RET 128 129 TEXT runtimewrite(SB),NOSPLIT,$-8 130 MOVQ fd+0(FP), DI // arg 1 - fd 131 MOVQ p+8(FP), SI // arg 2 - buf 132 MOVL n+16(FP), DX // arg 3 - nbyte 133 MOVL $4, AX // sys_write 134 SYSCALL 135 JCC 2(PC) 136 MOVL $-1, AX 137 MOVL AX, ret+24(FP) 138 RET 139 140 TEXT runtimeusleep(SB),NOSPLIT,$16 141 MOVL $0, DX 142 MOVL usec+0(FP), AX 143 MOVL $1000000, CX 144 DIVL CX 145 MOVQ AX, 0(SP) // tv_sec 146 MOVL $1000, AX 147 MULL DX 148 MOVQ AX, 8(SP) // tv_nsec 149 150 MOVQ SP, DI // arg 1 - rqtp 151 MOVQ $0, SI // arg 2 - rmtp 152 MOVL $91, AX // sys_nanosleep 153 SYSCALL 154 RET 155 156 TEXT runtimeraise(SB),NOSPLIT,$16 157 MOVL $299, AX // sys_getthrid 158 SYSCALL 159 MOVQ AX, DI // arg 1 - tid 160 MOVL sig+0(FP), SI // arg 2 - signum 161 MOVQ $0, DX // arg 3 - tcb 162 MOVL $119, AX // sys_thrkill 163 SYSCALL 164 RET 165 166 TEXT runtimeraiseproc(SB),NOSPLIT,$16 167 MOVL $20, AX // sys_getpid 168 SYSCALL 169 MOVQ AX, DI // arg 1 - pid 170 MOVL sig+0(FP), SI // arg 2 - signum 171 MOVL $122, AX // sys_kill 172 SYSCALL 173 RET 174 175 TEXT runtimesetitimer(SB),NOSPLIT,$-8 176 MOVL mode+0(FP), DI // arg 1 - which 177 MOVQ new+8(FP), SI // arg 2 - itv 178 MOVQ old+16(FP), DX // arg 3 - oitv 179 MOVL $69, AX // sys_setitimer 180 SYSCALL 181 RET 182 183 // func now() (sec int64, nsec int32) 184 TEXT timenow(SB), NOSPLIT, $32 185 MOVQ $0, DI // arg 1 - clock_id 186 LEAQ 8(SP), SI // arg 2 - tp 187 MOVL $87, AX // sys_clock_gettime 188 SYSCALL 189 MOVQ 8(SP), AX // sec 190 MOVQ 16(SP), DX // nsec 191 192 // sec is in AX, nsec in DX 193 MOVQ AX, sec+0(FP) 194 MOVL DX, nsec+8(FP) 195 RET 196 197 TEXT runtimenanotime(SB),NOSPLIT,$24 198 MOVQ CLOCK_MONOTONIC, DI // arg 1 - clock_id 199 LEAQ 8(SP), SI // arg 2 - tp 200 MOVL $87, AX // sys_clock_gettime 201 SYSCALL 202 MOVQ 8(SP), AX // sec 203 MOVQ 16(SP), DX // nsec 204 205 // sec is in AX, nsec in DX 206 // return nsec in AX 207 IMULQ $1000000000, AX 208 ADDQ DX, AX 209 MOVQ AX, ret+0(FP) 210 RET 211 212 TEXT runtimesigaction(SB),NOSPLIT,$-8 213 MOVL sig+0(FP), DI // arg 1 - signum 214 MOVQ new+8(FP), SI // arg 2 - nsa 215 MOVQ old+16(FP), DX // arg 3 - osa 216 MOVL $46, AX 217 SYSCALL 218 JCC 2(PC) 219 MOVL $0xf1, 0xf1 // crash 220 RET 221 222 TEXT runtimeobsdsigprocmask(SB),NOSPLIT,$0 223 MOVL how+0(FP), DI // arg 1 - how 224 MOVL new+4(FP), SI // arg 2 - set 225 MOVL $48, AX // sys_sigprocmask 226 SYSCALL 227 JCC 2(PC) 228 MOVL $0xf1, 0xf1 // crash 229 MOVL AX, ret+8(FP) 230 RET 231 232 TEXT runtimesigfwd(SB),NOSPLIT,$0-32 233 MOVQ fn+0(FP), AX 234 MOVL sig+8(FP), DI 235 MOVQ info+16(FP), SI 236 MOVQ ctx+24(FP), DX 237 PUSHQ BP 238 MOVQ SP, BP 239 ANDQ $~15, SP // alignment for x86_64 ABI 240 CALL AX 241 MOVQ BP, SP 242 POPQ BP 243 RET 244 245 TEXT runtimesigtramp(SB),NOSPLIT,$72 246 // Save callee-saved C registers, since the caller may be a C signal handler. 247 MOVQ BX, bx-8(SP) 248 MOVQ BP, bp-16(SP) // save in case GOEXPERIMENT=noframepointer is set 249 MOVQ R12, r12-24(SP) 250 MOVQ R13, r13-32(SP) 251 MOVQ R14, r14-40(SP) 252 MOVQ R15, r15-48(SP) 253 // We don't save mxcsr or the x87 control word because sigtrampgo doesn't 254 // modify them. 255 256 MOVQ DX, ctx-56(SP) 257 MOVQ SI, info-64(SP) 258 MOVQ DI, signum-72(SP) 259 CALL runtimesigtrampgo(SB) 260 261 MOVQ r15-48(SP), R15 262 MOVQ r14-40(SP), R14 263 MOVQ r13-32(SP), R13 264 MOVQ r12-24(SP), R12 265 MOVQ bp-16(SP), BP 266 MOVQ bx-8(SP), BX 267 RET 268 269 TEXT runtimemmap(SB),NOSPLIT,$0 270 MOVQ addr+0(FP), DI // arg 1 - addr 271 MOVQ n+8(FP), SI // arg 2 - len 272 MOVL prot+16(FP), DX // arg 3 - prot 273 MOVL flags+20(FP), R10 // arg 4 - flags 274 MOVL fd+24(FP), R8 // arg 5 - fd 275 MOVL off+28(FP), R9 276 SUBQ $16, SP 277 MOVQ R9, 8(SP) // arg 7 - offset (passed on stack) 278 MOVQ $0, R9 // arg 6 - pad 279 MOVL $197, AX 280 SYSCALL 281 ADDQ $16, SP 282 MOVQ AX, ret+32(FP) 283 RET 284 285 TEXT runtimemunmap(SB),NOSPLIT,$0 286 MOVQ addr+0(FP), DI // arg 1 - addr 287 MOVQ n+8(FP), SI // arg 2 - len 288 MOVL $73, AX // sys_munmap 289 SYSCALL 290 JCC 2(PC) 291 MOVL $0xf1, 0xf1 // crash 292 RET 293 294 TEXT runtimemadvise(SB),NOSPLIT,$0 295 MOVQ addr+0(FP), DI // arg 1 - addr 296 MOVQ n+8(FP), SI // arg 2 - len 297 MOVL flags+16(FP), DX // arg 3 - behav 298 MOVQ $75, AX // sys_madvise 299 SYSCALL 300 // ignore failure - maybe pages are locked 301 RET 302 303 TEXT runtimesigaltstack(SB),NOSPLIT,$-8 304 MOVQ new+0(FP), DI // arg 1 - nss 305 MOVQ old+8(FP), SI // arg 2 - oss 306 MOVQ $288, AX // sys_sigaltstack 307 SYSCALL 308 JCC 2(PC) 309 MOVL $0xf1, 0xf1 // crash 310 RET 311 312 // set tls base to DI 313 TEXT runtimesettls(SB),NOSPLIT,$0 314 // adjust for ELF: wants to use -8(FS) for g 315 ADDQ $8, DI 316 MOVQ $329, AX // sys___settcb 317 SYSCALL 318 JCC 2(PC) 319 MOVL $0xf1, 0xf1 // crash 320 RET 321 322 TEXT runtimesysctl(SB),NOSPLIT,$0 323 MOVQ mib+0(FP), DI // arg 1 - name 324 MOVL miblen+8(FP), SI // arg 2 - namelen 325 MOVQ out+16(FP), DX // arg 3 - oldp 326 MOVQ size+24(FP), R10 // arg 4 - oldlenp 327 MOVQ dst+32(FP), R8 // arg 5 - newp 328 MOVQ ndst+40(FP), R9 // arg 6 - newlen 329 MOVQ $202, AX // sys___sysctl 330 SYSCALL 331 JCC 4(PC) 332 NEGQ AX 333 MOVL AX, ret+48(FP) 334 RET 335 MOVL $0, AX 336 MOVL AX, ret+48(FP) 337 RET 338 339 // int32 runtimekqueue(void); 340 TEXT runtimekqueue(SB),NOSPLIT,$0 341 MOVQ $0, DI 342 MOVQ $0, SI 343 MOVQ $0, DX 344 MOVL $269, AX 345 SYSCALL 346 JCC 2(PC) 347 NEGQ AX 348 MOVL AX, ret+0(FP) 349 RET 350 351 // int32 runtimekevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout); 352 TEXT runtimekevent(SB),NOSPLIT,$0 353 MOVL kq+0(FP), DI 354 MOVQ ch+8(FP), SI 355 MOVL nch+16(FP), DX 356 MOVQ ev+24(FP), R10 357 MOVL nev+32(FP), R8 358 MOVQ ts+40(FP), R9 359 MOVL $72, AX 360 SYSCALL 361 JCC 2(PC) 362 NEGQ AX 363 MOVL AX, ret+48(FP) 364 RET 365 366 // void runtimecloseonexec(int32 fd); 367 TEXT runtimecloseonexec(SB),NOSPLIT,$0 368 MOVL fd+0(FP), DI // fd 369 MOVQ $2, SI // F_SETFD 370 MOVQ $1, DX // FD_CLOEXEC 371 MOVL $92, AX // fcntl 372 SYSCALL 373 RET 374