Text file
src/runtime/sys_freebsd_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, FreeBSD
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 #include "cgo/abi_amd64.h"
13
14 #define CLOCK_REALTIME 0
15 #define CLOCK_MONOTONIC 4
16 #define AMD64_SET_FSBASE 129
17
18 #define SYS_exit 1
19 #define SYS_read 3
20 #define SYS_write 4
21 #define SYS_open 5
22 #define SYS_close 6
23 #define SYS_getpid 20
24 #define SYS_kill 37
25 #define SYS_sigaltstack 53
26 #define SYS_munmap 73
27 #define SYS_madvise 75
28 #define SYS_setitimer 83
29 #define SYS_fcntl 92
30 #define SYS_sysarch 165
31 #define SYS___sysctl 202
32 #define SYS_clock_gettime 232
33 #define SYS_nanosleep 240
34 #define SYS_issetugid 253
35 #define SYS_sched_yield 331
36 #define SYS_sigprocmask 340
37 #define SYS_kqueue 362
38 #define SYS_sigaction 416
39 #define SYS_thr_exit 431
40 #define SYS_thr_self 432
41 #define SYS_thr_kill 433
42 #define SYS__umtx_op 454
43 #define SYS_thr_new 455
44 #define SYS_mmap 477
45 #define SYS_cpuset_getaffinity 487
46 #define SYS_pipe2 542
47 #define SYS_kevent 560
48
49 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
50 MOVQ addr+0(FP), DI
51 MOVL mode+8(FP), SI
52 MOVL val+12(FP), DX
53 MOVQ uaddr1+16(FP), R10
54 MOVQ ut+24(FP), R8
55 MOVL $SYS__umtx_op, AX
56 SYSCALL
57 JCC 2(PC)
58 NEGQ AX
59 MOVL AX, ret+32(FP)
60 RET
61
62 TEXT runtime·thr_new(SB),NOSPLIT,$0
63 MOVQ param+0(FP), DI
64 MOVL size+8(FP), SI
65 MOVL $SYS_thr_new, AX
66 SYSCALL
67 JCC 2(PC)
68 NEGQ AX
69 MOVL AX, ret+16(FP)
70 RET
71
72 TEXT runtime·thr_start(SB),NOSPLIT,$0
73 MOVQ DI, R13 // m
74
75 // set up FS to point at m->tls
76 LEAQ m_tls(R13), DI
77 CALL runtime·settls(SB) // smashes DI
78
79 // set up m, g
80 get_tls(CX)
81 MOVQ m_g0(R13), DI
82 MOVQ R13, g_m(DI)
83 MOVQ DI, g(CX)
84
85 CALL runtime·stackcheck(SB)
86 CALL runtime·mstart(SB)
87
88 MOVQ 0, AX // crash (not reached)
89
90 // Exit the entire program (like C exit)
91 TEXT runtime·exit(SB),NOSPLIT,$-8
92 MOVL code+0(FP), DI // arg 1 exit status
93 MOVL $SYS_exit, AX
94 SYSCALL
95 MOVL $0xf1, 0xf1 // crash
96 RET
97
98 // func exitThread(wait *atomic.uint32)
99 TEXT runtime·exitThread(SB),NOSPLIT,$0-8
100 MOVQ wait+0(FP), AX
101 // We're done using the stack.
102 MOVL $0, (AX)
103 MOVL $0, DI // arg 1 long *state
104 MOVL $SYS_thr_exit, AX
105 SYSCALL
106 MOVL $0xf1, 0xf1 // crash
107 JMP 0(PC)
108
109 TEXT runtime·open(SB),NOSPLIT,$-8
110 MOVQ name+0(FP), DI // arg 1 pathname
111 MOVL mode+8(FP), SI // arg 2 flags
112 MOVL perm+12(FP), DX // arg 3 mode
113 MOVL $SYS_open, AX
114 SYSCALL
115 JCC 2(PC)
116 MOVL $-1, AX
117 MOVL AX, ret+16(FP)
118 RET
119
120 TEXT runtime·closefd(SB),NOSPLIT,$-8
121 MOVL fd+0(FP), DI // arg 1 fd
122 MOVL $SYS_close, AX
123 SYSCALL
124 JCC 2(PC)
125 MOVL $-1, AX
126 MOVL AX, ret+8(FP)
127 RET
128
129 TEXT runtime·read(SB),NOSPLIT,$-8
130 MOVL fd+0(FP), DI // arg 1 fd
131 MOVQ p+8(FP), SI // arg 2 buf
132 MOVL n+16(FP), DX // arg 3 count
133 MOVL $SYS_read, AX
134 SYSCALL
135 JCC 2(PC)
136 NEGQ AX // caller expects negative errno
137 MOVL AX, ret+24(FP)
138 RET
139
140 // func pipe2(flags int32) (r, w int32, errno int32)
141 TEXT runtime·pipe2(SB),NOSPLIT,$0-20
142 LEAQ r+8(FP), DI
143 MOVL flags+0(FP), SI
144 MOVL $SYS_pipe2, AX
145 SYSCALL
146 JCC 2(PC)
147 NEGQ AX
148 MOVL AX, errno+16(FP)
149 RET
150
151 TEXT runtime·write1(SB),NOSPLIT,$-8
152 MOVQ fd+0(FP), DI // arg 1 fd
153 MOVQ p+8(FP), SI // arg 2 buf
154 MOVL n+16(FP), DX // arg 3 count
155 MOVL $SYS_write, AX
156 SYSCALL
157 JCC 2(PC)
158 NEGQ AX // caller expects negative errno
159 MOVL AX, ret+24(FP)
160 RET
161
162 TEXT runtime·thr_self(SB),NOSPLIT,$0-8
163 // thr_self(&0(FP))
164 LEAQ ret+0(FP), DI // arg 1
165 MOVL $SYS_thr_self, AX
166 SYSCALL
167 RET
168
169 TEXT runtime·thr_kill(SB),NOSPLIT,$0-16
170 // thr_kill(tid, sig)
171 MOVQ tid+0(FP), DI // arg 1 id
172 MOVQ sig+8(FP), SI // arg 2 sig
173 MOVL $SYS_thr_kill, AX
174 SYSCALL
175 RET
176
177 TEXT runtime·raiseproc(SB),NOSPLIT,$0
178 // getpid
179 MOVL $SYS_getpid, AX
180 SYSCALL
181 // kill(self, sig)
182 MOVQ AX, DI // arg 1 pid
183 MOVL sig+0(FP), SI // arg 2 sig
184 MOVL $SYS_kill, AX
185 SYSCALL
186 RET
187
188 TEXT runtime·setitimer(SB), NOSPLIT, $-8
189 MOVL mode+0(FP), DI
190 MOVQ new+8(FP), SI
191 MOVQ old+16(FP), DX
192 MOVL $SYS_setitimer, AX
193 SYSCALL
194 RET
195
196 // func fallback_walltime() (sec int64, nsec int32)
197 TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12
198 MOVL $SYS_clock_gettime, AX
199 MOVQ $CLOCK_REALTIME, DI
200 LEAQ 8(SP), SI
201 SYSCALL
202 MOVQ 8(SP), AX // sec
203 MOVQ 16(SP), DX // nsec
204
205 // sec is in AX, nsec in DX
206 MOVQ AX, sec+0(FP)
207 MOVL DX, nsec+8(FP)
208 RET
209
210 TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32-8
211 MOVL $SYS_clock_gettime, AX
212 MOVQ $CLOCK_MONOTONIC, DI
213 LEAQ 8(SP), SI
214 SYSCALL
215 MOVQ 8(SP), AX // sec
216 MOVQ 16(SP), DX // nsec
217
218 // sec is in AX, nsec in DX
219 // return nsec in AX
220 IMULQ $1000000000, AX
221 ADDQ DX, AX
222 MOVQ AX, ret+0(FP)
223 RET
224
225 TEXT runtime·asmSigaction(SB),NOSPLIT,$0
226 MOVQ sig+0(FP), DI // arg 1 sig
227 MOVQ new+8(FP), SI // arg 2 act
228 MOVQ old+16(FP), DX // arg 3 oact
229 MOVL $SYS_sigaction, AX
230 SYSCALL
231 JCC 2(PC)
232 MOVL $-1, AX
233 MOVL AX, ret+24(FP)
234 RET
235
236 TEXT runtime·callCgoSigaction(SB),NOSPLIT,$16
237 MOVQ sig+0(FP), DI // arg 1 sig
238 MOVQ new+8(FP), SI // arg 2 act
239 MOVQ old+16(FP), DX // arg 3 oact
240 MOVQ _cgo_sigaction(SB), AX
241 MOVQ SP, BX // callee-saved
242 ANDQ $~15, SP // alignment as per amd64 psABI
243 CALL AX
244 MOVQ BX, SP
245 MOVL AX, ret+24(FP)
246 RET
247
248 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
249 MOVQ fn+0(FP), AX
250 MOVL sig+8(FP), DI
251 MOVQ info+16(FP), SI
252 MOVQ ctx+24(FP), DX
253 MOVQ SP, BX // callee-saved
254 ANDQ $~15, SP // alignment for x86_64 ABI
255 CALL AX
256 MOVQ BX, SP
257 RET
258
259 // Called using C ABI.
260 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0
261 // Transition from C ABI to Go ABI.
262 PUSH_REGS_HOST_TO_ABI0()
263
264 // Set up ABIInternal environment: g in R14, cleared X15.
265 get_tls(R12)
266 MOVQ g(R12), R14
267 PXOR X15, X15
268
269 // Reserve space for spill slots.
270 NOP SP // disable vet stack checking
271 ADJSP $24
272
273 // Call into the Go signal handler
274 MOVQ DI, AX // sig
275 MOVQ SI, BX // info
276 MOVQ DX, CX // ctx
277 CALL ·sigtrampgo<ABIInternal>(SB)
278
279 ADJSP $-24
280
281 POP_REGS_HOST_TO_ABI0()
282 RET
283
284 // Called using C ABI.
285 TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT|NOFRAME,$0
286 // Transition from C ABI to Go ABI.
287 PUSH_REGS_HOST_TO_ABI0()
288
289 // Set up ABIInternal environment: g in R14, cleared X15.
290 get_tls(R12)
291 MOVQ g(R12), R14
292 PXOR X15, X15
293
294 // Reserve space for spill slots.
295 NOP SP // disable vet stack checking
296 ADJSP $24
297
298 // Call into the Go signal handler
299 MOVQ DI, AX // sig
300 MOVQ SI, BX // info
301 MOVQ DX, CX // ctx
302 CALL ·sigprofNonGo<ABIInternal>(SB)
303
304 ADJSP $-24
305
306 POP_REGS_HOST_TO_ABI0()
307 RET
308
309 // Used instead of sigtramp in programs that use cgo.
310 // Arguments from kernel are in DI, SI, DX.
311 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
312 // If no traceback function, do usual sigtramp.
313 MOVQ runtime·cgoTraceback(SB), AX
314 TESTQ AX, AX
315 JZ sigtramp
316
317 // If no traceback support function, which means that
318 // runtime/cgo was not linked in, do usual sigtramp.
319 MOVQ _cgo_callers(SB), AX
320 TESTQ AX, AX
321 JZ sigtramp
322
323 // Figure out if we are currently in a cgo call.
324 // If not, just do usual sigtramp.
325 get_tls(CX)
326 MOVQ g(CX),AX
327 TESTQ AX, AX
328 JZ sigtrampnog // g == nil
329 MOVQ g_m(AX), AX
330 TESTQ AX, AX
331 JZ sigtramp // g.m == nil
332 MOVL m_ncgo(AX), CX
333 TESTL CX, CX
334 JZ sigtramp // g.m.ncgo == 0
335 MOVQ m_curg(AX), CX
336 TESTQ CX, CX
337 JZ sigtramp // g.m.curg == nil
338 MOVQ g_syscallsp(CX), CX
339 TESTQ CX, CX
340 JZ sigtramp // g.m.curg.syscallsp == 0
341 MOVQ m_cgoCallers(AX), R8
342 TESTQ R8, R8
343 JZ sigtramp // g.m.cgoCallers == nil
344 MOVL m_cgoCallersUse(AX), CX
345 TESTL CX, CX
346 JNZ sigtramp // g.m.cgoCallersUse != 0
347
348 // Jump to a function in runtime/cgo.
349 // That function, written in C, will call the user's traceback
350 // function with proper unwind info, and will then call back here.
351 // The first three arguments, and the fifth, are already in registers.
352 // Set the two remaining arguments now.
353 MOVQ runtime·cgoTraceback(SB), CX
354 MOVQ $runtime·sigtramp(SB), R9
355 MOVQ _cgo_callers(SB), AX
356 JMP AX
357
358 sigtramp:
359 JMP runtime·sigtramp(SB)
360
361 sigtrampnog:
362 // Signal arrived on a non-Go thread. If this is SIGPROF, get a
363 // stack trace.
364 CMPL DI, $27 // 27 == SIGPROF
365 JNZ sigtramp
366
367 // Lock sigprofCallersUse.
368 MOVL $0, AX
369 MOVL $1, CX
370 MOVQ $runtime·sigprofCallersUse(SB), R11
371 LOCK
372 CMPXCHGL CX, 0(R11)
373 JNZ sigtramp // Skip stack trace if already locked.
374
375 // Jump to the traceback function in runtime/cgo.
376 // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
377 // the arguments to the Go calling convention.
378 // First three arguments to traceback function are in registers already.
379 MOVQ runtime·cgoTraceback(SB), CX
380 MOVQ $runtime·sigprofCallers(SB), R8
381 MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
382 MOVQ _cgo_callers(SB), AX
383 JMP AX
384
385 TEXT runtime·sysMmap(SB),NOSPLIT,$0
386 MOVQ addr+0(FP), DI // arg 1 addr
387 MOVQ n+8(FP), SI // arg 2 len
388 MOVL prot+16(FP), DX // arg 3 prot
389 MOVL flags+20(FP), R10 // arg 4 flags
390 MOVL fd+24(FP), R8 // arg 5 fid
391 MOVL off+28(FP), R9 // arg 6 offset
392 MOVL $SYS_mmap, AX
393 SYSCALL
394 JCC ok
395 MOVQ $0, p+32(FP)
396 MOVQ AX, err+40(FP)
397 RET
398 ok:
399 MOVQ AX, p+32(FP)
400 MOVQ $0, err+40(FP)
401 RET
402
403 // Call the function stored in _cgo_mmap using the GCC calling convention.
404 // This must be called on the system stack.
405 TEXT runtime·callCgoMmap(SB),NOSPLIT,$16
406 MOVQ addr+0(FP), DI
407 MOVQ n+8(FP), SI
408 MOVL prot+16(FP), DX
409 MOVL flags+20(FP), CX
410 MOVL fd+24(FP), R8
411 MOVL off+28(FP), R9
412 MOVQ _cgo_mmap(SB), AX
413 MOVQ SP, BX
414 ANDQ $~15, SP // alignment as per amd64 psABI
415 MOVQ BX, 0(SP)
416 CALL AX
417 MOVQ 0(SP), SP
418 MOVQ AX, ret+32(FP)
419 RET
420
421 TEXT runtime·sysMunmap(SB),NOSPLIT,$0
422 MOVQ addr+0(FP), DI // arg 1 addr
423 MOVQ n+8(FP), SI // arg 2 len
424 MOVL $SYS_munmap, AX
425 SYSCALL
426 JCC 2(PC)
427 MOVL $0xf1, 0xf1 // crash
428 RET
429
430 // Call the function stored in _cgo_munmap using the GCC calling convention.
431 // This must be called on the system stack.
432 TEXT runtime·callCgoMunmap(SB),NOSPLIT,$16-16
433 MOVQ addr+0(FP), DI
434 MOVQ n+8(FP), SI
435 MOVQ _cgo_munmap(SB), AX
436 MOVQ SP, BX
437 ANDQ $~15, SP // alignment as per amd64 psABI
438 MOVQ BX, 0(SP)
439 CALL AX
440 MOVQ 0(SP), SP
441 RET
442
443 TEXT runtime·madvise(SB),NOSPLIT,$0
444 MOVQ addr+0(FP), DI
445 MOVQ n+8(FP), SI
446 MOVL flags+16(FP), DX
447 MOVQ $SYS_madvise, AX
448 SYSCALL
449 JCC 2(PC)
450 MOVL $-1, AX
451 MOVL AX, ret+24(FP)
452 RET
453
454 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
455 MOVQ new+0(FP), DI
456 MOVQ old+8(FP), SI
457 MOVQ $SYS_sigaltstack, AX
458 SYSCALL
459 JCC 2(PC)
460 MOVL $0xf1, 0xf1 // crash
461 RET
462
463 TEXT runtime·usleep(SB),NOSPLIT,$16
464 MOVL $0, DX
465 MOVL usec+0(FP), AX
466 MOVL $1000000, CX
467 DIVL CX
468 MOVQ AX, 0(SP) // tv_sec
469 MOVL $1000, AX
470 MULL DX
471 MOVQ AX, 8(SP) // tv_nsec
472
473 MOVQ SP, DI // arg 1 - rqtp
474 MOVQ $0, SI // arg 2 - rmtp
475 MOVL $SYS_nanosleep, AX
476 SYSCALL
477 RET
478
479 // set tls base to DI
480 TEXT runtime·settls(SB),NOSPLIT,$8
481 ADDQ $8, DI // adjust for ELF: wants to use -8(FS) for g and m
482 MOVQ DI, 0(SP)
483 MOVQ SP, SI
484 MOVQ $AMD64_SET_FSBASE, DI
485 MOVQ $SYS_sysarch, AX
486 SYSCALL
487 JCC 2(PC)
488 MOVL $0xf1, 0xf1 // crash
489 RET
490
491 TEXT runtime·sysctl(SB),NOSPLIT,$0
492 MOVQ mib+0(FP), DI // arg 1 - name
493 MOVL miblen+8(FP), SI // arg 2 - namelen
494 MOVQ out+16(FP), DX // arg 3 - oldp
495 MOVQ size+24(FP), R10 // arg 4 - oldlenp
496 MOVQ dst+32(FP), R8 // arg 5 - newp
497 MOVQ ndst+40(FP), R9 // arg 6 - newlen
498 MOVQ $SYS___sysctl, AX
499 SYSCALL
500 JCC 4(PC)
501 NEGQ AX
502 MOVL AX, ret+48(FP)
503 RET
504 MOVL $0, AX
505 MOVL AX, ret+48(FP)
506 RET
507
508 TEXT runtime·osyield(SB),NOSPLIT,$-4
509 MOVL $SYS_sched_yield, AX
510 SYSCALL
511 RET
512
513 TEXT runtime·sigprocmask(SB),NOSPLIT,$0
514 MOVL how+0(FP), DI // arg 1 - how
515 MOVQ new+8(FP), SI // arg 2 - set
516 MOVQ old+16(FP), DX // arg 3 - oset
517 MOVL $SYS_sigprocmask, AX
518 SYSCALL
519 JAE 2(PC)
520 MOVL $0xf1, 0xf1 // crash
521 RET
522
523 // int32 runtime·kqueue(void);
524 TEXT runtime·kqueue(SB),NOSPLIT,$0
525 MOVQ $0, DI
526 MOVQ $0, SI
527 MOVQ $0, DX
528 MOVL $SYS_kqueue, AX
529 SYSCALL
530 JCC 2(PC)
531 NEGQ AX
532 MOVL AX, ret+0(FP)
533 RET
534
535 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
536 TEXT runtime·kevent(SB),NOSPLIT,$0
537 MOVL kq+0(FP), DI
538 MOVQ ch+8(FP), SI
539 MOVL nch+16(FP), DX
540 MOVQ ev+24(FP), R10
541 MOVL nev+32(FP), R8
542 MOVQ ts+40(FP), R9
543 MOVL $SYS_kevent, AX
544 SYSCALL
545 JCC 2(PC)
546 NEGQ AX
547 MOVL AX, ret+48(FP)
548 RET
549
550 // func fcntl(fd, cmd, arg int32) (int32, int32)
551 TEXT runtime·fcntl(SB),NOSPLIT,$0
552 MOVL fd+0(FP), DI // fd
553 MOVL cmd+4(FP), SI // cmd
554 MOVL arg+8(FP), DX // arg
555 MOVL $SYS_fcntl, AX
556 SYSCALL
557 JCC noerr
558 MOVL $-1, ret+16(FP)
559 MOVL AX, errno+20(FP)
560 RET
561 noerr:
562 MOVL AX, ret+16(FP)
563 MOVL $0, errno+20(FP)
564 RET
565
566 // func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
567 TEXT runtime·cpuset_getaffinity(SB), NOSPLIT, $0-44
568 MOVQ level+0(FP), DI
569 MOVQ which+8(FP), SI
570 MOVQ id+16(FP), DX
571 MOVQ size+24(FP), R10
572 MOVQ mask+32(FP), R8
573 MOVL $SYS_cpuset_getaffinity, AX
574 SYSCALL
575 JCC 2(PC)
576 NEGQ AX
577 MOVL AX, ret+40(FP)
578 RET
579
580 // func issetugid() int32
581 TEXT runtime·issetugid(SB),NOSPLIT,$0
582 MOVQ $0, DI
583 MOVQ $0, SI
584 MOVQ $0, DX
585 MOVL $SYS_issetugid, AX
586 SYSCALL
587 MOVL AX, ret+0(FP)
588 RET
589
View as plain text