xref: /openbsd-src/usr.bin/kdump/kdump.c (revision 4e1ee0786f11cc571bd0be17d38e46f635c719fc)
1 /*	$OpenBSD: kdump.c,v 1.144 2021/07/12 15:09:19 beck 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>	/* MAXCOMLEN nitems */
33 #include <sys/time.h>
34 #include <sys/signal.h>
35 #include <sys/uio.h>
36 #include <sys/ktrace.h>
37 #include <sys/ioctl.h>
38 #include <sys/malloc.h>
39 #include <sys/namei.h>
40 #include <sys/ptrace.h>
41 #include <sys/sem.h>
42 #include <sys/shm.h>
43 #include <sys/socket.h>
44 #include <sys/sysctl.h>
45 #include <sys/siginfo.h>
46 #include <sys/vmmeter.h>
47 #include <sys/tty.h>
48 #include <sys/wait.h>
49 #define PLEDGENAMES
50 #include <sys/pledge.h>
51 #undef PLEDGENAMES
52 #define _KERNEL
53 #include <errno.h>
54 #undef _KERNEL
55 #include <ddb/db_var.h>
56 #include <machine/cpu.h>
57 
58 #include <ctype.h>
59 #include <err.h>
60 #include <fcntl.h>
61 #include <limits.h>
62 #include <netdb.h>
63 #include <poll.h>
64 #include <signal.h>
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <stdint.h>
68 #include <string.h>
69 #include <unistd.h>
70 #include <vis.h>
71 
72 #include "ktrace.h"
73 #include "kdump.h"
74 #include "kdump_subr.h"
75 #include "extern.h"
76 
77 enum {
78 	TIMESTAMP_NONE,
79 	TIMESTAMP_ABSOLUTE,
80 	TIMESTAMP_RELATIVE,
81 	TIMESTAMP_ELAPSED
82 } timestamp = TIMESTAMP_NONE;
83 
84 int decimal, iohex, fancy = 1, maxdata = INT_MAX;
85 int needtid, tail, basecol;
86 char *tracefile = DEF_TRACEFILE;
87 struct ktr_header ktr_header;
88 pid_t pid_opt = -1;
89 
90 #define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
91 
92 #include <sys/syscall.h>
93 
94 #define KTRACE
95 #define PTRACE
96 #define NFSCLIENT
97 #define NFSSERVER
98 #define SYSVSEM
99 #define SYSVMSG
100 #define SYSVSHM
101 #define ACCOUNTING
102 #include <kern/syscalls.c>
103 #undef KTRACE
104 #undef PTRACE
105 #undef NFSCLIENT
106 #undef NFSSERVER
107 #undef SYSVSEM
108 #undef SYSVMSG
109 #undef SYSVSHM
110 #undef ACCOUNTING
111 
112 
113 static char *ptrace_ops[] = {
114 	"PT_TRACE_ME",	"PT_READ_I",	"PT_READ_D",	"PT_READ_U",
115 	"PT_WRITE_I",	"PT_WRITE_D",	"PT_WRITE_U",	"PT_CONTINUE",
116 	"PT_KILL",	"PT_ATTACH",	"PT_DETACH",	"PT_IO",
117 	"PT_SET_EVENT_MASK", "PT_GET_EVENT_MASK", "PT_GET_PROCESS_STATE",
118 	"PT_GET_THREAD_FIRST", "PT_GET_THREAD_NEXT",
119 };
120 
121 static int fread_tail(void *, size_t, size_t);
122 static void dumpheader(struct ktr_header *);
123 static void ktrgenio(struct ktr_genio *, size_t);
124 static void ktrnamei(const char *, size_t);
125 static void ktrpsig(struct ktr_psig *);
126 static void ktrsyscall(struct ktr_syscall *, size_t);
127 static const char *kresolvsysctl(int, const int *);
128 static void ktrsysret(struct ktr_sysret *, size_t);
129 static void ktruser(struct ktr_user *, size_t);
130 static void ktrexec(const char*, size_t);
131 static void ktrpledge(struct ktr_pledge *, size_t);
132 static void usage(void);
133 static void ioctldecode(int);
134 static void ptracedecode(int);
135 static void atfd(int);
136 static void polltimeout(int);
137 static void wait4pid(int);
138 static void signame(int);
139 static void semctlname(int);
140 static void shmctlname(int);
141 static void semgetname(int);
142 static void flagsandmodename(int);
143 static void clockname(int);
144 static void sockoptlevelname(int);
145 static void ktraceopname(int);
146 
147 static int screenwidth;
148 
149 int
150 main(int argc, char *argv[])
151 {
152 	int ch, silent;
153 	size_t ktrlen, size;
154 	int trpoints = ALL_POINTS;
155 	const char *errstr;
156 	void *m;
157 
158 	if (screenwidth == 0) {
159 		struct winsize ws;
160 
161 		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
162 		    ws.ws_col > 8)
163 			screenwidth = ws.ws_col;
164 		else
165 			screenwidth = 80;
166 	}
167 
168 	while ((ch = getopt(argc, argv, "f:dHlm:np:RTt:xX")) != -1)
169 		switch (ch) {
170 		case 'f':
171 			tracefile = optarg;
172 			break;
173 		case 'd':
174 			decimal = 1;
175 			break;
176 		case 'H':
177 			needtid = 1;
178 			break;
179 		case 'l':
180 			tail = 1;
181 			break;
182 		case 'm':
183 			maxdata = strtonum(optarg, 0, INT_MAX, &errstr);
184 			if (errstr)
185 				errx(1, "-m %s: %s", optarg, errstr);
186 			break;
187 		case 'n':
188 			fancy = 0;
189 			break;
190 		case 'p':
191 			pid_opt = strtonum(optarg, 1, INT_MAX, &errstr);
192 			if (errstr)
193 				errx(1, "-p %s: %s", optarg, errstr);
194 			break;
195 		case 'R':	/* relative timestamp */
196 			if (timestamp == TIMESTAMP_ABSOLUTE)
197 				timestamp = TIMESTAMP_ELAPSED;
198 			else
199 				timestamp = TIMESTAMP_RELATIVE;
200 			break;
201 		case 'T':
202 			if (timestamp == TIMESTAMP_RELATIVE)
203 				timestamp = TIMESTAMP_ELAPSED;
204 			else
205 				timestamp = TIMESTAMP_ABSOLUTE;
206 			break;
207 		case 't':
208 			trpoints = getpoints(optarg, DEF_POINTS);
209 			if (trpoints < 0)
210 				errx(1, "unknown trace point in %s", optarg);
211 			break;
212 		case 'x':
213 			iohex = 1;
214 			break;
215 		case 'X':
216 			iohex = 2;
217 			break;
218 		default:
219 			usage();
220 		}
221 	if (argc > optind)
222 		usage();
223 
224 	if (strcmp(tracefile, "-") != 0)
225 		if (unveil(tracefile, "r") == -1)
226 			err(1, "unveil %s", tracefile);
227 	if (unveil(_PATH_PROTOCOLS, "r") == -1)
228 		err(1, "unveil %s", _PATH_PROTOCOLS);
229 	if (pledge("stdio rpath getpw", NULL) == -1)
230 		err(1, "pledge");
231 
232 	m = malloc(size = 1025);
233 	if (m == NULL)
234 		err(1, NULL);
235 	if (strcmp(tracefile, "-") != 0)
236 		if (!freopen(tracefile, "r", stdin))
237 			err(1, "%s", tracefile);
238 
239 	if (fread_tail(&ktr_header, sizeof(struct ktr_header), 1) == 0 ||
240 	    ktr_header.ktr_type != htobe32(KTR_START))
241 		errx(1, "%s: not a dump", tracefile);
242 	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
243 		silent = 0;
244 		if (pid_opt != -1 && pid_opt != ktr_header.ktr_pid)
245 			silent = 1;
246 		if (silent == 0 && trpoints & (1<<ktr_header.ktr_type))
247 			dumpheader(&ktr_header);
248 		ktrlen = ktr_header.ktr_len;
249 		if (ktrlen > size) {
250 			void *newm;
251 
252 			if (ktrlen == SIZE_MAX)
253 				errx(1, "data too long");
254 			newm = realloc(m, ktrlen+1);
255 			if (newm == NULL)
256 				err(1, "realloc");
257 			m = newm;
258 			size = ktrlen;
259 		}
260 		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
261 			errx(1, "data too short");
262 		if (silent)
263 			continue;
264 		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
265 			continue;
266 		switch (ktr_header.ktr_type) {
267 		case KTR_SYSCALL:
268 			ktrsyscall(m, ktrlen);
269 			break;
270 		case KTR_SYSRET:
271 			ktrsysret(m, ktrlen);
272 			break;
273 		case KTR_NAMEI:
274 			ktrnamei(m, ktrlen);
275 			break;
276 		case KTR_GENIO:
277 			ktrgenio(m, ktrlen);
278 			break;
279 		case KTR_PSIG:
280 			ktrpsig(m);
281 			break;
282 		case KTR_STRUCT:
283 			ktrstruct(m, ktrlen);
284 			break;
285 		case KTR_USER:
286 			ktruser(m, ktrlen);
287 			break;
288 		case KTR_EXECARGS:
289 		case KTR_EXECENV:
290 			ktrexec(m, ktrlen);
291 			break;
292 		case KTR_PLEDGE:
293 			ktrpledge(m, ktrlen);
294 			break;
295 		default:
296 			printf("\n");
297 			break;
298 		}
299 		if (tail)
300 			(void)fflush(stdout);
301 	}
302 	exit(0);
303 }
304 
305 static int
306 fread_tail(void *buf, size_t size, size_t num)
307 {
308 	int i;
309 
310 	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
311 		(void)sleep(1);
312 		clearerr(stdin);
313 	}
314 	return (i);
315 }
316 
317 static void
318 dumpheader(struct ktr_header *kth)
319 {
320 	static struct timespec prevtime;
321 	char unknown[64], *type;
322 	struct timespec temp;
323 
324 	switch (kth->ktr_type) {
325 	case KTR_SYSCALL:
326 		type = "CALL";
327 		break;
328 	case KTR_SYSRET:
329 		type = "RET ";
330 		break;
331 	case KTR_NAMEI:
332 		type = "NAMI";
333 		break;
334 	case KTR_GENIO:
335 		type = "GIO ";
336 		break;
337 	case KTR_PSIG:
338 		type = "PSIG";
339 		break;
340 	case KTR_STRUCT:
341 		type = "STRU";
342 		break;
343 	case KTR_USER:
344 		type = "USER";
345 		break;
346 	case KTR_EXECARGS:
347 		type = "ARGS";
348 		break;
349 	case KTR_EXECENV:
350 		type = "ENV ";
351 		break;
352 	case KTR_PLEDGE:
353 		type = "PLDG";
354 		break;
355 	default:
356 		/* htobe32() not guaranteed to work as case label */
357 		if (kth->ktr_type == htobe32(KTR_START)) {
358 			type = "STRT";
359 			break;
360 		}
361 		(void)snprintf(unknown, sizeof unknown, "UNKNOWN(%u)",
362 		    kth->ktr_type);
363 		type = unknown;
364 	}
365 
366 	basecol = printf("%6ld", (long)kth->ktr_pid);
367 	if (needtid)
368 		basecol += printf("/%-7ld", (long)kth->ktr_tid);
369 	basecol += printf(" %-8.*s ", MAXCOMLEN, kth->ktr_comm);
370 	if (timestamp != TIMESTAMP_NONE) {
371 		if (timestamp == TIMESTAMP_ELAPSED) {
372 			if (prevtime.tv_sec == 0)
373 				prevtime = kth->ktr_time;
374 			timespecsub(&kth->ktr_time, &prevtime, &temp);
375 		} else if (timestamp == TIMESTAMP_RELATIVE) {
376 			timespecsub(&kth->ktr_time, &prevtime, &temp);
377 			prevtime = kth->ktr_time;
378 		} else
379 			temp = kth->ktr_time;
380 		basecol += printf("%lld.%06ld ", (long long)temp.tv_sec,
381 		    temp.tv_nsec / 1000);
382 	}
383 	basecol += printf("%s  ", type);
384 }
385 
386 /*
387  * Base Formatters
388  */
389 
390 /* some syscalls have padding that shouldn't be shown */
391 static int
392 pad(long arg)
393 {
394 	/* nothing printed */
395 	return (1);
396 }
397 
398 /* a formatter that just saves the argument for the next formatter */
399 int arg1;
400 static int
401 pass_two(long arg)
402 {
403 	arg1 = (int)arg;
404 
405 	/* nothing printed */
406 	return (1);
407 }
408 
409 static int
410 pdeclong(long arg)
411 {
412 	(void)printf("%ld", arg);
413 	return (0);
414 }
415 
416 static int
417 pdeculong(long arg)
418 {
419 	(void)printf("%lu", arg);
420 	return (0);
421 }
422 
423 static int
424 phexlong(long arg)
425 {
426 	(void)printf("%#lx", arg);
427 	return (0);
428 }
429 
430 static int
431 pnonfancy(long arg)
432 {
433 	if (decimal)
434 		(void)printf("%ld", arg);
435 	else
436 		(void)printf("%#lx", arg);
437 	return (0);
438 }
439 
440 static void
441 pdecint(int arg)
442 {
443 	(void)printf("%d", arg);
444 }
445 
446 static void
447 pdecuint(int arg)
448 {
449 	(void)printf("%u", arg);
450 }
451 
452 static void
453 phexint(int arg)
454 {
455 	(void)printf("%#x", arg);
456 }
457 
458 static void
459 poctint(int arg)
460 {
461 	(void)printf("%#o", arg);
462 }
463 
464 
465 #ifdef __LP64__
466 
467 /* on LP64, long long arguments are the same as long arguments */
468 #define Phexlonglong	Phexlong
469 #define phexll		NULL		/* not actually used on LP64 */
470 
471 #else /* __LP64__ */
472 
473 /* on ILP32, long long arguments are passed as two 32bit args */
474 #define Phexlonglong	PASS_LONGLONG, Phexll
475 
476 static int
477 phexll(long arg2)
478 {
479 	long long val;
480 
481 #if _BYTE_ORDER == _LITTLE_ENDIAN
482 	val = ((long long)arg2 << 32) | ((long long)arg1 & 0xffffffff);
483 #else
484 	val = ((long long)arg1 << 32) | ((long long)arg2 & 0xffffffff);
485 #endif
486 
487 	if (fancy || !decimal)
488 		(void)printf("%#llx", val);
489 	else
490 		(void)printf("%lld", val);
491 	return (0);
492 }
493 
494 #endif /* __LP64__ */
495 
496 static int (*long_formatters[])(long) = {
497 	NULL,
498 	pdeclong,
499 	pdeculong,
500 	phexlong,
501 	pass_two,
502 	pass_two,
503 	phexll,
504 	pad,
505 	pnonfancy,
506 };
507 
508 static void (*formatters[])(int) = {
509 	NULL,
510 	pdecint,
511 	phexint,
512 	poctint,
513 	pdecuint,
514 	ioctldecode,
515 	ptracedecode,
516 	atfd,
517 	polltimeout,
518 	wait4pid,
519 	signame,
520 	semctlname,
521 	shmctlname,
522 	semgetname,
523 	flagsandmodename,
524 	clockname,
525 	sockoptlevelname,
526 	ktraceopname,
527 	fcntlcmdname,
528 	modename,
529 	flagsname,
530 	openflagsname,
531 	atflagsname,
532 	accessmodename,
533 	mmapprotname,
534 	mmapflagsname,
535 	wait4optname,
536 	sendrecvflagsname,
537 	mountflagsname,
538 	rebootoptname,
539 	flockname,
540 	sockoptname,
541 	sockipprotoname,
542 	socktypename,
543 	sockflagsname,
544 	sockfamilyname,
545 	mlockallname,
546 	shmatname,
547 	whencename,
548 	pathconfname,
549 	rlimitname,
550 	shutdownhowname,
551 	prioname,
552 	madvisebehavname,
553 	msyncflagsname,
554 	clocktypename,
555 	rusagewho,
556 	sigactionflagname,
557 	sigprocmaskhowname,
558 	minheritname,
559 	quotactlname,
560 	sigill_name,
561 	sigtrap_name,
562 	sigemt_name,
563 	sigfpe_name,
564 	sigbus_name,
565 	sigsegv_name,
566 	sigchld_name,
567 	ktracefacname,
568 	itimername,
569 	sigset,
570 	uidname,
571 	gidname,
572 	syslogflagname,
573 	futexflagname,
574 };
575 
576 enum {
577 	/* the end of the (known) arguments is recognized by the zero fill */
578 	end_of_args	=  0,
579 
580 	/* negative are the negative of the index into long_formatters[] */
581 	Pdeclong	= -1,
582 	Pdeculong	= -2,
583 	Phexlong	= -3,
584 	PASS_TWO	= -4,
585 
586 /* the remaining long formatters still get called when non-fancy (-n option) */
587 #define FMT_IS_NONFANCY(x)	((x) <= PASS_LONGLONG)
588 	PASS_LONGLONG	= -5,
589 	Phexll		= -6,
590 	PAD		= -7,
591 	Pnonfancy	= -8,
592 
593 	/* positive values are the index into formatters[] */
594 	Pdecint		= 1,
595 	Phexint,
596 	Poctint,
597 	Pdecuint,
598 	Ioctldecode,
599 	Ptracedecode,
600 	Atfd,
601 	Polltimeout,
602 	Wait4pid,
603 	Signame,
604 	Semctlname,
605 	Shmctlname,
606 	Semgetname,
607 	Flagsandmodename,
608 	Clockname,
609 	Sockoptlevelname,
610 	Ktraceopname,
611 	Fcntlcmdname,
612 	Modename,
613 	Flagsname,
614 	Openflagsname,
615 	Atflagsname,
616 	Accessmodename,
617 	Mmapprotname,
618 	Mmapflagsname,
619 	Wait4optname,
620 	Sendrecvflagsname,
621 	Mountflagsname,
622 	Rebootoptname,
623 	Flockname,
624 	Sockoptname,
625 	Sockipprotoname,
626 	Socktypename,
627 	Sockflagsname,
628 	Sockfamilyname,
629 	Mlockallname,
630 	Shmatname,
631 	Whencename,
632 	Pathconfname,
633 	Rlimitname,
634 	Shutdownhowname,
635 	Prioname,
636 	Madvisebehavname,
637 	Msyncflagsname,
638 	Clocktypename,
639 	Rusagewho,
640 	Sigactionflagname,
641 	Sigprocmaskhowname,
642 	Minheritname,
643 	Quotactlname,
644 	Sigill_name,
645 	Sigtrap_name,
646 	Sigemt_name,
647 	Sigfpe_name,
648 	Sigbus_name,
649 	Sigsegv_name,
650 	Sigchld_name,
651 	Ktracefacname,
652 	Itimername,
653 	Sigset,
654 	Uidname,
655 	Gidname,
656 	Syslogflagname,
657 	Futexflagname,
658 };
659 
660 #define Pptr		Phexlong
661 #define	Psize		Pdeculong	/* size_t for small buffers */
662 #define	Pbigsize	Phexlong	/* size_t for I/O buffers */
663 #define Pcount		Pdecint		/* int for a count of something */
664 #define Pfd		Pdecint
665 #define Ppath		Phexlong
666 #define Pdev_t		Pdecint
667 #define Ppid_t		Pdecint
668 #define Ppgid		Pdecint		/* pid or negative pgid */
669 #define Poff_t		Phexlonglong
670 #define Pmsqid		Pdecint
671 #define Pshmid		Pdecint
672 #define Psemid		Pdecint
673 #define Pkey_t		Pdecint
674 #define Pucount		Pdecuint
675 #define Chflagsname	Phexlong	/* to be added */
676 #define Sockprotoname	Phexlong	/* to be added */
677 #define Swapctlname	Phexlong	/* to be added */
678 #define Msgflgname	Phexlong	/* to be added */
679 
680 
681 typedef signed char formatter;
682 static const formatter scargs[][8] = {
683     [SYS_exit]		= { Pdecint },
684     [SYS_read]		= { Pfd, Pptr, Pbigsize },
685     [SYS_write]		= { Pfd, Pptr, Pbigsize },
686     [SYS_open]		= { Ppath, PASS_TWO, Flagsandmodename },
687     [SYS_close]		= { Pfd },
688     [SYS_getentropy]	= { Pptr, Psize },
689     [SYS___tfork]	= { Pptr, Psize },
690     [SYS_link]		= { Ppath, Ppath },
691     [SYS_unlink]	= { Ppath },
692     [SYS_wait4]		= { Wait4pid, Pptr, Wait4optname },
693     [SYS_chdir]		= { Ppath },
694     [SYS_fchdir]	= { Pfd },
695     [SYS_mknod]		= { Ppath, Modename, Pdev_t },
696     [SYS_chmod]		= { Ppath, Modename },
697     [SYS_chown]		= { Ppath, Uidname, Gidname },
698     [SYS_break]		= { Pptr },
699     [SYS_getrusage]	= { Rusagewho, Pptr },
700     [SYS_mount]		= { Pptr, Ppath, Mountflagsname, Pptr },
701     [SYS_unmount]	= { Ppath, Mountflagsname },
702     [SYS_setuid]	= { Uidname },
703     [SYS_ptrace]	= { Ptracedecode, Ppid_t, Pptr, Pdecint },
704     [SYS_recvmsg]	= { Pfd, Pptr, Sendrecvflagsname },
705     [SYS_sendmsg]	= { Pfd, Pptr, Sendrecvflagsname },
706     [SYS_recvfrom]	= { Pfd, Pptr, Pbigsize, Sendrecvflagsname },
707     [SYS_accept]	= { Pfd, Pptr, Pptr },
708     [SYS_getpeername]	= { Pfd, Pptr, Pptr },
709     [SYS_getsockname]	= { Pfd, Pptr, Pptr },
710     [SYS_access]	= { Ppath, Accessmodename },
711     [SYS_chflags]	= { Ppath, Chflagsname },
712     [SYS_fchflags]	= { Pfd, Chflagsname },
713     [SYS_kill]		= { Ppgid, Signame },
714     [SYS_stat]		= { Ppath, Pptr },
715     [SYS_lstat]		= { Ppath, Pptr },
716     [SYS_dup]		= { Pfd },
717     [SYS_fstatat]	= { Atfd, Ppath, Pptr, Atflagsname },
718     [SYS_profil]	= { Pptr, Pbigsize, Pbigsize, Pdecuint },
719     [SYS_ktrace]	= { Ppath, Ktraceopname, Ktracefacname, Ppgid },
720     [SYS_sigaction]	= { Signame, Pptr, Pptr },
721     [SYS_sigprocmask]	= { Sigprocmaskhowname, Sigset },
722     [SYS_getlogin_r]	= { Pptr, Psize },
723     [SYS_setlogin]	= { Pptr },
724     [SYS_acct]		= { Ppath },
725     [SYS_fstat]		= { Pfd, Pptr },
726     [SYS_ioctl]		= { Pfd, Ioctldecode, Pptr },
727     [SYS_reboot]	= { Rebootoptname },
728     [SYS_revoke]	= { Ppath },
729     [SYS_symlink]	= { Ppath, Ppath },
730     [SYS_readlink]	= { Ppath, Pptr, Psize },
731     [SYS_execve]	= { Ppath, Pptr, Pptr },
732     [SYS_umask]		= { Modename },
733     [SYS_chroot]	= { Ppath },
734     [SYS_getfsstat]	= { Pptr, Pbigsize, Mountflagsname },
735     [SYS_statfs]	= { Ppath, Pptr },
736     [SYS_fstatfs]	= { Pfd, Pptr },
737     [SYS_fhstatfs]	= { Pptr, Pptr },
738     [SYS_gettimeofday]	= { Pptr, Pptr },
739     [SYS_settimeofday]	= { Pptr, Pptr },
740     [SYS_setitimer]	= { Itimername, Pptr, Pptr },
741     [SYS_getitimer]	= { Itimername, Pptr },
742     [SYS_select]	= { Pcount, Pptr, Pptr, Pptr, Pptr },
743     [SYS_kevent]	= { Pfd, Pptr, Pcount, Pptr, Pcount, Pptr },
744     [SYS_munmap]	= { Pptr, Pbigsize },
745     [SYS_mprotect]	= { Pptr, Pbigsize, Mmapprotname },
746     [SYS_madvise]	= { Pptr, Pbigsize, Madvisebehavname },
747     [SYS_utimes]	= { Ppath, Pptr },
748     [SYS_futimes]	= { Pfd, Pptr },
749     [SYS_kbind]		= { Pptr, Psize, Phexlonglong },
750     [SYS_getgroups]	= { Pcount, Pptr },
751     [SYS_setgroups]	= { Pcount, Pptr },
752     [SYS_setpgid]	= { Ppid_t, Ppid_t },
753     [SYS_futex]		= { Pptr, Futexflagname, Pcount, Pptr, Pptr },
754     [SYS_sendsyslog]	= { Pptr, Psize, Syslogflagname },
755     [SYS_utimensat]	= { Atfd, Ppath, Pptr, Atflagsname },
756     [SYS_futimens]	= { Pfd, Pptr },
757     [SYS_clock_gettime]	= { Clockname, Pptr },
758     [SYS_clock_settime]	= { Clockname, Pptr },
759     [SYS_clock_getres]	= { Clockname, Pptr },
760     [SYS_dup2]		= { Pfd, Pfd },
761     [SYS_nanosleep]	= { Pptr, Pptr },
762     [SYS_fcntl]		= { Pfd, PASS_TWO, Fcntlcmdname },
763     [SYS_accept4]	= { Pfd, Pptr, Pptr, Sockflagsname },
764     [SYS___thrsleep]	= { Pptr, Clockname, Pptr, Pptr, Pptr },
765     [SYS_fsync]		= { Pfd },
766     [SYS_setpriority]	= { Prioname, Ppid_t, Pdecint },
767     [SYS_socket]	= { Sockfamilyname, Socktypename, Sockprotoname },
768     [SYS_connect]	= { Pfd, Pptr, Pucount },
769     [SYS_getdents]	= { Pfd, Pptr, Pbigsize },
770     [SYS_getpriority]	= { Prioname, Ppid_t },
771     [SYS_pipe2]		= { Pptr, Flagsname },
772     [SYS_dup3]		= { Pfd, Pfd, Flagsname },
773     [SYS_sigreturn]	= { Pptr },
774     [SYS_bind]		= { Pfd, Pptr, Pucount },
775     [SYS_setsockopt]	= { Pfd, PASS_TWO, Sockoptlevelname, Pptr, Pdecint },
776     [SYS_listen]	= { Pfd, Pdecint },
777     [SYS_chflagsat]	= { Atfd, Ppath, Chflagsname, Atflagsname },
778     [SYS_ppoll]		= { Pptr, Pucount, Pptr, Pptr },
779     [SYS_pselect]	= { Pcount, Pptr, Pptr, Pptr, Pptr, Pptr },
780     [SYS_sigsuspend]	= { Sigset },
781     [SYS_getsockopt]	= { Pfd, PASS_TWO, Sockoptlevelname, Pptr, Pptr },
782     [SYS_thrkill]	= { Ppid_t, Signame, Pptr },
783     [SYS_readv]		= { Pfd, Pptr, Pcount },
784     [SYS_writev]	= { Pfd, Pptr, Pcount },
785     [SYS_fchown]	= { Pfd, Uidname, Gidname },
786     [SYS_fchmod]	= { Pfd, Modename },
787     [SYS_setreuid]	= { Uidname, Uidname },
788     [SYS_setregid]	= { Gidname, Gidname },
789     [SYS_rename]	= { Ppath, Ppath },
790     [SYS_flock]		= { Pfd, Flockname },
791     [SYS_mkfifo]	= { Ppath, Modename },
792     [SYS_sendto]	= { Pfd, Pptr, Pbigsize, Sendrecvflagsname },
793     [SYS_shutdown]	= { Pfd, Shutdownhowname },
794     [SYS_socketpair]	= { Sockfamilyname, Socktypename, Sockprotoname, Pptr },
795     [SYS_mkdir]		= { Ppath, Modename },
796     [SYS_rmdir]		= { Ppath },
797     [SYS_adjtime]	= { Pptr, Pptr },
798     [SYS_quotactl]	= { Ppath, Quotactlname, Uidname, Pptr },
799     [SYS_nfssvc]	= { Phexint, Pptr },
800     [SYS_getfh]		= { Ppath, Pptr },
801     [SYS_sysarch]	= { Pdecint, Pptr },
802     [SYS_pread]		= { Pfd, Pptr, Pbigsize, PAD, Poff_t },
803     [SYS_pwrite]	= { Pfd, Pptr, Pbigsize, PAD, Poff_t },
804     [SYS_setgid]	= { Gidname },
805     [SYS_setegid]	= { Gidname },
806     [SYS_seteuid]	= { Uidname },
807     [SYS_pathconf]	= { Ppath, Pathconfname },
808     [SYS_fpathconf]	= { Pfd, Pathconfname },
809     [SYS_swapctl]	= { Swapctlname, Pptr, Pdecint },
810     [SYS_getrlimit]	= { Rlimitname, Pptr },
811     [SYS_setrlimit]	= { Rlimitname, Pptr },
812     [SYS_mmap]		= { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, PAD, Poff_t },
813     [SYS_lseek]		= { Pfd, PAD, Poff_t, Whencename },
814     [SYS_truncate]	= { Ppath, PAD, Poff_t },
815     [SYS_ftruncate]	= { Pfd, PAD, Poff_t },
816     [SYS_sysctl]	= { Pptr, Pcount, Pptr, Pptr, Pptr, Psize },
817     [SYS_mlock]		= { Pptr, Pbigsize },
818     [SYS_munlock]	= { Pptr, Pbigsize },
819     [SYS_getpgid]	= { Ppid_t },
820     [SYS_utrace]	= { Pptr, Pptr, Psize },
821     [SYS_semget]	= { Pkey_t, Pcount, Semgetname },
822     [SYS_msgget]	= { Pkey_t, Msgflgname },
823     [SYS_msgsnd]	= { Pmsqid, Pptr, Psize, Msgflgname },
824     [SYS_msgrcv]	= { Pmsqid, Pptr, Psize, Pdeclong, Msgflgname },
825     [SYS_shmat]		= { Pshmid, Pptr, Shmatname },
826     [SYS_shmdt]		= { Pptr },
827     [SYS_minherit]	= { Pptr, Pbigsize, Minheritname },
828     [SYS_poll]		= { Pptr, Pucount, Polltimeout },
829     [SYS_lchown]	= { Ppath, Uidname, Gidname },
830     [SYS_getsid]	= { Ppid_t },
831     [SYS_msync]		= { Pptr, Pbigsize, Msyncflagsname },
832     [SYS_pipe]		= { Pptr },
833     [SYS_fhopen]	= { Pptr, Openflagsname },
834     [SYS_preadv]	= { Pfd, Pptr, Pcount, PAD, Poff_t },
835     [SYS_pwritev]	= { Pfd, Pptr, Pcount, PAD, Poff_t },
836     [SYS_mlockall]	= { Mlockallname },
837     [SYS_getresuid]	= { Pptr, Pptr, Pptr },
838     [SYS_setresuid]	= { Uidname, Uidname, Uidname },
839     [SYS_getresgid]	= { Pptr, Pptr, Pptr },
840     [SYS_setresgid]	= { Gidname, Gidname, Gidname },
841     [SYS_mquery]	= { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, PAD, Poff_t },
842     [SYS_closefrom]	= { Pfd },
843     [SYS_sigaltstack]	= { Pptr, Pptr },
844     [SYS_shmget]	= { Pkey_t, Pbigsize, Semgetname },
845     [SYS_semop]		= { Psemid, Pptr, Psize },
846     [SYS_fhstat]	= { Pptr, Pptr },
847     [SYS___semctl]	= { Psemid, Pcount, Semctlname, Pptr },
848     [SYS_shmctl]	= { Pshmid, Shmctlname, Pptr },
849     [SYS_msgctl]	= { Pmsqid, Shmctlname, Pptr },
850     [SYS___thrwakeup]	= { Pptr, Pcount },
851     [SYS___threxit]	= { Pptr },
852     [SYS___thrsigdivert] = { Sigset, Pptr, Pptr },
853     [SYS___getcwd]	= { Pptr, Psize },
854     [SYS_adjfreq]	= { Pptr, Pptr },
855     [SYS_setrtable]	= { Pdecint },
856     [SYS_faccessat]	= { Atfd, Ppath, Accessmodename, Atflagsname },
857     [SYS_fchmodat]	= { Atfd, Ppath, Modename, Atflagsname },
858     [SYS_fchownat]	= { Atfd, Ppath, Uidname, Gidname, Atflagsname },
859     [SYS_linkat]	= { Atfd, Ppath, Atfd, Ppath, Atflagsname },
860     [SYS_mkdirat]	= { Atfd, Ppath, Modename },
861     [SYS_mkfifoat]	= { Atfd, Ppath, Modename },
862     [SYS_mknodat]	= { Atfd, Ppath, Modename, Pdev_t },
863     [SYS_openat]	= { Atfd, Ppath, PASS_TWO, Flagsandmodename },
864     [SYS_readlinkat]	= { Atfd, Ppath, Pptr, Psize },
865     [SYS_renameat]	= { Atfd, Ppath, Atfd, Ppath },
866     [SYS_symlinkat]	= { Ppath, Atfd, Ppath },
867     [SYS_unlinkat]	= { Atfd, Ppath, Atflagsname },
868     [SYS___set_tcb]	= { Pptr },
869 };
870 
871 
872 static void
873 ktrsyscall(struct ktr_syscall *ktr, size_t ktrlen)
874 {
875 	register_t *ap;
876 	int narg;
877 	char sep;
878 
879 	if (ktr->ktr_argsize > ktrlen)
880 		errx(1, "syscall argument length %d > ktr header length %zu",
881 		    ktr->ktr_argsize, ktrlen);
882 
883 	narg = ktr->ktr_argsize / sizeof(register_t);
884 	sep = '\0';
885 
886 	if (ktr->ktr_code >= SYS_MAXSYSCALL || ktr->ktr_code < 0)
887 		(void)printf("[%d]", ktr->ktr_code);
888 	else
889 		(void)printf("%s", syscallnames[ktr->ktr_code]);
890 	ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
891 	(void)putchar('(');
892 
893 	if (ktr->ktr_code == SYS_sysctl && fancy) {
894 		const char *s;
895 		int n, i, *top;
896 
897 		n = ap[1];
898 		if (n > CTL_MAXNAME)
899 			n = CTL_MAXNAME;
900 		if (n < 0)
901 			errx(1, "invalid sysctl length %d", n);
902 		if (n > 0) {
903 			top = (int *)(ap + 6);
904 			printf("%d", top[0]);
905 			for (i = 1; i < n; i++)
906 				printf(".%d", top[i]);
907 			if ((s = kresolvsysctl(0, top)) != NULL) {
908 				printf("<%s", s);
909 				for (i = 1; i < n; i++) {
910 					if ((s = kresolvsysctl(i, top)) != NULL)
911 						printf(".%s", s);
912 					else
913 						printf(".%d", top[i]);
914 				}
915 				putchar('>');
916 			}
917 		}
918 
919 		sep = ',';
920 		ap += 2;
921 		narg -= 2;
922 	} else if (ktr->ktr_code < nitems(scargs)) {
923 		const formatter *fmts = scargs[ktr->ktr_code];
924 		int fmt;
925 
926 		while (narg && (fmt = *fmts) != 0) {
927 			if (sep)
928 				putchar(sep);
929 			sep = ',';
930 			if (!fancy && !FMT_IS_NONFANCY(fmt))
931 				fmt = Pnonfancy;
932 			if (fmt > 0)
933 				formatters[fmt]((int)*ap);
934 			else if (long_formatters[-fmt](*ap))
935 				sep = '\0';
936 			fmts++;
937 			ap++;
938 			narg--;
939 		}
940 	}
941 
942 	while (narg > 0) {
943 		if (sep)
944 			putchar(sep);
945 		if (decimal)
946 			(void)printf("%ld", (long)*ap);
947 		else
948 			(void)printf("%#lx", (long)*ap);
949 		sep = ',';
950 		ap++;
951 		narg--;
952 	}
953 	(void)printf(")\n");
954 }
955 
956 static struct ctlname topname[] = CTL_NAMES;
957 static struct ctlname kernname[] = CTL_KERN_NAMES;
958 static struct ctlname vmname[] = CTL_VM_NAMES;
959 static struct ctlname fsname[] = CTL_FS_NAMES;
960 static struct ctlname netname[] = CTL_NET_NAMES;
961 static struct ctlname hwname[] = CTL_HW_NAMES;
962 static struct ctlname debugname[CTL_DEBUG_MAXID];
963 static struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES;
964 static struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES;
965 static struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES;
966 static struct ctlname kernprocname[] = {
967 	{ NULL },
968 	{ "all" },
969 	{ "pid" },
970 	{ "pgrp" },
971 	{ "session" },
972 	{ "tty" },
973 	{ "uid" },
974 	{ "ruid" },
975 	{ "kthread" },
976 };
977 static struct ctlname ttysname[] = CTL_KERN_TTY_NAMES;
978 static struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES;
979 static struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES;
980 static struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES;
981 static struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES;
982 #ifdef CTL_MACHDEP_NAMES
983 static struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
984 #endif
985 static struct ctlname ddbname[] = CTL_DDB_NAMES;
986 
987 #ifndef nitems
988 #define nitems(_a)    (sizeof((_a)) / sizeof((_a)[0]))
989 #endif
990 
991 #define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)
992 
993 static const char *
994 kresolvsysctl(int depth, const int *top)
995 {
996 	struct ctlname *names;
997 	size_t		limit;
998 	int		idx = top[depth];
999 
1000 	names = NULL;
1001 
1002 	switch (depth) {
1003 	case 0:
1004 		SETNAME(topname);
1005 		break;
1006 	case 1:
1007 		switch (top[0]) {
1008 		case CTL_KERN:
1009 			SETNAME(kernname);
1010 			break;
1011 		case CTL_VM:
1012 			SETNAME(vmname);
1013 			break;
1014 		case CTL_FS:
1015 			SETNAME(fsname);
1016 			break;
1017 		case CTL_NET:
1018 			SETNAME(netname);
1019 			break;
1020 		case CTL_DEBUG:
1021 			SETNAME(debugname);
1022 			break;
1023 		case CTL_HW:
1024 			SETNAME(hwname);
1025 			break;
1026 #ifdef CTL_MACHDEP_NAMES
1027 		case CTL_MACHDEP:
1028 			SETNAME(machdepname);
1029 			break;
1030 #endif
1031 		case CTL_DDB:
1032 			SETNAME(ddbname);
1033 			break;
1034 		}
1035 		break;
1036 	case 2:
1037 		switch (top[0]) {
1038 		case CTL_KERN:
1039 			switch (top[1]) {
1040 			case KERN_MALLOCSTATS:
1041 				SETNAME(kernmallocname);
1042 				break;
1043 			case KERN_FORKSTAT:
1044 				SETNAME(forkstatname);
1045 				break;
1046 			case KERN_NCHSTATS:
1047 				SETNAME(nchstatsname);
1048 				break;
1049 			case KERN_TTY:
1050 				SETNAME(ttysname);
1051 				break;
1052 			case KERN_SEMINFO:
1053 				SETNAME(semname);
1054 				break;
1055 			case KERN_SHMINFO:
1056 				SETNAME(shmname);
1057 				break;
1058 			case KERN_WATCHDOG:
1059 				SETNAME(watchdogname);
1060 				break;
1061 			case KERN_PROC:
1062 				idx++;	/* zero is valid at this level */
1063 				SETNAME(kernprocname);
1064 				break;
1065 			case KERN_TIMECOUNTER:
1066 				SETNAME(tcname);
1067 				break;
1068 			}
1069 		}
1070 		break;
1071 	}
1072 	if (names != NULL && idx > 0 && idx < limit)
1073 		return (names[idx].ctl_name);
1074 	return (NULL);
1075 }
1076 
1077 static void
1078 ktrsysret(struct ktr_sysret *ktr, size_t ktrlen)
1079 {
1080 	register_t ret = 0;
1081 	long long retll;
1082 	int error = ktr->ktr_error;
1083 	int code = ktr->ktr_code;
1084 
1085 	if (ktrlen < sizeof(*ktr))
1086 		errx(1, "sysret length %zu < ktr header length %zu",
1087 		    ktrlen, sizeof(*ktr));
1088 	ktrlen -= sizeof(*ktr);
1089 	if (error == 0) {
1090 		if (ktrlen == sizeof(ret)) {
1091 			memcpy(&ret, ktr+1, sizeof(ret));
1092 			retll = ret;
1093 		} else if (ktrlen == sizeof(retll))
1094 			memcpy(&retll, ktr+1, sizeof(retll));
1095 		else
1096 			errx(1, "sysret bogus length %zu", ktrlen);
1097 	}
1098 
1099 	if (code >= SYS_MAXSYSCALL || code < 0)
1100 		(void)printf("[%d] ", code);
1101 	else
1102 		(void)printf("%s ", syscallnames[code]);
1103 
1104 doerr:
1105 	if (error == 0) {
1106 		if (fancy) {
1107 			switch (code) {
1108 			case SYS_lseek:
1109 				(void)printf("%lld", retll);
1110 				if (retll < 0 || retll > 9)
1111 					(void)printf("/%#llx", retll);
1112 				break;
1113 			case SYS_sigprocmask:
1114 			case SYS_sigpending:
1115 				sigset(ret);
1116 				break;
1117 			case SYS___thrsigdivert:
1118 				signame(ret);
1119 				break;
1120 			case SYS_getuid:
1121 			case SYS_geteuid:
1122 				uidname(ret);
1123 				break;
1124 			case SYS_getgid:
1125 			case SYS_getegid:
1126 				gidname(ret);
1127 				break;
1128 			/* syscalls that return errno values */
1129 			case SYS_getlogin_r:
1130 			case SYS___thrsleep:
1131 				if ((error = ret) != 0)
1132 					goto doerr;
1133 				/* FALLTHROUGH */
1134 			default:
1135 				(void)printf("%ld", (long)ret);
1136 				if (ret < 0 || ret > 9)
1137 					(void)printf("/%#lx", (long)ret);
1138 			}
1139 		} else {
1140 			if (decimal)
1141 				(void)printf("%lld", retll);
1142 			else
1143 				(void)printf("%#llx", retll);
1144 		}
1145 	} else if (error == ERESTART)
1146 		(void)printf("RESTART");
1147 	else if (error == EJUSTRETURN)
1148 		(void)printf("JUSTRETURN");
1149 	else {
1150 		(void)printf("-1 errno %d", error);
1151 		if (fancy)
1152 			(void)printf(" %s", strerror(error));
1153 	}
1154 	(void)putchar('\n');
1155 }
1156 
1157 static void
1158 ktrnamei(const char *cp, size_t len)
1159 {
1160 	showbufc(basecol, (unsigned char *)cp, len, VIS_DQ | VIS_TAB | VIS_NL);
1161 }
1162 
1163 void
1164 showbufc(int col, unsigned char *dp, size_t datalen, int flags)
1165 {
1166 	int width;
1167 	unsigned char visbuf[5], *cp;
1168 
1169 	flags |= VIS_CSTYLE;
1170 	putchar('"');
1171 	col++;
1172 	for (; datalen > 0; datalen--, dp++) {
1173 		(void)vis(visbuf, *dp, flags, *(dp+1));
1174 		cp = visbuf;
1175 
1176 		/*
1177 		 * Keep track of printables and
1178 		 * space chars (like fold(1)).
1179 		 */
1180 		if (col == 0) {
1181 			(void)putchar('\t');
1182 			col = 8;
1183 		}
1184 		switch (*cp) {
1185 		case '\n':
1186 			col = 0;
1187 			(void)putchar('\n');
1188 			continue;
1189 		case '\t':
1190 			width = 8 - (col&07);
1191 			break;
1192 		default:
1193 			width = strlen(cp);
1194 		}
1195 		if (col + width > (screenwidth-2)) {
1196 			(void)printf("\\\n\t");
1197 			col = 8;
1198 		}
1199 		col += width;
1200 		do {
1201 			(void)putchar(*cp++);
1202 		} while (*cp);
1203 	}
1204 	if (col == 0)
1205 		(void)printf("       ");
1206 	(void)printf("\"\n");
1207 }
1208 
1209 static void
1210 showbuf(unsigned char *dp, size_t datalen)
1211 {
1212 	int i, j;
1213 	int col = 0, bpl;
1214 	unsigned char c;
1215 
1216 	if (iohex == 1) {
1217 		putchar('\t');
1218 		col = 8;
1219 		for (i = 0; i < datalen; i++) {
1220 			printf("%02x", dp[i]);
1221 			col += 3;
1222 			if (i < datalen - 1) {
1223 				if (col + 3 > screenwidth) {
1224 					printf("\n\t");
1225 					col = 8;
1226 				} else
1227 					putchar(' ');
1228 			}
1229 		}
1230 		putchar('\n');
1231 		return;
1232 	}
1233 	if (iohex == 2) {
1234 		bpl = (screenwidth - 13)/4;
1235 		if (bpl <= 0)
1236 			bpl = 1;
1237 		for (i = 0; i < datalen; i += bpl) {
1238 			printf("   %04x:  ", i);
1239 			for (j = 0; j < bpl; j++) {
1240 				if (i+j >= datalen)
1241 					printf("   ");
1242 				else
1243 					printf("%02x ", dp[i+j]);
1244 			}
1245 			putchar(' ');
1246 			for (j = 0; j < bpl; j++) {
1247 				if (i+j >= datalen)
1248 					break;
1249 				c = dp[i+j];
1250 				if (!isprint(c))
1251 					c = '.';
1252 				putchar(c);
1253 			}
1254 			putchar('\n');
1255 		}
1256 		return;
1257 	}
1258 
1259 	(void)printf("       ");
1260 	showbufc(7, dp, datalen, 0);
1261 }
1262 
1263 static void
1264 ktrgenio(struct ktr_genio *ktr, size_t len)
1265 {
1266 	unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
1267 	size_t datalen;
1268 
1269 	if (len < sizeof(struct ktr_genio))
1270 		errx(1, "invalid ktr genio length %zu", len);
1271 
1272 	datalen = len - sizeof(struct ktr_genio);
1273 
1274 	printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1275 		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
1276 	if (maxdata == 0)
1277 		return;
1278 	if (datalen > maxdata)
1279 		datalen = maxdata;
1280 	if (iohex && !datalen)
1281 		return;
1282 	showbuf(dp, datalen);
1283 }
1284 
1285 static void
1286 ktrpsig(struct ktr_psig *psig)
1287 {
1288 	signame(psig->signo);
1289 	printf(" ");
1290 	if (psig->action == SIG_DFL)
1291 		(void)printf("SIG_DFL");
1292 	else {
1293 		(void)printf("caught handler=0x%lx mask=",
1294 		    (u_long)psig->action);
1295 		sigset(psig->mask);
1296 	}
1297 	if (psig->code) {
1298 		printf(" code ");
1299 		if (fancy) {
1300 			switch (psig->signo) {
1301 			case SIGILL:
1302 				sigill_name(psig->code);
1303 				break;
1304 			case SIGTRAP:
1305 				sigtrap_name(psig->code);
1306 				break;
1307 			case SIGEMT:
1308 				sigemt_name(psig->code);
1309 				break;
1310 			case SIGFPE:
1311 				sigfpe_name(psig->code);
1312 				break;
1313 			case SIGBUS:
1314 				sigbus_name(psig->code);
1315 				break;
1316 			case SIGSEGV:
1317 				sigsegv_name(psig->code);
1318 				break;
1319 			case SIGCHLD:
1320 				sigchld_name(psig->code);
1321 				break;
1322 			}
1323 		}
1324 		printf("<%d>", psig->code);
1325 	}
1326 
1327 	switch (psig->signo) {
1328 	case SIGSEGV:
1329 	case SIGILL:
1330 	case SIGBUS:
1331 	case SIGFPE:
1332 		printf(" addr=%p trapno=%d", psig->si.si_addr,
1333 		    psig->si.si_trapno);
1334 		break;
1335 	default:
1336 		break;
1337 	}
1338 	printf("\n");
1339 }
1340 
1341 static void
1342 ktruser(struct ktr_user *usr, size_t len)
1343 {
1344 	if (len < sizeof(struct ktr_user))
1345 		errx(1, "invalid ktr user length %zu", len);
1346 	len -= sizeof(struct ktr_user);
1347 	printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id);
1348 	printf(" %zu bytes\n", len);
1349 	showbuf((unsigned char *)(usr + 1), len);
1350 }
1351 
1352 static void
1353 ktrexec(const char *ptr, size_t len)
1354 {
1355 	int i, col;
1356 	size_t l;
1357 
1358 	putchar('\n');
1359 	i = 0;
1360 	while (len > 0) {
1361 		l = strnlen(ptr, len);
1362 		col = printf("\t[%d] = ", i++);
1363 		col += 7;	/* tab expands from 1 to 8 columns */
1364 		showbufc(col, (unsigned char *)ptr, l, VIS_DQ|VIS_TAB|VIS_NL);
1365 		if (l == len) {
1366 			printf("\tunterminated argument\n");
1367 			break;
1368 		}
1369 		len -= l + 1;
1370 		ptr += l + 1;
1371 	}
1372 }
1373 
1374 static void
1375 ktrpledge(struct ktr_pledge *pledge, size_t len)
1376 {
1377 	const char *name = "";
1378 	int i;
1379 
1380 	if (len < sizeof(struct ktr_pledge))
1381 		errx(1, "invalid ktr pledge length %zu", len);
1382 
1383 	if (pledge->syscall >= SYS_MAXSYSCALL || pledge->syscall < 0)
1384 		(void)printf("[%d]", pledge->syscall);
1385 	else
1386 		(void)printf("%s", syscallnames[pledge->syscall]);
1387 	printf(", ");
1388 	for (i = 0; pledge->code && pledgenames[i].bits != 0; i++) {
1389 		if (pledgenames[i].bits & pledge->code) {
1390 			name = pledgenames[i].name;
1391 			break;
1392 		}
1393 	}
1394 	printf("\"%s\"", name);
1395 	(void)printf(", errno %d", pledge->error);
1396 	if (fancy)
1397 		(void)printf(" %s", strerror(pledge->error));
1398 	printf("\n");
1399 }
1400 
1401 static void
1402 usage(void)
1403 {
1404 
1405 	extern char *__progname;
1406 	fprintf(stderr, "usage: %s "
1407 	    "[-dHlnRTXx] [-f file] [-m maxdata] [-p pid] [-t trstr]\n",
1408 	    __progname);
1409 	exit(1);
1410 }
1411 
1412 
1413 /*
1414  * FORMATTERS
1415  */
1416 
1417 static void
1418 ioctldecode(int cmd)
1419 {
1420 	char dirbuf[4], *dir = dirbuf;
1421 	const char *cp;
1422 
1423 	if ((cp = ioctlname((unsigned)cmd)) != NULL) {
1424 		(void)printf("%s", cp);
1425 		return;
1426 	}
1427 
1428 	if (cmd & IOC_IN)
1429 		*dir++ = 'W';
1430 	if (cmd & IOC_OUT)
1431 		*dir++ = 'R';
1432 	*dir = '\0';
1433 
1434 	printf("_IO%s('%c',%d",
1435 	    dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1436 	if ((cmd & IOC_VOID) == 0)
1437 		printf(decimal ? ",%u)" : ",%#x)", (cmd >> 16) & 0xff);
1438 	else
1439 		printf(")");
1440 }
1441 
1442 static void
1443 ptracedecode(int request)
1444 {
1445 	if (request >= 0 && request < nitems(ptrace_ops))
1446 		(void)printf("%s", ptrace_ops[request]);
1447 	else switch(request) {
1448 #ifdef PT_GETFPREGS
1449 	case PT_GETFPREGS:
1450 		(void)printf("PT_GETFPREGS");
1451 		break;
1452 #endif
1453 	case PT_GETREGS:
1454 		(void)printf("PT_GETREGS");
1455 		break;
1456 #ifdef PT_GETXMMREGS
1457 	case PT_GETXMMREGS:
1458 		(void)printf("PT_GETXMMREGS");
1459 		break;
1460 #endif
1461 #ifdef PT_SETFPREGS
1462 	case PT_SETFPREGS:
1463 		(void)printf("PT_SETFPREGS");
1464 		break;
1465 #endif
1466 	case PT_SETREGS:
1467 		(void)printf("PT_SETREGS");
1468 		break;
1469 #ifdef PT_SETXMMREGS
1470 	case PT_SETXMMREGS:
1471 		(void)printf("PT_SETXMMREGS");
1472 		break;
1473 #endif
1474 #ifdef PT_STEP
1475 	case PT_STEP:
1476 		(void)printf("PT_STEP");
1477 		break;
1478 #endif
1479 #ifdef PT_WCOOKIE
1480 	case PT_WCOOKIE:
1481 		(void)printf("PT_WCOOKIE");
1482 		break;
1483 #endif
1484 	default:
1485 		pdecint(request);
1486 	}
1487 }
1488 
1489 
1490 static void
1491 atfd(int fd)
1492 {
1493 	if (fd == AT_FDCWD)
1494 		(void)printf("AT_FDCWD");
1495 	else
1496 		pdecint(fd);
1497 }
1498 
1499 static void
1500 polltimeout(int timeout)
1501 {
1502 	if (timeout == INFTIM)
1503 		(void)printf("INFTIM");
1504 	else
1505 		pdecint(timeout);
1506 }
1507 
1508 static void
1509 wait4pid(int pid)
1510 {
1511 	if (pid == WAIT_ANY)
1512 		(void)printf("WAIT_ANY");
1513 	else if (pid == WAIT_MYPGRP)
1514 		(void)printf("WAIT_MYPGRP");
1515 	else
1516 		pdecint(pid);		/* ppgid */
1517 }
1518 
1519 static void
1520 signame(int sig)
1521 {
1522 	if (sig > 0 && sig < NSIG)
1523 		(void)printf("SIG%s", sys_signame[sig]);
1524 	else
1525 		(void)printf("SIG %d", sig);
1526 }
1527 
1528 void
1529 sigset(int ss)
1530 {
1531 	int	or = 0;
1532 	int	cnt = 0;
1533 	int	i;
1534 
1535 	for (i = 1; i < NSIG; i++)
1536 		if (sigismember(&ss, i))
1537 			cnt++;
1538 	if (cnt > (NSIG-1)/2) {
1539 		ss = ~ss;
1540 		putchar('~');
1541 	}
1542 
1543 	if (ss == 0) {
1544 		(void)printf("0<>");
1545 		return;
1546 	}
1547 
1548 	printf("%#x<", ss);
1549 	for (i = 1; i < NSIG; i++)
1550 		if (sigismember(&ss, i)) {
1551 			if (or) putchar('|'); else or=1;
1552 			signame(i);
1553 		}
1554 	printf(">");
1555 }
1556 
1557 static void
1558 semctlname(int cmd)
1559 {
1560 	switch (cmd) {
1561 	case GETNCNT:
1562 		(void)printf("GETNCNT");
1563 		break;
1564 	case GETPID:
1565 		(void)printf("GETPID");
1566 		break;
1567 	case GETVAL:
1568 		(void)printf("GETVAL");
1569 		break;
1570 	case GETALL:
1571 		(void)printf("GETALL");
1572 		break;
1573 	case GETZCNT:
1574 		(void)printf("GETZCNT");
1575 		break;
1576 	case SETVAL:
1577 		(void)printf("SETVAL");
1578 		break;
1579 	case SETALL:
1580 		(void)printf("SETALL");
1581 		break;
1582 	case IPC_RMID:
1583 		(void)printf("IPC_RMID");
1584 		break;
1585 	case IPC_SET:
1586 		(void)printf("IPC_SET");
1587 		break;
1588 	case IPC_STAT:
1589 		(void)printf("IPC_STAT");
1590 		break;
1591 	default: /* Should not reach */
1592 		(void)printf("<invalid=%d>", cmd);
1593 	}
1594 }
1595 
1596 static void
1597 shmctlname(int cmd)
1598 {
1599 	switch (cmd) {
1600 	case IPC_RMID:
1601 		(void)printf("IPC_RMID");
1602 		break;
1603 	case IPC_SET:
1604 		(void)printf("IPC_SET");
1605 		break;
1606 	case IPC_STAT:
1607 		(void)printf("IPC_STAT");
1608 		break;
1609 	default: /* Should not reach */
1610 		(void)printf("<invalid=%d>", cmd);
1611 	}
1612 }
1613 
1614 
1615 static void
1616 semgetname(int flag)
1617 {
1618 	int	or = 0;
1619 	if_print_or(flag, IPC_CREAT, or);
1620 	if_print_or(flag, IPC_EXCL, or);
1621 	if_print_or(flag, SEM_R, or);
1622 	if_print_or(flag, SEM_A, or);
1623 	if_print_or(flag, (SEM_R>>3), or);
1624 	if_print_or(flag, (SEM_A>>3), or);
1625 	if_print_or(flag, (SEM_R>>6), or);
1626 	if_print_or(flag, (SEM_A>>6), or);
1627 
1628 	if (flag & ~(IPC_CREAT|IPC_EXCL|SEM_R|SEM_A|((SEM_R|SEM_A)>>3)|
1629 	    ((SEM_R|SEM_A)>>6)))
1630 		printf("<invalid=%#x>", flag);
1631 }
1632 
1633 
1634 /*
1635  * Only used by SYS_open and SYS_openat. Unless O_CREAT is set in flags, the
1636  * mode argument is unused (and often bogus and misleading).
1637  */
1638 static void
1639 flagsandmodename(int mode)
1640 {
1641 	openflagsname(arg1);
1642 	if ((arg1 & O_CREAT) == O_CREAT) {
1643 		(void)putchar(',');
1644 		modename(mode);
1645 	} else if (!fancy)
1646 		(void)printf(",<unused>%#o", mode);
1647 }
1648 
1649 static void
1650 clockname(int clockid)
1651 {
1652 	clocktypename(__CLOCK_TYPE(clockid));
1653 	if (__CLOCK_PTID(clockid) != 0)
1654 		printf("(%d)", __CLOCK_PTID(clockid));
1655 }
1656 
1657 /*
1658  * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value
1659  * referring to a line in /etc/protocols.
1660  */
1661 static void
1662 sockoptlevelname(int optname)
1663 {
1664 	struct protoent *pe;
1665 
1666 	if (arg1 == SOL_SOCKET) {
1667 		(void)printf("SOL_SOCKET,");
1668 		sockoptname(optname);
1669 	} else {
1670 		pe = getprotobynumber(arg1);
1671 		(void)printf("%u<%s>,%d", arg1,
1672 		    pe != NULL ? pe->p_name : "unknown", optname);
1673 	}
1674 }
1675 
1676 static void
1677 ktraceopname(int ops)
1678 {
1679 	int invalid = 0;
1680 
1681 	printf("%#x<", ops);
1682 	switch (KTROP(ops)) {
1683 	case KTROP_SET:
1684 		printf("KTROP_SET");
1685 		break;
1686 	case KTROP_CLEAR:
1687 		printf("KTROP_CLEAR");
1688 		break;
1689 	case KTROP_CLEARFILE:
1690 		printf("KTROP_CLEARFILE");
1691 		break;
1692 	default:
1693 		printf("KTROP(%d)", KTROP(ops));
1694 		invalid = 1;
1695 		break;
1696 	}
1697 	if (ops & KTRFLAG_DESCEND) printf("|KTRFLAG_DESCEND");
1698 	printf(">");
1699 	if (invalid || (ops & ~(KTROP((unsigned)-1) | KTRFLAG_DESCEND)))
1700 		(void)printf("<invalid>%d", ops);
1701 }
1702