//	Copyright © 2009 The Go Authors.  All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#define __DARWIN_UNIX03 0

#include <u.h>
#include <sys/ptrace.h>
#include <sys/signal.h>
#include <mach/mach.h>
#include <mach/mach_traps.h>
#include <errno.h>
#include <libc.h>
#include <bio.h>
#include <mach.h>
#define Ureg Ureg32
#include <ureg_x86.h>
#undef Ureg
#define Ureg Ureg64
#include <ureg_amd64.h>
#undef Ureg
#undef waitpid	/* want Unix waitpid, not Plan 9 */

typedef struct Ureg32 Ureg32;
typedef struct Ureg64 Ureg64;

extern mach_port_t mach_reply_port(void);	// should be in system headers, is not

// Mach-error wrapper.
// Takes a mach return code and converts it into 0 / -1,
// setting errstr when it returns -1.

static struct {
	int code;
	char *name;
} macherr[] = {
	KERN_INVALID_ADDRESS,	"invalid address",
	KERN_PROTECTION_FAILURE,	"protection failure",
	KERN_NO_SPACE,	"no space",
	KERN_INVALID_ARGUMENT,	"invalid argument",
	KERN_FAILURE,	"failure",
	KERN_RESOURCE_SHORTAGE,	"resource shortage",
	KERN_NOT_RECEIVER,	"not receiver",
	KERN_NO_ACCESS,	"no access",
	KERN_MEMORY_FAILURE,	"memory failure",
	KERN_MEMORY_ERROR,	"memory error",
	KERN_ALREADY_IN_SET,	"already in set",
	KERN_NOT_IN_SET,	"not in set",
	KERN_NAME_EXISTS,	"name exists",
	KERN_ABORTED,	"aborted",
	KERN_INVALID_NAME,	"invalid name",
	KERN_INVALID_TASK,	"invalid task",
	KERN_INVALID_RIGHT,	"invalid right",
	KERN_INVALID_VALUE,	"invalid value",
	KERN_UREFS_OVERFLOW,	"urefs overflow",
	KERN_INVALID_CAPABILITY,	"invalid capability",
	KERN_RIGHT_EXISTS,	"right exists",
	KERN_INVALID_HOST,	"invalid host",
	KERN_MEMORY_PRESENT,	"memory present",
	KERN_MEMORY_DATA_MOVED,	"memory data moved",
	KERN_MEMORY_RESTART_COPY,	"memory restart copy",
	KERN_INVALID_PROCESSOR_SET,	"invalid processor set",
	KERN_POLICY_LIMIT,	"policy limit",
	KERN_INVALID_POLICY,	"invalid policy",
	KERN_INVALID_OBJECT,	"invalid object",
	KERN_ALREADY_WAITING,	"already waiting",
	KERN_DEFAULT_SET,	"default set",
	KERN_EXCEPTION_PROTECTED,	"exception protected",
	KERN_INVALID_LEDGER,	"invalid ledger",
	KERN_INVALID_MEMORY_CONTROL,	"invalid memory control",
	KERN_INVALID_SECURITY,	"invalid security",
	KERN_NOT_DEPRESSED,	"not depressed",
	KERN_TERMINATED,	"terminated",
	KERN_LOCK_SET_DESTROYED,	"lock set destroyed",
	KERN_LOCK_UNSTABLE,	"lock unstable",
	KERN_LOCK_OWNED,	"lock owned",
	KERN_LOCK_OWNED_SELF,	"lock owned self",
	KERN_SEMAPHORE_DESTROYED,	"semaphore destroyed",
	KERN_RPC_SERVER_TERMINATED,	"rpc server terminated",
	KERN_RPC_TERMINATE_ORPHAN,	"rpc terminate orphan",
	KERN_RPC_CONTINUE_ORPHAN,	"rpc continue orphan",
	KERN_NOT_SUPPORTED,	"not supported",
	KERN_NODE_DOWN,	"node down",
	KERN_NOT_WAITING,	"not waiting",
	KERN_OPERATION_TIMED_OUT,	"operation timed out",
	KERN_RETURN_MAX,	"return max",

	MACH_SEND_IN_PROGRESS,	"send in progress",
	MACH_SEND_INVALID_DATA,	"send invalid data",
	MACH_SEND_INVALID_DEST,	"send invalid dest",
	MACH_SEND_TIMED_OUT,	"send timed out",
	MACH_SEND_INTERRUPTED,	"send interrupted",
	MACH_SEND_MSG_TOO_SMALL,	"send msg too small",
	MACH_SEND_INVALID_REPLY,	"send invalid reply",
	MACH_SEND_INVALID_RIGHT,	"send invalid right",
	MACH_SEND_INVALID_NOTIFY,	"send invalid notify",
	MACH_SEND_INVALID_MEMORY,	"send invalid memory",
	MACH_SEND_NO_BUFFER,	"send no buffer",
	MACH_SEND_TOO_LARGE,	"send too large",
	MACH_SEND_INVALID_TYPE,	"send invalid type",
	MACH_SEND_INVALID_HEADER,	"send invalid header",
	MACH_SEND_INVALID_TRAILER,	"send invalid trailer",
	MACH_SEND_INVALID_RT_OOL_SIZE,	"send invalid rt ool size",
	MACH_RCV_IN_PROGRESS,	"rcv in progress",
	MACH_RCV_INVALID_NAME,	"rcv invalid name",
	MACH_RCV_TIMED_OUT,	"rcv timed out",
	MACH_RCV_TOO_LARGE,	"rcv too large",
	MACH_RCV_INTERRUPTED,	"rcv interrupted",
	MACH_RCV_PORT_CHANGED,	"rcv port changed",
	MACH_RCV_INVALID_NOTIFY,	"rcv invalid notify",
	MACH_RCV_INVALID_DATA,	"rcv invalid data",
	MACH_RCV_PORT_DIED,	"rcv port died",
	MACH_RCV_IN_SET,	"rcv in set",
	MACH_RCV_HEADER_ERROR,	"rcv header error",
	MACH_RCV_BODY_ERROR,	"rcv body error",
	MACH_RCV_INVALID_TYPE,	"rcv invalid type",
	MACH_RCV_SCATTER_SMALL,	"rcv scatter small",
	MACH_RCV_INVALID_TRAILER,	"rcv invalid trailer",
	MACH_RCV_IN_PROGRESS_TIMED,	"rcv in progress timed",

	MIG_TYPE_ERROR,	"mig type error",
	MIG_REPLY_MISMATCH,	"mig reply mismatch",
	MIG_REMOTE_ERROR,	"mig remote error",
	MIG_BAD_ID,	"mig bad id",
	MIG_BAD_ARGUMENTS,	"mig bad arguments",
	MIG_NO_REPLY,	"mig no reply",
	MIG_EXCEPTION,	"mig exception",
	MIG_ARRAY_TOO_LARGE,	"mig array too large",
	MIG_SERVER_DIED,	"server died",
	MIG_TRAILER_ERROR,	"trailer has an unknown format",
};

static int
me(kern_return_t r)
{
	int i;

	if(r == 0)
		return 0;

	for(i=0; i<nelem(macherr); i++){
		if(r == macherr[i].code){
			werrstr("mach: %s", macherr[i].name);
			return -1;
		}
	}
	werrstr("mach error %#x", r);
	return -1;
}

// Plan 9 and Linux do not distinguish between
// process ids and thread ids, so the interface here doesn't either.
// Unfortunately, Mach has three kinds of identifiers: process ids,
// handles to tasks (processes), and handles to threads within a
// process.  All of them are small integers.
//
// To accommodate Mach, we employ a clumsy hack: in this interface,
// if you pass in a positive number, that's a process id.
// If you pass in a negative number, that identifies a thread that
// has been previously returned by procthreadpids (it indexes
// into the Thread table below).

// Table of threads we have handles for.
typedef struct Thread Thread;
struct Thread
{
	int pid;
	mach_port_t task;
	mach_port_t thread;
	int stopped;
	int exc;
	int code[10];
	Map *map;
};
static Thread thr[1000];
static int nthr;
static pthread_mutex_t mu;
static pthread_cond_t cond;
static void* excthread(void*);
static void* waitthread(void*);
static mach_port_t excport;

enum {
	ExcMask = EXC_MASK_BAD_ACCESS |
		EXC_MASK_BAD_INSTRUCTION |
		EXC_MASK_ARITHMETIC |
		EXC_MASK_BREAKPOINT |
		EXC_MASK_SOFTWARE
};

// Add process pid to the thread table.
// If it's already there, don't re-add it (unless force != 0).
static Thread*
addpid(int pid, int force)
{
	int i, j;
	mach_port_t task;
	mach_port_t *thread;
	uint nthread;
	Thread *ret;
	static int first = 1;

	if(first){
		// Allocate a port for exception messages and
		// send all thread exceptions to that port.
		// The excthread reads that port and signals
		// us if we are waiting on that thread.
		pthread_t p;

		excport = mach_reply_port();
		pthread_mutex_init(&mu, nil);
		pthread_cond_init(&cond, nil);
		pthread_create(&p, nil, excthread, nil);
		pthread_create(&p, nil, waitthread, (void*)(uintptr)pid);
		first = 0;
	}

	if(!force){
		for(i=0; i<nthr; i++)
			if(thr[i].pid == pid)
				return &thr[i];
	}
	if(me(task_for_pid(mach_task_self(), pid, &task)) < 0)
		return nil;
	if(me(task_threads(task, &thread, &nthread)) < 0)
		return nil;
	mach_port_insert_right(mach_task_self(), excport, excport, MACH_MSG_TYPE_MAKE_SEND);
	if(me(task_set_exception_ports(task, ExcMask,
			excport, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)) < 0){
		fprint(2, "warning: cannot set excport: %r\n");
	}
	ret = nil;
	for(j=0; j<nthread; j++){
		if(force){
			// If we're forcing a refresh, don't re-add existing threads.
			for(i=0; i<nthr; i++)
				if(thr[i].pid == pid && thr[i].thread == thread[j]){
					if(ret == nil)
						ret = &thr[i];
					goto skip;
				}
		}
		if(nthr >= nelem(thr))
			return nil;
		// TODO: We probably should save the old thread exception
		// ports for each bit and then put them back when we exit.
		// Probably the BSD signal handlers have put stuff there.
		mach_port_insert_right(mach_task_self(), excport, excport, MACH_MSG_TYPE_MAKE_SEND);
		if(me(thread_set_exception_ports(thread[j], ExcMask,
				excport, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE)) < 0){
			fprint(2, "warning: cannot set excport: %r\n");
		}
		thr[nthr].pid = pid;
		thr[nthr].task = task;
		thr[nthr].thread = thread[j];
		if(ret == nil)
			ret = &thr[nthr];
		nthr++;
	skip:;
	}
	return ret;
}

static Thread*
idtotable(int id)
{
	if(id >= 0)
		return addpid(id, 1);

	id = -(id+1);
	if(id >= nthr)
		return nil;
	return &thr[id];
}

/*
static int
idtopid(int id)
{
	Thread *t;

	if((t = idtotable(id)) == nil)
		return -1;
	return t->pid;
}
*/

static mach_port_t
idtotask(int id)
{
	Thread *t;

	if((t = idtotable(id)) == nil)
		return -1;
	return t->task;
}

static mach_port_t
idtothread(int id)
{
	Thread *t;

	if((t = idtotable(id)) == nil)
		return -1;
	return t->thread;
}

static int machsegrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr);
static int machregrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr);

Map*
attachproc(int id, Fhdr *fp)
{
	Thread *t;
	Map *map;

	if((t = idtotable(id)) == nil)
		return nil;
	if(t->map)
		return t->map;
	map = newmap(0, 4);
	if(!map)
		return nil;
	map->pid = -((t-thr) + 1);
	if(mach->regsize)
		setmap(map, -1, 0, mach->regsize, 0, "regs", machregrw);
	setmap(map, -1, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "*text", machsegrw);
	setmap(map, -1, fp->dataddr, mach->utop, fp->dataddr, "*data", machsegrw);
	t->map = map;
	return map;
}

// Return list of ids for threads in id.
int
procthreadpids(int id, int *out, int nout)
{
	Thread *t;
	int i, n, pid;

	t = idtotable(id);
	if(t == nil)
		return -1;
	pid = t->pid;
	addpid(pid, 1);	// force refresh of thread list
	n = 0;
	for(i=0; i<nthr; i++) {
		if(thr[i].pid == pid) {
			if(n < nout)
				out[n] = -(i+1);
			n++;
		}
	}
	return n;
}

// Detach from proc.
// TODO(rsc): Perhaps should unsuspend any threads and clean-up the table.
void
detachproc(Map *m)
{
	free(m);
}

// Should return array of pending signals (notes)
// but don't know how to do that on OS X.
int
procnotes(int pid, char ***pnotes)
{
	*pnotes = 0;
	return 0;
}

// There must be a way to do this.  Gdb can do it.
// But I don't see, in the Apple gdb sources, how.
char*
proctextfile(int pid)
{
	return nil;
}

// Read/write from a Mach data segment.
static int
machsegrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr)
{
	mach_port_t task;
	int r;

	task = idtotask(map->pid);
	if(task == -1)
		return -1;

	if(isr){
		vm_size_t nn;
		nn = n;
		if(me(vm_read_overwrite(task, addr, n, (uintptr)v, &nn)) < 0) {
			fprint(2, "vm_read_overwrite %#llux %d to %p: %r\n", addr, n, v);
			return -1;
		}
		return nn;
	}else{
		r = vm_write(task, addr, (uintptr)v, n);
		if(r == KERN_INVALID_ADDRESS){
			// Happens when writing to text segment.
			// Change protections.
			if(me(vm_protect(task, addr, n, 0, VM_PROT_WRITE|VM_PROT_READ|VM_PROT_EXECUTE)) < 0){
				fprint(2, "vm_protect: %s\n", r);
				return -1;
			}
			r = vm_write(task, addr, (uintptr)v, n);
		}
		if(r != 0){
			me(r);
			return -1;
		}
		return n;
	}
}

// Convert Ureg offset to x86_thread_state32_t offset.
static int
go2darwin32(uvlong addr)
{
	switch(addr){
	case offsetof(Ureg32, ax):
		return offsetof(x86_thread_state32_t, eax);
	case offsetof(Ureg32, bx):
		return offsetof(x86_thread_state32_t, ebx);
	case offsetof(Ureg32, cx):
		return offsetof(x86_thread_state32_t, ecx);
	case offsetof(Ureg32, dx):
		return offsetof(x86_thread_state32_t, edx);
	case offsetof(Ureg32, si):
		return offsetof(x86_thread_state32_t, esi);
	case offsetof(Ureg32, di):
		return offsetof(x86_thread_state32_t, edi);
	case offsetof(Ureg32, bp):
		return offsetof(x86_thread_state32_t, ebp);
	case offsetof(Ureg32, fs):
		return offsetof(x86_thread_state32_t, fs);
	case offsetof(Ureg32, gs):
		return offsetof(x86_thread_state32_t, gs);
	case offsetof(Ureg32, pc):
		return offsetof(x86_thread_state32_t, eip);
	case offsetof(Ureg32, cs):
		return offsetof(x86_thread_state32_t, cs);
	case offsetof(Ureg32, flags):
		return offsetof(x86_thread_state32_t, eflags);
	case offsetof(Ureg32, sp):
		return offsetof(x86_thread_state32_t, esp);
	}
	return -1;
}

// Convert Ureg offset to x86_thread_state64_t offset.
static int
go2darwin64(uvlong addr)
{
	switch(addr){
	case offsetof(Ureg64, ax):
		return offsetof(x86_thread_state64_t, rax);
	case offsetof(Ureg64, bx):
		return offsetof(x86_thread_state64_t, rbx);
	case offsetof(Ureg64, cx):
		return offsetof(x86_thread_state64_t, rcx);
	case offsetof(Ureg64, dx):
		return offsetof(x86_thread_state64_t, rdx);
	case offsetof(Ureg64, si):
		return offsetof(x86_thread_state64_t, rsi);
	case offsetof(Ureg64, di):
		return offsetof(x86_thread_state64_t, rdi);
	case offsetof(Ureg64, bp):
		return offsetof(x86_thread_state64_t, rbp);
	case offsetof(Ureg64, r8):
		return offsetof(x86_thread_state64_t, r8);
	case offsetof(Ureg64, r9):
		return offsetof(x86_thread_state64_t, r9);
	case offsetof(Ureg64, r10):
		return offsetof(x86_thread_state64_t, r10);
	case offsetof(Ureg64, r11):
		return offsetof(x86_thread_state64_t, r11);
	case offsetof(Ureg64, r12):
		return offsetof(x86_thread_state64_t, r12);
	case offsetof(Ureg64, r13):
		return offsetof(x86_thread_state64_t, r13);
	case offsetof(Ureg64, r14):
		return offsetof(x86_thread_state64_t, r14);
	case offsetof(Ureg64, r15):
		return offsetof(x86_thread_state64_t, r15);
	case offsetof(Ureg64, fs):
		return offsetof(x86_thread_state64_t, fs);
	case offsetof(Ureg64, gs):
		return offsetof(x86_thread_state64_t, gs);
	case offsetof(Ureg64, ip):
		return offsetof(x86_thread_state64_t, rip);
	case offsetof(Ureg64, cs):
		return offsetof(x86_thread_state64_t, cs);
	case offsetof(Ureg64, flags):
		return offsetof(x86_thread_state64_t, rflags);
	case offsetof(Ureg64, sp):
		return offsetof(x86_thread_state64_t, rsp);
	}
	return -1;
}

extern Mach mi386;

// Read/write from fake register segment.
static int
machregrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr)
{
	uint nn, count, state;
	mach_port_t thread;
	int reg;
	char buf[100];
	union {
		x86_thread_state64_t reg64;
		x86_thread_state32_t reg32;
		uchar p[1];
	} u;
	uchar *p;

	if(n > 8){
		werrstr("asked for %d-byte register", n);
		return -1;
	}

	thread = idtothread(map->pid);
	if(thread == -1){
		werrstr("no such id");
		return -1;
	}

	if(mach == &mi386) {
		count = x86_THREAD_STATE32_COUNT;
		state = x86_THREAD_STATE32;
		if((reg = go2darwin32(addr)) < 0 || reg+n > sizeof u){
			if(isr){
				memset(v, 0, n);
				return 0;
			}
			werrstr("register %llud not available", addr);
			return -1;
		}
	} else {
		count = x86_THREAD_STATE64_COUNT;
		state = x86_THREAD_STATE64;
		if((reg = go2darwin64(addr)) < 0 || reg+n > sizeof u){
			if(isr){
				memset(v, 0, n);
				return 0;
			}
			werrstr("register %llud not available", addr);
			return -1;
		}
	}

	if(!isr && me(thread_suspend(thread)) < 0){
		werrstr("thread suspend %#x: %r", thread);
		return -1;
	}
	nn = count;
	if(me(thread_get_state(thread, state, (void*)u.p, &nn)) < 0){
		if(!isr)
			thread_resume(thread);
		rerrstr(buf, sizeof buf);
		if(strstr(buf, "send invalid dest") != nil) 
			werrstr("process exited");
		else
			werrstr("thread_get_state: %r");
		return -1;
	}

	p = u.p+reg;
	if(isr)
		memmove(v, p, n);
	else{
		memmove(p, v, n);
		nn = count;
		if(me(thread_set_state(thread, state, (void*)u.p, nn)) < 0){
			thread_resume(thread);
			werrstr("thread_set_state: %r");
			return -1;
		}

		if(me(thread_resume(thread)) < 0){
			werrstr("thread_resume: %r");
			return -1;
		}
	}
	return 0;
}

enum
{
	FLAGS_TF = 0x100		// x86 single-step processor flag
};

// Is thread t suspended?
static int
threadstopped(Thread *t)
{
	struct thread_basic_info info;
	uint size;

	size = sizeof info;
	if(me(thread_info(t->thread, THREAD_BASIC_INFO, (thread_info_t)&info, &size)) <  0){
		fprint(2, "threadstopped thread_info %#x: %r\n");
		return 1;
	}
	return info.suspend_count > 0;
}

// If thread t is suspended, start it up again.
// If singlestep is set, only let it execute one instruction.
static int
threadstart(Thread *t, int singlestep)
{
	int i;
	uint n;
	struct thread_basic_info info;

	if(!threadstopped(t))
		return 0;

	// Set or clear the processor single-step flag, as appropriate.
	if(mach == &mi386) {
		x86_thread_state32_t regs;
		n = x86_THREAD_STATE32_COUNT;
		if(me(thread_get_state(t->thread, x86_THREAD_STATE32,
				(thread_state_t)&regs,
				&n)) < 0)
			return -1;
		if(singlestep)
			regs.eflags |= FLAGS_TF;
		else
			regs.eflags &= ~FLAGS_TF;
		if(me(thread_set_state(t->thread, x86_THREAD_STATE32,
				(thread_state_t)&regs,
				x86_THREAD_STATE32_COUNT)) < 0)
			return -1;
	} else {
		x86_thread_state64_t regs;
		n = x86_THREAD_STATE64_COUNT;
		if(me(thread_get_state(t->thread, x86_THREAD_STATE64,
				(thread_state_t)&regs,
				&n)) < 0)
			return -1;
		if(singlestep)
			regs.rflags |= FLAGS_TF;
		else
			regs.rflags &= ~FLAGS_TF;
		if(me(thread_set_state(t->thread, x86_THREAD_STATE64,
				(thread_state_t)&regs,
				x86_THREAD_STATE64_COUNT)) < 0)
			return -1;
	}

	// Run.
	n = sizeof info;
	if(me(thread_info(t->thread, THREAD_BASIC_INFO, (thread_info_t)&info, &n)) < 0)
		return -1;
	for(i=0; i<info.suspend_count; i++)
		if(me(thread_resume(t->thread)) < 0)
			return -1;
	return 0;
}

// Stop thread t.
static int
threadstop(Thread *t)
{
	if(threadstopped(t))
		return 0;
	if(me(thread_suspend(t->thread)) < 0)
		return -1;
	return 0;
}

// Callback for exc_server below.  Called when a thread we are
// watching has an exception like hitting a breakpoint.
kern_return_t
catch_exception_raise(mach_port_t eport, mach_port_t thread,
	mach_port_t task, exception_type_t exception,
	exception_data_t code, mach_msg_type_number_t ncode)
{
	Thread *t;
	int i;

	t = nil;
	for(i=0; i<nthr; i++){
		if(thr[i].thread == thread){
			t = &thr[i];
			goto havet;
		}
	}
	if(nthr > 0)
		addpid(thr[0].pid, 1);
	for(i=0; i<nthr; i++){
		if(thr[i].thread == thread){
			t = &thr[i];
			goto havet;
		}
	}
	fprint(2, "did not find thread in catch_exception_raise\n");
	return KERN_SUCCESS;	// let thread continue

havet:
	t->exc = exception;
	if(ncode > nelem(t->code))
		ncode = nelem(t->code);
	memmove(t->code, code, ncode*sizeof t->code[0]);

	// Suspend thread, so that we can look at it & restart it later.
	if(me(thread_suspend(thread)) < 0)
		fprint(2, "catch_exception_raise thread_suspend: %r\n");

	// Synchronize with waitstop below.
	pthread_mutex_lock(&mu);
	pthread_cond_broadcast(&cond);
	pthread_mutex_unlock(&mu);

	return KERN_SUCCESS;
}

// Exception watching thread, started in addpid above.
static void*
excthread(void *v)
{
	extern boolean_t exc_server();
	mach_msg_server(exc_server, 2048, excport, 0);
	return 0;
}

// Wait for pid to exit.
static int exited;
static void*
waitthread(void *v)
{
	int pid, status;

	pid = (int)(uintptr)v;
	waitpid(pid, &status, 0);
	exited = 1;
	// Synchronize with waitstop below.
	pthread_mutex_lock(&mu);
	pthread_cond_broadcast(&cond);
	pthread_mutex_unlock(&mu);
	return nil;
}

// Wait for thread t to stop.
static int
waitstop(Thread *t)
{
	pthread_mutex_lock(&mu);
	while(!exited && !threadstopped(t))
		pthread_cond_wait(&cond, &mu);
	pthread_mutex_unlock(&mu);
	return 0;
}

int
ctlproc(int id, char *msg)
{
	Thread *t;
	int status;

	// Hang/attached dance is for debugging newly exec'ed programs.
	// After fork, the child does ctlproc("hang") before exec,
	// and the parent does ctlproc("attached") and then waitstop.
	// Using these requires the BSD ptrace interface, unlike everything
	// else we do, which uses only the Mach interface.  Our goal here
	// is to do as little as possible using ptrace and then flip over to Mach.

	if(strcmp(msg, "hang") == 0)
		return ptrace(PT_TRACE_ME, 0, 0, 0);

	if(strcmp(msg, "attached") == 0){
		// The pid "id" has done a ctlproc "hang" and then
		// exec, so we should find it stoppped just before exec
		// of the new program.
		#undef waitpid
		if(waitpid(id, &status, WUNTRACED) < 0){
			fprint(2, "ctlproc attached waitpid: %r\n");
			return -1;
		}
		if(WIFEXITED(status) || !WIFSTOPPED(status)){
			fprint(2, "ctlproc attached: bad process state\n");
			return -1;
		}

		// Find Mach thread for pid and suspend it.
		t = addpid(id, 1);
		if(t == nil) {
			fprint(2, "ctlproc attached: addpid: %r\n");
			return -1;
		}
		if(me(thread_suspend(t->thread)) < 0){
			fprint(2, "ctlproc attached: thread_suspend: %r\n");
			return -1;
		}

		// Let ptrace tell the process to keep going:
		// then ptrace is out of the way and we're back in Mach land.
		if(ptrace(PT_CONTINUE, id, (caddr_t)1, 0) < 0) {
			fprint(2, "ctlproc attached: ptrace continue: %r\n");
			return -1;
		}
		
		return 0;
	}

	// All the other control messages require a Thread structure.
	if((t = idtotable(id)) == nil){
		werrstr("no such thread");
		return -1;
	}

	if(strcmp(msg, "kill") == 0)
		return ptrace(PT_KILL, t->pid, 0, 0);

	if(strcmp(msg, "start") == 0)
		return threadstart(t, 0);

	if(strcmp(msg, "stop") == 0)
		return threadstop(t);

	if(strcmp(msg, "startstop") == 0){
		if(threadstart(t, 0) < 0)
			return -1;
		return waitstop(t);
	}

	if(strcmp(msg, "step") == 0){
		if(threadstart(t, 1) < 0)
			return -1;
		return waitstop(t);
	}

	if(strcmp(msg, "waitstop") == 0)
		return waitstop(t);

	// sysstop not available on OS X

	werrstr("unknown control message");
	return -1;
}

char*
procstatus(int id)
{
	Thread *t;

	if((t = idtotable(id)) == nil)
		return "gone!";

	if(threadstopped(t))
		return "Stopped";

	return "Running";
}

