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