Text file
src/runtime/sys_openbsd_arm.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 // System calls and other sys.stuff for ARM, OpenBSD
6 // /usr/src/sys/kern/syscalls.master for syscall numbers.
7 //
8
9 #include "go_asm.h"
10 #include "go_tls.h"
11 #include "textflag.h"
12
13 #define CLOCK_REALTIME $0
14 #define CLOCK_MONOTONIC $3
15
16 // With OpenBSD 6.7 onwards, an armv7 syscall returns two instructions
17 // after the SWI instruction, to allow for a speculative execution
18 // barrier to be placed after the SWI without impacting performance.
19 // For now use hardware no-ops as this works with both older and newer
20 // kernels. After OpenBSD 6.8 is released this should be changed to
21 // speculation barriers.
22 #define NOOP MOVW R0, R0
23 #define INVOKE_SYSCALL \
24 SWI $0; \
25 NOOP; \
26 NOOP
27
28 // mstart_stub is the first function executed on a new thread started by pthread_create.
29 // It just does some low-level setup and then calls mstart.
30 // Note: called with the C calling convention.
31 TEXT runtime·mstart_stub(SB),NOSPLIT,$0
32 // R0 points to the m.
33 // We are already on m's g0 stack.
34
35 // Save callee-save registers.
36 MOVM.DB.W [R4-R11], (R13)
37
38 MOVW m_g0(R0), g
39 BL runtime·save_g(SB)
40
41 BL runtime·mstart(SB)
42
43 // Restore callee-save registers.
44 MOVM.IA.W (R13), [R4-R11]
45
46 // Go is all done with this OS thread.
47 // Tell pthread everything is ok (we never join with this thread, so
48 // the value here doesn't really matter).
49 MOVW $0, R0
50 RET
51
52 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
53 MOVW sig+4(FP), R0
54 MOVW info+8(FP), R1
55 MOVW ctx+12(FP), R2
56 MOVW fn+0(FP), R3
57 MOVW R13, R9
58 SUB $24, R13
59 BIC $0x7, R13 // alignment for ELF ABI
60 BL (R3)
61 MOVW R9, R13
62 RET
63
64 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$0
65 // Reserve space for callee-save registers and arguments.
66 MOVM.DB.W [R4-R11], (R13)
67 SUB $16, R13
68
69 // If called from an external code context, g will not be set.
70 // Save R0, since runtime·load_g will clobber it.
71 MOVW R0, 4(R13) // signum
72 BL runtime·load_g(SB)
73
74 MOVW R1, 8(R13)
75 MOVW R2, 12(R13)
76 BL runtime·sigtrampgo(SB)
77
78 // Restore callee-save registers.
79 ADD $16, R13
80 MOVM.IA.W (R13), [R4-R11]
81
82 RET
83
84 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
85 B runtime·armPublicationBarrier(SB)
86
87 // TODO(jsing): OpenBSD only supports GOARM=7 machines... this
88 // should not be needed, however the linker still allows GOARM=5
89 // on this platform.
90 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
91 MOVM.WP [R1, R2, R3, R12], (R13)
92 MOVW $330, R12 // sys___get_tcb
93 INVOKE_SYSCALL
94 MOVM.IAW (R13), [R1, R2, R3, R12]
95 RET
96
97 // These trampolines help convert from Go calling convention to C calling convention.
98 // They should be called with asmcgocall - note that while asmcgocall does
99 // stack alignment, creation of a frame undoes it again.
100 // A pointer to the arguments is passed in R0.
101 // A single int32 result is returned in R0.
102 // (For more results, make an args/results structure.)
103 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
104 MOVW R13, R9
105 BIC $0x7, R13 // align for ELF ABI
106 MOVW 0(R0), R0 // arg 1 attr
107 CALL libc_pthread_attr_init(SB)
108 MOVW R9, R13
109 RET
110
111 TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
112 MOVW R13, R9
113 BIC $0x7, R13 // align for ELF ABI
114 MOVW 0(R0), R0 // arg 1 attr
115 CALL libc_pthread_attr_destroy(SB)
116 MOVW R9, R13
117 RET
118
119 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
120 MOVW R13, R9
121 BIC $0x7, R13 // align for ELF ABI
122 MOVW 4(R0), R1 // arg 2 size
123 MOVW 0(R0), R0 // arg 1 attr
124 CALL libc_pthread_attr_getstacksize(SB)
125 MOVW R9, R13
126 RET
127
128 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
129 MOVW R13, R9
130 BIC $0x7, R13 // align for ELF ABI
131 MOVW 4(R0), R1 // arg 2 state
132 MOVW 0(R0), R0 // arg 1 attr
133 CALL libc_pthread_attr_setdetachstate(SB)
134 MOVW R9, R13
135 RET
136
137 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
138 MOVW R13, R9
139 SUB $16, R13
140 BIC $0x7, R13 // align for ELF ABI
141 MOVW 0(R0), R1 // arg 2 attr
142 MOVW 4(R0), R2 // arg 3 start
143 MOVW 8(R0), R3 // arg 4 arg
144 MOVW R13, R0 // arg 1 &threadid (discarded)
145 CALL libc_pthread_create(SB)
146 MOVW R9, R13
147 RET
148
149 TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
150 MOVW R13, R9
151 BIC $0x7, R13 // align for ELF ABI
152 MOVW 4(R0), R1 // arg 2 - signal
153 MOVW $0, R2 // arg 3 - tcb
154 MOVW 0(R0), R0 // arg 1 - tid
155 CALL libc_thrkill(SB)
156 MOVW R9, R13
157 RET
158
159 TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
160 MOVW R13, R9
161 SUB $16, R13
162 BIC $0x7, R13 // align for ELF ABI
163 MOVW 4(R0), R1 // arg 2 - clock_id
164 MOVW 8(R0), R2 // arg 3 - abstime
165 MOVW 12(R0), R3 // arg 4 - lock
166 MOVW 16(R0), R4 // arg 5 - abort (on stack)
167 MOVW R4, 0(R13)
168 MOVW 0(R0), R0 // arg 1 - id
169 CALL libc_thrsleep(SB)
170 MOVW R9, R13
171 RET
172
173 TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
174 MOVW R13, R9
175 BIC $0x7, R13 // align for ELF ABI
176 MOVW 4(R0), R1 // arg 2 - count
177 MOVW 0(R0), R0 // arg 1 - id
178 CALL libc_thrwakeup(SB)
179 MOVW R9, R13
180 RET
181
182 TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
183 MOVW R13, R9
184 BIC $0x7, R13 // align for ELF ABI
185 MOVW 0(R0), R0 // arg 1 exit status
186 BL libc_exit(SB)
187 MOVW $0, R8 // crash on failure
188 MOVW R8, (R8)
189 MOVW R9, R13
190 RET
191
192 TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
193 MOVW R13, R9
194 MOVW R0, R8
195 BIC $0x7, R13 // align for ELF ABI
196 BL libc_getthrid(SB)
197 MOVW R0, 0(R8)
198 MOVW R9, R13
199 RET
200
201 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
202 MOVW R13, R9
203 BIC $0x7, R13 // align for ELF ABI
204 MOVW R0, R4
205 BL libc_getpid(SB) // arg 1 pid
206 MOVW R4, R1 // arg 2 signal
207 BL libc_kill(SB)
208 MOVW R9, R13
209 RET
210
211 TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
212 MOVW R13, R9
213 BIC $0x7, R13 // align for ELF ABI
214 BL libc_sched_yield(SB)
215 MOVW R9, R13
216 RET
217
218 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
219 MOVW R13, R9
220 SUB $16, R13
221 BIC $0x7, R13 // align for ELF ABI
222 MOVW R0, R8
223 MOVW 4(R0), R1 // arg 2 len
224 MOVW 8(R0), R2 // arg 3 prot
225 MOVW 12(R0), R3 // arg 4 flags
226 MOVW 16(R0), R4 // arg 5 fid (on stack)
227 MOVW R4, 0(R13)
228 MOVW $0, R5 // pad (on stack)
229 MOVW R5, 4(R13)
230 MOVW 20(R0), R6 // arg 6 offset (on stack)
231 MOVW R6, 8(R13) // low 32 bits
232 MOVW $0, R7
233 MOVW R7, 12(R13) // high 32 bits
234 MOVW 0(R0), R0 // arg 1 addr
235 BL libc_mmap(SB)
236 MOVW $0, R1
237 CMP $-1, R0
238 BNE ok
239 BL libc_errno(SB)
240 MOVW (R0), R1 // errno
241 MOVW $0, R0
242 ok:
243 MOVW R0, 24(R8)
244 MOVW R1, 28(R8)
245 MOVW R9, R13
246 RET
247
248 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
249 MOVW R13, R9
250 BIC $0x7, R13 // align for ELF ABI
251 MOVW 4(R0), R1 // arg 2 len
252 MOVW 0(R0), R0 // arg 1 addr
253 BL libc_munmap(SB)
254 CMP $-1, R0
255 BNE 3(PC)
256 MOVW $0, R8 // crash on failure
257 MOVW R8, (R8)
258 MOVW R9, R13
259 RET
260
261 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
262 MOVW R13, R9
263 BIC $0x7, R13 // align for ELF ABI
264 MOVW 4(R0), R1 // arg 2 len
265 MOVW 8(R0), R2 // arg 3 advice
266 MOVW 0(R0), R0 // arg 1 addr
267 BL libc_madvise(SB)
268 // ignore failure - maybe pages are locked
269 MOVW R9, R13
270 RET
271
272 TEXT runtime·open_trampoline(SB),NOSPLIT,$0
273 MOVW R13, R9
274 SUB $8, R13
275 BIC $0x7, R13 // align for ELF ABI
276 MOVW 4(R0), R1 // arg 2 - flags
277 MOVW 8(R0), R2 // arg 3 - mode (vararg, on stack)
278 MOVW R2, 0(R13)
279 MOVW 0(R0), R0 // arg 1 - path
280 MOVW R13, R4
281 BIC $0x7, R13 // align for ELF ABI
282 BL libc_open(SB)
283 MOVW R9, R13
284 RET
285
286 TEXT runtime·close_trampoline(SB),NOSPLIT,$0
287 MOVW R13, R9
288 BIC $0x7, R13 // align for ELF ABI
289 MOVW 0(R0), R0 // arg 1 - fd
290 BL libc_close(SB)
291 MOVW R9, R13
292 RET
293
294 TEXT runtime·read_trampoline(SB),NOSPLIT,$0
295 MOVW R13, R9
296 BIC $0x7, R13 // align for ELF ABI
297 MOVW 4(R0), R1 // arg 2 - buf
298 MOVW 8(R0), R2 // arg 3 - count
299 MOVW 0(R0), R0 // arg 1 - fd
300 BL libc_read(SB)
301 CMP $-1, R0
302 BNE noerr
303 BL libc_errno(SB)
304 MOVW (R0), R0 // errno
305 RSB.CS $0, R0 // caller expects negative errno
306 noerr:
307 MOVW R9, R13
308 RET
309
310 TEXT runtime·write_trampoline(SB),NOSPLIT,$0
311 MOVW R13, R9
312 BIC $0x7, R13 // align for ELF ABI
313 MOVW 4(R0), R1 // arg 2 buf
314 MOVW 8(R0), R2 // arg 3 count
315 MOVW 0(R0), R0 // arg 1 fd
316 BL libc_write(SB)
317 CMP $-1, R0
318 BNE noerr
319 BL libc_errno(SB)
320 MOVW (R0), R0 // errno
321 RSB.CS $0, R0 // caller expects negative errno
322 noerr:
323 MOVW R9, R13
324 RET
325
326 TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
327 MOVW R13, R9
328 BIC $0x7, R13 // align for ELF ABI
329 MOVW 4(R0), R1 // arg 2 flags
330 MOVW 0(R0), R0 // arg 1 filedes
331 BL libc_pipe2(SB)
332 CMP $-1, R0
333 BNE 3(PC)
334 BL libc_errno(SB)
335 MOVW (R0), R0 // errno
336 RSB.CS $0, R0 // caller expects negative errno
337 MOVW R9, R13
338 RET
339
340 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
341 MOVW R13, R9
342 BIC $0x7, R13 // align for ELF ABI
343 MOVW 4(R0), R1 // arg 2 new
344 MOVW 8(R0), R2 // arg 3 old
345 MOVW 0(R0), R0 // arg 1 which
346 BL libc_setitimer(SB)
347 MOVW R9, R13
348 RET
349
350 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
351 MOVW R13, R9
352 BIC $0x7, R13 // align for ELF ABI
353 MOVW 0(R0), R0 // arg 1 usec
354 BL libc_usleep(SB)
355 MOVW R9, R13
356 RET
357
358 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
359 MOVW R13, R9
360 SUB $8, R13
361 BIC $0x7, R13 // align for ELF ABI
362 MOVW 4(R0), R1 // arg 2 miblen
363 MOVW 8(R0), R2 // arg 3 out
364 MOVW 12(R0), R3 // arg 4 size
365 MOVW 16(R0), R4 // arg 5 dst (on stack)
366 MOVW R4, 0(R13)
367 MOVW 20(R0), R5 // arg 6 ndst (on stack)
368 MOVW R5, 4(R13)
369 MOVW 0(R0), R0 // arg 1 mib
370 BL libc_sysctl(SB)
371 MOVW R9, R13
372 RET
373
374 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
375 MOVW R13, R9
376 BIC $0x7, R13 // align for ELF ABI
377 BL libc_kqueue(SB)
378 MOVW R9, R13
379 RET
380
381 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
382 MOVW R13, R9
383 SUB $8, R13
384 BIC $0x7, R13 // align for ELF ABI
385 MOVW 4(R0), R1 // arg 2 keventt
386 MOVW 8(R0), R2 // arg 3 nch
387 MOVW 12(R0), R3 // arg 4 ev
388 MOVW 16(R0), R4 // arg 5 nev (on stack)
389 MOVW R4, 0(R13)
390 MOVW 20(R0), R5 // arg 6 ts (on stack)
391 MOVW R5, 4(R13)
392 MOVW 0(R0), R0 // arg 1 kq
393 BL libc_kevent(SB)
394 CMP $-1, R0
395 BNE ok
396 BL libc_errno(SB)
397 MOVW (R0), R0 // errno
398 RSB.CS $0, R0 // caller expects negative errno
399 ok:
400 MOVW R9, R13
401 RET
402
403 TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
404 MOVW R13, R9
405 BIC $0x7, R13 // align for ELF ABI
406 MOVW 4(R0), R1 // arg 2 tp
407 MOVW 0(R0), R0 // arg 1 clock_id
408 BL libc_clock_gettime(SB)
409 CMP $-1, R0
410 BNE noerr
411 BL libc_errno(SB)
412 MOVW (R0), R0 // errno
413 RSB.CS $0, R0 // caller expects negative errno
414 noerr:
415 MOVW R9, R13
416 RET
417
418 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
419 MOVW R13, R9
420 SUB $8, R13
421 BIC $0x7, R13 // align for ELF ABI
422 MOVW R0, R8
423 MOVW 0(R8), R0 // arg 1 fd
424 MOVW 4(R8), R1 // arg 2 cmd
425 MOVW 8(R8), R2 // arg 3 arg (vararg, on stack)
426 MOVW R2, 0(R13)
427 BL libc_fcntl(SB)
428 MOVW $0, R1
429 CMP $-1, R0
430 BNE noerr
431 BL libc_errno(SB)
432 MOVW (R0), R1
433 MOVW $-1, R0
434 noerr:
435 MOVW R0, 12(R8)
436 MOVW R1, 16(R8)
437 MOVW R9, R13
438 RET
439
440 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
441 MOVW R13, R9
442 BIC $0x7, R13 // align for ELF ABI
443 MOVW 4(R0), R1 // arg 2 new
444 MOVW 8(R0), R2 // arg 3 old
445 MOVW 0(R0), R0 // arg 1 sig
446 BL libc_sigaction(SB)
447 CMP $-1, R0
448 BNE 3(PC)
449 MOVW $0, R8 // crash on failure
450 MOVW R8, (R8)
451 MOVW R9, R13
452 RET
453
454 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
455 MOVW R13, R9
456 BIC $0x7, R13 // align for ELF ABI
457 MOVW 4(R0), R1 // arg 2 new
458 MOVW 8(R0), R2 // arg 3 old
459 MOVW 0(R0), R0 // arg 1 how
460 BL libc_pthread_sigmask(SB)
461 CMP $-1, R0
462 BNE 3(PC)
463 MOVW $0, R8 // crash on failure
464 MOVW R8, (R8)
465 MOVW R9, R13
466 RET
467
468 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
469 MOVW R13, R9
470 BIC $0x7, R13 // align for ELF ABI
471 MOVW 4(R0), R1 // arg 2 old
472 MOVW 0(R0), R0 // arg 1 new
473 BL libc_sigaltstack(SB)
474 CMP $-1, R0
475 BNE 3(PC)
476 MOVW $0, R8 // crash on failure
477 MOVW R8, (R8)
478 MOVW R9, R13
479 RET
480
481 // syscall calls a function in libc on behalf of the syscall package.
482 // syscall takes a pointer to a struct like:
483 // struct {
484 // fn uintptr
485 // a1 uintptr
486 // a2 uintptr
487 // a3 uintptr
488 // r1 uintptr
489 // r2 uintptr
490 // err uintptr
491 // }
492 // syscall must be called on the g0 stack with the
493 // C calling convention (use libcCall).
494 //
495 // syscall expects a 32-bit result and tests for 32-bit -1
496 // to decide there was an error.
497 TEXT runtime·syscall(SB),NOSPLIT,$0
498 MOVW R13, R9
499 BIC $0x7, R13 // align for ELF ABI
500
501 MOVW R0, R8
502
503 MOVW (0*4)(R8), R7 // fn
504 MOVW (1*4)(R8), R0 // a1
505 MOVW (2*4)(R8), R1 // a2
506 MOVW (3*4)(R8), R2 // a3
507
508 BL (R7)
509
510 MOVW R0, (4*4)(R8) // r1
511 MOVW R1, (5*4)(R8) // r2
512
513 // Standard libc functions return -1 on error and set errno.
514 CMP $-1, R0
515 BNE ok
516
517 // Get error code from libc.
518 BL libc_errno(SB)
519 MOVW (R0), R1
520 MOVW R1, (6*4)(R8) // err
521
522 ok:
523 MOVW $0, R0 // no error (it's ignored anyway)
524 MOVW R9, R13
525 RET
526
527 // syscallX calls a function in libc on behalf of the syscall package.
528 // syscallX takes a pointer to a struct like:
529 // struct {
530 // fn uintptr
531 // a1 uintptr
532 // a2 uintptr
533 // a3 uintptr
534 // r1 uintptr
535 // r2 uintptr
536 // err uintptr
537 // }
538 // syscallX must be called on the g0 stack with the
539 // C calling convention (use libcCall).
540 //
541 // syscallX is like syscall but expects a 64-bit result
542 // and tests for 64-bit -1 to decide there was an error.
543 TEXT runtime·syscallX(SB),NOSPLIT,$0
544 MOVW R13, R9
545 BIC $0x7, R13 // align for ELF ABI
546
547 MOVW R0, R8
548
549 MOVW (0*4)(R8), R7 // fn
550 MOVW (1*4)(R8), R0 // a1
551 MOVW (2*4)(R8), R1 // a2
552 MOVW (3*4)(R8), R2 // a3
553
554 BL (R7)
555
556 MOVW R0, (4*4)(R8) // r1
557 MOVW R1, (5*4)(R8) // r2
558
559 // Standard libc functions return -1 on error and set errno.
560 CMP $-1, R0
561 BNE ok
562 CMP $-1, R1
563 BNE ok
564
565 // Get error code from libc.
566 BL libc_errno(SB)
567 MOVW (R0), R1
568 MOVW R1, (6*4)(R8) // err
569
570 ok:
571 MOVW $0, R0 // no error (it's ignored anyway)
572 MOVW R9, R13
573 RET
574
575 // syscall6 calls a function in libc on behalf of the syscall package.
576 // syscall6 takes a pointer to a struct like:
577 // struct {
578 // fn uintptr
579 // a1 uintptr
580 // a2 uintptr
581 // a3 uintptr
582 // a4 uintptr
583 // a5 uintptr
584 // a6 uintptr
585 // r1 uintptr
586 // r2 uintptr
587 // err uintptr
588 // }
589 // syscall6 must be called on the g0 stack with the
590 // C calling convention (use libcCall).
591 //
592 // syscall6 expects a 32-bit result and tests for 32-bit -1
593 // to decide there was an error.
594 TEXT runtime·syscall6(SB),NOSPLIT,$0
595 MOVW R13, R9
596 SUB $8, R13
597 BIC $0x7, R13 // align for ELF ABI
598
599 MOVW R0, R8
600
601 MOVW (0*4)(R8), R7 // fn
602 MOVW (1*4)(R8), R0 // a1
603 MOVW (2*4)(R8), R1 // a2
604 MOVW (3*4)(R8), R2 // a3
605 MOVW (4*4)(R8), R3 // a4
606 MOVW (5*4)(R8), R4 // a5
607 MOVW R4, 0(R13)
608 MOVW (6*4)(R8), R5 // a6
609 MOVW R5, 4(R13)
610
611 BL (R7)
612
613 MOVW R0, (7*4)(R8) // r1
614 MOVW R1, (8*4)(R8) // r2
615
616 // Standard libc functions return -1 on error and set errno.
617 CMP $-1, R0
618 BNE ok
619
620 // Get error code from libc.
621 BL libc_errno(SB)
622 MOVW (R0), R1
623 MOVW R1, (9*4)(R8) // err
624
625 ok:
626 MOVW $0, R0 // no error (it's ignored anyway)
627 MOVW R9, R13
628 RET
629
630 // syscall6X calls a function in libc on behalf of the syscall package.
631 // syscall6X takes a pointer to a struct like:
632 // struct {
633 // fn uintptr
634 // a1 uintptr
635 // a2 uintptr
636 // a3 uintptr
637 // a4 uintptr
638 // a5 uintptr
639 // a6 uintptr
640 // r1 uintptr
641 // r2 uintptr
642 // err uintptr
643 // }
644 // syscall6X must be called on the g0 stack with the
645 // C calling convention (use libcCall).
646 //
647 // syscall6X is like syscall6 but expects a 64-bit result
648 // and tests for 64-bit -1 to decide there was an error.
649 TEXT runtime·syscall6X(SB),NOSPLIT,$0
650 MOVW R13, R9
651 SUB $8, R13
652 BIC $0x7, R13 // align for ELF ABI
653
654 MOVW R0, R8
655
656 MOVW (0*4)(R8), R7 // fn
657 MOVW (1*4)(R8), R0 // a1
658 MOVW (2*4)(R8), R1 // a2
659 MOVW (3*4)(R8), R2 // a3
660 MOVW (4*4)(R8), R3 // a4
661 MOVW (5*4)(R8), R4 // a5
662 MOVW R4, 0(R13)
663 MOVW (6*4)(R8), R5 // a6
664 MOVW R5, 4(R13)
665
666 BL (R7)
667
668 MOVW R0, (7*4)(R8) // r1
669 MOVW R1, (8*4)(R8) // r2
670
671 // Standard libc functions return -1 on error and set errno.
672 CMP $-1, R0
673 BNE ok
674 CMP $-1, R1
675 BNE ok
676
677 // Get error code from libc.
678 BL libc_errno(SB)
679 MOVW (R0), R1
680 MOVW R1, (9*4)(R8) // err
681
682 ok:
683 MOVW $0, R0 // no error (it's ignored anyway)
684 MOVW R9, R13
685 RET
686
687 // syscall10 calls a function in libc on behalf of the syscall package.
688 // syscall10 takes a pointer to a struct like:
689 // struct {
690 // fn uintptr
691 // a1 uintptr
692 // a2 uintptr
693 // a3 uintptr
694 // a4 uintptr
695 // a5 uintptr
696 // a6 uintptr
697 // a7 uintptr
698 // a8 uintptr
699 // a9 uintptr
700 // a10 uintptr
701 // r1 uintptr
702 // r2 uintptr
703 // err uintptr
704 // }
705 // syscall10 must be called on the g0 stack with the
706 // C calling convention (use libcCall).
707 TEXT runtime·syscall10(SB),NOSPLIT,$0
708 MOVW R13, R9
709 SUB $24, R13
710 BIC $0x7, R13 // align for ELF ABI
711
712 MOVW R0, R8
713
714 MOVW (0*4)(R8), R7 // fn
715 MOVW (1*4)(R8), R0 // a1
716 MOVW (2*4)(R8), R1 // a2
717 MOVW (3*4)(R8), R2 // a3
718 MOVW (4*4)(R8), R3 // a4
719 MOVW (5*4)(R8), R4 // a5
720 MOVW R4, 0(R13)
721 MOVW (6*4)(R8), R5 // a6
722 MOVW R5, 4(R13)
723 MOVW (7*4)(R8), R6 // a7
724 MOVW R6, 8(R13)
725 MOVW (8*4)(R8), R4 // a8
726 MOVW R4, 12(R13)
727 MOVW (9*4)(R8), R5 // a9
728 MOVW R5, 16(R13)
729 MOVW (10*4)(R8), R6 // a10
730 MOVW R6, 20(R13)
731
732 BL (R7)
733
734 MOVW R0, (11*4)(R8) // r1
735 MOVW R1, (12*4)(R8) // r2
736
737 // Standard libc functions return -1 on error and set errno.
738 CMP $-1, R0
739 BNE ok
740
741 // Get error code from libc.
742 BL libc_errno(SB)
743 MOVW (R0), R1
744 MOVW R1, (13*4)(R8) // err
745
746 ok:
747 MOVW $0, R0 // no error (it's ignored anyway)
748 MOVW R9, R13
749 RET
750
751 // syscall10X calls a function in libc on behalf of the syscall package.
752 // syscall10X takes a pointer to a struct like:
753 // struct {
754 // fn uintptr
755 // a1 uintptr
756 // a2 uintptr
757 // a3 uintptr
758 // a4 uintptr
759 // a5 uintptr
760 // a6 uintptr
761 // a7 uintptr
762 // a8 uintptr
763 // a9 uintptr
764 // a10 uintptr
765 // r1 uintptr
766 // r2 uintptr
767 // err uintptr
768 // }
769 // syscall10X must be called on the g0 stack with the
770 // C calling convention (use libcCall).
771 //
772 // syscall10X is like syscall10 but expects a 64-bit result
773 // and tests for 64-bit -1 to decide there was an error.
774 TEXT runtime·syscall10X(SB),NOSPLIT,$0
775 MOVW R13, R9
776 SUB $24, R13
777 BIC $0x7, R13 // align for ELF ABI
778
779 MOVW R0, R8
780
781 MOVW (0*4)(R8), R7 // fn
782 MOVW (1*4)(R8), R0 // a1
783 MOVW (2*4)(R8), R1 // a2
784 MOVW (3*4)(R8), R2 // a3
785 MOVW (4*4)(R8), R3 // a4
786 MOVW (5*4)(R8), R4 // a5
787 MOVW R4, 0(R13)
788 MOVW (6*4)(R8), R5 // a6
789 MOVW R5, 4(R13)
790 MOVW (7*4)(R8), R6 // a7
791 MOVW R6, 8(R13)
792 MOVW (8*4)(R8), R4 // a8
793 MOVW R4, 12(R13)
794 MOVW (9*4)(R8), R5 // a9
795 MOVW R5, 16(R13)
796 MOVW (10*4)(R8), R6 // a10
797 MOVW R6, 20(R13)
798
799 BL (R7)
800
801 MOVW R0, (11*4)(R8) // r1
802 MOVW R1, (12*4)(R8) // r2
803
804 // Standard libc functions return -1 on error and set errno.
805 CMP $-1, R0
806 BNE ok
807 CMP $-1, R1
808 BNE ok
809
810 // Get error code from libc.
811 BL libc_errno(SB)
812 MOVW (R0), R1
813 MOVW R1, (13*4)(R8) // err
814
815 ok:
816 MOVW $0, R0 // no error (it's ignored anyway)
817 MOVW R9, R13
818 RET
819
820 TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
821 MOVW R13, R9
822 MOVW R0, R8
823 BIC $0x7, R13 // align for ELF ABI
824 BL libc_issetugid(SB)
825 MOVW R0, 0(R8)
826 MOVW R9, R13
827 RET
828
View as plain text