Text file src/runtime/sys_linux_amd64.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 AMD64, Linux
7 //
8
9 #include "go_asm.h"
10 #include "go_tls.h"
11 #include "textflag.h"
12
13 #define AT_FDCWD -100
14
15 #define SYS_read 0
16 #define SYS_write 1
17 #define SYS_close 3
18 #define SYS_mmap 9
19 #define SYS_munmap 11
20 #define SYS_brk 12
21 #define SYS_rt_sigaction 13
22 #define SYS_rt_sigprocmask 14
23 #define SYS_rt_sigreturn 15
24 #define SYS_sched_yield 24
25 #define SYS_mincore 27
26 #define SYS_madvise 28
27 #define SYS_nanosleep 35
28 #define SYS_setittimer 38
29 #define SYS_getpid 39
30 #define SYS_socket 41
31 #define SYS_connect 42
32 #define SYS_clone 56
33 #define SYS_exit 60
34 #define SYS_kill 62
35 #define SYS_fcntl 72
36 #define SYS_sigaltstack 131
37 #define SYS_arch_prctl 158
38 #define SYS_gettid 186
39 #define SYS_futex 202
40 #define SYS_sched_getaffinity 204
41 #define SYS_epoll_create 213
42 #define SYS_exit_group 231
43 #define SYS_epoll_ctl 233
44 #define SYS_tgkill 234
45 #define SYS_openat 257
46 #define SYS_faccessat 269
47 #define SYS_epoll_pwait 281
48 #define SYS_epoll_create1 291
49
50 TEXT runtime·exit(SB),NOSPLIT,$0-4
51 MOVL code+0(FP), DI
52 MOVL $SYS_exit_group, AX
53 SYSCALL
54 RET
55
56 // func exitThread(wait *uint32)
57 TEXT runtime·exitThread(SB),NOSPLIT,$0-8
58 MOVQ wait+0(FP), AX
59 // We're done using the stack.
60 MOVL $0, (AX)
61 MOVL $0, DI // exit code
62 MOVL $SYS_exit, AX
63 SYSCALL
64 // We may not even have a stack any more.
65 INT $3
66 JMP 0(PC)
67
68 TEXT runtime·open(SB),NOSPLIT,$0-20
69 // This uses openat instead of open, because Android O blocks open.
70 MOVL $AT_FDCWD, DI // AT_FDCWD, so this acts like open
71 MOVQ name+0(FP), SI
72 MOVL mode+8(FP), DX
73 MOVL perm+12(FP), R10
74 MOVL $SYS_openat, AX
75 SYSCALL
76 CMPQ AX, $0xfffffffffffff001
77 JLS 2(PC)
78 MOVL $-1, AX
79 MOVL AX, ret+16(FP)
80 RET
81
82 TEXT runtime·closefd(SB),NOSPLIT,$0-12
83 MOVL fd+0(FP), DI
84 MOVL $SYS_close, AX
85 SYSCALL
86 CMPQ AX, $0xfffffffffffff001
87 JLS 2(PC)
88 MOVL $-1, AX
89 MOVL AX, ret+8(FP)
90 RET
91
92 TEXT runtime·write(SB),NOSPLIT,$0-28
93 MOVQ fd+0(FP), DI
94 MOVQ p+8(FP), SI
95 MOVL n+16(FP), DX
96 MOVL $SYS_write, AX
97 SYSCALL
98 CMPQ AX, $0xfffffffffffff001
99 JLS 2(PC)
100 MOVL $-1, AX
101 MOVL AX, ret+24(FP)
102 RET
103
104 TEXT runtime·read(SB),NOSPLIT,$0-28
105 MOVL fd+0(FP), DI
106 MOVQ p+8(FP), SI
107 MOVL n+16(FP), DX
108 MOVL $SYS_read, AX
109 SYSCALL
110 CMPQ AX, $0xfffffffffffff001
111 JLS 2(PC)
112 MOVL $-1, AX
113 MOVL AX, ret+24(FP)
114 RET
115
116 TEXT runtime·usleep(SB),NOSPLIT,$16
117 MOVL $0, DX
118 MOVL usec+0(FP), AX
119 MOVL $1000000, CX
120 DIVL CX
121 MOVQ AX, 0(SP)
122 MOVL $1000, AX // usec to nsec
123 MULL DX
124 MOVQ AX, 8(SP)
125
126 // nanosleep(&ts, 0)
127 MOVQ SP, DI
128 MOVL $0, SI
129 MOVL $SYS_nanosleep, AX
130 SYSCALL
131 RET
132
133 TEXT runtime·gettid(SB),NOSPLIT,$0-4
134 MOVL $SYS_gettid, AX
135 SYSCALL
136 MOVL AX, ret+0(FP)
137 RET
138
139 TEXT runtime·raise(SB),NOSPLIT,$0
140 MOVL $SYS_getpid, AX
141 SYSCALL
142 MOVL AX, R12
143 MOVL $SYS_gettid, AX
144 SYSCALL
145 MOVL AX, SI // arg 2 tid
146 MOVL R12, DI // arg 1 pid
147 MOVL sig+0(FP), DX // arg 3
148 MOVL $SYS_tgkill, AX
149 SYSCALL
150 RET
151
152 TEXT runtime·raiseproc(SB),NOSPLIT,$0
153 MOVL $SYS_getpid, AX
154 SYSCALL
155 MOVL AX, DI // arg 1 pid
156 MOVL sig+0(FP), SI // arg 2
157 MOVL $SYS_kill, AX
158 SYSCALL
159 RET
160
161 TEXT runtime·setitimer(SB),NOSPLIT,$0-24
162 MOVL mode+0(FP), DI
163 MOVQ new+8(FP), SI
164 MOVQ old+16(FP), DX
165 MOVL $SYS_setittimer, AX
166 SYSCALL
167 RET
168
169 TEXT runtime·mincore(SB),NOSPLIT,$0-28
170 MOVQ addr+0(FP), DI
171 MOVQ n+8(FP), SI
172 MOVQ dst+16(FP), DX
173 MOVL $SYS_mincore, AX
174 SYSCALL
175 MOVL AX, ret+24(FP)
176 RET
177
178 // func walltime() (sec int64, nsec int32)
179 TEXT runtime·walltime(SB),NOSPLIT,$0-12
180 // We don't know how much stack space the VDSO code will need,
181 // so switch to g0.
182 // In particular, a kernel configured with CONFIG_OPTIMIZE_INLINING=n
183 // and hardening can use a full page of stack space in gettime_sym
184 // due to stack probes inserted to avoid stack/heap collisions.
185 // See issue #20427.
186
187 MOVQ SP, BP // Save old SP; BP unchanged by C code.
188
189 get_tls(CX)
190 MOVQ g(CX), AX
191 MOVQ g_m(AX), BX // BX unchanged by C code.
192
193 // Set vdsoPC and vdsoSP for SIGPROF traceback.
194 MOVQ 0(SP), DX
195 MOVQ DX, m_vdsoPC(BX)
196 LEAQ sec+0(SP), DX
197 MOVQ DX, m_vdsoSP(BX)
198
199 CMPQ AX, m_curg(BX) // Only switch if on curg.
200 JNE noswitch
201
202 MOVQ m_g0(BX), DX
203 MOVQ (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack
204
205 noswitch:
206 SUBQ $16, SP // Space for results
207 ANDQ $~15, SP // Align for C code
208
209 MOVQ runtime·vdsoClockgettimeSym(SB), AX
210 CMPQ AX, $0
211 JEQ fallback
212 MOVL $0, DI // CLOCK_REALTIME
213 LEAQ 0(SP), SI
214 CALL AX
215 MOVQ 0(SP), AX // sec
216 MOVQ 8(SP), DX // nsec
217 MOVQ BP, SP // Restore real SP
218 MOVQ $0, m_vdsoSP(BX)
219 MOVQ AX, sec+0(FP)
220 MOVL DX, nsec+8(FP)
221 RET
222 fallback:
223 LEAQ 0(SP), DI
224 MOVQ $0, SI
225 MOVQ runtime·vdsoGettimeofdaySym(SB), AX
226 CALL AX
227 MOVQ 0(SP), AX // sec
228 MOVL 8(SP), DX // usec
229 IMULQ $1000, DX
230 MOVQ BP, SP // Restore real SP
231 MOVQ $0, m_vdsoSP(BX)
232 MOVQ AX, sec+0(FP)
233 MOVL DX, nsec+8(FP)
234 RET
235
236 TEXT runtime·nanotime(SB),NOSPLIT,$0-8
237 // Switch to g0 stack. See comment above in runtime·walltime.
238
239 MOVQ SP, BP // Save old SP; BP unchanged by C code.
240
241 get_tls(CX)
242 MOVQ g(CX), AX
243 MOVQ g_m(AX), BX // BX unchanged by C code.
244
245 // Set vdsoPC and vdsoSP for SIGPROF traceback.
246 MOVQ 0(SP), DX
247 MOVQ DX, m_vdsoPC(BX)
248 LEAQ ret+0(SP), DX
249 MOVQ DX, m_vdsoSP(BX)
250
251 CMPQ AX, m_curg(BX) // Only switch if on curg.
252 JNE noswitch
253
254 MOVQ m_g0(BX), DX
255 MOVQ (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack
256
257 noswitch:
258 SUBQ $16, SP // Space for results
259 ANDQ $~15, SP // Align for C code
260
261 MOVQ runtime·vdsoClockgettimeSym(SB), AX
262 CMPQ AX, $0
263 JEQ fallback
264 MOVL $1, DI // CLOCK_MONOTONIC
265 LEAQ 0(SP), SI
266 CALL AX
267 MOVQ 0(SP), AX // sec
268 MOVQ 8(SP), DX // nsec
269 MOVQ BP, SP // Restore real SP
270 MOVQ $0, m_vdsoSP(BX)
271 // sec is in AX, nsec in DX
272 // return nsec in AX
273 IMULQ $1000000000, AX
274 ADDQ DX, AX
275 MOVQ AX, ret+0(FP)
276 RET
277 fallback:
278 LEAQ 0(SP), DI
279 MOVQ $0, SI
280 MOVQ runtime·vdsoGettimeofdaySym(SB), AX
281 CALL AX
282 MOVQ 0(SP), AX // sec
283 MOVL 8(SP), DX // usec
284 MOVQ BP, SP // Restore real SP
285 MOVQ $0, m_vdsoSP(BX)
286 IMULQ $1000, DX
287 // sec is in AX, nsec in DX
288 // return nsec in AX
289 IMULQ $1000000000, AX
290 ADDQ DX, AX
291 MOVQ AX, ret+0(FP)
292 RET
293
294 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-28
295 MOVL how+0(FP), DI
296 MOVQ new+8(FP), SI
297 MOVQ old+16(FP), DX
298 MOVL size+24(FP), R10
299 MOVL $SYS_rt_sigprocmask, AX
300 SYSCALL
301 CMPQ AX, $0xfffffffffffff001
302 JLS 2(PC)
303 MOVL $0xf1, 0xf1 // crash
304 RET
305
306 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-36
307 MOVQ sig+0(FP), DI
308 MOVQ new+8(FP), SI
309 MOVQ old+16(FP), DX
310 MOVQ size+24(FP), R10
311 MOVL $SYS_rt_sigaction, AX
312 SYSCALL
313 MOVL AX, ret+32(FP)
314 RET
315
316 // Call the function stored in _cgo_sigaction using the GCC calling convention.
317 TEXT runtime·callCgoSigaction(SB),NOSPLIT,$16
318 MOVQ sig+0(FP), DI
319 MOVQ new+8(FP), SI
320 MOVQ old+16(FP), DX
321 MOVQ _cgo_sigaction(SB), AX
322 MOVQ SP, BX // callee-saved
323 ANDQ $~15, SP // alignment as per amd64 psABI
324 CALL AX
325 MOVQ BX, SP
326 MOVL AX, ret+24(FP)
327 RET
328
329 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
330 MOVQ fn+0(FP), AX
331 MOVL sig+8(FP), DI
332 MOVQ info+16(FP), SI
333 MOVQ ctx+24(FP), DX
334 PUSHQ BP
335 MOVQ SP, BP
336 ANDQ $~15, SP // alignment for x86_64 ABI
337 CALL AX
338 MOVQ BP, SP
339 POPQ BP
340 RET
341
342 TEXT runtime·sigtramp(SB),NOSPLIT,$72
343 // Save callee-saved C registers, since the caller may be a C signal handler.
344 MOVQ BX, bx-8(SP)
345 MOVQ BP, bp-16(SP) // save in case GOEXPERIMENT=noframepointer is set
346 MOVQ R12, r12-24(SP)
347 MOVQ R13, r13-32(SP)
348 MOVQ R14, r14-40(SP)
349 MOVQ R15, r15-48(SP)
350 // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
351 // modify them.
352
353 MOVQ DX, ctx-56(SP)
354 MOVQ SI, info-64(SP)
355 MOVQ DI, signum-72(SP)
356 MOVQ $runtime·sigtrampgo(SB), AX
357 CALL AX
358
359 MOVQ r15-48(SP), R15
360 MOVQ r14-40(SP), R14
361 MOVQ r13-32(SP), R13
362 MOVQ r12-24(SP), R12
363 MOVQ bp-16(SP), BP
364 MOVQ bx-8(SP), BX
365 RET
366
367 // Used instead of sigtramp in programs that use cgo.
368 // Arguments from kernel are in DI, SI, DX.
369 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
370 // If no traceback function, do usual sigtramp.
371 MOVQ runtime·cgoTraceback(SB), AX
372 TESTQ AX, AX
373 JZ sigtramp
374
375 // If no traceback support function, which means that
376 // runtime/cgo was not linked in, do usual sigtramp.
377 MOVQ _cgo_callers(SB), AX
378 TESTQ AX, AX
379 JZ sigtramp
380
381 // Figure out if we are currently in a cgo call.
382 // If not, just do usual sigtramp.
383 get_tls(CX)
384 MOVQ g(CX),AX
385 TESTQ AX, AX
386 JZ sigtrampnog // g == nil
387 MOVQ g_m(AX), AX
388 TESTQ AX, AX
389 JZ sigtramp // g.m == nil
390 MOVL m_ncgo(AX), CX
391 TESTL CX, CX
392 JZ sigtramp // g.m.ncgo == 0
393 MOVQ m_curg(AX), CX
394 TESTQ CX, CX
395 JZ sigtramp // g.m.curg == nil
396 MOVQ g_syscallsp(CX), CX
397 TESTQ CX, CX
398 JZ sigtramp // g.m.curg.syscallsp == 0
399 MOVQ m_cgoCallers(AX), R8
400 TESTQ R8, R8
401 JZ sigtramp // g.m.cgoCallers == nil
402 MOVL m_cgoCallersUse(AX), CX
403 TESTL CX, CX
404 JNZ sigtramp // g.m.cgoCallersUse != 0
405
406 // Jump to a function in runtime/cgo.
407 // That function, written in C, will call the user's traceback
408 // function with proper unwind info, and will then call back here.
409 // The first three arguments, and the fifth, are already in registers.
410 // Set the two remaining arguments now.
411 MOVQ runtime·cgoTraceback(SB), CX
412 MOVQ $runtime·sigtramp(SB), R9
413 MOVQ _cgo_callers(SB), AX
414 JMP AX
415
416 sigtramp:
417 JMP runtime·sigtramp(SB)
418
419 sigtrampnog:
420 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
421 // stack trace.
422 CMPL DI, $27 // 27 == SIGPROF
423 JNZ sigtramp
424
425 // Lock sigprofCallersUse.
426 MOVL $0, AX
427 MOVL $1, CX
428 MOVQ $runtime·sigprofCallersUse(SB), R11
429 LOCK
430 CMPXCHGL CX, 0(R11)
431 JNZ sigtramp // Skip stack trace if already locked.
432
433 // Jump to the traceback function in runtime/cgo.
434 // It will call back to sigprofNonGo, which will ignore the
435 // arguments passed in registers.
436 // First three arguments to traceback function are in registers already.
437 MOVQ runtime·cgoTraceback(SB), CX
438 MOVQ $runtime·sigprofCallers(SB), R8
439 MOVQ $runtime·sigprofNonGo(SB), R9
440 MOVQ _cgo_callers(SB), AX
441 JMP AX
442
443 // For cgo unwinding to work, this function must look precisely like
444 // the one in glibc. The glibc source code is:
445 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/sigaction.c
446 // The code that cares about the precise instructions used is:
447 // https://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/i386/linux-unwind.h?revision=219188&view=markup
448 TEXT runtime·sigreturn(SB),NOSPLIT,$0
449 MOVQ $SYS_rt_sigreturn, AX
450 SYSCALL
451 INT $3 // not reached
452
453 TEXT runtime·sysMmap(SB),NOSPLIT,$0
454 MOVQ addr+0(FP), DI
455 MOVQ n+8(FP), SI
456 MOVL prot+16(FP), DX
457 MOVL flags+20(FP), R10
458 MOVL fd+24(FP), R8
459 MOVL off+28(FP), R9
460
461 MOVL $SYS_mmap, AX
462 SYSCALL
463 CMPQ AX, $0xfffffffffffff001
464 JLS ok
465 NOTQ AX
466 INCQ AX
467 MOVQ $0, p+32(FP)
468 MOVQ AX, err+40(FP)
469 RET
470 ok:
471 MOVQ AX, p+32(FP)
472 MOVQ $0, err+40(FP)
473 RET
474
475 // Call the function stored in _cgo_mmap using the GCC calling convention.
476 // This must be called on the system stack.
477 TEXT runtime·callCgoMmap(SB),NOSPLIT,$16
478 MOVQ addr+0(FP), DI
479 MOVQ n+8(FP), SI
480 MOVL prot+16(FP), DX
481 MOVL flags+20(FP), CX
482 MOVL fd+24(FP), R8
483 MOVL off+28(FP), R9
484 MOVQ _cgo_mmap(SB), AX
485 MOVQ SP, BX
486 ANDQ $~15, SP // alignment as per amd64 psABI
487 MOVQ BX, 0(SP)
488 CALL AX
489 MOVQ 0(SP), SP
490 MOVQ AX, ret+32(FP)
491 RET
492
493 TEXT runtime·sysMunmap(SB),NOSPLIT,$0
494 MOVQ addr+0(FP), DI
495 MOVQ n+8(FP), SI
496 MOVQ $SYS_munmap, AX
497 SYSCALL
498 CMPQ AX, $0xfffffffffffff001
499 JLS 2(PC)
500 MOVL $0xf1, 0xf1 // crash
501 RET
502
503 // Call the function stored in _cgo_munmap using the GCC calling convention.
504 // This must be called on the system stack.
505 TEXT runtime·callCgoMunmap(SB),NOSPLIT,$16-16
506 MOVQ addr+0(FP), DI
507 MOVQ n+8(FP), SI
508 MOVQ _cgo_munmap(SB), AX
509 MOVQ SP, BX
510 ANDQ $~15, SP // alignment as per amd64 psABI
511 MOVQ BX, 0(SP)
512 CALL AX
513 MOVQ 0(SP), SP
514 RET
515
516 TEXT runtime·madvise(SB),NOSPLIT,$0
517 MOVQ addr+0(FP), DI
518 MOVQ n+8(FP), SI
519 MOVL flags+16(FP), DX
520 MOVQ $SYS_madvise, AX
521 SYSCALL
522 MOVL AX, ret+24(FP)
523 RET
524
525 // int64 futex(int32 *uaddr, int32 op, int32 val,
526 // struct timespec *timeout, int32 *uaddr2, int32 val2);
527 TEXT runtime·futex(SB),NOSPLIT,$0
528 MOVQ addr+0(FP), DI
529 MOVL op+8(FP), SI
530 MOVL val+12(FP), DX
531 MOVQ ts+16(FP), R10
532 MOVQ addr2+24(FP), R8
533 MOVL val3+32(FP), R9
534 MOVL $SYS_futex, AX
535 SYSCALL
536 MOVL AX, ret+40(FP)
537 RET
538
539 // int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
540 TEXT runtime·clone(SB),NOSPLIT,$0
541 MOVL flags+0(FP), DI
542 MOVQ stk+8(FP), SI
543 MOVQ $0, DX
544 MOVQ $0, R10
545
546 // Copy mp, gp, fn off parent stack for use by child.
547 // Careful: Linux system call clobbers CX and R11.
548 MOVQ mp+16(FP), R8
549 MOVQ gp+24(FP), R9
550 MOVQ fn+32(FP), R12
551
552 MOVL $SYS_clone, AX
553 SYSCALL
554
555 // In parent, return.
556 CMPQ AX, $0
557 JEQ 3(PC)
558 MOVL AX, ret+40(FP)
559 RET
560
561 // In child, on new stack.
562 MOVQ SI, SP
563
564 // If g or m are nil, skip Go-related setup.
565 CMPQ R8, $0 // m
566 JEQ nog
567 CMPQ R9, $0 // g
568 JEQ nog
569
570 // Initialize m->procid to Linux tid
571 MOVL $SYS_gettid, AX
572 SYSCALL
573 MOVQ AX, m_procid(R8)
574
575 // Set FS to point at m->tls.
576 LEAQ m_tls(R8), DI
577 CALL runtime·settls(SB)
578
579 // In child, set up new stack
580 get_tls(CX)
581 MOVQ R8, g_m(R9)
582 MOVQ R9, g(CX)
583 CALL runtime·stackcheck(SB)
584
585 nog:
586 // Call fn
587 CALL R12
588
589 // It shouldn't return. If it does, exit that thread.
590 MOVL $111, DI
591 MOVL $SYS_exit, AX
592 SYSCALL
593 JMP -3(PC) // keep exiting
594
595 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
596 MOVQ new+0(FP), DI
597 MOVQ old+8(FP), SI
598 MOVQ $SYS_sigaltstack, AX
599 SYSCALL
600 CMPQ AX, $0xfffffffffffff001
601 JLS 2(PC)
602 MOVL $0xf1, 0xf1 // crash
603 RET
604
605 // set tls base to DI
606 TEXT runtime·settls(SB),NOSPLIT,$32
607 #ifdef GOOS_android
608 // Android stores the TLS offset in runtime·tls_g.
609 SUBQ runtime·tls_g(SB), DI
610 #else
611 ADDQ $8, DI // ELF wants to use -8(FS)
612 #endif
613 MOVQ DI, SI
614 MOVQ $0x1002, DI // ARCH_SET_FS
615 MOVQ $SYS_arch_prctl, AX
616 SYSCALL
617 CMPQ AX, $0xfffffffffffff001
618 JLS 2(PC)
619 MOVL $0xf1, 0xf1 // crash
620 RET
621
622 TEXT runtime·osyield(SB),NOSPLIT,$0
623 MOVL $SYS_sched_yield, AX
624 SYSCALL
625 RET
626
627 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
628 MOVQ pid+0(FP), DI
629 MOVQ len+8(FP), SI
630 MOVQ buf+16(FP), DX
631 MOVL $SYS_sched_getaffinity, AX
632 SYSCALL
633 MOVL AX, ret+24(FP)
634 RET
635
636 // int32 runtime·epollcreate(int32 size);
637 TEXT runtime·epollcreate(SB),NOSPLIT,$0
638 MOVL size+0(FP), DI
639 MOVL $SYS_epoll_create, AX
640 SYSCALL
641 MOVL AX, ret+8(FP)
642 RET
643
644 // int32 runtime·epollcreate1(int32 flags);
645 TEXT runtime·epollcreate1(SB),NOSPLIT,$0
646 MOVL flags+0(FP), DI
647 MOVL $SYS_epoll_create1, AX
648 SYSCALL
649 MOVL AX, ret+8(FP)
650 RET
651
652 // func epollctl(epfd, op, fd int32, ev *epollEvent) int
653 TEXT runtime·epollctl(SB),NOSPLIT,$0
654 MOVL epfd+0(FP), DI
655 MOVL op+4(FP), SI
656 MOVL fd+8(FP), DX
657 MOVQ ev+16(FP), R10
658 MOVL $SYS_epoll_ctl, AX
659 SYSCALL
660 MOVL AX, ret+24(FP)
661 RET
662
663 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
664 TEXT runtime·epollwait(SB),NOSPLIT,$0
665 // This uses pwait instead of wait, because Android O blocks wait.
666 MOVL epfd+0(FP), DI
667 MOVQ ev+8(FP), SI
668 MOVL nev+16(FP), DX
669 MOVL timeout+20(FP), R10
670 MOVQ $0, R8
671 MOVL $SYS_epoll_pwait, AX
672 SYSCALL
673 MOVL AX, ret+24(FP)
674 RET
675
676 // void runtime·closeonexec(int32 fd);
677 TEXT runtime·closeonexec(SB),NOSPLIT,$0
678 MOVL fd+0(FP), DI // fd
679 MOVQ $2, SI // F_SETFD
680 MOVQ $1, DX // FD_CLOEXEC
681 MOVL $SYS_fcntl, AX
682 SYSCALL
683 RET
684
685
686 // int access(const char *name, int mode)
687 TEXT runtime·access(SB),NOSPLIT,$0
688 // This uses faccessat instead of access, because Android O blocks access.
689 MOVL $AT_FDCWD, DI // AT_FDCWD, so this acts like access
690 MOVQ name+0(FP), SI
691 MOVL mode+8(FP), DX
692 MOVL $0, R10
693 MOVL $SYS_faccessat, AX
694 SYSCALL
695 MOVL AX, ret+16(FP)
696 RET
697
698 // int connect(int fd, const struct sockaddr *addr, socklen_t addrlen)
699 TEXT runtime·connect(SB),NOSPLIT,$0-28
700 MOVL fd+0(FP), DI
701 MOVQ addr+8(FP), SI
702 MOVL len+16(FP), DX
703 MOVL $SYS_connect, AX
704 SYSCALL
705 MOVL AX, ret+24(FP)
706 RET
707
708 // int socket(int domain, int type, int protocol)
709 TEXT runtime·socket(SB),NOSPLIT,$0-20
710 MOVL domain+0(FP), DI
711 MOVL typ+4(FP), SI
712 MOVL prot+8(FP), DX
713 MOVL $SYS_socket, AX
714 SYSCALL
715 MOVL AX, ret+16(FP)
716 RET
717
718 // func sbrk0() uintptr
719 TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
720 // Implemented as brk(NULL).
721 MOVQ $0, DI
722 MOVL $SYS_brk, AX
723 SYSCALL
724 MOVQ AX, ret+0(FP)
725 RET
View as plain text