include("/sys/lib/acid/syscall"); // print various /proc filesdefn 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 cname(c) { complex Cname c; if c != 0 then { return *(c.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, " ", cname(h.c.name), "\n"); h = h.hash; }} defn imagecache() { local i; i=0; loop 1,IHASHSIZE do { imagecacheline(imagealloc.free[i]); i = i+1; }} // dump channelsdefn chan(c) { local d, q; c = (Chan)c; d=(Dev)(*(devtab+4*c.type)); q=c.qid; print(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(" ", cname(c.name), " mchan=", c.mchan\X); if c.mchan != 0 then { print(" ", cname(c.mchan.name)); } } print("\n");} defn chans() { local c; c = (Chan)chanalloc.list; while c != 0 do { chan(c); c=(Chan)c.link; }} // manipulate processesdefn proctab(x) { return procalloc.arena+sizeofProc*x;} defn proc(p) { complex Proc p; local s, i; if p.state != 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.entries; 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-relateddefn 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 processdefn 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 segmentdefn 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 (0x80000000|(pg.pa+(a%BY2PG)))\X;} // PC onlyMACHADDR = 0x80004000;PTEMAPMEM = (1024*1024);BY2PG = 4096;PTEPERTAB = (PTEMAPMEM/BY2PG);defn up() { local mach; mach = MACHADDR; complex Mach mach; return mach.externup;} print("/sys/lib/acid/kernel"); if (map()[2]) != {} then { // map has more than two elements -> active proc if objtype == "386" then { map({"*data", 0x80000000, 0xffffffff, 0x80000000}); print("\trc(\"cd /sys/src/9/pc; mk proc.acid\");"); print("\tinclude(\"/sys/src/9/pc/proc.acid\")"); } if (objtype == "mips" || objtype == "mips2") then { print("\trc(\"cd /sys/src/9/ch; mk proc.acid\");"); print("\tinclude(\"/sys/src/9/ch/proc.acid\")"); } if objtype == "alpha" then { map({"*data", 0x80000000, 0xffffffff, 0x80000000}); print("\trc(\"cd /sys/src/9/alphapc; mk proc.acid\");"); print("\tinclude(\"/sys/src/9/alphapc/proc.acid\")"); }}
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 cname(c) {
complex Cname c;
if c != 0 then {
return *(c.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, " ", cname(h.c.name), "\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(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(" ", cname(c.name), " mchan=", c.mchan\X);
if c.mchan != 0 then {
print(" ", cname(c.mchan.name));
}
}
print("\n");
}
defn chans() {
local c;
c = (Chan)chanalloc.list;
while c != 0 do {
chan(c);
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 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.entries;
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 (0x80000000|(pg.pa+(a%BY2PG)))\X;
}
// PC only
MACHADDR = 0x80004000;
PTEMAPMEM = (1024*1024);
BY2PG = 4096;
PTEPERTAB = (PTEMAPMEM/BY2PG);
defn up() {
local mach;
mach = MACHADDR;
complex Mach mach;
return mach.externup;
}
print("/sys/lib/acid/kernel");
if (map()[2]) != {} then { // map has more than two elements -> active proc
if objtype == "386" then {
map({"*data", 0x80000000, 0xffffffff, 0x80000000});
print("\trc(\"cd /sys/src/9/pc; mk proc.acid\");");
print("\tinclude(\"/sys/src/9/pc/proc.acid\")");
}
if (objtype == "mips" || objtype == "mips2") then {
print("\trc(\"cd /sys/src/9/ch; mk proc.acid\");");
print("\tinclude(\"/sys/src/9/ch/proc.acid\")");
}
if objtype == "alpha" then {
map({"*data", 0x80000000, 0xffffffff, 0x80000000});
print("\trc(\"cd /sys/src/9/alphapc; mk proc.acid\");");
print("\tinclude(\"/sys/src/9/alphapc/proc.acid\")");
}
}