1// Copyright 2014 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4//5// System calls and other sys.stuff for AMD64, SunOS6// /usr/include/sys/syscall.h for syscall numbers.7//89#include "go_asm.h"10#include "go_tls.h"11#include "textflag.h"1213// This is needed by asm_amd64.s14TEXT runtime·settls(SB),NOSPLIT,$815 RET1617// void libc_miniterrno(void *(*___errno)(void));18//19// Set the TLS errno pointer in M.20//21// Called using runtime·asmcgocall from os_solaris.c:/minit.22// NOT USING GO CALLING CONVENTION.23TEXT runtime·miniterrno(SB),NOSPLIT,$024 // asmcgocall will put first argument into DI.25 CALL DI // SysV ABI so returns in AX26 get_tls(CX)27 MOVQ g(CX), BX28 MOVQ g_m(BX), BX29 MOVQ AX, (m_mOS+mOS_perrno)(BX)30 RET3132// Call a library function with SysV calling conventions.33// The called function can take a maximum of 6 INTEGER class arguments,34// see35// Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell36// System V Application Binary Interface37// AMD64 Architecture Processor Supplement38// section 3.2.3.39//40// Called by runtime·asmcgocall or runtime·cgocall.41// NOT USING GO CALLING CONVENTION.42TEXT runtime·asmsysvicall6(SB),NOSPLIT,$043 // asmcgocall will put first argument into DI.44 PUSHQ DI // save for later45 MOVQ libcall_fn(DI), AX46 MOVQ libcall_args(DI), R1147 MOVQ libcall_n(DI), R104849 get_tls(CX)50 MOVQ g(CX), BX51 CMPQ BX, $052 JEQ skiperrno153 MOVQ g_m(BX), BX54 MOVQ (m_mOS+mOS_perrno)(BX), DX55 CMPQ DX, $056 JEQ skiperrno157 MOVL $0, 0(DX)5859skiperrno1:60 CMPQ R11, $061 JEQ skipargs62 // Load 6 args into correspondent registers.63 MOVQ 0(R11), DI64 MOVQ 8(R11), SI65 MOVQ 16(R11), DX66 MOVQ 24(R11), CX67 MOVQ 32(R11), R868 MOVQ 40(R11), R969skipargs:7071 // Call SysV function72 CALL AX7374 // Return result75 POPQ DI76 MOVQ AX, libcall_r1(DI)77 MOVQ DX, libcall_r2(DI)7879 get_tls(CX)80 MOVQ g(CX), BX81 CMPQ BX, $082 JEQ skiperrno283 MOVQ g_m(BX), BX84 MOVQ (m_mOS+mOS_perrno)(BX), AX85 CMPQ AX, $086 JEQ skiperrno287 MOVL 0(AX), AX88 MOVQ AX, libcall_err(DI)8990skiperrno2:91 RET9293// uint32 tstart_sysvicall(M *newm);94TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$095 // DI contains first arg newm96 MOVQ m_g0(DI), DX // g9798 // Make TLS entries point at g and m.99 get_tls(BX)100 MOVQ DX, g(BX)101 MOVQ DI, g_m(DX)102103 // Layout new m scheduler stack on os stack.104 MOVQ SP, AX105 MOVQ AX, (g_stack+stack_hi)(DX)106 SUBQ $(0x100000), AX // stack size107 MOVQ AX, (g_stack+stack_lo)(DX)108 ADDQ $const_stackGuard, AX109 MOVQ AX, g_stackguard0(DX)110 MOVQ AX, g_stackguard1(DX)111112 // Someday the convention will be D is always cleared.113 CLD114115 CALL runtime·stackcheck(SB) // clobbers AX,CX116 CALL runtime·mstart(SB)117118 XORL AX, AX // return 0 == success119 MOVL AX, ret+8(FP)120 RET121122// Careful, this is called by __sighndlr, a libc function. We must preserve123// registers as per AMD 64 ABI.124TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0125 // Note that we are executing on altsigstack here, so we have126 // more stack available than NOSPLIT would have us believe.127 // To defeat the linker, we make our own stack frame with128 // more space:129 SUBQ $168, SP130 // save registers131 MOVQ BX, 24(SP)132 MOVQ BP, 32(SP)133 MOVQ R12, 40(SP)134 MOVQ R13, 48(SP)135 MOVQ R14, 56(SP)136 MOVQ R15, 64(SP)137138 get_tls(BX)139 // check that g exists140 MOVQ g(BX), R10141 CMPQ R10, $0142 JNE allgood143 MOVQ SI, 72(SP)144 MOVQ DX, 80(SP)145 LEAQ 72(SP), AX146 MOVQ DI, 0(SP)147 MOVQ AX, 8(SP)148 MOVQ $runtime·badsignal(SB), AX149 CALL AX150 JMP exit151152allgood:153 // Save m->libcall and m->scratch. We need to do this because we154 // might get interrupted by a signal in runtime·asmcgocall.155156 // save m->libcall157 MOVQ g_m(R10), BP158 LEAQ (m_mOS+mOS_libcall)(BP), R11159 MOVQ libcall_fn(R11), R10160 MOVQ R10, 72(SP)161 MOVQ libcall_args(R11), R10162 MOVQ R10, 80(SP)163 MOVQ libcall_n(R11), R10164 MOVQ R10, 88(SP)165 MOVQ libcall_r1(R11), R10166 MOVQ R10, 152(SP)167 MOVQ libcall_r2(R11), R10168 MOVQ R10, 160(SP)169170 // save m->scratch171 LEAQ (m_mOS+mOS_scratch)(BP), R11172 MOVQ 0(R11), R10173 MOVQ R10, 96(SP)174 MOVQ 8(R11), R10175 MOVQ R10, 104(SP)176 MOVQ 16(R11), R10177 MOVQ R10, 112(SP)178 MOVQ 24(R11), R10179 MOVQ R10, 120(SP)180 MOVQ 32(R11), R10181 MOVQ R10, 128(SP)182 MOVQ 40(R11), R10183 MOVQ R10, 136(SP)184185 // save errno, it might be EINTR; stuff we do here might reset it.186 MOVQ (m_mOS+mOS_perrno)(BP), R10187 MOVL 0(R10), R10188 MOVQ R10, 144(SP)189190 // prepare call191 MOVQ DI, 0(SP)192 MOVQ SI, 8(SP)193 MOVQ DX, 16(SP)194 CALL runtime·sigtrampgo(SB)195196 get_tls(BX)197 MOVQ g(BX), BP198 MOVQ g_m(BP), BP199 // restore libcall200 LEAQ (m_mOS+mOS_libcall)(BP), R11201 MOVQ 72(SP), R10202 MOVQ R10, libcall_fn(R11)203 MOVQ 80(SP), R10204 MOVQ R10, libcall_args(R11)205 MOVQ 88(SP), R10206 MOVQ R10, libcall_n(R11)207 MOVQ 152(SP), R10208 MOVQ R10, libcall_r1(R11)209 MOVQ 160(SP), R10210 MOVQ R10, libcall_r2(R11)211212 // restore scratch213 LEAQ (m_mOS+mOS_scratch)(BP), R11214 MOVQ 96(SP), R10215 MOVQ R10, 0(R11)216 MOVQ 104(SP), R10217 MOVQ R10, 8(R11)218 MOVQ 112(SP), R10219 MOVQ R10, 16(R11)220 MOVQ 120(SP), R10221 MOVQ R10, 24(R11)222 MOVQ 128(SP), R10223 MOVQ R10, 32(R11)224 MOVQ 136(SP), R10225 MOVQ R10, 40(R11)226227 // restore errno228 MOVQ (m_mOS+mOS_perrno)(BP), R11229 MOVQ 144(SP), R10230 MOVL R10, 0(R11)231232exit:233 // restore registers234 MOVQ 24(SP), BX235 MOVQ 32(SP), BP236 MOVQ 40(SP), R12237 MOVQ 48(SP), R13238 MOVQ 56(SP), R14239 MOVQ 64(SP), R15240 ADDQ $168, SP241 RET242243TEXT runtime·sigfwd(SB),NOSPLIT,$0-32244 MOVQ fn+0(FP), AX245 MOVL sig+8(FP), DI246 MOVQ info+16(FP), SI247 MOVQ ctx+24(FP), DX248 MOVQ SP, BX // callee-saved249 ANDQ $~15, SP // alignment for x86_64 ABI250 CALL AX251 MOVQ BX, SP252 RET253254// Called from runtime·usleep (Go). Can be called on Go stack, on OS stack,255// can also be called in cgo callback path without a g->m.256TEXT runtime·usleep1(SB),NOSPLIT,$0257 MOVL usec+0(FP), DI258 MOVQ $usleep2<>(SB), AX // to hide from 6l259260 // Execute call on m->g0.261 get_tls(R15)262 CMPQ R15, $0263 JE noswitch264265 MOVQ g(R15), R13266 CMPQ R13, $0267 JE noswitch268 MOVQ g_m(R13), R13269 CMPQ R13, $0270 JE noswitch271 // TODO(aram): do something about the cpu profiler here.272273 MOVQ m_g0(R13), R14274 CMPQ g(R15), R14275 JNE switch276 // executing on m->g0 already277 CALL AX278 RET279280switch:281 // Switch to m->g0 stack and back.282 MOVQ (g_sched+gobuf_sp)(R14), R14283 MOVQ SP, -8(R14)284 LEAQ -8(R14), SP285 CALL AX286 MOVQ 0(SP), SP287 RET288289noswitch:290 // Not a Go-managed thread. Do not switch stack.291 CALL AX292 RET293294// Runs on OS stack. duration (in µs units) is in DI.295TEXT usleep2<>(SB),NOSPLIT,$0296 LEAQ libc_usleep(SB), AX297 CALL AX298 RET299300// Runs on OS stack, called from runtime·osyield.301TEXT runtime·osyield1(SB),NOSPLIT,$0302 LEAQ libc_sched_yield(SB), AX303 CALL AX304 RET
Findings
✓ No findings reported for this file.