Text file
src/runtime/sys_openbsd_amd64.s
Documentation: runtime
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 AMD64, OpenBSD.
6// System calls are implemented in libc/libpthread, this file
7// contains trampolines that convert from Go to C calling convention.
8// Some direct system call implementations currently remain.
9//
10
11#include "go_asm.h"
12#include "go_tls.h"
13#include "textflag.h"
14#include "cgo/abi_amd64.h"
15
16#define CLOCK_MONOTONIC $3
17
18TEXT runtime·settls(SB),NOSPLIT,$0
19 // Nothing to do, pthread already set thread-local storage up.
20 RET
21
22// mstart_stub is the first function executed on a new thread started by pthread_create.
23// It just does some low-level setup and then calls mstart.
24// Note: called with the C calling convention.
25TEXT runtime·mstart_stub(SB),NOSPLIT,$0
26 // DI points to the m.
27 // We are already on m's g0 stack.
28
29 // Transition from C ABI to Go ABI.
30 PUSH_REGS_HOST_TO_ABI0()
31
32 // Load g and save to TLS entry.
33 // See cmd/link/internal/ld/sym.go:computeTLSOffset.
34 MOVQ m_g0(DI), DX // g
35 MOVQ DX, -8(FS)
36
37 CALL runtime·mstart(SB)
38
39 POP_REGS_HOST_TO_ABI0()
40
41 // Go is all done with this OS thread.
42 // Tell pthread everything is ok (we never join with this thread, so
43 // the value here doesn't really matter).
44 XORL AX, AX
45 RET
46
47TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
48 MOVQ fn+0(FP), AX
49 MOVL sig+8(FP), DI
50 MOVQ info+16(FP), SI
51 MOVQ ctx+24(FP), DX
52 PUSHQ BP
53 MOVQ SP, BP
54 ANDQ $~15, SP // alignment for x86_64 ABI
55 CALL AX
56 MOVQ BP, SP
57 POPQ BP
58 RET
59
60// Called using C ABI.
61TEXT runtime·sigtramp<ABIInternal>(SB),NOSPLIT,$0
62 // Transition from C ABI to Go ABI.
63 PUSH_REGS_HOST_TO_ABI0()
64
65 // Call into the Go signal handler
66 NOP SP // disable vet stack checking
67 ADJSP $24
68 MOVQ DI, 0(SP) // sig
69 MOVQ SI, 8(SP) // info
70 MOVQ DX, 16(SP) // ctx
71 CALL ·sigtrampgo(SB)
72 ADJSP $-24
73
74 POP_REGS_HOST_TO_ABI0()
75 RET
76
77//
78// These trampolines help convert from Go calling convention to C calling convention.
79// They should be called with asmcgocall.
80// A pointer to the arguments is passed in DI.
81// A single int32 result is returned in AX.
82// (For more results, make an args/results structure.)
83TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
84 PUSHQ BP
85 MOVQ SP, BP
86 MOVQ 0(DI), DI // arg 1 - attr
87 CALL libc_pthread_attr_init(SB)
88 POPQ BP
89 RET
90
91TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
92 PUSHQ BP
93 MOVQ SP, BP
94 MOVQ 0(DI), DI // arg 1 - attr
95 CALL libc_pthread_attr_destroy(SB)
96 POPQ BP
97 RET
98
99TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
100 PUSHQ BP
101 MOVQ SP, BP
102 MOVQ 8(DI), SI // arg 2 - stacksize
103 MOVQ 0(DI), DI // arg 1 - attr
104 CALL libc_pthread_attr_getstacksize(SB)
105 POPQ BP
106 RET
107
108TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
109 PUSHQ BP
110 MOVQ SP, BP
111 MOVQ 8(DI), SI // arg 2 - detachstate
112 MOVQ 0(DI), DI // arg 1 - attr
113 CALL libc_pthread_attr_setdetachstate(SB)
114 POPQ BP
115 RET
116
117TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
118 PUSHQ BP
119 MOVQ SP, BP
120 SUBQ $16, SP
121 MOVQ 0(DI), SI // arg 2 - attr
122 MOVQ 8(DI), DX // arg 3 - start
123 MOVQ 16(DI), CX // arg 4 - arg
124 MOVQ SP, DI // arg 1 - &thread (discarded)
125 CALL libc_pthread_create(SB)
126 MOVQ BP, SP
127 POPQ BP
128 RET
129
130TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
131 PUSHQ BP
132 MOVQ SP, BP
133 MOVL 8(DI), SI // arg 2 - signal
134 MOVQ $0, DX // arg 3 - tcb
135 MOVL 0(DI), DI // arg 1 - tid
136 CALL libc_thrkill(SB)
137 POPQ BP
138 RET
139
140TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
141 PUSHQ BP
142 MOVQ SP, BP
143 MOVL 8(DI), SI // arg 2 - clock_id
144 MOVQ 16(DI), DX // arg 3 - abstime
145 MOVQ 24(DI), CX // arg 4 - lock
146 MOVQ 32(DI), R8 // arg 5 - abort
147 MOVQ 0(DI), DI // arg 1 - id
148 CALL libc_thrsleep(SB)
149 POPQ BP
150 RET
151
152TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
153 PUSHQ BP
154 MOVQ SP, BP
155 MOVL 8(DI), SI // arg 2 - count
156 MOVQ 0(DI), DI // arg 1 - id
157 CALL libc_thrwakeup(SB)
158 POPQ BP
159 RET
160
161TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
162 PUSHQ BP
163 MOVQ SP, BP
164 MOVL 0(DI), DI // arg 1 exit status
165 CALL libc_exit(SB)
166 MOVL $0xf1, 0xf1 // crash
167 POPQ BP
168 RET
169
170TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
171 PUSHQ BP
172 MOVQ SP, BP
173 MOVQ DI, BX // BX is caller-save
174 CALL libc_getthrid(SB)
175 MOVL AX, 0(BX) // return value
176 POPQ BP
177 RET
178
179TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
180 PUSHQ BP
181 MOVQ SP, BP
182 MOVL 0(DI), BX // signal
183 CALL libc_getpid(SB)
184 MOVL AX, DI // arg 1 pid
185 MOVL BX, SI // arg 2 signal
186 CALL libc_kill(SB)
187 POPQ BP
188 RET
189
190TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
191 PUSHQ BP
192 MOVQ SP, BP
193 CALL libc_sched_yield(SB)
194 POPQ BP
195 RET
196
197TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
198 PUSHQ BP // make a frame; keep stack aligned
199 MOVQ SP, BP
200 MOVQ DI, BX
201 MOVQ 0(BX), DI // arg 1 addr
202 MOVQ 8(BX), SI // arg 2 len
203 MOVL 16(BX), DX // arg 3 prot
204 MOVL 20(BX), CX // arg 4 flags
205 MOVL 24(BX), R8 // arg 5 fid
206 MOVL 28(BX), R9 // arg 6 offset
207 CALL libc_mmap(SB)
208 XORL DX, DX
209 CMPQ AX, $-1
210 JNE ok
211 CALL libc_errno(SB)
212 MOVLQSX (AX), DX // errno
213 XORQ AX, AX
214ok:
215 MOVQ AX, 32(BX)
216 MOVQ DX, 40(BX)
217 POPQ BP
218 RET
219
220TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
221 PUSHQ BP
222 MOVQ SP, BP
223 MOVQ 8(DI), SI // arg 2 len
224 MOVQ 0(DI), DI // arg 1 addr
225 CALL libc_munmap(SB)
226 TESTQ AX, AX
227 JEQ 2(PC)
228 MOVL $0xf1, 0xf1 // crash
229 POPQ BP
230 RET
231
232TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
233 PUSHQ BP
234 MOVQ SP, BP
235 MOVQ 8(DI), SI // arg 2 len
236 MOVL 16(DI), DX // arg 3 advice
237 MOVQ 0(DI), DI // arg 1 addr
238 CALL libc_madvise(SB)
239 // ignore failure - maybe pages are locked
240 POPQ BP
241 RET
242
243TEXT runtime·open_trampoline(SB),NOSPLIT,$0
244 PUSHQ BP
245 MOVQ SP, BP
246 MOVL 8(DI), SI // arg 2 - flags
247 MOVL 12(DI), DX // arg 3 - mode
248 MOVQ 0(DI), DI // arg 1 - path
249 XORL AX, AX // vararg: say "no float args"
250 CALL libc_open(SB)
251 POPQ BP
252 RET
253
254TEXT runtime·close_trampoline(SB),NOSPLIT,$0
255 PUSHQ BP
256 MOVQ SP, BP
257 MOVL 0(DI), DI // arg 1 - fd
258 CALL libc_close(SB)
259 POPQ BP
260 RET
261
262TEXT runtime·read_trampoline(SB),NOSPLIT,$0
263 PUSHQ BP
264 MOVQ SP, BP
265 MOVQ 8(DI), SI // arg 2 - buf
266 MOVL 16(DI), DX // arg 3 - count
267 MOVL 0(DI), DI // arg 1 - fd
268 CALL libc_read(SB)
269 TESTL AX, AX
270 JGE noerr
271 CALL libc_errno(SB)
272 MOVL (AX), AX // errno
273 NEGL AX // caller expects negative errno value
274noerr:
275 POPQ BP
276 RET
277
278TEXT runtime·write_trampoline(SB),NOSPLIT,$0
279 PUSHQ BP
280 MOVQ SP, BP
281 MOVQ 8(DI), SI // arg 2 buf
282 MOVL 16(DI), DX // arg 3 count
283 MOVL 0(DI), DI // arg 1 fd
284 CALL libc_write(SB)
285 TESTL AX, AX
286 JGE noerr
287 CALL libc_errno(SB)
288 MOVL (AX), AX // errno
289 NEGL AX // caller expects negative errno value
290noerr:
291 POPQ BP
292 RET
293
294TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
295 PUSHQ BP
296 MOVQ SP, BP
297 MOVL 8(DI), SI // arg 2 flags
298 MOVQ 0(DI), DI // arg 1 filedes
299 CALL libc_pipe2(SB)
300 TESTL AX, AX
301 JEQ 3(PC)
302 CALL libc_errno(SB)
303 MOVL (AX), AX // errno
304 NEGL AX // caller expects negative errno value
305 POPQ BP
306 RET
307
308TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
309 PUSHQ BP
310 MOVQ SP, BP
311 MOVQ 8(DI), SI // arg 2 new
312 MOVQ 16(DI), DX // arg 3 old
313 MOVL 0(DI), DI // arg 1 which
314 CALL libc_setitimer(SB)
315 POPQ BP
316 RET
317
318TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
319 PUSHQ BP
320 MOVQ SP, BP
321 MOVL 0(DI), DI // arg 1 usec
322 CALL libc_usleep(SB)
323 POPQ BP
324 RET
325
326TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
327 PUSHQ BP
328 MOVQ SP, BP
329 MOVL 8(DI), SI // arg 2 miblen
330 MOVQ 16(DI), DX // arg 3 out
331 MOVQ 24(DI), CX // arg 4 size
332 MOVQ 32(DI), R8 // arg 5 dst
333 MOVQ 40(DI), R9 // arg 6 ndst
334 MOVQ 0(DI), DI // arg 1 mib
335 CALL libc_sysctl(SB)
336 POPQ BP
337 RET
338
339TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
340 PUSHQ BP
341 MOVQ SP, BP
342 CALL libc_kqueue(SB)
343 POPQ BP
344 RET
345
346TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
347 PUSHQ BP
348 MOVQ SP, BP
349 MOVQ 8(DI), SI // arg 2 keventt
350 MOVL 16(DI), DX // arg 3 nch
351 MOVQ 24(DI), CX // arg 4 ev
352 MOVL 32(DI), R8 // arg 5 nev
353 MOVQ 40(DI), R9 // arg 6 ts
354 MOVL 0(DI), DI // arg 1 kq
355 CALL libc_kevent(SB)
356 CMPL AX, $-1
357 JNE ok
358 CALL libc_errno(SB)
359 MOVL (AX), AX // errno
360 NEGL AX // caller expects negative errno value
361ok:
362 POPQ BP
363 RET
364
365TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
366 PUSHQ BP // make a frame; keep stack aligned
367 MOVQ SP, BP
368 MOVQ 8(DI), SI // arg 2 tp
369 MOVL 0(DI), DI // arg 1 clock_id
370 CALL libc_clock_gettime(SB)
371 TESTL AX, AX
372 JEQ 2(PC)
373 MOVL $0xf1, 0xf1 // crash
374 POPQ BP
375 RET
376
377TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
378 PUSHQ BP
379 MOVQ SP, BP
380 MOVL 4(DI), SI // arg 2 cmd
381 MOVL 8(DI), DX // arg 3 arg
382 MOVL 0(DI), DI // arg 1 fd
383 XORL AX, AX // vararg: say "no float args"
384 CALL libc_fcntl(SB)
385 POPQ BP
386 RET
387
388TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
389 PUSHQ BP
390 MOVQ SP, BP
391 MOVQ 8(DI), SI // arg 2 new
392 MOVQ 16(DI), DX // arg 3 old
393 MOVL 0(DI), DI // arg 1 sig
394 CALL libc_sigaction(SB)
395 TESTL AX, AX
396 JEQ 2(PC)
397 MOVL $0xf1, 0xf1 // crash
398 POPQ BP
399 RET
400
401TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
402 PUSHQ BP
403 MOVQ SP, BP
404 MOVQ 8(DI), SI // arg 2 new
405 MOVQ 16(DI), DX // arg 3 old
406 MOVL 0(DI), DI // arg 1 how
407 CALL libc_pthread_sigmask(SB)
408 TESTL AX, AX
409 JEQ 2(PC)
410 MOVL $0xf1, 0xf1 // crash
411 POPQ BP
412 RET
413
414TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
415 PUSHQ BP
416 MOVQ SP, BP
417 MOVQ 8(DI), SI // arg 2 old
418 MOVQ 0(DI), DI // arg 1 new
419 CALL libc_sigaltstack(SB)
420 TESTQ AX, AX
421 JEQ 2(PC)
422 MOVL $0xf1, 0xf1 // crash
423 POPQ BP
424 RET
425
426// syscall calls a function in libc on behalf of the syscall package.
427// syscall takes a pointer to a struct like:
428// struct {
429// fn uintptr
430// a1 uintptr
431// a2 uintptr
432// a3 uintptr
433// r1 uintptr
434// r2 uintptr
435// err uintptr
436// }
437// syscall must be called on the g0 stack with the
438// C calling convention (use libcCall).
439//
440// syscall expects a 32-bit result and tests for 32-bit -1
441// to decide there was an error.
442TEXT runtime·syscall(SB),NOSPLIT,$0
443 PUSHQ BP
444 MOVQ SP, BP
445 SUBQ $16, SP
446 MOVQ (0*8)(DI), CX // fn
447 MOVQ (2*8)(DI), SI // a2
448 MOVQ (3*8)(DI), DX // a3
449 MOVQ DI, (SP)
450 MOVQ (1*8)(DI), DI // a1
451 XORL AX, AX // vararg: say "no float args"
452
453 CALL CX
454
455 MOVQ (SP), DI
456 MOVQ AX, (4*8)(DI) // r1
457 MOVQ DX, (5*8)(DI) // r2
458
459 // Standard libc functions return -1 on error
460 // and set errno.
461 CMPL AX, $-1 // Note: high 32 bits are junk
462 JNE ok
463
464 // Get error code from libc.
465 CALL libc_errno(SB)
466 MOVLQSX (AX), AX
467 MOVQ (SP), DI
468 MOVQ AX, (6*8)(DI) // err
469
470ok:
471 XORL AX, AX // no error (it's ignored anyway)
472 MOVQ BP, SP
473 POPQ BP
474 RET
475
476// syscallX calls a function in libc on behalf of the syscall package.
477// syscallX takes a pointer to a struct like:
478// struct {
479// fn uintptr
480// a1 uintptr
481// a2 uintptr
482// a3 uintptr
483// r1 uintptr
484// r2 uintptr
485// err uintptr
486// }
487// syscallX must be called on the g0 stack with the
488// C calling convention (use libcCall).
489//
490// syscallX is like syscall but expects a 64-bit result
491// and tests for 64-bit -1 to decide there was an error.
492TEXT runtime·syscallX(SB),NOSPLIT,$0
493 PUSHQ BP
494 MOVQ SP, BP
495 SUBQ $16, SP
496 MOVQ (0*8)(DI), CX // fn
497 MOVQ (2*8)(DI), SI // a2
498 MOVQ (3*8)(DI), DX // a3
499 MOVQ DI, (SP)
500 MOVQ (1*8)(DI), DI // a1
501 XORL AX, AX // vararg: say "no float args"
502
503 CALL CX
504
505 MOVQ (SP), DI
506 MOVQ AX, (4*8)(DI) // r1
507 MOVQ DX, (5*8)(DI) // r2
508
509 // Standard libc functions return -1 on error
510 // and set errno.
511 CMPQ AX, $-1
512 JNE ok
513
514 // Get error code from libc.
515 CALL libc_errno(SB)
516 MOVLQSX (AX), AX
517 MOVQ (SP), DI
518 MOVQ AX, (6*8)(DI) // err
519
520ok:
521 XORL AX, AX // no error (it's ignored anyway)
522 MOVQ BP, SP
523 POPQ BP
524 RET
525
526// syscall6 calls a function in libc on behalf of the syscall package.
527// syscall6 takes a pointer to a struct like:
528// struct {
529// fn uintptr
530// a1 uintptr
531// a2 uintptr
532// a3 uintptr
533// a4 uintptr
534// a5 uintptr
535// a6 uintptr
536// r1 uintptr
537// r2 uintptr
538// err uintptr
539// }
540// syscall6 must be called on the g0 stack with the
541// C calling convention (use libcCall).
542//
543// syscall6 expects a 32-bit result and tests for 32-bit -1
544// to decide there was an error.
545TEXT runtime·syscall6(SB),NOSPLIT,$0
546 PUSHQ BP
547 MOVQ SP, BP
548 SUBQ $16, SP
549 MOVQ (0*8)(DI), R11// fn
550 MOVQ (2*8)(DI), SI // a2
551 MOVQ (3*8)(DI), DX // a3
552 MOVQ (4*8)(DI), CX // a4
553 MOVQ (5*8)(DI), R8 // a5
554 MOVQ (6*8)(DI), R9 // a6
555 MOVQ DI, (SP)
556 MOVQ (1*8)(DI), DI // a1
557 XORL AX, AX // vararg: say "no float args"
558
559 CALL R11
560
561 MOVQ (SP), DI
562 MOVQ AX, (7*8)(DI) // r1
563 MOVQ DX, (8*8)(DI) // r2
564
565 CMPL AX, $-1
566 JNE ok
567
568 CALL libc_errno(SB)
569 MOVLQSX (AX), AX
570 MOVQ (SP), DI
571 MOVQ AX, (9*8)(DI) // err
572
573ok:
574 XORL AX, AX // no error (it's ignored anyway)
575 MOVQ BP, SP
576 POPQ BP
577 RET
578
579// syscall6X calls a function in libc on behalf of the syscall package.
580// syscall6X takes a pointer to a struct like:
581// struct {
582// fn uintptr
583// a1 uintptr
584// a2 uintptr
585// a3 uintptr
586// a4 uintptr
587// a5 uintptr
588// a6 uintptr
589// r1 uintptr
590// r2 uintptr
591// err uintptr
592// }
593// syscall6X must be called on the g0 stack with the
594// C calling convention (use libcCall).
595//
596// syscall6X is like syscall6 but expects a 64-bit result
597// and tests for 64-bit -1 to decide there was an error.
598TEXT runtime·syscall6X(SB),NOSPLIT,$0
599 PUSHQ BP
600 MOVQ SP, BP
601 SUBQ $16, SP
602 MOVQ (0*8)(DI), R11// fn
603 MOVQ (2*8)(DI), SI // a2
604 MOVQ (3*8)(DI), DX // a3
605 MOVQ (4*8)(DI), CX // a4
606 MOVQ (5*8)(DI), R8 // a5
607 MOVQ (6*8)(DI), R9 // a6
608 MOVQ DI, (SP)
609 MOVQ (1*8)(DI), DI // a1
610 XORL AX, AX // vararg: say "no float args"
611
612 CALL R11
613
614 MOVQ (SP), DI
615 MOVQ AX, (7*8)(DI) // r1
616 MOVQ DX, (8*8)(DI) // r2
617
618 CMPQ AX, $-1
619 JNE ok
620
621 CALL libc_errno(SB)
622 MOVLQSX (AX), AX
623 MOVQ (SP), DI
624 MOVQ AX, (9*8)(DI) // err
625
626ok:
627 XORL AX, AX // no error (it's ignored anyway)
628 MOVQ BP, SP
629 POPQ BP
630 RET
631
632// syscall10 calls a function in libc on behalf of the syscall package.
633// syscall10 takes a pointer to a struct like:
634// struct {
635// fn uintptr
636// a1 uintptr
637// a2 uintptr
638// a3 uintptr
639// a4 uintptr
640// a5 uintptr
641// a6 uintptr
642// a7 uintptr
643// a8 uintptr
644// a9 uintptr
645// a10 uintptr
646// r1 uintptr
647// r2 uintptr
648// err uintptr
649// }
650// syscall10 must be called on the g0 stack with the
651// C calling convention (use libcCall).
652TEXT runtime·syscall10(SB),NOSPLIT,$0
653 PUSHQ BP
654 MOVQ SP, BP
655 SUBQ $48, SP
656
657 // Arguments a1 to a6 get passed in registers, with a7 onwards being
658 // passed via the stack per the x86-64 System V ABI
659 // (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
660 MOVQ (7*8)(DI), R10 // a7
661 MOVQ (8*8)(DI), R11 // a8
662 MOVQ (9*8)(DI), R12 // a9
663 MOVQ (10*8)(DI), R13 // a10
664 MOVQ R10, (0*8)(SP) // a7
665 MOVQ R11, (1*8)(SP) // a8
666 MOVQ R12, (2*8)(SP) // a9
667 MOVQ R13, (3*8)(SP) // a10
668 MOVQ (0*8)(DI), R11 // fn
669 MOVQ (2*8)(DI), SI // a2
670 MOVQ (3*8)(DI), DX // a3
671 MOVQ (4*8)(DI), CX // a4
672 MOVQ (5*8)(DI), R8 // a5
673 MOVQ (6*8)(DI), R9 // a6
674 MOVQ DI, (4*8)(SP)
675 MOVQ (1*8)(DI), DI // a1
676 XORL AX, AX // vararg: say "no float args"
677
678 CALL R11
679
680 MOVQ (4*8)(SP), DI
681 MOVQ AX, (11*8)(DI) // r1
682 MOVQ DX, (12*8)(DI) // r2
683
684 CMPL AX, $-1
685 JNE ok
686
687 CALL libc_errno(SB)
688 MOVLQSX (AX), AX
689 MOVQ (4*8)(SP), DI
690 MOVQ AX, (13*8)(DI) // err
691
692ok:
693 XORL AX, AX // no error (it's ignored anyway)
694 MOVQ BP, SP
695 POPQ BP
696 RET
697
698// syscall10X calls a function in libc on behalf of the syscall package.
699// syscall10X takes a pointer to a struct like:
700// struct {
701// fn uintptr
702// a1 uintptr
703// a2 uintptr
704// a3 uintptr
705// a4 uintptr
706// a5 uintptr
707// a6 uintptr
708// a7 uintptr
709// a8 uintptr
710// a9 uintptr
711// a10 uintptr
712// r1 uintptr
713// r2 uintptr
714// err uintptr
715// }
716// syscall10X must be called on the g0 stack with the
717// C calling convention (use libcCall).
718//
719// syscall10X is like syscall10 but expects a 64-bit result
720// and tests for 64-bit -1 to decide there was an error.
721TEXT runtime·syscall10X(SB),NOSPLIT,$0
722 PUSHQ BP
723 MOVQ SP, BP
724 SUBQ $48, SP
725
726 // Arguments a1 to a6 get passed in registers, with a7 onwards being
727 // passed via the stack per the x86-64 System V ABI
728 // (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
729 MOVQ (7*8)(DI), R10 // a7
730 MOVQ (8*8)(DI), R11 // a8
731 MOVQ (9*8)(DI), R12 // a9
732 MOVQ (10*8)(DI), R13 // a10
733 MOVQ R10, (0*8)(SP) // a7
734 MOVQ R11, (1*8)(SP) // a8
735 MOVQ R12, (2*8)(SP) // a9
736 MOVQ R13, (3*8)(SP) // a10
737 MOVQ (0*8)(DI), R11 // fn
738 MOVQ (2*8)(DI), SI // a2
739 MOVQ (3*8)(DI), DX // a3
740 MOVQ (4*8)(DI), CX // a4
741 MOVQ (5*8)(DI), R8 // a5
742 MOVQ (6*8)(DI), R9 // a6
743 MOVQ DI, (4*8)(SP)
744 MOVQ (1*8)(DI), DI // a1
745 XORL AX, AX // vararg: say "no float args"
746
747 CALL R11
748
749 MOVQ (4*8)(SP), DI
750 MOVQ AX, (11*8)(DI) // r1
751 MOVQ DX, (12*8)(DI) // r2
752
753 CMPQ AX, $-1
754 JNE ok
755
756 CALL libc_errno(SB)
757 MOVLQSX (AX), AX
758 MOVQ (4*8)(SP), DI
759 MOVQ AX, (13*8)(DI) // err
760
761ok:
762 XORL AX, AX // no error (it's ignored anyway)
763 MOVQ BP, SP
764 POPQ BP
765 RET
View as plain text