github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/sys_freebsd_386.s (about) 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, FreeBSD 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_REALTIME 0 14 #define CLOCK_MONOTONIC 4 15 #define FD_CLOEXEC 1 16 #define F_SETFD 2 17 18 #define SYS_exit 1 19 #define SYS_read 3 20 #define SYS_write 4 21 #define SYS_open 5 22 #define SYS_close 6 23 #define SYS_getpid 20 24 #define SYS_kill 37 25 #define SYS_sigaltstack 53 26 #define SYS_munmap 73 27 #define SYS_madvise 75 28 #define SYS_setitimer 83 29 #define SYS_fcntl 92 30 #define SYS_sysarch 165 31 #define SYS___sysctl 202 32 #define SYS_clock_gettime 232 33 #define SYS_nanosleep 240 34 #define SYS_sched_yield 331 35 #define SYS_sigprocmask 340 36 #define SYS_kqueue 362 37 #define SYS_sigaction 416 38 #define SYS_sigreturn 417 39 #define SYS_thr_exit 431 40 #define SYS_thr_self 432 41 #define SYS_thr_kill 433 42 #define SYS__umtx_op 454 43 #define SYS_thr_new 455 44 #define SYS_mmap 477 45 #define SYS_cpuset_getaffinity 487 46 #define SYS_pipe2 542 47 #define SYS_kevent 560 48 49 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$-4 50 MOVL $SYS__umtx_op, AX 51 INT $0x80 52 JAE 2(PC) 53 NEGL AX 54 MOVL AX, ret+20(FP) 55 RET 56 57 TEXT runtime·thr_new(SB),NOSPLIT,$-4 58 MOVL $SYS_thr_new, AX 59 INT $0x80 60 JAE 2(PC) 61 NEGL AX 62 MOVL AX, ret+8(FP) 63 RET 64 65 // Called by OS using C ABI. 66 TEXT runtime·thr_start(SB),NOSPLIT,$0 67 NOP SP // tell vet SP changed - stop checking offsets 68 MOVL 4(SP), AX // m 69 MOVL m_g0(AX), BX 70 LEAL m_tls(AX), BP 71 MOVL m_id(AX), DI 72 ADDL $7, DI 73 PUSHAL 74 PUSHL $32 75 PUSHL BP 76 PUSHL DI 77 CALL runtime·setldt(SB) 78 POPL AX 79 POPL AX 80 POPL AX 81 POPAL 82 get_tls(CX) 83 MOVL BX, g(CX) 84 85 MOVL AX, g_m(BX) 86 CALL runtime·stackcheck(SB) // smashes AX 87 CALL runtime·mstart(SB) 88 89 MOVL 0, AX // crash (not reached) 90 91 // Exit the entire program (like C exit) 92 TEXT runtime·exit(SB),NOSPLIT,$-4 93 MOVL $SYS_exit, AX 94 INT $0x80 95 MOVL $0xf1, 0xf1 // crash 96 RET 97 98 GLOBL exitStack<>(SB),RODATA,$8 99 DATA exitStack<>+0x00(SB)/4, $0 100 DATA exitStack<>+0x04(SB)/4, $0 101 102 // func exitThread(wait *atomic.Uint32) 103 TEXT runtime·exitThread(SB),NOSPLIT,$0-4 104 MOVL wait+0(FP), AX 105 // We're done using the stack. 106 MOVL $0, (AX) 107 // thr_exit takes a single pointer argument, which it expects 108 // on the stack. We want to pass 0, so switch over to a fake 109 // stack of 0s. It won't write to the stack. 110 MOVL $exitStack<>(SB), SP 111 MOVL $SYS_thr_exit, AX 112 INT $0x80 113 MOVL $0xf1, 0xf1 // crash 114 JMP 0(PC) 115 116 TEXT runtime·open(SB),NOSPLIT,$-4 117 MOVL $SYS_open, AX 118 INT $0x80 119 JAE 2(PC) 120 MOVL $-1, AX 121 MOVL AX, ret+12(FP) 122 RET 123 124 TEXT runtime·closefd(SB),NOSPLIT,$-4 125 MOVL $SYS_close, AX 126 INT $0x80 127 JAE 2(PC) 128 MOVL $-1, AX 129 MOVL AX, ret+4(FP) 130 RET 131 132 TEXT runtime·read(SB),NOSPLIT,$-4 133 MOVL $SYS_read, AX 134 INT $0x80 135 JAE 2(PC) 136 NEGL AX // caller expects negative errno 137 MOVL AX, ret+12(FP) 138 RET 139 140 // func pipe2(flags int32) (r, w int32, errno int32) 141 TEXT runtime·pipe2(SB),NOSPLIT,$12-16 142 MOVL $SYS_pipe2, AX 143 LEAL r+4(FP), BX 144 MOVL BX, 4(SP) 145 MOVL flags+0(FP), BX 146 MOVL BX, 8(SP) 147 INT $0x80 148 JAE 2(PC) 149 NEGL AX 150 MOVL AX, errno+12(FP) 151 RET 152 153 TEXT runtime·write1(SB),NOSPLIT,$-4 154 MOVL $SYS_write, AX 155 INT $0x80 156 JAE 2(PC) 157 NEGL AX // caller expects negative errno 158 MOVL AX, ret+12(FP) 159 RET 160 161 TEXT runtime·thr_self(SB),NOSPLIT,$8-4 162 // thr_self(&0(FP)) 163 LEAL ret+0(FP), AX 164 MOVL AX, 4(SP) 165 MOVL $SYS_thr_self, AX 166 INT $0x80 167 RET 168 169 TEXT runtime·thr_kill(SB),NOSPLIT,$-4 170 // thr_kill(tid, sig) 171 MOVL $SYS_thr_kill, AX 172 INT $0x80 173 RET 174 175 TEXT runtime·raiseproc(SB),NOSPLIT,$16 176 // getpid 177 MOVL $SYS_getpid, AX 178 INT $0x80 179 // kill(self, sig) 180 MOVL AX, 4(SP) 181 MOVL sig+0(FP), AX 182 MOVL AX, 8(SP) 183 MOVL $SYS_kill, AX 184 INT $0x80 185 RET 186 187 TEXT runtime·mmap(SB),NOSPLIT,$32 188 LEAL addr+0(FP), SI 189 LEAL 4(SP), DI 190 CLD 191 MOVSL 192 MOVSL 193 MOVSL 194 MOVSL 195 MOVSL 196 MOVSL 197 MOVL $0, AX // top 32 bits of file offset 198 STOSL 199 MOVL $SYS_mmap, AX 200 INT $0x80 201 JAE ok 202 MOVL $0, p+24(FP) 203 MOVL AX, err+28(FP) 204 RET 205 ok: 206 MOVL AX, p+24(FP) 207 MOVL $0, err+28(FP) 208 RET 209 210 TEXT runtime·munmap(SB),NOSPLIT,$-4 211 MOVL $SYS_munmap, AX 212 INT $0x80 213 JAE 2(PC) 214 MOVL $0xf1, 0xf1 // crash 215 RET 216 217 TEXT runtime·madvise(SB),NOSPLIT,$-4 218 MOVL $SYS_madvise, AX 219 INT $0x80 220 JAE 2(PC) 221 MOVL $-1, AX 222 MOVL AX, ret+12(FP) 223 RET 224 225 TEXT runtime·setitimer(SB), NOSPLIT, $-4 226 MOVL $SYS_setitimer, AX 227 INT $0x80 228 RET 229 230 // func fallback_walltime() (sec int64, nsec int32) 231 TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12 232 MOVL $SYS_clock_gettime, AX 233 LEAL 12(SP), BX 234 MOVL $CLOCK_REALTIME, 4(SP) 235 MOVL BX, 8(SP) 236 INT $0x80 237 MOVL 12(SP), AX // sec 238 MOVL 16(SP), BX // nsec 239 240 // sec is in AX, nsec in BX 241 MOVL AX, sec_lo+0(FP) 242 MOVL $0, sec_hi+4(FP) 243 MOVL BX, nsec+8(FP) 244 RET 245 246 // func fallback_nanotime() int64 247 TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32-8 248 MOVL $SYS_clock_gettime, AX 249 LEAL 12(SP), BX 250 MOVL $CLOCK_MONOTONIC, 4(SP) 251 MOVL BX, 8(SP) 252 INT $0x80 253 MOVL 12(SP), AX // sec 254 MOVL 16(SP), BX // nsec 255 256 // sec is in AX, nsec in BX 257 // convert to DX:AX nsec 258 MOVL $1000000000, CX 259 MULL CX 260 ADDL BX, AX 261 ADCL $0, DX 262 263 MOVL AX, ret_lo+0(FP) 264 MOVL DX, ret_hi+4(FP) 265 RET 266 267 268 TEXT runtime·asmSigaction(SB),NOSPLIT,$-4 269 MOVL $SYS_sigaction, AX 270 INT $0x80 271 MOVL AX, ret+12(FP) 272 RET 273 274 TEXT runtime·sigfwd(SB),NOSPLIT,$12-16 275 MOVL fn+0(FP), AX 276 MOVL sig+4(FP), BX 277 MOVL info+8(FP), CX 278 MOVL ctx+12(FP), DX 279 MOVL SP, SI 280 SUBL $32, SP 281 ANDL $~15, SP // align stack: handler might be a C function 282 MOVL BX, 0(SP) 283 MOVL CX, 4(SP) 284 MOVL DX, 8(SP) 285 MOVL SI, 12(SP) // save SI: handler might be a Go function 286 CALL AX 287 MOVL 12(SP), AX 288 MOVL AX, SP 289 RET 290 291 // Called by OS using C ABI. 292 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$12 293 NOP SP // tell vet SP changed - stop checking offsets 294 MOVL 16(SP), BX // signo 295 MOVL BX, 0(SP) 296 MOVL 20(SP), BX // info 297 MOVL BX, 4(SP) 298 MOVL 24(SP), BX // context 299 MOVL BX, 8(SP) 300 CALL runtime·sigtrampgo(SB) 301 302 // call sigreturn 303 MOVL 24(SP), AX // context 304 MOVL $0, 0(SP) // syscall gap 305 MOVL AX, 4(SP) 306 MOVL $SYS_sigreturn, AX 307 INT $0x80 308 MOVL $0xf1, 0xf1 // crash 309 RET 310 311 TEXT runtime·sigaltstack(SB),NOSPLIT,$0 312 MOVL $SYS_sigaltstack, AX 313 INT $0x80 314 JAE 2(PC) 315 MOVL $0xf1, 0xf1 // crash 316 RET 317 318 TEXT runtime·usleep(SB),NOSPLIT,$20 319 MOVL $0, DX 320 MOVL usec+0(FP), AX 321 MOVL $1000000, CX 322 DIVL CX 323 MOVL AX, 12(SP) // tv_sec 324 MOVL $1000, AX 325 MULL DX 326 MOVL AX, 16(SP) // tv_nsec 327 328 MOVL $0, 0(SP) 329 LEAL 12(SP), AX 330 MOVL AX, 4(SP) // arg 1 - rqtp 331 MOVL $0, 8(SP) // arg 2 - rmtp 332 MOVL $SYS_nanosleep, AX 333 INT $0x80 334 RET 335 336 /* 337 descriptor entry format for system call 338 is the native machine format, ugly as it is: 339 340 2-byte limit 341 3-byte base 342 1-byte: 0x80=present, 0x60=dpl<<5, 0x1F=type 343 1-byte: 0x80=limit is *4k, 0x40=32-bit operand size, 344 0x0F=4 more bits of limit 345 1 byte: 8 more bits of base 346 347 int i386_get_ldt(int, union ldt_entry *, int); 348 int i386_set_ldt(int, const union ldt_entry *, int); 349 350 */ 351 352 // setldt(int entry, int address, int limit) 353 TEXT runtime·setldt(SB),NOSPLIT,$32 354 MOVL base+4(FP), BX 355 // see comment in sys_linux_386.s; freebsd is similar 356 ADDL $0x4, BX 357 358 // set up data_desc 359 LEAL 16(SP), AX // struct data_desc 360 MOVL $0, 0(AX) 361 MOVL $0, 4(AX) 362 363 MOVW BX, 2(AX) 364 SHRL $16, BX 365 MOVB BX, 4(AX) 366 SHRL $8, BX 367 MOVB BX, 7(AX) 368 369 MOVW $0xffff, 0(AX) 370 MOVB $0xCF, 6(AX) // 32-bit operand, 4k limit unit, 4 more bits of limit 371 372 MOVB $0xF2, 5(AX) // r/w data descriptor, dpl=3, present 373 374 // call i386_set_ldt(entry, desc, 1) 375 MOVL $0xffffffff, 0(SP) // auto-allocate entry and return in AX 376 MOVL AX, 4(SP) 377 MOVL $1, 8(SP) 378 CALL i386_set_ldt<>(SB) 379 380 // compute segment selector - (entry*8+7) 381 SHLL $3, AX 382 ADDL $7, AX 383 MOVW AX, GS 384 RET 385 386 TEXT i386_set_ldt<>(SB),NOSPLIT,$16 387 LEAL args+0(FP), AX // 0(FP) == 4(SP) before SP got moved 388 MOVL $0, 0(SP) // syscall gap 389 MOVL $1, 4(SP) 390 MOVL AX, 8(SP) 391 MOVL $SYS_sysarch, AX 392 INT $0x80 393 JAE 2(PC) 394 INT $3 395 RET 396 397 TEXT runtime·sysctl(SB),NOSPLIT,$28 398 LEAL mib+0(FP), SI 399 LEAL 4(SP), DI 400 CLD 401 MOVSL // arg 1 - name 402 MOVSL // arg 2 - namelen 403 MOVSL // arg 3 - oldp 404 MOVSL // arg 4 - oldlenp 405 MOVSL // arg 5 - newp 406 MOVSL // arg 6 - newlen 407 MOVL $SYS___sysctl, AX 408 INT $0x80 409 JAE 4(PC) 410 NEGL AX 411 MOVL AX, ret+24(FP) 412 RET 413 MOVL $0, AX 414 MOVL AX, ret+24(FP) 415 RET 416 417 TEXT runtime·osyield(SB),NOSPLIT,$-4 418 MOVL $SYS_sched_yield, AX 419 INT $0x80 420 RET 421 422 TEXT runtime·sigprocmask(SB),NOSPLIT,$16 423 MOVL $0, 0(SP) // syscall gap 424 MOVL how+0(FP), AX // arg 1 - how 425 MOVL AX, 4(SP) 426 MOVL new+4(FP), AX 427 MOVL AX, 8(SP) // arg 2 - set 428 MOVL old+8(FP), AX 429 MOVL AX, 12(SP) // arg 3 - oset 430 MOVL $SYS_sigprocmask, AX 431 INT $0x80 432 JAE 2(PC) 433 MOVL $0xf1, 0xf1 // crash 434 RET 435 436 // int32 runtime·kqueue(void); 437 TEXT runtime·kqueue(SB),NOSPLIT,$0 438 MOVL $SYS_kqueue, AX 439 INT $0x80 440 JAE 2(PC) 441 NEGL AX 442 MOVL AX, ret+0(FP) 443 RET 444 445 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout); 446 TEXT runtime·kevent(SB),NOSPLIT,$0 447 MOVL $SYS_kevent, AX 448 INT $0x80 449 JAE 2(PC) 450 NEGL AX 451 MOVL AX, ret+24(FP) 452 RET 453 454 // int32 runtime·closeonexec(int32 fd); 455 TEXT runtime·closeonexec(SB),NOSPLIT,$32 456 MOVL $SYS_fcntl, AX 457 // 0(SP) is where the caller PC would be; kernel skips it 458 MOVL fd+0(FP), BX 459 MOVL BX, 4(SP) // fd 460 MOVL $F_SETFD, 8(SP) 461 MOVL $FD_CLOEXEC, 12(SP) 462 INT $0x80 463 JAE 2(PC) 464 NEGL AX 465 RET 466 467 // func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32 468 TEXT runtime·cpuset_getaffinity(SB), NOSPLIT, $0-28 469 MOVL $SYS_cpuset_getaffinity, AX 470 INT $0x80 471 JAE 2(PC) 472 NEGL AX 473 MOVL AX, ret+24(FP) 474 RET 475 476 GLOBL runtime·tlsoffset(SB),NOPTR,$4