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