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