xref: /openbsd-src/usr.bin/kdump/kdump.c (revision c1a45aed656e7d5627c30c92421893a76f370ccb)
1 /*	$OpenBSD: kdump.c,v 1.148 2022/02/22 17:31:31 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 #ifdef SYS_pad_pread
822     [SYS_pad_pread]	= { Pfd, Pptr, Pbigsize, PAD, Poff_t },
823     [SYS_pad_pwrite]	= { Pfd, Pptr, Pbigsize, PAD, Poff_t },
824 #endif
825     [SYS_setgid]	= { Gidname },
826     [SYS_setegid]	= { Gidname },
827     [SYS_seteuid]	= { Uidname },
828     [SYS_pathconf]	= { Ppath, Pathconfname },
829     [SYS_fpathconf]	= { Pfd, Pathconfname },
830     [SYS_swapctl]	= { Swapctlname, Pptr, Pdecint },
831     [SYS_getrlimit]	= { Rlimitname, Pptr },
832     [SYS_setrlimit]	= { Rlimitname, Pptr },
833     [SYS_mmap]		= { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, Poff_t, END64 },
834     [SYS_lseek]		= { Pfd, Poff_t, Whencename, END64 },
835     [SYS_truncate]	= { Ppath, Poff_t, END64 },
836     [SYS_ftruncate]	= { Pfd, Poff_t, END64 },
837 #ifdef SYS_pad_mmap
838     [SYS_pad_mmap]	= { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, PAD, Poff_t },
839     [SYS_pad_lseek]	= { Pfd, PAD, Poff_t, Whencename },
840     [SYS_pad_truncate]	= { Ppath, PAD, Poff_t },
841     [SYS_pad_ftruncate]	= { Pfd, PAD, Poff_t },
842 #endif
843     [SYS_sysctl]	= { Pptr, Pcount, Pptr, Pptr, Pptr, Psize },
844     [SYS_mlock]		= { Pptr, Pbigsize },
845     [SYS_munlock]	= { Pptr, Pbigsize },
846     [SYS_getpgid]	= { Ppid_t },
847     [SYS_utrace]	= { Pptr, Pptr, Psize },
848     [SYS_semget]	= { Pkey_t, Pcount, Semgetname },
849     [SYS_msgget]	= { Pkey_t, Msgflgname },
850     [SYS_msgsnd]	= { Pmsqid, Pptr, Psize, Msgflgname },
851     [SYS_msgrcv]	= { Pmsqid, Pptr, Psize, Pdeclong, Msgflgname },
852     [SYS_shmat]		= { Pshmid, Pptr, Shmatname },
853     [SYS_shmdt]		= { Pptr },
854     [SYS_minherit]	= { Pptr, Pbigsize, Minheritname },
855     [SYS_poll]		= { Pptr, Pucount, Polltimeout },
856     [SYS_lchown]	= { Ppath, Uidname, Gidname },
857     [SYS_getsid]	= { Ppid_t },
858     [SYS_msync]		= { Pptr, Pbigsize, Msyncflagsname },
859     [SYS_pipe]		= { Pptr },
860     [SYS_fhopen]	= { Pptr, Openflagsname },
861     [SYS_preadv]	= { Pfd, Pptr, Pcount, Poff_t, END64 },
862     [SYS_pwritev]	= { Pfd, Pptr, Pcount, Poff_t, END64 },
863 #ifdef SYS_pad_preadv
864     [SYS_pad_preadv]	= { Pfd, Pptr, Pcount, PAD, Poff_t },
865     [SYS_pad_pwritev]	= { Pfd, Pptr, Pcount, PAD, Poff_t },
866 #endif
867     [SYS_mlockall]	= { Mlockallname },
868     [SYS_getresuid]	= { Pptr, Pptr, Pptr },
869     [SYS_setresuid]	= { Uidname, Uidname, Uidname },
870     [SYS_getresgid]	= { Pptr, Pptr, Pptr },
871     [SYS_setresgid]	= { Gidname, Gidname, Gidname },
872     [SYS_mquery]	= { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, Poff_t, END64 },
873 #ifdef SYS_pad_mquery
874     [SYS_pad_mquery]	= { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, PAD, Poff_t },
875 #endif
876     [SYS_closefrom]	= { Pfd },
877     [SYS_sigaltstack]	= { Pptr, Pptr },
878     [SYS_shmget]	= { Pkey_t, Pbigsize, Semgetname },
879     [SYS_semop]		= { Psemid, Pptr, Psize },
880     [SYS_fhstat]	= { Pptr, Pptr },
881     [SYS___semctl]	= { Psemid, Pcount, Semctlname, Pptr },
882     [SYS_shmctl]	= { Pshmid, Shmctlname, Pptr },
883     [SYS_msgctl]	= { Pmsqid, Shmctlname, Pptr },
884     [SYS___thrwakeup]	= { Pptr, Pcount },
885     [SYS___threxit]	= { Pptr },
886     [SYS___thrsigdivert] = { Sigset, Pptr, Pptr },
887     [SYS___getcwd]	= { Pptr, Psize },
888     [SYS_adjfreq]	= { Pptr, Pptr },
889     [SYS_setrtable]	= { Pdecint },
890     [SYS_faccessat]	= { Atfd, Ppath, Accessmodename, Atflagsname },
891     [SYS_fchmodat]	= { Atfd, Ppath, Modename, Atflagsname },
892     [SYS_fchownat]	= { Atfd, Ppath, Uidname, Gidname, Atflagsname },
893     [SYS_linkat]	= { Atfd, Ppath, Atfd, Ppath, Atflagsname },
894     [SYS_mkdirat]	= { Atfd, Ppath, Modename },
895     [SYS_mkfifoat]	= { Atfd, Ppath, Modename },
896     [SYS_mknodat]	= { Atfd, Ppath, Modename, Pdev_t },
897     [SYS_openat]	= { Atfd, Ppath, PASS_TWO, Flagsandmodename },
898     [SYS_readlinkat]	= { Atfd, Ppath, Pptr, Psize },
899     [SYS_renameat]	= { Atfd, Ppath, Atfd, Ppath },
900     [SYS_symlinkat]	= { Ppath, Atfd, Ppath },
901     [SYS_unlinkat]	= { Atfd, Ppath, Atflagsname },
902     [SYS___set_tcb]	= { Pptr },
903 };
904 
905 
906 static void
907 ktrsyscall(struct ktr_syscall *ktr, size_t ktrlen)
908 {
909 	register_t *ap;
910 	int narg;
911 	char sep;
912 
913 	if (ktr->ktr_argsize > ktrlen)
914 		errx(1, "syscall argument length %d > ktr header length %zu",
915 		    ktr->ktr_argsize, ktrlen);
916 
917 	narg = ktr->ktr_argsize / sizeof(register_t);
918 	sep = '\0';
919 
920 	if (ktr->ktr_code >= SYS_MAXSYSCALL || ktr->ktr_code < 0)
921 		(void)printf("[%d]", ktr->ktr_code);
922 	else
923 		(void)printf("%s", syscallnames[ktr->ktr_code]);
924 	ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
925 	(void)putchar('(');
926 
927 	if (ktr->ktr_code == SYS_sysctl && fancy) {
928 		const char *s;
929 		int n, i, *top;
930 
931 		n = ap[1];
932 		if (n > CTL_MAXNAME)
933 			n = CTL_MAXNAME;
934 		if (n < 0)
935 			errx(1, "invalid sysctl length %d", n);
936 		if (n > 0) {
937 			top = (int *)(ap + 6);
938 			printf("%d", top[0]);
939 			for (i = 1; i < n; i++)
940 				printf(".%d", top[i]);
941 			if ((s = kresolvsysctl(0, top)) != NULL) {
942 				printf("<%s", s);
943 				for (i = 1; i < n; i++) {
944 					if ((s = kresolvsysctl(i, top)) != NULL)
945 						printf(".%s", s);
946 					else
947 						printf(".%d", top[i]);
948 				}
949 				putchar('>');
950 			}
951 		}
952 
953 		sep = ',';
954 		ap += 2;
955 		narg -= 2;
956 	} else if (ktr->ktr_code < nitems(scargs)) {
957 		const formatter *fmts = scargs[ktr->ktr_code];
958 		int fmt;
959 		int arg = 0;
960 
961 		while (arg < narg && (fmt = *fmts) != 0) {
962 			if (PAD64 && fmt == PASS_LONGLONG && (arg & 1))
963 				goto skip;
964 			if (sep)
965 				putchar(sep);
966 			sep = ',';
967 			if (!fancy && !FMT_IS_NONFANCY(fmt))
968 				fmt = Pnonfancy;
969 			if (fmt > 0)
970 				formatters[fmt]((int)*ap);
971 			else if (long_formatters[-fmt](*ap))
972 				sep = '\0';
973 			fmts++;
974 skip:
975 			ap++;
976 			arg++;
977 		}
978 		narg -= arg;
979 	}
980 
981 	while (narg > 0) {
982 		if (sep)
983 			putchar(sep);
984 		if (decimal)
985 			(void)printf("%ld", (long)*ap);
986 		else
987 			(void)printf("%#lx", (long)*ap);
988 		sep = ',';
989 		ap++;
990 		narg--;
991 	}
992 	(void)printf(")\n");
993 }
994 
995 static struct ctlname topname[] = CTL_NAMES;
996 static struct ctlname kernname[] = CTL_KERN_NAMES;
997 static struct ctlname vmname[] = CTL_VM_NAMES;
998 static struct ctlname fsname[] = CTL_FS_NAMES;
999 static struct ctlname netname[] = CTL_NET_NAMES;
1000 static struct ctlname hwname[] = CTL_HW_NAMES;
1001 static struct ctlname debugname[CTL_DEBUG_MAXID];
1002 static struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES;
1003 static struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES;
1004 static struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES;
1005 static struct ctlname kernprocname[] = {
1006 	{ NULL },
1007 	{ "all" },
1008 	{ "pid" },
1009 	{ "pgrp" },
1010 	{ "session" },
1011 	{ "tty" },
1012 	{ "uid" },
1013 	{ "ruid" },
1014 	{ "kthread" },
1015 };
1016 static struct ctlname ttysname[] = CTL_KERN_TTY_NAMES;
1017 static struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES;
1018 static struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES;
1019 static struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES;
1020 static struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES;
1021 #ifdef CTL_MACHDEP_NAMES
1022 static struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
1023 #endif
1024 static struct ctlname ddbname[] = CTL_DDB_NAMES;
1025 
1026 #ifndef nitems
1027 #define nitems(_a)    (sizeof((_a)) / sizeof((_a)[0]))
1028 #endif
1029 
1030 #define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)
1031 
1032 static const char *
1033 kresolvsysctl(int depth, const int *top)
1034 {
1035 	struct ctlname *names;
1036 	size_t		limit;
1037 	int		idx = top[depth];
1038 
1039 	names = NULL;
1040 
1041 	switch (depth) {
1042 	case 0:
1043 		SETNAME(topname);
1044 		break;
1045 	case 1:
1046 		switch (top[0]) {
1047 		case CTL_KERN:
1048 			SETNAME(kernname);
1049 			break;
1050 		case CTL_VM:
1051 			SETNAME(vmname);
1052 			break;
1053 		case CTL_FS:
1054 			SETNAME(fsname);
1055 			break;
1056 		case CTL_NET:
1057 			SETNAME(netname);
1058 			break;
1059 		case CTL_DEBUG:
1060 			SETNAME(debugname);
1061 			break;
1062 		case CTL_HW:
1063 			SETNAME(hwname);
1064 			break;
1065 #ifdef CTL_MACHDEP_NAMES
1066 		case CTL_MACHDEP:
1067 			SETNAME(machdepname);
1068 			break;
1069 #endif
1070 		case CTL_DDB:
1071 			SETNAME(ddbname);
1072 			break;
1073 		}
1074 		break;
1075 	case 2:
1076 		switch (top[0]) {
1077 		case CTL_KERN:
1078 			switch (top[1]) {
1079 			case KERN_MALLOCSTATS:
1080 				SETNAME(kernmallocname);
1081 				break;
1082 			case KERN_FORKSTAT:
1083 				SETNAME(forkstatname);
1084 				break;
1085 			case KERN_NCHSTATS:
1086 				SETNAME(nchstatsname);
1087 				break;
1088 			case KERN_TTY:
1089 				SETNAME(ttysname);
1090 				break;
1091 			case KERN_SEMINFO:
1092 				SETNAME(semname);
1093 				break;
1094 			case KERN_SHMINFO:
1095 				SETNAME(shmname);
1096 				break;
1097 			case KERN_WATCHDOG:
1098 				SETNAME(watchdogname);
1099 				break;
1100 			case KERN_PROC:
1101 				idx++;	/* zero is valid at this level */
1102 				SETNAME(kernprocname);
1103 				break;
1104 			case KERN_TIMECOUNTER:
1105 				SETNAME(tcname);
1106 				break;
1107 			}
1108 		}
1109 		break;
1110 	}
1111 	if (names != NULL && idx > 0 && idx < limit)
1112 		return (names[idx].ctl_name);
1113 	return (NULL);
1114 }
1115 
1116 static void
1117 ktrsysret(struct ktr_sysret *ktr, size_t ktrlen)
1118 {
1119 	register_t ret = 0;
1120 	long long retll;
1121 	int error = ktr->ktr_error;
1122 	int code = ktr->ktr_code;
1123 
1124 	if (ktrlen < sizeof(*ktr))
1125 		errx(1, "sysret length %zu < ktr header length %zu",
1126 		    ktrlen, sizeof(*ktr));
1127 	ktrlen -= sizeof(*ktr);
1128 	if (error == 0) {
1129 		if (ktrlen == sizeof(ret)) {
1130 			memcpy(&ret, ktr+1, sizeof(ret));
1131 			retll = ret;
1132 		} else if (ktrlen == sizeof(retll))
1133 			memcpy(&retll, ktr+1, sizeof(retll));
1134 		else
1135 			errx(1, "sysret bogus length %zu", ktrlen);
1136 	}
1137 
1138 	if (code >= SYS_MAXSYSCALL || code < 0)
1139 		(void)printf("[%d] ", code);
1140 	else
1141 		(void)printf("%s ", syscallnames[code]);
1142 
1143 doerr:
1144 	if (error == 0) {
1145 		if (fancy) {
1146 			switch (code) {
1147 			case SYS_lseek:
1148 #ifdef SYS_pad_lseek
1149 			case SYS_pad_lseek:
1150 #endif
1151 				(void)printf("%lld", retll);
1152 				if (retll < 0 || retll > 9)
1153 					(void)printf("/%#llx", retll);
1154 				break;
1155 			case SYS_sigprocmask:
1156 			case SYS_sigpending:
1157 				sigset(ret);
1158 				break;
1159 			case SYS___thrsigdivert:
1160 				signame(ret);
1161 				break;
1162 			case SYS_getuid:
1163 			case SYS_geteuid:
1164 				uidname(ret);
1165 				break;
1166 			case SYS_getgid:
1167 			case SYS_getegid:
1168 				gidname(ret);
1169 				break;
1170 			/* syscalls that return errno values */
1171 			case SYS_getlogin_r:
1172 			case SYS___thrsleep:
1173 				if ((error = ret) != 0)
1174 					goto doerr;
1175 				/* FALLTHROUGH */
1176 			default:
1177 				(void)printf("%ld", (long)ret);
1178 				if (ret < 0 || ret > 9)
1179 					(void)printf("/%#lx", (long)ret);
1180 			}
1181 		} else {
1182 			if (decimal)
1183 				(void)printf("%lld", retll);
1184 			else
1185 				(void)printf("%#llx", retll);
1186 		}
1187 	} else if (error == ERESTART)
1188 		(void)printf("RESTART");
1189 	else if (error == EJUSTRETURN)
1190 		(void)printf("JUSTRETURN");
1191 	else {
1192 		(void)printf("-1 errno %d", error);
1193 		if (fancy)
1194 			(void)printf(" %s", strerror(error));
1195 	}
1196 	(void)putchar('\n');
1197 }
1198 
1199 static void
1200 ktrnamei(const char *cp, size_t len)
1201 {
1202 	showbufc(basecol, (unsigned char *)cp, len, VIS_DQ | VIS_TAB | VIS_NL);
1203 }
1204 
1205 void
1206 showbufc(int col, unsigned char *dp, size_t datalen, int flags)
1207 {
1208 	int width;
1209 	unsigned char visbuf[5], *cp;
1210 
1211 	flags |= VIS_CSTYLE;
1212 	putchar('"');
1213 	col++;
1214 	for (; datalen > 0; datalen--, dp++) {
1215 		(void)vis(visbuf, *dp, flags, *(dp+1));
1216 		cp = visbuf;
1217 
1218 		/*
1219 		 * Keep track of printables and
1220 		 * space chars (like fold(1)).
1221 		 */
1222 		if (col == 0) {
1223 			(void)putchar('\t');
1224 			col = 8;
1225 		}
1226 		switch (*cp) {
1227 		case '\n':
1228 			col = 0;
1229 			(void)putchar('\n');
1230 			continue;
1231 		case '\t':
1232 			width = 8 - (col&07);
1233 			break;
1234 		default:
1235 			width = strlen(cp);
1236 		}
1237 		if (col + width > (screenwidth-2)) {
1238 			(void)printf("\\\n\t");
1239 			col = 8;
1240 		}
1241 		col += width;
1242 		do {
1243 			(void)putchar(*cp++);
1244 		} while (*cp);
1245 	}
1246 	if (col == 0)
1247 		(void)printf("       ");
1248 	(void)printf("\"\n");
1249 }
1250 
1251 static void
1252 showbuf(unsigned char *dp, size_t datalen)
1253 {
1254 	int i, j;
1255 	int col = 0, bpl;
1256 	unsigned char c;
1257 
1258 	if (iohex == 1) {
1259 		putchar('\t');
1260 		col = 8;
1261 		for (i = 0; i < datalen; i++) {
1262 			printf("%02x", dp[i]);
1263 			col += 3;
1264 			if (i < datalen - 1) {
1265 				if (col + 3 > screenwidth) {
1266 					printf("\n\t");
1267 					col = 8;
1268 				} else
1269 					putchar(' ');
1270 			}
1271 		}
1272 		putchar('\n');
1273 		return;
1274 	}
1275 	if (iohex == 2) {
1276 		bpl = (screenwidth - 13)/4;
1277 		if (bpl <= 0)
1278 			bpl = 1;
1279 		for (i = 0; i < datalen; i += bpl) {
1280 			printf("   %04x:  ", i);
1281 			for (j = 0; j < bpl; j++) {
1282 				if (i+j >= datalen)
1283 					printf("   ");
1284 				else
1285 					printf("%02x ", dp[i+j]);
1286 			}
1287 			putchar(' ');
1288 			for (j = 0; j < bpl; j++) {
1289 				if (i+j >= datalen)
1290 					break;
1291 				c = dp[i+j];
1292 				if (!isprint(c))
1293 					c = '.';
1294 				putchar(c);
1295 			}
1296 			putchar('\n');
1297 		}
1298 		return;
1299 	}
1300 
1301 	(void)printf("       ");
1302 	showbufc(7, dp, datalen, 0);
1303 }
1304 
1305 static void
1306 ktrgenio(struct ktr_genio *ktr, size_t len)
1307 {
1308 	unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
1309 	size_t datalen;
1310 
1311 	if (len < sizeof(struct ktr_genio))
1312 		errx(1, "invalid ktr genio length %zu", len);
1313 
1314 	datalen = len - sizeof(struct ktr_genio);
1315 
1316 	printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1317 		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
1318 	if (maxdata == 0)
1319 		return;
1320 	if (datalen > maxdata)
1321 		datalen = maxdata;
1322 	if (iohex && !datalen)
1323 		return;
1324 	showbuf(dp, datalen);
1325 }
1326 
1327 static void
1328 ktrpsig(struct ktr_psig *psig)
1329 {
1330 	signame(psig->signo);
1331 	printf(" ");
1332 	if (psig->action == SIG_DFL)
1333 		(void)printf("SIG_DFL");
1334 	else {
1335 		(void)printf("caught handler=0x%lx mask=",
1336 		    (u_long)psig->action);
1337 		sigset(psig->mask);
1338 	}
1339 	if (psig->code) {
1340 		printf(" code ");
1341 		if (fancy) {
1342 			switch (psig->signo) {
1343 			case SIGILL:
1344 				sigill_name(psig->code);
1345 				break;
1346 			case SIGTRAP:
1347 				sigtrap_name(psig->code);
1348 				break;
1349 			case SIGEMT:
1350 				sigemt_name(psig->code);
1351 				break;
1352 			case SIGFPE:
1353 				sigfpe_name(psig->code);
1354 				break;
1355 			case SIGBUS:
1356 				sigbus_name(psig->code);
1357 				break;
1358 			case SIGSEGV:
1359 				sigsegv_name(psig->code);
1360 				break;
1361 			case SIGCHLD:
1362 				sigchld_name(psig->code);
1363 				break;
1364 			}
1365 		}
1366 		printf("<%d>", psig->code);
1367 	}
1368 
1369 	switch (psig->signo) {
1370 	case SIGSEGV:
1371 	case SIGILL:
1372 	case SIGBUS:
1373 	case SIGFPE:
1374 		printf(" addr=%p trapno=%d", psig->si.si_addr,
1375 		    psig->si.si_trapno);
1376 		break;
1377 	default:
1378 		break;
1379 	}
1380 	printf("\n");
1381 }
1382 
1383 static void
1384 ktruser(struct ktr_user *usr, size_t len)
1385 {
1386 	if (len < sizeof(struct ktr_user))
1387 		errx(1, "invalid ktr user length %zu", len);
1388 	len -= sizeof(struct ktr_user);
1389 	printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id);
1390 	printf(" %zu bytes\n", len);
1391 	showbuf((unsigned char *)(usr + 1), len);
1392 }
1393 
1394 static void
1395 ktrexec(const char *ptr, size_t len)
1396 {
1397 	int i, col;
1398 	size_t l;
1399 
1400 	putchar('\n');
1401 	i = 0;
1402 	while (len > 0) {
1403 		l = strnlen(ptr, len);
1404 		col = printf("\t[%d] = ", i++);
1405 		col += 7;	/* tab expands from 1 to 8 columns */
1406 		showbufc(col, (unsigned char *)ptr, l, VIS_DQ|VIS_TAB|VIS_NL);
1407 		if (l == len) {
1408 			printf("\tunterminated argument\n");
1409 			break;
1410 		}
1411 		len -= l + 1;
1412 		ptr += l + 1;
1413 	}
1414 }
1415 
1416 static void
1417 ktrpledge(struct ktr_pledge *pledge, size_t len)
1418 {
1419 	const char *name = "";
1420 	int i;
1421 
1422 	if (len < sizeof(struct ktr_pledge))
1423 		errx(1, "invalid ktr pledge length %zu", len);
1424 
1425 	if (pledge->syscall >= SYS_MAXSYSCALL || pledge->syscall < 0)
1426 		(void)printf("[%d]", pledge->syscall);
1427 	else
1428 		(void)printf("%s", syscallnames[pledge->syscall]);
1429 	printf(", ");
1430 	for (i = 0; pledge->code && pledgenames[i].bits != 0; i++) {
1431 		if (pledgenames[i].bits & pledge->code) {
1432 			name = pledgenames[i].name;
1433 			break;
1434 		}
1435 	}
1436 	printf("\"%s\"", name);
1437 	(void)printf(", errno %d", pledge->error);
1438 	if (fancy)
1439 		(void)printf(" %s", strerror(pledge->error));
1440 	printf("\n");
1441 }
1442 
1443 static void
1444 usage(void)
1445 {
1446 
1447 	extern char *__progname;
1448 	fprintf(stderr, "usage: %s "
1449 	    "[-dHlnRTXx] [-f file] [-m maxdata] [-p pid] [-t trstr]\n",
1450 	    __progname);
1451 	exit(1);
1452 }
1453 
1454 
1455 /*
1456  * FORMATTERS
1457  */
1458 
1459 static void
1460 ioctldecode(int cmd)
1461 {
1462 	char dirbuf[4], *dir = dirbuf;
1463 	const char *cp;
1464 
1465 	if ((cp = ioctlname((unsigned)cmd)) != NULL) {
1466 		(void)printf("%s", cp);
1467 		return;
1468 	}
1469 
1470 	if (cmd & IOC_IN)
1471 		*dir++ = 'W';
1472 	if (cmd & IOC_OUT)
1473 		*dir++ = 'R';
1474 	*dir = '\0';
1475 
1476 	printf("_IO%s('%c',%d",
1477 	    dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1478 	if ((cmd & IOC_VOID) == 0)
1479 		printf(decimal ? ",%u)" : ",%#x)", (cmd >> 16) & 0xff);
1480 	else
1481 		printf(")");
1482 }
1483 
1484 static void
1485 ptracedecode(int request)
1486 {
1487 	if (request >= 0 && request < nitems(ptrace_ops))
1488 		(void)printf("%s", ptrace_ops[request]);
1489 	else switch(request) {
1490 #ifdef PT_GETFPREGS
1491 	case PT_GETFPREGS:
1492 		(void)printf("PT_GETFPREGS");
1493 		break;
1494 #endif
1495 	case PT_GETREGS:
1496 		(void)printf("PT_GETREGS");
1497 		break;
1498 #ifdef PT_GETXMMREGS
1499 	case PT_GETXMMREGS:
1500 		(void)printf("PT_GETXMMREGS");
1501 		break;
1502 #endif
1503 #ifdef PT_SETFPREGS
1504 	case PT_SETFPREGS:
1505 		(void)printf("PT_SETFPREGS");
1506 		break;
1507 #endif
1508 	case PT_SETREGS:
1509 		(void)printf("PT_SETREGS");
1510 		break;
1511 #ifdef PT_SETXMMREGS
1512 	case PT_SETXMMREGS:
1513 		(void)printf("PT_SETXMMREGS");
1514 		break;
1515 #endif
1516 #ifdef PT_STEP
1517 	case PT_STEP:
1518 		(void)printf("PT_STEP");
1519 		break;
1520 #endif
1521 #ifdef PT_WCOOKIE
1522 	case PT_WCOOKIE:
1523 		(void)printf("PT_WCOOKIE");
1524 		break;
1525 #endif
1526 	default:
1527 		pdecint(request);
1528 	}
1529 }
1530 
1531 
1532 static void
1533 atfd(int fd)
1534 {
1535 	if (fd == AT_FDCWD)
1536 		(void)printf("AT_FDCWD");
1537 	else
1538 		pdecint(fd);
1539 }
1540 
1541 static void
1542 polltimeout(int timeout)
1543 {
1544 	if (timeout == INFTIM)
1545 		(void)printf("INFTIM");
1546 	else
1547 		pdecint(timeout);
1548 }
1549 
1550 static void
1551 wait4pid(int pid)
1552 {
1553 	if (pid == WAIT_ANY)
1554 		(void)printf("WAIT_ANY");
1555 	else if (pid == WAIT_MYPGRP)
1556 		(void)printf("WAIT_MYPGRP");
1557 	else
1558 		pdecint(pid);		/* ppgid */
1559 }
1560 
1561 static void
1562 signame(int sig)
1563 {
1564 	if (sig > 0 && sig < NSIG)
1565 		(void)printf("SIG%s", sys_signame[sig]);
1566 	else
1567 		(void)printf("SIG %d", sig);
1568 }
1569 
1570 void
1571 sigset(int ss)
1572 {
1573 	int	or = 0;
1574 	int	cnt = 0;
1575 	int	i;
1576 
1577 	for (i = 1; i < NSIG; i++)
1578 		if (sigismember(&ss, i))
1579 			cnt++;
1580 	if (cnt > (NSIG-1)/2) {
1581 		ss = ~ss;
1582 		putchar('~');
1583 	}
1584 
1585 	if (ss == 0) {
1586 		(void)printf("0<>");
1587 		return;
1588 	}
1589 
1590 	printf("%#x<", ss);
1591 	for (i = 1; i < NSIG; i++)
1592 		if (sigismember(&ss, i)) {
1593 			if (or) putchar('|'); else or=1;
1594 			signame(i);
1595 		}
1596 	printf(">");
1597 }
1598 
1599 static void
1600 semctlname(int cmd)
1601 {
1602 	switch (cmd) {
1603 	case GETNCNT:
1604 		(void)printf("GETNCNT");
1605 		break;
1606 	case GETPID:
1607 		(void)printf("GETPID");
1608 		break;
1609 	case GETVAL:
1610 		(void)printf("GETVAL");
1611 		break;
1612 	case GETALL:
1613 		(void)printf("GETALL");
1614 		break;
1615 	case GETZCNT:
1616 		(void)printf("GETZCNT");
1617 		break;
1618 	case SETVAL:
1619 		(void)printf("SETVAL");
1620 		break;
1621 	case SETALL:
1622 		(void)printf("SETALL");
1623 		break;
1624 	case IPC_RMID:
1625 		(void)printf("IPC_RMID");
1626 		break;
1627 	case IPC_SET:
1628 		(void)printf("IPC_SET");
1629 		break;
1630 	case IPC_STAT:
1631 		(void)printf("IPC_STAT");
1632 		break;
1633 	default: /* Should not reach */
1634 		(void)printf("<invalid=%d>", cmd);
1635 	}
1636 }
1637 
1638 static void
1639 shmctlname(int cmd)
1640 {
1641 	switch (cmd) {
1642 	case IPC_RMID:
1643 		(void)printf("IPC_RMID");
1644 		break;
1645 	case IPC_SET:
1646 		(void)printf("IPC_SET");
1647 		break;
1648 	case IPC_STAT:
1649 		(void)printf("IPC_STAT");
1650 		break;
1651 	default: /* Should not reach */
1652 		(void)printf("<invalid=%d>", cmd);
1653 	}
1654 }
1655 
1656 
1657 static void
1658 semgetname(int flag)
1659 {
1660 	int	or = 0;
1661 	if_print_or(flag, IPC_CREAT, or);
1662 	if_print_or(flag, IPC_EXCL, or);
1663 	if_print_or(flag, SEM_R, or);
1664 	if_print_or(flag, SEM_A, or);
1665 	if_print_or(flag, (SEM_R>>3), or);
1666 	if_print_or(flag, (SEM_A>>3), or);
1667 	if_print_or(flag, (SEM_R>>6), or);
1668 	if_print_or(flag, (SEM_A>>6), or);
1669 
1670 	if (flag & ~(IPC_CREAT|IPC_EXCL|SEM_R|SEM_A|((SEM_R|SEM_A)>>3)|
1671 	    ((SEM_R|SEM_A)>>6)))
1672 		printf("<invalid=%#x>", flag);
1673 }
1674 
1675 
1676 /*
1677  * Only used by SYS_open and SYS_openat. Unless O_CREAT is set in flags, the
1678  * mode argument is unused (and often bogus and misleading).
1679  */
1680 static void
1681 flagsandmodename(int mode)
1682 {
1683 	openflagsname(arg1);
1684 	if ((arg1 & O_CREAT) == O_CREAT) {
1685 		(void)putchar(',');
1686 		modename(mode);
1687 	} else if (!fancy)
1688 		(void)printf(",<unused>%#o", mode);
1689 }
1690 
1691 static void
1692 clockname(int clockid)
1693 {
1694 	clocktypename(__CLOCK_TYPE(clockid));
1695 	if (__CLOCK_PTID(clockid) != 0)
1696 		printf("(%d)", __CLOCK_PTID(clockid));
1697 }
1698 
1699 /*
1700  * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value
1701  * referring to a line in /etc/protocols.
1702  */
1703 static void
1704 sockoptlevelname(int optname)
1705 {
1706 	struct protoent *pe;
1707 
1708 	if (arg1 == SOL_SOCKET) {
1709 		(void)printf("SOL_SOCKET,");
1710 		sockoptname(optname);
1711 	} else {
1712 		pe = getprotobynumber(arg1);
1713 		(void)printf("%u<%s>,%d", arg1,
1714 		    pe != NULL ? pe->p_name : "unknown", optname);
1715 	}
1716 }
1717 
1718 static void
1719 ktraceopname(int ops)
1720 {
1721 	int invalid = 0;
1722 
1723 	printf("%#x<", ops);
1724 	switch (KTROP(ops)) {
1725 	case KTROP_SET:
1726 		printf("KTROP_SET");
1727 		break;
1728 	case KTROP_CLEAR:
1729 		printf("KTROP_CLEAR");
1730 		break;
1731 	case KTROP_CLEARFILE:
1732 		printf("KTROP_CLEARFILE");
1733 		break;
1734 	default:
1735 		printf("KTROP(%d)", KTROP(ops));
1736 		invalid = 1;
1737 		break;
1738 	}
1739 	if (ops & KTRFLAG_DESCEND) printf("|KTRFLAG_DESCEND");
1740 	printf(">");
1741 	if (invalid || (ops & ~(KTROP((unsigned)-1) | KTRFLAG_DESCEND)))
1742 		(void)printf("<invalid>%d", ops);
1743 }
1744