// print system callsdefn printstring(s){ print("\"", s, "\"");} defn printsyscall(name, fmt, arg) { local f, i, a, argp, sl; print(name, "("); i = 0; a = eval arg; while fmt[i] != 0 do { if fmt[i] == 's' then { if *a == 0 then print("nil"); else printstring(*(*a\s)); } else if fmt[i] == 'S' then { argp = *a; argl = {}; while *argp != 0 do { argl = append argl, *(*argp\s); argp++; } print(argl); } else print(fmt(*a, fmt[i])); if fmt[i+1] != 0 then print(", "); i = i+1; a++; } print(")\n");} defn code(*e) { return e; } syscalls = { { 0, {"sysr1", "s", code(0)}}, { 1, {"errstr", "s", code(*syserrstr:arg)}}, { 2, {"bind", "ssX", code(*sysbind:arg)}}, { 3, {"chdir", "s", code(*sysbind:arg)}}, { 4, {"close", "D", code(*sysclose:arg)}}, { 5, {"dup", "DD", code(*sysdup:arg)}}, { 6, {"alarm", "D", code(*sysalarm:arg)}}, { 7, {"exec", "sS", code(*sysexec:arg)}}, { 8, {"exits", "s", code(*sysexits:arg)}}, { 9, {"fsession", "DX", code(*sysfsession:arg)}}, {10, {"fauth", "DX", code(*sysfauth:arg)}}, {11, {"fstat", "DX", code(*sysfstat:arg)}}, {12, {"segbrk", "XX", code(*syssegbrk:arg)}}, {13, {"mount", "DsXs", code(*sysmount:arg)}}, {14, {"open", "sD", code(*sysopen:arg)}}, {15, {"read", "DXD", code(*sysread:arg)}}, {16, {"oseek", "DDD", code(*sysoseek:arg)}}, {17, {"sleep", "D", code(*syssleep:arg)}}, {18, {"stat", "sX", code(*sysstat:arg)}}, {19, {"rfork", "X", code(*sysstat:arg)}}, {20, {"write", "DXD", code(*syswrite:arg)}}, {21, {"pipe", "X", code(*syspipe:arg)}}, {22, {"create", "sDO", code(*syscreate:arg)}}, {23, {"fd2path", "DXD", code(*sysfd2path:arg)}}, {24, {"brk_", "X", code(*sysbrk_:arg)}}, {25, {"remove", "s", code(*sysremove:arg)}}, {26, {"wstat", "sX", code(*syswstat:arg)}}, {27, {"fwstat", "DX", code(*sysfwstat:arg)}}, {28, {"notify", "X", code(*sysnotify:arg)}}, {29, {"noted", "D", code(*sysnoted:arg)}}, {30, {"segattach", "DsXD", code(*syssegattach:arg)}}, {31, {"segdetach", "X", code(*syssegdetach:arg)}}, {32, {"segfree", "XD", code(*syssegfree:arg)}}, {33, {"segflush", "XD", code(*syssegflush:arg)}}, {34, {"rendezvous", "XX", code(*sysrendezvous:arg)}}, {35, {"unmount", "ss", code(*sysunmount:arg)}}, {36, {"wait", "X", code(*syswait:arg)}}, {37, {"read9p", "DXD", code(*sysread9p:arg)}}, {38, {"write9p", "DXD", code(*syswrite9p:arg)}}, {39, {"seek", "DZD", code(*sysseek:arg)}},}; defn syscall() { local n, sl, h, p; map({"*data", 0, 0xffffffff, 0}); n = *syscall:scallnr; sl = syscalls; while sl != {} do { h = head sl; sl = tail sl; if n == h[0] then { p = h[1]; printsyscall(p[0], p[1], p[2]); } }} // 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; } 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; }} // 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 procs() { local i; i=0; loop 1,conf.nproc do { proc(proctab(i)); i = i+1; }} // segment-relateddefn procsegs(p) { complex Proc p; local i; i=0; loop 1,NSEG do { segment(p.seg[i]); i = i+1; }} segtypes = { "text", "data", "bss", "stack", "shared", "physical", "shdata", "map" };defn segment(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");
// print system calls
defn printstring(s)
{
print("\"", s, "\"");
}
defn printsyscall(name, fmt, arg) {
local f, i, a, argp, sl;
print(name, "(");
i = 0;
a = eval arg;
while fmt[i] != 0 do {
if fmt[i] == 's' then {
if *a == 0 then
print("nil");
else
printstring(*(*a\s));
} else if fmt[i] == 'S' then {
argp = *a;
argl = {};
while *argp != 0 do {
argl = append argl, *(*argp\s);
argp++;
}
print(argl);
} else
print(fmt(*a, fmt[i]));
if fmt[i+1] != 0 then
print(", ");
i = i+1;
a++;
}
print(")\n");
}
defn code(*e) { return e; }
syscalls = {
{ 0, {"sysr1", "s", code(0)}},
{ 1, {"errstr", "s", code(*syserrstr:arg)}},
{ 2, {"bind", "ssX", code(*sysbind:arg)}},
{ 3, {"chdir", "s", code(*sysbind:arg)}},
{ 4, {"close", "D", code(*sysclose:arg)}},
{ 5, {"dup", "DD", code(*sysdup:arg)}},
{ 6, {"alarm", "D", code(*sysalarm:arg)}},
{ 7, {"exec", "sS", code(*sysexec:arg)}},
{ 8, {"exits", "s", code(*sysexits:arg)}},
{ 9, {"fsession", "DX", code(*sysfsession:arg)}},
{10, {"fauth", "DX", code(*sysfauth:arg)}},
{11, {"fstat", "DX", code(*sysfstat:arg)}},
{12, {"segbrk", "XX", code(*syssegbrk:arg)}},
{13, {"mount", "DsXs", code(*sysmount:arg)}},
{14, {"open", "sD", code(*sysopen:arg)}},
{15, {"read", "DXD", code(*sysread:arg)}},
{16, {"oseek", "DDD", code(*sysoseek:arg)}},
{17, {"sleep", "D", code(*syssleep:arg)}},
{18, {"stat", "sX", code(*sysstat:arg)}},
{19, {"rfork", "X", code(*sysstat:arg)}},
{20, {"write", "DXD", code(*syswrite:arg)}},
{21, {"pipe", "X", code(*syspipe:arg)}},
{22, {"create", "sDO", code(*syscreate:arg)}},
{23, {"fd2path", "DXD", code(*sysfd2path:arg)}},
{24, {"brk_", "X", code(*sysbrk_:arg)}},
{25, {"remove", "s", code(*sysremove:arg)}},
{26, {"wstat", "sX", code(*syswstat:arg)}},
{27, {"fwstat", "DX", code(*sysfwstat:arg)}},
{28, {"notify", "X", code(*sysnotify:arg)}},
{29, {"noted", "D", code(*sysnoted:arg)}},
{30, {"segattach", "DsXD", code(*syssegattach:arg)}},
{31, {"segdetach", "X", code(*syssegdetach:arg)}},
{32, {"segfree", "XD", code(*syssegfree:arg)}},
{33, {"segflush", "XD", code(*syssegflush:arg)}},
{34, {"rendezvous", "XX", code(*sysrendezvous:arg)}},
{35, {"unmount", "ss", code(*sysunmount:arg)}},
{36, {"wait", "X", code(*syswait:arg)}},
{37, {"read9p", "DXD", code(*sysread9p:arg)}},
{38, {"write9p", "DXD", code(*syswrite9p:arg)}},
{39, {"seek", "DZD", code(*sysseek:arg)}},
};
defn syscall() {
local n, sl, h, p;
map({"*data", 0, 0xffffffff, 0});
n = *syscall:scallnr;
sl = syscalls;
while sl != {} do {
h = head sl;
sl = tail sl;
if n == h[0] then {
p = h[1];
printsyscall(p[0], p[1], p[2]);
}
}
}
// 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;
} 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;
}
}
// 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 procs() {
local i;
i=0; loop 1,conf.nproc do {
proc(proctab(i));
i = i+1;
}
}
// segment-related
defn procsegs(p) {
complex Proc p;
local i;
i=0; loop 1,NSEG do {
segment(p.seg[i]);
i = i+1;
}
}
segtypes = { "text", "data", "bss", "stack", "shared", "physical", "shdata", "map" };
defn segment(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");