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