1 /* $OpenBSD: kdump.c,v 1.149 2022/07/20 05:56:36 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 [SYS_setgid] = { Gidname }, 822 [SYS_setegid] = { Gidname }, 823 [SYS_seteuid] = { Uidname }, 824 [SYS_pathconf] = { Ppath, Pathconfname }, 825 [SYS_fpathconf] = { Pfd, Pathconfname }, 826 [SYS_swapctl] = { Swapctlname, Pptr, Pdecint }, 827 [SYS_getrlimit] = { Rlimitname, Pptr }, 828 [SYS_setrlimit] = { Rlimitname, Pptr }, 829 [SYS_mmap] = { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, Poff_t, END64 }, 830 [SYS_lseek] = { Pfd, Poff_t, Whencename, END64 }, 831 [SYS_truncate] = { Ppath, Poff_t, END64 }, 832 [SYS_ftruncate] = { Pfd, Poff_t, END64 }, 833 [SYS_sysctl] = { Pptr, Pcount, Pptr, Pptr, Pptr, Psize }, 834 [SYS_mlock] = { Pptr, Pbigsize }, 835 [SYS_munlock] = { Pptr, Pbigsize }, 836 [SYS_getpgid] = { Ppid_t }, 837 [SYS_utrace] = { Pptr, Pptr, Psize }, 838 [SYS_semget] = { Pkey_t, Pcount, Semgetname }, 839 [SYS_msgget] = { Pkey_t, Msgflgname }, 840 [SYS_msgsnd] = { Pmsqid, Pptr, Psize, Msgflgname }, 841 [SYS_msgrcv] = { Pmsqid, Pptr, Psize, Pdeclong, Msgflgname }, 842 [SYS_shmat] = { Pshmid, Pptr, Shmatname }, 843 [SYS_shmdt] = { Pptr }, 844 [SYS_minherit] = { Pptr, Pbigsize, Minheritname }, 845 [SYS_poll] = { Pptr, Pucount, Polltimeout }, 846 [SYS_lchown] = { Ppath, Uidname, Gidname }, 847 [SYS_getsid] = { Ppid_t }, 848 [SYS_msync] = { Pptr, Pbigsize, Msyncflagsname }, 849 [SYS_pipe] = { Pptr }, 850 [SYS_fhopen] = { Pptr, Openflagsname }, 851 [SYS_preadv] = { Pfd, Pptr, Pcount, Poff_t, END64 }, 852 [SYS_pwritev] = { Pfd, Pptr, Pcount, Poff_t, END64 }, 853 [SYS_mlockall] = { Mlockallname }, 854 [SYS_getresuid] = { Pptr, Pptr, Pptr }, 855 [SYS_setresuid] = { Uidname, Uidname, Uidname }, 856 [SYS_getresgid] = { Pptr, Pptr, Pptr }, 857 [SYS_setresgid] = { Gidname, Gidname, Gidname }, 858 [SYS_mquery] = { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, Poff_t, END64 }, 859 [SYS_closefrom] = { Pfd }, 860 [SYS_sigaltstack] = { Pptr, Pptr }, 861 [SYS_shmget] = { Pkey_t, Pbigsize, Semgetname }, 862 [SYS_semop] = { Psemid, Pptr, Psize }, 863 [SYS_fhstat] = { Pptr, Pptr }, 864 [SYS___semctl] = { Psemid, Pcount, Semctlname, Pptr }, 865 [SYS_shmctl] = { Pshmid, Shmctlname, Pptr }, 866 [SYS_msgctl] = { Pmsqid, Shmctlname, Pptr }, 867 [SYS___thrwakeup] = { Pptr, Pcount }, 868 [SYS___threxit] = { Pptr }, 869 [SYS___thrsigdivert] = { Sigset, Pptr, Pptr }, 870 [SYS___getcwd] = { Pptr, Psize }, 871 [SYS_adjfreq] = { Pptr, Pptr }, 872 [SYS_setrtable] = { Pdecint }, 873 [SYS_faccessat] = { Atfd, Ppath, Accessmodename, Atflagsname }, 874 [SYS_fchmodat] = { Atfd, Ppath, Modename, Atflagsname }, 875 [SYS_fchownat] = { Atfd, Ppath, Uidname, Gidname, Atflagsname }, 876 [SYS_linkat] = { Atfd, Ppath, Atfd, Ppath, Atflagsname }, 877 [SYS_mkdirat] = { Atfd, Ppath, Modename }, 878 [SYS_mkfifoat] = { Atfd, Ppath, Modename }, 879 [SYS_mknodat] = { Atfd, Ppath, Modename, Pdev_t }, 880 [SYS_openat] = { Atfd, Ppath, PASS_TWO, Flagsandmodename }, 881 [SYS_readlinkat] = { Atfd, Ppath, Pptr, Psize }, 882 [SYS_renameat] = { Atfd, Ppath, Atfd, Ppath }, 883 [SYS_symlinkat] = { Ppath, Atfd, Ppath }, 884 [SYS_unlinkat] = { Atfd, Ppath, Atflagsname }, 885 [SYS___set_tcb] = { Pptr }, 886 }; 887 888 889 static void 890 ktrsyscall(struct ktr_syscall *ktr, size_t ktrlen) 891 { 892 register_t *ap; 893 int narg; 894 char sep; 895 896 if (ktr->ktr_argsize > ktrlen) 897 errx(1, "syscall argument length %d > ktr header length %zu", 898 ktr->ktr_argsize, ktrlen); 899 900 narg = ktr->ktr_argsize / sizeof(register_t); 901 sep = '\0'; 902 903 if (ktr->ktr_code >= SYS_MAXSYSCALL || ktr->ktr_code < 0) 904 (void)printf("[%d]", ktr->ktr_code); 905 else 906 (void)printf("%s", syscallnames[ktr->ktr_code]); 907 ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall)); 908 (void)putchar('('); 909 910 if (ktr->ktr_code == SYS_sysctl && fancy) { 911 const char *s; 912 int n, i, *top; 913 914 n = ap[1]; 915 if (n > CTL_MAXNAME) 916 n = CTL_MAXNAME; 917 if (n < 0) 918 errx(1, "invalid sysctl length %d", n); 919 if (n > 0) { 920 top = (int *)(ap + 6); 921 printf("%d", top[0]); 922 for (i = 1; i < n; i++) 923 printf(".%d", top[i]); 924 if ((s = kresolvsysctl(0, top)) != NULL) { 925 printf("<%s", s); 926 for (i = 1; i < n; i++) { 927 if ((s = kresolvsysctl(i, top)) != NULL) 928 printf(".%s", s); 929 else 930 printf(".%d", top[i]); 931 } 932 putchar('>'); 933 } 934 } 935 936 sep = ','; 937 ap += 2; 938 narg -= 2; 939 } else if (ktr->ktr_code < nitems(scargs)) { 940 const formatter *fmts = scargs[ktr->ktr_code]; 941 int fmt; 942 int arg = 0; 943 944 while (arg < narg && (fmt = *fmts) != 0) { 945 if (PAD64 && fmt == PASS_LONGLONG && (arg & 1)) 946 goto skip; 947 if (sep) 948 putchar(sep); 949 sep = ','; 950 if (!fancy && !FMT_IS_NONFANCY(fmt)) 951 fmt = Pnonfancy; 952 if (fmt > 0) 953 formatters[fmt]((int)*ap); 954 else if (long_formatters[-fmt](*ap)) 955 sep = '\0'; 956 fmts++; 957 skip: 958 ap++; 959 arg++; 960 } 961 narg -= arg; 962 } 963 964 while (narg > 0) { 965 if (sep) 966 putchar(sep); 967 if (decimal) 968 (void)printf("%ld", (long)*ap); 969 else 970 (void)printf("%#lx", (long)*ap); 971 sep = ','; 972 ap++; 973 narg--; 974 } 975 (void)printf(")\n"); 976 } 977 978 static struct ctlname topname[] = CTL_NAMES; 979 static struct ctlname kernname[] = CTL_KERN_NAMES; 980 static struct ctlname vmname[] = CTL_VM_NAMES; 981 static struct ctlname fsname[] = CTL_FS_NAMES; 982 static struct ctlname netname[] = CTL_NET_NAMES; 983 static struct ctlname hwname[] = CTL_HW_NAMES; 984 static struct ctlname debugname[CTL_DEBUG_MAXID]; 985 static struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES; 986 static struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES; 987 static struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES; 988 static struct ctlname kernprocname[] = { 989 { NULL }, 990 { "all" }, 991 { "pid" }, 992 { "pgrp" }, 993 { "session" }, 994 { "tty" }, 995 { "uid" }, 996 { "ruid" }, 997 { "kthread" }, 998 }; 999 static struct ctlname ttysname[] = CTL_KERN_TTY_NAMES; 1000 static struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES; 1001 static struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES; 1002 static struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES; 1003 static struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES; 1004 #ifdef CTL_MACHDEP_NAMES 1005 static struct ctlname machdepname[] = CTL_MACHDEP_NAMES; 1006 #endif 1007 static struct ctlname ddbname[] = CTL_DDB_NAMES; 1008 1009 #ifndef nitems 1010 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 1011 #endif 1012 1013 #define SETNAME(name) do { names = (name); limit = nitems(name); } while (0) 1014 1015 static const char * 1016 kresolvsysctl(int depth, const int *top) 1017 { 1018 struct ctlname *names; 1019 size_t limit; 1020 int idx = top[depth]; 1021 1022 names = NULL; 1023 1024 switch (depth) { 1025 case 0: 1026 SETNAME(topname); 1027 break; 1028 case 1: 1029 switch (top[0]) { 1030 case CTL_KERN: 1031 SETNAME(kernname); 1032 break; 1033 case CTL_VM: 1034 SETNAME(vmname); 1035 break; 1036 case CTL_FS: 1037 SETNAME(fsname); 1038 break; 1039 case CTL_NET: 1040 SETNAME(netname); 1041 break; 1042 case CTL_DEBUG: 1043 SETNAME(debugname); 1044 break; 1045 case CTL_HW: 1046 SETNAME(hwname); 1047 break; 1048 #ifdef CTL_MACHDEP_NAMES 1049 case CTL_MACHDEP: 1050 SETNAME(machdepname); 1051 break; 1052 #endif 1053 case CTL_DDB: 1054 SETNAME(ddbname); 1055 break; 1056 } 1057 break; 1058 case 2: 1059 switch (top[0]) { 1060 case CTL_KERN: 1061 switch (top[1]) { 1062 case KERN_MALLOCSTATS: 1063 SETNAME(kernmallocname); 1064 break; 1065 case KERN_FORKSTAT: 1066 SETNAME(forkstatname); 1067 break; 1068 case KERN_NCHSTATS: 1069 SETNAME(nchstatsname); 1070 break; 1071 case KERN_TTY: 1072 SETNAME(ttysname); 1073 break; 1074 case KERN_SEMINFO: 1075 SETNAME(semname); 1076 break; 1077 case KERN_SHMINFO: 1078 SETNAME(shmname); 1079 break; 1080 case KERN_WATCHDOG: 1081 SETNAME(watchdogname); 1082 break; 1083 case KERN_PROC: 1084 idx++; /* zero is valid at this level */ 1085 SETNAME(kernprocname); 1086 break; 1087 case KERN_TIMECOUNTER: 1088 SETNAME(tcname); 1089 break; 1090 } 1091 } 1092 break; 1093 } 1094 if (names != NULL && idx > 0 && idx < limit) 1095 return (names[idx].ctl_name); 1096 return (NULL); 1097 } 1098 1099 static void 1100 ktrsysret(struct ktr_sysret *ktr, size_t ktrlen) 1101 { 1102 register_t ret = 0; 1103 long long retll; 1104 int error = ktr->ktr_error; 1105 int code = ktr->ktr_code; 1106 1107 if (ktrlen < sizeof(*ktr)) 1108 errx(1, "sysret length %zu < ktr header length %zu", 1109 ktrlen, sizeof(*ktr)); 1110 ktrlen -= sizeof(*ktr); 1111 if (error == 0) { 1112 if (ktrlen == sizeof(ret)) { 1113 memcpy(&ret, ktr+1, sizeof(ret)); 1114 retll = ret; 1115 } else if (ktrlen == sizeof(retll)) 1116 memcpy(&retll, ktr+1, sizeof(retll)); 1117 else 1118 errx(1, "sysret bogus length %zu", ktrlen); 1119 } 1120 1121 if (code >= SYS_MAXSYSCALL || code < 0) 1122 (void)printf("[%d] ", code); 1123 else 1124 (void)printf("%s ", syscallnames[code]); 1125 1126 doerr: 1127 if (error == 0) { 1128 if (fancy) { 1129 switch (code) { 1130 case SYS_lseek: 1131 (void)printf("%lld", retll); 1132 if (retll < 0 || retll > 9) 1133 (void)printf("/%#llx", retll); 1134 break; 1135 case SYS_sigprocmask: 1136 case SYS_sigpending: 1137 sigset(ret); 1138 break; 1139 case SYS___thrsigdivert: 1140 signame(ret); 1141 break; 1142 case SYS_getuid: 1143 case SYS_geteuid: 1144 uidname(ret); 1145 break; 1146 case SYS_getgid: 1147 case SYS_getegid: 1148 gidname(ret); 1149 break; 1150 /* syscalls that return errno values */ 1151 case SYS_getlogin_r: 1152 case SYS___thrsleep: 1153 if ((error = ret) != 0) 1154 goto doerr; 1155 /* FALLTHROUGH */ 1156 default: 1157 (void)printf("%ld", (long)ret); 1158 if (ret < 0 || ret > 9) 1159 (void)printf("/%#lx", (long)ret); 1160 } 1161 } else { 1162 if (decimal) 1163 (void)printf("%lld", retll); 1164 else 1165 (void)printf("%#llx", retll); 1166 } 1167 } else if (error == ERESTART) 1168 (void)printf("RESTART"); 1169 else if (error == EJUSTRETURN) 1170 (void)printf("JUSTRETURN"); 1171 else { 1172 (void)printf("-1 errno %d", error); 1173 if (fancy) 1174 (void)printf(" %s", strerror(error)); 1175 } 1176 (void)putchar('\n'); 1177 } 1178 1179 static void 1180 ktrnamei(const char *cp, size_t len) 1181 { 1182 showbufc(basecol, (unsigned char *)cp, len, VIS_DQ | VIS_TAB | VIS_NL); 1183 } 1184 1185 void 1186 showbufc(int col, unsigned char *dp, size_t datalen, int flags) 1187 { 1188 int width; 1189 unsigned char visbuf[5], *cp; 1190 1191 flags |= VIS_CSTYLE; 1192 putchar('"'); 1193 col++; 1194 for (; datalen > 0; datalen--, dp++) { 1195 (void)vis(visbuf, *dp, flags, *(dp+1)); 1196 cp = visbuf; 1197 1198 /* 1199 * Keep track of printables and 1200 * space chars (like fold(1)). 1201 */ 1202 if (col == 0) { 1203 (void)putchar('\t'); 1204 col = 8; 1205 } 1206 switch (*cp) { 1207 case '\n': 1208 col = 0; 1209 (void)putchar('\n'); 1210 continue; 1211 case '\t': 1212 width = 8 - (col&07); 1213 break; 1214 default: 1215 width = strlen(cp); 1216 } 1217 if (col + width > (screenwidth-2)) { 1218 (void)printf("\\\n\t"); 1219 col = 8; 1220 } 1221 col += width; 1222 do { 1223 (void)putchar(*cp++); 1224 } while (*cp); 1225 } 1226 if (col == 0) 1227 (void)printf(" "); 1228 (void)printf("\"\n"); 1229 } 1230 1231 static void 1232 showbuf(unsigned char *dp, size_t datalen) 1233 { 1234 int i, j; 1235 int col = 0, bpl; 1236 unsigned char c; 1237 1238 if (iohex == 1) { 1239 putchar('\t'); 1240 col = 8; 1241 for (i = 0; i < datalen; i++) { 1242 printf("%02x", dp[i]); 1243 col += 3; 1244 if (i < datalen - 1) { 1245 if (col + 3 > screenwidth) { 1246 printf("\n\t"); 1247 col = 8; 1248 } else 1249 putchar(' '); 1250 } 1251 } 1252 putchar('\n'); 1253 return; 1254 } 1255 if (iohex == 2) { 1256 bpl = (screenwidth - 13)/4; 1257 if (bpl <= 0) 1258 bpl = 1; 1259 for (i = 0; i < datalen; i += bpl) { 1260 printf(" %04x: ", i); 1261 for (j = 0; j < bpl; j++) { 1262 if (i+j >= datalen) 1263 printf(" "); 1264 else 1265 printf("%02x ", dp[i+j]); 1266 } 1267 putchar(' '); 1268 for (j = 0; j < bpl; j++) { 1269 if (i+j >= datalen) 1270 break; 1271 c = dp[i+j]; 1272 if (!isprint(c)) 1273 c = '.'; 1274 putchar(c); 1275 } 1276 putchar('\n'); 1277 } 1278 return; 1279 } 1280 1281 (void)printf(" "); 1282 showbufc(7, dp, datalen, 0); 1283 } 1284 1285 static void 1286 ktrgenio(struct ktr_genio *ktr, size_t len) 1287 { 1288 unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio); 1289 size_t datalen; 1290 1291 if (len < sizeof(struct ktr_genio)) 1292 errx(1, "invalid ktr genio length %zu", len); 1293 1294 datalen = len - sizeof(struct ktr_genio); 1295 1296 printf("fd %d %s %zu bytes\n", ktr->ktr_fd, 1297 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen); 1298 if (maxdata == 0) 1299 return; 1300 if (datalen > maxdata) 1301 datalen = maxdata; 1302 if (iohex && !datalen) 1303 return; 1304 showbuf(dp, datalen); 1305 } 1306 1307 static void 1308 ktrpsig(struct ktr_psig *psig) 1309 { 1310 signame(psig->signo); 1311 printf(" "); 1312 if (psig->action == SIG_DFL) 1313 (void)printf("SIG_DFL"); 1314 else { 1315 (void)printf("caught handler=0x%lx mask=", 1316 (u_long)psig->action); 1317 sigset(psig->mask); 1318 } 1319 if (psig->code) { 1320 printf(" code "); 1321 if (fancy) { 1322 switch (psig->signo) { 1323 case SIGILL: 1324 sigill_name(psig->code); 1325 break; 1326 case SIGTRAP: 1327 sigtrap_name(psig->code); 1328 break; 1329 case SIGEMT: 1330 sigemt_name(psig->code); 1331 break; 1332 case SIGFPE: 1333 sigfpe_name(psig->code); 1334 break; 1335 case SIGBUS: 1336 sigbus_name(psig->code); 1337 break; 1338 case SIGSEGV: 1339 sigsegv_name(psig->code); 1340 break; 1341 case SIGCHLD: 1342 sigchld_name(psig->code); 1343 break; 1344 } 1345 } 1346 printf("<%d>", psig->code); 1347 } 1348 1349 switch (psig->signo) { 1350 case SIGSEGV: 1351 case SIGILL: 1352 case SIGBUS: 1353 case SIGFPE: 1354 printf(" addr=%p trapno=%d", psig->si.si_addr, 1355 psig->si.si_trapno); 1356 break; 1357 default: 1358 break; 1359 } 1360 printf("\n"); 1361 } 1362 1363 static void 1364 ktruser(struct ktr_user *usr, size_t len) 1365 { 1366 if (len < sizeof(struct ktr_user)) 1367 errx(1, "invalid ktr user length %zu", len); 1368 len -= sizeof(struct ktr_user); 1369 printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id); 1370 printf(" %zu bytes\n", len); 1371 showbuf((unsigned char *)(usr + 1), len); 1372 } 1373 1374 static void 1375 ktrexec(const char *ptr, size_t len) 1376 { 1377 int i, col; 1378 size_t l; 1379 1380 putchar('\n'); 1381 i = 0; 1382 while (len > 0) { 1383 l = strnlen(ptr, len); 1384 col = printf("\t[%d] = ", i++); 1385 col += 7; /* tab expands from 1 to 8 columns */ 1386 showbufc(col, (unsigned char *)ptr, l, VIS_DQ|VIS_TAB|VIS_NL); 1387 if (l == len) { 1388 printf("\tunterminated argument\n"); 1389 break; 1390 } 1391 len -= l + 1; 1392 ptr += l + 1; 1393 } 1394 } 1395 1396 static void 1397 ktrpledge(struct ktr_pledge *pledge, size_t len) 1398 { 1399 const char *name = ""; 1400 int i; 1401 1402 if (len < sizeof(struct ktr_pledge)) 1403 errx(1, "invalid ktr pledge length %zu", len); 1404 1405 if (pledge->syscall >= SYS_MAXSYSCALL || pledge->syscall < 0) 1406 (void)printf("[%d]", pledge->syscall); 1407 else 1408 (void)printf("%s", syscallnames[pledge->syscall]); 1409 printf(", "); 1410 for (i = 0; pledge->code && pledgenames[i].bits != 0; i++) { 1411 if (pledgenames[i].bits & pledge->code) { 1412 name = pledgenames[i].name; 1413 break; 1414 } 1415 } 1416 printf("\"%s\"", name); 1417 (void)printf(", errno %d", pledge->error); 1418 if (fancy) 1419 (void)printf(" %s", strerror(pledge->error)); 1420 printf("\n"); 1421 } 1422 1423 static void 1424 usage(void) 1425 { 1426 1427 extern char *__progname; 1428 fprintf(stderr, "usage: %s " 1429 "[-dHlnRTXx] [-f file] [-m maxdata] [-p pid] [-t trstr]\n", 1430 __progname); 1431 exit(1); 1432 } 1433 1434 1435 /* 1436 * FORMATTERS 1437 */ 1438 1439 static void 1440 ioctldecode(int cmd) 1441 { 1442 char dirbuf[4], *dir = dirbuf; 1443 const char *cp; 1444 1445 if ((cp = ioctlname((unsigned)cmd)) != NULL) { 1446 (void)printf("%s", cp); 1447 return; 1448 } 1449 1450 if (cmd & IOC_IN) 1451 *dir++ = 'W'; 1452 if (cmd & IOC_OUT) 1453 *dir++ = 'R'; 1454 *dir = '\0'; 1455 1456 printf("_IO%s('%c',%d", 1457 dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff); 1458 if ((cmd & IOC_VOID) == 0) 1459 printf(decimal ? ",%u)" : ",%#x)", (cmd >> 16) & 0xff); 1460 else 1461 printf(")"); 1462 } 1463 1464 static void 1465 ptracedecode(int request) 1466 { 1467 if (request >= 0 && request < nitems(ptrace_ops)) 1468 (void)printf("%s", ptrace_ops[request]); 1469 else switch(request) { 1470 #ifdef PT_GETFPREGS 1471 case PT_GETFPREGS: 1472 (void)printf("PT_GETFPREGS"); 1473 break; 1474 #endif 1475 case PT_GETREGS: 1476 (void)printf("PT_GETREGS"); 1477 break; 1478 #ifdef PT_GETXMMREGS 1479 case PT_GETXMMREGS: 1480 (void)printf("PT_GETXMMREGS"); 1481 break; 1482 #endif 1483 #ifdef PT_SETFPREGS 1484 case PT_SETFPREGS: 1485 (void)printf("PT_SETFPREGS"); 1486 break; 1487 #endif 1488 case PT_SETREGS: 1489 (void)printf("PT_SETREGS"); 1490 break; 1491 #ifdef PT_SETXMMREGS 1492 case PT_SETXMMREGS: 1493 (void)printf("PT_SETXMMREGS"); 1494 break; 1495 #endif 1496 #ifdef PT_STEP 1497 case PT_STEP: 1498 (void)printf("PT_STEP"); 1499 break; 1500 #endif 1501 #ifdef PT_WCOOKIE 1502 case PT_WCOOKIE: 1503 (void)printf("PT_WCOOKIE"); 1504 break; 1505 #endif 1506 default: 1507 pdecint(request); 1508 } 1509 } 1510 1511 1512 static void 1513 atfd(int fd) 1514 { 1515 if (fd == AT_FDCWD) 1516 (void)printf("AT_FDCWD"); 1517 else 1518 pdecint(fd); 1519 } 1520 1521 static void 1522 polltimeout(int timeout) 1523 { 1524 if (timeout == INFTIM) 1525 (void)printf("INFTIM"); 1526 else 1527 pdecint(timeout); 1528 } 1529 1530 static void 1531 wait4pid(int pid) 1532 { 1533 if (pid == WAIT_ANY) 1534 (void)printf("WAIT_ANY"); 1535 else if (pid == WAIT_MYPGRP) 1536 (void)printf("WAIT_MYPGRP"); 1537 else 1538 pdecint(pid); /* ppgid */ 1539 } 1540 1541 static void 1542 signame(int sig) 1543 { 1544 if (sig > 0 && sig < NSIG) 1545 (void)printf("SIG%s", sys_signame[sig]); 1546 else 1547 (void)printf("SIG %d", sig); 1548 } 1549 1550 void 1551 sigset(int ss) 1552 { 1553 int or = 0; 1554 int cnt = 0; 1555 int i; 1556 1557 for (i = 1; i < NSIG; i++) 1558 if (sigismember(&ss, i)) 1559 cnt++; 1560 if (cnt > (NSIG-1)/2) { 1561 ss = ~ss; 1562 putchar('~'); 1563 } 1564 1565 if (ss == 0) { 1566 (void)printf("0<>"); 1567 return; 1568 } 1569 1570 printf("%#x<", ss); 1571 for (i = 1; i < NSIG; i++) 1572 if (sigismember(&ss, i)) { 1573 if (or) putchar('|'); else or=1; 1574 signame(i); 1575 } 1576 printf(">"); 1577 } 1578 1579 static void 1580 semctlname(int cmd) 1581 { 1582 switch (cmd) { 1583 case GETNCNT: 1584 (void)printf("GETNCNT"); 1585 break; 1586 case GETPID: 1587 (void)printf("GETPID"); 1588 break; 1589 case GETVAL: 1590 (void)printf("GETVAL"); 1591 break; 1592 case GETALL: 1593 (void)printf("GETALL"); 1594 break; 1595 case GETZCNT: 1596 (void)printf("GETZCNT"); 1597 break; 1598 case SETVAL: 1599 (void)printf("SETVAL"); 1600 break; 1601 case SETALL: 1602 (void)printf("SETALL"); 1603 break; 1604 case IPC_RMID: 1605 (void)printf("IPC_RMID"); 1606 break; 1607 case IPC_SET: 1608 (void)printf("IPC_SET"); 1609 break; 1610 case IPC_STAT: 1611 (void)printf("IPC_STAT"); 1612 break; 1613 default: /* Should not reach */ 1614 (void)printf("<invalid=%d>", cmd); 1615 } 1616 } 1617 1618 static void 1619 shmctlname(int cmd) 1620 { 1621 switch (cmd) { 1622 case IPC_RMID: 1623 (void)printf("IPC_RMID"); 1624 break; 1625 case IPC_SET: 1626 (void)printf("IPC_SET"); 1627 break; 1628 case IPC_STAT: 1629 (void)printf("IPC_STAT"); 1630 break; 1631 default: /* Should not reach */ 1632 (void)printf("<invalid=%d>", cmd); 1633 } 1634 } 1635 1636 1637 static void 1638 semgetname(int flag) 1639 { 1640 int or = 0; 1641 if_print_or(flag, IPC_CREAT, or); 1642 if_print_or(flag, IPC_EXCL, or); 1643 if_print_or(flag, SEM_R, or); 1644 if_print_or(flag, SEM_A, or); 1645 if_print_or(flag, (SEM_R>>3), or); 1646 if_print_or(flag, (SEM_A>>3), or); 1647 if_print_or(flag, (SEM_R>>6), or); 1648 if_print_or(flag, (SEM_A>>6), or); 1649 1650 if (flag & ~(IPC_CREAT|IPC_EXCL|SEM_R|SEM_A|((SEM_R|SEM_A)>>3)| 1651 ((SEM_R|SEM_A)>>6))) 1652 printf("<invalid=%#x>", flag); 1653 } 1654 1655 1656 /* 1657 * Only used by SYS_open and SYS_openat. Unless O_CREAT is set in flags, the 1658 * mode argument is unused (and often bogus and misleading). 1659 */ 1660 static void 1661 flagsandmodename(int mode) 1662 { 1663 openflagsname(arg1); 1664 if ((arg1 & O_CREAT) == O_CREAT) { 1665 (void)putchar(','); 1666 modename(mode); 1667 } else if (!fancy) 1668 (void)printf(",<unused>%#o", mode); 1669 } 1670 1671 static void 1672 clockname(int clockid) 1673 { 1674 clocktypename(__CLOCK_TYPE(clockid)); 1675 if (__CLOCK_PTID(clockid) != 0) 1676 printf("(%d)", __CLOCK_PTID(clockid)); 1677 } 1678 1679 /* 1680 * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value 1681 * referring to a line in /etc/protocols. 1682 */ 1683 static void 1684 sockoptlevelname(int optname) 1685 { 1686 struct protoent *pe; 1687 1688 if (arg1 == SOL_SOCKET) { 1689 (void)printf("SOL_SOCKET,"); 1690 sockoptname(optname); 1691 } else { 1692 pe = getprotobynumber(arg1); 1693 (void)printf("%u<%s>,%d", arg1, 1694 pe != NULL ? pe->p_name : "unknown", optname); 1695 } 1696 } 1697 1698 static void 1699 ktraceopname(int ops) 1700 { 1701 int invalid = 0; 1702 1703 printf("%#x<", ops); 1704 switch (KTROP(ops)) { 1705 case KTROP_SET: 1706 printf("KTROP_SET"); 1707 break; 1708 case KTROP_CLEAR: 1709 printf("KTROP_CLEAR"); 1710 break; 1711 case KTROP_CLEARFILE: 1712 printf("KTROP_CLEARFILE"); 1713 break; 1714 default: 1715 printf("KTROP(%d)", KTROP(ops)); 1716 invalid = 1; 1717 break; 1718 } 1719 if (ops & KTRFLAG_DESCEND) printf("|KTRFLAG_DESCEND"); 1720 printf(">"); 1721 if (invalid || (ops & ~(KTROP((unsigned)-1) | KTRFLAG_DESCEND))) 1722 (void)printf("<invalid>%d", ops); 1723 } 1724