diff options
author | rsc <devnull@localhost> | 2005-02-11 00:01:49 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-02-11 00:01:49 +0000 |
commit | 281c90a5be6b1ab2280ffa23885fe41e7af80bce (patch) | |
tree | c26a67c58f869a3a6821f1a0ae980af03d4eb430 | |
parent | ce2a378d46c0bcd00ec08b9bc4ad861c8aa28a2f (diff) | |
download | plan9port-281c90a5be6b1ab2280ffa23885fe41e7af80bce.tar.gz plan9port-281c90a5be6b1ab2280ffa23885fe41e7af80bce.tar.bz2 plan9port-281c90a5be6b1ab2280ffa23885fe41e7af80bce.zip |
more pthread
-rw-r--r-- | include/mach.h | 7 | ||||
-rw-r--r-- | src/cmd/acid/acid.h | 6 | ||||
-rw-r--r-- | src/cmd/acid/builtin.c | 32 | ||||
-rw-r--r-- | src/cmd/acid/expr.c | 6 | ||||
-rw-r--r-- | src/cmd/acid/util.c | 3 | ||||
-rw-r--r-- | src/libmach/Linux.c | 41 | ||||
-rw-r--r-- | src/libmach/mkfile | 1 | ||||
-rw-r--r-- | src/libmach/pthread.c | 151 |
8 files changed, 132 insertions, 115 deletions
diff --git a/include/mach.h b/include/mach.h index 7fbffc45..a91468a2 100644 --- a/include/mach.h +++ b/include/mach.h @@ -540,6 +540,13 @@ struct ps_prochandle 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 866816e8..95f768e8 100644 --- a/src/cmd/acid/acid.h +++ b/src/cmd/acid/acid.h @@ -132,7 +132,10 @@ struct Store String* string; List* l; Node* cc; - char* reg; + struct { + char *name; + uint thread; + } reg; Node* con; } u; }; @@ -258,6 +261,7 @@ String* strnode(char*); 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 316c4921..8dbc1765 100644 --- a/src/cmd/acid/builtin.c +++ b/src/cmd/acid/builtin.c @@ -325,22 +325,33 @@ xkill(Node *r, Node *args) 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); - if(res.type != TSTRING) - error("register(string): arg type"); + 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(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 @@ patom(char type, Store *res) 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 6a0430dc..822d7bb8 100644 --- a/src/cmd/acid/expr.c +++ b/src/cmd/acid/expr.c @@ -135,7 +135,7 @@ oindm(Node *n, Node *res) 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 @@ oasgn(Node *n, Node *res) 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 @@ acidregsrw(Regs *r, char *name, ulong *u, int isr) 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 3ea3c4c0..3e6a313d 100644 --- a/src/cmd/acid/util.c +++ b/src/cmd/acid/util.c @@ -216,7 +216,8 @@ varreg(void) 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 ff727409..893ef6b4 100644 --- a/src/libmach/Linux.c +++ b/src/libmach/Linux.c @@ -447,6 +447,47 @@ proctextfile(int pid) 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 a6d6507e..470f7454 100644 --- a/src/libmach/mkfile +++ b/src/libmach/mkfile @@ -33,6 +33,7 @@ OFILES=\ 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 8a2b60a9..010887d3 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 @@ static char *tderrstr[] = [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 @@ terr(int e) 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 @@ ps_lcontinue(const struct ps_prochandle *ph) 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 @@ ps_pdread(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz) 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 @@ ps_lgetregs(struct ps_prochandle *ph, lwpid_t lwp, prgregset_t regs) 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 @@ ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lwp, prfpregset_t *fpregs) 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 @@ ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lwp, prfpregset_t *fpregs) 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 |