1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6
7 #include "/sys/src/libc/9syscall/sys.h"
8
9 /*
10 * Print functions for system call tracing.
11 */
12 static void
fmtrwdata(Fmt * f,char * a,int n,char * suffix)13 fmtrwdata(Fmt* f, char* a, int n, char* suffix)
14 {
15 int i;
16 char *t;
17
18 if(a == nil){
19 fmtprint(f, "0x0%s", suffix);
20 return;
21 }
22 a = validaddr(a, n, 0);
23 t = smalloc(n+1);
24 for(i = 0; i < n; i++){
25 if(a[i] > 0x20 && a[i] < 0x7f)
26 t[i] = a[i];
27 else
28 t[i] = '.';
29 }
30
31 fmtprint(f, " %#p/\"%s\"%s", a, t, suffix);
32 free(t);
33 }
34
35 static void
fmtuserstring(Fmt * f,char * a,char * suffix)36 fmtuserstring(Fmt* f, char* a, char* suffix)
37 {
38 int n;
39 char *t;
40
41 if(a == nil){
42 fmtprint(f, "0/\"\"%s", suffix);
43 return;
44 }
45 a = validaddr(a, 1, 0);
46 n = ((char*)vmemchr(a, 0, 0x7fffffff) - a) + 1;
47 t = smalloc(n);
48 memmove(t, a, n);
49 t[n] = 0;
50 fmtprint(f, "%#p/\"%s\"%s", a, t, suffix);
51 free(t);
52 }
53
54 /*
55 */
56 void
syscallfmt(int syscallno,va_list list)57 syscallfmt(int syscallno, va_list list)
58 {
59 long l;
60 Fmt fmt;
61 void *v;
62 vlong vl;
63 uintptr p;
64 int i[2], len;
65 char *a, **argv;
66
67 fmtstrinit(&fmt);
68 fmtprint(&fmt, "%d %s ", up->pid, up->text);
69
70 if(syscallno > nsyscall)
71 fmtprint(&fmt, " %d ", syscallno);
72 else
73 fmtprint(&fmt, "%s ", systab[syscallno].n);
74
75 if(up->syscalltrace != nil)
76 free(up->syscalltrace);
77
78 switch(syscallno){
79 case SYSR1:
80 p = va_arg(list, uintptr);
81 fmtprint(&fmt, "%#p", p);
82 break;
83 case _ERRSTR: /* deprecated */
84 case CHDIR:
85 case EXITS:
86 case REMOVE:
87 a = va_arg(list, char*);
88 fmtuserstring(&fmt, a, "");
89 break;
90 case BIND:
91 a = va_arg(list, char*);
92 fmtuserstring(&fmt, a, " ");
93 a = va_arg(list, char*);
94 fmtuserstring(&fmt, a, " ");
95 i[0] = va_arg(list, int);
96 fmtprint(&fmt, "%#ux", i[0]);
97 break;
98 case CLOSE:
99 case NOTED:
100 i[0] = va_arg(list, int);
101 fmtprint(&fmt, "%d", i[0]);
102 break;
103 case DUP:
104 i[0] = va_arg(list, int);
105 i[1] = va_arg(list, int);
106 fmtprint(&fmt, "%d %d", i[0], i[1]);
107 break;
108 case ALARM:
109 l = va_arg(list, unsigned long);
110 fmtprint(&fmt, "%#lud ", l);
111 break;
112 case EXEC:
113 a = va_arg(list, char*);
114 fmtuserstring(&fmt, a, "");
115 argv = va_arg(list, char**);
116 evenaddr(PTR2UINT(argv));
117 for(;;){
118 a = *(char**)validaddr(argv, sizeof(char**), 0);
119 if(a == nil)
120 break;
121 fmtprint(&fmt, " ");
122 fmtuserstring(&fmt, a, "");
123 argv++;
124 }
125 break;
126 case _FSESSION: /* deprecated */
127 case _FSTAT: /* deprecated */
128 case _FWSTAT: /* obsolete */
129 i[0] = va_arg(list, int);
130 a = va_arg(list, char*);
131 fmtprint(&fmt, "%d %#p", i[0], a);
132 break;
133 case FAUTH:
134 i[0] = va_arg(list, int);
135 a = va_arg(list, char*);
136 fmtprint(&fmt, "%d", i[0]);
137 fmtuserstring(&fmt, a, "");
138 break;
139 case SEGBRK:
140 case RENDEZVOUS:
141 v = va_arg(list, void*);
142 fmtprint(&fmt, "%#p ", v);
143 v = va_arg(list, void*);
144 fmtprint(&fmt, "%#p", v);
145 break;
146 case _MOUNT: /* deprecated */
147 i[0] = va_arg(list, int);
148 fmtprint(&fmt, "%d ", i[0]);
149 a = va_arg(list, char*);
150 fmtuserstring(&fmt, a, " ");
151 i[0] = va_arg(list, int);
152 fmtprint(&fmt, "%#ux ", i[0]);
153 a = va_arg(list, char*);
154 fmtuserstring(&fmt, a, "");
155 break;
156 case OPEN:
157 a = va_arg(list, char*);
158 fmtuserstring(&fmt, a, " ");
159 i[0] = va_arg(list, int);
160 fmtprint(&fmt, "%#ux", i[0]);
161 break;
162 case OSEEK: /* deprecated */
163 i[0] = va_arg(list, int);
164 l = va_arg(list, long);
165 i[1] = va_arg(list, int);
166 fmtprint(&fmt, "%d %ld %d", i[0], l, i[1]);
167 break;
168 case SLEEP:
169 l = va_arg(list, long);
170 fmtprint(&fmt, "%ld", l);
171 break;
172 case _STAT: /* obsolete */
173 case _WSTAT: /* obsolete */
174 a = va_arg(list, char*);
175 fmtuserstring(&fmt, a, " ");
176 a = va_arg(list, char*);
177 fmtprint(&fmt, "%#p", a);
178 break;
179 case RFORK:
180 i[0] = va_arg(list, int);
181 fmtprint(&fmt, "%#ux", i[0]);
182 break;
183 case PIPE:
184 case BRK_:
185 v = va_arg(list, int*);
186 fmtprint(&fmt, "%#p", v);
187 break;
188 case CREATE:
189 a = va_arg(list, char*);
190 fmtuserstring(&fmt, a, " ");
191 i[0] = va_arg(list, int);
192 i[1] = va_arg(list, int);
193 fmtprint(&fmt, "%#ux %#ux", i[0], i[1]);
194 break;
195 case FD2PATH:
196 case FSTAT:
197 case FWSTAT:
198 i[0] = va_arg(list, int);
199 a = va_arg(list, char*);
200 l = va_arg(list, unsigned long);
201 fmtprint(&fmt, "%d %#p %lud", i[0], a, l);
202 break;
203 case NOTIFY:
204 case SEGDETACH:
205 case _WAIT: /* deprecated */
206 v = va_arg(list, void*);
207 fmtprint(&fmt, "%#p", v);
208 break;
209 case SEGATTACH:
210 i[0] = va_arg(list, int);
211 fmtprint(&fmt, "%d ", i[0]);
212 a = va_arg(list, char*);
213 fmtuserstring(&fmt, a, " ");
214 /*FALLTHROUGH*/
215 case SEGFREE:
216 case SEGFLUSH:
217 v = va_arg(list, void*);
218 l = va_arg(list, unsigned long);
219 fmtprint(&fmt, "%#p %lud", v, l);
220 break;
221 case UNMOUNT:
222 a = va_arg(list, char*);
223 fmtuserstring(&fmt, a, " ");
224 a = va_arg(list, char*);
225 fmtuserstring(&fmt, a, "");
226 break;
227 case SEMACQUIRE:
228 case SEMRELEASE:
229 v = va_arg(list, int*);
230 i[0] = va_arg(list, int);
231 fmtprint(&fmt, "%#p %d", v, i[0]);
232 break;
233 case TSEMACQUIRE:
234 v = va_arg(list, long*);
235 l = va_arg(list, ulong);
236 fmtprint(&fmt, "%#p %ld", v, l);
237 break;
238 case SEEK:
239 v = va_arg(list, vlong*);
240 i[0] = va_arg(list, int);
241 vl = va_arg(list, vlong);
242 i[1] = va_arg(list, int);
243 fmtprint(&fmt, "%#p %d %#llux %d", v, i[0], vl, i[1]);
244 break;
245 case FVERSION:
246 i[0] = va_arg(list, int);
247 i[1] = va_arg(list, int);
248 fmtprint(&fmt, "%d %d ", i[0], i[1]);
249 a = va_arg(list, char*);
250 fmtuserstring(&fmt, a, " ");
251 l = va_arg(list, unsigned long);
252 fmtprint(&fmt, "%lud", l);
253 break;
254 case WSTAT:
255 case STAT:
256 a = va_arg(list, char*);
257 fmtuserstring(&fmt, a, " ");
258 /*FALLTHROUGH*/
259 case ERRSTR:
260 case AWAIT:
261 a = va_arg(list, char*);
262 l = va_arg(list, unsigned long);
263 fmtprint(&fmt, "%#p %lud", a, l);
264 break;
265 case MOUNT:
266 i[0] = va_arg(list, int);
267 i[1] = va_arg(list, int);
268 fmtprint(&fmt, "%d %d ", i[0], i[1]);
269 a = va_arg(list, char*);
270 fmtuserstring(&fmt, a, " ");
271 i[0] = va_arg(list, int);
272 fmtprint(&fmt, "%#ux ", i[0]);
273 a = va_arg(list, char*);
274 fmtuserstring(&fmt, a, "");
275 break;
276 case _READ: /* deprecated */
277 case PREAD:
278 i[0] = va_arg(list, int);
279 v = va_arg(list, void*);
280 l = va_arg(list, long);
281 fmtprint(&fmt, "%d %#p %ld", i[0], v, l);
282 if(syscallno == PREAD){
283 vl = va_arg(list, vlong);
284 fmtprint(&fmt, " %lld", vl);
285 }
286 break;
287 case _WRITE: /* deprecated */
288 case PWRITE:
289 i[0] = va_arg(list, int);
290 v = va_arg(list, void*);
291 l = va_arg(list, long);
292 fmtprint(&fmt, "%d ", i[0]);
293 len = MIN(l, 64);
294 fmtrwdata(&fmt, v, len, " ");
295 fmtprint(&fmt, "%ld", l);
296 if(syscallno == PWRITE){
297 vl = va_arg(list, vlong);
298 fmtprint(&fmt, " %lld", vl);
299 }
300 break;
301 case NSEC:
302 /* compilers on 32-bit systems insert &ret as only argument */
303 if (sizeof(void *) < sizeof(vlong))
304 fmtprint(&fmt, "%#p", va_arg(list, vlong*));
305 break;
306 }
307 up->syscalltrace = fmtstrflush(&fmt);
308 }
309
310 void
sysretfmt(int syscallno,va_list list,Ar0 * ar0,uvlong start,uvlong stop)311 sysretfmt(int syscallno, va_list list, Ar0* ar0, uvlong start, uvlong stop)
312 {
313 long l;
314 void* v;
315 Fmt fmt;
316 vlong vl;
317 int i, len;
318 char *a, *errstr;
319
320 fmtstrinit(&fmt);
321
322 if(up->syscalltrace)
323 free(up->syscalltrace);
324
325 errstr = "\"\"";
326 switch(syscallno){
327 default:
328 if(ar0->i == -1)
329 errstr = up->syserrstr;
330 fmtprint(&fmt, " = %d", (int)ar0->i);
331 break;
332 case ALARM:
333 case _WRITE:
334 case PWRITE:
335 if(ar0->l == -1)
336 errstr = up->syserrstr;
337 fmtprint(&fmt, " = %ld", (long)ar0->l);
338 break;
339 case NSEC:
340 fmtprint(&fmt, " = %lld", ar0->vl);
341 break;
342 case EXEC:
343 case SEGBRK:
344 case SEGATTACH:
345 case RENDEZVOUS:
346 if(ar0->v == (void*)-1)
347 errstr = up->syserrstr;
348 fmtprint(&fmt, " = %#p", ar0->v);
349 break;
350 case AWAIT:
351 a = va_arg(list, char*);
352 l = va_arg(list, unsigned long);
353 if(ar0->i > 0){
354 fmtuserstring(&fmt, a, " ");
355 fmtprint(&fmt, "%lud = %d", l, (int)ar0->i);
356 }
357 else{
358 fmtprint(&fmt, "%#p/\"\" %lud = %d", a, l, (int)ar0->i);
359 errstr = up->syserrstr;
360 }
361 break;
362 case _ERRSTR:
363 case ERRSTR:
364 a = va_arg(list, char*);
365 if(syscallno == _ERRSTR)
366 l = 64;
367 else
368 l = va_arg(list, unsigned long);
369 if(ar0->i > 0){
370 fmtuserstring(&fmt, a, " ");
371 fmtprint(&fmt, "%lud = %d", l, (int)ar0->i);
372 }
373 else{
374 fmtprint(&fmt, "\"\" %lud = %d", l, (int)ar0->i);
375 errstr = up->syserrstr;
376 }
377 break;
378 case FD2PATH:
379 i = va_arg(list, int);
380 USED(i);
381 a = va_arg(list, char*);
382 l = va_arg(list, unsigned long);
383 if(ar0->i > 0){
384 fmtuserstring(&fmt, a, " ");
385 fmtprint(&fmt, "%lud = %d", l, (int)ar0->i);
386 }
387 else{
388 fmtprint(&fmt, "\"\" %lud = %d", l, (int)ar0->i);
389 errstr = up->syserrstr;
390 }
391 break;
392 case _READ:
393 case PREAD:
394 i = va_arg(list, int);
395 USED(i);
396 v = va_arg(list, void*);
397 l = va_arg(list, long);
398 if(ar0->l > 0){
399 len = MIN(ar0->l, 64);
400 fmtrwdata(&fmt, v, len, "");
401 }
402 else{
403 fmtprint(&fmt, "/\"\"");
404 errstr = up->syserrstr;
405 }
406 fmtprint(&fmt, " %ld", l);
407 if(syscallno == PREAD){
408 vl = va_arg(list, vlong);
409 fmtprint(&fmt, " %lld", vl);
410 }
411 fmtprint(&fmt, " = %d", (int)ar0->i);
412 break;
413 }
414 fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop);
415
416 up->syscalltrace = fmtstrflush(&fmt);
417 }
418