From 08cfcd1dd64d965fc319ae683638b16a1e93e075 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 24 Mar 2009 13:51:48 -0700 Subject: [PATCH] convert darwin to use godefs-generated defs.h. this change is much smaller if you ignore the machine-generated defs.h. TBR=r OCL=26684 CL=26684 --- src/runtime/Makefile | 12 +- src/runtime/darwin/amd64/defs.h | 279 ++++++++++++++++++++++++++------ src/runtime/darwin/defs.c | 104 ++++++++++++ src/runtime/darwin/os.h | 24 +++ src/runtime/darwin/signal.c | 248 ++++++---------------------- src/runtime/darwin/thread.c | 228 +++++++------------------- 6 files changed, 478 insertions(+), 417 deletions(-) create mode 100644 src/runtime/darwin/defs.c create mode 100644 src/runtime/darwin/os.h diff --git a/src/runtime/Makefile b/src/runtime/Makefile index d281a90f6ff..5bf0dbbea83 100644 --- a/src/runtime/Makefile +++ b/src/runtime/Makefile @@ -7,7 +7,7 @@ O=6 CC=$(O)c AS=$(O)a -LIB=lib_$(GOARCH)_$(GOOS).a +LIB=lib.a OFILES=\ array.$O\ @@ -41,11 +41,15 @@ OFILES=\ thread.$O\ traceback.$O\ -OS_H=$(GOARCH)_$(GOOS).h -HFILES=runtime.h hashmap.h malloc.h $(OS_H_) +HFILES=\ + runtime.h\ + hashmap.h\ + malloc.h\ + $(GOOS)/os.h\ + $(GOOS)/$(GOARCH)/defs.h\ install: $(LIB) runtime.acid - cp $(LIB) $(GOROOT)/lib + cp $(LIB) $(GOROOT)/lib_$(GOARCH)_$(GOOS).a cp runtime.acid $(GOROOT)/acid/runtime.acid $(LIB): $(OFILES) diff --git a/src/runtime/darwin/amd64/defs.h b/src/runtime/darwin/amd64/defs.h index 359b476a300..8db6c2ecacf 100644 --- a/src/runtime/darwin/amd64/defs.h +++ b/src/runtime/darwin/amd64/defs.h @@ -1,61 +1,244 @@ -/* - * System structs for Darwin, amd64 - */ +// godefs -f -m64 defs.c -typedef uint32 dev_t; -typedef uint64 ino_t; -typedef uint16 mode_t; -typedef uint16 nlink_t; -typedef uint32 uid_t; -typedef uint32 gid_t; -typedef int64 off_t; -typedef int32 blksize_t; -typedef int64 blkcnt_t; -typedef int64 time_t; +// MACHINE GENERATED - DO NOT EDIT. -struct timespec { - time_t tv_sec; - int64 tv_nsec; +// Constants +enum { + PROT_NONE = 0, + PROT_READ = 0x1, + PROT_WRITE = 0x2, + PROT_EXEC = 0x4, + MAP_ANON = 0x1000, + MAP_PRIVATE = 0x2, + 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, }; -struct timeval { - time_t tv_sec; - int64 tv_usec; +// Types +#pragma pack on + +typedef struct MachBody MachBody; +struct MachBody { + uint32 msgh_descriptor_count; }; -struct stat { // really a stat64 - dev_t st_dev; - mode_t st_mode; - nlink_t st_nlink; - ino_t st_ino; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - struct timespec st_atimespec; - struct timespec st_mtimespec; - struct timespec st_ctimespec; - struct timespec st_birthtimespec; - off_t st_size; - blkcnt_t st_blocks; - blksize_t st_blksize; - uint32 st_flags; - uint32 st_gen; - int64 st_qspare[2]; +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; }; -#define O_CREAT 0x0200 +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; +}; -void bsdthread_create(void*, M*, G*, void(*)(void)); -void bsdthread_register(void); +typedef struct MachPort MachPort; +struct MachPort { + uint32 name; + uint32 pad1; + uint32 pad2; + uint32 disposition; + uint32 type; +}; +typedef struct StackT StackT; +struct StackT { + void *ss_sp; + uint64 ss_size; + int32 ss_flags; + byte pad0[4]; +}; -// Mach calls +typedef union Sighandler Sighandler; +union Sighandler { + void *__sa_handler; + void *__sa_sigaction; +}; -typedef int32 kern_return_t; -typedef uint32 mach_port_t; +typedef struct Sigaction Sigaction; +struct Sigaction { + Sighandler __sigaction_u; + void *sa_tramp; + uint32 sa_mask; + int32 sa_flags; +}; -mach_port_t mach_semcreate(void); -void mach_semacquire(mach_port_t); -void mach_semrelease(mach_port_t); -void mach_semreset(mach_port_t); -void mach_semdestroy(mach_port_t); +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 FPControl FPControl; +struct FPControl { + byte pad0[2]; +}; + +typedef struct FPStatus FPStatus; +struct FPStatus { + byte pad0[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 { + int32 fpu_reserved[2]; + 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 pad0[4]; +}; + +typedef struct Ucontext Ucontext; +struct Ucontext { + int32 uc_onstack; + uint32 uc_sigmask; + StackT uc_stack; + Ucontext *uc_link; + uint64 uc_mcsize; + Mcontext *uc_mcontext; +}; +#pragma pack off diff --git a/src/runtime/darwin/defs.c b/src/runtime/darwin/defs.c new file mode 100644 index 00000000000..1ed662957fa --- /dev/null +++ b/src/runtime/darwin/defs.c @@ -0,0 +1,104 @@ +// 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 defs.c >386/defs.h + */ + +#define __DARWIN_UNIX03 0 + +#include +#include +#include +#include +#include +#include + +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, + + $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, +}; + +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 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/runtime/darwin/os.h b/src/runtime/darwin/os.h new file mode 100644 index 00000000000..2a3ca87bd01 --- /dev/null +++ b/src/runtime/darwin/os.h @@ -0,0 +1,24 @@ +// 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. + +void bsdthread_create(void*, M*, G*, void(*)(void)); +void bsdthread_register(void); +int32 mach_msg_trap(MachHeader*, int32, uint32, uint32, uint32, uint32, uint32); +uint32 mach_reply_port(void); +void mach_semacquire(uint32); +uint32 mach_semcreate(void); +void mach_semdestroy(uint32); +void mach_semrelease(uint32); +void mach_semreset(uint32); +uint32 mach_task_self(void); +uint32 mach_task_self(void); +uint32 mach_thread_self(void); +uint32 mach_thread_self(void); + +struct Sigaction; +void sigaction(int64, struct Sigaction*, struct Sigaction*); + +struct StackT; +void sigaltstack(struct StackT*, struct StackT*); +void sigtramp(void); diff --git a/src/runtime/darwin/signal.c b/src/runtime/darwin/signal.c index 937f402e4b1..2325b503cfe 100644 --- a/src/runtime/darwin/signal.c +++ b/src/runtime/darwin/signal.c @@ -4,204 +4,100 @@ #include "runtime.h" #include "defs.h" +#include "os.h" #include "signals.h" -typedef uint64 __uint64_t; - -/* From /usr/include/mach/i386/_structs.h */ -#define _STRUCT_X86_THREAD_STATE64 struct __darwin_x86_thread_state64 -_STRUCT_X86_THREAD_STATE64 +void +dumpregs(Regs *r) { - __uint64_t __rax; - __uint64_t __rbx; - __uint64_t __rcx; - __uint64_t __rdx; - __uint64_t __rdi; - __uint64_t __rsi; - __uint64_t __rbp; - __uint64_t __rsp; - __uint64_t __r8; - __uint64_t __r9; - __uint64_t __r10; - __uint64_t __r11; - __uint64_t __r12; - __uint64_t __r13; - __uint64_t __r14; - __uint64_t __r15; - __uint64_t __rip; - __uint64_t __rflags; - __uint64_t __cs; - __uint64_t __fs; - __uint64_t __gs; -}; - + printf("rax %X\n", r->rax); + printf("rbx %X\n", r->rbx); + printf("rcx %X\n", r->rcx); + printf("rdx %X\n", r->rdx); + printf("rdi %X\n", r->rdi); + printf("rsi %X\n", r->rsi); + printf("rbp %X\n", r->rbp); + printf("rsp %X\n", r->rsp); + printf("r8 %X\n", r->r8 ); + printf("r9 %X\n", r->r9 ); + printf("r10 %X\n", r->r10); + printf("r11 %X\n", r->r11); + printf("r12 %X\n", r->r12); + printf("r13 %X\n", r->r13); + printf("r14 %X\n", r->r14); + printf("r15 %X\n", r->r15); + printf("rip %X\n", r->rip); + printf("rflags %X\n", r->rflags); + printf("cs %X\n", r->cs); + printf("fs %X\n", r->fs); + printf("gs %X\n", r->gs); +} void -print_thread_state(_STRUCT_X86_THREAD_STATE64* ss) +sighandler(int32 sig, Siginfo *info, void *context) { - prints("\nrax "); sys·printhex(ss->__rax); - prints("\nrbx "); sys·printhex(ss->__rbx); - prints("\nrcx "); sys·printhex(ss->__rcx); - prints("\nrdx "); sys·printhex(ss->__rdx); - prints("\nrdi "); sys·printhex(ss->__rdi); - prints("\nrsi "); sys·printhex(ss->__rsi); - prints("\nrbp "); sys·printhex(ss->__rbp); - prints("\nrsp "); sys·printhex(ss->__rsp); - prints("\nr8 "); sys·printhex(ss->__r8 ); - prints("\nr9 "); sys·printhex(ss->__r9 ); - prints("\nr10 "); sys·printhex(ss->__r10); - prints("\nr11 "); sys·printhex(ss->__r11); - prints("\nr12 "); sys·printhex(ss->__r12); - prints("\nr13 "); sys·printhex(ss->__r13); - prints("\nr14 "); sys·printhex(ss->__r14); - prints("\nr15 "); sys·printhex(ss->__r15); - prints("\nrip "); sys·printhex(ss->__rip); - prints("\nrflags "); sys·printhex(ss->__rflags); - prints("\ncs "); sys·printhex(ss->__cs); - prints("\nfs "); sys·printhex(ss->__fs); - prints("\ngs "); sys·printhex(ss->__gs); - prints("\n"); -} + Ucontext *uc; + Mcontext *mc; + Regs *r; - -/* Code generated via: g++ -m64 gen_signals_support.cc && a.out */ - -static void *adr_at(void *ptr, int32 offs) { - return (void *)((uint8 *)ptr + offs); -} - -static void *ptr_at(void *ptr, int32 offs) { - return *(void **)((uint8 *)ptr + offs); -} - -typedef void ucontext_t; -typedef void _STRUCT_MCONTEXT64; -typedef void _STRUCT_X86_EXCEPTION_STATE64; -typedef void _STRUCT_X86_FLOAT_STATE64; - -static _STRUCT_MCONTEXT64 *get_uc_mcontext(ucontext_t *ptr) { - return (_STRUCT_MCONTEXT64 *)ptr_at(ptr, 48); -} - -static _STRUCT_X86_EXCEPTION_STATE64 *get___es(_STRUCT_MCONTEXT64 *ptr) { - return (_STRUCT_X86_EXCEPTION_STATE64 *)adr_at(ptr, 0); -} - -static _STRUCT_X86_THREAD_STATE64 *get___ss(_STRUCT_MCONTEXT64 *ptr) { - return (_STRUCT_X86_THREAD_STATE64 *)adr_at(ptr, 16); -} - -static _STRUCT_X86_FLOAT_STATE64 *get___fs(_STRUCT_MCONTEXT64 *ptr) { - return (_STRUCT_X86_FLOAT_STATE64 *)adr_at(ptr, 184); -} - -/* End of generated code */ - - -/* - * This assembler routine takes the args from registers, puts them on the stack, - * and calls the registered handler. - */ -extern void sigtramp(void); -/* - * Rudimentary reverse-engineered definition of signal interface. - * You'd think it would be documented. - */ -struct siginfo { - int32 si_signo; /* signal number */ - int32 si_errno; /* errno association */ - int32 si_code; /* signal code */ - int32 si_pid; /* sending process */ - int32 si_uid; /* sender's ruid */ - int32 si_status; /* exit value */ - void *si_addr; /* faulting address */ - /* more stuff here */ -}; - -struct sigaction { - void (*sa_handler)(int32, struct siginfo*, void*); // actual handler - void (*sa_trampoline)(void); // assembly trampoline - uint32 sa_mask; // signal mask during handler - int32 sa_flags; // flags below -}; - -void -sighandler(int32 sig, struct siginfo *info, void *context) -{ if(panicking) // traceback already printed sys_Exit(2); panicking = 1; - _STRUCT_MCONTEXT64 *uc_mcontext = get_uc_mcontext(context); - _STRUCT_X86_THREAD_STATE64 *ss = get___ss(uc_mcontext); - if(sig < 0 || sig >= NSIG){ - prints("Signal "); - sys·printint(sig); + printf("Signal %d\n", sig); }else{ - prints(sigtab[sig].name); + printf("%s\n", sigtab[sig].name); } - prints("\nFaulting address: "); sys·printpointer(info->si_addr); - prints("\npc: "); sys·printhex(ss->__rip); - prints("\n\n"); + uc = context; + mc = uc->uc_mcontext; + r = &mc->ss; + + printf("Faulting address: %p\n", info->si_addr); + printf("PC=%X\n", r->rip); + printf("\n"); if(gotraceback()){ - traceback((void *)ss->__rip, (void *)ss->__rsp, (void*)ss->__r15); - tracebackothers((void*)ss->__r15); - print_thread_state(ss); + traceback((void*)r->rip, (void*)r->rsp, (void*)r->r15); + tracebackothers((void*)r->r15); + dumpregs(r); } sys_Exit(2); } void -sigignore(int32, struct siginfo*, void*) +sigignore(int32, Siginfo*, void*) { } -struct stack_t { - byte *sp; - int64 size; - int32 flags; -}; - void signalstack(byte *p, int32 n) { - struct stack_t st; + StackT st; - st.sp = p; - st.size = n; - st.flags = 0; + st.ss_sp = p; + st.ss_size = n; + st.ss_flags = 0; sigaltstack(&st, nil); } -void sigaction(int64, void*, void*); - -enum { - SA_SIGINFO = 0x40, - SA_RESTART = 0x02, - SA_ONSTACK = 0x01, - SA_USERTRAMP = 0x100, - SA_64REGSET = 0x200, -}; - void initsig(void) { int32 i; - static struct sigaction sa; + static Sigaction sa; sa.sa_flags |= SA_SIGINFO|SA_ONSTACK; sa.sa_mask = 0; // 0xFFFFFFFFU; - sa.sa_trampoline = sigtramp; + sa.sa_tramp = sigtramp; // sigtramp's job is to call into real handler for(i = 0; igsignal->stackguard, 32*1024); } - // Mach IPC, to get at semaphores // Definitions are in /usr/include/mach on a Mac. static void -macherror(kern_return_t r, int8 *fn) +macherror(int32 r, int8 *fn) { prints("mach error "); prints(fn); @@ -182,129 +182,24 @@ enum DebugMach = 0 }; -typedef int32 mach_msg_option_t; -typedef uint32 mach_msg_bits_t; -typedef uint32 mach_msg_id_t; -typedef uint32 mach_msg_size_t; -typedef uint32 mach_msg_timeout_t; -typedef uint32 mach_port_name_t; -typedef uint64 mach_vm_address_t; - -typedef struct mach_msg_header_t mach_msg_header_t; -typedef struct mach_msg_body_t mach_msg_body_t; -typedef struct mach_msg_port_descriptor_t mach_msg_port_descriptor_t; -typedef struct NDR_record_t NDR_record_t; - -enum -{ - MACH_MSG_TYPE_MOVE_RECEIVE = 16, - MACH_MSG_TYPE_MOVE_SEND = 17, - MACH_MSG_TYPE_MOVE_SEND_ONCE = 18, - MACH_MSG_TYPE_COPY_SEND = 19, - MACH_MSG_TYPE_MAKE_SEND = 20, - MACH_MSG_TYPE_MAKE_SEND_ONCE = 21, - MACH_MSG_TYPE_COPY_RECEIVE = 22, - - MACH_MSG_PORT_DESCRIPTOR = 0, - MACH_MSG_OOL_DESCRIPTOR = 1, - MACH_MSG_OOL_PORTS_DESCRIPTOR = 2, - MACH_MSG_OOL_VOLATILE_DESCRIPTOR = 3, - - MACH_MSGH_BITS_COMPLEX = 0x80000000, - - MACH_SEND_MSG = 1, - MACH_RCV_MSG = 2, - MACH_RCV_LARGE = 4, - - 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, -}; - -mach_port_t mach_task_self(void); -mach_port_t mach_thread_self(void); - -#pragma pack on -struct mach_msg_header_t -{ - mach_msg_bits_t bits; - mach_msg_size_t size; - mach_port_t remote_port; - mach_port_t local_port; - mach_msg_size_t reserved; - mach_msg_id_t id; -}; - -struct mach_msg_body_t -{ - uint32 descriptor_count; -}; - -struct mach_msg_port_descriptor_t -{ - mach_port_t name; - uint32 pad1; - uint16 pad2; - uint8 disposition; - uint8 type; -}; - -enum -{ - NDR_PROTOCOL_2_0 = 0, - NDR_INT_BIG_ENDIAN = 0, - NDR_INT_LITTLE_ENDIAN = 1, - NDR_FLOAT_IEEE = 0, - NDR_CHAR_ASCII = 0 -}; - -struct NDR_record_t -{ - uint8 mig_vers; - uint8 if_vers; - uint8 reserved1; - uint8 mig_encoding; - uint8 int_rep; - uint8 char_rep; - uint8 float_rep; - uint8 reserved2; -}; -#pragma pack off - -static NDR_record_t zerondr; +static MachNDR zerondr; #define MACH_MSGH_BITS(a, b) ((a) | ((b)<<8)) -// Mach system calls (in sys_amd64_darwin.s) -kern_return_t mach_msg_trap(mach_msg_header_t*, - mach_msg_option_t, mach_msg_size_t, mach_msg_size_t, - mach_port_name_t, mach_msg_timeout_t, mach_port_name_t); -mach_port_t mach_reply_port(void); -mach_port_t mach_task_self(void); -mach_port_t mach_thread_self(void); - -static kern_return_t -mach_msg(mach_msg_header_t *h, - mach_msg_option_t op, - mach_msg_size_t send_size, - mach_msg_size_t rcv_size, - mach_port_name_t rcv_name, - mach_msg_timeout_t timeout, - mach_port_name_t notify) +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 mach_msg_trap(h, op, send_size, rcv_size, rcv_name, timeout, notify); } - // Mach RPC (MIG) -// I'm not using the Mach names anymore. They're too long. enum { @@ -316,18 +211,18 @@ enum typedef struct CodeMsg CodeMsg; struct CodeMsg { - mach_msg_header_t h; - NDR_record_t NDR; - kern_return_t code; + MachHeader h; + MachNDR NDR; + int32 code; }; #pragma pack off -static kern_return_t -machcall(mach_msg_header_t *h, int32 maxsize, int32 rxsize) +static int32 +machcall(MachHeader *h, int32 maxsize, int32 rxsize) { uint32 *p; int32 i, ret, id; - mach_port_t port; + uint32 port; CodeMsg *c; if((port = m->machport) == 0){ @@ -335,15 +230,15 @@ machcall(mach_msg_header_t *h, int32 maxsize, int32 rxsize) m->machport = port; } - h->bits |= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); - h->local_port = port; - h->reserved = 0; - id = h->id; + 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; prints("send:\t"); - for(i=0; isize/sizeof(p[0]); i++){ + for(i=0; imsgh_size/sizeof(p[0]); i++){ prints(" "); sys·printpointer((void*)p[i]); if(i%8 == 7) @@ -354,7 +249,7 @@ machcall(mach_msg_header_t *h, int32 maxsize, int32 rxsize) } ret = mach_msg(h, MACH_SEND_MSG|MACH_RCV_MSG, - h->size, maxsize, port, 0, 0); + h->msgh_size, maxsize, port, 0, 0); if(ret != 0){ if(DebugMach){ prints("mach_msg error "); @@ -367,7 +262,7 @@ machcall(mach_msg_header_t *h, int32 maxsize, int32 rxsize) if(DebugMach){ p = (uint32*)h; prints("recv:\t"); - for(i=0; isize/sizeof(p[0]); i++){ + for(i=0; imsgh_size/sizeof(p[0]); i++){ prints(" "); sys·printpointer((void*)p[i]); if(i%8 == 7) @@ -377,10 +272,10 @@ machcall(mach_msg_header_t *h, int32 maxsize, int32 rxsize) prints("\n"); } - if(h->id != id+Reply){ + if(h->msgh_id != id+Reply){ if(DebugMach){ prints("mach_msg reply id mismatch "); - sys·printint(h->id); + sys·printint(h->msgh_id); prints(" != "); sys·printint(id+Reply); prints("\n"); @@ -395,8 +290,8 @@ machcall(mach_msg_header_t *h, int32 maxsize, int32 rxsize) // 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->size == sizeof(CodeMsg) - && !(h->bits & MACH_MSGH_BITS_COMPLEX)){ + if(h->msgh_size == sizeof(CodeMsg) + && !(h->msgh_bits & MACH_MSGH_BITS_COMPLEX)){ if(DebugMach){ prints("mig result "); sys·printint(c->code); @@ -405,10 +300,10 @@ machcall(mach_msg_header_t *h, int32 maxsize, int32 rxsize) return c->code; } - if(h->size != rxsize){ + if(h->msgh_size != rxsize){ if(DebugMach){ prints("mach_msg reply size mismatch "); - sys·printint(h->size); + sys·printint(h->msgh_size); prints(" != "); sys·printint(rxsize); prints("\n"); @@ -439,28 +334,28 @@ typedef struct Tmach_semdestroyMsg Tmach_semdestroyMsg; #pragma pack on struct Tmach_semcreateMsg { - mach_msg_header_t h; - NDR_record_t ndr; + MachHeader h; + MachNDR ndr; int32 policy; int32 value; }; struct Rmach_semcreateMsg { - mach_msg_header_t h; - mach_msg_body_t body; - mach_msg_port_descriptor_t semaphore; + MachHeader h; + MachBody body; + MachPort semaphore; }; struct Tmach_semdestroyMsg { - mach_msg_header_t h; - mach_msg_body_t body; - mach_msg_port_descriptor_t semaphore; + MachHeader h; + MachBody body; + MachPort semaphore; }; #pragma pack off -mach_port_t +uint32 mach_semcreate(void) { union { @@ -468,12 +363,12 @@ mach_semcreate(void) Rmach_semcreateMsg rx; uint8 pad[MinMachMsg]; } m; - kern_return_t r; + int32 r; - m.tx.h.bits = 0; - m.tx.h.size = sizeof(m.tx); - m.tx.h.remote_port = mach_task_self(); - m.tx.h.id = Tmach_semcreate; + m.tx.h.msgh_bits = 0; + m.tx.h.msgh_size = sizeof(m.tx); + m.tx.h.msgh_remote_port = mach_task_self(); + m.tx.h.msgh_id = Tmach_semcreate; m.tx.ndr = zerondr; m.tx.policy = 0; // 0 = SYNC_POLICY_FIFO @@ -481,25 +376,25 @@ mach_semcreate(void) if((r = machcall(&m.tx.h, sizeof m, sizeof(m.rx))) != 0) macherror(r, "semaphore_create"); - if(m.rx.body.descriptor_count != 1) + if(m.rx.body.msgh_descriptor_count != 1) unimplemented("mach_semcreate desc count"); return m.rx.semaphore.name; } void -mach_semdestroy(mach_port_t sem) +mach_semdestroy(uint32 sem) { union { Tmach_semdestroyMsg tx; uint8 pad[MinMachMsg]; } m; - kern_return_t r; + int32 r; - m.tx.h.bits = MACH_MSGH_BITS_COMPLEX; - m.tx.h.size = sizeof(m.tx); - m.tx.h.remote_port = mach_task_self(); - m.tx.h.id = Tmach_semdestroy; - m.tx.body.descriptor_count = 1; + m.tx.h.msgh_bits = MACH_MSGH_BITS_COMPLEX; + m.tx.h.msgh_size = sizeof(m.tx); + m.tx.h.msgh_remote_port = 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; @@ -508,26 +403,25 @@ mach_semdestroy(mach_port_t sem) macherror(r, "semaphore_destroy"); } -// The other calls have simple system call traps -// in sys_amd64_darwin.s -kern_return_t mach_semaphore_wait(uint32 sema); -kern_return_t mach_semaphore_timedwait(uint32 sema, uint32 sec, uint32 nsec); -kern_return_t mach_semaphore_signal(uint32 sema); -kern_return_t mach_semaphore_signal_all(uint32 sema); +// The other calls have simple system call traps in sys.s +int32 mach_semaphore_wait(uint32 sema); +int32 mach_semaphore_timedwait(uint32 sema, uint32 sec, uint32 nsec); +int32 mach_semaphore_signal(uint32 sema); +int32 mach_semaphore_signal_all(uint32 sema); void -mach_semacquire(mach_port_t sem) +mach_semacquire(uint32 sem) { - kern_return_t r; + int32 r; if((r = mach_semaphore_wait(sem)) != 0) macherror(r, "semaphore_wait"); } void -mach_semrelease(mach_port_t sem) +mach_semrelease(uint32 sem) { - kern_return_t r; + int32 r; if((r = mach_semaphore_signal(sem)) != 0) macherror(r, "semaphore_signal");