Home | History | Annotate | Download | only in 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 //
      6 // System calls and other sys.stuff for AMD64, Linux
      7 //
      8 
      9 #include "go_asm.h"
     10 #include "go_tls.h"
     11 #include "textflag.h"
     12 
     13 TEXT runtimeexit(SB),NOSPLIT,$0-4
     14 	MOVL	code+0(FP), DI
     15 	MOVL	$231, AX	// exitgroup - force all os threads to exit
     16 	SYSCALL
     17 	RET
     18 
     19 TEXT runtimeexit1(SB),NOSPLIT,$0-4
     20 	MOVL	code+0(FP), DI
     21 	MOVL	$60, AX	// exit - exit the current os thread
     22 	SYSCALL
     23 	RET
     24 
     25 TEXT runtimeopen(SB),NOSPLIT,$0-20
     26 	MOVQ	name+0(FP), DI
     27 	MOVL	mode+8(FP), SI
     28 	MOVL	perm+12(FP), DX
     29 	MOVL	$2, AX			// syscall entry
     30 	SYSCALL
     31 	CMPQ	AX, $0xfffffffffffff001
     32 	JLS	2(PC)
     33 	MOVL	$-1, AX
     34 	MOVL	AX, ret+16(FP)
     35 	RET
     36 
     37 TEXT runtimeclosefd(SB),NOSPLIT,$0-12
     38 	MOVL	fd+0(FP), DI
     39 	MOVL	$3, AX			// syscall entry
     40 	SYSCALL
     41 	CMPQ	AX, $0xfffffffffffff001
     42 	JLS	2(PC)
     43 	MOVL	$-1, AX
     44 	MOVL	AX, ret+8(FP)
     45 	RET
     46 
     47 TEXT runtimewrite(SB),NOSPLIT,$0-28
     48 	MOVQ	fd+0(FP), DI
     49 	MOVQ	p+8(FP), SI
     50 	MOVL	n+16(FP), DX
     51 	MOVL	$1, AX			// syscall entry
     52 	SYSCALL
     53 	CMPQ	AX, $0xfffffffffffff001
     54 	JLS	2(PC)
     55 	MOVL	$-1, AX
     56 	MOVL	AX, ret+24(FP)
     57 	RET
     58 
     59 TEXT runtimeread(SB),NOSPLIT,$0-28
     60 	MOVL	fd+0(FP), DI
     61 	MOVQ	p+8(FP), SI
     62 	MOVL	n+16(FP), DX
     63 	MOVL	$0, AX			// syscall entry
     64 	SYSCALL
     65 	CMPQ	AX, $0xfffffffffffff001
     66 	JLS	2(PC)
     67 	MOVL	$-1, AX
     68 	MOVL	AX, ret+24(FP)
     69 	RET
     70 
     71 TEXT runtimegetrlimit(SB),NOSPLIT,$0-20
     72 	MOVL	kind+0(FP), DI
     73 	MOVQ	limit+8(FP), SI
     74 	MOVL	$97, AX			// syscall entry
     75 	SYSCALL
     76 	MOVL	AX, ret+16(FP)
     77 	RET
     78 
     79 TEXT runtimeusleep(SB),NOSPLIT,$16
     80 	MOVL	$0, DX
     81 	MOVL	usec+0(FP), AX
     82 	MOVL	$1000000, CX
     83 	DIVL	CX
     84 	MOVQ	AX, 0(SP)
     85 	MOVQ	DX, 8(SP)
     86 
     87 	// select(0, 0, 0, 0, &tv)
     88 	MOVL	$0, DI
     89 	MOVL	$0, SI
     90 	MOVL	$0, DX
     91 	MOVL	$0, R10
     92 	MOVQ	SP, R8
     93 	MOVL	$23, AX
     94 	SYSCALL
     95 	RET
     96 
     97 TEXT runtimegettid(SB),NOSPLIT,$0-4
     98 	MOVL	$186, AX	// syscall - gettid
     99 	SYSCALL
    100 	MOVL	AX, ret+0(FP)
    101 	RET
    102 
    103 TEXT runtimeraise(SB),NOSPLIT,$0
    104 	MOVL	$186, AX	// syscall - gettid
    105 	SYSCALL
    106 	MOVL	AX, DI	// arg 1 tid
    107 	MOVL	sig+0(FP), SI	// arg 2
    108 	MOVL	$200, AX	// syscall - tkill
    109 	SYSCALL
    110 	RET
    111 
    112 TEXT runtimeraiseproc(SB),NOSPLIT,$0
    113 	MOVL	$39, AX	// syscall - getpid
    114 	SYSCALL
    115 	MOVL	AX, DI	// arg 1 pid
    116 	MOVL	sig+0(FP), SI	// arg 2
    117 	MOVL	$62, AX	// syscall - kill
    118 	SYSCALL
    119 	RET
    120 
    121 TEXT runtimesetitimer(SB),NOSPLIT,$0-24
    122 	MOVL	mode+0(FP), DI
    123 	MOVQ	new+8(FP), SI
    124 	MOVQ	old+16(FP), DX
    125 	MOVL	$38, AX			// syscall entry
    126 	SYSCALL
    127 	RET
    128 
    129 TEXT runtimemincore(SB),NOSPLIT,$0-28
    130 	MOVQ	addr+0(FP), DI
    131 	MOVQ	n+8(FP), SI
    132 	MOVQ	dst+16(FP), DX
    133 	MOVL	$27, AX			// syscall entry
    134 	SYSCALL
    135 	MOVL	AX, ret+24(FP)
    136 	RET
    137 
    138 // func now() (sec int64, nsec int32)
    139 TEXT timenow(SB),NOSPLIT,$16
    140 	// Be careful. We're calling a function with gcc calling convention here.
    141 	// We're guaranteed 128 bytes on entry, and we've taken 16, and the
    142 	// call uses another 8.
    143 	// That leaves 104 for the gettime code to use. Hope that's enough!
    144 	MOVQ	runtime__vdso_clock_gettime_sym(SB), AX
    145 	CMPQ	AX, $0
    146 	JEQ	fallback
    147 	MOVL	$0, DI // CLOCK_REALTIME
    148 	LEAQ	0(SP), SI
    149 	CALL	AX
    150 	MOVQ	0(SP), AX	// sec
    151 	MOVQ	8(SP), DX	// nsec
    152 	MOVQ	AX, sec+0(FP)
    153 	MOVL	DX, nsec+8(FP)
    154 	RET
    155 fallback:
    156 	LEAQ	0(SP), DI
    157 	MOVQ	$0, SI
    158 	MOVQ	runtime__vdso_gettimeofday_sym(SB), AX
    159 	CALL	AX
    160 	MOVQ	0(SP), AX	// sec
    161 	MOVL	8(SP), DX	// usec
    162 	IMULQ	$1000, DX
    163 	MOVQ	AX, sec+0(FP)
    164 	MOVL	DX, nsec+8(FP)
    165 	RET
    166 
    167 TEXT runtimenanotime(SB),NOSPLIT,$16
    168 	// Duplicate time.now here to avoid using up precious stack space.
    169 	// See comment above in time.now.
    170 	MOVQ	runtime__vdso_clock_gettime_sym(SB), AX
    171 	CMPQ	AX, $0
    172 	JEQ	fallback
    173 	MOVL	$1, DI // CLOCK_MONOTONIC
    174 	LEAQ	0(SP), SI
    175 	CALL	AX
    176 	MOVQ	0(SP), AX	// sec
    177 	MOVQ	8(SP), DX	// nsec
    178 	// sec is in AX, nsec in DX
    179 	// return nsec in AX
    180 	IMULQ	$1000000000, AX
    181 	ADDQ	DX, AX
    182 	MOVQ	AX, ret+0(FP)
    183 	RET
    184 fallback:
    185 	LEAQ	0(SP), DI
    186 	MOVQ	$0, SI
    187 	MOVQ	runtime__vdso_gettimeofday_sym(SB), AX
    188 	CALL	AX
    189 	MOVQ	0(SP), AX	// sec
    190 	MOVL	8(SP), DX	// usec
    191 	IMULQ	$1000, DX
    192 	// sec is in AX, nsec in DX
    193 	// return nsec in AX
    194 	IMULQ	$1000000000, AX
    195 	ADDQ	DX, AX
    196 	MOVQ	AX, ret+0(FP)
    197 	RET
    198 
    199 TEXT runtimertsigprocmask(SB),NOSPLIT,$0-28
    200 	MOVL	sig+0(FP), DI
    201 	MOVQ	new+8(FP), SI
    202 	MOVQ	old+16(FP), DX
    203 	MOVL	size+24(FP), R10
    204 	MOVL	$14, AX			// syscall entry
    205 	SYSCALL
    206 	CMPQ	AX, $0xfffffffffffff001
    207 	JLS	2(PC)
    208 	MOVL	$0xf1, 0xf1  // crash
    209 	RET
    210 
    211 TEXT runtimert_sigaction(SB),NOSPLIT,$0-36
    212 	MOVQ	sig+0(FP), DI
    213 	MOVQ	new+8(FP), SI
    214 	MOVQ	old+16(FP), DX
    215 	MOVQ	size+24(FP), R10
    216 	MOVL	$13, AX			// syscall entry
    217 	SYSCALL
    218 	MOVL	AX, ret+32(FP)
    219 	RET
    220 
    221 TEXT runtimesigfwd(SB),NOSPLIT,$0-32
    222 	MOVL	sig+8(FP), DI
    223 	MOVQ	info+16(FP), SI
    224 	MOVQ	ctx+24(FP), DX
    225 	MOVQ	fn+0(FP), AX
    226 	CALL	AX
    227 	RET
    228 
    229 TEXT runtimesigtramp(SB),NOSPLIT,$24
    230 	MOVQ	DI, 0(SP)   // signum
    231 	MOVQ	SI, 8(SP)   // info
    232 	MOVQ	DX, 16(SP)  // ctx
    233 	MOVQ	$runtimesigtrampgo(SB), AX
    234 	CALL AX
    235 	RET
    236 
    237 TEXT runtimesigreturn(SB),NOSPLIT,$0
    238 	MOVL	$15, AX	// rt_sigreturn
    239 	SYSCALL
    240 	INT $3	// not reached
    241 
    242 TEXT runtimemmap(SB),NOSPLIT,$0
    243 	MOVQ	addr+0(FP), DI
    244 	MOVQ	n+8(FP), SI
    245 	MOVL	prot+16(FP), DX
    246 	MOVL	flags+20(FP), R10
    247 	MOVL	fd+24(FP), R8
    248 	MOVL	off+28(FP), R9
    249 
    250 	MOVL	$9, AX			// mmap
    251 	SYSCALL
    252 	CMPQ	AX, $0xfffffffffffff001
    253 	JLS	3(PC)
    254 	NOTQ	AX
    255 	INCQ	AX
    256 	MOVQ	AX, ret+32(FP)
    257 	RET
    258 
    259 TEXT runtimemunmap(SB),NOSPLIT,$0
    260 	MOVQ	addr+0(FP), DI
    261 	MOVQ	n+8(FP), SI
    262 	MOVQ	$11, AX	// munmap
    263 	SYSCALL
    264 	CMPQ	AX, $0xfffffffffffff001
    265 	JLS	2(PC)
    266 	MOVL	$0xf1, 0xf1  // crash
    267 	RET
    268 
    269 TEXT runtimemadvise(SB),NOSPLIT,$0
    270 	MOVQ	addr+0(FP), DI
    271 	MOVQ	n+8(FP), SI
    272 	MOVL	flags+16(FP), DX
    273 	MOVQ	$28, AX	// madvise
    274 	SYSCALL
    275 	// ignore failure - maybe pages are locked
    276 	RET
    277 
    278 // int64 futex(int32 *uaddr, int32 op, int32 val,
    279 //	struct timespec *timeout, int32 *uaddr2, int32 val2);
    280 TEXT runtimefutex(SB),NOSPLIT,$0
    281 	MOVQ	addr+0(FP), DI
    282 	MOVL	op+8(FP), SI
    283 	MOVL	val+12(FP), DX
    284 	MOVQ	ts+16(FP), R10
    285 	MOVQ	addr2+24(FP), R8
    286 	MOVL	val3+32(FP), R9
    287 	MOVL	$202, AX
    288 	SYSCALL
    289 	MOVL	AX, ret+40(FP)
    290 	RET
    291 
    292 // int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
    293 TEXT runtimeclone(SB),NOSPLIT,$0
    294 	MOVL	flags+0(FP), DI
    295 	MOVQ	stack+8(FP), SI
    296 	MOVQ	$0, DX
    297 	MOVQ	$0, R10
    298 
    299 	// Copy mp, gp, fn off parent stack for use by child.
    300 	// Careful: Linux system call clobbers CX and R11.
    301 	MOVQ	mp+16(FP), R8
    302 	MOVQ	gp+24(FP), R9
    303 	MOVQ	fn+32(FP), R12
    304 
    305 	MOVL	$56, AX
    306 	SYSCALL
    307 
    308 	// In parent, return.
    309 	CMPQ	AX, $0
    310 	JEQ	3(PC)
    311 	MOVL	AX, ret+40(FP)
    312 	RET
    313 
    314 	// In child, on new stack.
    315 	MOVQ	SI, SP
    316 
    317 	// If g or m are nil, skip Go-related setup.
    318 	CMPQ	R8, $0    // m
    319 	JEQ	nog
    320 	CMPQ	R9, $0    // g
    321 	JEQ	nog
    322 
    323 	// Initialize m->procid to Linux tid
    324 	MOVL	$186, AX	// gettid
    325 	SYSCALL
    326 	MOVQ	AX, m_procid(R8)
    327 
    328 	// Set FS to point at m->tls.
    329 	LEAQ	m_tls(R8), DI
    330 	CALL	runtimesettls(SB)
    331 
    332 	// In child, set up new stack
    333 	get_tls(CX)
    334 	MOVQ	R8, g_m(R9)
    335 	MOVQ	R9, g(CX)
    336 	CALL	runtimestackcheck(SB)
    337 
    338 nog:
    339 	// Call fn
    340 	CALL	R12
    341 
    342 	// It shouldn't return.  If it does, exit that thread.
    343 	MOVL	$111, DI
    344 	MOVL	$60, AX
    345 	SYSCALL
    346 	JMP	-3(PC)	// keep exiting
    347 
    348 TEXT runtimesigaltstack(SB),NOSPLIT,$-8
    349 	MOVQ	new+8(SP), DI
    350 	MOVQ	old+16(SP), SI
    351 	MOVQ	$131, AX
    352 	SYSCALL
    353 	CMPQ	AX, $0xfffffffffffff001
    354 	JLS	2(PC)
    355 	MOVL	$0xf1, 0xf1  // crash
    356 	RET
    357 
    358 // set tls base to DI
    359 TEXT runtimesettls(SB),NOSPLIT,$32
    360 	ADDQ	$8, DI	// ELF wants to use -8(FS)
    361 
    362 	MOVQ	DI, SI
    363 	MOVQ	$0x1002, DI	// ARCH_SET_FS
    364 	MOVQ	$158, AX	// arch_prctl
    365 	SYSCALL
    366 	CMPQ	AX, $0xfffffffffffff001
    367 	JLS	2(PC)
    368 	MOVL	$0xf1, 0xf1  // crash
    369 	RET
    370 
    371 TEXT runtimeosyield(SB),NOSPLIT,$0
    372 	MOVL	$24, AX
    373 	SYSCALL
    374 	RET
    375 
    376 TEXT runtimesched_getaffinity(SB),NOSPLIT,$0
    377 	MOVQ	pid+0(FP), DI
    378 	MOVQ	len+8(FP), SI
    379 	MOVQ	buf+16(FP), DX
    380 	MOVL	$204, AX			// syscall entry
    381 	SYSCALL
    382 	MOVL	AX, ret+24(FP)
    383 	RET
    384 
    385 // int32 runtimeepollcreate(int32 size);
    386 TEXT runtimeepollcreate(SB),NOSPLIT,$0
    387 	MOVL    size+0(FP), DI
    388 	MOVL    $213, AX                        // syscall entry
    389 	SYSCALL
    390 	MOVL	AX, ret+8(FP)
    391 	RET
    392 
    393 // int32 runtimeepollcreate1(int32 flags);
    394 TEXT runtimeepollcreate1(SB),NOSPLIT,$0
    395 	MOVL	flags+0(FP), DI
    396 	MOVL	$291, AX			// syscall entry
    397 	SYSCALL
    398 	MOVL	AX, ret+8(FP)
    399 	RET
    400 
    401 // func epollctl(epfd, op, fd int32, ev *epollEvent) int
    402 TEXT runtimeepollctl(SB),NOSPLIT,$0
    403 	MOVL	epfd+0(FP), DI
    404 	MOVL	op+4(FP), SI
    405 	MOVL	fd+8(FP), DX
    406 	MOVQ	ev+16(FP), R10
    407 	MOVL	$233, AX			// syscall entry
    408 	SYSCALL
    409 	MOVL	AX, ret+24(FP)
    410 	RET
    411 
    412 // int32 runtimeepollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
    413 TEXT runtimeepollwait(SB),NOSPLIT,$0
    414 	MOVL	epfd+0(FP), DI
    415 	MOVQ	ev+8(FP), SI
    416 	MOVL	nev+16(FP), DX
    417 	MOVL	timeout+20(FP), R10
    418 	MOVL	$232, AX			// syscall entry
    419 	SYSCALL
    420 	MOVL	AX, ret+24(FP)
    421 	RET
    422 
    423 // void runtimecloseonexec(int32 fd);
    424 TEXT runtimecloseonexec(SB),NOSPLIT,$0
    425 	MOVL    fd+0(FP), DI  // fd
    426 	MOVQ    $2, SI  // F_SETFD
    427 	MOVQ    $1, DX  // FD_CLOEXEC
    428 	MOVL	$72, AX  // fcntl
    429 	SYSCALL
    430 	RET
    431