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 386, 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 // Exit the entire program (like C exit) 16 TEXT runtimeexit(SB),NOSPLIT,$-4 17 MOVL $1, AX 18 INT $0x80 19 MOVL $0xf1, 0xf1 // crash 20 RET 21 22 TEXT runtimeexit1(SB),NOSPLIT,$8 23 MOVL $0, 0(SP) 24 MOVL $0, 4(SP) // arg 1 - notdead 25 MOVL $302, AX // sys___threxit 26 INT $0x80 27 JAE 2(PC) 28 MOVL $0xf1, 0xf1 // crash 29 RET 30 31 TEXT runtimeopen(SB),NOSPLIT,$-4 32 MOVL $5, AX 33 INT $0x80 34 JAE 2(PC) 35 MOVL $-1, AX 36 MOVL AX, ret+12(FP) 37 RET 38 39 TEXT runtimeclosefd(SB),NOSPLIT,$-4 40 MOVL $6, AX 41 INT $0x80 42 JAE 2(PC) 43 MOVL $-1, AX 44 MOVL AX, ret+4(FP) 45 RET 46 47 TEXT runtimeread(SB),NOSPLIT,$-4 48 MOVL $3, AX 49 INT $0x80 50 JAE 2(PC) 51 MOVL $-1, AX 52 MOVL AX, ret+12(FP) 53 RET 54 55 TEXT runtimewrite(SB),NOSPLIT,$-4 56 MOVL $4, AX // sys_write 57 INT $0x80 58 JAE 2(PC) 59 MOVL $-1, AX 60 MOVL AX, ret+12(FP) 61 RET 62 63 TEXT runtimeusleep(SB),NOSPLIT,$24 64 MOVL $0, DX 65 MOVL usec+0(FP), AX 66 MOVL $1000000, CX 67 DIVL CX 68 MOVL AX, 12(SP) // tv_sec - l32 69 MOVL $0, 16(SP) // tv_sec - h32 70 MOVL $1000, AX 71 MULL DX 72 MOVL AX, 20(SP) // tv_nsec 73 74 MOVL $0, 0(SP) 75 LEAL 12(SP), AX 76 MOVL AX, 4(SP) // arg 1 - rqtp 77 MOVL $0, 8(SP) // arg 2 - rmtp 78 MOVL $91, AX // sys_nanosleep 79 INT $0x80 80 RET 81 82 TEXT runtimeraise(SB),NOSPLIT,$12 83 MOVL $299, AX // sys_getthrid 84 INT $0x80 85 MOVL $0, 0(SP) 86 MOVL AX, 4(SP) // arg 1 - pid 87 MOVL sig+0(FP), AX 88 MOVL AX, 8(SP) // arg 2 - signum 89 MOVL $37, AX // sys_kill 90 INT $0x80 91 RET 92 93 TEXT runtimeraiseproc(SB),NOSPLIT,$12 94 MOVL $20, AX // sys_getpid 95 INT $0x80 96 MOVL $0, 0(SP) 97 MOVL AX, 4(SP) // arg 1 - pid 98 MOVL sig+0(FP), AX 99 MOVL AX, 8(SP) // arg 2 - signum 100 MOVL $37, AX // sys_kill 101 INT $0x80 102 RET 103 104 TEXT runtimemmap(SB),NOSPLIT,$36 105 LEAL addr+0(FP), SI 106 LEAL 4(SP), DI 107 CLD 108 MOVSL // arg 1 - addr 109 MOVSL // arg 2 - len 110 MOVSL // arg 3 - prot 111 MOVSL // arg 4 - flags 112 MOVSL // arg 5 - fd 113 MOVL $0, AX 114 STOSL // arg 6 - pad 115 MOVSL // arg 7 - offset 116 MOVL $0, AX // top 32 bits of file offset 117 STOSL 118 MOVL $197, AX // sys_mmap 119 INT $0x80 120 MOVL AX, ret+24(FP) 121 RET 122 123 TEXT runtimemunmap(SB),NOSPLIT,$-4 124 MOVL $73, AX // sys_munmap 125 INT $0x80 126 JAE 2(PC) 127 MOVL $0xf1, 0xf1 // crash 128 RET 129 130 TEXT runtimemadvise(SB),NOSPLIT,$-4 131 MOVL $75, AX // sys_madvise 132 INT $0x80 133 JAE 2(PC) 134 MOVL $0xf1, 0xf1 // crash 135 RET 136 137 TEXT runtimesetitimer(SB),NOSPLIT,$-4 138 MOVL $69, AX 139 INT $0x80 140 RET 141 142 // func now() (sec int64, nsec int32) 143 TEXT timenow(SB), NOSPLIT, $32 144 LEAL 12(SP), BX 145 MOVL $0, 4(SP) // arg 1 - clock_id 146 MOVL BX, 8(SP) // arg 2 - tp 147 MOVL $87, AX // sys_clock_gettime 148 INT $0x80 149 150 MOVL 12(SP), AX // sec - l32 151 MOVL AX, sec+0(FP) 152 MOVL 16(SP), AX // sec - h32 153 MOVL AX, sec+4(FP) 154 155 MOVL 20(SP), BX // nsec 156 MOVL BX, nsec+8(FP) 157 RET 158 159 // int64 nanotime(void) so really 160 // void nanotime(int64 *nsec) 161 TEXT runtimenanotime(SB),NOSPLIT,$32 162 LEAL 12(SP), BX 163 MOVL CLOCK_MONOTONIC, 4(SP) // arg 1 - clock_id 164 MOVL BX, 8(SP) // arg 2 - tp 165 MOVL $87, AX // sys_clock_gettime 166 INT $0x80 167 168 MOVL 16(SP), CX // sec - h32 169 IMULL $1000000000, CX 170 171 MOVL 12(SP), AX // sec - l32 172 MOVL $1000000000, BX 173 MULL BX // result in dx:ax 174 175 MOVL 20(SP), BX // nsec 176 ADDL BX, AX 177 ADCL CX, DX // add high bits with carry 178 179 MOVL AX, ret_lo+0(FP) 180 MOVL DX, ret_hi+4(FP) 181 RET 182 183 TEXT runtimesigaction(SB),NOSPLIT,$-4 184 MOVL $46, AX // sys_sigaction 185 INT $0x80 186 JAE 2(PC) 187 MOVL $0xf1, 0xf1 // crash 188 RET 189 190 TEXT runtimesigprocmask(SB),NOSPLIT,$-4 191 MOVL $48, AX // sys_sigprocmask 192 INT $0x80 193 JAE 2(PC) 194 MOVL $0xf1, 0xf1 // crash 195 MOVL AX, ret+8(FP) 196 RET 197 198 TEXT runtimesigtramp(SB),NOSPLIT,$44 199 get_tls(CX) 200 201 // check that g exists 202 MOVL g(CX), DI 203 CMPL DI, $0 204 JNE 6(PC) 205 MOVL signo+0(FP), BX 206 MOVL BX, 0(SP) 207 MOVL $runtimebadsignal(SB), AX 208 CALL AX 209 JMP ret 210 211 // save g 212 MOVL DI, 20(SP) 213 214 // g = m->gsignal 215 MOVL g_m(DI), BX 216 MOVL m_gsignal(BX), BX 217 MOVL BX, g(CX) 218 219 // copy arguments for call to sighandler 220 MOVL signo+0(FP), BX 221 MOVL BX, 0(SP) 222 MOVL info+4(FP), BX 223 MOVL BX, 4(SP) 224 MOVL context+8(FP), BX 225 MOVL BX, 8(SP) 226 MOVL DI, 12(SP) 227 228 CALL runtimesighandler(SB) 229 230 // restore g 231 get_tls(CX) 232 MOVL 20(SP), BX 233 MOVL BX, g(CX) 234 235 ret: 236 // call sigreturn 237 MOVL context+8(FP), AX 238 MOVL $0, 0(SP) // syscall gap 239 MOVL AX, 4(SP) // arg 1 - sigcontext 240 MOVL $103, AX // sys_sigreturn 241 INT $0x80 242 MOVL $0xf1, 0xf1 // crash 243 RET 244 245 // int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void)); 246 TEXT runtimetfork(SB),NOSPLIT,$12 247 248 // Copy mp, gp and fn from the parent stack onto the child stack. 249 MOVL param+0(FP), AX 250 MOVL 8(AX), CX // tf_stack 251 SUBL $16, CX 252 MOVL CX, 8(AX) 253 MOVL mm+8(FP), SI 254 MOVL SI, 0(CX) 255 MOVL gg+12(FP), SI 256 MOVL SI, 4(CX) 257 MOVL fn+16(FP), SI 258 MOVL SI, 8(CX) 259 MOVL $1234, 12(CX) 260 261 MOVL $0, 0(SP) // syscall gap 262 MOVL param+0(FP), AX 263 MOVL AX, 4(SP) // arg 1 - param 264 MOVL psize+4(FP), AX 265 MOVL AX, 8(SP) // arg 2 - psize 266 MOVL $8, AX // sys___tfork 267 INT $0x80 268 269 // Return if tfork syscall failed. 270 JCC 4(PC) 271 NEGL AX 272 MOVL AX, ret+20(FP) 273 RET 274 275 // In parent, return. 276 CMPL AX, $0 277 JEQ 3(PC) 278 MOVL AX, ret+20(FP) 279 RET 280 281 // Paranoia: check that SP is as we expect. 282 MOVL 12(SP), BP 283 CMPL BP, $1234 284 JEQ 2(PC) 285 INT $3 286 287 // Reload registers. 288 MOVL 0(SP), BX // m 289 MOVL 4(SP), DX // g 290 MOVL 8(SP), SI // fn 291 292 // Set FS to point at m->tls. 293 LEAL m_tls(BX), BP 294 PUSHAL // save registers 295 PUSHL BP 296 CALL runtimesettls(SB) 297 POPL AX 298 POPAL 299 300 // Now segment is established. Initialize m, g. 301 get_tls(AX) 302 MOVL DX, g(AX) 303 MOVL BX, g_m(DX) 304 305 CALL runtimestackcheck(SB) // smashes AX, CX 306 MOVL 0(DX), DX // paranoia; check they are not nil 307 MOVL 0(BX), BX 308 309 // More paranoia; check that stack splitting code works. 310 PUSHAL 311 CALL runtimeemptyfunc(SB) 312 POPAL 313 314 // Call fn. 315 CALL SI 316 317 CALL runtimeexit1(SB) 318 MOVL $0x1234, 0x1005 319 RET 320 321 TEXT runtimesigaltstack(SB),NOSPLIT,$-8 322 MOVL $288, AX // sys_sigaltstack 323 MOVL new+4(SP), BX 324 MOVL old+8(SP), CX 325 INT $0x80 326 CMPL AX, $0xfffff001 327 JLS 2(PC) 328 INT $3 329 RET 330 331 TEXT runtimesetldt(SB),NOSPLIT,$4 332 // Under OpenBSD we set the GS base instead of messing with the LDT. 333 MOVL tls0+4(FP), AX 334 MOVL AX, 0(SP) 335 CALL runtimesettls(SB) 336 RET 337 338 TEXT runtimesettls(SB),NOSPLIT,$8 339 // adjust for ELF: wants to use -4(GS) for g 340 MOVL tlsbase+0(FP), CX 341 ADDL $4, CX 342 MOVL $0, 0(SP) // syscall gap 343 MOVL CX, 4(SP) // arg 1 - tcb 344 MOVL $329, AX // sys___set_tcb 345 INT $0x80 346 JCC 2(PC) 347 MOVL $0xf1, 0xf1 // crash 348 RET 349 350 TEXT runtimeosyield(SB),NOSPLIT,$-4 351 MOVL $298, AX // sys_sched_yield 352 INT $0x80 353 RET 354 355 TEXT runtimethrsleep(SB),NOSPLIT,$-4 356 MOVL $94, AX // sys___thrsleep 357 INT $0x80 358 MOVL AX, ret+20(FP) 359 RET 360 361 TEXT runtimethrwakeup(SB),NOSPLIT,$-4 362 MOVL $301, AX // sys___thrwakeup 363 INT $0x80 364 MOVL AX, ret+8(FP) 365 RET 366 367 TEXT runtimesysctl(SB),NOSPLIT,$28 368 LEAL mib+0(FP), SI 369 LEAL 4(SP), DI 370 CLD 371 MOVSL // arg 1 - name 372 MOVSL // arg 2 - namelen 373 MOVSL // arg 3 - oldp 374 MOVSL // arg 4 - oldlenp 375 MOVSL // arg 5 - newp 376 MOVSL // arg 6 - newlen 377 MOVL $202, AX // sys___sysctl 378 INT $0x80 379 JCC 4(PC) 380 NEGL AX 381 MOVL AX, ret+24(FP) 382 RET 383 MOVL $0, AX 384 MOVL AX, ret+24(FP) 385 RET 386 387 // int32 runtimekqueue(void); 388 TEXT runtimekqueue(SB),NOSPLIT,$0 389 MOVL $269, AX 390 INT $0x80 391 JAE 2(PC) 392 NEGL AX 393 MOVL AX, ret+0(FP) 394 RET 395 396 // int32 runtimekevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout); 397 TEXT runtimekevent(SB),NOSPLIT,$0 398 MOVL $72, AX // sys_kevent 399 INT $0x80 400 JAE 2(PC) 401 NEGL AX 402 MOVL AX, ret+24(FP) 403 RET 404 405 // int32 runtimecloseonexec(int32 fd); 406 TEXT runtimecloseonexec(SB),NOSPLIT,$32 407 MOVL $92, AX // sys_fcntl 408 // 0(SP) is where the caller PC would be; kernel skips it 409 MOVL fd+0(FP), BX 410 MOVL BX, 4(SP) // fd 411 MOVL $2, 8(SP) // F_SETFD 412 MOVL $1, 12(SP) // FD_CLOEXEC 413 INT $0x80 414 JAE 2(PC) 415 NEGL AX 416 RET 417 418 GLOBL runtimetlsoffset(SB),NOPTR,$4 419