more pthread
diff --git a/include/mach.h b/include/mach.h
index 7fbffc4..a91468a 100644
--- a/include/mach.h
+++ b/include/mach.h
@@ -540,6 +540,13 @@
 	int pid;
 };
 
+int		sys_ps_lgetregs(struct ps_prochandle*, uint, void*);
+int		sys_ps_lgetfpregs(struct ps_prochandle*, uint, void*);
+int		sys_ps_lsetregs(struct ps_prochandle*, uint, void*);
+int		sys_ps_lsetfpregs(struct ps_prochandle*, uint, void*);
+Regs*	threadregs(uint);
+int		pthreaddbinit(void);
+
 extern int machdebug;
 #if defined(__cplusplus)
 }
diff --git a/src/cmd/acid/acid.h b/src/cmd/acid/acid.h
index 866816e..95f768e 100644
--- a/src/cmd/acid/acid.h
+++ b/src/cmd/acid/acid.h
@@ -132,7 +132,10 @@
 		String*	string;
 		List*	l;
 		Node*	cc;
-		char*	reg;
+		struct {
+			char *name;
+			uint	thread;
+		} reg;
 		Node*	con;
 	} u;
 };
@@ -258,6 +261,7 @@
 String*	strnodlen(char*, int);
 #define system acidsystem
 char*	system(void);
+Regs*	threadregs(uint);
 int	trlist(Map*, Regs*, ulong, ulong, Symbol*, int);
 void	unwind(void);
 void	userinit(void);
diff --git a/src/cmd/acid/builtin.c b/src/cmd/acid/builtin.c
index 316c492..8dbc176 100644
--- a/src/cmd/acid/builtin.c
+++ b/src/cmd/acid/builtin.c
@@ -325,22 +325,33 @@
 void
 xregister(Node *r, Node *args)
 {
+	int tid;
 	Regdesc *rp;
-	Node res;
+	Node res, resid;
+	Node *av[Maxarg];
 
-	if(args == 0)
-		error("register(string): arg count");
-	expr(args, &res);
+	na = 0;
+	flatten(av, args);
+	if(na != 1 && na != 2)
+		error("register(name[, threadid]): arg count");
+
+	expr(av[0], &res);
 	if(res.type != TSTRING)
-		error("register(string): arg type");
-
+		error("register(name[, threadid]): arg type: name should be string");
+	tid = 0;
+	if(na == 2){
+		expr(av[1], &resid);
+		if(resid.type != TINT)
+			error("register(name[, threadid]): arg type: threadid should be int");
+		tid = resid.store.u.ival;
+	}
 	if((rp = regdesc(res.store.u.string->string)) == nil)
 		error("no such register");
-
 	r->op = OCONST;
 	r->type = TREG;
 	r->store.fmt = rp->format;
-	r->store.u.reg = rp->name;
+	r->store.u.reg.name = rp->name;
+	r->store.u.reg.thread = tid;
 }
 
 void
@@ -1127,7 +1138,10 @@
 
 	switch(type){
 	case TREG:
-		Bprint(bout, "register(\"%s\")", res->u.reg);
+		if(res->u.reg.thread)
+			Bprint(bout, "register(\"%s\", 0x%ux)", res->u.reg.name, res->u.reg.thread);
+		else
+			Bprint(bout, "register(\"%s\")", res->u.reg.name);
 		return;
 	case TCON:
 		Bprint(bout, "refconst(");
diff --git a/src/cmd/acid/expr.c b/src/cmd/acid/expr.c
index 6a0430d..822d7bb 100644
--- a/src/cmd/acid/expr.c
+++ b/src/cmd/acid/expr.c
@@ -135,7 +135,7 @@
 		res->store.comt = l.store.comt;
 		break;
 	case TREG:
-		indirreg(correg, l.store.u.reg, l.store.fmt, res);
+		indirreg(threadregs(l.store.u.reg.thread), l.store.u.reg.name, l.store.fmt, res);
 		res->store.comt = l.store.comt;
 		break;
 	case TCON:
@@ -334,7 +334,7 @@
 	case OINDM:
 		expr(lp->left, &aes);
 		if(aes.type == TREG)
-			windirreg(correg, aes.store.u.reg, n->right, res);
+			windirreg(threadregs(aes.store.u.reg.thread), aes.store.u.reg.name, n->right, res);
 		else
 			windir(cormap, aes, n->right, res);
 		break;
@@ -1097,7 +1097,7 @@
 			werrstr("*%s: register %s not mapped", name, v->store.u.reg);
 			return -1;
 		}
-		return rget(correg, v->store.u.reg, u);
+		return rget(threadregs(v->store.u.reg.thread), v->store.u.reg.name, u);
 	case TCON:
 		n = v->store.u.con;
 		if(n->op != OCONST || n->type != TINT){
diff --git a/src/cmd/acid/util.c b/src/cmd/acid/util.c
index 3ea3c4c..3e6a313 100644
--- a/src/cmd/acid/util.c
+++ b/src/cmd/acid/util.c
@@ -216,7 +216,8 @@
 		l = mkvar(r->name);
 		v = l->v;
 		v->set = 1;
-		v->store.u.reg = r->name;
+		v->store.u.reg.name = r->name;
+		v->store.u.reg.thread = 0;
 		v->store.fmt = r->format;
 		v->type = TREG;
 
diff --git a/src/libmach/Linux.c b/src/libmach/Linux.c
index ff72740..893ef6b 100644
--- a/src/libmach/Linux.c
+++ b/src/libmach/Linux.c
@@ -447,6 +447,47 @@
 	return nil;
 }
 
+int
+sys_ps_lgetregs(struct ps_prochandle *ph, uint tid, void *regs)
+{
+	int i, oldpid;
+	uint u, *uregs;
+	
+	oldpid = corpid;
+	ptraceattach(tid);
+	uregs = (uint*)regs;
+	for(i=0; i<sizeof(UregLinux386)/sizeof(uint); i++){
+		errno = 0;
+		u = ptrace(PTRACE_PEEKUSER, tid, 4*i, 0);
+		if(errno)
+			return 1;
+		uregs[i] = u;
+	}
+	ptraceattach(oldpid);
+	return 0;
+}
+
+int
+sys_ps_lsetregs(struct ps_prochandle *ph, uint tid, void *regs)
+{
+	return 1;
+}
+
+int
+sys_ps_lgetfpregs(struct ps_prochandle *ph, uint tid, void *regs)
+{
+	return 1;
+}
+
+
+int
+sys_ps_lsetfpregs(struct ps_prochandle *ph, uint tid, void *regs)
+{
+	return 1;
+}
+
+
+
 
 #if 0
 	snprint(buf, sizeof buf, "/proc/%d/maps", pid);
diff --git a/src/libmach/mkfile b/src/libmach/mkfile
index a6d6507..470f745 100644
--- a/src/libmach/mkfile
+++ b/src/libmach/mkfile
@@ -33,6 +33,7 @@
 	machocorepower.$O\
 	machpower.$O\
 	map.$O\
+	pthread.$O\
 	regs.$O\
 	stabs.$O\
 	swap.$O\
diff --git a/src/libmach/pthread.c b/src/libmach/pthread.c
index 8a2b60a..010887d 100644
--- a/src/libmach/pthread.c
+++ b/src/libmach/pthread.c
@@ -5,103 +5,10 @@
 #include <sys/procfs.h>	/* psaddr_t */
 #include <libc.h>
 #include <mach.h>
+#include "ureg386.h"
+#include "elf.h"
 
-typedef struct Ptprog Ptprog;
-struct Pprog
-{
-	Pthread *t;
-	uint nt;
-};
-
-typedef struct Pthread Pthread;
-struct Pthread
-{
-	td_thrhandle_t handle;
-};
-
-void
-pthreadattach(int pid)
-{
-	
-}
-
-void pthreadattach()
-	set up mapping
-
-Regs *pthreadregs()
-int npthread();
-
-
-
-static int td_get_allthreads(td_thragent_t*, td_thrhandle_t**);
-static int terr(int);
-
-
-Regs*
-threadregs()
-{
-
-}
-
-
-
-typedef struct AllThread AllThread;
-struct AllThread
-{
-	td_thrhandle_t *a;
-	int n;
-	int err;
-};
-
-static int
-thritercb(const td_thrhandle_t *th, void *cb)
-{
-	td_thrhandle_t **p;
-	AllThread *a;
-	int n;
-
-	a = cb;
-	if((a->n&(a->n-1)) == 0){
-		if(a->n == 0)
-			n = 1;
-		else
-			n = a->n<<1;
-		if((p = realloc(a->a, n*sizeof a->a[0])) == 0){
-			a->err = -1;
-			return -1;	/* stop iteration */
-		}
-		a->a = p;
-	}
-	a->a[a->n++] = *th;
-	return 0;
-}
-
-int
-td_get_allthreads(td_thragent_t *ta, td_thrhandle_t **pall)
-{
-	int e;
-	AllThread a;
-
-	a.a = nil;
-	a.n = 0;
-	a.err = 0;
-	if((e = td_ta_thr_iter(ta, thritercb, &a, 
-		TD_THR_ANY_STATE,
-		TD_THR_LOWEST_PRIORITY,
-		TD_SIGNO_MASK,
-		TD_THR_ANY_USER_FLAGS)) != TD_OK){
-		werrstr("%s", terr(e));
-		return -1;
-	}
-
-	if(a.err){
-		free(a.a);
-		return -1;
-	}
-
-	*pall = a.a;
-	return a.n;
-}
+static char *terr(int);
 
 static char *tderrstr[] =
 {
@@ -132,6 +39,8 @@
 [TD_NOTLS]		"there is no TLS segment in the given module",
 };
 
+static td_thragent_t *ta;
+
 static char*
 terr(int e)
 {
@@ -144,6 +53,45 @@
 	return tderrstr[e];
 }
 
+int
+pthreaddbinit(void)
+{
+	int e;
+	struct ps_prochandle p;
+	
+	p.pid = 0;
+	if((e = td_ta_new(&p, &ta)) != TD_OK){
+		werrstr("%s", terr(e));
+		return -1;
+	}
+	return 0;
+}
+
+Regs*
+threadregs(uint tid)
+{
+	int e;
+	static UregRegs r;
+	static Ureg u;
+	td_thrhandle_t th;
+	prgregset_t regs;
+
+	if(tid == 0)
+		return correg;
+	if(!ta)
+		pthreaddbinit();
+	if((e = td_ta_map_id2thr(ta, tid, &th)) != TD_OK
+	|| (e = td_thr_getgregs(&th, regs)) != TD_OK){
+		werrstr("reading thread registers: %s", terr(e));
+		return nil;
+	}
+	linux2ureg386((UregLinux386*)regs, &u);
+	r.r.rw = _uregrw;
+	r.ureg = (uchar*)&u;
+	return &r.r;
+}
+
+
 /*
  * bottom-end functions for libthread_db to call
  */
@@ -192,7 +140,7 @@
 int
 ps_pdread(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz)
 {
-	if(get1(ph->map, addr, v, sz) < 0)
+	if(get1(cormap, (ulong)addr, v, sz) < 0)
 		return PS_ERR;
 	return PS_OK;
 }
@@ -200,7 +148,7 @@
 int
 ps_pdwrite(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz)
 {
-	if(put1(ph->map, addr, v, sz) < 0)
+	if(put1(cormap, (ulong)addr, v, sz) < 0)
 		return PS_ERR;
 	return PS_OK;
 }
@@ -227,7 +175,7 @@
 		return sys_ps_lgetregs(ph, lwp, regs);
 	for(i=0; i<corhdr->nthread; i++){
 		if(corhdr->thread[i].id == lwp){
-			ureg2prgregset(corhdr->thread[i].ureg, regs);
+			ureg2linux386(corhdr->thread[i].ureg, (UregLinux386*)regs);
 			return PS_OK;
 		}
 	}
@@ -248,7 +196,7 @@
 	if(corhdr == nil)
 		return sys_ps_lgetfpregs(ph, lwp, fpregs);
 	/* BUG - Look in core dump. */
-	return PS_ERR:
+	return PS_ERR;
 }
 
 int
@@ -265,7 +213,8 @@
 int
 ps_get_thread_area(struct ps_prochandle *ph, lwpid_t lwp, int xxx, psaddr_t *addr)
 {
-	return sys_ps_get_thread_area(ph, lwp, xxx, addr);
+	return PS_ERR;
+//	return sys_ps_get_thread_area(ph, lwp, xxx, addr);
 }
 
 int