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