xref: /openbsd-src/usr.bin/kdump/kdump.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*	$OpenBSD: kdump.c,v 1.141 2020/01/18 23:56:31 cheloha 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");
227 	if (unveil(_PATH_PROTOCOLS, "r") == -1)
228 		err(1, "unveil");
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 			case SYS_futex:
1132 				if ((error = ret) != 0)
1133 					goto doerr;
1134 				/* FALLTHROUGH */
1135 			default:
1136 				(void)printf("%ld", (long)ret);
1137 				if (ret < 0 || ret > 9)
1138 					(void)printf("/%#lx", (long)ret);
1139 			}
1140 		} else {
1141 			if (decimal)
1142 				(void)printf("%lld", retll);
1143 			else
1144 				(void)printf("%#llx", retll);
1145 		}
1146 	} else if (error == ERESTART)
1147 		(void)printf("RESTART");
1148 	else if (error == EJUSTRETURN)
1149 		(void)printf("JUSTRETURN");
1150 	else {
1151 		(void)printf("-1 errno %d", error);
1152 		if (fancy)
1153 			(void)printf(" %s", strerror(error));
1154 	}
1155 	(void)putchar('\n');
1156 }
1157 
1158 static void
1159 ktrnamei(const char *cp, size_t len)
1160 {
1161 	showbufc(basecol, (unsigned char *)cp, len, VIS_DQ | VIS_TAB | VIS_NL);
1162 }
1163 
1164 void
1165 showbufc(int col, unsigned char *dp, size_t datalen, int flags)
1166 {
1167 	int width;
1168 	unsigned char visbuf[5], *cp;
1169 
1170 	flags |= VIS_CSTYLE;
1171 	putchar('"');
1172 	col++;
1173 	for (; datalen > 0; datalen--, dp++) {
1174 		(void)vis(visbuf, *dp, flags, *(dp+1));
1175 		cp = visbuf;
1176 
1177 		/*
1178 		 * Keep track of printables and
1179 		 * space chars (like fold(1)).
1180 		 */
1181 		if (col == 0) {
1182 			(void)putchar('\t');
1183 			col = 8;
1184 		}
1185 		switch (*cp) {
1186 		case '\n':
1187 			col = 0;
1188 			(void)putchar('\n');
1189 			continue;
1190 		case '\t':
1191 			width = 8 - (col&07);
1192 			break;
1193 		default:
1194 			width = strlen(cp);
1195 		}
1196 		if (col + width > (screenwidth-2)) {
1197 			(void)printf("\\\n\t");
1198 			col = 8;
1199 		}
1200 		col += width;
1201 		do {
1202 			(void)putchar(*cp++);
1203 		} while (*cp);
1204 	}
1205 	if (col == 0)
1206 		(void)printf("       ");
1207 	(void)printf("\"\n");
1208 }
1209 
1210 static void
1211 showbuf(unsigned char *dp, size_t datalen)
1212 {
1213 	int i, j;
1214 	int col = 0, bpl;
1215 	unsigned char c;
1216 
1217 	if (iohex == 1) {
1218 		putchar('\t');
1219 		col = 8;
1220 		for (i = 0; i < datalen; i++) {
1221 			printf("%02x", dp[i]);
1222 			col += 3;
1223 			if (i < datalen - 1) {
1224 				if (col + 3 > screenwidth) {
1225 					printf("\n\t");
1226 					col = 8;
1227 				} else
1228 					putchar(' ');
1229 			}
1230 		}
1231 		putchar('\n');
1232 		return;
1233 	}
1234 	if (iohex == 2) {
1235 		bpl = (screenwidth - 13)/4;
1236 		if (bpl <= 0)
1237 			bpl = 1;
1238 		for (i = 0; i < datalen; i += bpl) {
1239 			printf("   %04x:  ", i);
1240 			for (j = 0; j < bpl; j++) {
1241 				if (i+j >= datalen)
1242 					printf("   ");
1243 				else
1244 					printf("%02x ", dp[i+j]);
1245 			}
1246 			putchar(' ');
1247 			for (j = 0; j < bpl; j++) {
1248 				if (i+j >= datalen)
1249 					break;
1250 				c = dp[i+j];
1251 				if (!isprint(c))
1252 					c = '.';
1253 				putchar(c);
1254 			}
1255 			putchar('\n');
1256 		}
1257 		return;
1258 	}
1259 
1260 	(void)printf("       ");
1261 	showbufc(7, dp, datalen, 0);
1262 }
1263 
1264 static void
1265 ktrgenio(struct ktr_genio *ktr, size_t len)
1266 {
1267 	unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
1268 	size_t datalen;
1269 
1270 	if (len < sizeof(struct ktr_genio))
1271 		errx(1, "invalid ktr genio length %zu", len);
1272 
1273 	datalen = len - sizeof(struct ktr_genio);
1274 
1275 	printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1276 		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
1277 	if (maxdata == 0)
1278 		return;
1279 	if (datalen > maxdata)
1280 		datalen = maxdata;
1281 	if (iohex && !datalen)
1282 		return;
1283 	showbuf(dp, datalen);
1284 }
1285 
1286 static void
1287 ktrpsig(struct ktr_psig *psig)
1288 {
1289 	signame(psig->signo);
1290 	printf(" ");
1291 	if (psig->action == SIG_DFL)
1292 		(void)printf("SIG_DFL");
1293 	else {
1294 		(void)printf("caught handler=0x%lx mask=",
1295 		    (u_long)psig->action);
1296 		sigset(psig->mask);
1297 	}
1298 	if (psig->code) {
1299 		printf(" code ");
1300 		if (fancy) {
1301 			switch (psig->signo) {
1302 			case SIGILL:
1303 				sigill_name(psig->code);
1304 				break;
1305 			case SIGTRAP:
1306 				sigtrap_name(psig->code);
1307 				break;
1308 			case SIGEMT:
1309 				sigemt_name(psig->code);
1310 				break;
1311 			case SIGFPE:
1312 				sigfpe_name(psig->code);
1313 				break;
1314 			case SIGBUS:
1315 				sigbus_name(psig->code);
1316 				break;
1317 			case SIGSEGV:
1318 				sigsegv_name(psig->code);
1319 				break;
1320 			case SIGCHLD:
1321 				sigchld_name(psig->code);
1322 				break;
1323 			}
1324 		}
1325 		printf("<%d>", psig->code);
1326 	}
1327 
1328 	switch (psig->signo) {
1329 	case SIGSEGV:
1330 	case SIGILL:
1331 	case SIGBUS:
1332 	case SIGFPE:
1333 		printf(" addr=%p trapno=%d", psig->si.si_addr,
1334 		    psig->si.si_trapno);
1335 		break;
1336 	default:
1337 		break;
1338 	}
1339 	printf("\n");
1340 }
1341 
1342 static void
1343 ktruser(struct ktr_user *usr, size_t len)
1344 {
1345 	if (len < sizeof(struct ktr_user))
1346 		errx(1, "invalid ktr user length %zu", len);
1347 	len -= sizeof(struct ktr_user);
1348 	printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id);
1349 	printf(" %zu bytes\n", len);
1350 	showbuf((unsigned char *)(usr + 1), len);
1351 }
1352 
1353 static void
1354 ktrexec(const char *ptr, size_t len)
1355 {
1356 	int i, col;
1357 	size_t l;
1358 
1359 	putchar('\n');
1360 	i = 0;
1361 	while (len > 0) {
1362 		l = strnlen(ptr, len);
1363 		col = printf("\t[%d] = ", i++);
1364 		col += 7;	/* tab expands from 1 to 8 columns */
1365 		showbufc(col, (unsigned char *)ptr, l, VIS_DQ|VIS_TAB|VIS_NL);
1366 		if (l == len) {
1367 			printf("\tunterminated argument\n");
1368 			break;
1369 		}
1370 		len -= l + 1;
1371 		ptr += l + 1;
1372 	}
1373 }
1374 
1375 static void
1376 ktrpledge(struct ktr_pledge *pledge, size_t len)
1377 {
1378 	char *name = "";
1379 	int i;
1380 
1381 	if (len < sizeof(struct ktr_pledge))
1382 		errx(1, "invalid ktr pledge length %zu", len);
1383 
1384 	if (pledge->syscall >= SYS_MAXSYSCALL || pledge->syscall < 0)
1385 		(void)printf("[%d]", pledge->syscall);
1386 	else
1387 		(void)printf("%s", syscallnames[pledge->syscall]);
1388 	printf(", ");
1389 	for (i = 0; pledge->code && pledgenames[i].bits != 0; i++) {
1390 		if (pledgenames[i].bits & pledge->code) {
1391 			name = pledgenames[i].name;
1392 			break;
1393 		}
1394 	}
1395 	printf("\"%s\"", name);
1396 	(void)printf(", errno %d", pledge->error);
1397 	if (fancy)
1398 		(void)printf(" %s", strerror(pledge->error));
1399 	printf("\n");
1400 }
1401 
1402 static void
1403 usage(void)
1404 {
1405 
1406 	extern char *__progname;
1407 	fprintf(stderr, "usage: %s "
1408 	    "[-dHlnRTXx] [-f file] [-m maxdata] [-p pid] [-t trstr]\n",
1409 	    __progname);
1410 	exit(1);
1411 }
1412 
1413 
1414 /*
1415  * FORMATTERS
1416  */
1417 
1418 static void
1419 ioctldecode(int cmd)
1420 {
1421 	char dirbuf[4], *dir = dirbuf;
1422 	const char *cp;
1423 
1424 	if ((cp = ioctlname((unsigned)cmd)) != NULL) {
1425 		(void)printf("%s", cp);
1426 		return;
1427 	}
1428 
1429 	if (cmd & IOC_IN)
1430 		*dir++ = 'W';
1431 	if (cmd & IOC_OUT)
1432 		*dir++ = 'R';
1433 	*dir = '\0';
1434 
1435 	printf("_IO%s('%c',%d",
1436 	    dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1437 	if ((cmd & IOC_VOID) == 0)
1438 		printf(decimal ? ",%u)" : ",%#x)", (cmd >> 16) & 0xff);
1439 	else
1440 		printf(")");
1441 }
1442 
1443 static void
1444 ptracedecode(int request)
1445 {
1446 	if (request >= 0 && request < nitems(ptrace_ops))
1447 		(void)printf("%s", ptrace_ops[request]);
1448 	else switch(request) {
1449 #ifdef PT_GETFPREGS
1450 	case PT_GETFPREGS:
1451 		(void)printf("PT_GETFPREGS");
1452 		break;
1453 #endif
1454 	case PT_GETREGS:
1455 		(void)printf("PT_GETREGS");
1456 		break;
1457 #ifdef PT_GETXMMREGS
1458 	case PT_GETXMMREGS:
1459 		(void)printf("PT_GETXMMREGS");
1460 		break;
1461 #endif
1462 #ifdef PT_SETFPREGS
1463 	case PT_SETFPREGS:
1464 		(void)printf("PT_SETFPREGS");
1465 		break;
1466 #endif
1467 	case PT_SETREGS:
1468 		(void)printf("PT_SETREGS");
1469 		break;
1470 #ifdef PT_SETXMMREGS
1471 	case PT_SETXMMREGS:
1472 		(void)printf("PT_SETXMMREGS");
1473 		break;
1474 #endif
1475 #ifdef PT_STEP
1476 	case PT_STEP:
1477 		(void)printf("PT_STEP");
1478 		break;
1479 #endif
1480 #ifdef PT_WCOOKIE
1481 	case PT_WCOOKIE:
1482 		(void)printf("PT_WCOOKIE");
1483 		break;
1484 #endif
1485 	default:
1486 		pdecint(request);
1487 	}
1488 }
1489 
1490 
1491 static void
1492 atfd(int fd)
1493 {
1494 	if (fd == AT_FDCWD)
1495 		(void)printf("AT_FDCWD");
1496 	else
1497 		pdecint(fd);
1498 }
1499 
1500 static void
1501 polltimeout(int timeout)
1502 {
1503 	if (timeout == INFTIM)
1504 		(void)printf("INFTIM");
1505 	else
1506 		pdecint(timeout);
1507 }
1508 
1509 static void
1510 wait4pid(int pid)
1511 {
1512 	if (pid == WAIT_ANY)
1513 		(void)printf("WAIT_ANY");
1514 	else if (pid == WAIT_MYPGRP)
1515 		(void)printf("WAIT_MYPGRP");
1516 	else
1517 		pdecint(pid);		/* ppgid */
1518 }
1519 
1520 static void
1521 signame(int sig)
1522 {
1523 	if (sig > 0 && sig < NSIG)
1524 		(void)printf("SIG%s", sys_signame[sig]);
1525 	else
1526 		(void)printf("SIG %d", sig);
1527 }
1528 
1529 void
1530 sigset(int ss)
1531 {
1532 	int	or = 0;
1533 	int	cnt = 0;
1534 	int	i;
1535 
1536 	for (i = 1; i < NSIG; i++)
1537 		if (sigismember(&ss, i))
1538 			cnt++;
1539 	if (cnt > (NSIG-1)/2) {
1540 		ss = ~ss;
1541 		putchar('~');
1542 	}
1543 
1544 	if (ss == 0) {
1545 		(void)printf("0<>");
1546 		return;
1547 	}
1548 
1549 	printf("%#x<", ss);
1550 	for (i = 1; i < NSIG; i++)
1551 		if (sigismember(&ss, i)) {
1552 			if (or) putchar('|'); else or=1;
1553 			signame(i);
1554 		}
1555 	printf(">");
1556 }
1557 
1558 static void
1559 semctlname(int cmd)
1560 {
1561 	switch (cmd) {
1562 	case GETNCNT:
1563 		(void)printf("GETNCNT");
1564 		break;
1565 	case GETPID:
1566 		(void)printf("GETPID");
1567 		break;
1568 	case GETVAL:
1569 		(void)printf("GETVAL");
1570 		break;
1571 	case GETALL:
1572 		(void)printf("GETALL");
1573 		break;
1574 	case GETZCNT:
1575 		(void)printf("GETZCNT");
1576 		break;
1577 	case SETVAL:
1578 		(void)printf("SETVAL");
1579 		break;
1580 	case SETALL:
1581 		(void)printf("SETALL");
1582 		break;
1583 	case IPC_RMID:
1584 		(void)printf("IPC_RMID");
1585 		break;
1586 	case IPC_SET:
1587 		(void)printf("IPC_SET");
1588 		break;
1589 	case IPC_STAT:
1590 		(void)printf("IPC_STAT");
1591 		break;
1592 	default: /* Should not reach */
1593 		(void)printf("<invalid=%d>", cmd);
1594 	}
1595 }
1596 
1597 static void
1598 shmctlname(int cmd)
1599 {
1600 	switch (cmd) {
1601 	case IPC_RMID:
1602 		(void)printf("IPC_RMID");
1603 		break;
1604 	case IPC_SET:
1605 		(void)printf("IPC_SET");
1606 		break;
1607 	case IPC_STAT:
1608 		(void)printf("IPC_STAT");
1609 		break;
1610 	default: /* Should not reach */
1611 		(void)printf("<invalid=%d>", cmd);
1612 	}
1613 }
1614 
1615 
1616 static void
1617 semgetname(int flag)
1618 {
1619 	int	or = 0;
1620 	if_print_or(flag, IPC_CREAT, or);
1621 	if_print_or(flag, IPC_EXCL, or);
1622 	if_print_or(flag, SEM_R, or);
1623 	if_print_or(flag, SEM_A, or);
1624 	if_print_or(flag, (SEM_R>>3), or);
1625 	if_print_or(flag, (SEM_A>>3), or);
1626 	if_print_or(flag, (SEM_R>>6), or);
1627 	if_print_or(flag, (SEM_A>>6), or);
1628 
1629 	if (flag & ~(IPC_CREAT|IPC_EXCL|SEM_R|SEM_A|((SEM_R|SEM_A)>>3)|
1630 	    ((SEM_R|SEM_A)>>6)))
1631 		printf("<invalid=%#x>", flag);
1632 }
1633 
1634 
1635 /*
1636  * Only used by SYS_open and SYS_openat. Unless O_CREAT is set in flags, the
1637  * mode argument is unused (and often bogus and misleading).
1638  */
1639 static void
1640 flagsandmodename(int mode)
1641 {
1642 	openflagsname(arg1);
1643 	if ((arg1 & O_CREAT) == O_CREAT) {
1644 		(void)putchar(',');
1645 		modename(mode);
1646 	} else if (!fancy)
1647 		(void)printf(",<unused>%#o", mode);
1648 }
1649 
1650 static void
1651 clockname(int clockid)
1652 {
1653 	clocktypename(__CLOCK_TYPE(clockid));
1654 	if (__CLOCK_PTID(clockid) != 0)
1655 		printf("(%d)", __CLOCK_PTID(clockid));
1656 }
1657 
1658 /*
1659  * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value
1660  * referring to a line in /etc/protocols.
1661  */
1662 static void
1663 sockoptlevelname(int optname)
1664 {
1665 	struct protoent *pe;
1666 
1667 	if (arg1 == SOL_SOCKET) {
1668 		(void)printf("SOL_SOCKET,");
1669 		sockoptname(optname);
1670 	} else {
1671 		pe = getprotobynumber(arg1);
1672 		(void)printf("%u<%s>,%d", arg1,
1673 		    pe != NULL ? pe->p_name : "unknown", optname);
1674 	}
1675 }
1676 
1677 static void
1678 ktraceopname(int ops)
1679 {
1680 	int invalid = 0;
1681 
1682 	printf("%#x<", ops);
1683 	switch (KTROP(ops)) {
1684 	case KTROP_SET:
1685 		printf("KTROP_SET");
1686 		break;
1687 	case KTROP_CLEAR:
1688 		printf("KTROP_CLEAR");
1689 		break;
1690 	case KTROP_CLEARFILE:
1691 		printf("KTROP_CLEARFILE");
1692 		break;
1693 	default:
1694 		printf("KTROP(%d)", KTROP(ops));
1695 		invalid = 1;
1696 		break;
1697 	}
1698 	if (ops & KTRFLAG_DESCEND) printf("|KTRFLAG_DESCEND");
1699 	printf(">");
1700 	if (invalid || (ops & ~(KTROP((unsigned)-1) | KTRFLAG_DESCEND)))
1701 		(void)printf("<invalid>%d", ops);
1702 }
1703