xref: /openbsd-src/usr.bin/kdump/kdump.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*	$OpenBSD: kdump.c,v 1.62 2011/07/28 10:33:36 otto Exp $	*/
2 
3 /*-
4  * Copyright (c) 1988, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/param.h>
33 #include <sys/time.h>
34 #include <sys/uio.h>
35 #include <sys/ktrace.h>
36 #include <sys/ioctl.h>
37 #include <sys/malloc.h>
38 #include <sys/namei.h>
39 #include <sys/ptrace.h>
40 #include <sys/sem.h>
41 #include <sys/shm.h>
42 #include <sys/socket.h>
43 #include <sys/sysctl.h>
44 #include <sys/socket.h>
45 #include <sys/un.h>
46 #include <sys/vmmeter.h>
47 #include <sys/stat.h>
48 #include <sys/tty.h>
49 #include <netinet/in.h>
50 #include <arpa/inet.h>
51 #define _KERNEL
52 #include <sys/errno.h>
53 #undef _KERNEL
54 #include <ddb/db_var.h>
55 #include <machine/cpu.h>
56 
57 #include <ctype.h>
58 #include <err.h>
59 #include <fcntl.h>
60 #include <signal.h>
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <stdint.h>
64 #include <string.h>
65 #include <grp.h>
66 #include <pwd.h>
67 #include <unistd.h>
68 #include <vis.h>
69 
70 #include "ktrace.h"
71 #include "kdump.h"
72 #include "kdump_subr.h"
73 #include "extern.h"
74 
75 int timestamp, decimal, iohex, fancy = 1, tail, maxdata = INT_MAX, resolv;
76 char *tracefile = DEF_TRACEFILE;
77 struct ktr_header ktr_header;
78 pid_t pid = -1;
79 
80 #define TIME_FORMAT	"%b %e %T %Y"
81 #define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
82 
83 #include <sys/syscall.h>
84 
85 #include <compat/linux/linux_syscall.h>
86 
87 #define KTRACE
88 #define PTRACE
89 #define NFSCLIENT
90 #define NFSSERVER
91 #define SYSVSEM
92 #define SYSVMSG
93 #define SYSVSHM
94 #define LFS
95 #include <kern/syscalls.c>
96 
97 #include <compat/linux/linux_syscalls.c>
98 #undef KTRACE
99 #undef PTRACE
100 #undef NFSCLIENT
101 #undef NFSSERVER
102 #undef SYSVSEM
103 #undef SYSVMSG
104 #undef SYSVSHM
105 #undef LFS
106 
107 struct emulation {
108 	char *name;		/* Emulation name */
109 	char **sysnames;	/* Array of system call names */
110 	int  nsysnames;		/* Number of */
111 };
112 
113 static struct emulation emulations[] = {
114 	{ "native",	syscallnames,		SYS_MAXSYSCALL },
115 	{ "linux",	linux_syscallnames,	LINUX_SYS_MAXSYSCALL },
116 	{ NULL,		NULL,			0 }
117 };
118 
119 static struct emulation *current;
120 static struct emulation *def_emul;
121 
122 struct pid_emul {
123 	struct emulation *e;
124 	pid_t p;
125 };
126 
127 static struct pid_emul *pe_table;
128 static size_t pe_size;
129 
130 
131 static char *ptrace_ops[] = {
132 	"PT_TRACE_ME",	"PT_READ_I",	"PT_READ_D",	"PT_READ_U",
133 	"PT_WRITE_I",	"PT_WRITE_D",	"PT_WRITE_U",	"PT_CONTINUE",
134 	"PT_KILL",	"PT_ATTACH",	"PT_DETACH",	"PT_IO",
135 };
136 
137 static int narg;
138 static register_t *ap;
139 static char sep;
140 
141 static void mappidtoemul(pid_t, struct emulation *);
142 static struct emulation * findemul(pid_t);
143 static int fread_tail(void *, size_t, size_t);
144 static void dumpheader(struct ktr_header *);
145 static void ktrcsw(struct ktr_csw *);
146 static void ktremul(char *, size_t);
147 static void ktrgenio(struct ktr_genio *, size_t);
148 static void ktrnamei(const char *, size_t);
149 static void ktrpsig(struct ktr_psig *);
150 static void ktrsyscall(struct ktr_syscall *);
151 static const char *kresolvsysctl(int, int *, int);
152 static void ktrsysret(struct ktr_sysret *);
153 static void ktrstruct(char *, size_t);
154 static void setemul(const char *);
155 static void usage(void);
156 static void atfd(int);
157 
158 int
159 main(int argc, char *argv[])
160 {
161 	int ch, silent;
162 	size_t ktrlen, size;
163 	int trpoints = ALL_POINTS;
164 	void *m;
165 
166 	def_emul = current = &emulations[0];	/* native */
167 
168 	while ((ch = getopt(argc, argv, "e:f:dlm:nrRp:Tt:xX")) != -1)
169 		switch (ch) {
170 		case 'e':
171 			setemul(optarg);
172 			def_emul = current;
173 			break;
174 		case 'f':
175 			tracefile = optarg;
176 			break;
177 		case 'd':
178 			decimal = 1;
179 			break;
180 		case 'l':
181 			tail = 1;
182 			break;
183 		case 'm':
184 			maxdata = atoi(optarg);
185 			break;
186 		case 'n':
187 			fancy = 0;
188 			break;
189 		case 'p':
190 			pid = atoi(optarg);
191 			break;
192 		case 'r':
193 			resolv = 1;
194 			break;
195 		case 'R':
196 			timestamp = 2;	/* relative timestamp */
197 			break;
198 		case 'T':
199 			timestamp = 1;
200 			break;
201 		case 't':
202 			trpoints = getpoints(optarg);
203 			if (trpoints < 0)
204 				errx(1, "unknown trace point in %s", optarg);
205 			break;
206 		case 'x':
207 			iohex = 1;
208 			break;
209 		case 'X':
210 			iohex = 2;
211 			break;
212 		default:
213 			usage();
214 		}
215 	if (argc > optind)
216 		usage();
217 
218 	m = malloc(size = 1025);
219 	if (m == NULL)
220 		err(1, NULL);
221 	if (!freopen(tracefile, "r", stdin))
222 		err(1, "%s", tracefile);
223 	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
224 		silent = 0;
225 		if (pe_size == 0)
226 			mappidtoemul(ktr_header.ktr_pid, current);
227 		if (pid != -1 && pid != ktr_header.ktr_pid)
228 			silent = 1;
229 		if (silent == 0 && trpoints & (1<<ktr_header.ktr_type))
230 			dumpheader(&ktr_header);
231 		ktrlen = ktr_header.ktr_len;
232 		if (ktrlen > size) {
233 			void *newm;
234 
235 			newm = realloc(m, ktrlen+1);
236 			if (newm == NULL)
237 				err(1, NULL);
238 			m = newm;
239 			size = ktrlen;
240 		}
241 		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
242 			errx(1, "data too short");
243 		if (silent)
244 			continue;
245 		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
246 			continue;
247 		current = findemul(ktr_header.ktr_pid);
248 		switch (ktr_header.ktr_type) {
249 		case KTR_SYSCALL:
250 			ktrsyscall((struct ktr_syscall *)m);
251 			break;
252 		case KTR_SYSRET:
253 			ktrsysret((struct ktr_sysret *)m);
254 			break;
255 		case KTR_NAMEI:
256 			ktrnamei(m, ktrlen);
257 			break;
258 		case KTR_GENIO:
259 			ktrgenio((struct ktr_genio *)m, ktrlen);
260 			break;
261 		case KTR_PSIG:
262 			ktrpsig((struct ktr_psig *)m);
263 			break;
264 		case KTR_CSW:
265 			ktrcsw((struct ktr_csw *)m);
266 			break;
267 		case KTR_EMUL:
268 			ktremul(m, ktrlen);
269 			mappidtoemul(ktr_header.ktr_pid, current);
270 			break;
271 		case KTR_STRUCT:
272 			ktrstruct(m, ktrlen);
273 			break;
274 		}
275 		if (tail)
276 			(void)fflush(stdout);
277 	}
278 	exit(0);
279 }
280 
281 static void
282 mappidtoemul(pid_t pid, struct emulation *emul)
283 {
284 	size_t i;
285 	struct pid_emul *tmp;
286 
287 	for (i = 0; i < pe_size; i++) {
288 		if (pe_table[i].p == pid) {
289 			pe_table[i].e = emul;
290 			return;
291 		}
292 	}
293 	tmp = realloc(pe_table, (pe_size + 1) * sizeof(*pe_table));
294 	if (tmp == NULL)
295 		err(1, NULL);
296 	pe_table = tmp;
297 	pe_table[pe_size].p = pid;
298 	pe_table[pe_size].e = emul;
299 	pe_size++;
300 }
301 
302 static struct emulation*
303 findemul(pid_t pid)
304 {
305 	size_t i;
306 
307 	for (i = 0; i < pe_size; i++)
308 		if (pe_table[i].p == pid)
309 			return pe_table[i].e;
310 	return def_emul;
311 }
312 
313 static int
314 fread_tail(void *buf, size_t size, size_t num)
315 {
316 	int i;
317 
318 	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
319 		(void)sleep(1);
320 		clearerr(stdin);
321 	}
322 	return (i);
323 }
324 
325 static void
326 dumpheader(struct ktr_header *kth)
327 {
328 	static struct timeval prevtime;
329 	char unknown[64], *type;
330 	struct timeval temp;
331 
332 	switch (kth->ktr_type) {
333 	case KTR_SYSCALL:
334 		type = "CALL";
335 		break;
336 	case KTR_SYSRET:
337 		type = "RET ";
338 		break;
339 	case KTR_NAMEI:
340 		type = "NAMI";
341 		break;
342 	case KTR_GENIO:
343 		type = "GIO ";
344 		break;
345 	case KTR_PSIG:
346 		type = "PSIG";
347 		break;
348 	case KTR_CSW:
349 		type = "CSW";
350 		break;
351 	case KTR_EMUL:
352 		type = "EMUL";
353 		break;
354 	case KTR_STRUCT:
355 		type = "STRU";
356 		break;
357 	default:
358 		(void)snprintf(unknown, sizeof unknown, "UNKNOWN(%d)",
359 		    kth->ktr_type);
360 		type = unknown;
361 	}
362 
363 	(void)printf("%6ld %-8.*s ", (long)kth->ktr_pid, MAXCOMLEN,
364 	    kth->ktr_comm);
365 	if (timestamp) {
366 		if (timestamp == 2) {
367 			timersub(&kth->ktr_time, &prevtime, &temp);
368 			prevtime = kth->ktr_time;
369 		} else
370 			temp = kth->ktr_time;
371 		(void)printf("%ld.%06ld ", temp.tv_sec, temp.tv_usec);
372 	}
373 	(void)printf("%s  ", type);
374 }
375 
376 static void
377 ioctldecode(u_long cmd)
378 {
379 	char dirbuf[4], *dir = dirbuf;
380 
381 	if (cmd & IOC_IN)
382 		*dir++ = 'W';
383 	if (cmd & IOC_OUT)
384 		*dir++ = 'R';
385 	*dir = '\0';
386 
387 	printf(decimal ? ",_IO%s('%c',%lu" : ",_IO%s('%c',%#lx",
388 	    dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
389 	if ((cmd & IOC_VOID) == 0)
390 		printf(decimal ? ",%lu)" : ",%#lx)", (cmd >> 16) & 0xff);
391 	else
392 		printf(")");
393 }
394 
395 static void
396 ptracedecode(void)
397 {
398 	if (*ap >= 0 && *ap <
399 	    sizeof(ptrace_ops) / sizeof(ptrace_ops[0]))
400 		(void)printf("%s", ptrace_ops[*ap]);
401 	else switch(*ap) {
402 #ifdef PT_GETFPREGS
403 	case PT_GETFPREGS:
404 		(void)printf("PT_GETFPREGS");
405 		break;
406 #endif
407 	case PT_GETREGS:
408 		(void)printf("PT_GETREGS");
409 		break;
410 #ifdef PT_SETFPREGS
411 	case PT_SETFPREGS:
412 		(void)printf("PT_SETFPREGS");
413 		break;
414 #endif
415 	case PT_SETREGS:
416 		(void)printf("PT_SETREGS");
417 		break;
418 #ifdef PT_STEP
419 	case PT_STEP:
420 		(void)printf("PT_STEP");
421 		break;
422 #endif
423 #ifdef PT_WCOOKIE
424 	case PT_WCOOKIE:
425 		(void)printf("PT_WCOOKIE");
426 		break;
427 #endif
428 	default:
429 		(void)printf("%ld", (long)*ap);
430 		break;
431 	}
432 	sep = ',';
433 	ap++;
434 	narg--;
435 }
436 
437 static void
438 pn(void (*f)(int))
439 {
440 	if (sep)
441 		(void)putchar(sep);
442 	if (fancy && f != NULL)
443 		f((int)*ap);
444 	else if (decimal)
445 		(void)printf("%ld", (long)*ap);
446 	else
447 		(void)printf("%#lx", (long)*ap);
448 	ap++;
449 	narg--;
450 	sep = ',';
451 }
452 
453 #ifdef __LP64__
454 #define plln()	pn(NULL)
455 #elif _BYTE_ORDER == _LITTLE_ENDIAN
456 static void
457 plln(void)
458 {
459 	long long val = ((long long)*ap) & 0xffffffff;
460 	ap++;
461 	val |= ((long long)*ap) << 32;
462 	ap++;
463 	narg -= 2;
464 	if (sep)
465 		(void)putchar(sep);
466 	if (decimal)
467 		(void)printf("%lld", val);
468 	else
469 		(void)printf("%#llx", val);
470 	sep = ',';
471 }
472 #else
473 static void
474 plln(void)
475 {
476 	long long val = ((long long)*ap) << 32;
477 	ap++;
478 	val |= ((long long)*ap) & 0xffffffff;
479 	ap++;
480 	narg -= 2;
481 	if (sep)
482 		(void)putchar(sep);
483 	if (decimal)
484 		(void)printf("%lld", val);
485 	else
486 		(void)printf("%#llx", val);
487 	sep = ',';
488 }
489 #endif
490 
491 static void
492 ktrsyscall(struct ktr_syscall *ktr)
493 {
494 	narg = ktr->ktr_argsize / sizeof(register_t);
495 	sep = '\0';
496 
497 	if (ktr->ktr_code >= current->nsysnames || ktr->ktr_code < 0)
498 		(void)printf("[%d]", ktr->ktr_code);
499 	else
500 		(void)printf("%s", current->sysnames[ktr->ktr_code]);
501 	ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
502 	(void)putchar('(');
503 
504 	if (current != &emulations[0])
505 		goto nonnative;
506 
507 	switch (ktr->ktr_code) {
508 	case SYS_ioctl: {
509 		const char *cp;
510 
511 		pn(NULL);
512 		if (!fancy)
513 			break;
514 		if ((cp = ioctlname(*ap)) != NULL)
515 			(void)printf(",%s", cp);
516 		else
517 			ioctldecode(*ap);
518 		ap++;
519 		narg--;
520 		break;
521 	}
522 	case SYS___sysctl: {
523 		const char *s;
524 		int *np, n, i, *top;
525 
526 		if (!fancy)
527 			break;
528 		n = ap[1];
529 		if (n > CTL_MAXNAME)
530 			n = CTL_MAXNAME;
531 		np = top = (int *)(ap + 6);
532 		for (i = 0; n--; np++, i++) {
533 			if (sep)
534 				putchar(sep);
535 			if (resolv && (s = kresolvsysctl(i, top, *np)) != NULL)
536 				printf("%s", s);
537 			else
538 				printf("%d", *np);
539 			sep = '.';
540 		}
541 
542 		sep = ',';
543 		ap += 2;
544 		narg -= 2;
545 		break;
546 	}
547 	case SYS_ptrace:
548 		if (!fancy)
549 			break;
550 		ptracedecode();
551 		break;
552 	case SYS_access:
553 		pn(NULL);
554 		pn(accessmodename);
555 		break;
556 	case SYS_chmod:
557 	case SYS_fchmod:
558 		pn(NULL);
559 		pn(modename);
560 		break;
561 	case SYS_fcntl: {
562 		int cmd;
563 		int arg;
564 		pn(NULL);
565 		if (!fancy)
566 			break;
567 		cmd = ap[0];
568 		arg = ap[1];
569 		(void)putchar(',');
570 		fcntlcmdname(cmd, arg);
571 		ap += 2;
572 		narg -= 2;
573 		break;
574 	}
575 	case SYS_flock:
576 		pn(NULL);
577 		pn(flockname);
578 		break;
579 	case SYS_getrlimit:
580 	case SYS_setrlimit:
581 		pn(rlimitname);
582 		break;
583 	case SYS_getsockopt:
584 	case SYS_setsockopt: {
585 		int level;
586 
587 		pn(NULL);
588 		level = *ap;
589 		pn(sockoptlevelname);
590 		if (level == SOL_SOCKET)
591 			pn(sockoptname);
592 		break;
593 	}
594 	case SYS_kill:
595 		pn(NULL);
596 		pn(signame);
597 		break;
598 	case SYS_lseek:
599 		pn(NULL);
600 		/* skip padding */
601 		ap++;
602 		narg--;
603 		plln();
604 		pn(whencename);
605 		break;
606 	case SYS_madvise:
607 		pn(NULL);
608 		pn(NULL);
609 		pn(madvisebehavname);
610 		break;
611 	case SYS_minherit:
612 		pn(NULL);
613 		pn(NULL);
614 		pn(minheritname);
615 		break;
616 	case SYS_mlockall:
617 		pn(mlockallname);
618 		break;
619 	case SYS_mmap:
620 		pn(NULL);
621 		pn(NULL);
622 		pn(mmapprotname);
623 		pn(mmapflagsname);
624 		pn(NULL);
625 		/* skip padding */
626 		ap++;
627 		narg--;
628 		plln();
629 		break;
630 	case SYS_mprotect:
631 		pn(NULL);
632 		pn(NULL);
633 		pn(mmapprotname);
634 		break;
635 	case SYS_mquery:
636 		pn(NULL);
637 		pn(NULL);
638 		pn(mmapprotname);
639 		pn(mmapflagsname);
640 		pn(NULL);
641 		/* skip padding */
642 		ap++;
643 		narg--;
644 		plln();
645 		break;
646 	case SYS_msync:
647 		pn(NULL);
648 		pn(NULL);
649 		pn(msyncflagsname);
650 		break;
651 	case SYS_msgctl:
652 		pn(NULL);
653 		pn(shmctlname);
654 		break;
655 	case SYS_open: {
656 		int     flags;
657 		int     mode;
658 
659 		pn(NULL);
660 		if (!fancy)
661 			break;
662 		flags = ap[0];
663 		mode = ap[1];
664 		(void)putchar(',');
665 		flagsandmodename(flags, mode);
666 		ap += 2;
667 		narg -= 2;
668 		break;
669 	}
670 	case SYS_pread:
671 	case SYS_preadv:
672 	case SYS_pwrite:
673 	case SYS_pwritev:
674 		pn(NULL);
675 		pn(NULL);
676 		pn(NULL);
677 		/* skip padding */
678 		ap++;
679 		narg--;
680 		plln();
681 		break;
682 	case SYS_recvmsg:
683 	case SYS_sendmsg:
684 		pn(NULL);
685 		pn(NULL);
686 		pn(sendrecvflagsname);
687 		break;
688 	case SYS_recvfrom:
689 	case SYS_sendto:
690 		pn(NULL);
691 		pn(NULL);
692 		pn(NULL);
693 		pn(sendrecvflagsname);
694 		break;
695 	case SYS___semctl:
696 		pn(NULL);
697 		pn(NULL);
698 		pn(semctlname);
699 		break;
700 	case SYS_semget:
701 		pn(NULL);
702 		pn(NULL);
703 		pn(semgetname);
704 		break;
705 	case SYS_shmat:
706 		pn(NULL);
707 		pn(NULL);
708 		pn(shmatname);
709 		break;
710 	case SYS_shmctl:
711 		pn(NULL);
712 		pn(shmctlname);
713 		break;
714 	case SYS_sigaction:
715 		pn(signame);
716 		break;
717 	case SYS_sigprocmask:
718 		pn(sigprocmaskhowname);
719 		break;
720 	case SYS_socket: {
721 		int sockdomain = *ap;
722 
723 		pn(sockdomainname);
724 		pn(socktypename);
725 		if (sockdomain == PF_INET || sockdomain == PF_INET6)
726 			pn(sockipprotoname);
727 		break;
728 	}
729 	case SYS_socketpair:
730 		pn(sockdomainname);
731 		pn(socktypename);
732 		break;
733 	case SYS_truncate:
734 	case SYS_ftruncate:
735 		pn(NULL);
736 		/* skip padding */
737 		ap++;
738 		narg--;
739 		plln();
740 		break;
741 	case SYS_wait4:
742 		pn(NULL);
743 		pn(NULL);
744 		pn(wait4optname);
745 		break;
746 	case SYS_faccessat:
747 		pn(atfd);
748 		pn(NULL);
749 		pn(accessmodename);
750 		pn(atflagsname);
751 		break;
752 	case SYS_fchmodat:
753 		pn(atfd);
754 		pn(NULL);
755 		pn(modename);
756 		pn(atflagsname);
757 		break;
758 	case SYS_fchownat:
759 		pn(atfd);
760 		pn(NULL);
761 		pn(NULL);
762 		pn(NULL);
763 		pn(atflagsname);
764 		break;
765 	case SYS_fstatat:
766 		pn(atfd);
767 		pn(NULL);
768 		pn(NULL);
769 		pn(atflagsname);
770 		break;
771 	case SYS_linkat:
772 		pn(atfd);
773 		pn(NULL);
774 		pn(atfd);
775 		pn(NULL);
776 		pn(atflagsname);
777 		break;
778 	case SYS_mkdirat:
779 	case SYS_mkfifoat:
780 	case SYS_mknodat:
781 		pn(atfd);
782 		pn(NULL);
783 		pn(modename);
784 		break;
785 	case SYS_openat: {
786 		int     flags;
787 		int     mode;
788 
789 		pn(atfd);
790 		pn(NULL);
791 		if (!fancy)
792 			break;
793 		flags = ap[0];
794 		mode = ap[1];
795 		(void)putchar(',');
796 		flagsandmodename(flags, mode);
797 		ap += 2;
798 		narg -= 2;
799 		break;
800 	}
801 	case SYS_readlinkat:
802 		pn(atfd);
803 		break;
804 	case SYS_renameat:
805 		pn(atfd);
806 		pn(NULL);
807 		pn(atfd);
808 		break;
809 	case SYS_symlinkat:
810 		pn(NULL);
811 		pn(atfd);
812 		break;
813 	case SYS_unlinkat:
814 		pn(atfd);
815 		pn(NULL);
816 		pn(atflagsname);
817 		break;
818 	case SYS_utimensat:
819 		pn(atfd);
820 		pn(NULL);
821 		pn(NULL);
822 		pn(atflagsname);
823 		break;
824 	}
825 
826 nonnative:
827 	while (narg) {
828 		if (sep)
829 			putchar(sep);
830 		if (decimal)
831 			(void)printf("%ld", (long)*ap);
832 		else
833 			(void)printf("%#lx", (long)*ap);
834 		sep = ',';
835 		ap++;
836 		narg--;
837 	}
838 	(void)printf(")\n");
839 }
840 
841 static struct ctlname topname[] = CTL_NAMES;
842 static struct ctlname kernname[] = CTL_KERN_NAMES;
843 static struct ctlname vmname[] = CTL_VM_NAMES;
844 static struct ctlname fsname[] = CTL_FS_NAMES;
845 static struct ctlname netname[] = CTL_NET_NAMES;
846 static struct ctlname hwname[] = CTL_HW_NAMES;
847 static struct ctlname username[] = CTL_USER_NAMES;
848 static struct ctlname debugname[CTL_DEBUG_MAXID];
849 static struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES;
850 static struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES;
851 static struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES;
852 static struct ctlname ttysname[] = CTL_KERN_TTY_NAMES;
853 static struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES;
854 static struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES;
855 static struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES;
856 static struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES;
857 #ifdef CTL_MACHDEP_NAMES
858 static struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
859 #endif
860 static struct ctlname ddbname[] = CTL_DDB_NAMES;
861 
862 #ifndef nitems
863 #define nitems(_a)    (sizeof((_a)) / sizeof((_a)[0]))
864 #endif
865 
866 #define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)
867 
868 static const char *
869 kresolvsysctl(int depth, int *top, int idx)
870 {
871 	struct ctlname *names;
872 	size_t		limit;
873 
874 	names = NULL;
875 
876 	switch (depth) {
877 	case 0:
878 		SETNAME(topname);
879 		break;
880 	case 1:
881 		switch (top[0]) {
882 		case CTL_KERN:
883 			SETNAME(kernname);
884 			break;
885 		case CTL_VM:
886 			SETNAME(vmname);
887 			break;
888 		case CTL_FS:
889 			SETNAME(fsname);
890 			break;
891 		case CTL_NET:
892 			SETNAME(netname);
893 			break;
894 		case CTL_DEBUG:
895 			SETNAME(debugname);
896 			break;
897 		case CTL_HW:
898 			SETNAME(hwname);
899 			break;
900 #ifdef CTL_MACHDEP_NAMES
901 		case CTL_MACHDEP:
902 			SETNAME(machdepname);
903 			break;
904 #endif
905 		case CTL_USER:
906 			SETNAME(username);
907 			break;
908 		case CTL_DDB:
909 			SETNAME(ddbname);
910 			break;
911 		}
912 		break;
913 	case 2:
914 		switch (top[0]) {
915 		case CTL_KERN:
916 			switch (top[1]) {
917 			case KERN_MALLOCSTATS:
918 				SETNAME(kernmallocname);
919 				break;
920 			case KERN_FORKSTAT:
921 				SETNAME(forkstatname);
922 				break;
923 			case KERN_NCHSTATS:
924 				SETNAME(nchstatsname);
925 				break;
926 			case KERN_TTY:
927 				SETNAME(ttysname);
928 				break;
929 			case KERN_SEMINFO:
930 				SETNAME(semname);
931 				break;
932 			case KERN_SHMINFO:
933 				SETNAME(shmname);
934 				break;
935 			case KERN_WATCHDOG:
936 				SETNAME(watchdogname);
937 				break;
938 			case KERN_TIMECOUNTER:
939 				SETNAME(tcname);
940 				break;
941 			}
942 		}
943 		break;
944 	}
945 	if (names != NULL && idx > 0 && idx < limit)
946 		return (names[idx].ctl_name);
947 	return (NULL);
948 }
949 
950 static void
951 ktrsysret(struct ktr_sysret *ktr)
952 {
953 	register_t ret = ktr->ktr_retval;
954 	int error = ktr->ktr_error;
955 	int code = ktr->ktr_code;
956 
957 	if (code >= current->nsysnames || code < 0)
958 		(void)printf("[%d] ", code);
959 	else {
960 		(void)printf("%s ", current->sysnames[code]);
961 		if (ret > 0 && (strcmp(current->sysnames[code], "fork") == 0 ||
962 		    strcmp(current->sysnames[code], "vfork") == 0 ||
963 		    strcmp(current->sysnames[code], "rfork") == 0 ||
964 		    strcmp(current->sysnames[code], "clone") == 0))
965 			mappidtoemul(ret, current);
966 	}
967 
968 	if (error == 0) {
969 		if (fancy) {
970 			(void)printf("%ld", (long)ret);
971 			if (ret < 0 || ret > 9)
972 				(void)printf("/%#lx", (long)ret);
973 		} else {
974 			if (decimal)
975 				(void)printf("%ld", (long)ret);
976 			else
977 				(void)printf("%#lx", (long)ret);
978 		}
979 	} else if (error == ERESTART)
980 		(void)printf("RESTART");
981 	else if (error == EJUSTRETURN)
982 		(void)printf("JUSTRETURN");
983 	else {
984 		(void)printf("-1 errno %d", ktr->ktr_error);
985 		if (fancy)
986 			(void)printf(" %s", strerror(ktr->ktr_error));
987 	}
988 	(void)putchar('\n');
989 }
990 
991 static void
992 ktrnamei(const char *cp, size_t len)
993 {
994 	(void)printf("\"%.*s\"\n", (int)len, cp);
995 }
996 
997 static void
998 ktremul(char *cp, size_t len)
999 {
1000 	char name[1024];
1001 
1002 	if (len >= sizeof(name))
1003 		errx(1, "Emulation name too long");
1004 
1005 	strncpy(name, cp, len);
1006 	name[len] = '\0';
1007 	(void)printf("\"%s\"\n", name);
1008 
1009 	setemul(name);
1010 }
1011 
1012 static void
1013 ktrgenio(struct ktr_genio *ktr, size_t len)
1014 {
1015 	unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
1016 	int i, j;
1017 	size_t datalen = len - sizeof(struct ktr_genio);
1018 	static int screenwidth = 0;
1019 	int col = 0, width, bpl;
1020 	unsigned char visbuf[5], *cp, c;
1021 
1022 	if (screenwidth == 0) {
1023 		struct winsize ws;
1024 
1025 		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1026 		    ws.ws_col > 8)
1027 			screenwidth = ws.ws_col;
1028 		else
1029 			screenwidth = 80;
1030 	}
1031 	printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1032 		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
1033 	if (maxdata == 0)
1034 		return;
1035 	if (datalen > maxdata)
1036 		datalen = maxdata;
1037 	if (iohex && !datalen)
1038 		return;
1039 	if (iohex == 1) {
1040 		putchar('\t');
1041 		col = 8;
1042 		for (i = 0; i < datalen; i++) {
1043 			printf("%02x", dp[i]);
1044 			col += 3;
1045 			if (i < datalen - 1) {
1046 				if (col + 3 > screenwidth) {
1047 					printf("\n\t");
1048 					col = 8;
1049 				} else
1050 					putchar(' ');
1051 			}
1052 		}
1053 		putchar('\n');
1054 		return;
1055 	}
1056 	if (iohex == 2) {
1057 		bpl = (screenwidth - 13)/4;
1058 		if (bpl <= 0)
1059 			bpl = 1;
1060 		for (i = 0; i < datalen; i += bpl) {
1061 			printf("   %04x:  ", i);
1062 			for (j = 0; j < bpl; j++) {
1063 				if (i+j >= datalen)
1064 					printf("   ");
1065 				else
1066 					printf("%02x ", dp[i+j]);
1067 			}
1068 			putchar(' ');
1069 			for (j = 0; j < bpl; j++) {
1070 				if (i+j >= datalen)
1071 					break;
1072 				c = dp[i+j];
1073 				if (!isprint(c))
1074 					c = '.';
1075 				putchar(c);
1076 			}
1077 			putchar('\n');
1078 		}
1079 		return;
1080 	}
1081 	(void)printf("       \"");
1082 	col = 8;
1083 	for (; datalen > 0; datalen--, dp++) {
1084 		(void)vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
1085 		cp = visbuf;
1086 
1087 		/*
1088 		 * Keep track of printables and
1089 		 * space chars (like fold(1)).
1090 		 */
1091 		if (col == 0) {
1092 			(void)putchar('\t');
1093 			col = 8;
1094 		}
1095 		switch (*cp) {
1096 		case '\n':
1097 			col = 0;
1098 			(void)putchar('\n');
1099 			continue;
1100 		case '\t':
1101 			width = 8 - (col&07);
1102 			break;
1103 		default:
1104 			width = strlen(cp);
1105 		}
1106 		if (col + width > (screenwidth-2)) {
1107 			(void)printf("\\\n\t");
1108 			col = 8;
1109 		}
1110 		col += width;
1111 		do {
1112 			(void)putchar(*cp++);
1113 		} while (*cp);
1114 	}
1115 	if (col == 0)
1116 		(void)printf("       ");
1117 	(void)printf("\"\n");
1118 }
1119 
1120 static void
1121 ktrpsig(struct ktr_psig *psig)
1122 {
1123 	(void)printf("SIG%s ", sys_signame[psig->signo]);
1124 	if (psig->action == SIG_DFL)
1125 		(void)printf("SIG_DFL code %d", psig->code);
1126 	else
1127 		(void)printf("caught handler=0x%lx mask=0x%x",
1128 		    (u_long)psig->action, psig->mask);
1129 	switch (psig->signo) {
1130 	case SIGSEGV:
1131 	case SIGILL:
1132 	case SIGBUS:
1133 	case SIGFPE:
1134 		printf(" addr=%p trapno=%d", psig->si.si_addr,
1135 		    psig->si.si_trapno);
1136 		break;
1137 	default:
1138 		break;
1139 	}
1140 	printf("\n");
1141 }
1142 
1143 static void
1144 ktrcsw(struct ktr_csw *cs)
1145 {
1146 	(void)printf("%s %s\n", cs->out ? "stop" : "resume",
1147 	    cs->user ? "user" : "kernel");
1148 }
1149 
1150 
1151 
1152 void
1153 ktrsockaddr(struct sockaddr *sa)
1154 {
1155 /*
1156  TODO: Support additional address families
1157 	#include <netnatm/natm.h>
1158 	struct sockaddr_natm	*natm;
1159 	#include <netsmb/netbios.h>
1160 	struct sockaddr_nb	*nb;
1161 */
1162 	char addr[64];
1163 
1164 	/*
1165 	 * note: ktrstruct() has already verified that sa points to a
1166 	 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1167 	 * sa->sa_len bytes long.
1168 	 */
1169 	printf("struct sockaddr { ");
1170 	sockfamilyname(sa->sa_family);
1171 	printf(", ");
1172 
1173 #define check_sockaddr_len(n)					\
1174 	if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) {	\
1175 		printf("invalid");				\
1176 		break;						\
1177 	}
1178 
1179 	switch(sa->sa_family) {
1180 	case AF_INET: {
1181 		struct sockaddr_in	*sa_in;
1182 
1183 		sa_in = (struct sockaddr_in *)sa;
1184 		check_sockaddr_len(in);
1185 		inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr);
1186 		printf("%s:%u", addr, ntohs(sa_in->sin_port));
1187 		break;
1188 	}
1189 	case AF_INET6: {
1190 		struct sockaddr_in6	*sa_in6;
1191 
1192 		sa_in6 = (struct sockaddr_in6 *)sa;
1193 		check_sockaddr_len(in6);
1194 		inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr);
1195 		printf("[%s]:%u", addr, htons(sa_in6->sin6_port));
1196 		break;
1197 	}
1198 #ifdef IPX
1199 	case AF_IPX: {
1200 		struct sockaddr_ipx	*sa_ipx;
1201 
1202 		sa_ipx = (struct sockaddr_ipx *)sa;
1203 		check_sockaddr_len(ipx);
1204 		/* XXX wish we had ipx_ntop */
1205 		printf("%s", ipx_ntoa(sa_ipx->sipx_addr));
1206 		break;
1207 	}
1208 #endif
1209 	case AF_UNIX: {
1210 		struct sockaddr_un *sa_un;
1211 
1212 		sa_un = (struct sockaddr_un *)sa;
1213 		if (sa_un->sun_len <= sizeof(sa_un->sun_len) +
1214 		    sizeof(sa_un->sun_family)) {
1215 			printf("invalid");
1216 			break;
1217 		}
1218 		printf("\"%.*s\"", (int)(sa_un->sun_len -
1219 		    sizeof(sa_un->sun_len) - sizeof(sa_un->sun_family)),
1220 		    sa_un->sun_path);
1221 		break;
1222 	}
1223 	default:
1224 		printf("unknown address family");
1225 	}
1226 	printf(" }\n");
1227 }
1228 
1229 void
1230 ktrstat(struct stat *statp)
1231 {
1232 	char mode[12], timestr[PATH_MAX + 4];
1233 	struct passwd *pwd;
1234 	struct group  *grp;
1235 	struct tm *tm;
1236 
1237 	/*
1238 	 * note: ktrstruct() has already verified that statp points to a
1239 	 * buffer exactly sizeof(struct stat) bytes long.
1240 	 */
1241 	printf("struct stat {");
1242 	strmode(statp->st_mode, mode);
1243 	printf("dev=%d, ino=%u, mode=%s, nlink=%u, ",
1244 	    statp->st_dev, statp->st_ino, mode, statp->st_nlink);
1245 	if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1246 		printf("uid=%u, ", statp->st_uid);
1247 	else
1248 		printf("uid=\"%s\", ", pwd->pw_name);
1249 	if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1250 		printf("gid=%u, ", statp->st_gid);
1251 	else
1252 		printf("gid=\"%s\", ", grp->gr_name);
1253 	printf("rdev=%d, ", statp->st_rdev);
1254 	printf("atime=");
1255 	if (resolv == 0)
1256 		printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1257 	else {
1258 		tm = localtime(&statp->st_atim.tv_sec);
1259 		(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1260 		printf("\"%s\"", timestr);
1261 	}
1262 	if (statp->st_atim.tv_nsec != 0)
1263 		printf(".%09ld, ", statp->st_atim.tv_nsec);
1264 	else
1265 		printf(", ");
1266 	printf("stime=");
1267 	if (resolv == 0)
1268 		printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1269 	else {
1270 		tm = localtime(&statp->st_mtim.tv_sec);
1271 		(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1272 		printf("\"%s\"", timestr);
1273 	}
1274 	if (statp->st_mtim.tv_nsec != 0)
1275 		printf(".%09ld, ", statp->st_mtim.tv_nsec);
1276 	else
1277 		printf(", ");
1278 	printf("ctime=");
1279 	if (resolv == 0)
1280 		printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1281 	else {
1282 		tm = localtime(&statp->st_ctim.tv_sec);
1283 		(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1284 		printf("\"%s\"", timestr);
1285 	}
1286 	if (statp->st_ctim.tv_nsec != 0)
1287 		printf(".%09ld, ", statp->st_ctim.tv_nsec);
1288 	else
1289 		printf(", ");
1290 	printf("size=%lld, blocks=%lld, blksize=%u, flags=0x%x, gen=0x%x",
1291 	    statp->st_size, statp->st_blocks, statp->st_blksize,
1292 	    statp->st_flags, statp->st_gen);
1293 	printf(" }\n");
1294 }
1295 
1296 void
1297 ktrstruct(char *buf, size_t buflen)
1298 {
1299 	char *name, *data;
1300 	size_t namelen, datalen;
1301 	int i;
1302 	struct stat sb;
1303 	struct sockaddr_storage ss;
1304 
1305 	for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0';
1306 	     ++namelen)
1307 		/* nothing */;
1308 	if (namelen == buflen)
1309 		goto invalid;
1310 	if (name[namelen] != '\0')
1311 		goto invalid;
1312 	data = buf + namelen + 1;
1313 	datalen = buflen - namelen - 1;
1314 	if (datalen == 0)
1315 		goto invalid;
1316 	/* sanity check */
1317 	for (i = 0; i < namelen; ++i)
1318 		if (!isalpha((unsigned char)name[i]))
1319 			goto invalid;
1320 	if (strcmp(name, "stat") == 0) {
1321 		if (datalen != sizeof(struct stat))
1322 			goto invalid;
1323 		memcpy(&sb, data, datalen);
1324 		ktrstat(&sb);
1325 	} else if (strcmp(name, "sockaddr") == 0) {
1326 		if (datalen > sizeof(ss))
1327 			goto invalid;
1328 		memcpy(&ss, data, datalen);
1329 		if ((ss.ss_family != AF_UNIX &&
1330 		    datalen < sizeof(struct sockaddr)) || datalen != ss.ss_len)
1331 			goto invalid;
1332 		ktrsockaddr((struct sockaddr *)&ss);
1333 	} else {
1334 		printf("unknown structure %s\n", name);
1335 	}
1336 	return;
1337 invalid:
1338 	printf("invalid record\n");
1339 }
1340 
1341 static void
1342 usage(void)
1343 {
1344 
1345 	extern char *__progname;
1346 	fprintf(stderr, "usage: %s "
1347 	    "[-dlnRrTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n"
1348 	    "%*s[-t [ceinsw]]\n",
1349 	    __progname, (int)(sizeof("usage: ") + strlen(__progname)), "");
1350 	exit(1);
1351 }
1352 
1353 static void
1354 setemul(const char *name)
1355 {
1356 	int i;
1357 
1358 	for (i = 0; emulations[i].name != NULL; i++)
1359 		if (strcmp(emulations[i].name, name) == 0) {
1360 			current = &emulations[i];
1361 			return;
1362 		}
1363 	warnx("Emulation `%s' unknown", name);
1364 }
1365 
1366 static void
1367 atfd(int fd)
1368 {
1369 	if (fd == AT_FDCWD)
1370 		(void)printf("AT_FDCWD");
1371 	else if (decimal)
1372 		(void)printf("%d", fd);
1373 	else
1374 		(void)printf("%#x", fd);
1375 }
1376