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