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