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