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