Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

include("/sys/lib/acid/syscall");

// print various /proc files
defn fd() {
        rc("cat /proc/"+itoa(pid)+"/fd");
}

defn segment() {
        rc("cat /proc/"+itoa(pid)+"/segment");
}

defn ns() {
        rc("cat /proc/"+itoa(pid)+"/ns");
}

defn qid(qid) {
        complex Qid qid;
        return itoa(qid.path\X)+"."+itoa(qid.vers\X);
}

defn path(p) {
        complex Path p;
        if p != 0 then {
                return *(p.s\s);
        } else
                return "<null>";
}

// print Image cache contents
// requires include("/sys/src/9/xxx/segment.acid")
IHASHSIZE = 64;
defn imagecacheline(h) {
        while h != 0 do {
                complex Image h;
                print (h\X, " ", qid(h.qid), " type ", h.type\D, " ref ", h.ref, " next ", h.next\X, " ", path(h.c.path), "\n");
                h = h.hash;
        }
}

defn imagecache() {
        local i;

        i=0; loop 1,IHASHSIZE do {
                imagecacheline(imagealloc.free[i]);
                i = i+1;
        }
}

// dump channels
defn chan(c) {
        local d, q;

        c = (Chan)c;
        d=(Dev)(*(devtab+4*c.type));
        q=c.qid;
        print("chan(", c\X, "): ref=", c.ref\D, " #", d.dc\r, c.dev\D, " (", q.path, " ", q.vers\D, " ", q.type\X, ")");
        print(" fid=", c.fid\D, " iounit=", c.iounit\D);
        if c.ref != 0 then {
                print(" ", path(c.path), " mchan=", c.mchan\X);
                if c.mchan != 0 then {
                        print(" ", path(c.mchan.path));
                }
        }
        print("\n");
}

defn chans() {
        local c;

        c = (Chan)chanalloc.list;
        while c != 0 do {
                if c.ref != 0 then
                        chan(c);
                c=(Chan)c.link;
        }
}

defn nchans() {
        local c, n;
        
        n = 0;
        c = (Chan)chanalloc.list;
        while c != 0 do {
                if c.ref != 0 then
                        n++;
                c = (Chan)c.link;
        }
        return n;
}

defn activechanlist() {
        local l, n;
        
        l = {};
        c = (Chan)chanalloc.list;
        while c != 0 do {
                if c.ref != 0 then
                        l = append l,c;
                c = (Chan)c.link;
        }
        return l;
}

defn difflist(a, b) {
        local l, x;
        
        l = {};
        while a != {} do {
                x = head a;
                if match(x, b) == -1 then
                        l = append l, x;
                a = tail a;
        }
        return l;
}

_active_chan_list = {};
defn newchans() {
        local l, new;
        
        l = activechanlist();
        if _active_chan_list != {} then
                newerchans(_active_chan_list);
        _active_chan_list = l;
}

defn newerchans(oldlist){
        local new;
        
        new = difflist(activechanlist(), oldlist);
        while new != {} do {
                chan(head new);
                new = tail new;
        }
}

// look for channels that refer to themselves
defn badchans() {
        local bad, c, i, len, mtpt, p;
        
        c = (Chan)chanalloc.list;
        while c != 0 do {
                if c.ref != 0 then {
                        bad = "";
                        p = (Path)c.path;
                        if p != 0 then {
                                path(p);
                                mtpt = p.mtpt;
                                len = p.mlen;
                                i=0; loop 1,len do {
                                        if mtpt[i] == c then
                                                bad = bad+" mtpt self-ref";
                                        i = i+1;
                                }
                        }
                        if bad != "" then
                                print("chan(", c\X, "):", bad, "\n");
                }
                c = (Chan)c.link;
        }
}

// manipulate processes
defn proctab(x) {
        return procalloc.arena+sizeofProc*x;
}

defn proc(p) {
        complex Proc p;
        local s, i;

        if p.state != 0 && p.pid != 0 && p.text != 0 then {     // 0 is Dead
                s = p.psstate;
                if s == 0 then {
                        s = "kproc";
                } else {
                        s = *(s\s);
                }
                print(p\X, " ", p.pid, ": ", *(p.text\s), " ", *(p.user\s), " pc ", p.pc\X, " ", s, " (", *(statename[p.state]\s), ") ut ", p.time[0]\D, " st ", p.time[1]\D, " qpc ", p.qpc\X, "\n");
        }
}

defn procenv(p) {
        complex Proc p;
        local e, v;

        e = p.egrp;
        complex Egrp e;
        v = e.ent;
        while v != 0 do {
                complex Evalue v;
                print(*(v.name\s), "=");
                printstringn(v.value, v.len);
                print("\n");
                v = v.link;
        }
}

KSTACK=4096;

defn procstksize(p) {
        complex Proc p;
        local top, sp;

        if p.state != 0 then {  // 0 is Dead
                top = p.kstack+KSTACK;
                sp = *p.sched;
                print(top-sp\D, "\n");
        }
}

defn procstk(p) {
        complex Proc p;
        local l;

        if p.state != 0 then {  // 0 is Dead
                l = p.sched;
                if objtype=="386" then
                        _stk(gotolabel, *l, linkreg(0), 0);
                else
                        _stk(*(l+4), *l, linkreg(0), 0);
        }
}

defn procs() {
        local i;

        i=0; loop 1,conf.nproc do {
                proc(proctab(i));
                i = i+1;
        }
}

defn stacks() {
        local i, p;

        i=0; loop 1,conf.nproc do {
                p = (Proc)proctab(i);
                if p.state != 0 then {
                        print("=========================================================\n");
                        proc(p);
                        procstk(p);
                }
                i = i+1;
        }
}

defn stacksizes() {
        local i;

        i=0; loop 1,conf.nproc do {
                procstksize(proctab(i));
                i = i+1;
        }
}

// segment-related
defn procsegs(p) {
        complex Proc p;
        local i;

        i=0; loop 1,NSEG do {
                psegment(p.seg[i]);
                i = i+1;
        }
}

segtypes = { "text", "data", "bss", "stack", "shared", "physical", "shdata", "map" };
defn psegment(s) {
        complex Segment s;

        if s != 0 then {
                print(s\X, " ", segtypes[s.type&SG_TYPE], " ", s.base\X, "-", s.top\X, " image ", s.image\X, "\n");
        }
}

// find physical address for an address in a given process
defn procaddr(p, a) {
        complex Proc p;
        local i, s, r;

        r = 0;
        i=0; loop 1,NSEG do {
                s = p.seg[i];
                if s != 0 then {
                        complex Segment s;
                        if s.base <= a && a < s.top then {
                                r = segaddr(s, a);
                        }
                }
                i = i+1;
        }
        return r;
}

// find an address in a given segment
defn segaddr(s, a) {
        complex Segment s;
        local pte, pg;

        a = a - s.base;
        if s.map == 0 || s.mapsize < a/PTEMAPMEM then {
                return 0;
        }

        pte = s.map[a/PTEMAPMEM];
        if pte == 0 then {
                return 0;
        }

        complex Pte pte;
        pg = pte.pages[(a%PTEMAPMEM)/BY2PG];
        if pg == 0 then {
                return 0;
        }

        if pg & 1 then {        // swapped out, return disk address
                return pg&~1;
        }

        complex Page pg;
        return (KZERO|(pg.pa+(a%BY2PG)))\X;
}

defn kzero() {
        return main - (main & 0x0FFFFFFF);
}

// PC only
PTEMAPMEM = (1024*1024);
BY2PG = 4096;
PTEPERTAB = (PTEMAPMEM/BY2PG);
defn up() {
        local mach;

        MACHADDR = KZERO+0x15000;
        mach = MACHADDR;
        complex Mach mach;
        return mach.externup;
}

defn intrcount() {
        local p, pp, t, i, j;

        p = intrtimes;
        i=0;
        loop 1,256 do {
                pp = p[i];
                i=i+1;
                if pp != 0 then {
                        j=0;
                        t=0;
                        loop 1,1000 do {
                                t = t+pp[j];
                                j=j+1;
                        }
                        print(itoa(i, "%5d"), " ", itoa(t, "%11d"), "\n");
                }
        }
}

print("/sys/lib/acid/kernel");

defn needacid(s){
        print("\trc(\"cd /sys/src/9/", kdir, "; mk ", s, ".acid\")\n");
        print("\tinclude(\"/sys/src/9/", kdir, "/", s, ".acid\")\n");
}

defn kinit() {
if (map()[2]) != {} then {      // map has more than two elements -> active proc
        kdir = "unknown";
        KZERO = kzero();
        
        if objtype == "386" then {
                map({"*data", KZERO, 0xffffffff, KZERO});
                kdir="pc";
        }
        if (objtype == "mips" || objtype == "mips2") then {
                kdir = "ch";
        }
        if objtype == "alpha" then {
                map({"*data", KZERO, 0xffffffff, KZERO});
                kdir = "alpha";
        }
        needacid("proc");
}
}