...

Text file src/runtime/sys_linux_arm64.s

Documentation: runtime

     1// Copyright 2014 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 arm64, Linux
     7//
     8
     9#include "go_asm.h"
    10#include "go_tls.h"
    11#include "textflag.h"
    12#include "cgo/abi_arm64.h"
    13
    14#define AT_FDCWD -100
    15
    16#define CLOCK_REALTIME 0
    17#define CLOCK_MONOTONIC 1
    18
    19#define SYS_exit		93
    20#define SYS_read		63
    21#define SYS_write		64
    22#define SYS_openat		56
    23#define SYS_close		57
    24#define SYS_pipe2		59
    25#define SYS_nanosleep		101
    26#define SYS_mmap		222
    27#define SYS_munmap		215
    28#define SYS_setitimer		103
    29#define SYS_clone		220
    30#define SYS_sched_yield		124
    31#define SYS_rt_sigreturn	139
    32#define SYS_rt_sigaction	134
    33#define SYS_rt_sigprocmask	135
    34#define SYS_sigaltstack		132
    35#define SYS_madvise		233
    36#define SYS_mincore		232
    37#define SYS_getpid		172
    38#define SYS_gettid		178
    39#define SYS_kill		129
    40#define SYS_tgkill		131
    41#define SYS_futex		98
    42#define SYS_sched_getaffinity	123
    43#define SYS_exit_group		94
    44#define SYS_clock_gettime	113
    45#define SYS_faccessat		48
    46#define SYS_socket		198
    47#define SYS_connect		203
    48#define SYS_brk			214
    49#define SYS_timer_create	107
    50#define SYS_timer_settime	110
    51#define SYS_timer_delete	111
    52
    53TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
    54	MOVW	code+0(FP), R0
    55	MOVD	$SYS_exit_group, R8
    56	SVC
    57	RET
    58
    59// func exitThread(wait *atomic.Uint32)
    60TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
    61	MOVD	wait+0(FP), R0
    62	// We're done using the stack.
    63	MOVW	$0, R1
    64	STLRW	R1, (R0)
    65	MOVW	$0, R0	// exit code
    66	MOVD	$SYS_exit, R8
    67	SVC
    68	JMP	0(PC)
    69
    70TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
    71	MOVD	$AT_FDCWD, R0
    72	MOVD	name+0(FP), R1
    73	MOVW	mode+8(FP), R2
    74	MOVW	perm+12(FP), R3
    75	MOVD	$SYS_openat, R8
    76	SVC
    77	CMN	$4095, R0
    78	BCC	done
    79	MOVW	$-1, R0
    80done:
    81	MOVW	R0, ret+16(FP)
    82	RET
    83
    84TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
    85	MOVW	fd+0(FP), R0
    86	MOVD	$SYS_close, R8
    87	SVC
    88	CMN	$4095, R0
    89	BCC	done
    90	MOVW	$-1, R0
    91done:
    92	MOVW	R0, ret+8(FP)
    93	RET
    94
    95TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
    96	MOVD	fd+0(FP), R0
    97	MOVD	p+8(FP), R1
    98	MOVW	n+16(FP), R2
    99	MOVD	$SYS_write, R8
   100	SVC
   101	MOVW	R0, ret+24(FP)
   102	RET
   103
   104TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
   105	MOVW	fd+0(FP), R0
   106	MOVD	p+8(FP), R1
   107	MOVW	n+16(FP), R2
   108	MOVD	$SYS_read, R8
   109	SVC
   110	MOVW	R0, ret+24(FP)
   111	RET
   112
   113// func pipe2(flags int32) (r, w int32, errno int32)
   114TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
   115	MOVD	$r+8(FP), R0
   116	MOVW	flags+0(FP), R1
   117	MOVW	$SYS_pipe2, R8
   118	SVC
   119	MOVW	R0, errno+16(FP)
   120	RET
   121
   122TEXT runtime·usleep(SB),NOSPLIT,$24-4
   123	MOVWU	usec+0(FP), R3
   124	MOVD	R3, R5
   125	MOVW	$1000000, R4
   126	UDIV	R4, R3
   127	MOVD	R3, 8(RSP)
   128	MUL	R3, R4
   129	SUB	R4, R5
   130	MOVW	$1000, R4
   131	MUL	R4, R5
   132	MOVD	R5, 16(RSP)
   133
   134	// nanosleep(&ts, 0)
   135	ADD	$8, RSP, R0
   136	MOVD	$0, R1
   137	MOVD	$SYS_nanosleep, R8
   138	SVC
   139	RET
   140
   141TEXT runtime·gettid(SB),NOSPLIT,$0-4
   142	MOVD	$SYS_gettid, R8
   143	SVC
   144	MOVW	R0, ret+0(FP)
   145	RET
   146
   147TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
   148	MOVD	$SYS_getpid, R8
   149	SVC
   150	MOVW	R0, R19
   151	MOVD	$SYS_gettid, R8
   152	SVC
   153	MOVW	R0, R1	// arg 2 tid
   154	MOVW	R19, R0	// arg 1 pid
   155	MOVW	sig+0(FP), R2	// arg 3
   156	MOVD	$SYS_tgkill, R8
   157	SVC
   158	RET
   159
   160TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
   161	MOVD	$SYS_getpid, R8
   162	SVC
   163	MOVW	R0, R0		// arg 1 pid
   164	MOVW	sig+0(FP), R1	// arg 2
   165	MOVD	$SYS_kill, R8
   166	SVC
   167	RET
   168
   169TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
   170	MOVD	$SYS_getpid, R8
   171	SVC
   172	MOVD	R0, ret+0(FP)
   173	RET
   174
   175TEXT ·tgkill(SB),NOSPLIT,$0-24
   176	MOVD	tgid+0(FP), R0
   177	MOVD	tid+8(FP), R1
   178	MOVD	sig+16(FP), R2
   179	MOVD	$SYS_tgkill, R8
   180	SVC
   181	RET
   182
   183TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
   184	MOVW	mode+0(FP), R0
   185	MOVD	new+8(FP), R1
   186	MOVD	old+16(FP), R2
   187	MOVD	$SYS_setitimer, R8
   188	SVC
   189	RET
   190
   191TEXT runtime·timer_create(SB),NOSPLIT,$0-28
   192	MOVW	clockid+0(FP), R0
   193	MOVD	sevp+8(FP), R1
   194	MOVD	timerid+16(FP), R2
   195	MOVD	$SYS_timer_create, R8
   196	SVC
   197	MOVW	R0, ret+24(FP)
   198	RET
   199
   200TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
   201	MOVW	timerid+0(FP), R0
   202	MOVW	flags+4(FP), R1
   203	MOVD	new+8(FP), R2
   204	MOVD	old+16(FP), R3
   205	MOVD	$SYS_timer_settime, R8
   206	SVC
   207	MOVW	R0, ret+24(FP)
   208	RET
   209
   210TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
   211	MOVW	timerid+0(FP), R0
   212	MOVD	$SYS_timer_delete, R8
   213	SVC
   214	MOVW	R0, ret+8(FP)
   215	RET
   216
   217TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
   218	MOVD	addr+0(FP), R0
   219	MOVD	n+8(FP), R1
   220	MOVD	dst+16(FP), R2
   221	MOVD	$SYS_mincore, R8
   222	SVC
   223	MOVW	R0, ret+24(FP)
   224	RET
   225
   226// func walltime() (sec int64, nsec int32)
   227TEXT runtime·walltime(SB),NOSPLIT,$24-12
   228#ifdef GOEXPERIMENT_runtimesecret
   229	MOVW 	g_secret(g), R20
   230	CBZ 	R20, nosecret
   231	BL	·secretEraseRegisters(SB)
   232
   233nosecret:
   234#endif
   235	MOVD	RSP, R20	// R20 is unchanged by C code
   236	MOVD	RSP, R1
   237
   238	MOVD	g_m(g), R21	// R21 = m
   239
   240	// Set vdsoPC and vdsoSP for SIGPROF traceback.
   241	// Save the old values on stack and restore them on exit,
   242	// so this function is reentrant.
   243	MOVD	m_vdsoPC(R21), R2
   244	MOVD	m_vdsoSP(R21), R3
   245	MOVD	R2, 8(RSP)
   246	MOVD	R3, 16(RSP)
   247
   248	MOVD	$ret-8(FP), R2 // caller's SP
   249	MOVD	LR, m_vdsoPC(R21)
   250	MOVD	R2, m_vdsoSP(R21)
   251
   252	MOVD	m_curg(R21), R0
   253	CMP	g, R0
   254	BNE	noswitch
   255
   256	MOVD	m_g0(R21), R3
   257	MOVD	(g_sched+gobuf_sp)(R3), R1	// Set RSP to g0 stack
   258
   259noswitch:
   260	SUB	$16, R1
   261	BIC	$15, R1	// Align for C code
   262	MOVD	R1, RSP
   263
   264	MOVW	$CLOCK_REALTIME, R0
   265	MOVD	runtime·vdsoClockgettimeSym(SB), R2
   266	CBZ	R2, fallback
   267
   268	// Store g on gsignal's stack, so if we receive a signal
   269	// during VDSO code we can find the g.
   270	// If we don't have a signal stack, we won't receive signal,
   271	// so don't bother saving g.
   272	// When using cgo, we already saved g on TLS, also don't save
   273	// g here.
   274	// Also don't save g if we are already on the signal stack.
   275	// We won't get a nested signal.
   276	MOVBU	runtime·iscgo(SB), R22
   277	CBNZ	R22, nosaveg
   278	MOVD	m_gsignal(R21), R22          // g.m.gsignal
   279	CBZ	R22, nosaveg
   280	CMP	g, R22
   281	BEQ	nosaveg
   282	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
   283	MOVD	g, (R22)
   284
   285	BL	(R2)
   286
   287	MOVD	ZR, (R22)  // clear g slot, R22 is unchanged by C code
   288
   289	B	finish
   290
   291nosaveg:
   292	BL	(R2)
   293	B	finish
   294
   295fallback:
   296	MOVD	$SYS_clock_gettime, R8
   297	SVC
   298
   299finish:
   300	MOVD	0(RSP), R3	// sec
   301	MOVD	8(RSP), R5	// nsec
   302
   303	MOVD	R20, RSP	// restore SP
   304	// Restore vdsoPC, vdsoSP
   305	// We don't worry about being signaled between the two stores.
   306	// If we are not in a signal handler, we'll restore vdsoSP to 0,
   307	// and no one will care about vdsoPC. If we are in a signal handler,
   308	// we cannot receive another signal.
   309	MOVD	16(RSP), R1
   310	MOVD	R1, m_vdsoSP(R21)
   311	MOVD	8(RSP), R1
   312	MOVD	R1, m_vdsoPC(R21)
   313
   314	MOVD	R3, sec+0(FP)
   315	MOVW	R5, nsec+8(FP)
   316	RET
   317
   318TEXT runtime·nanotime1(SB),NOSPLIT,$24-8
   319#ifdef GOEXPERIMENT_runtimesecret
   320	MOVW	g_secret(g), R20
   321	CBZ	R20, nosecret
   322	BL	·secretEraseRegisters(SB)
   323
   324nosecret:
   325#endif
   326	MOVD	RSP, R20	// R20 is unchanged by C code
   327	MOVD	RSP, R1
   328
   329	MOVD	g_m(g), R21	// R21 = m
   330
   331	// Set vdsoPC and vdsoSP for SIGPROF traceback.
   332	// Save the old values on stack and restore them on exit,
   333	// so this function is reentrant.
   334	MOVD	m_vdsoPC(R21), R2
   335	MOVD	m_vdsoSP(R21), R3
   336	MOVD	R2, 8(RSP)
   337	MOVD	R3, 16(RSP)
   338
   339	MOVD	$ret-8(FP), R2 // caller's SP
   340	MOVD	LR, m_vdsoPC(R21)
   341	MOVD	R2, m_vdsoSP(R21)
   342
   343	MOVD	m_curg(R21), R0
   344	CMP	g, R0
   345	BNE	noswitch
   346
   347	MOVD	m_g0(R21), R3
   348	MOVD	(g_sched+gobuf_sp)(R3), R1	// Set RSP to g0 stack
   349
   350noswitch:
   351	SUB	$32, R1
   352	BIC	$15, R1
   353	MOVD	R1, RSP
   354
   355	MOVW	$CLOCK_MONOTONIC, R0
   356	MOVD	runtime·vdsoClockgettimeSym(SB), R2
   357	CBZ	R2, fallback
   358
   359	// Store g on gsignal's stack, so if we receive a signal
   360	// during VDSO code we can find the g.
   361	// If we don't have a signal stack, we won't receive signal,
   362	// so don't bother saving g.
   363	// When using cgo, we already saved g on TLS, also don't save
   364	// g here.
   365	// Also don't save g if we are already on the signal stack.
   366	// We won't get a nested signal.
   367	MOVBU	runtime·iscgo(SB), R22
   368	CBNZ	R22, nosaveg
   369	MOVD	m_gsignal(R21), R22          // g.m.gsignal
   370	CBZ	R22, nosaveg
   371	CMP	g, R22
   372	BEQ	nosaveg
   373	MOVD	(g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
   374	MOVD	g, (R22)
   375
   376	BL	(R2)
   377
   378	MOVD	ZR, (R22)  // clear g slot, R22 is unchanged by C code
   379
   380	B	finish
   381
   382nosaveg:
   383	BL	(R2)
   384	B	finish
   385
   386fallback:
   387	MOVD	$SYS_clock_gettime, R8
   388	SVC
   389
   390finish:
   391	MOVD	0(RSP), R3	// sec
   392	MOVD	8(RSP), R5	// nsec
   393
   394	MOVD	R20, RSP	// restore SP
   395	// Restore vdsoPC, vdsoSP
   396	// We don't worry about being signaled between the two stores.
   397	// If we are not in a signal handler, we'll restore vdsoSP to 0,
   398	// and no one will care about vdsoPC. If we are in a signal handler,
   399	// we cannot receive another signal.
   400	MOVD	16(RSP), R1
   401	MOVD	R1, m_vdsoSP(R21)
   402	MOVD	8(RSP), R1
   403	MOVD	R1, m_vdsoPC(R21)
   404
   405	// sec is in R3, nsec in R5
   406	// return nsec in R3
   407	MOVD	$1000000000, R4
   408	MUL	R4, R3
   409	ADD	R5, R3
   410	MOVD	R3, ret+0(FP)
   411	RET
   412
   413TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
   414	MOVW	how+0(FP), R0
   415	MOVD	new+8(FP), R1
   416	MOVD	old+16(FP), R2
   417	MOVW	size+24(FP), R3
   418	MOVD	$SYS_rt_sigprocmask, R8
   419	SVC
   420	CMN	$4095, R0
   421	BCC	done
   422	MOVD	$0, R0
   423	MOVD	R0, (R0)	// crash
   424done:
   425	RET
   426
   427TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
   428	MOVD	sig+0(FP), R0
   429	MOVD	new+8(FP), R1
   430	MOVD	old+16(FP), R2
   431	MOVD	size+24(FP), R3
   432	MOVD	$SYS_rt_sigaction, R8
   433	SVC
   434	MOVW	R0, ret+32(FP)
   435	RET
   436
   437// Call the function stored in _cgo_sigaction using the GCC calling convention.
   438TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
   439	MOVD	sig+0(FP), R0
   440	MOVD	new+8(FP), R1
   441	MOVD	old+16(FP), R2
   442	MOVD	 _cgo_sigaction(SB), R3
   443	SUB	$16, RSP		// reserve 16 bytes for sp-8 where fp may be saved.
   444	BL	R3
   445	ADD	$16, RSP
   446	MOVW	R0, ret+24(FP)
   447	RET
   448
   449TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   450	MOVW	sig+8(FP), R0
   451	MOVD	info+16(FP), R1
   452	MOVD	ctx+24(FP), R2
   453	MOVD	fn+0(FP), R11
   454	BL	(R11)
   455	RET
   456
   457// Called from c-abi, R0: sig, R1: info, R2: cxt
   458TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$176
   459	// Save callee-save registers in the case of signal forwarding.
   460	// Please refer to https://golang.org/issue/31827 .
   461	SAVE_R19_TO_R28(8*4)
   462	SAVE_F8_TO_F15(8*14)
   463
   464	// this might be called in external code context,
   465	// where g is not set.
   466	// first save R0, because runtime·load_g will clobber it
   467	MOVW	R0, 8(RSP)
   468	MOVBU	runtime·iscgo(SB), R0
   469	CBZ	R0, 2(PC)
   470	BL	runtime·load_g(SB)
   471
   472	// Restore signum to R0.
   473	MOVW	8(RSP), R0
   474	// R1 and R2 already contain info and ctx, respectively.
   475	MOVD	$runtime·sigtrampgo<ABIInternal>(SB), R3
   476	BL	(R3)
   477
   478	// Restore callee-save registers.
   479	RESTORE_R19_TO_R28(8*4)
   480	RESTORE_F8_TO_F15(8*14)
   481
   482	RET
   483
   484// Called from c-abi, R0: sig, R1: info, R2: cxt
   485TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$176
   486	// Save callee-save registers because it's a callback from c code.
   487	SAVE_R19_TO_R28(8*4)
   488	SAVE_F8_TO_F15(8*14)
   489
   490	// R0, R1 and R2 already contain sig, info and ctx, respectively.
   491	CALL	runtime·sigprofNonGo<ABIInternal>(SB)
   492
   493	// Restore callee-save registers.
   494	RESTORE_R19_TO_R28(8*4)
   495	RESTORE_F8_TO_F15(8*14)
   496	RET
   497
   498// Called from c-abi, R0: sig, R1: info, R2: cxt
   499TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
   500	// The stack unwinder, presumably written in C, may not be able to
   501	// handle Go frame correctly. So, this function is NOFRAME, and we
   502	// save/restore LR manually.
   503	MOVD	LR, R10
   504	// Save R27, g because they will be clobbered,
   505	// we need to restore them before jump to sigtramp.
   506	MOVD	R27, R11
   507	MOVD	g, R12
   508
   509	// If no traceback function, do usual sigtramp.
   510	MOVD	runtime·cgoTraceback(SB), R6
   511	CBZ	R6, sigtramp
   512
   513	// If no traceback support function, which means that
   514	// runtime/cgo was not linked in, do usual sigtramp.
   515	MOVD	_cgo_callers(SB), R7
   516	CBZ	R7, sigtramp
   517
   518	// Figure out if we are currently in a cgo call.
   519	// If not, just do usual sigtramp.
   520	// first save R0, because runtime·load_g will clobber it.
   521	MOVD	R0, R8
   522	// Set up g register.
   523	CALL	runtime·load_g(SB)
   524	MOVD	R8, R0
   525
   526	CBZ	g, sigtrampnog // g == nil
   527	MOVD	g_m(g), R6
   528	CBZ	R6, sigtramp    // g.m == nil
   529	MOVW	m_ncgo(R6), R7
   530	CBZW	R7, sigtramp    // g.m.ncgo = 0
   531	MOVD	m_curg(R6), R8
   532	CBZ	R8, sigtramp    // g.m.curg == nil
   533	MOVD	g_syscallsp(R8), R7
   534	CBZ	R7,	sigtramp    // g.m.curg.syscallsp == 0
   535	MOVD	m_cgoCallers(R6), R4 // R4 is the fifth arg in C calling convention.
   536	CBZ	R4,	sigtramp    // g.m.cgoCallers == nil
   537	MOVW	m_cgoCallersUse(R6), R8
   538	CBNZW	R8, sigtramp    // g.m.cgoCallersUse != 0
   539
   540	// Jump to a function in runtime/cgo.
   541	// That function, written in C, will call the user's traceback
   542	// function with proper unwind info, and will then call back here.
   543	// The first three arguments, and the fifth, are already in registers.
   544	// Set the two remaining arguments now.
   545	MOVD	runtime·cgoTraceback(SB), R3
   546	MOVD	$runtime·sigtramp(SB), R5
   547	MOVD	_cgo_callers(SB), R13
   548	MOVD	R10, LR // restore
   549	MOVD	R11, R27
   550	MOVD	R12, g
   551	B	(R13)
   552
   553sigtramp:
   554	MOVD	R10, LR // restore
   555	MOVD	R11, R27
   556	MOVD	R12, g
   557	B	runtime·sigtramp(SB)
   558
   559sigtrampnog:
   560	// Signal arrived on a non-Go thread. If this is SIGPROF, get a
   561	// stack trace.
   562	CMPW	$27, R0 // 27 == SIGPROF
   563	BNE	sigtramp
   564
   565	// Lock sigprofCallersUse (cas from 0 to 1).
   566	MOVW	$1, R7
   567	MOVD	$runtime·sigprofCallersUse(SB), R8
   568load_store_loop:
   569	LDAXRW	(R8), R9
   570	CBNZW	R9, sigtramp // Skip stack trace if already locked.
   571	STLXRW	R7, (R8), R9
   572	CBNZ	R9, load_store_loop
   573
   574	// Jump to the traceback function in runtime/cgo.
   575	// It will call back to sigprofNonGo, which will ignore the
   576	// arguments passed in registers.
   577	// First three arguments to traceback function are in registers already.
   578	MOVD	runtime·cgoTraceback(SB), R3
   579	MOVD	$runtime·sigprofCallers(SB), R4
   580	MOVD	$runtime·sigprofNonGoWrapper<>(SB), R5
   581	MOVD	_cgo_callers(SB), R13
   582	MOVD	R10, LR // restore
   583	MOVD	R11, R27
   584	MOVD	R12, g
   585	B	(R13)
   586
   587TEXT runtime·sysMmap(SB),NOSPLIT|NOFRAME,$0
   588	MOVD	addr+0(FP), R0
   589	MOVD	n+8(FP), R1
   590	MOVW	prot+16(FP), R2
   591	MOVW	flags+20(FP), R3
   592	MOVW	fd+24(FP), R4
   593	MOVW	off+28(FP), R5
   594
   595	MOVD	$SYS_mmap, R8
   596	SVC
   597	CMN	$4095, R0
   598	BCC	ok
   599	NEG	R0,R0
   600	MOVD	$0, p+32(FP)
   601	MOVD	R0, err+40(FP)
   602	RET
   603ok:
   604	MOVD	R0, p+32(FP)
   605	MOVD	$0, err+40(FP)
   606	RET
   607
   608// Call the function stored in _cgo_mmap using the GCC calling convention.
   609// This must be called on the system stack.
   610TEXT runtime·callCgoMmap(SB),NOSPLIT,$0
   611	MOVD	addr+0(FP), R0
   612	MOVD	n+8(FP), R1
   613	MOVW	prot+16(FP), R2
   614	MOVW	flags+20(FP), R3
   615	MOVW	fd+24(FP), R4
   616	MOVW	off+28(FP), R5
   617	MOVD	_cgo_mmap(SB), R9
   618	SUB	$16, RSP		// reserve 16 bytes for sp-8 where fp may be saved.
   619	BL	R9
   620	ADD	$16, RSP
   621	MOVD	R0, ret+32(FP)
   622	RET
   623
   624TEXT runtime·sysMunmap(SB),NOSPLIT|NOFRAME,$0
   625	MOVD	addr+0(FP), R0
   626	MOVD	n+8(FP), R1
   627	MOVD	$SYS_munmap, R8
   628	SVC
   629	CMN	$4095, R0
   630	BCC	cool
   631	MOVD	R0, 0xf0(R0)
   632cool:
   633	RET
   634
   635// Call the function stored in _cgo_munmap using the GCC calling convention.
   636// This must be called on the system stack.
   637TEXT runtime·callCgoMunmap(SB),NOSPLIT,$0
   638	MOVD	addr+0(FP), R0
   639	MOVD	n+8(FP), R1
   640	MOVD	_cgo_munmap(SB), R9
   641	SUB	$16, RSP		// reserve 16 bytes for sp-8 where fp may be saved.
   642	BL	R9
   643	ADD	$16, RSP
   644	RET
   645
   646TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
   647	MOVD	addr+0(FP), R0
   648	MOVD	n+8(FP), R1
   649	MOVW	flags+16(FP), R2
   650	MOVD	$SYS_madvise, R8
   651	SVC
   652	MOVW	R0, ret+24(FP)
   653	RET
   654
   655// int64 futex(int32 *uaddr, int32 op, int32 val,
   656//	struct timespec *timeout, int32 *uaddr2, int32 val2);
   657TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
   658	MOVD	addr+0(FP), R0
   659	MOVW	op+8(FP), R1
   660	MOVW	val+12(FP), R2
   661	MOVD	ts+16(FP), R3
   662	MOVD	addr2+24(FP), R4
   663	MOVW	val3+32(FP), R5
   664	MOVD	$SYS_futex, R8
   665	SVC
   666	MOVW	R0, ret+40(FP)
   667	RET
   668
   669// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
   670TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
   671	MOVW	flags+0(FP), R0
   672	MOVD	stk+8(FP), R1
   673
   674	// Copy mp, gp, fn off parent stack for use by child.
   675	MOVD	mp+16(FP), R10
   676	MOVD	gp+24(FP), R11
   677	MOVD	fn+32(FP), R12
   678
   679	MOVD	R10, -8(R1)
   680	MOVD	R11, -16(R1)
   681	MOVD	R12, -24(R1)
   682	MOVD	$1234, R10
   683	MOVD	R10, -32(R1)
   684
   685	MOVD	$SYS_clone, R8
   686	SVC
   687
   688	// In parent, return.
   689	CMP	ZR, R0
   690	BEQ	child
   691	MOVW	R0, ret+40(FP)
   692	RET
   693child:
   694
   695	// In child, on new stack.
   696	MOVD	-32(RSP), R10
   697	MOVD	$1234, R0
   698	CMP	R0, R10
   699	BEQ	good
   700	MOVD	$0, R0
   701	MOVD	R0, (R0)	// crash
   702
   703good:
   704	// Initialize m->procid to Linux tid
   705	MOVD	$SYS_gettid, R8
   706	SVC
   707
   708	MOVD	-24(RSP), R12     // fn
   709	MOVD	-16(RSP), R11     // g
   710	MOVD	-8(RSP), R10      // m
   711
   712	CMP	$0, R10
   713	BEQ	nog
   714	CMP	$0, R11
   715	BEQ	nog
   716
   717	MOVD	R0, m_procid(R10)
   718
   719	// TODO: setup TLS.
   720
   721	// In child, set up new stack
   722	MOVD	R10, g_m(R11)
   723	MOVD	R11, g
   724	//CALL	runtime·stackcheck(SB)
   725
   726nog:
   727	// Call fn
   728	MOVD	R12, R0
   729	BL	(R0)
   730
   731	// It shouldn't return.	 If it does, exit that thread.
   732	MOVW	$111, R0
   733again:
   734	MOVD	$SYS_exit, R8
   735	SVC
   736	B	again	// keep exiting
   737
   738TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
   739	MOVD	new+0(FP), R0
   740	MOVD	old+8(FP), R1
   741	MOVD	$SYS_sigaltstack, R8
   742	SVC
   743	CMN	$4095, R0
   744	BCC	ok
   745	MOVD	$0, R0
   746	MOVD	R0, (R0)	// crash
   747ok:
   748	RET
   749
   750TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
   751	MOVD	$SYS_sched_yield, R8
   752	SVC
   753	RET
   754
   755TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
   756	MOVD	pid+0(FP), R0
   757	MOVD	len+8(FP), R1
   758	MOVD	buf+16(FP), R2
   759	MOVD	$SYS_sched_getaffinity, R8
   760	SVC
   761	MOVW	R0, ret+24(FP)
   762	RET
   763
   764// int access(const char *name, int mode)
   765TEXT runtime·access(SB),NOSPLIT,$0-20
   766	MOVD	$AT_FDCWD, R0
   767	MOVD	name+0(FP), R1
   768	MOVW	mode+8(FP), R2
   769	MOVD	$SYS_faccessat, R8
   770	SVC
   771	MOVW	R0, ret+16(FP)
   772	RET
   773
   774// int connect(int fd, const struct sockaddr *addr, socklen_t len)
   775TEXT runtime·connect(SB),NOSPLIT,$0-28
   776	MOVW	fd+0(FP), R0
   777	MOVD	addr+8(FP), R1
   778	MOVW	len+16(FP), R2
   779	MOVD	$SYS_connect, R8
   780	SVC
   781	MOVW	R0, ret+24(FP)
   782	RET
   783
   784// int socket(int domain, int typ, int prot)
   785TEXT runtime·socket(SB),NOSPLIT,$0-20
   786	MOVW	domain+0(FP), R0
   787	MOVW	typ+4(FP), R1
   788	MOVW	prot+8(FP), R2
   789	MOVD	$SYS_socket, R8
   790	SVC
   791	MOVW	R0, ret+16(FP)
   792	RET
   793
   794// func sbrk0() uintptr
   795TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
   796	// Implemented as brk(NULL).
   797	MOVD	$0, R0
   798	MOVD	$SYS_brk, R8
   799	SVC
   800	MOVD	R0, ret+0(FP)
   801	RET
   802
   803// func vgetrandom1(buf *byte, length uintptr, flags uint32, state uintptr, stateSize uintptr) int
   804TEXT runtime·vgetrandom1<ABIInternal>(SB),NOSPLIT,$16-48
   805	MOVD	RSP, R20
   806
   807	MOVD	runtime·vdsoGetrandomSym(SB), R8
   808	MOVD	g_m(g), R21
   809
   810	MOVD	m_vdsoPC(R21), R9
   811	MOVD	R9, 8(RSP)
   812	MOVD	m_vdsoSP(R21), R9
   813	MOVD	R9, 16(RSP)
   814	MOVD	LR, m_vdsoPC(R21)
   815	MOVD	$buf-8(FP), R9
   816	MOVD	R9, m_vdsoSP(R21)
   817
   818	MOVD	RSP, R9
   819	BIC	$15, R9
   820	MOVD	R9, RSP
   821
   822	MOVBU	runtime·iscgo(SB), R9
   823	CBNZ	R9, nosaveg
   824	MOVD	m_gsignal(R21), R9
   825	CBZ	R9, nosaveg
   826	CMP	g, R9
   827	BEQ	nosaveg
   828	MOVD	(g_stack+stack_lo)(R9), R22
   829	MOVD	g, (R22)
   830
   831	BL	(R8)
   832
   833	MOVD	ZR, (R22)
   834	B	restore
   835
   836nosaveg:
   837	BL	(R8)
   838
   839restore:
   840	MOVD	R20, RSP
   841	MOVD	16(RSP), R1
   842	MOVD	R1, m_vdsoSP(R21)
   843	MOVD	8(RSP), R1
   844	MOVD	R1, m_vdsoPC(R21)
   845	NOP	R0 // Satisfy go vet, since the return value comes from the vDSO function.
   846	RET

View as plain text