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