xref: /plan9-contrib/sys/src/9k/port/syscallfmt.c (revision 406c76facc4b13aa2a55454bf4091aab9f03da22)
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