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