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