// Derived from Plan 9 from User Space src/libmach/Linux.c
// http://code.swtch.com/plan9port/src/tip/src/libmach/Linux.c
//
//	Copyright © 1994-1999 Lucent Technologies Inc.
//	Power PC support Copyright © 1995-2004 C H Forsyth (forsyth@terzarima.net).
//	Portions Copyright © 1997-1999 Vita Nuova Limited.
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).
//	Revisions Copyright © 2000-2004 Lucent Technologies Inc. and others.
//	Portions Copyright © 2001-2007 Russ Cox.
//	Portions 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.

#include <u.h>
#include <sys/syscall.h>	/* for tkill */
#include <unistd.h>
#include <dirent.h>
#include <sys/ptrace.h>
#include <sys/signal.h>
#include <sys/wait.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

// The old glibc used with crosstool compilers on thresher
// doesn't know these numbers, but the Linux kernel
// had them as far back as 2.6.0.
#ifndef WSTOPPED
#define WSTOPPED 2
#define WCONTINUED 8
#define WIFCONTINUED(x) ((x) == 0xffff)
#endif
#ifndef PTRACE_SETOPTIONS
#define PTRACE_SETOPTIONS 0x4200
#define PTRACE_GETEVENTMSG 0x4201
#define PTRACE_O_TRACEFORK 0x2
#define PTRACE_O_TRACEVFORK 0x4
#define PTRACE_O_TRACECLONE 0x8
#define PTRACE_O_TRACEEXEC 0x10
#define PTRACE_O_TRACEVFORKDONE 0x20
#define PTRACE_O_TRACEEXIT 0x40
#define PTRACE_EVENT_FORK 0x1
#define PTRACE_EVENT_VFORK 0x2
#define PTRACE_EVENT_CLONE 0x3
#define PTRACE_EVENT_EXEC 0x4
#define PTRACE_EVENT_VFORK_DONE 0x5
#define PTRACE_EVENT_EXIT 0x6
#endif

typedef struct Ureg64 Ureg64;

static Maprw ptracesegrw;
static Maprw ptraceregrw;

// /usr/include/asm-x86_64/user.h
struct user_regs_struct {
	unsigned long r15,r14,r13,r12,rbp,rbx,r11,r10;
	unsigned long r9,r8,rax,rcx,rdx,rsi,rdi,orig_rax;
	unsigned long rip,cs,eflags;
	unsigned long rsp,ss;
  	unsigned long fs_base, gs_base;
	unsigned long ds,es,fs,gs;
};

// Linux gets very upset if a debugger forgets the reported state
// of a debugged process, so we keep everything we know about
// a debugged process in the LinuxThread structure.
//
// We can poll for state changes by calling waitpid and interpreting
// the integer status code that comes back.  Wait1 does this.
//
// If the process is already running, it is an error to PTRACE_CONT it.
//
// If the process is already stopped, it is an error to stop it again.
//
// If the process is stopped because of a signal, the debugger must
// relay the signal to the PTRACE_CONT call, or else the signal is
// dropped.
//
// If the process exits, the debugger should detach so that the real
// parent can reap the zombie.
//
// On first attach, the debugger should set a handful of flags in order
// to catch future events like fork, clone, exec, etc.

// One for every attached thread.
typedef struct LinuxThread LinuxThread;
struct LinuxThread
{
	int pid;
	int tid;
	int state;
	int signal;
	int child;
	int exitcode;
};

static int trace = 0;

static LinuxThread **thr;
static int nthr;
static int mthr;

static int realpid(int pid);

enum
{
	Unknown,
	Detached,
	Attached,
	AttachStop,
	Stopped,
	Running,
	Forking,
	Vforking,
	VforkDone,
	Cloning,
	Execing,
	Exiting,
	Exited,
	Killed,

	NSTATE,
};

static char* statestr[NSTATE] = {
	"Unknown",
	"Detached",
	"Attached",
	"AttachStop",
	"Stopped",
	"Running",
	"Forking",
	"Vforking",
	"VforkDone",
	"Cloning",
	"Execing",
	"Exiting",
	"Exited",
	"Killed"
};

static LinuxThread*
attachthread(int pid, int tid, int *new, int newstate)
{
	int i, n, status;
	LinuxThread **p, *t;
	uintptr flags;

	if(new)
		*new = 0;

	for(i=0; i<nthr; i++)
		if((pid == 0 || thr[i]->pid == pid) && thr[i]->tid == tid) {
			t = thr[i];
			goto fixup;
		}

	if(!new)
		return nil;

	if(nthr >= mthr) {
		n = mthr;
		if(n == 0)
			n = 64;
		else
			n *= 2;
		p = realloc(thr, n*sizeof thr[0]);
		if(p == nil)
			return nil;
		thr = p;
		mthr = n;
	}

	t = malloc(sizeof *t);
	if(t == nil)
		return nil;
        memset(t, 0, sizeof *t);

	thr[nthr++] = t;
	t->pid = pid;
	t->tid = tid;
	t->state = newstate;
	if(trace)
		fprint(2, "new thread %d %d\n", t->pid, t->tid);
	if(new)
		*new = 1;

fixup:
	if(t->state == Detached) {
		if(ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) {
			fprint(2, "ptrace ATTACH %d: %r\n", tid);
			return nil;
		}
		t->state = Attached;
	}

	if(t->state == Attached) {
		// wait for stop, so we can set options
		if(waitpid(tid, &status, __WALL|WUNTRACED|WSTOPPED) < 0)
			return nil;
		if(!WIFSTOPPED(status)) {
			fprint(2, "waitpid %d: status=%#x not stopped\n", tid);
			return nil;
		}
		t->state = AttachStop;
	}

	if(t->state == AttachStop) {
		// set options so we'll find out about new threads
		flags = PTRACE_O_TRACEFORK |
			PTRACE_O_TRACEVFORK |
			PTRACE_O_TRACECLONE |
			PTRACE_O_TRACEEXEC |
			PTRACE_O_TRACEVFORKDONE |
			PTRACE_O_TRACEEXIT;
		if(ptrace(PTRACE_SETOPTIONS, tid, 0, (void*)flags) < 0)	{
			fprint(2, "ptrace PTRACE_SETOPTIONS %d: %r\n", tid);
			return nil;
		}
		t->state = Stopped;
	}

	return t;
}

static LinuxThread*
findthread(int tid)
{
	return attachthread(0, tid, nil, 0);
}

int
procthreadpids(int pid, int *p, int np)
{
	int i, n;
	LinuxThread *t;

	n = 0;
	for(i=0; i<nthr; i++) {
		t = thr[i];
		if(t->pid == pid) {
			switch(t->state) {
			case Exited:
			case Detached:
			case Killed:
				break;

			default:
				if(n < np)
					p[n] = t->tid;
				n++;
				break;
			}
		}
	}
	return n;
}

// Execute a single wait and update the corresponding thread.
static int
wait1(int nohang)
{
	int tid, new, status, event;
	ulong data;
	LinuxThread *t;
	enum
	{
		NormalStop = 0x137f
	};

	if(nohang != 0)
		nohang = WNOHANG;

	tid = waitpid(-1, &status, __WALL|WUNTRACED|WSTOPPED|WCONTINUED|nohang);
	if(tid < 0)
		return -1;
	if(tid == 0)
		return 0;

	if(trace > 0 && status != NormalStop)
		fprint(2, "TID %d: %#x\n", tid, status);

	// If we've not heard of this tid, something is wrong.
	t = findthread(tid);
	if(t == nil) {
		fprint(2, "ptrace waitpid: unexpected new tid %d status %#x\n", tid, status);
		return -1;
	}

	if(WIFSTOPPED(status)) {
		t->state = Stopped;
		t->signal = WSTOPSIG(status);
		if(trace)
			fprint(2, "tid %d: stopped %#x%s\n", tid, status,
				status != NormalStop ? " ***" : "");
		if(t->signal == SIGTRAP && (event = status>>16) != 0) {	// ptrace event
			switch(event) {
			case PTRACE_EVENT_FORK:
				t->state = Forking;
				goto child;

			case PTRACE_EVENT_VFORK:
				t->state = Vforking;
				goto child;

			case PTRACE_EVENT_CLONE:
				t->state = Cloning;
				goto child;

			child:
				if(ptrace(PTRACE_GETEVENTMSG, t->tid, 0, &data) < 0) {
					fprint(2, "ptrace GETEVENTMSG tid %d: %r\n", tid);
					break;
				}
				t->child = data;
				attachthread(t->pid, t->child, &new, Running);
				if(!new)
					fprint(2, "ptrace child: not new\n");
				break;

			case PTRACE_EVENT_EXEC:
				t->state = Execing;
				break;

			case PTRACE_EVENT_VFORK_DONE:
				t->state = VforkDone;
				break;

			case PTRACE_EVENT_EXIT:
				if(trace)
					fprint(2, "tid %d: exiting %#x\n", tid, status);
				t->state = Exiting;
				if(ptrace(PTRACE_GETEVENTMSG, t->tid, 0, &data) < 0) {
					fprint(2, "ptrace GETEVENTMSG tid %d: %r\n", tid);
					break;
				}
				t->exitcode = data;
				break;
			}
		}
	}
	if(WIFCONTINUED(status)) {
		if(trace)
			fprint(2, "tid %d: continued %#x\n", tid, status);
		t->state = Running;
	}
	if(WIFEXITED(status)) {
		if(trace)
			fprint(2, "tid %d: exited %#x\n", tid, status);
		t->state = Exited;
		t->exitcode = WEXITSTATUS(status);
		t->signal = -1;
		ptrace(PTRACE_DETACH, t->tid, 0, 0);
		if(trace)
			fprint(2, "tid %d: detach exited\n", tid);
	}
	if(WIFSIGNALED(status)) {
		if(trace)
			fprint(2, "tid %d: signaled %#x\n", tid, status);
		t->state = Exited;
		t->signal = WTERMSIG(status);
		t->exitcode = -1;
		ptrace(PTRACE_DETACH, t->tid, 0, 0);
		if(trace)
			fprint(2, "tid %d: detach signaled\n", tid);
	}
	return 1;
}

static int
waitstop(LinuxThread *t)
{
	while(t->state == Running)
		if(wait1(0) < 0)
			return -1;
	return 0;
}

// Attach to and stop all threads in process pid.
// Must stop everyone in order to make sure we set
// the "tell me about new threads" option in every
// task.
int
attachallthreads(int pid)
{
	int tid, foundnew, new;
	char buf[100];
	DIR *d;
	struct dirent *de;
	LinuxThread *t;

	if(pid == 0) {
		fprint(2, "attachallthreads(0)\n");
		return -1;
	}

	pid = realpid(pid);

	snprint(buf, sizeof buf, "/proc/%d/task", pid);
	if((d = opendir(buf)) == nil) {
		fprint(2, "opendir %s: %r\n", buf);
		return -1;
	}

	// Loop in case new threads are being created right now.
	// We stop every thread as we find it, so eventually
	// this has to stop (or the system runs out of procs).
	do {
		foundnew = 0;
		while((de = readdir(d)) != nil) {
			tid = atoi(de->d_name);
			if(tid == 0)
				continue;
			t = attachthread(pid, tid, &new, Detached);
			foundnew |= new;
			if(t)
				waitstop(t);
		}
		rewinddir(d);
	} while(foundnew);
	closedir(d);

	return 0;
}

Map*
attachproc(int pid, Fhdr *fp)
{
	Map *map;

	if(pid == 0) {
		fprint(2, "attachproc(0)\n");
		return nil;
	}

	if(findthread(pid) == nil && attachallthreads(pid) < 0)
		return nil;

	map = newmap(0, 4);
	if (!map)
		return 0;
	map->pid = pid;
	if(mach->regsize)
		setmap(map, -1, 0, mach->regsize, 0, "regs", ptraceregrw);
//	if(mach->fpregsize)
//		setmap(map, -1, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs", ptraceregrw);
	setmap(map, -1, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "*text", ptracesegrw);
	setmap(map, -1, fp->dataddr, mach->utop, fp->dataddr, "*data", ptracesegrw);
	return map;
}

void
detachproc(Map *m)
{
	LinuxThread *t;

	t = findthread(m->pid);
	if(t != nil) {
		ptrace(PTRACE_DETACH, t->tid, 0, 0);
		t->state = Detached;
		if(trace)
			fprint(2, "tid %d: detachproc\n", t->tid);
		// TODO(rsc): Reclaim thread structs somehow?
	}
	free(m);
}

/* /proc/pid/stat contains
	pid
	command in parens
	0. state
	1. ppid
	2. pgrp
	3. session
	4. tty_nr
	5. tpgid
	6. flags (math=4, traced=10)
	7. minflt
	8. cminflt
	9. majflt
	10. cmajflt
	11. utime
	12. stime
	13. cutime
	14. cstime
	15. priority
	16. nice
	17. 0
	18. itrealvalue
	19. starttime
	20. vsize
	21. rss
	22. rlim
	23. startcode
	24. endcode
	25. startstack
	26. kstkesp
	27. kstkeip
	28. pending signal bitmap
	29. blocked signal bitmap
	30. ignored signal bitmap
	31. caught signal bitmap
	32. wchan
	33. nswap
	34. cnswap
	35. exit_signal
	36. processor
*/

static int
readstat(int pid, char *buf, int nbuf, char **f, int nf)
{
	int fd, n;
	char *p;

	snprint(buf, nbuf, "/proc/%d/stat", pid);
	if((fd = open(buf, OREAD)) < 0){
		fprint(2, "open %s: %r\n", buf);
		return -1;
	}
	n = read(fd, buf, nbuf-1);
	close(fd);
	if(n <= 0){
		fprint(2, "read %s: %r\n", buf);
		return -1;
	}
	buf[n] = 0;

	/* command name is in parens, no parens afterward */
	p = strrchr(buf, ')');
	if(p == nil || *++p != ' '){
		fprint(2, "bad format in /proc/%d/stat\n", pid);
		return -1;
	}
	++p;

	nf = tokenize(p, f, nf);
	if(0) print("code 0x%lux-0x%lux stack 0x%lux kstk 0x%lux keip 0x%lux pending 0x%lux\n",
		strtoul(f[23], 0, 0), strtoul(f[24], 0, 0), strtoul(f[25], 0, 0),
		strtoul(f[26], 0, 0), strtoul(f[27], 0, 0), strtoul(f[28], 0, 0));

	return nf;
}

static char*
readstatus(int pid, char *buf, int nbuf, char *key)
{
	int fd, n;
	char *p;

	snprint(buf, nbuf, "/proc/%d/status", pid);
	if((fd = open(buf, OREAD)) < 0){
		fprint(2, "open %s: %r\n", buf);
		return nil;
	}
	n = read(fd, buf, nbuf-1);
	close(fd);
	if(n <= 0){
		fprint(2, "read %s: %r\n", buf);
		return nil;
	}
	buf[n] = 0;
	p = strstr(buf, key);
	if(p)
		return p+strlen(key);
	return nil;
}

int
procnotes(int pid, char ***pnotes)
{
	char buf[1024], *f[40];
	int i, n, nf;
	char *s, **notes;
	ulong sigs;
	extern char *_p9sigstr(int, char*);

	*pnotes = nil;
	nf = readstat(pid, buf, sizeof buf, f, nelem(f));
	if(nf <= 28)
		return -1;

	sigs = strtoul(f[28], 0, 0) & ~(1<<SIGCONT);
	if(sigs == 0){
		*pnotes = nil;
		return 0;
	}

	notes = malloc(32*sizeof(char*));
	if(notes == nil)
		return -1;
	memset(notes, 0, 32*sizeof(char*));
	n = 0;
	for(i=0; i<32; i++){
		if((sigs&(1<<i)) == 0)
			continue;
		if((s = _p9sigstr(i, nil)) == nil)
			continue;
		notes[n++] = s;
	}
	*pnotes = notes;
	return n;
}

static int
realpid(int pid)
{
	char buf[1024], *p;

	p = readstatus(pid, buf, sizeof buf, "\nTgid:");
	if(p == nil)
		return pid;
	return atoi(p);
}

int
ctlproc(int pid, char *msg)
{
	int new;
	LinuxThread *t;
	uintptr data;

	while(wait1(1) > 0)
		;

	if(strcmp(msg, "attached") == 0){
		t = attachthread(pid, pid, &new, Attached);
		if(t == nil)
			return -1;
		return 0;
	}

	if(strcmp(msg, "hang") == 0){
		if(pid == getpid())
			return ptrace(PTRACE_TRACEME, 0, 0, 0);
		werrstr("can only hang self");
		return -1;
	}

	t = findthread(pid);
	if(t == nil) {
		werrstr("not attached to pid %d", pid);
		return -1;
	}
	if(t->state == Exited) {
		werrstr("pid %d has exited", pid);
		return -1;
	}
	if(t->state == Killed) {
		werrstr("pid %d has been killed", pid);
		return -1;
	}

	if(strcmp(msg, "kill") == 0) {
		if(ptrace(PTRACE_KILL, pid, 0, 0) < 0)
			return -1;
		t->state = Killed;
		return 0;
	}
	if(strcmp(msg, "startstop") == 0){
		if(ctlproc(pid, "start") < 0)
			return -1;
		return waitstop(t);
	}
	if(strcmp(msg, "sysstop") == 0){
		if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
			return -1;
		t->state = Running;
		return waitstop(t);
	}
	if(strcmp(msg, "stop") == 0){
		if(trace > 1)
			fprint(2, "tid %d: tkill stop\n", pid);
		if(t->state == Stopped)
			return 0;
		if(syscall(__NR_tkill, pid, SIGSTOP) < 0)
			return -1;
		return waitstop(t);
	}
	if(strcmp(msg, "step") == 0){
		if(t->state == Running) {
			werrstr("cannot single-step unstopped %d", pid);
			return -1;
		}
		if(ptrace(PTRACE_SINGLESTEP, pid, 0, 0) < 0)
			return -1;
		return waitstop(t);
	}
	if(strcmp(msg, "start") == 0) {
		if(t->state == Running)
			return 0;
		data = 0;
		if(t->state == Stopped && t->signal != SIGSTOP && t->signal != SIGTRAP)
			data = t->signal;
		if(trace && data)
			fprint(2, "tid %d: continue %lud\n", pid, (ulong)data);
		if(ptrace(PTRACE_CONT, pid, 0, (void*)data) < 0)
			return -1;
		t->state = Running;
		return 0;
	}
	if(strcmp(msg, "waitstop") == 0) {
		return waitstop(t);
	}
	werrstr("unknown control message '%s'", msg);
	return -1;
}

char*
proctextfile(int pid)
{
	static char buf[1024], pbuf[128];

	snprint(pbuf, sizeof pbuf, "/proc/%d/exe", pid);
	if(readlink(pbuf, buf, sizeof buf) >= 0)
		return strdup(buf);
	if(access(pbuf, AEXIST) >= 0)
		return strdup(pbuf);
	return nil;
}


static int
ptracerw(int type, int xtype, int isr, int pid, uvlong addr, void *v, uint n)
{
	int i;
	uintptr u;
	uchar buf[sizeof(uintptr)];

	for(i=0; i<n; i+=sizeof(uintptr)){
		if(isr){
			errno = 0;
			u = ptrace(type, pid, addr+i, 0);
			if(errno)
				goto ptraceerr;
			if(n-i >= sizeof(uintptr))
				*(uintptr*)((char*)v+i) = u;
			else{
				*(uintptr*)buf = u;
				memmove((char*)v+i, buf, n-i);
			}
		}else{
			if(n-i >= sizeof(uintptr))
				u = *(uintptr*)((char*)v+i);
			else{
				errno = 0;
				u = ptrace(xtype, pid, addr+i, 0);
				if(errno)
					return -1;
				*(uintptr*)buf = u;
				memmove(buf, (char*)v+i, n-i);
				u = *(uintptr*)buf;
			}
			if(ptrace(type, pid, addr+i, u) < 0)
				goto ptraceerr;
		}
	}
	return 0;

ptraceerr:
	werrstr("ptrace %s addr=%#llux pid=%d: %r", isr ? "read" : "write", addr, pid);
	return -1;
}

static int
ptracesegrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr)
{
	return ptracerw(isr ? PTRACE_PEEKDATA : PTRACE_POKEDATA, PTRACE_PEEKDATA,
		isr, map->pid, addr, v, n);
}

// If the debugger is compiled as an x86-64 program,
// then all the ptrace register read/writes are done on
// a 64-bit register set.  If the target program
// is a 32-bit program, the debugger is expected to
// read the bottom half of the relevant registers
// out of the 64-bit set.

// Linux 32-bit is
//	BX CX DX SI DI BP AX DS ES FS GS OrigAX IP CS EFLAGS SP SS

// Linux 64-bit is
//	R15 R14 R13 R12 BP BX R11 R10 R9 R8 AX CX DX SI DI OrigAX IP CS EFLAGS SP SS FSBase GSBase DS ES FS GS

// Go 32-bit is
//	DI SI BP NSP BX DX CX AX GS FS ES DS TRAP ECODE PC CS EFLAGS SP SS

// uint go32tolinux32tab[] = {
//	4, 3, 5, 15, 0, 2, 1, 6, 10, 9, 8, 7, -1, -1, 12, 13, 14, 15, 16
// };
uint go32tolinux64tab[] = {
	14, 13, 4, 19, 5, 12, 11, 10, 26, 25, 24, 23, -1, -1, 16, 17, 18, 19, 20
};
static int
go32tolinux64(uvlong addr)
{
	int r;

	if(addr%4 || addr/4 >= nelem(go32tolinux64tab))
		return -1;
	r = go32tolinux64tab[addr/4];
	if(r < 0)
		return -1;
	return r*8;
}

extern Mach mi386;

static int
go2linux(uvlong addr)
{
	// TODO(rsc): If this file is being compiled in 32-bit mode,
	// need to use the go32tolinux32 table instead.

	if(mach == &mi386)
		return go32tolinux64(addr);

	switch(addr){
	case offsetof(Ureg64, ax):
		return offsetof(struct user_regs_struct, rax);
	case offsetof(Ureg64, bx):
		return offsetof(struct user_regs_struct, rbx);
	case offsetof(Ureg64, cx):
		return offsetof(struct user_regs_struct, rcx);
	case offsetof(Ureg64, dx):
		return offsetof(struct user_regs_struct, rdx);
	case offsetof(Ureg64, si):
		return offsetof(struct user_regs_struct, rsi);
	case offsetof(Ureg64, di):
		return offsetof(struct user_regs_struct, rdi);
	case offsetof(Ureg64, bp):
		return offsetof(struct user_regs_struct, rbp);
	case offsetof(Ureg64, r8):
		return offsetof(struct user_regs_struct, r8);
	case offsetof(Ureg64, r9):
		return offsetof(struct user_regs_struct, r9);
	case offsetof(Ureg64, r10):
		return offsetof(struct user_regs_struct, r10);
	case offsetof(Ureg64, r11):
		return offsetof(struct user_regs_struct, r11);
	case offsetof(Ureg64, r12):
		return offsetof(struct user_regs_struct, r12);
	case offsetof(Ureg64, r13):
		return offsetof(struct user_regs_struct, r13);
	case offsetof(Ureg64, r14):
		return offsetof(struct user_regs_struct, r14);
	case offsetof(Ureg64, r15):
		return offsetof(struct user_regs_struct, r15);
	case offsetof(Ureg64, ds):
		return offsetof(struct user_regs_struct, ds);
	case offsetof(Ureg64, es):
		return offsetof(struct user_regs_struct, es);
	case offsetof(Ureg64, fs):
		return offsetof(struct user_regs_struct, fs);
	case offsetof(Ureg64, gs):
		return offsetof(struct user_regs_struct, gs);
	case offsetof(Ureg64, ip):
		return offsetof(struct user_regs_struct, rip);
	case offsetof(Ureg64, cs):
		return offsetof(struct user_regs_struct, cs);
	case offsetof(Ureg64, flags):
		return offsetof(struct user_regs_struct, eflags);
	case offsetof(Ureg64, sp):
		return offsetof(struct user_regs_struct, rsp);
	case offsetof(Ureg64, ss):
		return offsetof(struct user_regs_struct, ss);
	}
	return -1;
}

static int
ptraceregrw(Map *map, Seg *seg, uvlong addr, void *v, uint n, int isr)
{
	int laddr;
	uvlong u;

	if((laddr = go2linux(addr)) < 0){
		if(isr){
			memset(v, 0, n);
			return 0;
		}
		werrstr("register %llud not available", addr);
		return -1;
	}

	if(isr){
		errno = 0;
		u = ptrace(PTRACE_PEEKUSER, map->pid, laddr, 0);
		if(errno)
			goto ptraceerr;
		switch(n){
		case 1:
			*(uint8*)v = u;
			break;
		case 2:
			*(uint16*)v = u;
			break;
		case 4:
			*(uint32*)v = u;
			break;
		case 8:
			*(uint64*)v = u;
			break;
		default:
			werrstr("bad register size");
			return -1;
		}
	}else{
		switch(n){
		case 1:
			u = *(uint8*)v;
			break;
		case 2:
			u = *(uint16*)v;
			break;
		case 4:
			u = *(uint32*)v;
			break;
		case 8:
			u = *(uint64*)v;
			break;
		default:
			werrstr("bad register size");
			return -1;
		}
		if(ptrace(PTRACE_POKEUSER, map->pid, laddr, (void*)(uintptr)u) < 0)
			goto ptraceerr;
	}
	return 0;

ptraceerr:
	werrstr("ptrace %s register laddr=%d pid=%d n=%d: %r", isr ? "read" : "write", laddr, map->pid, n);
	return -1;
}

char*
procstatus(int pid)
{
	LinuxThread *t;

	t = findthread(pid);
	if(t == nil)
		return "???";

	return statestr[t->state];
}
