tmore pthread - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 281c90a5be6b1ab2280ffa23885fe41e7af80bce
 (DIR) parent ce2a378d46c0bcd00ec08b9bc4ad861c8aa28a2f
 (HTM) Author: rsc <devnull@localhost>
       Date:   Fri, 11 Feb 2005 00:01:49 +0000
       
       more pthread
       
       Diffstat:
         M include/mach.h                      |       7 +++++++
         M src/cmd/acid/acid.h                 |       6 +++++-
         M src/cmd/acid/builtin.c              |      32 ++++++++++++++++++++++---------
         M src/cmd/acid/expr.c                 |       6 +++---
         M src/cmd/acid/util.c                 |       3 ++-
         M src/libmach/Linux.c                 |      41 +++++++++++++++++++++++++++++++
         M src/libmach/mkfile                  |       1 +
         M src/libmach/pthread.c               |     151 ++++++++++---------------------
       
       8 files changed, 132 insertions(+), 115 deletions(-)
       ---
 (DIR) diff --git a/include/mach.h b/include/mach.h
       t@@ -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)
        }
 (DIR) diff --git a/src/cmd/acid/acid.h b/src/cmd/acid/acid.h
       t@@ -132,7 +132,10 @@ struct Store
                        String*        string;
                        List*        l;
                        Node*        cc;
       -                char*        reg;
       +                struct {
       +                        char *name;
       +                        uint        thread;
       +                } reg;
                        Node*        con;
                } u;
        };
       t@@ -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);
 (DIR) diff --git a/src/cmd/acid/builtin.c b/src/cmd/acid/builtin.c
       t@@ -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
       t@@ -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(");
 (DIR) diff --git a/src/cmd/acid/expr.c b/src/cmd/acid/expr.c
       t@@ -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:
       t@@ -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;
       t@@ -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){
 (DIR) diff --git a/src/cmd/acid/util.c b/src/cmd/acid/util.c
       t@@ -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;
        
 (DIR) diff --git a/src/libmach/Linux.c b/src/libmach/Linux.c
       t@@ -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);
 (DIR) diff --git a/src/libmach/mkfile b/src/libmach/mkfile
       t@@ -33,6 +33,7 @@ OFILES=\
                machocorepower.$O\
                machpower.$O\
                map.$O\
       +        pthread.$O\
                regs.$O\
                stabs.$O\
                swap.$O\
 (DIR) diff --git a/src/libmach/pthread.c b/src/libmach/pthread.c
       t@@ -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[] =
        {
       t@@ -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)
        {
       t@@ -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
         */
       t@@ -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;
        }
       t@@ -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;
        }
       t@@ -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;
                        }
                }
       t@@ -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
       t@@ -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