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