more pthread
This commit is contained in:
parent
ce2a378d46
commit
281c90a5be
8 changed files with 132 additions and 115 deletions
|
|
@ -540,6 +540,13 @@ struct ps_prochandle
|
||||||
int pid;
|
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;
|
extern int machdebug;
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,10 @@ struct Store
|
||||||
String* string;
|
String* string;
|
||||||
List* l;
|
List* l;
|
||||||
Node* cc;
|
Node* cc;
|
||||||
char* reg;
|
struct {
|
||||||
|
char *name;
|
||||||
|
uint thread;
|
||||||
|
} reg;
|
||||||
Node* con;
|
Node* con;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
@ -258,6 +261,7 @@ String* strnode(char*);
|
||||||
String* strnodlen(char*, int);
|
String* strnodlen(char*, int);
|
||||||
#define system acidsystem
|
#define system acidsystem
|
||||||
char* system(void);
|
char* system(void);
|
||||||
|
Regs* threadregs(uint);
|
||||||
int trlist(Map*, Regs*, ulong, ulong, Symbol*, int);
|
int trlist(Map*, Regs*, ulong, ulong, Symbol*, int);
|
||||||
void unwind(void);
|
void unwind(void);
|
||||||
void userinit(void);
|
void userinit(void);
|
||||||
|
|
|
||||||
|
|
@ -325,22 +325,33 @@ xkill(Node *r, Node *args)
|
||||||
void
|
void
|
||||||
xregister(Node *r, Node *args)
|
xregister(Node *r, Node *args)
|
||||||
{
|
{
|
||||||
|
int tid;
|
||||||
Regdesc *rp;
|
Regdesc *rp;
|
||||||
Node res;
|
Node res, resid;
|
||||||
|
Node *av[Maxarg];
|
||||||
|
|
||||||
if(args == 0)
|
na = 0;
|
||||||
error("register(string): arg count");
|
flatten(av, args);
|
||||||
expr(args, &res);
|
if(na != 1 && na != 2)
|
||||||
|
error("register(name[, threadid]): arg count");
|
||||||
|
|
||||||
|
expr(av[0], &res);
|
||||||
if(res.type != TSTRING)
|
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)
|
if((rp = regdesc(res.store.u.string->string)) == nil)
|
||||||
error("no such register");
|
error("no such register");
|
||||||
|
|
||||||
r->op = OCONST;
|
r->op = OCONST;
|
||||||
r->type = TREG;
|
r->type = TREG;
|
||||||
r->store.fmt = rp->format;
|
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
|
void
|
||||||
|
|
@ -1127,7 +1138,10 @@ patom(char type, Store *res)
|
||||||
|
|
||||||
switch(type){
|
switch(type){
|
||||||
case TREG:
|
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;
|
return;
|
||||||
case TCON:
|
case TCON:
|
||||||
Bprint(bout, "refconst(");
|
Bprint(bout, "refconst(");
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ oindm(Node *n, Node *res)
|
||||||
res->store.comt = l.store.comt;
|
res->store.comt = l.store.comt;
|
||||||
break;
|
break;
|
||||||
case TREG:
|
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;
|
res->store.comt = l.store.comt;
|
||||||
break;
|
break;
|
||||||
case TCON:
|
case TCON:
|
||||||
|
|
@ -334,7 +334,7 @@ oasgn(Node *n, Node *res)
|
||||||
case OINDM:
|
case OINDM:
|
||||||
expr(lp->left, &aes);
|
expr(lp->left, &aes);
|
||||||
if(aes.type == TREG)
|
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
|
else
|
||||||
windir(cormap, aes, n->right, res);
|
windir(cormap, aes, n->right, res);
|
||||||
break;
|
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);
|
werrstr("*%s: register %s not mapped", name, v->store.u.reg);
|
||||||
return -1;
|
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:
|
case TCON:
|
||||||
n = v->store.u.con;
|
n = v->store.u.con;
|
||||||
if(n->op != OCONST || n->type != TINT){
|
if(n->op != OCONST || n->type != TINT){
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,8 @@ varreg(void)
|
||||||
l = mkvar(r->name);
|
l = mkvar(r->name);
|
||||||
v = l->v;
|
v = l->v;
|
||||||
v->set = 1;
|
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->store.fmt = r->format;
|
||||||
v->type = TREG;
|
v->type = TREG;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -447,6 +447,47 @@ proctextfile(int pid)
|
||||||
return nil;
|
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
|
#if 0
|
||||||
snprint(buf, sizeof buf, "/proc/%d/maps", pid);
|
snprint(buf, sizeof buf, "/proc/%d/maps", pid);
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ OFILES=\
|
||||||
machocorepower.$O\
|
machocorepower.$O\
|
||||||
machpower.$O\
|
machpower.$O\
|
||||||
map.$O\
|
map.$O\
|
||||||
|
pthread.$O\
|
||||||
regs.$O\
|
regs.$O\
|
||||||
stabs.$O\
|
stabs.$O\
|
||||||
swap.$O\
|
swap.$O\
|
||||||
|
|
|
||||||
|
|
@ -5,103 +5,10 @@
|
||||||
#include <sys/procfs.h> /* psaddr_t */
|
#include <sys/procfs.h> /* psaddr_t */
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <mach.h>
|
#include <mach.h>
|
||||||
|
#include "ureg386.h"
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
typedef struct Ptprog Ptprog;
|
static char *terr(int);
|
||||||
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 *tderrstr[] =
|
static char *tderrstr[] =
|
||||||
{
|
{
|
||||||
|
|
@ -132,6 +39,8 @@ static char *tderrstr[] =
|
||||||
[TD_NOTLS] "there is no TLS segment in the given module",
|
[TD_NOTLS] "there is no TLS segment in the given module",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static td_thragent_t *ta;
|
||||||
|
|
||||||
static char*
|
static char*
|
||||||
terr(int e)
|
terr(int e)
|
||||||
{
|
{
|
||||||
|
|
@ -144,6 +53,45 @@ terr(int e)
|
||||||
return tderrstr[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
|
* bottom-end functions for libthread_db to call
|
||||||
*/
|
*/
|
||||||
|
|
@ -192,7 +140,7 @@ ps_lcontinue(const struct ps_prochandle *ph)
|
||||||
int
|
int
|
||||||
ps_pdread(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz)
|
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_ERR;
|
||||||
return PS_OK;
|
return PS_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -200,7 +148,7 @@ ps_pdread(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz)
|
||||||
int
|
int
|
||||||
ps_pdwrite(struct ps_prochandle *ph, psaddr_t addr, void *v, size_t sz)
|
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_ERR;
|
||||||
return PS_OK;
|
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);
|
return sys_ps_lgetregs(ph, lwp, regs);
|
||||||
for(i=0; i<corhdr->nthread; i++){
|
for(i=0; i<corhdr->nthread; i++){
|
||||||
if(corhdr->thread[i].id == lwp){
|
if(corhdr->thread[i].id == lwp){
|
||||||
ureg2prgregset(corhdr->thread[i].ureg, regs);
|
ureg2linux386(corhdr->thread[i].ureg, (UregLinux386*)regs);
|
||||||
return PS_OK;
|
return PS_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -248,7 +196,7 @@ ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lwp, prfpregset_t *fpregs)
|
||||||
if(corhdr == nil)
|
if(corhdr == nil)
|
||||||
return sys_ps_lgetfpregs(ph, lwp, fpregs);
|
return sys_ps_lgetfpregs(ph, lwp, fpregs);
|
||||||
/* BUG - Look in core dump. */
|
/* BUG - Look in core dump. */
|
||||||
return PS_ERR:
|
return PS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -265,7 +213,8 @@ ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lwp, prfpregset_t *fpregs)
|
||||||
int
|
int
|
||||||
ps_get_thread_area(struct ps_prochandle *ph, lwpid_t lwp, int xxx, psaddr_t *addr)
|
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
|
int
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue