diff options
Diffstat (limited to 'src/pkg/runtime/darwin')
-rw-r--r-- | src/pkg/runtime/darwin/386/defs.h | 289 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/386/rt0.s | 8 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/386/signal.c | 194 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/386/sys.s | 311 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/amd64/defs.h | 305 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/amd64/rt0.s | 10 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/amd64/signal.c | 204 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/amd64/sys.s | 295 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/defs.c | 159 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/mem.c | 55 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/os.h | 31 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/signals.h | 51 | ||||
-rw-r--r-- | src/pkg/runtime/darwin/thread.c | 484 |
13 files changed, 0 insertions, 2396 deletions
diff --git a/src/pkg/runtime/darwin/386/defs.h b/src/pkg/runtime/darwin/386/defs.h deleted file mode 100644 index bb70207fd..000000000 --- a/src/pkg/runtime/darwin/386/defs.h +++ /dev/null @@ -1,289 +0,0 @@ -// godefs -f -m32 defs.c - -// MACHINE GENERATED - DO NOT EDIT. - -// Constants -enum { - PROT_NONE = 0, - PROT_READ = 0x1, - PROT_WRITE = 0x2, - PROT_EXEC = 0x4, - MAP_ANON = 0x1000, - MAP_PRIVATE = 0x2, - MAP_FIXED = 0x10, - MACH_MSG_TYPE_MOVE_RECEIVE = 0x10, - MACH_MSG_TYPE_MOVE_SEND = 0x11, - MACH_MSG_TYPE_MOVE_SEND_ONCE = 0x12, - MACH_MSG_TYPE_COPY_SEND = 0x13, - MACH_MSG_TYPE_MAKE_SEND = 0x14, - MACH_MSG_TYPE_MAKE_SEND_ONCE = 0x15, - MACH_MSG_TYPE_COPY_RECEIVE = 0x16, - MACH_MSG_PORT_DESCRIPTOR = 0, - MACH_MSG_OOL_DESCRIPTOR = 0x1, - MACH_MSG_OOL_PORTS_DESCRIPTOR = 0x2, - MACH_MSG_OOL_VOLATILE_DESCRIPTOR = 0x3, - MACH_MSGH_BITS_COMPLEX = 0x80000000, - MACH_SEND_MSG = 0x1, - MACH_RCV_MSG = 0x2, - MACH_RCV_LARGE = 0x4, - MACH_SEND_TIMEOUT = 0x10, - MACH_SEND_INTERRUPT = 0x40, - MACH_SEND_CANCEL = 0x80, - MACH_SEND_ALWAYS = 0x10000, - MACH_SEND_TRAILER = 0x20000, - MACH_RCV_TIMEOUT = 0x100, - MACH_RCV_NOTIFY = 0x200, - MACH_RCV_INTERRUPT = 0x400, - MACH_RCV_OVERWRITE = 0x1000, - NDR_PROTOCOL_2_0 = 0, - NDR_INT_BIG_ENDIAN = 0, - NDR_INT_LITTLE_ENDIAN = 0x1, - NDR_FLOAT_IEEE = 0, - NDR_CHAR_ASCII = 0, - SA_SIGINFO = 0x40, - SA_RESTART = 0x2, - SA_ONSTACK = 0x1, - SA_USERTRAMP = 0x100, - SA_64REGSET = 0x200, - SIGHUP = 0x1, - SIGINT = 0x2, - SIGQUIT = 0x3, - SIGILL = 0x4, - SIGTRAP = 0x5, - SIGABRT = 0x6, - SIGEMT = 0x7, - SIGFPE = 0x8, - SIGKILL = 0x9, - SIGBUS = 0xa, - SIGSEGV = 0xb, - SIGSYS = 0xc, - SIGPIPE = 0xd, - SIGALRM = 0xe, - SIGTERM = 0xf, - SIGURG = 0x10, - SIGSTOP = 0x11, - SIGTSTP = 0x12, - SIGCONT = 0x13, - SIGCHLD = 0x14, - SIGTTIN = 0x15, - SIGTTOU = 0x16, - SIGIO = 0x17, - SIGXCPU = 0x18, - SIGXFSZ = 0x19, - SIGVTALRM = 0x1a, - SIGPROF = 0x1b, - SIGWINCH = 0x1c, - SIGINFO = 0x1d, - SIGUSR1 = 0x1e, - SIGUSR2 = 0x1f, - FPE_INTDIV = 0x7, - FPE_INTOVF = 0x8, - FPE_FLTDIV = 0x1, - FPE_FLTOVF = 0x2, - FPE_FLTUND = 0x3, - FPE_FLTRES = 0x4, - FPE_FLTINV = 0x5, - FPE_FLTSUB = 0x6, - BUS_ADRALN = 0x1, - BUS_ADRERR = 0x2, - BUS_OBJERR = 0x3, - SEGV_MAPERR = 0x1, - SEGV_ACCERR = 0x2, - ITIMER_REAL = 0, - ITIMER_VIRTUAL = 0x1, - ITIMER_PROF = 0x2, -}; - -// Types -#pragma pack on - -typedef struct MachBody MachBody; -struct MachBody { - uint32 msgh_descriptor_count; -}; - -typedef struct MachHeader MachHeader; -struct MachHeader { - uint32 msgh_bits; - uint32 msgh_size; - uint32 msgh_remote_port; - uint32 msgh_local_port; - uint32 msgh_reserved; - int32 msgh_id; -}; - -typedef struct MachNDR MachNDR; -struct MachNDR { - uint8 mig_vers; - uint8 if_vers; - uint8 reserved1; - uint8 mig_encoding; - uint8 int_rep; - uint8 char_rep; - uint8 float_rep; - uint8 reserved2; -}; - -typedef struct MachPort MachPort; -struct MachPort { - uint32 name; - uint32 pad1; - uint16 pad2; - uint8 disposition; - uint8 type; -}; - -typedef struct StackT StackT; -struct StackT { - void *ss_sp; - uint32 ss_size; - int32 ss_flags; -}; - -typedef union Sighandler Sighandler; -union Sighandler { - uint32 __sa_handler; - uint32 __sa_sigaction; -}; - -typedef struct Sigaction Sigaction; -struct Sigaction { - Sighandler __sigaction_u; - uint32 sa_tramp; - uint32 sa_mask; - int32 sa_flags; -}; - -typedef union Sigval Sigval; -union Sigval { - int32 sival_int; - void *sival_ptr; -}; - -typedef struct Siginfo Siginfo; -struct Siginfo { - int32 si_signo; - int32 si_errno; - int32 si_code; - int32 si_pid; - uint32 si_uid; - int32 si_status; - void *si_addr; - Sigval si_value; - int32 si_band; - uint32 __pad[7]; -}; - -typedef struct Timeval Timeval; -struct Timeval { - int32 tv_sec; - int32 tv_usec; -}; - -typedef struct Itimerval Itimerval; -struct Itimerval { - Timeval it_interval; - Timeval it_value; -}; - -typedef struct FPControl FPControl; -struct FPControl { - byte pad_godefs_0[2]; -}; - -typedef struct FPStatus FPStatus; -struct FPStatus { - byte pad_godefs_0[2]; -}; - -typedef struct RegMMST RegMMST; -struct RegMMST { - int8 mmst_reg[10]; - int8 mmst_rsrv[6]; -}; - -typedef struct RegXMM RegXMM; -struct RegXMM { - int8 xmm_reg[16]; -}; - -typedef struct Regs Regs; -struct Regs { - uint32 eax; - uint32 ebx; - uint32 ecx; - uint32 edx; - uint32 edi; - uint32 esi; - uint32 ebp; - uint32 esp; - uint32 ss; - uint32 eflags; - uint32 eip; - uint32 cs; - uint32 ds; - uint32 es; - uint32 fs; - uint32 gs; -}; - -typedef struct FloatState FloatState; -struct FloatState { - uint64 fpu_reserved; - FPControl fpu_fcw; - FPStatus fpu_fsw; - uint8 fpu_ftw; - uint8 fpu_rsrv1; - uint16 fpu_fop; - uint32 fpu_ip; - uint16 fpu_cs; - uint16 fpu_rsrv2; - uint32 fpu_dp; - uint16 fpu_ds; - uint16 fpu_rsrv3; - uint32 fpu_mxcsr; - uint32 fpu_mxcsrmask; - RegMMST fpu_stmm0; - RegMMST fpu_stmm1; - RegMMST fpu_stmm2; - RegMMST fpu_stmm3; - RegMMST fpu_stmm4; - RegMMST fpu_stmm5; - RegMMST fpu_stmm6; - RegMMST fpu_stmm7; - RegXMM fpu_xmm0; - RegXMM fpu_xmm1; - RegXMM fpu_xmm2; - RegXMM fpu_xmm3; - RegXMM fpu_xmm4; - RegXMM fpu_xmm5; - RegXMM fpu_xmm6; - RegXMM fpu_xmm7; - int8 fpu_rsrv4[224]; - int32 fpu_reserved1; -}; - -typedef struct ExceptionState ExceptionState; -struct ExceptionState { - uint32 trapno; - uint32 err; - uint32 faultvaddr; -}; - -typedef struct Mcontext Mcontext; -struct Mcontext { - ExceptionState es; - Regs ss; - FloatState fs; -}; - -typedef struct Ucontext Ucontext; -struct Ucontext { - int32 uc_onstack; - uint32 uc_sigmask; - StackT uc_stack; - uint32 uc_link; - uint32 uc_mcsize; - Mcontext *uc_mcontext; -}; -#pragma pack off diff --git a/src/pkg/runtime/darwin/386/rt0.s b/src/pkg/runtime/darwin/386/rt0.s deleted file mode 100644 index 30b497f5e..000000000 --- a/src/pkg/runtime/darwin/386/rt0.s +++ /dev/null @@ -1,8 +0,0 @@ -// 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. - -// Darwin and Linux use the same linkage to main - -TEXT _rt0_386_darwin(SB),7,$0 - JMP _rt0_386(SB) diff --git a/src/pkg/runtime/darwin/386/signal.c b/src/pkg/runtime/darwin/386/signal.c deleted file mode 100644 index 29170b669..000000000 --- a/src/pkg/runtime/darwin/386/signal.c +++ /dev/null @@ -1,194 +0,0 @@ -// 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. - -#include "runtime.h" -#include "defs.h" -#include "os.h" -#include "signals.h" - -void -runtime·dumpregs(Regs *r) -{ - runtime·printf("eax %x\n", r->eax); - runtime·printf("ebx %x\n", r->ebx); - runtime·printf("ecx %x\n", r->ecx); - runtime·printf("edx %x\n", r->edx); - runtime·printf("edi %x\n", r->edi); - runtime·printf("esi %x\n", r->esi); - runtime·printf("ebp %x\n", r->ebp); - runtime·printf("esp %x\n", r->esp); - runtime·printf("eip %x\n", r->eip); - runtime·printf("eflags %x\n", r->eflags); - runtime·printf("cs %x\n", r->cs); - runtime·printf("fs %x\n", r->fs); - runtime·printf("gs %x\n", r->gs); -} - -String -runtime·signame(int32 sig) -{ - if(sig < 0 || sig >= NSIG) - return runtime·emptystring; - return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name); -} - -void -runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) -{ - Ucontext *uc; - Mcontext *mc; - Regs *r; - uintptr *sp; - byte *pc; - - uc = context; - mc = uc->uc_mcontext; - r = &mc->ss; - - if(sig == SIGPROF) { - runtime·sigprof((uint8*)r->eip, (uint8*)r->esp, nil, gp); - return; - } - - if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) { - // Work around Leopard bug that doesn't set FPE_INTDIV. - // Look at instruction to see if it is a divide. - // Not necessary in Snow Leopard (si_code will be != 0). - if(sig == SIGFPE && info->si_code == 0) { - pc = (byte*)r->eip; - if(pc[0] == 0x66) // 16-bit instruction prefix - pc++; - if(pc[0] == 0xF6 || pc[0] == 0xF7) - info->si_code = FPE_INTDIV; - } - - // Make it look like a call to the signal func. - // Have to pass arguments out of band since - // augmenting the stack frame would break - // the unwinding code. - gp->sig = sig; - gp->sigcode0 = info->si_code; - gp->sigcode1 = (uintptr)info->si_addr; - gp->sigpc = r->eip; - - // Only push runtime·sigpanic if r->eip != 0. - // If r->eip == 0, probably panicked because of a - // call to a nil func. Not pushing that onto sp will - // make the trace look like a call to runtime·sigpanic instead. - // (Otherwise the trace will end at runtime·sigpanic and we - // won't get to see who faulted.) - if(r->eip != 0) { - sp = (uintptr*)r->esp; - *--sp = r->eip; - r->esp = (uintptr)sp; - } - r->eip = (uintptr)runtime·sigpanic; - return; - } - - if(runtime·sigtab[sig].flags & SigQueue) { - if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore)) - return; - runtime·exit(2); // SIGINT, SIGTERM, etc - } - - if(runtime·panicking) // traceback already printed - runtime·exit(2); - runtime·panicking = 1; - - if(sig < 0 || sig >= NSIG){ - runtime·printf("Signal %d\n", sig); - }else{ - runtime·printf("%s\n", runtime·sigtab[sig].name); - } - - runtime·printf("pc: %x\n", r->eip); - runtime·printf("\n"); - - if(runtime·gotraceback()){ - runtime·traceback((void*)r->eip, (void*)r->esp, 0, gp); - runtime·tracebackothers(gp); - runtime·dumpregs(r); - } - - runtime·exit(2); -} - -void -runtime·sigignore(int32, Siginfo*, void*) -{ -} - -void -runtime·signalstack(byte *p, int32 n) -{ - StackT st; - - st.ss_sp = p; - st.ss_size = n; - st.ss_flags = 0; - runtime·sigaltstack(&st, nil); -} - -static void -sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart) -{ - Sigaction sa; - - runtime·memclr((byte*)&sa, sizeof sa); - sa.sa_flags = SA_SIGINFO|SA_ONSTACK; - if(restart) - sa.sa_flags |= SA_RESTART; - sa.sa_mask = ~0U; - sa.sa_tramp = (uintptr)runtime·sigtramp; // runtime·sigtramp's job is to call into real handler - sa.__sigaction_u.__sa_sigaction = (uintptr)fn; - runtime·sigaction(i, &sa, nil); -} - -void -runtime·initsig(int32 queue) -{ - int32 i; - void *fn; - - runtime·siginit(); - - for(i = 0; i<NSIG; i++) { - if(runtime·sigtab[i].flags) { - if((runtime·sigtab[i].flags & SigQueue) != queue) - continue; - if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) - fn = runtime·sighandler; - else - fn = runtime·sigignore; - sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0); - } - } -} - -void -runtime·resetcpuprofiler(int32 hz) -{ - Itimerval it; - - runtime·memclr((byte*)&it, sizeof it); - if(hz == 0) { - runtime·setitimer(ITIMER_PROF, &it, nil); - sigaction(SIGPROF, SIG_IGN, true); - } else { - sigaction(SIGPROF, runtime·sighandler, true); - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = 1000000 / hz; - it.it_value = it.it_interval; - runtime·setitimer(ITIMER_PROF, &it, nil); - } - m->profilehz = hz; -} - -void -os·sigpipe(void) -{ - sigaction(SIGPIPE, SIG_DFL, false); - runtime·raisesigpipe(); -} diff --git a/src/pkg/runtime/darwin/386/sys.s b/src/pkg/runtime/darwin/386/sys.s deleted file mode 100644 index 87fbdbb79..000000000 --- a/src/pkg/runtime/darwin/386/sys.s +++ /dev/null @@ -1,311 +0,0 @@ -// 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 386, Darwin -// See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228 -// or /usr/include/sys/syscall.h (on a Mac) for system call numbers. - -#include "386/asm.h" - -TEXT runtime·notok(SB),7,$0 - MOVL $0xf1, 0xf1 - RET - -// Exit the entire program (like C exit) -TEXT runtime·exit(SB),7,$0 - MOVL $1, AX - INT $0x80 - CALL runtime·notok(SB) - RET - -// Exit this OS thread (like pthread_exit, which eventually -// calls __bsdthread_terminate). -TEXT runtime·exit1(SB),7,$0 - MOVL $361, AX - INT $0x80 - JAE 2(PC) - CALL runtime·notok(SB) - RET - -TEXT runtime·write(SB),7,$0 - MOVL $4, AX - INT $0x80 - RET - -TEXT runtime·raisesigpipe(SB),7,$8 - get_tls(CX) - MOVL m(CX), DX - MOVL m_procid(DX), DX - MOVL DX, 0(SP) // thread_port - MOVL $13, 4(SP) // signal: SIGPIPE - MOVL $328, AX // __pthread_kill - INT $0x80 - RET - -TEXT runtime·mmap(SB),7,$0 - MOVL $197, AX - INT $0x80 - RET - -TEXT runtime·munmap(SB),7,$0 - MOVL $73, AX - INT $0x80 - JAE 2(PC) - CALL runtime·notok(SB) - RET - -TEXT runtime·setitimer(SB),7,$0 - MOVL $83, AX - INT $0x80 - RET - -// void gettime(int64 *sec, int32 *usec) -TEXT runtime·gettime(SB), 7, $32 - LEAL 12(SP), AX // must be non-nil, unused - MOVL AX, 4(SP) - MOVL $0, 8(SP) // time zone pointer - MOVL $116, AX - INT $0x80 - - MOVL sec+0(FP), DI - MOVL AX, (DI) - MOVL $0, 4(DI) // zero extend 32 -> 64 - - MOVL usec+4(FP), DI - MOVL DX, (DI) - RET - -TEXT runtime·sigaction(SB),7,$0 - MOVL $46, AX - INT $0x80 - JAE 2(PC) - CALL runtime·notok(SB) - RET - -// Sigtramp's job is to call the actual signal handler. -// It is called with the following arguments on the stack: -// 0(FP) "return address" - ignored -// 4(FP) actual handler -// 8(FP) siginfo style - ignored -// 12(FP) signal number -// 16(FP) siginfo -// 20(FP) context -TEXT runtime·sigtramp(SB),7,$40 - get_tls(CX) - - // save g - MOVL g(CX), DI - MOVL DI, 20(SP) - - // g = m->gsignal - MOVL m(CX), BP - MOVL m_gsignal(BP), BP - MOVL BP, g(CX) - - // copy arguments to sighandler - MOVL sig+8(FP), BX - MOVL BX, 0(SP) - MOVL info+12(FP), BX - MOVL BX, 4(SP) - MOVL context+16(FP), BX - MOVL BX, 8(SP) - MOVL DI, 12(SP) - - MOVL handler+0(FP), BX - CALL BX - - // restore g - get_tls(CX) - MOVL 20(SP), DI - MOVL DI, g(CX) - - // call sigreturn - MOVL context+16(FP), CX - MOVL style+4(FP), BX - MOVL $0, 0(SP) // "caller PC" - ignored - MOVL CX, 4(SP) - MOVL BX, 8(SP) - MOVL $184, AX // sigreturn(ucontext, infostyle) - INT $0x80 - CALL runtime·notok(SB) - RET - -TEXT runtime·sigaltstack(SB),7,$0 - MOVL $53, AX - INT $0x80 - JAE 2(PC) - CALL runtime·notok(SB) - RET - -// void bsdthread_create(void *stk, M *m, G *g, void (*fn)(void)) -// System call args are: func arg stack pthread flags. -TEXT runtime·bsdthread_create(SB),7,$32 - MOVL $360, AX - // 0(SP) is where the caller PC would be; kernel skips it - MOVL func+12(FP), BX - MOVL BX, 4(SP) // func - MOVL mm+4(FP), BX - MOVL BX, 8(SP) // arg - MOVL stk+0(FP), BX - MOVL BX, 12(SP) // stack - MOVL gg+8(FP), BX - MOVL BX, 16(SP) // pthread - MOVL $0x1000000, 20(SP) // flags = PTHREAD_START_CUSTOM - INT $0x80 - JAE 3(PC) - NEGL AX - RET - MOVL $0, AX - RET - -// The thread that bsdthread_create creates starts executing here, -// because we registered this function using bsdthread_register -// at startup. -// AX = "pthread" (= g) -// BX = mach thread port -// CX = "func" (= fn) -// DX = "arg" (= m) -// DI = stack top -// SI = flags (= 0x1000000) -// SP = stack - C_32_STK_ALIGN -TEXT runtime·bsdthread_start(SB),7,$0 - // set up ldt 7+id to point at m->tls. - // m->tls is at m+40. newosproc left - // the m->id in tls[0]. - LEAL m_tls(DX), BP - MOVL 0(BP), DI - ADDL $7, DI // m0 is LDT#7. count up. - // setldt(tls#, &tls, sizeof tls) - PUSHAL // save registers - PUSHL $32 // sizeof tls - PUSHL BP // &tls - PUSHL DI // tls # - CALL runtime·setldt(SB) - POPL AX - POPL AX - POPL AX - POPAL - - // Now segment is established. Initialize m, g. - get_tls(BP) - MOVL AX, g(BP) - MOVL DX, m(BP) - MOVL BX, m_procid(DX) // m->procid = thread port (for debuggers) - CALL runtime·stackcheck(SB) // smashes AX - CALL CX // fn() - CALL runtime·exit1(SB) - RET - -// void bsdthread_register(void) -// registers callbacks for threadstart (see bsdthread_create above -// and wqthread and pthsize (not used). returns 0 on success. -TEXT runtime·bsdthread_register(SB),7,$40 - MOVL $366, AX - // 0(SP) is where kernel expects caller PC; ignored - MOVL $runtime·bsdthread_start(SB), 4(SP) // threadstart - MOVL $0, 8(SP) // wqthread, not used by us - MOVL $0, 12(SP) // pthsize, not used by us - MOVL $0, 16(SP) // dummy_value [sic] - MOVL $0, 20(SP) // targetconc_ptr - MOVL $0, 24(SP) // dispatchqueue_offset - INT $0x80 - JAE 2(PC) - CALL runtime·notok(SB) - RET - -// Invoke Mach system call. -// Assumes system call number in AX, -// caller PC on stack, caller's caller PC next, -// and then the system call arguments. -// -// Can be used for BSD too, but we don't, -// because if you use this interface the BSD -// system call numbers need an extra field -// in the high 16 bits that seems to be the -// argument count in bytes but is not always. -// INT $0x80 works fine for those. -TEXT runtime·sysenter(SB),7,$0 - POPL DX - MOVL SP, CX - BYTE $0x0F; BYTE $0x34; // SYSENTER - // returns to DX with SP set to CX - -TEXT runtime·mach_msg_trap(SB),7,$0 - MOVL $-31, AX - CALL runtime·sysenter(SB) - RET - -TEXT runtime·mach_reply_port(SB),7,$0 - MOVL $-26, AX - CALL runtime·sysenter(SB) - RET - -TEXT runtime·mach_task_self(SB),7,$0 - MOVL $-28, AX - CALL runtime·sysenter(SB) - RET - -// Mach provides trap versions of the semaphore ops, -// instead of requiring the use of RPC. - -// uint32 mach_semaphore_wait(uint32) -TEXT runtime·mach_semaphore_wait(SB),7,$0 - MOVL $-36, AX - CALL runtime·sysenter(SB) - RET - -// uint32 mach_semaphore_timedwait(uint32, uint32, uint32) -TEXT runtime·mach_semaphore_timedwait(SB),7,$0 - MOVL $-38, AX - CALL runtime·sysenter(SB) - RET - -// uint32 mach_semaphore_signal(uint32) -TEXT runtime·mach_semaphore_signal(SB),7,$0 - MOVL $-33, AX - CALL runtime·sysenter(SB) - RET - -// uint32 mach_semaphore_signal_all(uint32) -TEXT runtime·mach_semaphore_signal_all(SB),7,$0 - MOVL $-34, AX - CALL runtime·sysenter(SB) - RET - -// setldt(int entry, int address, int limit) -// entry and limit are ignored. -TEXT runtime·setldt(SB),7,$32 - MOVL address+4(FP), BX // aka base - - /* - * When linking against the system libraries, - * we use its pthread_create and let it set up %gs - * for us. When we do that, the private storage - * we get is not at 0(GS) but at 0x468(GS). - * To insulate the rest of the tool chain from this ugliness, - * 8l rewrites 0(GS) into 0x468(GS) for us. - * To accommodate that rewrite, we translate the - * address and limit here so that 0x468(GS) maps to 0(address). - * - * See ../../../../libcgo/darwin_386.c for the derivation - * of the constant. - */ - SUBL $0x468, BX - - /* - * Must set up as USER_CTHREAD segment because - * Darwin forces that value into %gs for signal handlers, - * and if we don't set one up, we'll get a recursive - * fault trying to get into the signal handler. - * Since we have to set one up anyway, it might as - * well be the value we want. So don't bother with - * i386_set_ldt. - */ - MOVL BX, 4(SP) - MOVL $3, AX // thread_fast_set_cthread_self - machdep call #3 - INT $0x82 // sic: 0x82, not 0x80, for machdep call - - XORL AX, AX - MOVW GS, AX - RET diff --git a/src/pkg/runtime/darwin/amd64/defs.h b/src/pkg/runtime/darwin/amd64/defs.h deleted file mode 100644 index 90f798e8a..000000000 --- a/src/pkg/runtime/darwin/amd64/defs.h +++ /dev/null @@ -1,305 +0,0 @@ -// godefs -f -m64 defs.c - -// MACHINE GENERATED - DO NOT EDIT. - -// Constants -enum { - PROT_NONE = 0, - PROT_READ = 0x1, - PROT_WRITE = 0x2, - PROT_EXEC = 0x4, - MAP_ANON = 0x1000, - MAP_PRIVATE = 0x2, - MAP_FIXED = 0x10, - MACH_MSG_TYPE_MOVE_RECEIVE = 0x10, - MACH_MSG_TYPE_MOVE_SEND = 0x11, - MACH_MSG_TYPE_MOVE_SEND_ONCE = 0x12, - MACH_MSG_TYPE_COPY_SEND = 0x13, - MACH_MSG_TYPE_MAKE_SEND = 0x14, - MACH_MSG_TYPE_MAKE_SEND_ONCE = 0x15, - MACH_MSG_TYPE_COPY_RECEIVE = 0x16, - MACH_MSG_PORT_DESCRIPTOR = 0, - MACH_MSG_OOL_DESCRIPTOR = 0x1, - MACH_MSG_OOL_PORTS_DESCRIPTOR = 0x2, - MACH_MSG_OOL_VOLATILE_DESCRIPTOR = 0x3, - MACH_MSGH_BITS_COMPLEX = 0x80000000, - MACH_SEND_MSG = 0x1, - MACH_RCV_MSG = 0x2, - MACH_RCV_LARGE = 0x4, - MACH_SEND_TIMEOUT = 0x10, - MACH_SEND_INTERRUPT = 0x40, - MACH_SEND_CANCEL = 0x80, - MACH_SEND_ALWAYS = 0x10000, - MACH_SEND_TRAILER = 0x20000, - MACH_RCV_TIMEOUT = 0x100, - MACH_RCV_NOTIFY = 0x200, - MACH_RCV_INTERRUPT = 0x400, - MACH_RCV_OVERWRITE = 0x1000, - NDR_PROTOCOL_2_0 = 0, - NDR_INT_BIG_ENDIAN = 0, - NDR_INT_LITTLE_ENDIAN = 0x1, - NDR_FLOAT_IEEE = 0, - NDR_CHAR_ASCII = 0, - SA_SIGINFO = 0x40, - SA_RESTART = 0x2, - SA_ONSTACK = 0x1, - SA_USERTRAMP = 0x100, - SA_64REGSET = 0x200, - SIGHUP = 0x1, - SIGINT = 0x2, - SIGQUIT = 0x3, - SIGILL = 0x4, - SIGTRAP = 0x5, - SIGABRT = 0x6, - SIGEMT = 0x7, - SIGFPE = 0x8, - SIGKILL = 0x9, - SIGBUS = 0xa, - SIGSEGV = 0xb, - SIGSYS = 0xc, - SIGPIPE = 0xd, - SIGALRM = 0xe, - SIGTERM = 0xf, - SIGURG = 0x10, - SIGSTOP = 0x11, - SIGTSTP = 0x12, - SIGCONT = 0x13, - SIGCHLD = 0x14, - SIGTTIN = 0x15, - SIGTTOU = 0x16, - SIGIO = 0x17, - SIGXCPU = 0x18, - SIGXFSZ = 0x19, - SIGVTALRM = 0x1a, - SIGPROF = 0x1b, - SIGWINCH = 0x1c, - SIGINFO = 0x1d, - SIGUSR1 = 0x1e, - SIGUSR2 = 0x1f, - FPE_INTDIV = 0x7, - FPE_INTOVF = 0x8, - FPE_FLTDIV = 0x1, - FPE_FLTOVF = 0x2, - FPE_FLTUND = 0x3, - FPE_FLTRES = 0x4, - FPE_FLTINV = 0x5, - FPE_FLTSUB = 0x6, - BUS_ADRALN = 0x1, - BUS_ADRERR = 0x2, - BUS_OBJERR = 0x3, - SEGV_MAPERR = 0x1, - SEGV_ACCERR = 0x2, - ITIMER_REAL = 0, - ITIMER_VIRTUAL = 0x1, - ITIMER_PROF = 0x2, -}; - -// Types -#pragma pack on - -typedef struct MachBody MachBody; -struct MachBody { - uint32 msgh_descriptor_count; -}; - -typedef struct MachHeader MachHeader; -struct MachHeader { - uint32 msgh_bits; - uint32 msgh_size; - uint32 msgh_remote_port; - uint32 msgh_local_port; - uint32 msgh_reserved; - int32 msgh_id; -}; - -typedef struct MachNDR MachNDR; -struct MachNDR { - uint8 mig_vers; - uint8 if_vers; - uint8 reserved1; - uint8 mig_encoding; - uint8 int_rep; - uint8 char_rep; - uint8 float_rep; - uint8 reserved2; -}; - -typedef struct MachPort MachPort; -struct MachPort { - uint32 name; - uint32 pad1; - uint16 pad2; - uint8 disposition; - uint8 type; -}; - -typedef struct StackT StackT; -struct StackT { - void *ss_sp; - uint64 ss_size; - int32 ss_flags; - byte pad_godefs_0[4]; -}; - -typedef union Sighandler Sighandler; -union Sighandler { - uint64 __sa_handler; - uint64 __sa_sigaction; -}; - -typedef struct Sigaction Sigaction; -struct Sigaction { - Sighandler __sigaction_u; - uint64 sa_tramp; - uint32 sa_mask; - int32 sa_flags; -}; - -typedef union Sigval Sigval; -union Sigval { - int32 sival_int; - void *sival_ptr; -}; - -typedef struct Siginfo Siginfo; -struct Siginfo { - int32 si_signo; - int32 si_errno; - int32 si_code; - int32 si_pid; - uint32 si_uid; - int32 si_status; - void *si_addr; - Sigval si_value; - int64 si_band; - uint64 __pad[7]; -}; - -typedef struct Timeval Timeval; -struct Timeval { - int64 tv_sec; - int32 tv_usec; - byte pad_godefs_0[4]; -}; - -typedef struct Itimerval Itimerval; -struct Itimerval { - Timeval it_interval; - Timeval it_value; -}; - -typedef struct FPControl FPControl; -struct FPControl { - byte pad_godefs_0[2]; -}; - -typedef struct FPStatus FPStatus; -struct FPStatus { - byte pad_godefs_0[2]; -}; - -typedef struct RegMMST RegMMST; -struct RegMMST { - int8 mmst_reg[10]; - int8 mmst_rsrv[6]; -}; - -typedef struct RegXMM RegXMM; -struct RegXMM { - int8 xmm_reg[16]; -}; - -typedef struct Regs Regs; -struct Regs { - uint64 rax; - uint64 rbx; - uint64 rcx; - uint64 rdx; - uint64 rdi; - uint64 rsi; - uint64 rbp; - uint64 rsp; - uint64 r8; - uint64 r9; - uint64 r10; - uint64 r11; - uint64 r12; - uint64 r13; - uint64 r14; - uint64 r15; - uint64 rip; - uint64 rflags; - uint64 cs; - uint64 fs; - uint64 gs; -}; - -typedef struct FloatState FloatState; -struct FloatState { - uint64 fpu_reserved; - FPControl fpu_fcw; - FPStatus fpu_fsw; - uint8 fpu_ftw; - uint8 fpu_rsrv1; - uint16 fpu_fop; - uint32 fpu_ip; - uint16 fpu_cs; - uint16 fpu_rsrv2; - uint32 fpu_dp; - uint16 fpu_ds; - uint16 fpu_rsrv3; - uint32 fpu_mxcsr; - uint32 fpu_mxcsrmask; - RegMMST fpu_stmm0; - RegMMST fpu_stmm1; - RegMMST fpu_stmm2; - RegMMST fpu_stmm3; - RegMMST fpu_stmm4; - RegMMST fpu_stmm5; - RegMMST fpu_stmm6; - RegMMST fpu_stmm7; - RegXMM fpu_xmm0; - RegXMM fpu_xmm1; - RegXMM fpu_xmm2; - RegXMM fpu_xmm3; - RegXMM fpu_xmm4; - RegXMM fpu_xmm5; - RegXMM fpu_xmm6; - RegXMM fpu_xmm7; - RegXMM fpu_xmm8; - RegXMM fpu_xmm9; - RegXMM fpu_xmm10; - RegXMM fpu_xmm11; - RegXMM fpu_xmm12; - RegXMM fpu_xmm13; - RegXMM fpu_xmm14; - RegXMM fpu_xmm15; - int8 fpu_rsrv4[96]; - int32 fpu_reserved1; -}; - -typedef struct ExceptionState ExceptionState; -struct ExceptionState { - uint32 trapno; - uint32 err; - uint64 faultvaddr; -}; - -typedef struct Mcontext Mcontext; -struct Mcontext { - ExceptionState es; - Regs ss; - FloatState fs; - byte pad_godefs_0[4]; -}; - -typedef struct Ucontext Ucontext; -struct Ucontext { - int32 uc_onstack; - uint32 uc_sigmask; - StackT uc_stack; - uint64 uc_link; - uint64 uc_mcsize; - Mcontext *uc_mcontext; -}; -#pragma pack off diff --git a/src/pkg/runtime/darwin/amd64/rt0.s b/src/pkg/runtime/darwin/amd64/rt0.s deleted file mode 100644 index 4cfab5876..000000000 --- a/src/pkg/runtime/darwin/amd64/rt0.s +++ /dev/null @@ -1,10 +0,0 @@ -// 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. - -// Darwin and Linux use the same linkage to main - -TEXT _rt0_amd64_darwin(SB),7,$-8 - MOVQ $_rt0_amd64(SB), AX - MOVQ SP, DI - JMP AX diff --git a/src/pkg/runtime/darwin/amd64/signal.c b/src/pkg/runtime/darwin/amd64/signal.c deleted file mode 100644 index 036a3aca7..000000000 --- a/src/pkg/runtime/darwin/amd64/signal.c +++ /dev/null @@ -1,204 +0,0 @@ -// 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. - -#include "runtime.h" -#include "defs.h" -#include "os.h" -#include "signals.h" - -void -runtime·dumpregs(Regs *r) -{ - runtime·printf("rax %X\n", r->rax); - runtime·printf("rbx %X\n", r->rbx); - runtime·printf("rcx %X\n", r->rcx); - runtime·printf("rdx %X\n", r->rdx); - runtime·printf("rdi %X\n", r->rdi); - runtime·printf("rsi %X\n", r->rsi); - runtime·printf("rbp %X\n", r->rbp); - runtime·printf("rsp %X\n", r->rsp); - runtime·printf("r8 %X\n", r->r8 ); - runtime·printf("r9 %X\n", r->r9 ); - runtime·printf("r10 %X\n", r->r10); - runtime·printf("r11 %X\n", r->r11); - runtime·printf("r12 %X\n", r->r12); - runtime·printf("r13 %X\n", r->r13); - runtime·printf("r14 %X\n", r->r14); - runtime·printf("r15 %X\n", r->r15); - runtime·printf("rip %X\n", r->rip); - runtime·printf("rflags %X\n", r->rflags); - runtime·printf("cs %X\n", r->cs); - runtime·printf("fs %X\n", r->fs); - runtime·printf("gs %X\n", r->gs); -} - -String -runtime·signame(int32 sig) -{ - if(sig < 0 || sig >= NSIG) - return runtime·emptystring; - return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name); -} - -void -runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp) -{ - Ucontext *uc; - Mcontext *mc; - Regs *r; - uintptr *sp; - byte *pc; - - uc = context; - mc = uc->uc_mcontext; - r = &mc->ss; - - if(sig == SIGPROF) { - runtime·sigprof((uint8*)r->rip, (uint8*)r->rsp, nil, gp); - return; - } - - if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) { - // Work around Leopard bug that doesn't set FPE_INTDIV. - // Look at instruction to see if it is a divide. - // Not necessary in Snow Leopard (si_code will be != 0). - if(sig == SIGFPE && info->si_code == 0) { - pc = (byte*)r->rip; - if((pc[0]&0xF0) == 0x40) // 64-bit REX prefix - pc++; - else if(pc[0] == 0x66) // 16-bit instruction prefix - pc++; - if(pc[0] == 0xF6 || pc[0] == 0xF7) - info->si_code = FPE_INTDIV; - } - - // Make it look like a call to the signal func. - // Have to pass arguments out of band since - // augmenting the stack frame would break - // the unwinding code. - gp->sig = sig; - gp->sigcode0 = info->si_code; - gp->sigcode1 = (uintptr)info->si_addr; - gp->sigpc = r->rip; - - // Only push runtime·sigpanic if r->rip != 0. - // If r->rip == 0, probably panicked because of a - // call to a nil func. Not pushing that onto sp will - // make the trace look like a call to runtime·sigpanic instead. - // (Otherwise the trace will end at runtime·sigpanic and we - // won't get to see who faulted.) - if(r->rip != 0) { - sp = (uintptr*)r->rsp; - *--sp = r->rip; - r->rsp = (uintptr)sp; - } - r->rip = (uintptr)runtime·sigpanic; - return; - } - - if(runtime·sigtab[sig].flags & SigQueue) { - if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore)) - return; - runtime·exit(2); // SIGINT, SIGTERM, etc - } - - if(runtime·panicking) // traceback already printed - runtime·exit(2); - runtime·panicking = 1; - - if(sig < 0 || sig >= NSIG){ - runtime·printf("Signal %d\n", sig); - }else{ - runtime·printf("%s\n", runtime·sigtab[sig].name); - } - - runtime·printf("pc: %X\n", r->rip); - runtime·printf("\n"); - - if(runtime·gotraceback()){ - runtime·traceback((void*)r->rip, (void*)r->rsp, 0, gp); - runtime·tracebackothers(gp); - runtime·dumpregs(r); - } - - runtime·exit(2); -} - -void -runtime·sigignore(int32, Siginfo*, void*) -{ -} - -void -runtime·signalstack(byte *p, int32 n) -{ - StackT st; - - st.ss_sp = p; - st.ss_size = n; - st.ss_flags = 0; - runtime·sigaltstack(&st, nil); -} - -static void -sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart) -{ - Sigaction sa; - - runtime·memclr((byte*)&sa, sizeof sa); - sa.sa_flags = SA_SIGINFO|SA_ONSTACK; - if(restart) - sa.sa_flags |= SA_RESTART; - sa.sa_mask = ~0ULL; - sa.sa_tramp = (uintptr)runtime·sigtramp; // runtime·sigtramp's job is to call into real handler - sa.__sigaction_u.__sa_sigaction = (uintptr)fn; - runtime·sigaction(i, &sa, nil); -} - -void -runtime·initsig(int32 queue) -{ - int32 i; - void *fn; - - runtime·siginit(); - - for(i = 0; i<NSIG; i++) { - if(runtime·sigtab[i].flags) { - if((runtime·sigtab[i].flags & SigQueue) != queue) - continue; - if(runtime·sigtab[i].flags & (SigCatch | SigQueue)) - fn = runtime·sighandler; - else - fn = runtime·sigignore; - sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0); - } - } -} - -void -runtime·resetcpuprofiler(int32 hz) -{ - Itimerval it; - - runtime·memclr((byte*)&it, sizeof it); - if(hz == 0) { - runtime·setitimer(ITIMER_PROF, &it, nil); - sigaction(SIGPROF, SIG_IGN, true); - } else { - sigaction(SIGPROF, runtime·sighandler, true); - it.it_interval.tv_sec = 0; - it.it_interval.tv_usec = 1000000 / hz; - it.it_value = it.it_interval; - runtime·setitimer(ITIMER_PROF, &it, nil); - } - m->profilehz = hz; -} - -void -os·sigpipe(void) -{ - sigaction(SIGPIPE, SIG_DFL, false); - runtime·raisesigpipe(); -} diff --git a/src/pkg/runtime/darwin/amd64/sys.s b/src/pkg/runtime/darwin/amd64/sys.s deleted file mode 100644 index 8d1b20f11..000000000 --- a/src/pkg/runtime/darwin/amd64/sys.s +++ /dev/null @@ -1,295 +0,0 @@ -// 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, Darwin -// See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228 -// or /usr/include/sys/syscall.h (on a Mac) for system call numbers. -// -// The low 24 bits are the system call number. -// The high 8 bits specify the kind of system call: 1=Mach, 2=BSD, 3=Machine-Dependent. -// - -#include "amd64/asm.h" - -// Exit the entire program (like C exit) -TEXT runtime·exit(SB),7,$0 - MOVL 8(SP), DI // arg 1 exit status - MOVL $(0x2000000+1), AX // syscall entry - SYSCALL - CALL runtime·notok(SB) - RET - -// Exit this OS thread (like pthread_exit, which eventually -// calls __bsdthread_terminate). -TEXT runtime·exit1(SB),7,$0 - MOVL 8(SP), DI // arg 1 exit status - MOVL $(0x2000000+361), AX // syscall entry - SYSCALL - CALL runtime·notok(SB) - RET - -TEXT runtime·write(SB),7,$0 - MOVL 8(SP), DI // arg 1 fd - MOVQ 16(SP), SI // arg 2 buf - MOVL 24(SP), DX // arg 3 count - MOVL $(0x2000000+4), AX // syscall entry - SYSCALL - RET - -TEXT runtime·raisesigpipe(SB),7,$24 - get_tls(CX) - MOVQ m(CX), DX - MOVL $13, DI // arg 1 SIGPIPE - MOVQ m_procid(DX), SI // arg 2 thread_port - MOVL $(0x2000000+328), AX // syscall entry __pthread_kill - SYSCALL - RET - -TEXT runtime·setitimer(SB), 7, $0 - MOVL 8(SP), DI - MOVQ 16(SP), SI - MOVQ 24(SP), DX - MOVL $(0x2000000+83), AX // syscall entry - SYSCALL - RET - -// void gettime(int64 *sec, int32 *usec) -TEXT runtime·gettime(SB), 7, $32 - MOVQ SP, DI // must be non-nil, unused - MOVQ $0, SI - MOVL $(0x2000000+116), AX - SYSCALL - MOVQ sec+0(FP), DI - MOVQ AX, (DI) - MOVQ usec+8(FP), DI - MOVL DX, (DI) - RET - -TEXT runtime·sigaction(SB),7,$0 - MOVL 8(SP), DI // arg 1 sig - MOVQ 16(SP), SI // arg 2 act - MOVQ 24(SP), DX // arg 3 oact - MOVQ 24(SP), CX // arg 3 oact - MOVQ 24(SP), R10 // arg 3 oact - MOVL $(0x2000000+46), AX // syscall entry - SYSCALL - JCC 2(PC) - CALL runtime·notok(SB) - RET - -TEXT runtime·sigtramp(SB),7,$64 - get_tls(BX) - - // save g - MOVQ g(BX), R10 - MOVQ R10, 48(SP) - - // g = m->gsignal - MOVQ m(BX), BP - MOVQ m_gsignal(BP), BP - MOVQ BP, g(BX) - - MOVL DX, 0(SP) - MOVQ CX, 8(SP) - MOVQ R8, 16(SP) - MOVQ R10, 24(SP) - - MOVQ R8, 32(SP) // save ucontext - MOVQ SI, 40(SP) // save infostyle - CALL DI - - // restore g - get_tls(BX) - MOVQ 48(SP), R10 - MOVQ R10, g(BX) - - // call sigreturn - MOVL $(0x2000000+184), AX // sigreturn(ucontext, infostyle) - MOVQ 32(SP), DI // saved ucontext - MOVQ 40(SP), SI // saved infostyle - SYSCALL - INT $3 // not reached - -TEXT runtime·mmap(SB),7,$0 - MOVQ 8(SP), DI // arg 1 addr - MOVQ 16(SP), SI // arg 2 len - MOVL 24(SP), DX // arg 3 prot - MOVL 28(SP), R10 // arg 4 flags - MOVL 32(SP), R8 // arg 5 fid - MOVL 36(SP), R9 // arg 6 offset - MOVL $(0x2000000+197), AX // syscall entry - SYSCALL - RET - -TEXT runtime·munmap(SB),7,$0 - MOVQ 8(SP), DI // arg 1 addr - MOVQ 16(SP), SI // arg 2 len - MOVL $(0x2000000+73), AX // syscall entry - SYSCALL - JCC 2(PC) - CALL runtime·notok(SB) - RET - -TEXT runtime·notok(SB),7,$0 - MOVL $0xf1, BP - MOVQ BP, (BP) - RET - -TEXT runtime·sigaltstack(SB),7,$0 - MOVQ new+8(SP), DI - MOVQ old+16(SP), SI - MOVQ $(0x2000000+53), AX - SYSCALL - JCC 2(PC) - CALL runtime·notok(SB) - RET - -// void bsdthread_create(void *stk, M *m, G *g, void (*fn)(void)) -TEXT runtime·bsdthread_create(SB),7,$0 - // Set up arguments to bsdthread_create system call. - // The ones in quotes pass through to the thread callback - // uninterpreted, so we can put whatever we want there. - MOVQ fn+32(SP), DI // "func" - MOVQ mm+16(SP), SI // "arg" - MOVQ stk+8(SP), DX // stack - MOVQ gg+24(SP), R10 // "pthread" - MOVQ $0x01000000, R8 // flags = PTHREAD_START_CUSTOM - MOVQ $0, R9 // paranoia - MOVQ $(0x2000000+360), AX // bsdthread_create - SYSCALL - JCC 3(PC) - NEGL AX - RET - MOVL $0, AX - RET - -// The thread that bsdthread_create creates starts executing here, -// because we registered this function using bsdthread_register -// at startup. -// DI = "pthread" -// SI = mach thread port -// DX = "func" (= fn) -// CX = "arg" (= m) -// R8 = stack -// R9 = flags (= 0) -// SP = stack - C_64_REDZONE_LEN (= stack - 128) -TEXT runtime·bsdthread_start(SB),7,$0 - MOVQ R8, SP // empirically, SP is very wrong but R8 is right - - PUSHQ DX - PUSHQ CX - PUSHQ SI - - // set up thread local storage pointing at m->tls. - LEAQ m_tls(CX), DI - CALL runtime·settls(SB) - - POPQ SI - POPQ CX - POPQ DX - - get_tls(BX) - MOVQ CX, m(BX) - MOVQ SI, m_procid(CX) // thread port is m->procid - MOVQ m_g0(CX), AX - MOVQ AX, g(BX) - CALL runtime·stackcheck(SB) // smashes AX, CX - CALL DX // fn - CALL runtime·exit1(SB) - RET - -// void bsdthread_register(void) -// registers callbacks for threadstart (see bsdthread_create above -// and wqthread and pthsize (not used). returns 0 on success. -TEXT runtime·bsdthread_register(SB),7,$0 - MOVQ $runtime·bsdthread_start(SB), DI // threadstart - MOVQ $0, SI // wqthread, not used by us - MOVQ $0, DX // pthsize, not used by us - MOVQ $0, R10 // dummy_value [sic] - MOVQ $0, R8 // targetconc_ptr - MOVQ $0, R9 // dispatchqueue_offset - MOVQ $(0x2000000+366), AX // bsdthread_register - SYSCALL - JCC 2(PC) - CALL runtime·notok(SB) - RET - -// Mach system calls use 0x1000000 instead of the BSD's 0x2000000. - -// uint32 mach_msg_trap(void*, uint32, uint32, uint32, uint32, uint32, uint32) -TEXT runtime·mach_msg_trap(SB),7,$0 - MOVQ 8(SP), DI - MOVL 16(SP), SI - MOVL 20(SP), DX - MOVL 24(SP), R10 - MOVL 28(SP), R8 - MOVL 32(SP), R9 - MOVL 36(SP), R11 - PUSHQ R11 // seventh arg, on stack - MOVL $(0x1000000+31), AX // mach_msg_trap - SYSCALL - POPQ R11 - RET - -TEXT runtime·mach_task_self(SB),7,$0 - MOVL $(0x1000000+28), AX // task_self_trap - SYSCALL - RET - -TEXT runtime·mach_thread_self(SB),7,$0 - MOVL $(0x1000000+27), AX // thread_self_trap - SYSCALL - RET - -TEXT runtime·mach_reply_port(SB),7,$0 - MOVL $(0x1000000+26), AX // mach_reply_port - SYSCALL - RET - -// Mach provides trap versions of the semaphore ops, -// instead of requiring the use of RPC. - -// uint32 mach_semaphore_wait(uint32) -TEXT runtime·mach_semaphore_wait(SB),7,$0 - MOVL 8(SP), DI - MOVL $(0x1000000+36), AX // semaphore_wait_trap - SYSCALL - RET - -// uint32 mach_semaphore_timedwait(uint32, uint32, uint32) -TEXT runtime·mach_semaphore_timedwait(SB),7,$0 - MOVL 8(SP), DI - MOVL 12(SP), SI - MOVL 16(SP), DX - MOVL $(0x1000000+38), AX // semaphore_timedwait_trap - SYSCALL - RET - -// uint32 mach_semaphore_signal(uint32) -TEXT runtime·mach_semaphore_signal(SB),7,$0 - MOVL 8(SP), DI - MOVL $(0x1000000+33), AX // semaphore_signal_trap - SYSCALL - RET - -// uint32 mach_semaphore_signal_all(uint32) -TEXT runtime·mach_semaphore_signal_all(SB),7,$0 - MOVL 8(SP), DI - MOVL $(0x1000000+34), AX // semaphore_signal_all_trap - SYSCALL - RET - -// set tls base to DI -TEXT runtime·settls(SB),7,$32 - /* - * Same as in ../386/sys.s:/ugliness, different constant. - * See ../../../../libcgo/darwin_amd64.c for the derivation - * of the constant. - */ - SUBQ $0x8a0, DI - - MOVL $(0x3000000+3), AX // thread_fast_set_cthread_self - machdep call #3 - SYSCALL - RET diff --git a/src/pkg/runtime/darwin/defs.c b/src/pkg/runtime/darwin/defs.c deleted file mode 100644 index 032a6bcbb..000000000 --- a/src/pkg/runtime/darwin/defs.c +++ /dev/null @@ -1,159 +0,0 @@ -// 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. - -/* - * Input to godefs. - * - godefs -f -m64 defs.c >amd64/defs.h - godefs -f -m32 defs.c >386/defs.h - */ - -#define __DARWIN_UNIX03 0 - -#include <mach/mach.h> -#include <mach/message.h> -#include <sys/types.h> -#include <sys/time.h> -#include <signal.h> -#include <sys/mman.h> - -enum { - $PROT_NONE = PROT_NONE, - $PROT_READ = PROT_READ, - $PROT_WRITE = PROT_WRITE, - $PROT_EXEC = PROT_EXEC, - - $MAP_ANON = MAP_ANON, - $MAP_PRIVATE = MAP_PRIVATE, - $MAP_FIXED = MAP_FIXED, - - $MACH_MSG_TYPE_MOVE_RECEIVE = MACH_MSG_TYPE_MOVE_RECEIVE, - $MACH_MSG_TYPE_MOVE_SEND = MACH_MSG_TYPE_MOVE_SEND, - $MACH_MSG_TYPE_MOVE_SEND_ONCE = MACH_MSG_TYPE_MOVE_SEND_ONCE, - $MACH_MSG_TYPE_COPY_SEND = MACH_MSG_TYPE_COPY_SEND, - $MACH_MSG_TYPE_MAKE_SEND = MACH_MSG_TYPE_MAKE_SEND, - $MACH_MSG_TYPE_MAKE_SEND_ONCE = MACH_MSG_TYPE_MAKE_SEND_ONCE, - $MACH_MSG_TYPE_COPY_RECEIVE = MACH_MSG_TYPE_COPY_RECEIVE, - - $MACH_MSG_PORT_DESCRIPTOR = MACH_MSG_PORT_DESCRIPTOR, - $MACH_MSG_OOL_DESCRIPTOR = MACH_MSG_OOL_DESCRIPTOR, - $MACH_MSG_OOL_PORTS_DESCRIPTOR = MACH_MSG_OOL_PORTS_DESCRIPTOR, - $MACH_MSG_OOL_VOLATILE_DESCRIPTOR = MACH_MSG_OOL_VOLATILE_DESCRIPTOR, - - $MACH_MSGH_BITS_COMPLEX = MACH_MSGH_BITS_COMPLEX, - - $MACH_SEND_MSG = MACH_SEND_MSG, - $MACH_RCV_MSG = MACH_RCV_MSG, - $MACH_RCV_LARGE = MACH_RCV_LARGE, - - $MACH_SEND_TIMEOUT = MACH_SEND_TIMEOUT, - $MACH_SEND_INTERRUPT = MACH_SEND_INTERRUPT, - $MACH_SEND_CANCEL = MACH_SEND_CANCEL, - $MACH_SEND_ALWAYS = MACH_SEND_ALWAYS, - $MACH_SEND_TRAILER = MACH_SEND_TRAILER, - $MACH_RCV_TIMEOUT = MACH_RCV_TIMEOUT, - $MACH_RCV_NOTIFY = MACH_RCV_NOTIFY, - $MACH_RCV_INTERRUPT = MACH_RCV_INTERRUPT, - $MACH_RCV_OVERWRITE = MACH_RCV_OVERWRITE, - - $NDR_PROTOCOL_2_0 = NDR_PROTOCOL_2_0, - $NDR_INT_BIG_ENDIAN = NDR_INT_BIG_ENDIAN, - $NDR_INT_LITTLE_ENDIAN = NDR_INT_LITTLE_ENDIAN, - $NDR_FLOAT_IEEE = NDR_FLOAT_IEEE, - $NDR_CHAR_ASCII = NDR_CHAR_ASCII, - - $SA_SIGINFO = SA_SIGINFO, - $SA_RESTART = SA_RESTART, - $SA_ONSTACK = SA_ONSTACK, - $SA_USERTRAMP = SA_USERTRAMP, - $SA_64REGSET = SA_64REGSET, - - $SIGHUP = SIGHUP, - $SIGINT = SIGINT, - $SIGQUIT = SIGQUIT, - $SIGILL = SIGILL, - $SIGTRAP = SIGTRAP, - $SIGABRT = SIGABRT, - $SIGEMT = SIGEMT, - $SIGFPE = SIGFPE, - $SIGKILL = SIGKILL, - $SIGBUS = SIGBUS, - $SIGSEGV = SIGSEGV, - $SIGSYS = SIGSYS, - $SIGPIPE = SIGPIPE, - $SIGALRM = SIGALRM, - $SIGTERM = SIGTERM, - $SIGURG = SIGURG, - $SIGSTOP = SIGSTOP, - $SIGTSTP = SIGTSTP, - $SIGCONT = SIGCONT, - $SIGCHLD = SIGCHLD, - $SIGTTIN = SIGTTIN, - $SIGTTOU = SIGTTOU, - $SIGIO = SIGIO, - $SIGXCPU = SIGXCPU, - $SIGXFSZ = SIGXFSZ, - $SIGVTALRM = SIGVTALRM, - $SIGPROF = SIGPROF, - $SIGWINCH = SIGWINCH, - $SIGINFO = SIGINFO, - $SIGUSR1 = SIGUSR1, - $SIGUSR2 = SIGUSR2, - - $FPE_INTDIV = FPE_INTDIV, - $FPE_INTOVF = FPE_INTOVF, - $FPE_FLTDIV = FPE_FLTDIV, - $FPE_FLTOVF = FPE_FLTOVF, - $FPE_FLTUND = FPE_FLTUND, - $FPE_FLTRES = FPE_FLTRES, - $FPE_FLTINV = FPE_FLTINV, - $FPE_FLTSUB = FPE_FLTSUB, - - $BUS_ADRALN = BUS_ADRALN, - $BUS_ADRERR = BUS_ADRERR, - $BUS_OBJERR = BUS_OBJERR, - - $SEGV_MAPERR = SEGV_MAPERR, - $SEGV_ACCERR = SEGV_ACCERR, - - $ITIMER_REAL = ITIMER_REAL, - $ITIMER_VIRTUAL = ITIMER_VIRTUAL, - $ITIMER_PROF = ITIMER_PROF, -}; - -typedef mach_msg_body_t $MachBody; -typedef mach_msg_header_t $MachHeader; -typedef NDR_record_t $MachNDR; -typedef mach_msg_port_descriptor_t $MachPort; - -typedef stack_t $StackT; -typedef union __sigaction_u $Sighandler; - -typedef struct __sigaction $Sigaction; // used in syscalls -// typedef struct sigaction $Sigaction; // used by the C library -typedef union sigval $Sigval; -typedef siginfo_t $Siginfo; -typedef struct timeval $Timeval; -typedef struct itimerval $Itimerval; - -typedef struct fp_control $FPControl; -typedef struct fp_status $FPStatus; -typedef struct mmst_reg $RegMMST; -typedef struct xmm_reg $RegXMM; - -#ifdef __LP64__ -// amd64 -typedef x86_thread_state64_t $Regs; -typedef x86_float_state64_t $FloatState; -typedef x86_exception_state64_t $ExceptionState; -typedef struct mcontext64 $Mcontext; -#else -// 386 -typedef x86_thread_state32_t $Regs; -typedef x86_float_state32_t $FloatState; -typedef x86_exception_state32_t $ExceptionState; -typedef struct mcontext32 $Mcontext; -#endif - -typedef ucontext_t $Ucontext; diff --git a/src/pkg/runtime/darwin/mem.c b/src/pkg/runtime/darwin/mem.c deleted file mode 100644 index 935c032bc..000000000 --- a/src/pkg/runtime/darwin/mem.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "runtime.h" -#include "defs.h" -#include "os.h" -#include "malloc.h" - -void* -runtime·SysAlloc(uintptr n) -{ - void *v; - - mstats.sys += n; - v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); - if(v < (void*)4096) - return nil; - return v; -} - -void -runtime·SysUnused(void *v, uintptr n) -{ - USED(v); - USED(n); - // TODO(rsc): call madvise MADV_DONTNEED -} - -void -runtime·SysFree(void *v, uintptr n) -{ - mstats.sys -= n; - runtime·munmap(v, n); -} - -void* -runtime·SysReserve(void *v, uintptr n) -{ - return runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); -} - -enum -{ - ENOMEM = 12, -}; - -void -runtime·SysMap(void *v, uintptr n) -{ - void *p; - - mstats.sys += n; - p = runtime·mmap(v, n, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0); - if(p == (void*)-ENOMEM) - runtime·throw("runtime: out of memory"); - if(p != v) - runtime·throw("runtime: cannot map pages in arena address space"); -} diff --git a/src/pkg/runtime/darwin/os.h b/src/pkg/runtime/darwin/os.h deleted file mode 100644 index db3c2e8a7..000000000 --- a/src/pkg/runtime/darwin/os.h +++ /dev/null @@ -1,31 +0,0 @@ -// 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. - -#define SIG_DFL ((void*)0) -#define SIG_IGN ((void*)1) - -int32 runtime·bsdthread_create(void*, M*, G*, void(*)(void)); -void runtime·bsdthread_register(void); -int32 runtime·mach_msg_trap(MachHeader*, int32, uint32, uint32, uint32, uint32, uint32); -uint32 runtime·mach_reply_port(void); -void runtime·mach_semacquire(uint32); -uint32 runtime·mach_semcreate(void); -void runtime·mach_semdestroy(uint32); -void runtime·mach_semrelease(uint32); -void runtime·mach_semreset(uint32); -uint32 runtime·mach_task_self(void); -uint32 runtime·mach_task_self(void); -uint32 runtime·mach_thread_self(void); -uint32 runtime·mach_thread_self(void); - -struct Sigaction; -void runtime·sigaction(uintptr, struct Sigaction*, struct Sigaction*); - -struct StackT; -void runtime·sigaltstack(struct StackT*, struct StackT*); -void runtime·sigtramp(void); -void runtime·sigpanic(void); -void runtime·setitimer(int32, Itimerval*, Itimerval*); - -void runtime·raisesigpipe(void); diff --git a/src/pkg/runtime/darwin/signals.h b/src/pkg/runtime/darwin/signals.h deleted file mode 100644 index 035027fad..000000000 --- a/src/pkg/runtime/darwin/signals.h +++ /dev/null @@ -1,51 +0,0 @@ -// 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. - -#define C SigCatch -#define I SigIgnore -#define R SigRestart -#define Q SigQueue -#define P SigPanic - -SigTab runtime·sigtab[] = { - /* 0 */ 0, "SIGNONE: no trap", - /* 1 */ Q+R, "SIGHUP: terminal line hangup", - /* 2 */ Q+R, "SIGINT: interrupt", - /* 3 */ C, "SIGQUIT: quit", - /* 4 */ C, "SIGILL: illegal instruction", - /* 5 */ C, "SIGTRAP: trace trap", /* used by panic and array out of bounds, etc. */ - /* 6 */ C, "SIGABRT: abort", - /* 7 */ C, "SIGEMT: emulate instruction executed", - /* 8 */ C+P, "SIGFPE: floating-point exception", - /* 9 */ 0, "SIGKILL: kill", - /* 10 */ C+P, "SIGBUS: bus error", - /* 11 */ C+P, "SIGSEGV: segmentation violation", - /* 12 */ C, "SIGSYS: bad system call", - /* 13 */ I, "SIGPIPE: write to broken pipe", - /* 14 */ Q+I+R, "SIGALRM: alarm clock", - /* 15 */ Q+R, "SIGTERM: termination", - /* 16 */ Q+I+R, "SIGURG: urgent condition on socket", - /* 17 */ 0, "SIGSTOP: stop", - /* 18 */ Q+I+R, "SIGTSTP: keyboard stop", - /* 19 */ 0, "SIGCONT: continue after stop", - /* 20 */ Q+I+R, "SIGCHLD: child status has changed", - /* 21 */ Q+I+R, "SIGTTIN: background read from tty", - /* 22 */ Q+I+R, "SIGTTOU: background write to tty", - /* 23 */ Q+I+R, "SIGIO: i/o now possible", - /* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded", - /* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded", - /* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock", - /* 27 */ Q+I+R, "SIGPROF: profiling alarm clock", - /* 28 */ Q+I+R, "SIGWINCH: window size change", - /* 29 */ Q+I+R, "SIGINFO: status request from keyboard", - /* 30 */ Q+I+R, "SIGUSR1: user-defined signal 1", - /* 31 */ Q+I+R, "SIGUSR2: user-defined signal 2", -}; -#undef C -#undef I -#undef R -#undef Q -#undef P - -#define NSIG 32 diff --git a/src/pkg/runtime/darwin/thread.c b/src/pkg/runtime/darwin/thread.c deleted file mode 100644 index 6733e815e..000000000 --- a/src/pkg/runtime/darwin/thread.c +++ /dev/null @@ -1,484 +0,0 @@ -// 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. - -#include "runtime.h" -#include "defs.h" -#include "os.h" -#include "stack.h" - -extern SigTab runtime·sigtab[]; - -static void -unimplemented(int8 *name) -{ - runtime·prints(name); - runtime·prints(" not implemented\n"); - *(int32*)1231 = 1231; -} - -// Thread-safe allocation of a semaphore. -// Psema points at a kernel semaphore key. -// It starts out zero, meaning no semaphore. -// Fill it in, being careful of others calling initsema -// simultaneously. -static void -initsema(uint32 *psema) -{ - uint32 sema; - - if(*psema != 0) // already have one - return; - - sema = runtime·mach_semcreate(); - if(!runtime·cas(psema, 0, sema)){ - // Someone else filled it in. Use theirs. - runtime·mach_semdestroy(sema); - return; - } -} - - -// Blocking locks. - -// Implement Locks, using semaphores. -// l->key is the number of threads who want the lock. -// In a race, one thread increments l->key from 0 to 1 -// and the others increment it from >0 to >1. The thread -// who does the 0->1 increment gets the lock, and the -// others wait on the semaphore. When the 0->1 thread -// releases the lock by decrementing l->key, l->key will -// be >0, so it will increment the semaphore to wake up -// one of the others. This is the same algorithm used -// in Plan 9's user-level locks. - -void -runtime·lock(Lock *l) -{ - if(m->locks < 0) - runtime·throw("lock count"); - m->locks++; - - if(runtime·xadd(&l->key, 1) > 1) { // someone else has it; wait - // Allocate semaphore if needed. - if(l->sema == 0) - initsema(&l->sema); - runtime·mach_semacquire(l->sema); - } -} - -void -runtime·unlock(Lock *l) -{ - m->locks--; - if(m->locks < 0) - runtime·throw("lock count"); - - if(runtime·xadd(&l->key, -1) > 0) { // someone else is waiting - // Allocate semaphore if needed. - if(l->sema == 0) - initsema(&l->sema); - runtime·mach_semrelease(l->sema); - } -} - -static void -destroylock(Lock *l) -{ - if(l->sema != 0) { - runtime·mach_semdestroy(l->sema); - l->sema = 0; - } -} - -// User-level semaphore implementation: -// try to do the operations in user space on u, -// but when it's time to block, fall back on the kernel semaphore k. -// This is the same algorithm used in Plan 9. -void -runtime·usemacquire(Usema *s) -{ - if((int32)runtime·xadd(&s->u, -1) < 0) { - if(s->k == 0) - initsema(&s->k); - runtime·mach_semacquire(s->k); - } -} - -void -runtime·usemrelease(Usema *s) -{ - if((int32)runtime·xadd(&s->u, 1) <= 0) { - if(s->k == 0) - initsema(&s->k); - runtime·mach_semrelease(s->k); - } -} - - -// Event notifications. -void -runtime·noteclear(Note *n) -{ - n->wakeup = 0; -} - -void -runtime·notesleep(Note *n) -{ - while(!n->wakeup) - runtime·usemacquire(&n->sema); -} - -void -runtime·notewakeup(Note *n) -{ - n->wakeup = 1; - runtime·usemrelease(&n->sema); -} - - -// BSD interface for threading. -void -runtime·osinit(void) -{ - // Register our thread-creation callback (see {amd64,386}/sys.s) - // but only if we're not using cgo. If we are using cgo we need - // to let the C pthread libary install its own thread-creation callback. - if(!runtime·iscgo) - runtime·bsdthread_register(); - runtime·destroylock = destroylock; -} - -void -runtime·goenvs(void) -{ - runtime·goenvs_unix(); -} - -void -runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)) -{ - int32 errno; - - m->tls[0] = m->id; // so 386 asm can find it - if(0){ - runtime·printf("newosproc stk=%p m=%p g=%p fn=%p id=%d/%d ostk=%p\n", - stk, m, g, fn, m->id, m->tls[0], &m); - } - if((errno = runtime·bsdthread_create(stk, m, g, fn)) < 0) { - runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), -errno); - runtime·throw("runtime.newosproc"); - } -} - -// Called to initialize a new m (including the bootstrap m). -void -runtime·minit(void) -{ - // Initialize signal handling. - m->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K - runtime·signalstack(m->gsignal->stackguard - StackGuard, 32*1024); -} - -// Mach IPC, to get at semaphores -// Definitions are in /usr/include/mach on a Mac. - -static void -macherror(int32 r, int8 *fn) -{ - runtime·printf("mach error %s: %d\n", fn, r); - runtime·throw("mach error"); -} - -enum -{ - DebugMach = 0 -}; - -static MachNDR zerondr; - -#define MACH_MSGH_BITS(a, b) ((a) | ((b)<<8)) - -static int32 -mach_msg(MachHeader *h, - int32 op, - uint32 send_size, - uint32 rcv_size, - uint32 rcv_name, - uint32 timeout, - uint32 notify) -{ - // TODO: Loop on interrupt. - return runtime·mach_msg_trap(h, op, send_size, rcv_size, rcv_name, timeout, notify); -} - -// Mach RPC (MIG) - -enum -{ - MinMachMsg = 48, - Reply = 100, -}; - -#pragma pack on -typedef struct CodeMsg CodeMsg; -struct CodeMsg -{ - MachHeader h; - MachNDR NDR; - int32 code; -}; -#pragma pack off - -static int32 -machcall(MachHeader *h, int32 maxsize, int32 rxsize) -{ - uint32 *p; - int32 i, ret, id; - uint32 port; - CodeMsg *c; - - if((port = m->machport) == 0){ - port = runtime·mach_reply_port(); - m->machport = port; - } - - h->msgh_bits |= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); - h->msgh_local_port = port; - h->msgh_reserved = 0; - id = h->msgh_id; - - if(DebugMach){ - p = (uint32*)h; - runtime·prints("send:\t"); - for(i=0; i<h->msgh_size/sizeof(p[0]); i++){ - runtime·prints(" "); - runtime·printpointer((void*)p[i]); - if(i%8 == 7) - runtime·prints("\n\t"); - } - if(i%8) - runtime·prints("\n"); - } - - ret = mach_msg(h, MACH_SEND_MSG|MACH_RCV_MSG, - h->msgh_size, maxsize, port, 0, 0); - if(ret != 0){ - if(DebugMach){ - runtime·prints("mach_msg error "); - runtime·printint(ret); - runtime·prints("\n"); - } - return ret; - } - - if(DebugMach){ - p = (uint32*)h; - runtime·prints("recv:\t"); - for(i=0; i<h->msgh_size/sizeof(p[0]); i++){ - runtime·prints(" "); - runtime·printpointer((void*)p[i]); - if(i%8 == 7) - runtime·prints("\n\t"); - } - if(i%8) - runtime·prints("\n"); - } - - if(h->msgh_id != id+Reply){ - if(DebugMach){ - runtime·prints("mach_msg reply id mismatch "); - runtime·printint(h->msgh_id); - runtime·prints(" != "); - runtime·printint(id+Reply); - runtime·prints("\n"); - } - return -303; // MIG_REPLY_MISMATCH - } - - // Look for a response giving the return value. - // Any call can send this back with an error, - // and some calls only have return values so they - // send it back on success too. I don't quite see how - // you know it's one of these and not the full response - // format, so just look if the message is right. - c = (CodeMsg*)h; - if(h->msgh_size == sizeof(CodeMsg) - && !(h->msgh_bits & MACH_MSGH_BITS_COMPLEX)){ - if(DebugMach){ - runtime·prints("mig result "); - runtime·printint(c->code); - runtime·prints("\n"); - } - return c->code; - } - - if(h->msgh_size != rxsize){ - if(DebugMach){ - runtime·prints("mach_msg reply size mismatch "); - runtime·printint(h->msgh_size); - runtime·prints(" != "); - runtime·printint(rxsize); - runtime·prints("\n"); - } - return -307; // MIG_ARRAY_TOO_LARGE - } - - return 0; -} - - -// Semaphores! - -enum -{ - Tmach_semcreate = 3418, - Rmach_semcreate = Tmach_semcreate + Reply, - - Tmach_semdestroy = 3419, - Rmach_semdestroy = Tmach_semdestroy + Reply, - - // Mach calls that get interrupted by Unix signals - // return this error code. We retry them. - KERN_ABORTED = 14, -}; - -typedef struct Tmach_semcreateMsg Tmach_semcreateMsg; -typedef struct Rmach_semcreateMsg Rmach_semcreateMsg; -typedef struct Tmach_semdestroyMsg Tmach_semdestroyMsg; -// Rmach_semdestroyMsg = CodeMsg - -#pragma pack on -struct Tmach_semcreateMsg -{ - MachHeader h; - MachNDR ndr; - int32 policy; - int32 value; -}; - -struct Rmach_semcreateMsg -{ - MachHeader h; - MachBody body; - MachPort semaphore; -}; - -struct Tmach_semdestroyMsg -{ - MachHeader h; - MachBody body; - MachPort semaphore; -}; -#pragma pack off - -uint32 -runtime·mach_semcreate(void) -{ - union { - Tmach_semcreateMsg tx; - Rmach_semcreateMsg rx; - uint8 pad[MinMachMsg]; - } m; - int32 r; - - m.tx.h.msgh_bits = 0; - m.tx.h.msgh_size = sizeof(m.tx); - m.tx.h.msgh_remote_port = runtime·mach_task_self(); - m.tx.h.msgh_id = Tmach_semcreate; - m.tx.ndr = zerondr; - - m.tx.policy = 0; // 0 = SYNC_POLICY_FIFO - m.tx.value = 0; - - while((r = machcall(&m.tx.h, sizeof m, sizeof(m.rx))) != 0){ - if(r == KERN_ABORTED) // interrupted - continue; - macherror(r, "semaphore_create"); - } - if(m.rx.body.msgh_descriptor_count != 1) - unimplemented("mach_semcreate desc count"); - return m.rx.semaphore.name; -} - -void -runtime·mach_semdestroy(uint32 sem) -{ - union { - Tmach_semdestroyMsg tx; - uint8 pad[MinMachMsg]; - } m; - int32 r; - - m.tx.h.msgh_bits = MACH_MSGH_BITS_COMPLEX; - m.tx.h.msgh_size = sizeof(m.tx); - m.tx.h.msgh_remote_port = runtime·mach_task_self(); - m.tx.h.msgh_id = Tmach_semdestroy; - m.tx.body.msgh_descriptor_count = 1; - m.tx.semaphore.name = sem; - m.tx.semaphore.disposition = MACH_MSG_TYPE_MOVE_SEND; - m.tx.semaphore.type = 0; - - while((r = machcall(&m.tx.h, sizeof m, 0)) != 0){ - if(r == KERN_ABORTED) // interrupted - continue; - macherror(r, "semaphore_destroy"); - } -} - -// The other calls have simple system call traps in sys.s -int32 runtime·mach_semaphore_wait(uint32 sema); -int32 runtime·mach_semaphore_timedwait(uint32 sema, uint32 sec, uint32 nsec); -int32 runtime·mach_semaphore_signal(uint32 sema); -int32 runtime·mach_semaphore_signal_all(uint32 sema); - -void -runtime·mach_semacquire(uint32 sem) -{ - int32 r; - - while((r = runtime·mach_semaphore_wait(sem)) != 0) { - if(r == KERN_ABORTED) // interrupted - continue; - macherror(r, "semaphore_wait"); - } -} - -void -runtime·mach_semrelease(uint32 sem) -{ - int32 r; - - while((r = runtime·mach_semaphore_signal(sem)) != 0) { - if(r == KERN_ABORTED) // interrupted - continue; - macherror(r, "semaphore_signal"); - } -} - -void -runtime·sigpanic(void) -{ - switch(g->sig) { - case SIGBUS: - if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000) - runtime·panicstring("invalid memory address or nil pointer dereference"); - runtime·printf("unexpected fault address %p\n", g->sigcode1); - runtime·throw("fault"); - case SIGSEGV: - if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000) - runtime·panicstring("invalid memory address or nil pointer dereference"); - runtime·printf("unexpected fault address %p\n", g->sigcode1); - runtime·throw("fault"); - case SIGFPE: - switch(g->sigcode0) { - case FPE_INTDIV: - runtime·panicstring("integer divide by zero"); - case FPE_INTOVF: - runtime·panicstring("integer overflow"); - } - runtime·panicstring("floating point error"); - } - runtime·panicstring(runtime·sigtab[g->sig].name); -} |