github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/src/runtime/sys_linux_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 // 6 // System calls and other sys.stuff for 386, Linux 7 // 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 #ifdef GOBUILDMODE_shared 14 #define INVOKE_SYSINFO CALL 0x10(GS) 15 #else 16 #define INVOKE_SYSINFO CALL *runtime·_vdso(SB) 17 #endif 18 19 TEXT runtime·exit(SB),NOSPLIT,$0 20 MOVL $252, AX // syscall number 21 MOVL code+0(FP), BX 22 INVOKE_SYSINFO 23 INT $3 // not reached 24 RET 25 26 TEXT runtime·exit1(SB),NOSPLIT,$0 27 MOVL $1, AX // exit - exit the current os thread 28 MOVL code+0(FP), BX 29 INVOKE_SYSINFO 30 INT $3 // not reached 31 RET 32 33 TEXT runtime·open(SB),NOSPLIT,$0 34 MOVL $5, AX // syscall - open 35 MOVL name+0(FP), BX 36 MOVL mode+4(FP), CX 37 MOVL perm+8(FP), DX 38 INVOKE_SYSINFO 39 CMPL AX, $0xfffff001 40 JLS 2(PC) 41 MOVL $-1, AX 42 MOVL AX, ret+12(FP) 43 RET 44 45 TEXT runtime·closefd(SB),NOSPLIT,$0 46 MOVL $6, AX // syscall - close 47 MOVL fd+0(FP), BX 48 INVOKE_SYSINFO 49 CMPL AX, $0xfffff001 50 JLS 2(PC) 51 MOVL $-1, AX 52 MOVL AX, ret+4(FP) 53 RET 54 55 TEXT runtime·write(SB),NOSPLIT,$0 56 MOVL $4, AX // syscall - write 57 MOVL fd+0(FP), BX 58 MOVL p+4(FP), CX 59 MOVL n+8(FP), DX 60 INVOKE_SYSINFO 61 CMPL AX, $0xfffff001 62 JLS 2(PC) 63 MOVL $-1, AX 64 MOVL AX, ret+12(FP) 65 RET 66 67 TEXT runtime·read(SB),NOSPLIT,$0 68 MOVL $3, AX // syscall - read 69 MOVL fd+0(FP), BX 70 MOVL p+4(FP), CX 71 MOVL n+8(FP), DX 72 INVOKE_SYSINFO 73 CMPL AX, $0xfffff001 74 JLS 2(PC) 75 MOVL $-1, AX 76 MOVL AX, ret+12(FP) 77 RET 78 79 TEXT runtime·getrlimit(SB),NOSPLIT,$0 80 MOVL $191, AX // syscall - ugetrlimit 81 MOVL kind+0(FP), BX 82 MOVL limit+4(FP), CX 83 INVOKE_SYSINFO 84 MOVL AX, ret+8(FP) 85 RET 86 87 TEXT runtime·usleep(SB),NOSPLIT,$8 88 MOVL $0, DX 89 MOVL usec+0(FP), AX 90 MOVL $1000000, CX 91 DIVL CX 92 MOVL AX, 0(SP) 93 MOVL DX, 4(SP) 94 95 // select(0, 0, 0, 0, &tv) 96 MOVL $142, AX 97 MOVL $0, BX 98 MOVL $0, CX 99 MOVL $0, DX 100 MOVL $0, SI 101 LEAL 0(SP), DI 102 INVOKE_SYSINFO 103 RET 104 105 TEXT runtime·gettid(SB),NOSPLIT,$0-4 106 MOVL $224, AX // syscall - gettid 107 INVOKE_SYSINFO 108 MOVL AX, ret+0(FP) 109 RET 110 111 TEXT runtime·raise(SB),NOSPLIT,$12 112 MOVL $224, AX // syscall - gettid 113 INVOKE_SYSINFO 114 MOVL AX, BX // arg 1 tid 115 MOVL sig+0(FP), CX // arg 2 signal 116 MOVL $238, AX // syscall - tkill 117 INVOKE_SYSINFO 118 RET 119 120 TEXT runtime·raiseproc(SB),NOSPLIT,$12 121 MOVL $20, AX // syscall - getpid 122 INVOKE_SYSINFO 123 MOVL AX, BX // arg 1 pid 124 MOVL sig+0(FP), CX // arg 2 signal 125 MOVL $37, AX // syscall - kill 126 INVOKE_SYSINFO 127 RET 128 129 TEXT runtime·setitimer(SB),NOSPLIT,$0-12 130 MOVL $104, AX // syscall - setitimer 131 MOVL mode+0(FP), BX 132 MOVL new+4(FP), CX 133 MOVL old+8(FP), DX 134 INVOKE_SYSINFO 135 RET 136 137 TEXT runtime·mincore(SB),NOSPLIT,$0-16 138 MOVL $218, AX // syscall - mincore 139 MOVL addr+0(FP), BX 140 MOVL n+4(FP), CX 141 MOVL dst+8(FP), DX 142 INVOKE_SYSINFO 143 MOVL AX, ret+12(FP) 144 RET 145 146 // func now() (sec int64, nsec int32) 147 TEXT time·now(SB), NOSPLIT, $32 148 MOVL $265, AX // syscall - clock_gettime 149 MOVL $0, BX // CLOCK_REALTIME 150 LEAL 8(SP), CX 151 MOVL $0, DX 152 INVOKE_SYSINFO 153 MOVL 8(SP), AX // sec 154 MOVL 12(SP), BX // nsec 155 156 // sec is in AX, nsec in BX 157 MOVL AX, sec+0(FP) 158 MOVL $0, sec+4(FP) 159 MOVL BX, nsec+8(FP) 160 RET 161 162 // int64 nanotime(void) so really 163 // void nanotime(int64 *nsec) 164 TEXT runtime·nanotime(SB), NOSPLIT, $32 165 MOVL $265, AX // syscall - clock_gettime 166 MOVL $1, BX // CLOCK_MONOTONIC 167 LEAL 8(SP), CX 168 MOVL $0, DX 169 INVOKE_SYSINFO 170 MOVL 8(SP), AX // sec 171 MOVL 12(SP), BX // nsec 172 173 // sec is in AX, nsec in BX 174 // convert to DX:AX nsec 175 MOVL $1000000000, CX 176 MULL CX 177 ADDL BX, AX 178 ADCL $0, DX 179 180 MOVL AX, ret_lo+0(FP) 181 MOVL DX, ret_hi+4(FP) 182 RET 183 184 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0 185 MOVL $175, AX // syscall entry 186 MOVL sig+0(FP), BX 187 MOVL new+4(FP), CX 188 MOVL old+8(FP), DX 189 MOVL size+12(FP), SI 190 INVOKE_SYSINFO 191 CMPL AX, $0xfffff001 192 JLS 2(PC) 193 INT $3 194 RET 195 196 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0 197 MOVL $174, AX // syscall - rt_sigaction 198 MOVL sig+0(FP), BX 199 MOVL new+4(FP), CX 200 MOVL old+8(FP), DX 201 MOVL size+12(FP), SI 202 INVOKE_SYSINFO 203 MOVL AX, ret+16(FP) 204 RET 205 206 TEXT runtime·sigfwd(SB),NOSPLIT,$12-16 207 MOVL sig+4(FP), AX 208 MOVL AX, 0(SP) 209 MOVL info+8(FP), AX 210 MOVL AX, 4(SP) 211 MOVL ctx+12(FP), AX 212 MOVL AX, 8(SP) 213 MOVL fn+0(FP), AX 214 CALL AX 215 RET 216 217 TEXT runtime·sigtramp(SB),NOSPLIT,$12 218 MOVL sig+0(FP), BX 219 MOVL BX, 0(SP) 220 MOVL info+4(FP), BX 221 MOVL BX, 4(SP) 222 MOVL context+8(FP), BX 223 MOVL BX, 8(SP) 224 CALL runtime·sigtrampgo(SB) 225 RET 226 227 TEXT runtime·sigreturn(SB),NOSPLIT,$0 228 MOVL $173, AX // rt_sigreturn 229 // Sigreturn expects same SP as signal handler, 230 // so cannot CALL *runtime._vsdo(SB) here. 231 INT $0x80 232 INT $3 // not reached 233 RET 234 235 TEXT runtime·mmap(SB),NOSPLIT,$0 236 MOVL $192, AX // mmap2 237 MOVL addr+0(FP), BX 238 MOVL n+4(FP), CX 239 MOVL prot+8(FP), DX 240 MOVL flags+12(FP), SI 241 MOVL fd+16(FP), DI 242 MOVL off+20(FP), BP 243 SHRL $12, BP 244 INVOKE_SYSINFO 245 CMPL AX, $0xfffff001 246 JLS 3(PC) 247 NOTL AX 248 INCL AX 249 MOVL AX, ret+24(FP) 250 RET 251 252 TEXT runtime·munmap(SB),NOSPLIT,$0 253 MOVL $91, AX // munmap 254 MOVL addr+0(FP), BX 255 MOVL n+4(FP), CX 256 INVOKE_SYSINFO 257 CMPL AX, $0xfffff001 258 JLS 2(PC) 259 INT $3 260 RET 261 262 TEXT runtime·madvise(SB),NOSPLIT,$0 263 MOVL $219, AX // madvise 264 MOVL addr+0(FP), BX 265 MOVL n+4(FP), CX 266 MOVL flags+8(FP), DX 267 INVOKE_SYSINFO 268 // ignore failure - maybe pages are locked 269 RET 270 271 // int32 futex(int32 *uaddr, int32 op, int32 val, 272 // struct timespec *timeout, int32 *uaddr2, int32 val2); 273 TEXT runtime·futex(SB),NOSPLIT,$0 274 MOVL $240, AX // futex 275 MOVL addr+0(FP), BX 276 MOVL op+4(FP), CX 277 MOVL val+8(FP), DX 278 MOVL ts+12(FP), SI 279 MOVL addr2+16(FP), DI 280 MOVL val3+20(FP), BP 281 INVOKE_SYSINFO 282 MOVL AX, ret+24(FP) 283 RET 284 285 // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void)); 286 TEXT runtime·clone(SB),NOSPLIT,$0 287 MOVL $120, AX // clone 288 MOVL flags+0(FP), BX 289 MOVL stack+4(FP), CX 290 MOVL $0, DX // parent tid ptr 291 MOVL $0, DI // child tid ptr 292 293 // Copy mp, gp, fn off parent stack for use by child. 294 SUBL $16, CX 295 MOVL mm+8(FP), SI 296 MOVL SI, 0(CX) 297 MOVL gg+12(FP), SI 298 MOVL SI, 4(CX) 299 MOVL fn+16(FP), SI 300 MOVL SI, 8(CX) 301 MOVL $1234, 12(CX) 302 303 // cannot use CALL *runtime·_vdso(SB) here, because 304 // the stack changes during the system call (after 305 // CALL *runtime·_vdso(SB), the child is still using 306 // the parent's stack when executing its RET instruction). 307 INT $0x80 308 309 // In parent, return. 310 CMPL AX, $0 311 JEQ 3(PC) 312 MOVL AX, ret+20(FP) 313 RET 314 315 // Paranoia: check that SP is as we expect. 316 MOVL 12(SP), BP 317 CMPL BP, $1234 318 JEQ 2(PC) 319 INT $3 320 321 // Initialize AX to Linux tid 322 MOVL $224, AX 323 INVOKE_SYSINFO 324 325 MOVL 0(SP), BX // m 326 MOVL 4(SP), DX // g 327 MOVL 8(SP), SI // fn 328 329 CMPL BX, $0 330 JEQ nog 331 CMPL DX, $0 332 JEQ nog 333 334 MOVL AX, m_procid(BX) // save tid as m->procid 335 336 // set up ldt 7+id to point at m->tls. 337 // newosproc left the id in tls[0]. 338 LEAL m_tls(BX), BP 339 MOVL 0(BP), DI 340 ADDL $7, DI // m0 is LDT#7. count up. 341 // setldt(tls#, &tls, sizeof tls) 342 PUSHAL // save registers 343 PUSHL $32 // sizeof tls 344 PUSHL BP // &tls 345 PUSHL DI // tls # 346 CALL runtime·setldt(SB) 347 POPL AX 348 POPL AX 349 POPL AX 350 POPAL 351 352 // Now segment is established. Initialize m, g. 353 get_tls(AX) 354 MOVL DX, g(AX) 355 MOVL BX, g_m(DX) 356 357 CALL runtime·stackcheck(SB) // smashes AX, CX 358 MOVL 0(DX), DX // paranoia; check they are not nil 359 MOVL 0(BX), BX 360 361 // more paranoia; check that stack splitting code works 362 PUSHAL 363 CALL runtime·emptyfunc(SB) 364 POPAL 365 366 nog: 367 CALL SI // fn() 368 CALL runtime·exit1(SB) 369 MOVL $0x1234, 0x1005 370 371 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 372 MOVL $186, AX // sigaltstack 373 MOVL new+4(SP), BX 374 MOVL old+8(SP), CX 375 INVOKE_SYSINFO 376 CMPL AX, $0xfffff001 377 JLS 2(PC) 378 INT $3 379 RET 380 381 // <asm-i386/ldt.h> 382 // struct user_desc { 383 // unsigned int entry_number; 384 // unsigned long base_addr; 385 // unsigned int limit; 386 // unsigned int seg_32bit:1; 387 // unsigned int contents:2; 388 // unsigned int read_exec_only:1; 389 // unsigned int limit_in_pages:1; 390 // unsigned int seg_not_present:1; 391 // unsigned int useable:1; 392 // }; 393 #define SEG_32BIT 0x01 394 // contents are the 2 bits 0x02 and 0x04. 395 #define CONTENTS_DATA 0x00 396 #define CONTENTS_STACK 0x02 397 #define CONTENTS_CODE 0x04 398 #define READ_EXEC_ONLY 0x08 399 #define LIMIT_IN_PAGES 0x10 400 #define SEG_NOT_PRESENT 0x20 401 #define USEABLE 0x40 402 403 // setldt(int entry, int address, int limit) 404 TEXT runtime·setldt(SB),NOSPLIT,$32 405 MOVL entry+0(FP), BX // entry 406 MOVL address+4(FP), CX // base address 407 408 /* 409 * When linking against the system libraries, 410 * we use its pthread_create and let it set up %gs 411 * for us. When we do that, the private storage 412 * we get is not at 0(GS), but -4(GS). 413 * To insulate the rest of the tool chain from this 414 * ugliness, 8l rewrites 0(TLS) into -4(GS) for us. 415 * To accommodate that rewrite, we translate 416 * the address here and bump the limit to 0xffffffff (no limit) 417 * so that -4(GS) maps to 0(address). 418 * Also, the final 0(GS) (current 4(CX)) has to point 419 * to itself, to mimic ELF. 420 */ 421 ADDL $0x4, CX // address 422 MOVL CX, 0(CX) 423 424 // set up user_desc 425 LEAL 16(SP), AX // struct user_desc 426 MOVL BX, 0(AX) 427 MOVL CX, 4(AX) 428 MOVL $0xfffff, 8(AX) 429 MOVL $(SEG_32BIT|LIMIT_IN_PAGES|USEABLE|CONTENTS_DATA), 12(AX) // flag bits 430 431 // call modify_ldt 432 MOVL $1, BX // func = 1 (write) 433 MOVL AX, CX // user_desc 434 MOVL $16, DX // sizeof(user_desc) 435 MOVL $123, AX // syscall - modify_ldt 436 INVOKE_SYSINFO 437 438 // breakpoint on error 439 CMPL AX, $0xfffff001 440 JLS 2(PC) 441 INT $3 442 443 // compute segment selector - (entry*8+7) 444 MOVL entry+0(FP), AX 445 SHLL $3, AX 446 ADDL $7, AX 447 MOVW AX, GS 448 449 RET 450 451 TEXT runtime·osyield(SB),NOSPLIT,$0 452 MOVL $158, AX 453 INVOKE_SYSINFO 454 RET 455 456 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0 457 MOVL $242, AX // syscall - sched_getaffinity 458 MOVL pid+0(FP), BX 459 MOVL len+4(FP), CX 460 MOVL buf+8(FP), DX 461 INVOKE_SYSINFO 462 MOVL AX, ret+12(FP) 463 RET 464 465 // int32 runtime·epollcreate(int32 size); 466 TEXT runtime·epollcreate(SB),NOSPLIT,$0 467 MOVL $254, AX 468 MOVL size+0(FP), BX 469 INVOKE_SYSINFO 470 MOVL AX, ret+4(FP) 471 RET 472 473 // int32 runtime·epollcreate1(int32 flags); 474 TEXT runtime·epollcreate1(SB),NOSPLIT,$0 475 MOVL $329, AX 476 MOVL flags+0(FP), BX 477 INVOKE_SYSINFO 478 MOVL AX, ret+4(FP) 479 RET 480 481 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 482 TEXT runtime·epollctl(SB),NOSPLIT,$0 483 MOVL $255, AX 484 MOVL epfd+0(FP), BX 485 MOVL op+4(FP), CX 486 MOVL fd+8(FP), DX 487 MOVL ev+12(FP), SI 488 INVOKE_SYSINFO 489 MOVL AX, ret+16(FP) 490 RET 491 492 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 493 TEXT runtime·epollwait(SB),NOSPLIT,$0 494 MOVL $256, AX 495 MOVL epfd+0(FP), BX 496 MOVL ev+4(FP), CX 497 MOVL nev+8(FP), DX 498 MOVL timeout+12(FP), SI 499 INVOKE_SYSINFO 500 MOVL AX, ret+16(FP) 501 RET 502 503 // void runtime·closeonexec(int32 fd); 504 TEXT runtime·closeonexec(SB),NOSPLIT,$0 505 MOVL $55, AX // fcntl 506 MOVL fd+0(FP), BX // fd 507 MOVL $2, CX // F_SETFD 508 MOVL $1, DX // FD_CLOEXEC 509 INVOKE_SYSINFO 510 RET