2 |
- |
1 |
// print system calls
|
|
|
2 |
defn printstring(s)
|
|
|
3 |
{
|
|
|
4 |
print("\"", s, "\"");
|
|
|
5 |
}
|
|
|
6 |
|
|
|
7 |
defn printtextordata(addr, n)
|
|
|
8 |
{
|
|
|
9 |
local a, i;
|
|
|
10 |
|
|
|
11 |
a = addr\c;
|
|
|
12 |
i = 0;
|
|
|
13 |
loop 1, n do {
|
|
|
14 |
if (a[i]>=127) then {
|
|
|
15 |
print(fmt(addr, 'X'), ", ", n\D);
|
|
|
16 |
return {};
|
|
|
17 |
}
|
|
|
18 |
i = i+1;
|
|
|
19 |
}
|
|
|
20 |
|
|
|
21 |
print("\"");
|
|
|
22 |
printstringn(addr, n);
|
|
|
23 |
print("\"");
|
|
|
24 |
}
|
|
|
25 |
|
|
|
26 |
defn printstringn(s, n)
|
|
|
27 |
{
|
|
|
28 |
local m;
|
|
|
29 |
|
|
|
30 |
m = n;
|
|
|
31 |
if (m > 100) then m = 100;
|
|
|
32 |
loop 1,m do {
|
|
|
33 |
print(*(s\c)); s=s+1;
|
|
|
34 |
}
|
|
|
35 |
if(m != n) then print("...");
|
|
|
36 |
}
|
|
|
37 |
|
|
|
38 |
defn printsyscall(name, fmt, arg) {
|
|
|
39 |
local f, i, a, argp, sl;
|
|
|
40 |
|
|
|
41 |
print(name, "(");
|
|
|
42 |
i = 0;
|
|
|
43 |
a = eval arg;
|
|
|
44 |
while fmt[i] != 0 do {
|
|
|
45 |
if fmt[i] == 's' then {
|
|
|
46 |
if *a == 0 then
|
|
|
47 |
print("nil");
|
|
|
48 |
else
|
|
|
49 |
printstring(*(*a\s));
|
|
|
50 |
} else if fmt[i] == 'S' then {
|
|
|
51 |
argp = *a;
|
|
|
52 |
argl = {};
|
|
|
53 |
while *argp != 0 do {
|
|
|
54 |
argl = append argl, *(*argp\s);
|
|
|
55 |
argp++;
|
|
|
56 |
}
|
|
|
57 |
print(argl);
|
|
|
58 |
} else if (fmt[i] == 'Z') && (~*a == 0) then {
|
|
|
59 |
print("-1");
|
|
|
60 |
a++; // advance extra word for quadword
|
|
|
61 |
} else if (fmt[i] == 'Y') || (fmt[i] == 'V') then {
|
|
|
62 |
print(fmt(*a, fmt[i]));
|
|
|
63 |
a++; // advance extra word for quadword
|
|
|
64 |
} else if (fmt[i] == 'T') then {
|
|
|
65 |
if *a == 0 then
|
|
|
66 |
print("nil");
|
|
|
67 |
else
|
|
|
68 |
printtextordata(*a, a[1]);
|
|
|
69 |
} else
|
|
|
70 |
print(fmt(*a, fmt[i]));
|
|
|
71 |
if fmt[i+1] != 0 then
|
|
|
72 |
print(", ");
|
|
|
73 |
i = i+1;
|
|
|
74 |
a++;
|
|
|
75 |
}
|
|
|
76 |
print(")\n");
|
|
|
77 |
}
|
|
|
78 |
|
|
|
79 |
defn code(*e) { return e; }
|
|
|
80 |
|
|
|
81 |
syscalls = {
|
|
|
82 |
{ 0, {"sysr1", "s", code(0)}},
|
|
|
83 |
{ 1, {"_errstr", "s", code(*sys_errstr:arg)}},
|
|
|
84 |
{ 2, {"bind", "ssX", code(*sysbind:arg)}},
|
|
|
85 |
{ 3, {"chdir", "s", code(*sysbind:arg)}},
|
|
|
86 |
{ 4, {"close", "D", code(*sysclose:arg)}},
|
|
|
87 |
{ 5, {"dup", "DD", code(*sysdup:arg)}},
|
|
|
88 |
{ 6, {"alarm", "D", code(*sysalarm:arg)}},
|
|
|
89 |
{ 7, {"exec", "sS", code(*sysexec:arg)}},
|
|
|
90 |
{ 8, {"exits", "s", code(*sysexits:arg)}},
|
|
|
91 |
{ 9, {"_fsession", "DX", code(*sys_fsession:arg)}},
|
|
|
92 |
{10, {"fauth", "DX", code(*sysfauth:arg)}},
|
|
|
93 |
{11, {"_fstat", "DX", code(*sys_fstat:arg)}},
|
|
|
94 |
{12, {"segbrk", "XX", code(*syssegbrk:arg)}},
|
|
|
95 |
{13, {"_mount", "DsXs", code(*sys_mount:arg)}},
|
|
|
96 |
{14, {"open", "sD", code(*sysopen:arg)}},
|
|
|
97 |
{15, {"_read", "DXD", code(*sys_read:arg)}},
|
|
|
98 |
{16, {"oseek", "DDD", code(*sysoseek:arg)}},
|
|
|
99 |
{17, {"sleep", "D", code(*syssleep:arg)}},
|
|
|
100 |
{18, {"_stat", "sX", code(*sys_stat:arg)}},
|
|
|
101 |
{19, {"rfork", "X", code(*sysstat:arg)}},
|
|
|
102 |
{20, {"_write", "DXD", code(*sys_write:arg)}},
|
|
|
103 |
{21, {"pipe", "X", code(*syspipe:arg)}},
|
|
|
104 |
{22, {"create", "sDO", code(*syscreate:arg)}},
|
|
|
105 |
{23, {"fd2path", "DXD", code(*sysfd2path:arg)}},
|
|
|
106 |
{24, {"brk_", "X", code(*sysbrk_:arg)}},
|
|
|
107 |
{25, {"remove", "s", code(*sysremove:arg)}},
|
|
|
108 |
{26, {"_wstat", "sX", code(*sys_wstat:arg)}},
|
|
|
109 |
{27, {"_fwstat", "DX", code(*sys_fwstat:arg)}},
|
|
|
110 |
{28, {"notify", "X", code(*sysnotify:arg)}},
|
|
|
111 |
{29, {"noted", "D", code(*sysnoted:arg)}},
|
|
|
112 |
{30, {"segattach", "DsXD", code(*syssegattach:arg)}},
|
|
|
113 |
{31, {"segdetach", "X", code(*syssegdetach:arg)}},
|
|
|
114 |
{32, {"segfree", "XD", code(*syssegfree:arg)}},
|
|
|
115 |
{33, {"segflush", "XD", code(*syssegflush:arg)}},
|
|
|
116 |
{34, {"rendezvous", "XX", code(*sysrendezvous:arg)}},
|
|
|
117 |
{35, {"unmount", "ss", code(*sysunmount:arg)}},
|
|
|
118 |
{36, {"_wait", "X", code(*sys_wait:arg)}},
|
|
|
119 |
{39, {"seek", "XDVD", code(*sysseek:arg)}},
|
|
|
120 |
{40, {"fversion", "DDsD", code(*sysfversion:arg)}},
|
|
|
121 |
{41, {"errstr", "TD", code(*syserrstr:arg)}},
|
|
|
122 |
{42, {"stat", "sXD", code(*sysstat:arg)}},
|
|
|
123 |
{43, {"fstat", "DXD", code(*sysfstat:arg)}},
|
|
|
124 |
{44, {"wstat", "sXD", code(*syswstat:arg)}},
|
|
|
125 |
{45, {"fwstat", "DXD", code(*sysfwstat:arg)}},
|
|
|
126 |
{46, {"mount", "DDsXs", code(*sysmount:arg)}},
|
|
|
127 |
{47, {"await", "TD", code(*sysawait:arg)}},
|
|
|
128 |
{50, {"pread", "DXDZ", code(*syspread:arg)}},
|
|
|
129 |
{51, {"pwrite", "DTDZ", code(*syspwrite:arg)}},
|
|
|
130 |
};
|
|
|
131 |
|
|
|
132 |
defn syscall() {
|
|
|
133 |
local n, sl, h, p;
|
|
|
134 |
|
|
|
135 |
map({"*data", 0, 0xffffffff, 0});
|
|
|
136 |
n = *syscall:scallnr;
|
|
|
137 |
sl = syscalls;
|
|
|
138 |
while sl != {} do {
|
|
|
139 |
h = head sl;
|
|
|
140 |
sl = tail sl;
|
|
|
141 |
|
|
|
142 |
if n == h[0] then {
|
|
|
143 |
p = h[1];
|
|
|
144 |
printsyscall(p[0], p[1], p[2]);
|
|
|
145 |
}
|
|
|
146 |
}
|
|
|
147 |
}
|
|
|
148 |
|
|
|
149 |
defn UPCSPRET() {
|
|
|
150 |
// return sys call number, address of first argument, location of syscall return value
|
|
|
151 |
if objtype == "386" then
|
|
|
152 |
return { code(*(*PC-4)), code(*SP+4), code(*AX) };
|
|
|
153 |
if (objtype == "mips") || (objtype == "mips2") then
|
|
|
154 |
return { code(*(*PC-4) & 0xffff), code(*SP+4), code(*R1) };
|
|
|
155 |
if objtype == "arm" then
|
|
|
156 |
return { code(*(*PC-4) & 0xffff), code(*SP+4), code(*R0) }; // untested
|
|
|
157 |
if objtype == "alpha" then
|
|
|
158 |
return { code(*(*PC-4) & 0xffff), code(*SP+4), code(*R0) }; // untested
|
|
|
159 |
}
|
|
|
160 |
|
|
|
161 |
defn trapoffset() {
|
|
|
162 |
// return offset from entry point to trap instr
|
|
|
163 |
if objtype == "386" then return 5;
|
|
|
164 |
if objtype == "mips" then return 8;
|
|
|
165 |
if objtype == "mips2" then return 8;
|
|
|
166 |
if objtype == "arm" then return 8; // untested
|
|
|
167 |
if objtype == "alpha" then return 8; // untested
|
|
|
168 |
}
|
|
|
169 |
|
|
|
170 |
defn trapreason() {
|
|
|
171 |
// return reason for trap
|
|
|
172 |
if objtype == "386" then return reason(*TRAP);
|
|
|
173 |
if objtype == "mips" then return reason(*CAUSE);
|
|
|
174 |
if objtype == "mips2" then return reason(*CAUSE);
|
|
|
175 |
if objtype == "arm" then return "unknown trap"; // untested
|
|
|
176 |
if objtype == "alpha" then return reason(cause); // untested
|
|
|
177 |
}
|
|
|
178 |
|
|
|
179 |
|
|
|
180 |
defn usyscall() { // gives args for system call in user level; not useful with -k
|
|
|
181 |
local n, sl, h, p;
|
|
|
182 |
|
|
|
183 |
// stopped at TRAP instruction in system call library
|
|
|
184 |
pcsp = UPCSPRET();
|
|
|
185 |
n = eval pcsp[0];
|
|
|
186 |
sl = syscalls;
|
|
|
187 |
while sl != {} do {
|
|
|
188 |
h = head sl;
|
|
|
189 |
sl = tail sl;
|
|
|
190 |
|
|
|
191 |
if n == h[0] then {
|
|
|
192 |
p = h[1];
|
|
|
193 |
printsyscall(p[0], p[1], pcsp[1]);
|
|
|
194 |
}
|
|
|
195 |
}
|
|
|
196 |
}
|