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
// 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, OpenBSD
// /usr/src/sys/kern/syscalls.master for syscall numbers.
//
 
#include "go_asm.h"
#include "go_tls.h"
#include "textflag.h"
 
#define CLOCK_MONOTONIC    $3
 
// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
TEXT runtime·tfork(SB),NOSPLIT,$32
 
   // Copy mp, gp and fn off parent stack for use by child.
   MOVQ    mm+16(FP), R8
   MOVQ    gg+24(FP), R9
   MOVQ    fn+32(FP), R12
 
   MOVQ    param+0(FP), DI
   MOVQ    psize+8(FP), SI
   MOVL    $8, AX            // sys___tfork
   SYSCALL
 
   // Return if tfork syscall failed.
   JCC    4(PC)
   NEGQ    AX
   MOVL    AX, ret+40(FP)
   RET
 
   // In parent, return.
   CMPL    AX, $0
   JEQ    3(PC)
   MOVL    AX, ret+40(FP)
   RET
 
   // Set FS to point at m->tls.
   LEAQ    m_tls(R8), DI
   CALL    runtime·settls(SB)
 
   // In child, set up new stack.
   get_tls(CX)
   MOVQ    R8, g_m(R9)
   MOVQ    R9, g(CX)
   CALL    runtime·stackcheck(SB)
 
   // Call fn
   CALL    R12
 
   // It shouldn't return. If it does, exit
   MOVQ    $0, DI            // arg 1 - notdead
   MOVL    $302, AX        // sys___threxit
   SYSCALL
   JMP    -3(PC)            // keep exiting
 
TEXT runtime·osyield(SB),NOSPLIT,$0
   MOVL    $298, AX        // sys_sched_yield
   SYSCALL
   RET
 
TEXT runtime·thrsleep(SB),NOSPLIT,$0
   MOVQ    ident+0(FP), DI        // arg 1 - ident
   MOVL    clock_id+8(FP), SI        // arg 2 - clock_id
   MOVQ    tsp+16(FP), DX        // arg 3 - tp
   MOVQ    lock+24(FP), R10        // arg 4 - lock
   MOVQ    abort+32(FP), R8        // arg 5 - abort
   MOVL    $94, AX            // sys___thrsleep
   SYSCALL
   MOVL    AX, ret+40(FP)
   RET
 
TEXT runtime·thrwakeup(SB),NOSPLIT,$0
   MOVQ    ident+0(FP), DI        // arg 1 - ident
   MOVL    n+8(FP), SI        // arg 2 - n
   MOVL    $301, AX        // sys___thrwakeup
   SYSCALL
   MOVL    AX, ret+16(FP)
   RET
 
// 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            // sys_exit
   SYSCALL
   MOVL    $0xf1, 0xf1        // crash
   RET
 
// func exitThread(wait *uint32)
TEXT runtime·exitThread(SB),NOSPLIT,$0-8
   MOVQ    wait+0(FP), DI        // arg 1 - notdead
   MOVL    $302, AX        // sys___threxit
   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 - nbyte
   MOVL    $4, AX            // sys_write
   SYSCALL
   JCC    2(PC)
   MOVL    $-1, AX
   MOVL    AX, ret+24(FP)
   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    $91, AX            // sys_nanosleep
   SYSCALL
   RET
 
TEXT runtime·raise(SB),NOSPLIT,$16
   MOVL    $299, AX        // sys_getthrid
   SYSCALL
   MOVQ    AX, DI            // arg 1 - tid
   MOVL    sig+0(FP), SI        // arg 2 - signum
   MOVQ    $0, DX            // arg 3 - tcb
   MOVL    $119, AX        // sys_thrkill
   SYSCALL
   RET
 
TEXT runtime·raiseproc(SB),NOSPLIT,$16
   MOVL    $20, AX            // sys_getpid
   SYSCALL
   MOVQ    AX, DI            // arg 1 - pid
   MOVL    sig+0(FP), SI        // arg 2 - signum
   MOVL    $122, AX        // sys_kill
   SYSCALL
   RET
 
TEXT runtime·setitimer(SB),NOSPLIT,$-8
   MOVL    mode+0(FP), DI        // arg 1 - which
   MOVQ    new+8(FP), SI        // arg 2 - itv
   MOVQ    old+16(FP), DX        // arg 3 - oitv
   MOVL    $69, AX            // sys_setitimer
   SYSCALL
   RET
 
// func walltime() (sec int64, nsec int32)
TEXT runtime·walltime(SB), NOSPLIT, $32
   MOVQ    $0, DI            // arg 1 - clock_id
   LEAQ    8(SP), SI        // arg 2 - tp
   MOVL    $87, AX            // sys_clock_gettime
   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·nanotime(SB),NOSPLIT,$24
   MOVQ    CLOCK_MONOTONIC, DI    // arg 1 - clock_id
   LEAQ    8(SP), SI        // arg 2 - tp
   MOVL    $87, AX            // sys_clock_gettime
   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·sigaction(SB),NOSPLIT,$-8
   MOVL    sig+0(FP), DI        // arg 1 - signum
   MOVQ    new+8(FP), SI        // arg 2 - nsa
   MOVQ    old+16(FP), DX        // arg 3 - osa
   MOVL    $46, AX
   SYSCALL
   JCC    2(PC)
   MOVL    $0xf1, 0xf1        // crash
   RET
 
TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$0
   MOVL    how+0(FP), DI        // arg 1 - how
   MOVL    new+4(FP), SI        // arg 2 - set
   MOVL    $48, AX            // sys_sigprocmask
   SYSCALL
   JCC    2(PC)
   MOVL    $0xf1, 0xf1        // crash
   MOVL    AX, ret+8(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
 
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 - fd
   MOVL    off+28(FP), R9
   SUBQ    $16, SP
   MOVQ    R9, 8(SP)        // arg 7 - offset (passed on stack)
   MOVQ    $0, R9            // arg 6 - pad
   MOVL    $197, AX
   SYSCALL
   JCC    ok
   ADDQ    $16, SP
   MOVQ    $0, p+32(FP)
   MOVQ    AX, err+40(FP)
   RET
ok:
   ADDQ    $16, SP
   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            // sys_munmap
   SYSCALL
   JCC    2(PC)
   MOVL    $0xf1, 0xf1        // crash
   RET
 
TEXT runtime·madvise(SB),NOSPLIT,$0
   MOVQ    addr+0(FP), DI        // arg 1 - addr
   MOVQ    n+8(FP), SI        // arg 2 - len
   MOVL    flags+16(FP), DX    // arg 3 - behav
   MOVQ    $75, AX            // sys_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        // arg 1 - nss
   MOVQ    old+8(FP), SI        // arg 2 - oss
   MOVQ    $288, AX        // sys_sigaltstack
   SYSCALL
   JCC    2(PC)
   MOVL    $0xf1, 0xf1        // crash
   RET
 
// set tls base to DI
TEXT runtime·settls(SB),NOSPLIT,$0
   // adjust for ELF: wants to use -8(FS) for g
   ADDQ    $8, DI
   MOVQ    $329, AX        // sys___settcb
   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
 
// int32 runtime·kqueue(void);
TEXT runtime·kqueue(SB),NOSPLIT,$0
   MOVQ    $0, DI
   MOVQ    $0, SI
   MOVQ    $0, DX
   MOVL    $269, 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    $72, 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