#include <dtracy.h>
-Lock *machlocks;
+static Lock *machlocks;
typedef struct DTKChan DTKChan;
typedef struct DTKAux DTKAux;
enum {
/* Qdir */
Qclone = 1,
+ Qprobes = 2,
};
enum {
CMgo, "go", 1,
};
-DTKChan **dtktab;
-int ndtktab;
+static DTKChan **dtktab;
+static int ndtktab;
static DTKChan *
dtklook(vlong n)
}
if(c->qid.path == Qdir){
if(s-- == 0) goto clone;
+ if(s-- == 0) goto probes;
if(s >= ndtktab) return -1;
if(dtklook(s) == nil) return 0;
sprint(up->genbuf, "%d", s);
devdir(c, (Qid){Qclone, 0, QTFILE}, up->genbuf, 0, eve, 0444, dp);
return 1;
}
+ if(c->qid.path == Qprobes){
+ probes:
+ strcpy(up->genbuf, "probes");
+ devdir(c, (Qid){Qprobes, 0, QTFILE}, up->genbuf, 0, eve, 0444, dp);
+ return 1;
+ }
if(s >= nelem(dtracydir))
return -1;
tab = &dtracydir[s];
p = dtknew();
c->qid.path = QIDPATH(p->idx, Qctl);
}
- p = dtklook(SLOT(c->qid));
- if(SLOT(c->qid) >= 0 && p == nil) error(Enonexist);
- if(FILE(c->qid) != Qdir && !iseve()) error(Eperm);
+ if(c->qid.path == Qprobes){
+ p = nil;
+ }else{
+ p = dtklook(SLOT(c->qid));
+ if(SLOT(c->qid) >= 0 && p == nil) error(Enonexist);
+ if(FILE(c->qid) != Qdir && !iseve()) error(Eperm);
+ }
ch = devopen(c, omode, nil, 0, dtracygen);
if(p != nil) p->ref++;
qunlock(&dtracylock);
}
if(aux->str == nil){
fmtstrinit(&f);
- for(e = c->enab; e != nil; e = e->channext){
- fmtprint(&f, "%d %d %d %s:%s:%s\n", e->epid, e->gr->id, e->gr->reclen,
- e->prob->provider == nil ? "" : e->prob->provider,
- e->prob->function == nil ? "" : e->prob->function,
- e->prob->name == nil ? "" : e->prob->name);
- }
+ for(e = c->enab; e != nil; e = e->channext)
+ fmtprint(&f, "%d %d %d %s\n", e->epid, e->gr->id, e->gr->reclen, e->prob->name);
aux->str = fmtstrflush(&f);
}
return readstr(off, a, n, aux->str);
return m;
}
+static long
+probesread(DTKAux *aux, char *a, long n, vlong off)
+{
+ Fmt f;
+ DTProbe **l;
+ int i, nl;
+
+ if(aux->str == nil){
+ fmtstrinit(&f);
+ nl = dtplist(&l);
+ for(i = 0; i < nl; i++)
+ fmtprint(&f, "%s\n", l[i]->name);
+ dtfree(l);
+ aux->str = fmtstrflush(&f);
+ }
+ return readstr(off, a, n, aux->str);
+}
+
static long
dtracyread(Chan *c, void *a, long n, vlong off)
{
case Qdir:
rc = devdirread(c, a, n, nil, 0, dtracygen);
goto out;
+ case Qprobes:
+ rc = probesread(c->aux, a, n, off);
+ goto out;
default:
error(Egreg);
}
return v;
}
-void
+int
dtmachlock(int i)
{
+ while(i < 0) {
+ i = dtmachlock(m->machno);
+ if(i == m->machno)
+ return i;
+ dtmachunlock(i);
+ i = -1;
+ }
ilock(&machlocks[i]);
+ return i;
}
void
}
}
+extern int peek(char *, char *, int);
+
int
dtpeek(uvlong addr, void *buf, int len)
{
- if((uintptr)addr != addr || up == nil || !okaddr((uintptr) addr, len, 0)) return -1;
- memmove(buf, (void *) addr, len);
- return 0;
+ uintptr a;
+
+ a = addr;
+ if(len == 0) return 0;
+ if(a != addr || a > -(uintptr)len || len < 0) return -1;
+ if(up == nil || up->privatemem || a >= KZERO) return -1;
+ return peek((void *)a, buf, len) > 0 ? -1 : 0;
}