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