//	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("%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 accomodate 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)
			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(strcmp(buf, "send invalid dest") == 0)
			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)
			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.
		return ptrace(PT_CONTINUE, id, (caddr_t)1, 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";
}

