1 /* $OpenBSD: kdump.c,v 1.141 2020/01/18 23:56:31 cheloha 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"); 227 if (unveil(_PATH_PROTOCOLS, "r") == -1) 228 err(1, "unveil"); 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 case SYS_futex: 1132 if ((error = ret) != 0) 1133 goto doerr; 1134 /* FALLTHROUGH */ 1135 default: 1136 (void)printf("%ld", (long)ret); 1137 if (ret < 0 || ret > 9) 1138 (void)printf("/%#lx", (long)ret); 1139 } 1140 } else { 1141 if (decimal) 1142 (void)printf("%lld", retll); 1143 else 1144 (void)printf("%#llx", retll); 1145 } 1146 } else if (error == ERESTART) 1147 (void)printf("RESTART"); 1148 else if (error == EJUSTRETURN) 1149 (void)printf("JUSTRETURN"); 1150 else { 1151 (void)printf("-1 errno %d", error); 1152 if (fancy) 1153 (void)printf(" %s", strerror(error)); 1154 } 1155 (void)putchar('\n'); 1156 } 1157 1158 static void 1159 ktrnamei(const char *cp, size_t len) 1160 { 1161 showbufc(basecol, (unsigned char *)cp, len, VIS_DQ | VIS_TAB | VIS_NL); 1162 } 1163 1164 void 1165 showbufc(int col, unsigned char *dp, size_t datalen, int flags) 1166 { 1167 int width; 1168 unsigned char visbuf[5], *cp; 1169 1170 flags |= VIS_CSTYLE; 1171 putchar('"'); 1172 col++; 1173 for (; datalen > 0; datalen--, dp++) { 1174 (void)vis(visbuf, *dp, flags, *(dp+1)); 1175 cp = visbuf; 1176 1177 /* 1178 * Keep track of printables and 1179 * space chars (like fold(1)). 1180 */ 1181 if (col == 0) { 1182 (void)putchar('\t'); 1183 col = 8; 1184 } 1185 switch (*cp) { 1186 case '\n': 1187 col = 0; 1188 (void)putchar('\n'); 1189 continue; 1190 case '\t': 1191 width = 8 - (col&07); 1192 break; 1193 default: 1194 width = strlen(cp); 1195 } 1196 if (col + width > (screenwidth-2)) { 1197 (void)printf("\\\n\t"); 1198 col = 8; 1199 } 1200 col += width; 1201 do { 1202 (void)putchar(*cp++); 1203 } while (*cp); 1204 } 1205 if (col == 0) 1206 (void)printf(" "); 1207 (void)printf("\"\n"); 1208 } 1209 1210 static void 1211 showbuf(unsigned char *dp, size_t datalen) 1212 { 1213 int i, j; 1214 int col = 0, bpl; 1215 unsigned char c; 1216 1217 if (iohex == 1) { 1218 putchar('\t'); 1219 col = 8; 1220 for (i = 0; i < datalen; i++) { 1221 printf("%02x", dp[i]); 1222 col += 3; 1223 if (i < datalen - 1) { 1224 if (col + 3 > screenwidth) { 1225 printf("\n\t"); 1226 col = 8; 1227 } else 1228 putchar(' '); 1229 } 1230 } 1231 putchar('\n'); 1232 return; 1233 } 1234 if (iohex == 2) { 1235 bpl = (screenwidth - 13)/4; 1236 if (bpl <= 0) 1237 bpl = 1; 1238 for (i = 0; i < datalen; i += bpl) { 1239 printf(" %04x: ", i); 1240 for (j = 0; j < bpl; j++) { 1241 if (i+j >= datalen) 1242 printf(" "); 1243 else 1244 printf("%02x ", dp[i+j]); 1245 } 1246 putchar(' '); 1247 for (j = 0; j < bpl; j++) { 1248 if (i+j >= datalen) 1249 break; 1250 c = dp[i+j]; 1251 if (!isprint(c)) 1252 c = '.'; 1253 putchar(c); 1254 } 1255 putchar('\n'); 1256 } 1257 return; 1258 } 1259 1260 (void)printf(" "); 1261 showbufc(7, dp, datalen, 0); 1262 } 1263 1264 static void 1265 ktrgenio(struct ktr_genio *ktr, size_t len) 1266 { 1267 unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio); 1268 size_t datalen; 1269 1270 if (len < sizeof(struct ktr_genio)) 1271 errx(1, "invalid ktr genio length %zu", len); 1272 1273 datalen = len - sizeof(struct ktr_genio); 1274 1275 printf("fd %d %s %zu bytes\n", ktr->ktr_fd, 1276 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen); 1277 if (maxdata == 0) 1278 return; 1279 if (datalen > maxdata) 1280 datalen = maxdata; 1281 if (iohex && !datalen) 1282 return; 1283 showbuf(dp, datalen); 1284 } 1285 1286 static void 1287 ktrpsig(struct ktr_psig *psig) 1288 { 1289 signame(psig->signo); 1290 printf(" "); 1291 if (psig->action == SIG_DFL) 1292 (void)printf("SIG_DFL"); 1293 else { 1294 (void)printf("caught handler=0x%lx mask=", 1295 (u_long)psig->action); 1296 sigset(psig->mask); 1297 } 1298 if (psig->code) { 1299 printf(" code "); 1300 if (fancy) { 1301 switch (psig->signo) { 1302 case SIGILL: 1303 sigill_name(psig->code); 1304 break; 1305 case SIGTRAP: 1306 sigtrap_name(psig->code); 1307 break; 1308 case SIGEMT: 1309 sigemt_name(psig->code); 1310 break; 1311 case SIGFPE: 1312 sigfpe_name(psig->code); 1313 break; 1314 case SIGBUS: 1315 sigbus_name(psig->code); 1316 break; 1317 case SIGSEGV: 1318 sigsegv_name(psig->code); 1319 break; 1320 case SIGCHLD: 1321 sigchld_name(psig->code); 1322 break; 1323 } 1324 } 1325 printf("<%d>", psig->code); 1326 } 1327 1328 switch (psig->signo) { 1329 case SIGSEGV: 1330 case SIGILL: 1331 case SIGBUS: 1332 case SIGFPE: 1333 printf(" addr=%p trapno=%d", psig->si.si_addr, 1334 psig->si.si_trapno); 1335 break; 1336 default: 1337 break; 1338 } 1339 printf("\n"); 1340 } 1341 1342 static void 1343 ktruser(struct ktr_user *usr, size_t len) 1344 { 1345 if (len < sizeof(struct ktr_user)) 1346 errx(1, "invalid ktr user length %zu", len); 1347 len -= sizeof(struct ktr_user); 1348 printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id); 1349 printf(" %zu bytes\n", len); 1350 showbuf((unsigned char *)(usr + 1), len); 1351 } 1352 1353 static void 1354 ktrexec(const char *ptr, size_t len) 1355 { 1356 int i, col; 1357 size_t l; 1358 1359 putchar('\n'); 1360 i = 0; 1361 while (len > 0) { 1362 l = strnlen(ptr, len); 1363 col = printf("\t[%d] = ", i++); 1364 col += 7; /* tab expands from 1 to 8 columns */ 1365 showbufc(col, (unsigned char *)ptr, l, VIS_DQ|VIS_TAB|VIS_NL); 1366 if (l == len) { 1367 printf("\tunterminated argument\n"); 1368 break; 1369 } 1370 len -= l + 1; 1371 ptr += l + 1; 1372 } 1373 } 1374 1375 static void 1376 ktrpledge(struct ktr_pledge *pledge, size_t len) 1377 { 1378 char *name = ""; 1379 int i; 1380 1381 if (len < sizeof(struct ktr_pledge)) 1382 errx(1, "invalid ktr pledge length %zu", len); 1383 1384 if (pledge->syscall >= SYS_MAXSYSCALL || pledge->syscall < 0) 1385 (void)printf("[%d]", pledge->syscall); 1386 else 1387 (void)printf("%s", syscallnames[pledge->syscall]); 1388 printf(", "); 1389 for (i = 0; pledge->code && pledgenames[i].bits != 0; i++) { 1390 if (pledgenames[i].bits & pledge->code) { 1391 name = pledgenames[i].name; 1392 break; 1393 } 1394 } 1395 printf("\"%s\"", name); 1396 (void)printf(", errno %d", pledge->error); 1397 if (fancy) 1398 (void)printf(" %s", strerror(pledge->error)); 1399 printf("\n"); 1400 } 1401 1402 static void 1403 usage(void) 1404 { 1405 1406 extern char *__progname; 1407 fprintf(stderr, "usage: %s " 1408 "[-dHlnRTXx] [-f file] [-m maxdata] [-p pid] [-t trstr]\n", 1409 __progname); 1410 exit(1); 1411 } 1412 1413 1414 /* 1415 * FORMATTERS 1416 */ 1417 1418 static void 1419 ioctldecode(int cmd) 1420 { 1421 char dirbuf[4], *dir = dirbuf; 1422 const char *cp; 1423 1424 if ((cp = ioctlname((unsigned)cmd)) != NULL) { 1425 (void)printf("%s", cp); 1426 return; 1427 } 1428 1429 if (cmd & IOC_IN) 1430 *dir++ = 'W'; 1431 if (cmd & IOC_OUT) 1432 *dir++ = 'R'; 1433 *dir = '\0'; 1434 1435 printf("_IO%s('%c',%d", 1436 dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff); 1437 if ((cmd & IOC_VOID) == 0) 1438 printf(decimal ? ",%u)" : ",%#x)", (cmd >> 16) & 0xff); 1439 else 1440 printf(")"); 1441 } 1442 1443 static void 1444 ptracedecode(int request) 1445 { 1446 if (request >= 0 && request < nitems(ptrace_ops)) 1447 (void)printf("%s", ptrace_ops[request]); 1448 else switch(request) { 1449 #ifdef PT_GETFPREGS 1450 case PT_GETFPREGS: 1451 (void)printf("PT_GETFPREGS"); 1452 break; 1453 #endif 1454 case PT_GETREGS: 1455 (void)printf("PT_GETREGS"); 1456 break; 1457 #ifdef PT_GETXMMREGS 1458 case PT_GETXMMREGS: 1459 (void)printf("PT_GETXMMREGS"); 1460 break; 1461 #endif 1462 #ifdef PT_SETFPREGS 1463 case PT_SETFPREGS: 1464 (void)printf("PT_SETFPREGS"); 1465 break; 1466 #endif 1467 case PT_SETREGS: 1468 (void)printf("PT_SETREGS"); 1469 break; 1470 #ifdef PT_SETXMMREGS 1471 case PT_SETXMMREGS: 1472 (void)printf("PT_SETXMMREGS"); 1473 break; 1474 #endif 1475 #ifdef PT_STEP 1476 case PT_STEP: 1477 (void)printf("PT_STEP"); 1478 break; 1479 #endif 1480 #ifdef PT_WCOOKIE 1481 case PT_WCOOKIE: 1482 (void)printf("PT_WCOOKIE"); 1483 break; 1484 #endif 1485 default: 1486 pdecint(request); 1487 } 1488 } 1489 1490 1491 static void 1492 atfd(int fd) 1493 { 1494 if (fd == AT_FDCWD) 1495 (void)printf("AT_FDCWD"); 1496 else 1497 pdecint(fd); 1498 } 1499 1500 static void 1501 polltimeout(int timeout) 1502 { 1503 if (timeout == INFTIM) 1504 (void)printf("INFTIM"); 1505 else 1506 pdecint(timeout); 1507 } 1508 1509 static void 1510 wait4pid(int pid) 1511 { 1512 if (pid == WAIT_ANY) 1513 (void)printf("WAIT_ANY"); 1514 else if (pid == WAIT_MYPGRP) 1515 (void)printf("WAIT_MYPGRP"); 1516 else 1517 pdecint(pid); /* ppgid */ 1518 } 1519 1520 static void 1521 signame(int sig) 1522 { 1523 if (sig > 0 && sig < NSIG) 1524 (void)printf("SIG%s", sys_signame[sig]); 1525 else 1526 (void)printf("SIG %d", sig); 1527 } 1528 1529 void 1530 sigset(int ss) 1531 { 1532 int or = 0; 1533 int cnt = 0; 1534 int i; 1535 1536 for (i = 1; i < NSIG; i++) 1537 if (sigismember(&ss, i)) 1538 cnt++; 1539 if (cnt > (NSIG-1)/2) { 1540 ss = ~ss; 1541 putchar('~'); 1542 } 1543 1544 if (ss == 0) { 1545 (void)printf("0<>"); 1546 return; 1547 } 1548 1549 printf("%#x<", ss); 1550 for (i = 1; i < NSIG; i++) 1551 if (sigismember(&ss, i)) { 1552 if (or) putchar('|'); else or=1; 1553 signame(i); 1554 } 1555 printf(">"); 1556 } 1557 1558 static void 1559 semctlname(int cmd) 1560 { 1561 switch (cmd) { 1562 case GETNCNT: 1563 (void)printf("GETNCNT"); 1564 break; 1565 case GETPID: 1566 (void)printf("GETPID"); 1567 break; 1568 case GETVAL: 1569 (void)printf("GETVAL"); 1570 break; 1571 case GETALL: 1572 (void)printf("GETALL"); 1573 break; 1574 case GETZCNT: 1575 (void)printf("GETZCNT"); 1576 break; 1577 case SETVAL: 1578 (void)printf("SETVAL"); 1579 break; 1580 case SETALL: 1581 (void)printf("SETALL"); 1582 break; 1583 case IPC_RMID: 1584 (void)printf("IPC_RMID"); 1585 break; 1586 case IPC_SET: 1587 (void)printf("IPC_SET"); 1588 break; 1589 case IPC_STAT: 1590 (void)printf("IPC_STAT"); 1591 break; 1592 default: /* Should not reach */ 1593 (void)printf("<invalid=%d>", cmd); 1594 } 1595 } 1596 1597 static void 1598 shmctlname(int cmd) 1599 { 1600 switch (cmd) { 1601 case IPC_RMID: 1602 (void)printf("IPC_RMID"); 1603 break; 1604 case IPC_SET: 1605 (void)printf("IPC_SET"); 1606 break; 1607 case IPC_STAT: 1608 (void)printf("IPC_STAT"); 1609 break; 1610 default: /* Should not reach */ 1611 (void)printf("<invalid=%d>", cmd); 1612 } 1613 } 1614 1615 1616 static void 1617 semgetname(int flag) 1618 { 1619 int or = 0; 1620 if_print_or(flag, IPC_CREAT, or); 1621 if_print_or(flag, IPC_EXCL, or); 1622 if_print_or(flag, SEM_R, or); 1623 if_print_or(flag, SEM_A, or); 1624 if_print_or(flag, (SEM_R>>3), or); 1625 if_print_or(flag, (SEM_A>>3), or); 1626 if_print_or(flag, (SEM_R>>6), or); 1627 if_print_or(flag, (SEM_A>>6), or); 1628 1629 if (flag & ~(IPC_CREAT|IPC_EXCL|SEM_R|SEM_A|((SEM_R|SEM_A)>>3)| 1630 ((SEM_R|SEM_A)>>6))) 1631 printf("<invalid=%#x>", flag); 1632 } 1633 1634 1635 /* 1636 * Only used by SYS_open and SYS_openat. Unless O_CREAT is set in flags, the 1637 * mode argument is unused (and often bogus and misleading). 1638 */ 1639 static void 1640 flagsandmodename(int mode) 1641 { 1642 openflagsname(arg1); 1643 if ((arg1 & O_CREAT) == O_CREAT) { 1644 (void)putchar(','); 1645 modename(mode); 1646 } else if (!fancy) 1647 (void)printf(",<unused>%#o", mode); 1648 } 1649 1650 static void 1651 clockname(int clockid) 1652 { 1653 clocktypename(__CLOCK_TYPE(clockid)); 1654 if (__CLOCK_PTID(clockid) != 0) 1655 printf("(%d)", __CLOCK_PTID(clockid)); 1656 } 1657 1658 /* 1659 * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value 1660 * referring to a line in /etc/protocols. 1661 */ 1662 static void 1663 sockoptlevelname(int optname) 1664 { 1665 struct protoent *pe; 1666 1667 if (arg1 == SOL_SOCKET) { 1668 (void)printf("SOL_SOCKET,"); 1669 sockoptname(optname); 1670 } else { 1671 pe = getprotobynumber(arg1); 1672 (void)printf("%u<%s>,%d", arg1, 1673 pe != NULL ? pe->p_name : "unknown", optname); 1674 } 1675 } 1676 1677 static void 1678 ktraceopname(int ops) 1679 { 1680 int invalid = 0; 1681 1682 printf("%#x<", ops); 1683 switch (KTROP(ops)) { 1684 case KTROP_SET: 1685 printf("KTROP_SET"); 1686 break; 1687 case KTROP_CLEAR: 1688 printf("KTROP_CLEAR"); 1689 break; 1690 case KTROP_CLEARFILE: 1691 printf("KTROP_CLEARFILE"); 1692 break; 1693 default: 1694 printf("KTROP(%d)", KTROP(ops)); 1695 invalid = 1; 1696 break; 1697 } 1698 if (ops & KTRFLAG_DESCEND) printf("|KTRFLAG_DESCEND"); 1699 printf(">"); 1700 if (invalid || (ops & ~(KTROP((unsigned)-1) | KTRFLAG_DESCEND))) 1701 (void)printf("<invalid>%d", ops); 1702 } 1703