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