xref: /freebsd/usr.bin/kdump/kdump.c (revision 9124ddeb4a551977cf6b2218291e7c666ce25f47)
1 /*-
2  * Copyright (c) 1988, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #ifndef lint
31 static const char copyright[] =
32 "@(#) Copyright (c) 1988, 1993\n\
33 	The Regents of the University of California.  All rights reserved.\n";
34 #endif /* not lint */
35 
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)kdump.c	8.1 (Berkeley) 6/6/93";
39 #endif
40 #endif /* not lint */
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43 
44 #define _KERNEL
45 extern int errno;
46 #include <sys/errno.h>
47 #undef _KERNEL
48 #include <sys/param.h>
49 #include <sys/errno.h>
50 #define _KERNEL
51 #include <sys/time.h>
52 #undef _KERNEL
53 #include <sys/uio.h>
54 #include <sys/ktrace.h>
55 #include <sys/ioctl.h>
56 #include <sys/socket.h>
57 #include <sys/stat.h>
58 #include <sys/sysent.h>
59 #include <sys/un.h>
60 #include <sys/queue.h>
61 #ifdef IPX
62 #include <sys/types.h>
63 #include <netipx/ipx.h>
64 #endif
65 #ifdef NETATALK
66 #include <netatalk/at.h>
67 #endif
68 #include <arpa/inet.h>
69 #include <netinet/in.h>
70 #include <ctype.h>
71 #include <dlfcn.h>
72 #include <err.h>
73 #include <grp.h>
74 #include <inttypes.h>
75 #include <locale.h>
76 #include <pwd.h>
77 #include <stdio.h>
78 #include <stdlib.h>
79 #include <string.h>
80 #include <time.h>
81 #include <unistd.h>
82 #include <vis.h>
83 #include "ktrace.h"
84 #include "kdump_subr.h"
85 
86 u_int abidump(struct ktr_header *);
87 int fetchprocinfo(struct ktr_header *, u_int *);
88 int fread_tail(void *, int, int);
89 void dumpheader(struct ktr_header *);
90 void ktrsyscall(struct ktr_syscall *, u_int);
91 void ktrsysret(struct ktr_sysret *, u_int);
92 void ktrnamei(char *, int);
93 void hexdump(char *, int, int);
94 void visdump(char *, int, int);
95 void ktrgenio(struct ktr_genio *, int);
96 void ktrpsig(struct ktr_psig *);
97 void ktrcsw(struct ktr_csw *);
98 void ktruser_malloc(unsigned char *);
99 void ktruser_rtld(int, unsigned char *);
100 void ktruser(int, unsigned char *);
101 void ktrsockaddr(struct sockaddr *);
102 void ktrstat(struct stat *);
103 void ktrstruct(char *, size_t);
104 void ktrcapfail(struct ktr_cap_fail *);
105 void usage(void);
106 void ioctlname(unsigned long, int);
107 
108 int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
109     resolv = 0, abiflag = 0;
110 const char *tracefile = DEF_TRACEFILE;
111 struct ktr_header ktr_header;
112 
113 #define TIME_FORMAT	"%b %e %T %Y"
114 #define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
115 
116 #define print_number(i,n,c) do {					\
117 	if (decimal)							\
118 		printf("%c%jd", c, (intmax_t)*i);			\
119 	else								\
120 		printf("%c%#jx", c, (uintmax_t)(u_register_t)*i);	\
121 	i++;								\
122 	n--;								\
123 	c = ',';							\
124 } while (0)
125 
126 #if defined(__amd64__) || defined(__i386__)
127 
128 void linux_ktrsyscall(struct ktr_syscall *);
129 void linux_ktrsysret(struct ktr_sysret *);
130 extern char *linux_syscallnames[];
131 extern int nlinux_syscalls;
132 
133 /*
134  * from linux.h
135  * Linux syscalls return negative errno's, we do positive and map them
136  */
137 static int bsd_to_linux_errno[ELAST + 1] = {
138 	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
139 	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
140 	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
141 	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
142 	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
143 	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
144 	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
145 	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
146 	-6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
147 	-72, -67, -71
148 };
149 #endif
150 
151 struct proc_info
152 {
153 	TAILQ_ENTRY(proc_info)	info;
154 	u_int			sv_flags;
155 	pid_t			pid;
156 };
157 
158 TAILQ_HEAD(trace_procs, proc_info) trace_procs;
159 
160 int
161 main(int argc, char *argv[])
162 {
163 	int ch, ktrlen, size;
164 	void *m;
165 	int trpoints = ALL_POINTS;
166 	int drop_logged;
167 	pid_t pid = 0;
168 	u_int sv_flags;
169 
170 	setlocale(LC_CTYPE, "");
171 
172 	while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1)
173 		switch (ch) {
174 		case 'A':
175 			abiflag = 1;
176 			break;
177 		case 'f':
178 			tracefile = optarg;
179 			break;
180 		case 'd':
181 			decimal = 1;
182 			break;
183 		case 'l':
184 			tail = 1;
185 			break;
186 		case 'm':
187 			maxdata = atoi(optarg);
188 			break;
189 		case 'n':
190 			fancy = 0;
191 			break;
192 		case 'p':
193 			pid = atoi(optarg);
194 			break;
195 		case 'r':
196 			resolv = 1;
197 			break;
198 		case 's':
199 			suppressdata = 1;
200 			break;
201 		case 'E':
202 			timestamp = 3;	/* elapsed timestamp */
203 			break;
204 		case 'H':
205 			threads = 1;
206 			break;
207 		case 'R':
208 			timestamp = 2;	/* relative timestamp */
209 			break;
210 		case 'T':
211 			timestamp = 1;
212 			break;
213 		case 't':
214 			trpoints = getpoints(optarg);
215 			if (trpoints < 0)
216 				errx(1, "unknown trace point in %s", optarg);
217 			break;
218 		default:
219 			usage();
220 		}
221 
222 	if (argc > optind)
223 		usage();
224 
225 	m = malloc(size = 1025);
226 	if (m == NULL)
227 		errx(1, "%s", strerror(ENOMEM));
228 	if (!freopen(tracefile, "r", stdin))
229 		err(1, "%s", tracefile);
230 	TAILQ_INIT(&trace_procs);
231 	drop_logged = 0;
232 	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
233 		if (ktr_header.ktr_type & KTR_DROP) {
234 			ktr_header.ktr_type &= ~KTR_DROP;
235 			if (!drop_logged && threads) {
236 				printf(
237 				    "%6jd %6jd %-8.*s Events dropped.\n",
238 				    (intmax_t)ktr_header.ktr_pid,
239 				    ktr_header.ktr_tid > 0 ?
240 				    (intmax_t)ktr_header.ktr_tid : 0,
241 				    MAXCOMLEN, ktr_header.ktr_comm);
242 				drop_logged = 1;
243 			} else if (!drop_logged) {
244 				printf("%6jd %-8.*s Events dropped.\n",
245 				    (intmax_t)ktr_header.ktr_pid, MAXCOMLEN,
246 				    ktr_header.ktr_comm);
247 				drop_logged = 1;
248 			}
249 		}
250 		if (trpoints & (1<<ktr_header.ktr_type))
251 			if (pid == 0 || ktr_header.ktr_pid == pid)
252 				dumpheader(&ktr_header);
253 		if ((ktrlen = ktr_header.ktr_len) < 0)
254 			errx(1, "bogus length 0x%x", ktrlen);
255 		if (ktrlen > size) {
256 			m = realloc(m, ktrlen+1);
257 			if (m == NULL)
258 				errx(1, "%s", strerror(ENOMEM));
259 			size = ktrlen;
260 		}
261 		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
262 			errx(1, "data too short");
263 		if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
264 			continue;
265 		sv_flags = abidump(&ktr_header);
266 		if (pid && ktr_header.ktr_pid != pid)
267 			continue;
268 		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
269 			continue;
270 		drop_logged = 0;
271 		switch (ktr_header.ktr_type) {
272 		case KTR_SYSCALL:
273 #if defined(__amd64__) || defined(__i386__)
274 			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
275 				linux_ktrsyscall((struct ktr_syscall *)m);
276 			else
277 #endif
278 				ktrsyscall((struct ktr_syscall *)m, sv_flags);
279 			break;
280 		case KTR_SYSRET:
281 #if defined(__amd64__) || defined(__i386__)
282 			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
283 				linux_ktrsysret((struct ktr_sysret *)m);
284 			else
285 #endif
286 				ktrsysret((struct ktr_sysret *)m, sv_flags);
287 			break;
288 		case KTR_NAMEI:
289 		case KTR_SYSCTL:
290 			ktrnamei(m, ktrlen);
291 			break;
292 		case KTR_GENIO:
293 			ktrgenio((struct ktr_genio *)m, ktrlen);
294 			break;
295 		case KTR_PSIG:
296 			ktrpsig((struct ktr_psig *)m);
297 			break;
298 		case KTR_CSW:
299 			ktrcsw((struct ktr_csw *)m);
300 			break;
301 		case KTR_USER:
302 			ktruser(ktrlen, m);
303 			break;
304 		case KTR_STRUCT:
305 			ktrstruct(m, ktrlen);
306 			break;
307 		case KTR_CAPFAIL:
308 			ktrcapfail((struct ktr_cap_fail *)m);
309 		default:
310 			printf("\n");
311 			break;
312 		}
313 		if (tail)
314 			fflush(stdout);
315 	}
316 	return 0;
317 }
318 
319 int
320 fread_tail(void *buf, int size, int num)
321 {
322 	int i;
323 
324 	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
325 		sleep(1);
326 		clearerr(stdin);
327 	}
328 	return (i);
329 }
330 
331 int
332 fetchprocinfo(struct ktr_header *kth, u_int *flags)
333 {
334 	struct proc_info *pi;
335 
336 	switch (kth->ktr_type) {
337 	case KTR_PROCCTOR:
338 		TAILQ_FOREACH(pi, &trace_procs, info) {
339 			if (pi->pid == kth->ktr_pid) {
340 				TAILQ_REMOVE(&trace_procs, pi, info);
341 				break;
342 			}
343 		}
344 		pi = malloc(sizeof(struct proc_info));
345 		if (pi == NULL)
346 			errx(1, "%s", strerror(ENOMEM));
347 		pi->sv_flags = *flags;
348 		pi->pid = kth->ktr_pid;
349 		TAILQ_INSERT_TAIL(&trace_procs, pi, info);
350 		return (1);
351 
352 	case KTR_PROCDTOR:
353 		TAILQ_FOREACH(pi, &trace_procs, info) {
354 			if (pi->pid == kth->ktr_pid) {
355 				TAILQ_REMOVE(&trace_procs, pi, info);
356 				free(pi);
357 				break;
358 			}
359 		}
360 		return (1);
361 	}
362 
363 	return (0);
364 }
365 
366 u_int
367 abidump(struct ktr_header *kth)
368 {
369 	struct proc_info *pi;
370 	const char *abi;
371 	const char *arch;
372 	u_int flags = 0;
373 
374 	TAILQ_FOREACH(pi, &trace_procs, info) {
375 		if (pi->pid == kth->ktr_pid) {
376 			flags = pi->sv_flags;
377 			break;
378 		}
379 	}
380 
381 	if (abiflag == 0)
382 		return (flags);
383 
384 	switch (flags & SV_ABI_MASK) {
385 	case SV_ABI_LINUX:
386 		abi = "L";
387 		break;
388 	case SV_ABI_FREEBSD:
389 		abi = "F";
390 		break;
391 	default:
392 		abi = "U";
393 		break;
394 	}
395 
396 	if (flags != 0) {
397 		if (flags & SV_LP64)
398 			arch = "64";
399 		else
400 			arch = "32";
401 	} else
402 		arch = "00";
403 
404 	printf("%s%s  ", abi, arch);
405 
406 	return (flags);
407 }
408 
409 void
410 dumpheader(struct ktr_header *kth)
411 {
412 	static char unknown[64];
413 	static struct timeval prevtime, temp;
414 	const char *type;
415 
416 	switch (kth->ktr_type) {
417 	case KTR_SYSCALL:
418 		type = "CALL";
419 		break;
420 	case KTR_SYSRET:
421 		type = "RET ";
422 		break;
423 	case KTR_NAMEI:
424 		type = "NAMI";
425 		break;
426 	case KTR_GENIO:
427 		type = "GIO ";
428 		break;
429 	case KTR_PSIG:
430 		type = "PSIG";
431 		break;
432 	case KTR_CSW:
433 		type = "CSW ";
434 		break;
435 	case KTR_USER:
436 		type = "USER";
437 		break;
438 	case KTR_STRUCT:
439 		type = "STRU";
440 		break;
441 	case KTR_SYSCTL:
442 		type = "SCTL";
443 		break;
444 	case KTR_PROCCTOR:
445 		/* FALLTHROUGH */
446 	case KTR_PROCDTOR:
447 		return;
448 	case KTR_CAPFAIL:
449 		type = "CAP ";
450 		break;
451 	default:
452 		sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
453 		type = unknown;
454 	}
455 
456 	/*
457 	 * The ktr_tid field was previously the ktr_buffer field, which held
458 	 * the kernel pointer value for the buffer associated with data
459 	 * following the record header.  It now holds a threadid, but only
460 	 * for trace files after the change.  Older trace files still contain
461 	 * kernel pointers.  Detect this and suppress the results by printing
462 	 * negative tid's as 0.
463 	 */
464 	if (threads)
465 		printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid,
466 		    kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0,
467 		    MAXCOMLEN, kth->ktr_comm);
468 	else
469 		printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN,
470 		    kth->ktr_comm);
471 	if (timestamp) {
472 		if (timestamp == 3) {
473 			if (prevtime.tv_sec == 0)
474 				prevtime = kth->ktr_time;
475 			timevalsub(&kth->ktr_time, &prevtime);
476 		}
477 		if (timestamp == 2) {
478 			temp = kth->ktr_time;
479 			timevalsub(&kth->ktr_time, &prevtime);
480 			prevtime = temp;
481 		}
482 		printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
483 		    kth->ktr_time.tv_usec);
484 	}
485 	printf("%s  ", type);
486 }
487 
488 #include <sys/syscall.h>
489 #define KTRACE
490 #include <sys/kern/syscalls.c>
491 #undef KTRACE
492 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
493 
494 void
495 ktrsyscall(struct ktr_syscall *ktr, u_int flags)
496 {
497 	int narg = ktr->ktr_narg;
498 	register_t *ip;
499 	intmax_t arg;
500 
501 	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
502 	    (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
503 		printf("[%d]", ktr->ktr_code);
504 	else
505 		printf("%s", syscallnames[ktr->ktr_code]);
506 	ip = &ktr->ktr_args[0];
507 	if (narg) {
508 		char c = '(';
509 		if (fancy &&
510 		    (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
511 			switch (ktr->ktr_code) {
512 			case SYS_ioctl: {
513 				print_number(ip, narg, c);
514 				putchar(c);
515 				ioctlname(*ip, decimal);
516 				c = ',';
517 				ip++;
518 				narg--;
519 				break;
520 			}
521 			case SYS_ptrace:
522 				putchar('(');
523 				ptraceopname(*ip);
524 				c = ',';
525 				ip++;
526 				narg--;
527 				break;
528 			case SYS_access:
529 			case SYS_eaccess:
530 				print_number(ip, narg, c);
531 				putchar(',');
532 				accessmodename(*ip);
533 				ip++;
534 				narg--;
535 				break;
536 			case SYS_open:
537 				print_number(ip, narg, c);
538 				putchar(',');
539 				flagsandmodename(ip[0], ip[1], decimal);
540 				ip += 2;
541 				narg -= 2;
542 				break;
543 			case SYS_wait4:
544 				print_number(ip, narg, c);
545 				print_number(ip, narg, c);
546 				putchar(',');
547 				wait4optname(*ip);
548 				ip++;
549 				narg--;
550 				break;
551 			case SYS_chmod:
552 			case SYS_fchmod:
553 			case SYS_lchmod:
554 				print_number(ip, narg, c);
555 				putchar(',');
556 				modename(*ip);
557 				ip++;
558 				narg--;
559 				break;
560 			case SYS_mknod:
561 				print_number(ip, narg, c);
562 				putchar(',');
563 				modename(*ip);
564 				ip++;
565 				narg--;
566 				break;
567 			case SYS_getfsstat:
568 				print_number(ip, narg, c);
569 				print_number(ip, narg, c);
570 				putchar(',');
571 				getfsstatflagsname(*ip);
572 				ip++;
573 				narg--;
574 				break;
575 			case SYS_mount:
576 				print_number(ip, narg, c);
577 				print_number(ip, narg, c);
578 				putchar(',');
579 				mountflagsname(*ip);
580 				ip++;
581 				narg--;
582 				break;
583 			case SYS_unmount:
584 				print_number(ip, narg, c);
585 				putchar(',');
586 				mountflagsname(*ip);
587 				ip++;
588 				narg--;
589 				break;
590 			case SYS_recvmsg:
591 			case SYS_sendmsg:
592 				print_number(ip, narg, c);
593 				print_number(ip, narg, c);
594 				putchar(',');
595 				sendrecvflagsname(*ip);
596 				ip++;
597 				narg--;
598 				break;
599 			case SYS_recvfrom:
600 			case SYS_sendto:
601 				print_number(ip, narg, c);
602 				print_number(ip, narg, c);
603 				print_number(ip, narg, c);
604 				putchar(',');
605 				sendrecvflagsname(*ip);
606 				ip++;
607 				narg--;
608 				break;
609 			case SYS_chflags:
610 			case SYS_fchflags:
611 			case SYS_lchflags:
612 				print_number(ip, narg, c);
613 				putchar(',');
614 				modename(*ip);
615 				ip++;
616 				narg--;
617 				break;
618 			case SYS_kill:
619 				print_number(ip, narg, c);
620 				putchar(',');
621 				signame(*ip);
622 				ip++;
623 				narg--;
624 				break;
625 			case SYS_reboot:
626 				putchar('(');
627 				rebootoptname(*ip);
628 				ip++;
629 				narg--;
630 				break;
631 			case SYS_umask:
632 				putchar('(');
633 				modename(*ip);
634 				ip++;
635 				narg--;
636 				break;
637 			case SYS_msync:
638 				print_number(ip, narg, c);
639 				print_number(ip, narg, c);
640 				putchar(',');
641 				msyncflagsname(*ip);
642 				ip++;
643 				narg--;
644 				break;
645 #ifdef SYS_freebsd6_mmap
646 			case SYS_freebsd6_mmap:
647 				print_number(ip, narg, c);
648 				print_number(ip, narg, c);
649 				putchar(',');
650 				mmapprotname(*ip);
651 				putchar(',');
652 				ip++;
653 				narg--;
654 				mmapflagsname(*ip);
655 				ip++;
656 				narg--;
657 				break;
658 #endif
659 			case SYS_mmap:
660 				print_number(ip, narg, c);
661 				print_number(ip, narg, c);
662 				putchar(',');
663 				mmapprotname(*ip);
664 				putchar(',');
665 				ip++;
666 				narg--;
667 				mmapflagsname(*ip);
668 				ip++;
669 				narg--;
670 				break;
671 			case SYS_mprotect:
672 				print_number(ip, narg, c);
673 				print_number(ip, narg, c);
674 				putchar(',');
675 				mmapprotname(*ip);
676 				ip++;
677 				narg--;
678 				break;
679 			case SYS_madvise:
680 				print_number(ip, narg, c);
681 				print_number(ip, narg, c);
682 				putchar(',');
683 				madvisebehavname(*ip);
684 				ip++;
685 				narg--;
686 				break;
687 			case SYS_setpriority:
688 				print_number(ip, narg, c);
689 				print_number(ip, narg, c);
690 				putchar(',');
691 				prioname(*ip);
692 				ip++;
693 				narg--;
694 				break;
695 			case SYS_fcntl:
696 				print_number(ip, narg, c);
697 				putchar(',');
698 				fcntlcmdname(ip[0], ip[1], decimal);
699 				ip += 2;
700 				narg -= 2;
701 				break;
702 			case SYS_socket: {
703 				int sockdomain;
704 				putchar('(');
705 				sockdomain = *ip;
706 				sockdomainname(sockdomain);
707 				ip++;
708 				narg--;
709 				putchar(',');
710 				socktypename(*ip);
711 				ip++;
712 				narg--;
713 				if (sockdomain == PF_INET ||
714 				    sockdomain == PF_INET6) {
715 					putchar(',');
716 					sockipprotoname(*ip);
717 					ip++;
718 					narg--;
719 				}
720 				c = ',';
721 				break;
722 			}
723 			case SYS_setsockopt:
724 			case SYS_getsockopt:
725 				print_number(ip, narg, c);
726 				putchar(',');
727 				sockoptlevelname(*ip, decimal);
728 				if (*ip == SOL_SOCKET) {
729 					ip++;
730 					narg--;
731 					putchar(',');
732 					sockoptname(*ip);
733 				}
734 				ip++;
735 				narg--;
736 				break;
737 #ifdef SYS_freebsd6_lseek
738 			case SYS_freebsd6_lseek:
739 				print_number(ip, narg, c);
740 				/* Hidden 'pad' argument, not in lseek(2) */
741 				print_number(ip, narg, c);
742 				print_number(ip, narg, c);
743 				putchar(',');
744 				whencename(*ip);
745 				ip++;
746 				narg--;
747 				break;
748 #endif
749 			case SYS_lseek:
750 				print_number(ip, narg, c);
751 				/* Hidden 'pad' argument, not in lseek(2) */
752 				print_number(ip, narg, c);
753 				putchar(',');
754 				whencename(*ip);
755 				ip++;
756 				narg--;
757 				break;
758 			case SYS_flock:
759 				print_number(ip, narg, c);
760 				putchar(',');
761 				flockname(*ip);
762 				ip++;
763 				narg--;
764 				break;
765 			case SYS_mkfifo:
766 			case SYS_mkdir:
767 				print_number(ip, narg, c);
768 				putchar(',');
769 				modename(*ip);
770 				ip++;
771 				narg--;
772 				break;
773 			case SYS_shutdown:
774 				print_number(ip, narg, c);
775 				putchar(',');
776 				shutdownhowname(*ip);
777 				ip++;
778 				narg--;
779 				break;
780 			case SYS_socketpair:
781 				putchar('(');
782 				sockdomainname(*ip);
783 				ip++;
784 				narg--;
785 				putchar(',');
786 				socktypename(*ip);
787 				ip++;
788 				narg--;
789 				c = ',';
790 				break;
791 			case SYS_getrlimit:
792 			case SYS_setrlimit:
793 				putchar('(');
794 				rlimitname(*ip);
795 				ip++;
796 				narg--;
797 				c = ',';
798 				break;
799 			case SYS_quotactl:
800 				print_number(ip, narg, c);
801 				putchar(',');
802 				quotactlname(*ip);
803 				ip++;
804 				narg--;
805 				c = ',';
806 				break;
807 			case SYS_nfssvc:
808 				putchar('(');
809 				nfssvcname(*ip);
810 				ip++;
811 				narg--;
812 				c = ',';
813 				break;
814 			case SYS_rtprio:
815 				putchar('(');
816 				rtprioname(*ip);
817 				ip++;
818 				narg--;
819 				c = ',';
820 				break;
821 			case SYS___semctl:
822 				print_number(ip, narg, c);
823 				print_number(ip, narg, c);
824 				putchar(',');
825 				semctlname(*ip);
826 				ip++;
827 				narg--;
828 				break;
829 			case SYS_semget:
830 				print_number(ip, narg, c);
831 				print_number(ip, narg, c);
832 				putchar(',');
833 				semgetname(*ip);
834 				ip++;
835 				narg--;
836 				break;
837 			case SYS_msgctl:
838 				print_number(ip, narg, c);
839 				putchar(',');
840 				shmctlname(*ip);
841 				ip++;
842 				narg--;
843 				break;
844 			case SYS_shmat:
845 				print_number(ip, narg, c);
846 				print_number(ip, narg, c);
847 				putchar(',');
848 				shmatname(*ip);
849 				ip++;
850 				narg--;
851 				break;
852 			case SYS_shmctl:
853 				print_number(ip, narg, c);
854 				putchar(',');
855 				shmctlname(*ip);
856 				ip++;
857 				narg--;
858 				break;
859 			case SYS_minherit:
860 				print_number(ip, narg, c);
861 				print_number(ip, narg, c);
862 				putchar(',');
863 				minheritname(*ip);
864 				ip++;
865 				narg--;
866 				break;
867 			case SYS_rfork:
868 				putchar('(');
869 				rforkname(*ip);
870 				ip++;
871 				narg--;
872 				c = ',';
873 				break;
874 			case SYS_lio_listio:
875 				putchar('(');
876 				lio_listioname(*ip);
877 				ip++;
878 				narg--;
879 				c = ',';
880 				break;
881 			case SYS_mlockall:
882 				putchar('(');
883 				mlockallname(*ip);
884 				ip++;
885 				narg--;
886 				break;
887 			case SYS_sched_setscheduler:
888 				print_number(ip, narg, c);
889 				putchar(',');
890 				schedpolicyname(*ip);
891 				ip++;
892 				narg--;
893 				break;
894 			case SYS_sched_get_priority_max:
895 			case SYS_sched_get_priority_min:
896 				putchar('(');
897 				schedpolicyname(*ip);
898 				ip++;
899 				narg--;
900 				break;
901 			case SYS_sendfile:
902 				print_number(ip, narg, c);
903 				print_number(ip, narg, c);
904 				print_number(ip, narg, c);
905 				print_number(ip, narg, c);
906 				print_number(ip, narg, c);
907 				print_number(ip, narg, c);
908 				putchar(',');
909 				sendfileflagsname(*ip);
910 				ip++;
911 				narg--;
912 				break;
913 			case SYS_kldsym:
914 				print_number(ip, narg, c);
915 				putchar(',');
916 				kldsymcmdname(*ip);
917 				ip++;
918 				narg--;
919 				break;
920 			case SYS_sigprocmask:
921 				putchar('(');
922 				sigprocmaskhowname(*ip);
923 				ip++;
924 				narg--;
925 				c = ',';
926 				break;
927 			case SYS___acl_get_file:
928 			case SYS___acl_set_file:
929 			case SYS___acl_get_fd:
930 			case SYS___acl_set_fd:
931 			case SYS___acl_delete_file:
932 			case SYS___acl_delete_fd:
933 			case SYS___acl_aclcheck_file:
934 			case SYS___acl_aclcheck_fd:
935 			case SYS___acl_get_link:
936 			case SYS___acl_set_link:
937 			case SYS___acl_delete_link:
938 			case SYS___acl_aclcheck_link:
939 				print_number(ip, narg, c);
940 				putchar(',');
941 				acltypename(*ip);
942 				ip++;
943 				narg--;
944 				break;
945 			case SYS_sigaction:
946 				putchar('(');
947 				signame(*ip);
948 				ip++;
949 				narg--;
950 				c = ',';
951 				break;
952 			case SYS_extattrctl:
953 				print_number(ip, narg, c);
954 				putchar(',');
955 				extattrctlname(*ip);
956 				ip++;
957 				narg--;
958 				break;
959 			case SYS_nmount:
960 				print_number(ip, narg, c);
961 				print_number(ip, narg, c);
962 				putchar(',');
963 				mountflagsname(*ip);
964 				ip++;
965 				narg--;
966 				break;
967 			case SYS_thr_create:
968 				print_number(ip, narg, c);
969 				print_number(ip, narg, c);
970 				putchar(',');
971 				thrcreateflagsname(*ip);
972 				ip++;
973 				narg--;
974 				break;
975 			case SYS_thr_kill:
976 				print_number(ip, narg, c);
977 				putchar(',');
978 				signame(*ip);
979 				ip++;
980 				narg--;
981 				break;
982 			case SYS_kldunloadf:
983 				print_number(ip, narg, c);
984 				putchar(',');
985 				kldunloadfflagsname(*ip);
986 				ip++;
987 				narg--;
988 				break;
989 			case SYS_cap_new:
990 				print_number(ip, narg, c);
991 				putchar(',');
992 				arg = *ip;
993 				ip++;
994 				narg--;
995 				/*
996 				 * Hack: the second argument is a
997 				 * cap_rights_t, which 64 bits wide, so on
998 				 * 32-bit systems, it is split between two
999 				 * registers.
1000 				 *
1001 				 * Since sizeof() is not evaluated by the
1002 				 * preprocessor, we can't use an #ifdef,
1003 				 * but the compiler will probably optimize
1004 				 * the code out anyway.
1005 				 */
1006 				if (sizeof(cap_rights_t) > sizeof(register_t)) {
1007 #if _BYTE_ORDER == _LITTLE_ENDIAN
1008 					arg = ((intmax_t)*ip << 32) + arg;
1009 #else
1010 					arg = (arg << 32) + *ip;
1011 #endif
1012 					ip++;
1013 					narg--;
1014 				}
1015 				capname(arg);
1016 				break;
1017 			case SYS_posix_fadvise:
1018 				print_number(ip, narg, c);
1019 				print_number(ip, narg, c);
1020 				print_number(ip, narg, c);
1021 				(void)putchar(',');
1022 				fadvisebehavname((int)*ip);
1023 				ip++;
1024 				narg--;
1025 				break;
1026 			}
1027 		}
1028 		while (narg > 0) {
1029 			print_number(ip, narg, c);
1030 		}
1031 		putchar(')');
1032 	}
1033 	putchar('\n');
1034 }
1035 
1036 void
1037 ktrsysret(struct ktr_sysret *ktr, u_int flags)
1038 {
1039 	register_t ret = ktr->ktr_retval;
1040 	int error = ktr->ktr_error;
1041 	int code = ktr->ktr_code;
1042 
1043 	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
1044 	    (code >= nsyscalls || code < 0))
1045 		printf("[%d] ", code);
1046 	else
1047 		printf("%s ", syscallnames[code]);
1048 
1049 	if (error == 0) {
1050 		if (fancy) {
1051 			printf("%ld", (long)ret);
1052 			if (ret < 0 || ret > 9)
1053 				printf("/%#lx", (unsigned long)ret);
1054 		} else {
1055 			if (decimal)
1056 				printf("%ld", (long)ret);
1057 			else
1058 				printf("%#lx", (unsigned long)ret);
1059 		}
1060 	} else if (error == ERESTART)
1061 		printf("RESTART");
1062 	else if (error == EJUSTRETURN)
1063 		printf("JUSTRETURN");
1064 	else {
1065 		printf("-1 errno %d", ktr->ktr_error);
1066 		if (fancy)
1067 			printf(" %s", strerror(ktr->ktr_error));
1068 	}
1069 	putchar('\n');
1070 }
1071 
1072 void
1073 ktrnamei(char *cp, int len)
1074 {
1075 	printf("\"%.*s\"\n", len, cp);
1076 }
1077 
1078 void
1079 hexdump(char *p, int len, int screenwidth)
1080 {
1081 	int n, i;
1082 	int width;
1083 
1084 	width = 0;
1085 	do {
1086 		width += 2;
1087 		i = 13;			/* base offset */
1088 		i += (width / 2) + 1;	/* spaces every second byte */
1089 		i += (width * 2);	/* width of bytes */
1090 		i += 3;			/* "  |" */
1091 		i += width;		/* each byte */
1092 		i += 1;			/* "|" */
1093 	} while (i < screenwidth);
1094 	width -= 2;
1095 
1096 	for (n = 0; n < len; n += width) {
1097 		for (i = n; i < n + width; i++) {
1098 			if ((i % width) == 0) {	/* beginning of line */
1099 				printf("       0x%04x", i);
1100 			}
1101 			if ((i % 2) == 0) {
1102 				printf(" ");
1103 			}
1104 			if (i < len)
1105 				printf("%02x", p[i] & 0xff);
1106 			else
1107 				printf("  ");
1108 		}
1109 		printf("  |");
1110 		for (i = n; i < n + width; i++) {
1111 			if (i >= len)
1112 				break;
1113 			if (p[i] >= ' ' && p[i] <= '~')
1114 				printf("%c", p[i]);
1115 			else
1116 				printf(".");
1117 		}
1118 		printf("|\n");
1119 	}
1120 	if ((i % width) != 0)
1121 		printf("\n");
1122 }
1123 
1124 void
1125 visdump(char *dp, int datalen, int screenwidth)
1126 {
1127 	int col = 0;
1128 	char *cp;
1129 	int width;
1130 	char visbuf[5];
1131 
1132 	printf("       \"");
1133 	col = 8;
1134 	for (;datalen > 0; datalen--, dp++) {
1135 		 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
1136 		cp = visbuf;
1137 		/*
1138 		 * Keep track of printables and
1139 		 * space chars (like fold(1)).
1140 		 */
1141 		if (col == 0) {
1142 			putchar('\t');
1143 			col = 8;
1144 		}
1145 		switch(*cp) {
1146 		case '\n':
1147 			col = 0;
1148 			putchar('\n');
1149 			continue;
1150 		case '\t':
1151 			width = 8 - (col&07);
1152 			break;
1153 		default:
1154 			width = strlen(cp);
1155 		}
1156 		if (col + width > (screenwidth-2)) {
1157 			printf("\\\n\t");
1158 			col = 8;
1159 		}
1160 		col += width;
1161 		do {
1162 			putchar(*cp++);
1163 		} while (*cp);
1164 	}
1165 	if (col == 0)
1166 		printf("       ");
1167 	printf("\"\n");
1168 }
1169 
1170 void
1171 ktrgenio(struct ktr_genio *ktr, int len)
1172 {
1173 	int datalen = len - sizeof (struct ktr_genio);
1174 	char *dp = (char *)ktr + sizeof (struct ktr_genio);
1175 	static int screenwidth = 0;
1176 	int i, binary;
1177 
1178 	if (screenwidth == 0) {
1179 		struct winsize ws;
1180 
1181 		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1182 		    ws.ws_col > 8)
1183 			screenwidth = ws.ws_col;
1184 		else
1185 			screenwidth = 80;
1186 	}
1187 	printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1188 		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1189 		datalen == 1 ? "" : "s");
1190 	if (suppressdata)
1191 		return;
1192 	if (maxdata && datalen > maxdata)
1193 		datalen = maxdata;
1194 
1195 	for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1196 		if (dp[i] >= 32 && dp[i] < 127)
1197 			continue;
1198 		if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1199 			continue;
1200 		binary = 1;
1201 	}
1202 	if (binary)
1203 		hexdump(dp, datalen, screenwidth);
1204 	else
1205 		visdump(dp, datalen, screenwidth);
1206 }
1207 
1208 const char *signames[] = {
1209 	"NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",	/*  1 - 6  */
1210 	"EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",		/*  7 - 12 */
1211 	"PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",		/* 13 - 18 */
1212 	"CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",		/* 19 - 24 */
1213 	"XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",	/* 25 - 30 */
1214 	"USR2", NULL,						/* 31 - 32 */
1215 };
1216 
1217 void
1218 ktrpsig(struct ktr_psig *psig)
1219 {
1220 	if (psig->signo > 0 && psig->signo < NSIG)
1221 		printf("SIG%s ", signames[psig->signo]);
1222 	else
1223 		printf("SIG %d ", psig->signo);
1224 	if (psig->action == SIG_DFL)
1225 		printf("SIG_DFL code=0x%x\n", psig->code);
1226 	else {
1227 		printf("caught handler=0x%lx mask=0x%x code=0x%x\n",
1228 		    (u_long)psig->action, psig->mask.__bits[0], psig->code);
1229 	}
1230 }
1231 
1232 void
1233 ktrcsw(struct ktr_csw *cs)
1234 {
1235 	printf("%s %s\n", cs->out ? "stop" : "resume",
1236 		cs->user ? "user" : "kernel");
1237 }
1238 
1239 #define	UTRACE_DLOPEN_START		1
1240 #define	UTRACE_DLOPEN_STOP		2
1241 #define	UTRACE_DLCLOSE_START		3
1242 #define	UTRACE_DLCLOSE_STOP		4
1243 #define	UTRACE_LOAD_OBJECT		5
1244 #define	UTRACE_UNLOAD_OBJECT		6
1245 #define	UTRACE_ADD_RUNDEP		7
1246 #define	UTRACE_PRELOAD_FINISHED		8
1247 #define	UTRACE_INIT_CALL		9
1248 #define	UTRACE_FINI_CALL		10
1249 
1250 struct utrace_rtld {
1251 	char sig[4];				/* 'RTLD' */
1252 	int event;
1253 	void *handle;
1254 	void *mapbase;
1255 	size_t mapsize;
1256 	int refcnt;
1257 	char name[MAXPATHLEN];
1258 };
1259 
1260 void
1261 ktruser_rtld(int len, unsigned char *p)
1262 {
1263 	struct utrace_rtld *ut = (struct utrace_rtld *)p;
1264 	void *parent;
1265 	int mode;
1266 
1267 	switch (ut->event) {
1268 	case UTRACE_DLOPEN_START:
1269 		mode = ut->refcnt;
1270 		printf("dlopen(%s, ", ut->name);
1271 		switch (mode & RTLD_MODEMASK) {
1272 		case RTLD_NOW:
1273 			printf("RTLD_NOW");
1274 			break;
1275 		case RTLD_LAZY:
1276 			printf("RTLD_LAZY");
1277 			break;
1278 		default:
1279 			printf("%#x", mode & RTLD_MODEMASK);
1280 		}
1281 		if (mode & RTLD_GLOBAL)
1282 			printf(" | RTLD_GLOBAL");
1283 		if (mode & RTLD_TRACE)
1284 			printf(" | RTLD_TRACE");
1285 		if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
1286 			printf(" | %#x", mode &
1287 			    ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
1288 		printf(")\n");
1289 		break;
1290 	case UTRACE_DLOPEN_STOP:
1291 		printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
1292 		    ut->refcnt);
1293 		break;
1294 	case UTRACE_DLCLOSE_START:
1295 		printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
1296 		    ut->refcnt);
1297 		break;
1298 	case UTRACE_DLCLOSE_STOP:
1299 		printf("dlclose(%p) finished\n", ut->handle);
1300 		break;
1301 	case UTRACE_LOAD_OBJECT:
1302 		printf("RTLD: loaded   %p @ %p - %p (%s)\n", ut->handle,
1303 		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1304 		    ut->name);
1305 		break;
1306 	case UTRACE_UNLOAD_OBJECT:
1307 		printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
1308 		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1309 		    ut->name);
1310 		break;
1311 	case UTRACE_ADD_RUNDEP:
1312 		parent = ut->mapbase;
1313 		printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
1314 		    ut->handle, ut->name, ut->refcnt);
1315 		break;
1316 	case UTRACE_PRELOAD_FINISHED:
1317 		printf("RTLD: LD_PRELOAD finished\n");
1318 		break;
1319 	case UTRACE_INIT_CALL:
1320 		printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1321 		    ut->name);
1322 		break;
1323 	case UTRACE_FINI_CALL:
1324 		printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1325 		    ut->name);
1326 		break;
1327 	default:
1328 		p += 4;
1329 		len -= 4;
1330 		printf("RTLD: %d ", len);
1331 		while (len--)
1332 			if (decimal)
1333 				printf(" %d", *p++);
1334 			else
1335 				printf(" %02x", *p++);
1336 		printf("\n");
1337 	}
1338 }
1339 
1340 struct utrace_malloc {
1341 	void *p;
1342 	size_t s;
1343 	void *r;
1344 };
1345 
1346 void
1347 ktruser_malloc(unsigned char *p)
1348 {
1349 	struct utrace_malloc *ut = (struct utrace_malloc *)p;
1350 
1351 	if (ut->p == (void *)(intptr_t)(-1))
1352 		printf("malloc_init()\n");
1353 	else if (ut->s == 0)
1354 		printf("free(%p)\n", ut->p);
1355 	else if (ut->p == NULL)
1356 		printf("%p = malloc(%zu)\n", ut->r, ut->s);
1357 	else
1358 		printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1359 }
1360 
1361 void
1362 ktruser(int len, unsigned char *p)
1363 {
1364 
1365 	if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1366 		ktruser_rtld(len, p);
1367 		return;
1368 	}
1369 
1370 	if (len == sizeof(struct utrace_malloc)) {
1371 		ktruser_malloc(p);
1372 		return;
1373 	}
1374 
1375 	printf("%d ", len);
1376 	while (len--)
1377 		if (decimal)
1378 			printf(" %d", *p++);
1379 		else
1380 			printf(" %02x", *p++);
1381 	printf("\n");
1382 }
1383 
1384 void
1385 ktrsockaddr(struct sockaddr *sa)
1386 {
1387 /*
1388  TODO: Support additional address families
1389 	#include <netnatm/natm.h>
1390 	struct sockaddr_natm	*natm;
1391 	#include <netsmb/netbios.h>
1392 	struct sockaddr_nb	*nb;
1393 */
1394 	char addr[64];
1395 
1396 	/*
1397 	 * note: ktrstruct() has already verified that sa points to a
1398 	 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1399 	 * sa->sa_len bytes long.
1400 	 */
1401 	printf("struct sockaddr { ");
1402 	sockfamilyname(sa->sa_family);
1403 	printf(", ");
1404 
1405 #define check_sockaddr_len(n)					\
1406 	if (sa_##n.s##n##_len < sizeof(struct sockaddr_##n)) {	\
1407 		printf("invalid");				\
1408 		break;						\
1409 	}
1410 
1411 	switch(sa->sa_family) {
1412 	case AF_INET: {
1413 		struct sockaddr_in sa_in;
1414 
1415 		memset(&sa_in, 0, sizeof(sa_in));
1416 		memcpy(&sa_in, sa, sizeof(sa));
1417 		check_sockaddr_len(in);
1418 		inet_ntop(AF_INET, &sa_in.sin_addr, addr, sizeof addr);
1419 		printf("%s:%u", addr, ntohs(sa_in.sin_port));
1420 		break;
1421 	}
1422 #ifdef NETATALK
1423 	case AF_APPLETALK: {
1424 		struct sockaddr_at	sa_at;
1425 		struct netrange		*nr;
1426 
1427 		memset(&sa_at, 0, sizeof(sa_at));
1428 		memcpy(&sa_at, sa, sizeof(sa));
1429 		check_sockaddr_len(at);
1430 		nr = &sa_at.sat_range.r_netrange;
1431 		printf("%d.%d, %d-%d, %d", ntohs(sa_at.sat_addr.s_net),
1432 			sa_at.sat_addr.s_node, ntohs(nr->nr_firstnet),
1433 			ntohs(nr->nr_lastnet), nr->nr_phase);
1434 		break;
1435 	}
1436 #endif
1437 	case AF_INET6: {
1438 		struct sockaddr_in6 sa_in6;
1439 
1440 		memset(&sa_in6, 0, sizeof(sa_in6));
1441 		memcpy(&sa_in6, sa, sizeof(sa));
1442 		check_sockaddr_len(in6);
1443 		inet_ntop(AF_INET6, &sa_in6.sin6_addr, addr, sizeof addr);
1444 		printf("[%s]:%u", addr, htons(sa_in6.sin6_port));
1445 		break;
1446 	}
1447 #ifdef IPX
1448 	case AF_IPX: {
1449 		struct sockaddr_ipx sa_ipx;
1450 
1451 		memset(&sa_ipx, 0, sizeof(sa_ipx));
1452 		memcpy(&sa_ipx, sa, sizeof(sa));
1453 		check_sockaddr_len(ipx);
1454 		/* XXX wish we had ipx_ntop */
1455 		printf("%s", ipx_ntoa(sa_ipx.sipx_addr));
1456 		free(sa_ipx);
1457 		break;
1458 	}
1459 #endif
1460 	case AF_UNIX: {
1461 		struct sockaddr_un sa_un;
1462 
1463 		memset(&sa_un, 0, sizeof(sa_un));
1464 		memcpy(&sa_un, sa, sizeof(sa));
1465 		check_sockaddr_len(un);
1466 		printf("%.*s", (int)sizeof(sa_un.sun_path), sa_un.sun_path);
1467 		break;
1468 	}
1469 	default:
1470 		printf("unknown address family");
1471 	}
1472 	printf(" }\n");
1473 }
1474 
1475 void
1476 ktrstat(struct stat *statp)
1477 {
1478 	char mode[12], timestr[PATH_MAX + 4];
1479 	struct passwd *pwd;
1480 	struct group  *grp;
1481 	struct tm *tm;
1482 
1483 	/*
1484 	 * note: ktrstruct() has already verified that statp points to a
1485 	 * buffer exactly sizeof(struct stat) bytes long.
1486 	 */
1487 	printf("struct stat {");
1488 	strmode(statp->st_mode, mode);
1489 	printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ",
1490 		(uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode,
1491 		(uintmax_t)statp->st_nlink);
1492 	if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1493 		printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1494 	else
1495 		printf("uid=\"%s\", ", pwd->pw_name);
1496 	if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1497 		printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1498 	else
1499 		printf("gid=\"%s\", ", grp->gr_name);
1500 	printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1501 	printf("atime=");
1502 	if (resolv == 0)
1503 		printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1504 	else {
1505 		tm = localtime(&statp->st_atim.tv_sec);
1506 		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1507 		printf("\"%s\"", timestr);
1508 	}
1509 	if (statp->st_atim.tv_nsec != 0)
1510 		printf(".%09ld, ", statp->st_atim.tv_nsec);
1511 	else
1512 		printf(", ");
1513 	printf("stime=");
1514 	if (resolv == 0)
1515 		printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1516 	else {
1517 		tm = localtime(&statp->st_mtim.tv_sec);
1518 		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1519 		printf("\"%s\"", timestr);
1520 	}
1521 	if (statp->st_mtim.tv_nsec != 0)
1522 		printf(".%09ld, ", statp->st_mtim.tv_nsec);
1523 	else
1524 		printf(", ");
1525 	printf("ctime=");
1526 	if (resolv == 0)
1527 		printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1528 	else {
1529 		tm = localtime(&statp->st_ctim.tv_sec);
1530 		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1531 		printf("\"%s\"", timestr);
1532 	}
1533 	if (statp->st_ctim.tv_nsec != 0)
1534 		printf(".%09ld, ", statp->st_ctim.tv_nsec);
1535 	else
1536 		printf(", ");
1537 	printf("birthtime=");
1538 	if (resolv == 0)
1539 		printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
1540 	else {
1541 		tm = localtime(&statp->st_birthtim.tv_sec);
1542 		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1543 		printf("\"%s\"", timestr);
1544 	}
1545 	if (statp->st_birthtim.tv_nsec != 0)
1546 		printf(".%09ld, ", statp->st_birthtim.tv_nsec);
1547 	else
1548 		printf(", ");
1549 	printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1550 		(uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
1551 		(intmax_t)statp->st_blocks, statp->st_flags);
1552 	printf(" }\n");
1553 }
1554 
1555 void
1556 ktrstruct(char *buf, size_t buflen)
1557 {
1558 	char *name, *data;
1559 	size_t namelen, datalen;
1560 	int i;
1561 	struct stat sb;
1562 	struct sockaddr_storage ss;
1563 
1564 	for (name = buf, namelen = 0;
1565 	     namelen < buflen && name[namelen] != '\0';
1566 	     ++namelen)
1567 		/* nothing */;
1568 	if (namelen == buflen)
1569 		goto invalid;
1570 	if (name[namelen] != '\0')
1571 		goto invalid;
1572 	data = buf + namelen + 1;
1573 	datalen = buflen - namelen - 1;
1574 	if (datalen == 0)
1575 		goto invalid;
1576 	/* sanity check */
1577 	for (i = 0; i < (int)namelen; ++i)
1578 		if (!isalpha(name[i]))
1579 			goto invalid;
1580 	if (strcmp(name, "stat") == 0) {
1581 		if (datalen != sizeof(struct stat))
1582 			goto invalid;
1583 		memcpy(&sb, data, datalen);
1584 		ktrstat(&sb);
1585 	} else if (strcmp(name, "sockaddr") == 0) {
1586 		if (datalen > sizeof(ss))
1587 			goto invalid;
1588 		memcpy(&ss, data, datalen);
1589 		if (datalen < sizeof(struct sockaddr) ||
1590 		    datalen != ss.ss_len)
1591 			goto invalid;
1592 		ktrsockaddr((struct sockaddr *)&ss);
1593 	} else {
1594 		printf("unknown structure\n");
1595 	}
1596 	return;
1597 invalid:
1598 	printf("invalid record\n");
1599 }
1600 
1601 void
1602 ktrcapfail(struct ktr_cap_fail *ktr)
1603 {
1604 	switch (ktr->cap_type) {
1605 	case CAPFAIL_NOTCAPABLE:
1606 		/* operation on fd with insufficient capabilities */
1607 		printf("operation requires ");
1608 		capname((intmax_t)ktr->cap_needed);
1609 		printf(", process holds ");
1610 		capname((intmax_t)ktr->cap_held);
1611 		break;
1612 	case CAPFAIL_INCREASE:
1613 		/* requested more capabilities than fd already has */
1614 		printf("attempt to increase capabilities from ");
1615 		capname((intmax_t)ktr->cap_held);
1616 		printf(" to ");
1617 		capname((intmax_t)ktr->cap_needed);
1618 		break;
1619 	case CAPFAIL_SYSCALL:
1620 		/* called restricted syscall */
1621 		printf("disallowed system call");
1622 		break;
1623 	case CAPFAIL_LOOKUP:
1624 		/* used ".." in strict-relative mode */
1625 		printf("restricted VFS lookup");
1626 		break;
1627 	default:
1628 		printf("unknown capability failure: ");
1629 		capname((intmax_t)ktr->cap_needed);
1630 		printf(" ");
1631 		capname((intmax_t)ktr->cap_held);
1632 		break;
1633 	}
1634 }
1635 
1636 #if defined(__amd64__) || defined(__i386__)
1637 void
1638 linux_ktrsyscall(struct ktr_syscall *ktr)
1639 {
1640 	int narg = ktr->ktr_narg;
1641 	register_t *ip;
1642 
1643 	if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
1644 		printf("[%d]", ktr->ktr_code);
1645 	else
1646 		printf("%s", linux_syscallnames[ktr->ktr_code]);
1647 	ip = &ktr->ktr_args[0];
1648 	if (narg) {
1649 		char c = '(';
1650 		while (narg > 0)
1651 			print_number(ip, narg, c);
1652 		putchar(')');
1653 	}
1654 	putchar('\n');
1655 }
1656 
1657 void
1658 linux_ktrsysret(struct ktr_sysret *ktr)
1659 {
1660 	register_t ret = ktr->ktr_retval;
1661 	int error = ktr->ktr_error;
1662 	int code = ktr->ktr_code;
1663 
1664 	if (code >= nlinux_syscalls || code < 0)
1665 		printf("[%d] ", code);
1666 	else
1667 		printf("%s ", linux_syscallnames[code]);
1668 
1669 	if (error == 0) {
1670 		if (fancy) {
1671 			printf("%ld", (long)ret);
1672 			if (ret < 0 || ret > 9)
1673 				printf("/%#lx", (unsigned long)ret);
1674 		} else {
1675 			if (decimal)
1676 				printf("%ld", (long)ret);
1677 			else
1678 				printf("%#lx", (unsigned long)ret);
1679 		}
1680 	} else if (error == ERESTART)
1681 		printf("RESTART");
1682 	else if (error == EJUSTRETURN)
1683 		printf("JUSTRETURN");
1684 	else {
1685 		if (ktr->ktr_error <= ELAST + 1)
1686 			error = abs(bsd_to_linux_errno[ktr->ktr_error]);
1687 		else
1688 			error = 999;
1689 		printf("-1 errno %d", error);
1690 		if (fancy)
1691 			printf(" %s", strerror(ktr->ktr_error));
1692 	}
1693 	putchar('\n');
1694 }
1695 #endif
1696 
1697 void
1698 usage(void)
1699 {
1700 	fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] "
1701 	    "[-m maxdata] [-p pid] [-t trstr]\n");
1702 	exit(1);
1703 }
1704