]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/syscallfmt.c
syscallfmt: use up->syserrstr instead of up->errstr (import from sources)
[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((ulong)a, n, 0);
24         t = smalloc(n+1);
25         for(i = 0; i < n; i++)
26                 if(a[i] > 0x20 && a[i] < 0x7f)  /* printable ascii? */
27                         t[i] = a[i];
28                 else
29                         t[i] = '.';
30
31         fmtprint(f, " %#p/\"%s\"%s", a, t, suffix);
32         free(t);
33 }
34
35 static void
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         validaddr((ulong)a, 1, 0);
46         n = ((char*)vmemchr(a, 0, 0x7fffffff) - a) + 1;
47         t = smalloc(n+1);
48         memmove(t, a, n);
49         t[n] = 0;
50         fmtprint(f, "%#p/\"%s\"%s", a, t, suffix);
51         free(t);
52 }
53
54 void
55 syscallfmt(int syscallno, ulong pc, va_list list)
56 {
57         long l;
58         Fmt fmt;
59         void *v;
60         vlong vl;
61         uintptr p;
62         int i[2], len;
63         char *a, **argv;
64
65         fmtstrinit(&fmt);
66         fmtprint(&fmt, "%uld %s ", up->pid, up->text);
67
68         if(syscallno > nsyscall)
69                 fmtprint(&fmt, " %d ", syscallno);
70         else
71                 fmtprint(&fmt, "%s ", sysctab[syscallno]?
72                         sysctab[syscallno]: "huh?");
73
74         fmtprint(&fmt, "%ulx ", pc);
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                         validaddr((ulong)argv, sizeof(char**), 0);
119                         a = *(char **)argv;
120                         if(a == nil)
121                                 break;
122                         fmtprint(&fmt, " ");
123                         fmtuserstring(&fmt, a, "");
124                         argv++;
125                 }
126                 break;
127         case _FSESSION:                                 /* deprecated */
128         case _FSTAT:                                    /* deprecated */
129         case _FWSTAT:                                   /* obsolete */
130                 i[0] = va_arg(list, int);
131                 a = va_arg(list, char*);
132                 fmtprint(&fmt, "%d %#p", i[0], a);
133                 break;
134         case FAUTH:
135                 i[0] = va_arg(list, int);
136                 a = va_arg(list, char*);
137                 fmtprint(&fmt, "%d", i[0]);
138                 fmtuserstring(&fmt, a, "");
139                 break;
140         case SEGBRK:
141         case RENDEZVOUS:
142                 v = va_arg(list, void*);
143                 fmtprint(&fmt, "%#p ", v);
144                 v = va_arg(list, void*);
145                 fmtprint(&fmt, "%#p", v);
146                 break;
147         case _MOUNT:                                    /* deprecated */
148                 i[0] = va_arg(list, int);
149                 fmtprint(&fmt, "%d ", i[0]);
150                 a = va_arg(list, char*);
151                 fmtuserstring(&fmt, a, " ");
152                 i[0] = va_arg(list, int);
153                 fmtprint(&fmt, "%#ux ", i[0]);
154                 a = va_arg(list, char*);
155                 fmtuserstring(&fmt, a, "");
156                 break;
157         case OPEN:
158                 a = va_arg(list, char*);
159                 fmtuserstring(&fmt, a, " ");
160                 i[0] = va_arg(list, int);
161                 fmtprint(&fmt, "%#ux", i[0]);
162                 break;
163         case OSEEK:                                     /* deprecated */
164                 i[0] = va_arg(list, int);
165                 l = va_arg(list, long);
166                 i[1] = va_arg(list, int);
167                 fmtprint(&fmt, "%d %ld %d", i[0], l, i[1]);
168                 break;
169         case SLEEP:
170                 l = va_arg(list, long);
171                 fmtprint(&fmt, "%ld", l);
172                 break;
173         case _STAT:                                     /* obsolete */
174         case _WSTAT:                                    /* obsolete */
175                 a = va_arg(list, char*);
176                 fmtuserstring(&fmt, a, " ");
177                 a = va_arg(list, char*);
178                 fmtprint(&fmt, "%#p", a);
179                 break;
180         case RFORK:
181                 i[0] = va_arg(list, int);
182                 fmtprint(&fmt, "%#ux", i[0]);
183                 break;
184         case PIPE:
185         case BRK_:
186                 v = va_arg(list, int*);
187                 fmtprint(&fmt, "%#p", v);
188                 break;
189         case CREATE:
190                 a = va_arg(list, char*);
191                 fmtuserstring(&fmt, a, " ");
192                 i[0] = va_arg(list, int);
193                 i[1] = va_arg(list, int);
194                 fmtprint(&fmt, "%#ux %#ux", i[0], i[1]);
195                 break;
196         case FD2PATH:
197         case FSTAT:
198         case FWSTAT:
199                 i[0] = va_arg(list, int);
200                 a = va_arg(list, char*);
201                 l = va_arg(list, unsigned long);
202                 fmtprint(&fmt, "%d %#p %lud", i[0], a, l);
203                 break;
204         case NOTIFY:
205         case SEGDETACH:
206         case _WAIT:                                     /* deprecated */
207                 v = va_arg(list, void*);
208                 fmtprint(&fmt, "%#p", v);
209                 break;
210         case SEGATTACH:
211                 i[0] = va_arg(list, int);
212                 fmtprint(&fmt, "%d ", i[0]);
213                 a = va_arg(list, char*);
214                 fmtuserstring(&fmt, a, " ");
215                 /*FALLTHROUGH*/
216         case SEGFREE:
217         case SEGFLUSH:
218                 v = va_arg(list, void*);
219                 l = va_arg(list, unsigned long);
220                 fmtprint(&fmt, "%#p %lud", v, l);
221                 break;
222         case UNMOUNT:
223                 a = va_arg(list, char*);
224                 fmtuserstring(&fmt, a, " ");
225                 a = va_arg(list, char*);
226                 fmtuserstring(&fmt, a, "");
227                 break;
228         case SEMACQUIRE:
229         case SEMRELEASE:
230                 v = va_arg(list, int*);
231                 i[0] = va_arg(list, int);
232                 fmtprint(&fmt, "%#p %d", v, i[0]);
233                 break;
234         case TSEMACQUIRE:
235                 v = va_arg(list, int*);
236                 l = va_arg(list, ulong);
237                 fmtprint(&fmt, "%#p %ld", v, l);
238                 break;
239         case SEEK:
240                 v = va_arg(list, vlong*);
241                 i[0] = va_arg(list, int);
242                 vl = va_arg(list, vlong);
243                 i[1] = va_arg(list, int);
244                 fmtprint(&fmt, "%#p %d %#llux %d", v, i[0], vl, i[1]);
245                 break;
246         case FVERSION:
247                 i[0] = va_arg(list, int);
248                 i[1] = va_arg(list, int);
249                 fmtprint(&fmt, "%d %d ", i[0], i[1]);
250                 a = va_arg(list, char*);
251                 fmtuserstring(&fmt, a, " ");
252                 l = va_arg(list, unsigned long);
253                 fmtprint(&fmt, "%lud", l);
254                 break;
255         case WSTAT:
256         case STAT:
257                 a = va_arg(list, char*);
258                 fmtuserstring(&fmt, a, " ");
259                 /*FALLTHROUGH*/
260         case ERRSTR:
261         case AWAIT:
262                 a = va_arg(list, char*);
263                 l = va_arg(list, unsigned long);
264                 fmtprint(&fmt, "%#p %lud", a, l);
265                 break;
266         case MOUNT:
267                 i[0] = va_arg(list, int);
268                 i[1] = va_arg(list, int);
269                 fmtprint(&fmt, "%d %d ", i[0], i[1]);
270                 a = va_arg(list, char*);
271                 fmtuserstring(&fmt, a, " ");
272                 i[0] = va_arg(list, int);
273                 fmtprint(&fmt, "%#ux ", i[0]);
274                 a = va_arg(list, char*);
275                 fmtuserstring(&fmt, a, "");
276                 break;
277         case _READ:                                     /* deprecated */
278         case PREAD:
279                 i[0] = va_arg(list, int);
280                 v = va_arg(list, void*);
281                 l = va_arg(list, long);
282                 fmtprint(&fmt, "%d %#p %ld", i[0], v, l);
283                 if(syscallno == PREAD){
284                         vl = va_arg(list, vlong);
285                         fmtprint(&fmt, " %lld", vl);
286                 }
287                 break;
288         case _WRITE:                                    /* deprecated */
289         case PWRITE:
290                 i[0] = va_arg(list, int);
291                 v = va_arg(list, void*);
292                 l = va_arg(list, long);
293                 fmtprint(&fmt, "%d ", i[0]);
294                 len = MIN(l, 64);
295                 fmtrwdata(&fmt, v, len, " ");
296                 fmtprint(&fmt, "%ld", l);
297                 if(syscallno == PWRITE){
298                         vl = va_arg(list, vlong);
299                         fmtprint(&fmt, " %lld", vl);
300                 }
301                 break;
302         }
303
304         up->syscalltrace = fmtstrflush(&fmt);
305 }
306
307 void
308 sysretfmt(int syscallno, va_list list, long ret, uvlong start, uvlong stop)
309 {
310         long l;
311         void* v;
312         Fmt fmt;
313         vlong vl;
314         int i, len;
315         char *a, *errstr;
316
317         fmtstrinit(&fmt);
318
319         if(up->syscalltrace)
320                 free(up->syscalltrace);
321
322         errstr = "\"\"";
323         switch(syscallno){
324         default:
325         case ALARM:
326         case _WRITE:
327         case PWRITE:
328                 if(ret == -1)
329                         errstr = up->syserrstr;
330                 fmtprint(&fmt, " = %ld", ret);
331                 break;
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, ret);
346                 }
347                 else{
348                         fmtprint(&fmt, "%#p/\"\" %lud = %ld", a, l, 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, ret);
362                 }
363                 else{
364                         fmtprint(&fmt, "\"\" %lud = %ld", l, 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, ret);
376                 }
377                 else{
378                         fmtprint(&fmt, "\"\" %lud = %ld", l, 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", ret);
402                 break;
403         }
404         fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop);
405         up->syscalltrace = fmtstrflush(&fmt);
406 }