liyujie
2025-08-28 d9927380ed7c8366f762049be9f3fee225860833
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// System calls and other sys.stuff for AMD64, FreeBSD
// /usr/src/sys/kern/syscalls.master for syscall numbers.
//
 
#include "go_asm.h"
#include "go_tls.h"
#include "textflag.h"
 
TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
   MOVQ addr+0(FP), DI
   MOVL mode+8(FP), SI
   MOVL val+12(FP), DX
   MOVQ uaddr1+16(FP), R10
   MOVQ ut+24(FP), R8
   MOVL $454, AX
   SYSCALL
   MOVL    AX, ret+32(FP)
   RET
 
TEXT runtime·thr_new(SB),NOSPLIT,$0
   MOVQ param+0(FP), DI
   MOVL size+8(FP), SI
   MOVL $455, AX
   SYSCALL
   MOVL    AX, ret+16(FP)
   RET
 
TEXT runtime·thr_start(SB),NOSPLIT,$0
   MOVQ    DI, R13 // m
 
   // set up FS to point at m->tls
   LEAQ    m_tls(R13), DI
   CALL    runtime·settls(SB)    // smashes DI
 
   // set up m, g
   get_tls(CX)
   MOVQ    m_g0(R13), DI
   MOVQ    R13, g_m(DI)
   MOVQ    DI, g(CX)
 
   CALL    runtime·stackcheck(SB)
   CALL    runtime·mstart(SB)
 
   MOVQ 0, AX            // crash (not reached)
 
// Exit the entire program (like C exit)
TEXT runtime·exit(SB),NOSPLIT,$-8
   MOVL    code+0(FP), DI        // arg 1 exit status
   MOVL    $1, AX
   SYSCALL
   MOVL    $0xf1, 0xf1  // crash
   RET
 
// func exitThread(wait *uint32)
TEXT runtime·exitThread(SB),NOSPLIT,$0-8
   MOVQ    wait+0(FP), AX
   // We're done using the stack.
   MOVL    $0, (AX)
   MOVL    $0, DI        // arg 1 long *state
   MOVL    $431, AX    // thr_exit
   SYSCALL
   MOVL    $0xf1, 0xf1  // crash
   JMP    0(PC)
 
TEXT runtime·open(SB),NOSPLIT,$-8
   MOVQ    name+0(FP), DI        // arg 1 pathname
   MOVL    mode+8(FP), SI        // arg 2 flags
   MOVL    perm+12(FP), DX        // arg 3 mode
   MOVL    $5, AX
   SYSCALL
   JCC    2(PC)
   MOVL    $-1, AX
   MOVL    AX, ret+16(FP)
   RET
 
TEXT runtime·closefd(SB),NOSPLIT,$-8
   MOVL    fd+0(FP), DI        // arg 1 fd
   MOVL    $6, AX
   SYSCALL
   JCC    2(PC)
   MOVL    $-1, AX
   MOVL    AX, ret+8(FP)
   RET
 
TEXT runtime·read(SB),NOSPLIT,$-8
   MOVL    fd+0(FP), DI        // arg 1 fd
   MOVQ    p+8(FP), SI        // arg 2 buf
   MOVL    n+16(FP), DX        // arg 3 count
   MOVL    $3, AX
   SYSCALL
   JCC    2(PC)
   MOVL    $-1, AX
   MOVL    AX, ret+24(FP)
   RET
 
TEXT runtime·write(SB),NOSPLIT,$-8
   MOVQ    fd+0(FP), DI        // arg 1 fd
   MOVQ    p+8(FP), SI        // arg 2 buf
   MOVL    n+16(FP), DX        // arg 3 count
   MOVL    $4, AX
   SYSCALL
   JCC    2(PC)
   MOVL    $-1, AX
   MOVL    AX, ret+24(FP)
   RET
 
TEXT runtime·raise(SB),NOSPLIT,$16
   // thr_self(&8(SP))
   LEAQ    8(SP), DI    // arg 1 &8(SP)
   MOVL    $432, AX
   SYSCALL
   // thr_kill(self, SIGPIPE)
   MOVQ    8(SP), DI    // arg 1 id
   MOVL    sig+0(FP), SI    // arg 2
   MOVL    $433, AX
   SYSCALL
   RET
 
TEXT runtime·raiseproc(SB),NOSPLIT,$0
   // getpid
   MOVL    $20, AX
   SYSCALL
   // kill(self, sig)
   MOVQ    AX, DI        // arg 1 pid
   MOVL    sig+0(FP), SI    // arg 2 sig
   MOVL    $37, AX
   SYSCALL
   RET
 
TEXT runtime·setitimer(SB), NOSPLIT, $-8
   MOVL    mode+0(FP), DI
   MOVQ    new+8(FP), SI
   MOVQ    old+16(FP), DX
   MOVL    $83, AX
   SYSCALL
   RET
 
// func fallback_walltime() (sec int64, nsec int32)
TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12
   MOVL    $232, AX    // clock_gettime
   MOVQ    $0, DI        // CLOCK_REALTIME
   LEAQ    8(SP), SI
   SYSCALL
   MOVQ    8(SP), AX    // sec
   MOVQ    16(SP), DX    // nsec
 
   // sec is in AX, nsec in DX
   MOVQ    AX, sec+0(FP)
   MOVL    DX, nsec+8(FP)
   RET
 
TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32-8
   MOVL    $232, AX
   MOVQ    $4, DI        // CLOCK_MONOTONIC
   LEAQ    8(SP), SI
   SYSCALL
   MOVQ    8(SP), AX    // sec
   MOVQ    16(SP), DX    // nsec
 
   // sec is in AX, nsec in DX
   // return nsec in AX
   IMULQ    $1000000000, AX
   ADDQ    DX, AX
   MOVQ    AX, ret+0(FP)
   RET
 
TEXT runtime·asmSigaction(SB),NOSPLIT,$0
   MOVQ    sig+0(FP), DI        // arg 1 sig
   MOVQ    new+8(FP), SI        // arg 2 act
   MOVQ    old+16(FP), DX        // arg 3 oact
   MOVL    $416, AX
   SYSCALL
   JCC    2(PC)
   MOVL    $-1, AX
   MOVL    AX, ret+24(FP)
   RET
 
TEXT runtime·callCgoSigaction(SB),NOSPLIT,$16
   MOVQ    sig+0(FP), DI        // arg 1 sig
   MOVQ    new+8(FP), SI        // arg 2 act
   MOVQ    old+16(FP), DX        // arg 3 oact
   MOVQ    _cgo_sigaction(SB), AX
   MOVQ    SP, BX            // callee-saved
   ANDQ    $~15, SP        // alignment as per amd64 psABI
   CALL    AX
   MOVQ    BX, SP
   MOVL    AX, ret+24(FP)
   RET
 
TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   MOVQ    fn+0(FP),    AX
   MOVL    sig+8(FP),   DI
   MOVQ    info+16(FP), SI
   MOVQ    ctx+24(FP),  DX
   PUSHQ    BP
   MOVQ    SP, BP
   ANDQ    $~15, SP     // alignment for x86_64 ABI
   CALL    AX
   MOVQ    BP, SP
   POPQ    BP
   RET
 
TEXT runtime·sigtramp(SB),NOSPLIT,$72
   // Save callee-saved C registers, since the caller may be a C signal handler.
   MOVQ    BX, bx-8(SP)
   MOVQ    BP, bp-16(SP)  // save in case GOEXPERIMENT=noframepointer is set
   MOVQ    R12, r12-24(SP)
   MOVQ    R13, r13-32(SP)
   MOVQ    R14, r14-40(SP)
   MOVQ    R15, r15-48(SP)
   // We don't save mxcsr or the x87 control word because sigtrampgo doesn't
   // modify them.
 
   MOVQ    DX, ctx-56(SP)
   MOVQ    SI, info-64(SP)
   MOVQ    DI, signum-72(SP)
   CALL    runtime·sigtrampgo(SB)
 
   MOVQ    r15-48(SP), R15
   MOVQ    r14-40(SP), R14
   MOVQ    r13-32(SP), R13
   MOVQ    r12-24(SP), R12
   MOVQ    bp-16(SP),  BP
   MOVQ    bx-8(SP),   BX
   RET
 
// Used instead of sigtramp in programs that use cgo.
// Arguments from kernel are in DI, SI, DX.
TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
   // If no traceback function, do usual sigtramp.
   MOVQ    runtime·cgoTraceback(SB), AX
   TESTQ    AX, AX
   JZ    sigtramp
 
   // If no traceback support function, which means that
   // runtime/cgo was not linked in, do usual sigtramp.
   MOVQ    _cgo_callers(SB), AX
   TESTQ    AX, AX
   JZ    sigtramp
 
   // Figure out if we are currently in a cgo call.
   // If not, just do usual sigtramp.
   get_tls(CX)
   MOVQ    g(CX),AX
   TESTQ    AX, AX
   JZ    sigtrampnog     // g == nil
   MOVQ    g_m(AX), AX
   TESTQ    AX, AX
   JZ    sigtramp        // g.m == nil
   MOVL    m_ncgo(AX), CX
   TESTL    CX, CX
   JZ    sigtramp        // g.m.ncgo == 0
   MOVQ    m_curg(AX), CX
   TESTQ    CX, CX
   JZ    sigtramp        // g.m.curg == nil
   MOVQ    g_syscallsp(CX), CX
   TESTQ    CX, CX
   JZ    sigtramp        // g.m.curg.syscallsp == 0
   MOVQ    m_cgoCallers(AX), R8
   TESTQ    R8, R8
   JZ    sigtramp        // g.m.cgoCallers == nil
   MOVL    m_cgoCallersUse(AX), CX
   TESTL    CX, CX
   JNZ    sigtramp    // g.m.cgoCallersUse != 0
 
   // Jump to a function in runtime/cgo.
   // That function, written in C, will call the user's traceback
   // function with proper unwind info, and will then call back here.
   // The first three arguments, and the fifth, are already in registers.
   // Set the two remaining arguments now.
   MOVQ    runtime·cgoTraceback(SB), CX
   MOVQ    $runtime·sigtramp(SB), R9
   MOVQ    _cgo_callers(SB), AX
   JMP    AX
 
sigtramp:
   JMP    runtime·sigtramp(SB)
 
sigtrampnog:
   // Signal arrived on a non-Go thread. If this is SIGPROF, get a
   // stack trace.
   CMPL    DI, $27 // 27 == SIGPROF
   JNZ    sigtramp
 
   // Lock sigprofCallersUse.
   MOVL    $0, AX
   MOVL    $1, CX
   MOVQ    $runtime·sigprofCallersUse(SB), R11
   LOCK
   CMPXCHGL    CX, 0(R11)
   JNZ    sigtramp  // Skip stack trace if already locked.
 
   // Jump to the traceback function in runtime/cgo.
   // It will call back to sigprofNonGo, which will ignore the
   // arguments passed in registers.
   // First three arguments to traceback function are in registers already.
   MOVQ    runtime·cgoTraceback(SB), CX
   MOVQ    $runtime·sigprofCallers(SB), R8
   MOVQ    $runtime·sigprofNonGo(SB), R9
   MOVQ    _cgo_callers(SB), AX
   JMP    AX
 
TEXT runtime·mmap(SB),NOSPLIT,$0
   MOVQ    addr+0(FP), DI        // arg 1 addr
   MOVQ    n+8(FP), SI        // arg 2 len
   MOVL    prot+16(FP), DX        // arg 3 prot
   MOVL    flags+20(FP), R10        // arg 4 flags
   MOVL    fd+24(FP), R8        // arg 5 fid
   MOVL    off+28(FP), R9        // arg 6 offset
   MOVL    $477, AX
   SYSCALL
   JCC    ok
   MOVQ    $0, p+32(FP)
   MOVQ    AX, err+40(FP)
   RET
ok:
   MOVQ    AX, p+32(FP)
   MOVQ    $0, err+40(FP)
   RET
 
TEXT runtime·munmap(SB),NOSPLIT,$0
   MOVQ    addr+0(FP), DI        // arg 1 addr
   MOVQ    n+8(FP), SI        // arg 2 len
   MOVL    $73, AX
   SYSCALL
   JCC    2(PC)
   MOVL    $0xf1, 0xf1  // crash
   RET
 
TEXT runtime·madvise(SB),NOSPLIT,$0
   MOVQ    addr+0(FP), DI
   MOVQ    n+8(FP), SI
   MOVL    flags+16(FP), DX
   MOVQ    $75, AX    // madvise
   SYSCALL
   JCC    2(PC)
   MOVL    $-1, AX
   MOVL    AX, ret+24(FP)
   RET
 
TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
   MOVQ    new+0(FP), DI
   MOVQ    old+8(FP), SI
   MOVQ    $53, AX
   SYSCALL
   JCC    2(PC)
   MOVL    $0xf1, 0xf1  // crash
   RET
 
TEXT runtime·usleep(SB),NOSPLIT,$16
   MOVL    $0, DX
   MOVL    usec+0(FP), AX
   MOVL    $1000000, CX
   DIVL    CX
   MOVQ    AX, 0(SP)        // tv_sec
   MOVL    $1000, AX
   MULL    DX
   MOVQ    AX, 8(SP)        // tv_nsec
 
   MOVQ    SP, DI            // arg 1 - rqtp
   MOVQ    $0, SI            // arg 2 - rmtp
   MOVL    $240, AX        // sys_nanosleep
   SYSCALL
   RET
 
// set tls base to DI
TEXT runtime·settls(SB),NOSPLIT,$8
   ADDQ    $8, DI    // adjust for ELF: wants to use -8(FS) for g and m
   MOVQ    DI, 0(SP)
   MOVQ    SP, SI
   MOVQ    $129, DI    // AMD64_SET_FSBASE
   MOVQ    $165, AX    // sysarch
   SYSCALL
   JCC    2(PC)
   MOVL    $0xf1, 0xf1  // crash
   RET
 
TEXT runtime·sysctl(SB),NOSPLIT,$0
   MOVQ    mib+0(FP), DI        // arg 1 - name
   MOVL    miblen+8(FP), SI        // arg 2 - namelen
   MOVQ    out+16(FP), DX        // arg 3 - oldp
   MOVQ    size+24(FP), R10        // arg 4 - oldlenp
   MOVQ    dst+32(FP), R8        // arg 5 - newp
   MOVQ    ndst+40(FP), R9        // arg 6 - newlen
   MOVQ    $202, AX        // sys___sysctl
   SYSCALL
   JCC 4(PC)
   NEGQ    AX
   MOVL    AX, ret+48(FP)
   RET
   MOVL    $0, AX
   MOVL    AX, ret+48(FP)
   RET
 
TEXT runtime·osyield(SB),NOSPLIT,$-4
   MOVL    $331, AX        // sys_sched_yield
   SYSCALL
   RET
 
TEXT runtime·sigprocmask(SB),NOSPLIT,$0
   MOVL    how+0(FP), DI        // arg 1 - how
   MOVQ    new+8(FP), SI        // arg 2 - set
   MOVQ    old+16(FP), DX        // arg 3 - oset
   MOVL    $340, AX        // sys_sigprocmask
   SYSCALL
   JAE    2(PC)
   MOVL    $0xf1, 0xf1  // crash
   RET
 
// int32 runtime·kqueue(void);
TEXT runtime·kqueue(SB),NOSPLIT,$0
   MOVQ    $0, DI
   MOVQ    $0, SI
   MOVQ    $0, DX
   MOVL    $362, AX
   SYSCALL
   JCC    2(PC)
   NEGQ    AX
   MOVL    AX, ret+0(FP)
   RET
 
// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
TEXT runtime·kevent(SB),NOSPLIT,$0
   MOVL    kq+0(FP), DI
   MOVQ    ch+8(FP), SI
   MOVL    nch+16(FP), DX
   MOVQ    ev+24(FP), R10
   MOVL    nev+32(FP), R8
   MOVQ    ts+40(FP), R9
   MOVL    $363, AX
   SYSCALL
   JCC    2(PC)
   NEGQ    AX
   MOVL    AX, ret+48(FP)
   RET
 
// void runtime·closeonexec(int32 fd);
TEXT runtime·closeonexec(SB),NOSPLIT,$0
   MOVL    fd+0(FP), DI    // fd
   MOVQ    $2, SI        // F_SETFD
   MOVQ    $1, DX        // FD_CLOEXEC
   MOVL    $92, AX        // fcntl
   SYSCALL
   RET
 
// func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32
TEXT runtime·cpuset_getaffinity(SB), NOSPLIT, $0-44
   MOVQ    level+0(FP), DI
   MOVQ    which+8(FP), SI
   MOVQ    id+16(FP), DX
   MOVQ    size+24(FP), R10
   MOVQ    mask+32(FP), R8
   MOVL    $487, AX
   SYSCALL
   JCC    2(PC)
   NEGQ    AX
   MOVL    AX, ret+40(FP)
   RET