1 /* $OpenBSD: kdump.c,v 1.164 2024/06/29 11:32:35 jsg 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 if (len < sizeof(struct ktr_pinsyscall))
1503 errx(1, "invalid ktr pinsyscall length %zu", len);
1504
1505 if (pinsyscall->syscall >= SYS_MAXSYSCALL || pinsyscall->syscall < 0)
1506 (void)printf("[%d]", pinsyscall->syscall);
1507 else
1508 (void)printf("%s", syscallnames[pinsyscall->syscall]);
1509 (void)printf(", addr %lx, errno %d", pinsyscall->addr,
1510 pinsyscall->error);
1511 (void)printf(", errno %d", pinsyscall->error);
1512 if (fancy)
1513 (void)printf(" %s", strerror(pinsyscall->error));
1514 printf("\n");
1515 }
1516
1517 static void
usage(void)1518 usage(void)
1519 {
1520
1521 extern char *__progname;
1522 fprintf(stderr, "usage: %s "
1523 "[-dHlnRTXx] [-f file] [-m maxdata] [-P program] [-p pid] "
1524 "[-t trstr]\n\t[-u label]\n", __progname);
1525 exit(1);
1526 }
1527
1528
1529 /*
1530 * FORMATTERS
1531 */
1532
1533 static void
ioctldecode(int cmd)1534 ioctldecode(int cmd)
1535 {
1536 char dirbuf[4], *dir = dirbuf;
1537 const char *cp;
1538
1539 if ((cp = ioctlname((unsigned)cmd)) != NULL) {
1540 (void)printf("%s", cp);
1541 return;
1542 }
1543
1544 if (cmd & IOC_IN)
1545 *dir++ = 'W';
1546 if (cmd & IOC_OUT)
1547 *dir++ = 'R';
1548 *dir = '\0';
1549
1550 printf("_IO%s('%c',%d",
1551 dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1552 if ((cmd & IOC_VOID) == 0)
1553 printf(decimal ? ",%u)" : ",%#x)", (cmd >> 16) & 0xff);
1554 else
1555 printf(")");
1556 }
1557
1558 static void
ptracedecode(int request)1559 ptracedecode(int request)
1560 {
1561 if (request >= 0 && request < nitems(ptrace_ops))
1562 (void)printf("%s", ptrace_ops[request]);
1563 else switch(request) {
1564 #ifdef PT_GETFPREGS
1565 case PT_GETFPREGS:
1566 (void)printf("PT_GETFPREGS");
1567 break;
1568 #endif
1569 case PT_GETREGS:
1570 (void)printf("PT_GETREGS");
1571 break;
1572 #ifdef PT_GETXMMREGS
1573 case PT_GETXMMREGS:
1574 (void)printf("PT_GETXMMREGS");
1575 break;
1576 #endif
1577 #ifdef PT_SETFPREGS
1578 case PT_SETFPREGS:
1579 (void)printf("PT_SETFPREGS");
1580 break;
1581 #endif
1582 case PT_SETREGS:
1583 (void)printf("PT_SETREGS");
1584 break;
1585 #ifdef PT_SETXMMREGS
1586 case PT_SETXMMREGS:
1587 (void)printf("PT_SETXMMREGS");
1588 break;
1589 #endif
1590 #ifdef PT_STEP
1591 case PT_STEP:
1592 (void)printf("PT_STEP");
1593 break;
1594 #endif
1595 #ifdef PT_WCOOKIE
1596 case PT_WCOOKIE:
1597 (void)printf("PT_WCOOKIE");
1598 break;
1599 #endif
1600 default:
1601 pdecint(request);
1602 }
1603 }
1604
1605
1606 static void
atfd(int fd)1607 atfd(int fd)
1608 {
1609 if (fd == AT_FDCWD)
1610 (void)printf("AT_FDCWD");
1611 else
1612 pdecint(fd);
1613 }
1614
1615 static void
polltimeout(int timeout)1616 polltimeout(int timeout)
1617 {
1618 if (timeout == INFTIM)
1619 (void)printf("INFTIM");
1620 else
1621 pdecint(timeout);
1622 }
1623
1624 static void
wait4pid(int pid)1625 wait4pid(int pid)
1626 {
1627 if (pid == WAIT_ANY)
1628 (void)printf("WAIT_ANY");
1629 else if (pid == WAIT_MYPGRP)
1630 (void)printf("WAIT_MYPGRP");
1631 else
1632 pdecint(pid); /* ppgid */
1633 }
1634
1635 static void
signame(int sig)1636 signame(int sig)
1637 {
1638 if (sig > 0 && sig < NSIG)
1639 (void)printf("SIG%s", sys_signame[sig]);
1640 else
1641 (void)printf("SIG %d", sig);
1642 }
1643
1644 void
sigset(int ss)1645 sigset(int ss)
1646 {
1647 int or = 0;
1648 int cnt = 0;
1649 int i;
1650
1651 for (i = 1; i < NSIG; i++)
1652 if (sigismember(&ss, i))
1653 cnt++;
1654 if (cnt > (NSIG-1)/2) {
1655 ss = ~ss;
1656 putchar('~');
1657 }
1658
1659 if (ss == 0) {
1660 (void)printf("0<>");
1661 return;
1662 }
1663
1664 printf("%#x<", ss);
1665 for (i = 1; i < NSIG; i++)
1666 if (sigismember(&ss, i)) {
1667 if (or) putchar('|'); else or=1;
1668 signame(i);
1669 }
1670 printf(">");
1671 }
1672
1673 static void
semctlname(int cmd)1674 semctlname(int cmd)
1675 {
1676 switch (cmd) {
1677 case GETNCNT:
1678 (void)printf("GETNCNT");
1679 break;
1680 case GETPID:
1681 (void)printf("GETPID");
1682 break;
1683 case GETVAL:
1684 (void)printf("GETVAL");
1685 break;
1686 case GETALL:
1687 (void)printf("GETALL");
1688 break;
1689 case GETZCNT:
1690 (void)printf("GETZCNT");
1691 break;
1692 case SETVAL:
1693 (void)printf("SETVAL");
1694 break;
1695 case SETALL:
1696 (void)printf("SETALL");
1697 break;
1698 case IPC_RMID:
1699 (void)printf("IPC_RMID");
1700 break;
1701 case IPC_SET:
1702 (void)printf("IPC_SET");
1703 break;
1704 case IPC_STAT:
1705 (void)printf("IPC_STAT");
1706 break;
1707 default: /* Should not reach */
1708 (void)printf("<invalid=%d>", cmd);
1709 }
1710 }
1711
1712 static void
shmctlname(int cmd)1713 shmctlname(int cmd)
1714 {
1715 switch (cmd) {
1716 case IPC_RMID:
1717 (void)printf("IPC_RMID");
1718 break;
1719 case IPC_SET:
1720 (void)printf("IPC_SET");
1721 break;
1722 case IPC_STAT:
1723 (void)printf("IPC_STAT");
1724 break;
1725 default: /* Should not reach */
1726 (void)printf("<invalid=%d>", cmd);
1727 }
1728 }
1729
1730
1731 static void
semgetname(int flag)1732 semgetname(int flag)
1733 {
1734 int or = 0;
1735 if_print_or(flag, IPC_CREAT, or);
1736 if_print_or(flag, IPC_EXCL, or);
1737 if_print_or(flag, SEM_R, or);
1738 if_print_or(flag, SEM_A, or);
1739 if_print_or(flag, (SEM_R>>3), or);
1740 if_print_or(flag, (SEM_A>>3), or);
1741 if_print_or(flag, (SEM_R>>6), or);
1742 if_print_or(flag, (SEM_A>>6), or);
1743
1744 if (flag & ~(IPC_CREAT|IPC_EXCL|SEM_R|SEM_A|((SEM_R|SEM_A)>>3)|
1745 ((SEM_R|SEM_A)>>6)))
1746 printf("<invalid=%#x>", flag);
1747 }
1748
1749
1750 /*
1751 * Only used by SYS_open and SYS_openat. Unless O_CREAT is set in flags, the
1752 * mode argument is unused (and often bogus and misleading).
1753 */
1754 static void
flagsandmodename(int mode)1755 flagsandmodename(int mode)
1756 {
1757 openflagsname(arg1);
1758 if ((arg1 & O_CREAT) == O_CREAT) {
1759 (void)putchar(',');
1760 modename(mode);
1761 } else if (!fancy)
1762 (void)printf(",<unused>%#o", mode);
1763 }
1764
1765 static void
clockname(int clockid)1766 clockname(int clockid)
1767 {
1768 clocktypename(__CLOCK_TYPE(clockid));
1769 if (__CLOCK_PTID(clockid) != 0)
1770 printf("(%d)", __CLOCK_PTID(clockid));
1771 }
1772
1773 /*
1774 * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value
1775 * referring to a line in /etc/protocols.
1776 */
1777 static void
sockoptlevelname(int optname)1778 sockoptlevelname(int optname)
1779 {
1780 struct protoent *pe;
1781
1782 if (arg1 == SOL_SOCKET) {
1783 (void)printf("SOL_SOCKET,");
1784 sockoptname(optname);
1785 } else {
1786 pe = getprotobynumber(arg1);
1787 (void)printf("%u<%s>,%d", arg1,
1788 pe != NULL ? pe->p_name : "unknown", optname);
1789 }
1790 }
1791
1792 static void
ktraceopname(int ops)1793 ktraceopname(int ops)
1794 {
1795 int invalid = 0;
1796
1797 printf("%#x<", ops);
1798 switch (KTROP(ops)) {
1799 case KTROP_SET:
1800 printf("KTROP_SET");
1801 break;
1802 case KTROP_CLEAR:
1803 printf("KTROP_CLEAR");
1804 break;
1805 case KTROP_CLEARFILE:
1806 printf("KTROP_CLEARFILE");
1807 break;
1808 default:
1809 printf("KTROP(%d)", KTROP(ops));
1810 invalid = 1;
1811 break;
1812 }
1813 if (ops & KTRFLAG_DESCEND) printf("|KTRFLAG_DESCEND");
1814 printf(">");
1815 if (invalid || (ops & ~(KTROP((unsigned)-1) | KTRFLAG_DESCEND)))
1816 (void)printf("<invalid>%d", ops);
1817 }
1818
1819 static void
idtypeandid(int id)1820 idtypeandid(int id)
1821 {
1822 switch (arg1) {
1823 case P_PID:
1824 printf("P_PID,%d", id);
1825 break;
1826 case P_PGID:
1827 printf("P_PGID,%d", id);
1828 break;
1829 case P_ALL:
1830 printf("P_ALL,<unused>%d", id);
1831 break;
1832 default: /* Should not reach */
1833 printf("<invalid=%d>, <unused>%d", arg1, id);
1834 }
1835 }
1836