Text file src/runtime/sys_linux_386.s
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 // Most linux systems use glibc's dynamic linker, which puts the
14 // __kernel_vsyscall vdso helper at 0x10(GS) for easy access from position
15 // independent code and setldt in runtime does the same in the statically
16 // linked case. However, systems that use alternative libc such as Android's
17 // bionic and musl, do not save the helper anywhere, and so the only way to
18 // invoke a syscall from position independent code is boring old int $0x80
19 // (which is also what syscall wrappers in bionic/musl use).
20 //
21 // The benchmarks also showed that using int $0x80 is as fast as calling
22 // *%gs:0x10 except on AMD Opteron. See https://golang.org/cl/19833
23 // for the benchmark program and raw data.
24 //#define INVOKE_SYSCALL CALL 0x10(GS) // non-portable
25 #define INVOKE_SYSCALL INT $0x80
26
27 #define SYS_exit 1
28 #define SYS_read 3
29 #define SYS_write 4
30 #define SYS_open 5
31 #define SYS_close 6
32 #define SYS_getpid 20
33 #define SYS_access 33
34 #define SYS_kill 37
35 #define SYS_brk 45
36 #define SYS_fcntl 55
37 #define SYS_munmap 91
38 #define SYS_socketcall 102
39 #define SYS_setittimer 104
40 #define SYS_clone 120
41 #define SYS_sched_yield 158
42 #define SYS_nanosleep 162
43 #define SYS_rt_sigreturn 173
44 #define SYS_rt_sigaction 174
45 #define SYS_rt_sigprocmask 175
46 #define SYS_sigaltstack 186
47 #define SYS_mmap2 192
48 #define SYS_mincore 218
49 #define SYS_madvise 219
50 #define SYS_gettid 224
51 #define SYS_futex 240
52 #define SYS_sched_getaffinity 242
53 #define SYS_set_thread_area 243
54 #define SYS_exit_group 252
55 #define SYS_epoll_create 254
56 #define SYS_epoll_ctl 255
57 #define SYS_epoll_wait 256
58 #define SYS_clock_gettime 265
59 #define SYS_tgkill 270
60 #define SYS_epoll_create1 329
61
62 TEXT runtime·exit(SB),NOSPLIT,$0
63 MOVL $SYS_exit_group, AX
64 MOVL code+0(FP), BX
65 INVOKE_SYSCALL
66 INT $3 // not reached
67 RET
68
69 TEXT exit1<>(SB),NOSPLIT,$0
70 MOVL $SYS_exit, AX
71 MOVL code+0(FP), BX
72 INVOKE_SYSCALL
73 INT $3 // not reached
74 RET
75
76 // func exitThread(wait *uint32)
77 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
78 MOVL wait+0(FP), AX
79 // We're done using the stack.
80 MOVL $0, (AX)
81 MOVL $1, AX // exit (just this thread)
82 MOVL $0, BX // exit code
83 INT $0x80 // no stack; must not use CALL
84 // We may not even have a stack any more.
85 INT $3
86 JMP 0(PC)
87
88 TEXT runtime·open(SB),NOSPLIT,$0
89 MOVL $SYS_open, AX
90 MOVL name+0(FP), BX
91 MOVL mode+4(FP), CX
92 MOVL perm+8(FP), DX
93 INVOKE_SYSCALL
94 CMPL AX, $0xfffff001
95 JLS 2(PC)
96 MOVL $-1, AX
97 MOVL AX, ret+12(FP)
98 RET
99
100 TEXT runtime·closefd(SB),NOSPLIT,$0
101 MOVL $SYS_close, AX
102 MOVL fd+0(FP), BX
103 INVOKE_SYSCALL
104 CMPL AX, $0xfffff001
105 JLS 2(PC)
106 MOVL $-1, AX
107 MOVL AX, ret+4(FP)
108 RET
109
110 TEXT runtime·write(SB),NOSPLIT,$0
111 MOVL $SYS_write, AX
112 MOVL fd+0(FP), BX
113 MOVL p+4(FP), CX
114 MOVL n+8(FP), DX
115 INVOKE_SYSCALL
116 CMPL AX, $0xfffff001
117 JLS 2(PC)
118 MOVL $-1, AX
119 MOVL AX, ret+12(FP)
120 RET
121
122 TEXT runtime·read(SB),NOSPLIT,$0
123 MOVL $SYS_read, AX
124 MOVL fd+0(FP), BX
125 MOVL p+4(FP), CX
126 MOVL n+8(FP), DX
127 INVOKE_SYSCALL
128 CMPL AX, $0xfffff001
129 JLS 2(PC)
130 MOVL $-1, AX
131 MOVL AX, ret+12(FP)
132 RET
133
134 TEXT runtime·usleep(SB),NOSPLIT,$8
135 MOVL $0, DX
136 MOVL usec+0(FP), AX
137 MOVL $1000000, CX
138 DIVL CX
139 MOVL AX, 0(SP)
140 MOVL $1000, AX // usec to nsec
141 MULL DX
142 MOVL AX, 4(SP)
143
144 // nanosleep(&ts, 0)
145 MOVL $SYS_nanosleep, AX
146 LEAL 0(SP), BX
147 MOVL $0, CX
148 INVOKE_SYSCALL
149 RET
150
151 TEXT runtime·gettid(SB),NOSPLIT,$0-4
152 MOVL $SYS_gettid, AX
153 INVOKE_SYSCALL
154 MOVL AX, ret+0(FP)
155 RET
156
157 TEXT runtime·raise(SB),NOSPLIT,$12
158 MOVL $SYS_getpid, AX
159 INVOKE_SYSCALL
160 MOVL AX, BX // arg 1 pid
161 MOVL $SYS_gettid, AX
162 INVOKE_SYSCALL
163 MOVL AX, CX // arg 2 tid
164 MOVL sig+0(FP), DX // arg 3 signal
165 MOVL $SYS_tgkill, AX
166 INVOKE_SYSCALL
167 RET
168
169 TEXT runtime·raiseproc(SB),NOSPLIT,$12
170 MOVL $SYS_getpid, AX
171 INVOKE_SYSCALL
172 MOVL AX, BX // arg 1 pid
173 MOVL sig+0(FP), CX // arg 2 signal
174 MOVL $SYS_kill, AX
175 INVOKE_SYSCALL
176 RET
177
178 TEXT runtime·setitimer(SB),NOSPLIT,$0-12
179 MOVL $SYS_setittimer, AX
180 MOVL mode+0(FP), BX
181 MOVL new+4(FP), CX
182 MOVL old+8(FP), DX
183 INVOKE_SYSCALL
184 RET
185
186 TEXT runtime·mincore(SB),NOSPLIT,$0-16
187 MOVL $SYS_mincore, AX
188 MOVL addr+0(FP), BX
189 MOVL n+4(FP), CX
190 MOVL dst+8(FP), DX
191 INVOKE_SYSCALL
192 MOVL AX, ret+12(FP)
193 RET
194
195 // func walltime() (sec int64, nsec int32)
196 TEXT runtime·walltime(SB), NOSPLIT, $0-12
197 // We don't know how much stack space the VDSO code will need,
198 // so switch to g0.
199
200 MOVL SP, BP // Save old SP; BP unchanged by C code.
201
202 get_tls(CX)
203 MOVL g(CX), AX
204 MOVL g_m(AX), SI // SI unchanged by C code.
205
206 // Set vdsoPC and vdsoSP for SIGPROF traceback.
207 MOVL 0(SP), DX
208 MOVL DX, m_vdsoPC(SI)
209 LEAL sec+0(SP), DX
210 MOVL DX, m_vdsoSP(SI)
211
212 CMPL AX, m_curg(SI) // Only switch if on curg.
213 JNE noswitch
214
215 MOVL m_g0(SI), DX
216 MOVL (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack
217
218 noswitch:
219 SUBL $16, SP // Space for results
220 ANDL $~15, SP // Align for C code
221
222 // Stack layout, depending on call path:
223 // x(SP) vDSO INVOKE_SYSCALL
224 // 12 ts.tv_nsec ts.tv_nsec
225 // 8 ts.tv_sec ts.tv_sec
226 // 4 &ts -
227 // 0 CLOCK_<id> -
228
229 MOVL runtime·vdsoClockgettimeSym(SB), AX
230 CMPL AX, $0
231 JEQ fallback
232
233 LEAL 8(SP), BX // &ts (struct timespec)
234 MOVL BX, 4(SP)
235 MOVL $0, 0(SP) // CLOCK_REALTIME
236 CALL AX
237 JMP finish
238
239 fallback:
240 MOVL $SYS_clock_gettime, AX
241 MOVL $0, BX // CLOCK_REALTIME
242 LEAL 8(SP), CX
243 INVOKE_SYSCALL
244
245 finish:
246 MOVL 8(SP), AX // sec
247 MOVL 12(SP), BX // nsec
248
249 MOVL BP, SP // Restore real SP
250 MOVL $0, m_vdsoSP(SI)
251
252 // sec is in AX, nsec in BX
253 MOVL AX, sec_lo+0(FP)
254 MOVL $0, sec_hi+4(FP)
255 MOVL BX, nsec+8(FP)
256 RET
257
258 // int64 nanotime(void) so really
259 // void nanotime(int64 *nsec)
260 TEXT runtime·nanotime(SB), NOSPLIT, $0-8
261 // Switch to g0 stack. See comment above in runtime·walltime.
262
263 MOVL SP, BP // Save old SP; BP unchanged by C code.
264
265 get_tls(CX)
266 MOVL g(CX), AX
267 MOVL g_m(AX), SI // SI unchanged by C code.
268
269 // Set vdsoPC and vdsoSP for SIGPROF traceback.
270 MOVL 0(SP), DX
271 MOVL DX, m_vdsoPC(SI)
272 LEAL ret+0(SP), DX
273 MOVL DX, m_vdsoSP(SI)
274
275 CMPL AX, m_curg(SI) // Only switch if on curg.
276 JNE noswitch
277
278 MOVL m_g0(SI), DX
279 MOVL (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack
280
281 noswitch:
282 SUBL $16, SP // Space for results
283 ANDL $~15, SP // Align for C code
284
285 MOVL runtime·vdsoClockgettimeSym(SB), AX
286 CMPL AX, $0
287 JEQ fallback
288
289 LEAL 8(SP), BX // &ts (struct timespec)
290 MOVL BX, 4(SP)
291 MOVL $1, 0(SP) // CLOCK_MONOTONIC
292 CALL AX
293 JMP finish
294
295 fallback:
296 MOVL $SYS_clock_gettime, AX
297 MOVL $1, BX // CLOCK_MONOTONIC
298 LEAL 8(SP), CX
299 INVOKE_SYSCALL
300
301 finish:
302 MOVL 8(SP), AX // sec
303 MOVL 12(SP), BX // nsec
304
305 MOVL BP, SP // Restore real SP
306 MOVL $0, m_vdsoSP(SI)
307
308 // sec is in AX, nsec in BX
309 // convert to DX:AX nsec
310 MOVL $1000000000, CX
311 MULL CX
312 ADDL BX, AX
313 ADCL $0, DX
314
315 MOVL AX, ret_lo+0(FP)
316 MOVL DX, ret_hi+4(FP)
317 RET
318
319 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
320 MOVL $SYS_rt_sigprocmask, AX
321 MOVL how+0(FP), BX
322 MOVL new+4(FP), CX
323 MOVL old+8(FP), DX
324 MOVL size+12(FP), SI
325 INVOKE_SYSCALL
326 CMPL AX, $0xfffff001
327 JLS 2(PC)
328 INT $3
329 RET
330
331 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
332 MOVL $SYS_rt_sigaction, AX
333 MOVL sig+0(FP), BX
334 MOVL new+4(FP), CX
335 MOVL old+8(FP), DX
336 MOVL size+12(FP), SI
337 INVOKE_SYSCALL
338 MOVL AX, ret+16(FP)
339 RET
340
341 TEXT runtime·sigfwd(SB),NOSPLIT,$12-16
342 MOVL fn+0(FP), AX
343 MOVL sig+4(FP), BX
344 MOVL info+8(FP), CX
345 MOVL ctx+12(FP), DX
346 MOVL SP, SI
347 SUBL $32, SP
348 ANDL $-15, SP // align stack: handler might be a C function
349 MOVL BX, 0(SP)
350 MOVL CX, 4(SP)
351 MOVL DX, 8(SP)
352 MOVL SI, 12(SP) // save SI: handler might be a Go function
353 CALL AX
354 MOVL 12(SP), AX
355 MOVL AX, SP
356 RET
357
358 TEXT runtime·sigtramp(SB),NOSPLIT,$28
359 // Save callee-saved C registers, since the caller may be a C signal handler.
360 MOVL BX, bx-4(SP)
361 MOVL BP, bp-8(SP)
362 MOVL SI, si-12(SP)
363 MOVL DI, di-16(SP)
364 // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
365 // modify them.
366
367 MOVL sig+0(FP), BX
368 MOVL BX, 0(SP)
369 MOVL info+4(FP), BX
370 MOVL BX, 4(SP)
371 MOVL ctx+8(FP), BX
372 MOVL BX, 8(SP)
373 CALL runtime·sigtrampgo(SB)
374
375 MOVL di-16(SP), DI
376 MOVL si-12(SP), SI
377 MOVL bp-8(SP), BP
378 MOVL bx-4(SP), BX
379 RET
380
381 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
382 JMP runtime·sigtramp(SB)
383
384 TEXT runtime·sigreturn(SB),NOSPLIT,$0
385 MOVL $SYS_rt_sigreturn, AX
386 // Sigreturn expects same SP as signal handler,
387 // so cannot CALL 0x10(GS) here.
388 INT $0x80
389 INT $3 // not reached
390 RET
391
392 TEXT runtime·mmap(SB),NOSPLIT,$0
393 MOVL $SYS_mmap2, AX
394 MOVL addr+0(FP), BX
395 MOVL n+4(FP), CX
396 MOVL prot+8(FP), DX
397 MOVL flags+12(FP), SI
398 MOVL fd+16(FP), DI
399 MOVL off+20(FP), BP
400 SHRL $12, BP
401 INVOKE_SYSCALL
402 CMPL AX, $0xfffff001
403 JLS ok
404 NOTL AX
405 INCL AX
406 MOVL $0, p+24(FP)
407 MOVL AX, err+28(FP)
408 RET
409 ok:
410 MOVL AX, p+24(FP)
411 MOVL $0, err+28(FP)
412 RET
413
414 TEXT runtime·munmap(SB),NOSPLIT,$0
415 MOVL $SYS_munmap, AX
416 MOVL addr+0(FP), BX
417 MOVL n+4(FP), CX
418 INVOKE_SYSCALL
419 CMPL AX, $0xfffff001
420 JLS 2(PC)
421 INT $3
422 RET
423
424 TEXT runtime·madvise(SB),NOSPLIT,$0
425 MOVL $SYS_madvise, AX
426 MOVL addr+0(FP), BX
427 MOVL n+4(FP), CX
428 MOVL flags+8(FP), DX
429 INVOKE_SYSCALL
430 MOVL AX, ret+12(FP)
431 RET
432
433 // int32 futex(int32 *uaddr, int32 op, int32 val,
434 // struct timespec *timeout, int32 *uaddr2, int32 val2);
435 TEXT runtime·futex(SB),NOSPLIT,$0
436 MOVL $SYS_futex, AX
437 MOVL addr+0(FP), BX
438 MOVL op+4(FP), CX
439 MOVL val+8(FP), DX
440 MOVL ts+12(FP), SI
441 MOVL addr2+16(FP), DI
442 MOVL val3+20(FP), BP
443 INVOKE_SYSCALL
444 MOVL AX, ret+24(FP)
445 RET
446
447 // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
448 TEXT runtime·clone(SB),NOSPLIT,$0
449 MOVL $SYS_clone, AX
450 MOVL flags+0(FP), BX
451 MOVL stk+4(FP), CX
452 MOVL $0, DX // parent tid ptr
453 MOVL $0, DI // child tid ptr
454
455 // Copy mp, gp, fn off parent stack for use by child.
456 SUBL $16, CX
457 MOVL mp+8(FP), SI
458 MOVL SI, 0(CX)
459 MOVL gp+12(FP), SI
460 MOVL SI, 4(CX)
461 MOVL fn+16(FP), SI
462 MOVL SI, 8(CX)
463 MOVL $1234, 12(CX)
464
465 // cannot use CALL 0x10(GS) here, because the stack changes during the
466 // system call (after CALL 0x10(GS), the child is still using the
467 // parent's stack when executing its RET instruction).
468 INT $0x80
469
470 // In parent, return.
471 CMPL AX, $0
472 JEQ 3(PC)
473 MOVL AX, ret+20(FP)
474 RET
475
476 // Paranoia: check that SP is as we expect.
477 NOP SP // tell vet SP changed - stop checking offsets
478 MOVL 12(SP), BP
479 CMPL BP, $1234
480 JEQ 2(PC)
481 INT $3
482
483 // Initialize AX to Linux tid
484 MOVL $SYS_gettid, AX
485 INVOKE_SYSCALL
486
487 MOVL 0(SP), BX // m
488 MOVL 4(SP), DX // g
489 MOVL 8(SP), SI // fn
490
491 CMPL BX, $0
492 JEQ nog
493 CMPL DX, $0
494 JEQ nog
495
496 MOVL AX, m_procid(BX) // save tid as m->procid
497
498 // set up ldt 7+id to point at m->tls.
499 LEAL m_tls(BX), BP
500 MOVL m_id(BX), DI
501 ADDL $7, DI // m0 is LDT#7. count up.
502 // setldt(tls#, &tls, sizeof tls)
503 PUSHAL // save registers
504 PUSHL $32 // sizeof tls
505 PUSHL BP // &tls
506 PUSHL DI // tls #
507 CALL runtime·setldt(SB)
508 POPL AX
509 POPL AX
510 POPL AX
511 POPAL
512
513 // Now segment is established. Initialize m, g.
514 get_tls(AX)
515 MOVL DX, g(AX)
516 MOVL BX, g_m(DX)
517
518 CALL runtime·stackcheck(SB) // smashes AX, CX
519 MOVL 0(DX), DX // paranoia; check they are not nil
520 MOVL 0(BX), BX
521
522 // more paranoia; check that stack splitting code works
523 PUSHAL
524 CALL runtime·emptyfunc(SB)
525 POPAL
526
527 nog:
528 CALL SI // fn()
529 CALL exit1<>(SB)
530 MOVL $0x1234, 0x1005
531
532 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
533 MOVL $SYS_sigaltstack, AX
534 MOVL new+0(FP), BX
535 MOVL old+4(FP), CX
536 INVOKE_SYSCALL
537 CMPL AX, $0xfffff001
538 JLS 2(PC)
539 INT $3
540 RET
541
542 // <asm-i386/ldt.h>
543 // struct user_desc {
544 // unsigned int entry_number;
545 // unsigned long base_addr;
546 // unsigned int limit;
547 // unsigned int seg_32bit:1;
548 // unsigned int contents:2;
549 // unsigned int read_exec_only:1;
550 // unsigned int limit_in_pages:1;
551 // unsigned int seg_not_present:1;
552 // unsigned int useable:1;
553 // };
554 #define SEG_32BIT 0x01
555 // contents are the 2 bits 0x02 and 0x04.
556 #define CONTENTS_DATA 0x00
557 #define CONTENTS_STACK 0x02
558 #define CONTENTS_CODE 0x04
559 #define READ_EXEC_ONLY 0x08
560 #define LIMIT_IN_PAGES 0x10
561 #define SEG_NOT_PRESENT 0x20
562 #define USEABLE 0x40
563
564 // `-1` means the kernel will pick a TLS entry on the first setldt call,
565 // which happens during runtime init, and that we'll store back the saved
566 // entry and reuse that on subsequent calls when creating new threads.
567 DATA runtime·tls_entry_number+0(SB)/4, $-1
568 GLOBL runtime·tls_entry_number(SB), NOPTR, $4
569
570 // setldt(int entry, int address, int limit)
571 // We use set_thread_area, which mucks with the GDT, instead of modify_ldt,
572 // which would modify the LDT, but is disabled on some kernels.
573 // The name, setldt, is a misnomer, although we leave this name as it is for
574 // the compatibility with other platforms.
575 TEXT runtime·setldt(SB),NOSPLIT,$32
576 MOVL base+4(FP), DX
577
578 #ifdef GOOS_android
579 // Android stores the TLS offset in runtime·tls_g.
580 SUBL runtime·tls_g(SB), DX
581 MOVL DX, 0(DX)
582 #else
583 /*
584 * When linking against the system libraries,
585 * we use its pthread_create and let it set up %gs
586 * for us. When we do that, the private storage
587 * we get is not at 0(GS), but -4(GS).
588 * To insulate the rest of the tool chain from this
589 * ugliness, 8l rewrites 0(TLS) into -4(GS) for us.
590 * To accommodate that rewrite, we translate
591 * the address here and bump the limit to 0xffffffff (no limit)
592 * so that -4(GS) maps to 0(address).
593 * Also, the final 0(GS) (current 4(DX)) has to point
594 * to itself, to mimic ELF.
595 */
596 ADDL $0x4, DX // address
597 MOVL DX, 0(DX)
598 #endif
599
600 // get entry number
601 MOVL runtime·tls_entry_number(SB), CX
602
603 // set up user_desc
604 LEAL 16(SP), AX // struct user_desc
605 MOVL CX, 0(AX) // unsigned int entry_number
606 MOVL DX, 4(AX) // unsigned long base_addr
607 MOVL $0xfffff, 8(AX) // unsigned int limit
608 MOVL $(SEG_32BIT|LIMIT_IN_PAGES|USEABLE|CONTENTS_DATA), 12(AX) // flag bits
609
610 // call set_thread_area
611 MOVL AX, BX // user_desc
612 MOVL $SYS_set_thread_area, AX
613 // We can't call this via 0x10(GS) because this is called from setldt0 to set that up.
614 INT $0x80
615
616 // breakpoint on error
617 CMPL AX, $0xfffff001
618 JLS 2(PC)
619 INT $3
620
621 // read allocated entry number back out of user_desc
622 LEAL 16(SP), AX // get our user_desc back
623 MOVL 0(AX), AX
624
625 // store entry number if the kernel allocated it
626 CMPL CX, $-1
627 JNE 2(PC)
628 MOVL AX, runtime·tls_entry_number(SB)
629
630 // compute segment selector - (entry*8+3)
631 SHLL $3, AX
632 ADDL $3, AX
633 MOVW AX, GS
634
635 RET
636
637 TEXT runtime·osyield(SB),NOSPLIT,$0
638 MOVL $SYS_sched_yield, AX
639 INVOKE_SYSCALL
640 RET
641
642 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
643 MOVL $SYS_sched_getaffinity, AX
644 MOVL pid+0(FP), BX
645 MOVL len+4(FP), CX
646 MOVL buf+8(FP), DX
647 INVOKE_SYSCALL
648 MOVL AX, ret+12(FP)
649 RET
650
651 // int32 runtime·epollcreate(int32 size);
652 TEXT runtime·epollcreate(SB),NOSPLIT,$0
653 MOVL $SYS_epoll_create, AX
654 MOVL size+0(FP), BX
655 INVOKE_SYSCALL
656 MOVL AX, ret+4(FP)
657 RET
658
659 // int32 runtime·epollcreate1(int32 flags);
660 TEXT runtime·epollcreate1(SB),NOSPLIT,$0
661 MOVL $SYS_epoll_create1, AX
662 MOVL flags+0(FP), BX
663 INVOKE_SYSCALL
664 MOVL AX, ret+4(FP)
665 RET
666
667 // func epollctl(epfd, op, fd int32, ev *epollEvent) int
668 TEXT runtime·epollctl(SB),NOSPLIT,$0
669 MOVL $SYS_epoll_ctl, AX
670 MOVL epfd+0(FP), BX
671 MOVL op+4(FP), CX
672 MOVL fd+8(FP), DX
673 MOVL ev+12(FP), SI
674 INVOKE_SYSCALL
675 MOVL AX, ret+16(FP)
676 RET
677
678 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
679 TEXT runtime·epollwait(SB),NOSPLIT,$0
680 MOVL $SYS_epoll_wait, AX
681 MOVL epfd+0(FP), BX
682 MOVL ev+4(FP), CX
683 MOVL nev+8(FP), DX
684 MOVL timeout+12(FP), SI
685 INVOKE_SYSCALL
686 MOVL AX, ret+16(FP)
687 RET
688
689 // void runtime·closeonexec(int32 fd);
690 TEXT runtime·closeonexec(SB),NOSPLIT,$0
691 MOVL $SYS_fcntl, AX
692 MOVL fd+0(FP), BX // fd
693 MOVL $2, CX // F_SETFD
694 MOVL $1, DX // FD_CLOEXEC
695 INVOKE_SYSCALL
696 RET
697
698 // int access(const char *name, int mode)
699 TEXT runtime·access(SB),NOSPLIT,$0
700 MOVL $SYS_access, AX
701 MOVL name+0(FP), BX
702 MOVL mode+4(FP), CX
703 INVOKE_SYSCALL
704 MOVL AX, ret+8(FP)
705 RET
706
707 // int connect(int fd, const struct sockaddr *addr, socklen_t addrlen)
708 TEXT runtime·connect(SB),NOSPLIT,$0-16
709 // connect is implemented as socketcall(NR_socket, 3, *(rest of args))
710 // stack already should have fd, addr, addrlen.
711 MOVL $SYS_socketcall, AX
712 MOVL $3, BX // connect
713 LEAL fd+0(FP), CX
714 INVOKE_SYSCALL
715 MOVL AX, ret+12(FP)
716 RET
717
718 // int socket(int domain, int type, int protocol)
719 TEXT runtime·socket(SB),NOSPLIT,$0-16
720 // socket is implemented as socketcall(NR_socket, 1, *(rest of args))
721 // stack already should have domain, type, protocol.
722 MOVL $SYS_socketcall, AX
723 MOVL $1, BX // socket
724 LEAL domain+0(FP), CX
725 INVOKE_SYSCALL
726 MOVL AX, ret+12(FP)
727 RET
728
729 // func sbrk0() uintptr
730 TEXT runtime·sbrk0(SB),NOSPLIT,$0-4
731 // Implemented as brk(NULL).
732 MOVL $SYS_brk, AX
733 MOVL $0, BX // NULL
734 INVOKE_SYSCALL
735 MOVL AX, ret+0(FP)
736 RET
View as plain text