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