1 /* $OpenBSD: kdump.c,v 1.86 2013/12/21 07:32:35 guenther Exp $ */ 2 3 /*- 4 * Copyright (c) 1988, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/param.h> 33 #include <sys/time.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 _KERNEL 49 #include <errno.h> 50 #undef _KERNEL 51 #include <ddb/db_var.h> 52 #include <machine/cpu.h> 53 54 #include <ctype.h> 55 #include <err.h> 56 #include <fcntl.h> 57 #include <limits.h> 58 #include <poll.h> 59 #include <signal.h> 60 #include <stdio.h> 61 #include <stdlib.h> 62 #include <stdint.h> 63 #include <string.h> 64 #include <unistd.h> 65 #include <vis.h> 66 67 #include "ktrace.h" 68 #include "kdump.h" 69 #include "kdump_subr.h" 70 #include "extern.h" 71 72 int timestamp, decimal, iohex, fancy = 1, maxdata = INT_MAX; 73 int needtid, resolv, tail; 74 char *tracefile = DEF_TRACEFILE; 75 struct ktr_header ktr_header; 76 pid_t pid_opt = -1; 77 78 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 79 80 #include <sys/syscall.h> 81 82 #include <compat/linux/linux_syscall.h> 83 84 #define KTRACE 85 #define PTRACE 86 #define NFSCLIENT 87 #define NFSSERVER 88 #define SYSVSEM 89 #define SYSVMSG 90 #define SYSVSHM 91 #define LFS 92 #include <kern/syscalls.c> 93 94 #include <compat/linux/linux_syscalls.c> 95 #undef KTRACE 96 #undef PTRACE 97 #undef NFSCLIENT 98 #undef NFSSERVER 99 #undef SYSVSEM 100 #undef SYSVMSG 101 #undef SYSVSHM 102 #undef LFS 103 104 struct emulation { 105 char *name; /* Emulation name */ 106 char **sysnames; /* Array of system call names */ 107 int nsysnames; /* Number of */ 108 }; 109 110 static struct emulation emulations[] = { 111 { "native", syscallnames, SYS_MAXSYSCALL }, 112 { "linux", linux_syscallnames, LINUX_SYS_MAXSYSCALL }, 113 { NULL, NULL, 0 } 114 }; 115 116 static struct emulation *current; 117 static struct emulation *def_emul; 118 119 struct pid_emul { 120 struct emulation *e; 121 pid_t p; 122 }; 123 124 static struct pid_emul *pe_table; 125 static size_t pe_size; 126 127 128 static char *ptrace_ops[] = { 129 "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U", 130 "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE", 131 "PT_KILL", "PT_ATTACH", "PT_DETACH", "PT_IO", 132 "PT_SET_EVENT_MASK", "PT_GET_EVENT_MASK", "PT_GET_PROCESS_STATE", 133 "PT_GET_THREAD_FIRST", "PT_GET_THREAD_NEXT", 134 }; 135 136 static int narg; 137 static register_t *ap; 138 static char sep; 139 140 static void mappidtoemul(pid_t, struct emulation *); 141 static struct emulation * findemul(pid_t); 142 static int fread_tail(void *, size_t, size_t); 143 static void dumpheader(struct ktr_header *); 144 static void ktrcsw(struct ktr_csw *); 145 static void ktremul(char *, size_t); 146 static void ktrgenio(struct ktr_genio *, size_t); 147 static void ktrnamei(const char *, size_t); 148 static void ktrpsig(struct ktr_psig *); 149 static void ktrsyscall(struct ktr_syscall *); 150 static const char *kresolvsysctl(int, int *, int); 151 static void ktrsysret(struct ktr_sysret *); 152 static void ktruser(struct ktr_user *, size_t); 153 static void setemul(const char *); 154 static void usage(void); 155 static void atfd(int); 156 static void polltimeout(int); 157 static void pgid(int); 158 static void wait4pid(int); 159 static void signame(int); 160 static void semctlname(int); 161 static void shmctlname(int); 162 static void semgetname(int); 163 static void flagsandmodename(int, int); 164 static void clockname(int); 165 static void sockoptlevelname(int); 166 167 int 168 main(int argc, char *argv[]) 169 { 170 int ch, silent; 171 size_t ktrlen, size; 172 int trpoints = ALL_POINTS; 173 void *m; 174 175 def_emul = current = &emulations[0]; /* native */ 176 177 while ((ch = getopt(argc, argv, "e:f:dHlm:nrRp:Tt:xX")) != -1) 178 switch (ch) { 179 case 'e': 180 setemul(optarg); 181 def_emul = current; 182 break; 183 case 'f': 184 tracefile = optarg; 185 break; 186 case 'd': 187 decimal = 1; 188 break; 189 case 'H': 190 needtid = 1; 191 break; 192 case 'l': 193 tail = 1; 194 break; 195 case 'm': 196 maxdata = atoi(optarg); 197 break; 198 case 'n': 199 fancy = 0; 200 break; 201 case 'p': 202 pid_opt = atoi(optarg); 203 break; 204 case 'r': 205 resolv = 1; 206 break; 207 case 'R': 208 timestamp = 2; /* relative timestamp */ 209 break; 210 case 'T': 211 timestamp = 1; 212 break; 213 case 't': 214 trpoints = getpoints(optarg); 215 if (trpoints < 0) 216 errx(1, "unknown trace point in %s", optarg); 217 break; 218 case 'x': 219 iohex = 1; 220 break; 221 case 'X': 222 iohex = 2; 223 break; 224 default: 225 usage(); 226 } 227 if (argc > optind) 228 usage(); 229 230 m = malloc(size = 1025); 231 if (m == NULL) 232 err(1, NULL); 233 if (!freopen(tracefile, "r", stdin)) 234 err(1, "%s", tracefile); 235 if (fread_tail(&ktr_header, sizeof(struct ktr_header), 1) == 0 || 236 ktr_header.ktr_type != htobe32(KTR_START)) 237 errx(1, "%s: not a dump", tracefile); 238 while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 239 silent = 0; 240 if (pe_size == 0) 241 mappidtoemul(ktr_header.ktr_pid, current); 242 if (pid_opt != -1 && pid_opt != ktr_header.ktr_pid) 243 silent = 1; 244 if (silent == 0 && trpoints & (1<<ktr_header.ktr_type)) 245 dumpheader(&ktr_header); 246 ktrlen = ktr_header.ktr_len; 247 if (ktrlen > size) { 248 void *newm; 249 250 if (ktrlen == SIZE_MAX) 251 errx(1, "data too long"); 252 newm = realloc(m, ktrlen+1); 253 if (newm == NULL) 254 err(1, "realloc"); 255 m = newm; 256 size = ktrlen; 257 } 258 if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 259 errx(1, "data too short"); 260 if (silent) 261 continue; 262 if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 263 continue; 264 current = findemul(ktr_header.ktr_pid); 265 switch (ktr_header.ktr_type) { 266 case KTR_SYSCALL: 267 ktrsyscall((struct ktr_syscall *)m); 268 break; 269 case KTR_SYSRET: 270 ktrsysret((struct ktr_sysret *)m); 271 break; 272 case KTR_NAMEI: 273 ktrnamei(m, ktrlen); 274 break; 275 case KTR_GENIO: 276 ktrgenio((struct ktr_genio *)m, ktrlen); 277 break; 278 case KTR_PSIG: 279 ktrpsig((struct ktr_psig *)m); 280 break; 281 case KTR_CSW: 282 ktrcsw((struct ktr_csw *)m); 283 break; 284 case KTR_EMUL: 285 ktremul(m, ktrlen); 286 mappidtoemul(ktr_header.ktr_pid, current); 287 break; 288 case KTR_STRUCT: 289 ktrstruct(m, ktrlen); 290 break; 291 case KTR_USER: 292 ktruser(m, ktrlen); 293 break; 294 } 295 if (tail) 296 (void)fflush(stdout); 297 } 298 exit(0); 299 } 300 301 static void 302 mappidtoemul(pid_t pid, struct emulation *emul) 303 { 304 size_t i; 305 struct pid_emul *tmp; 306 307 for (i = 0; i < pe_size; i++) { 308 if (pe_table[i].p == pid) { 309 pe_table[i].e = emul; 310 return; 311 } 312 } 313 tmp = realloc(pe_table, (pe_size + 1) * sizeof(*pe_table)); 314 if (tmp == NULL) 315 err(1, NULL); 316 pe_table = tmp; 317 pe_table[pe_size].p = pid; 318 pe_table[pe_size].e = emul; 319 pe_size++; 320 } 321 322 static struct emulation* 323 findemul(pid_t pid) 324 { 325 size_t i; 326 327 for (i = 0; i < pe_size; i++) 328 if (pe_table[i].p == pid) 329 return pe_table[i].e; 330 return def_emul; 331 } 332 333 static int 334 fread_tail(void *buf, size_t size, size_t num) 335 { 336 int i; 337 338 while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 339 (void)sleep(1); 340 clearerr(stdin); 341 } 342 return (i); 343 } 344 345 static void 346 dumpheader(struct ktr_header *kth) 347 { 348 static struct timespec prevtime; 349 char unknown[64], *type; 350 struct timespec temp; 351 352 switch (kth->ktr_type) { 353 case KTR_SYSCALL: 354 type = "CALL"; 355 break; 356 case KTR_SYSRET: 357 type = "RET "; 358 break; 359 case KTR_NAMEI: 360 type = "NAMI"; 361 break; 362 case KTR_GENIO: 363 type = "GIO "; 364 break; 365 case KTR_PSIG: 366 type = "PSIG"; 367 break; 368 case KTR_CSW: 369 type = "CSW"; 370 break; 371 case KTR_EMUL: 372 type = "EMUL"; 373 break; 374 case KTR_STRUCT: 375 type = "STRU"; 376 break; 377 case KTR_USER: 378 type = "USER"; 379 break; 380 default: 381 (void)snprintf(unknown, sizeof unknown, "UNKNOWN(%d)", 382 kth->ktr_type); 383 type = unknown; 384 } 385 386 (void)printf("%6ld", (long)kth->ktr_pid); 387 if (needtid) 388 (void)printf("/%-7ld", (long)kth->ktr_tid); 389 (void)printf(" %-8.*s ", MAXCOMLEN, kth->ktr_comm); 390 if (timestamp) { 391 if (timestamp == 2) { 392 timespecsub(&kth->ktr_time, &prevtime, &temp); 393 prevtime = kth->ktr_time; 394 } else 395 temp = kth->ktr_time; 396 printf("%lld.%06ld ", (long long)temp.tv_sec, 397 temp.tv_nsec / 1000); 398 } 399 (void)printf("%s ", type); 400 } 401 402 static void 403 ioctldecode(u_long cmd) 404 { 405 char dirbuf[4], *dir = dirbuf; 406 407 if (cmd & IOC_IN) 408 *dir++ = 'W'; 409 if (cmd & IOC_OUT) 410 *dir++ = 'R'; 411 *dir = '\0'; 412 413 printf(decimal ? ",_IO%s('%c',%lu" : ",_IO%s('%c',%#lx", 414 dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff); 415 if ((cmd & IOC_VOID) == 0) 416 printf(decimal ? ",%lu)" : ",%#lx)", (cmd >> 16) & 0xff); 417 else 418 printf(")"); 419 } 420 421 static void 422 ptracedecode(void) 423 { 424 if (*ap >= 0 && *ap < 425 sizeof(ptrace_ops) / sizeof(ptrace_ops[0])) 426 (void)printf("%s", ptrace_ops[*ap]); 427 else switch(*ap) { 428 #ifdef PT_GETFPREGS 429 case PT_GETFPREGS: 430 (void)printf("PT_GETFPREGS"); 431 break; 432 #endif 433 case PT_GETREGS: 434 (void)printf("PT_GETREGS"); 435 break; 436 #ifdef PT_GETXMMREGS 437 case PT_GETXMMREGS: 438 (void)printf("PT_GETXMMREGS"); 439 break; 440 #endif 441 #ifdef PT_SETFPREGS 442 case PT_SETFPREGS: 443 (void)printf("PT_SETFPREGS"); 444 break; 445 #endif 446 case PT_SETREGS: 447 (void)printf("PT_SETREGS"); 448 break; 449 #ifdef PT_SETXMMREGS 450 case PT_SETXMMREGS: 451 (void)printf("PT_SETXMMREGS"); 452 break; 453 #endif 454 #ifdef PT_STEP 455 case PT_STEP: 456 (void)printf("PT_STEP"); 457 break; 458 #endif 459 #ifdef PT_WCOOKIE 460 case PT_WCOOKIE: 461 (void)printf("PT_WCOOKIE"); 462 break; 463 #endif 464 default: 465 (void)printf("%ld", (long)*ap); 466 break; 467 } 468 sep = ','; 469 ap++; 470 narg--; 471 } 472 473 static void 474 pn(void (*f)(int)) 475 { 476 if (sep) 477 (void)putchar(sep); 478 if (fancy && f != NULL) 479 f((int)*ap); 480 else if (decimal) 481 (void)printf("%ld", (long)*ap); 482 else 483 (void)printf("%#lx", (long)*ap); 484 ap++; 485 narg--; 486 sep = ','; 487 } 488 489 #ifdef __LP64__ 490 #define plln() pn(NULL) 491 #elif _BYTE_ORDER == _LITTLE_ENDIAN 492 static void 493 plln(void) 494 { 495 long long val = ((long long)*ap) & 0xffffffff; 496 ap++; 497 val |= ((long long)*ap) << 32; 498 ap++; 499 narg -= 2; 500 if (sep) 501 (void)putchar(sep); 502 if (decimal) 503 (void)printf("%lld", val); 504 else 505 (void)printf("%#llx", val); 506 sep = ','; 507 } 508 #else 509 static void 510 plln(void) 511 { 512 long long val = ((long long)*ap) << 32; 513 ap++; 514 val |= ((long long)*ap) & 0xffffffff; 515 ap++; 516 narg -= 2; 517 if (sep) 518 (void)putchar(sep); 519 if (decimal) 520 (void)printf("%lld", val); 521 else 522 (void)printf("%#llx", val); 523 sep = ','; 524 } 525 #endif 526 527 static void 528 ktrsyscall(struct ktr_syscall *ktr) 529 { 530 narg = ktr->ktr_argsize / sizeof(register_t); 531 sep = '\0'; 532 533 if (ktr->ktr_code >= current->nsysnames || ktr->ktr_code < 0) 534 (void)printf("[%d]", ktr->ktr_code); 535 else 536 (void)printf("%s", current->sysnames[ktr->ktr_code]); 537 ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall)); 538 (void)putchar('('); 539 540 if (current != &emulations[0]) 541 goto nonnative; 542 543 switch (ktr->ktr_code) { 544 case SYS_ioctl: { 545 const char *cp; 546 547 pn(NULL); 548 if (!fancy) 549 break; 550 if ((cp = ioctlname(*ap)) != NULL) 551 (void)printf(",%s", cp); 552 else 553 ioctldecode(*ap); 554 ap++; 555 narg--; 556 break; 557 } 558 case SYS___sysctl: { 559 const char *s; 560 int *np, n, i, *top; 561 562 if (!fancy) 563 break; 564 n = ap[1]; 565 if (n > CTL_MAXNAME) 566 n = CTL_MAXNAME; 567 np = top = (int *)(ap + 6); 568 for (i = 0; n--; np++, i++) { 569 if (sep) 570 putchar(sep); 571 if (resolv && (s = kresolvsysctl(i, top, *np)) != NULL) 572 printf("%s", s); 573 else 574 printf("%d", *np); 575 sep = '.'; 576 } 577 578 sep = ','; 579 ap += 2; 580 narg -= 2; 581 break; 582 } 583 case SYS_ptrace: 584 if (!fancy) 585 break; 586 ptracedecode(); 587 break; 588 case SYS_access: 589 pn(NULL); 590 pn(accessmodename); 591 break; 592 case SYS_chmod: 593 case SYS_fchmod: 594 pn(NULL); 595 pn(modename); 596 break; 597 case SYS_fcntl: { 598 int cmd; 599 int arg; 600 pn(NULL); 601 if (!fancy) 602 break; 603 cmd = ap[0]; 604 arg = ap[1]; 605 (void)putchar(','); 606 fcntlcmdname(cmd, arg); 607 ap += 2; 608 narg -= 2; 609 break; 610 } 611 case SYS_flock: 612 pn(NULL); 613 pn(flockname); 614 break; 615 case SYS_getrlimit: 616 case SYS_setrlimit: 617 pn(rlimitname); 618 break; 619 case SYS_getsockopt: 620 case SYS_setsockopt: { 621 int level; 622 623 pn(NULL); 624 level = *ap; 625 pn(sockoptlevelname); 626 if (level == SOL_SOCKET) 627 pn(sockoptname); 628 break; 629 } 630 case SYS_kill: 631 pn(pgid); 632 pn(signame); 633 break; 634 case SYS_lseek: 635 pn(NULL); 636 /* skip padding */ 637 ap++; 638 narg--; 639 plln(); 640 pn(whencename); 641 break; 642 case SYS_madvise: 643 pn(NULL); 644 pn(NULL); 645 pn(madvisebehavname); 646 break; 647 case SYS_minherit: 648 pn(NULL); 649 pn(NULL); 650 pn(minheritname); 651 break; 652 case SYS_mlockall: 653 pn(mlockallname); 654 break; 655 case SYS_mmap: 656 pn(NULL); 657 pn(NULL); 658 pn(mmapprotname); 659 pn(mmapflagsname); 660 pn(NULL); 661 /* skip padding */ 662 ap++; 663 narg--; 664 plln(); 665 break; 666 case SYS_mprotect: 667 pn(NULL); 668 pn(NULL); 669 pn(mmapprotname); 670 break; 671 case SYS_mquery: 672 pn(NULL); 673 pn(NULL); 674 pn(mmapprotname); 675 pn(mmapflagsname); 676 pn(NULL); 677 /* skip padding */ 678 ap++; 679 narg--; 680 plln(); 681 break; 682 case SYS_msync: 683 pn(NULL); 684 pn(NULL); 685 pn(msyncflagsname); 686 break; 687 case SYS_msgctl: 688 pn(NULL); 689 pn(shmctlname); 690 break; 691 case SYS_open: { 692 int flags; 693 int mode; 694 695 pn(NULL); 696 if (!fancy) 697 break; 698 flags = ap[0]; 699 mode = ap[1]; 700 (void)putchar(','); 701 flagsandmodename(flags, mode); 702 ap += 2; 703 narg -= 2; 704 break; 705 } 706 case SYS_pread: 707 case SYS_preadv: 708 case SYS_pwrite: 709 case SYS_pwritev: 710 pn(NULL); 711 pn(NULL); 712 pn(NULL); 713 /* skip padding */ 714 ap++; 715 narg--; 716 plln(); 717 break; 718 case SYS_recvmsg: 719 case SYS_sendmsg: 720 pn(NULL); 721 pn(NULL); 722 pn(sendrecvflagsname); 723 break; 724 case SYS_recvfrom: 725 case SYS_sendto: 726 pn(NULL); 727 pn(NULL); 728 pn(NULL); 729 pn(sendrecvflagsname); 730 break; 731 case SYS_shutdown: 732 pn(NULL); 733 pn(shutdownhowname); 734 break; 735 case SYS___semctl: 736 pn(NULL); 737 pn(NULL); 738 pn(semctlname); 739 break; 740 case SYS_semget: 741 pn(NULL); 742 pn(NULL); 743 pn(semgetname); 744 break; 745 case SYS_shmat: 746 pn(NULL); 747 pn(NULL); 748 pn(shmatname); 749 break; 750 case SYS_shmctl: 751 pn(NULL); 752 pn(shmctlname); 753 break; 754 case SYS_clock_gettime: 755 case SYS_clock_settime: 756 case SYS_clock_getres: 757 pn(clockname); 758 break; 759 case SYS_poll: 760 pn(NULL); 761 pn(NULL); 762 pn(polltimeout); 763 break; 764 case SYS_sigaction: 765 pn(signame); 766 break; 767 case SYS_sigprocmask: 768 pn(sigprocmaskhowname); 769 pn(sigset); 770 break; 771 case SYS_sigsuspend: 772 pn(sigset); 773 break; 774 case SYS_socket: { 775 int sockdomain = *ap; 776 777 pn(sockdomainname); 778 pn(socktypename); 779 if (sockdomain == PF_INET || sockdomain == PF_INET6) 780 pn(sockipprotoname); 781 break; 782 } 783 case SYS_socketpair: 784 pn(sockdomainname); 785 pn(socktypename); 786 break; 787 case SYS_truncate: 788 case SYS_ftruncate: 789 pn(NULL); 790 /* skip padding */ 791 ap++; 792 narg--; 793 plln(); 794 break; 795 case SYS_wait4: 796 pn(wait4pid); 797 pn(NULL); 798 pn(wait4optname); 799 break; 800 case SYS_getrusage: 801 pn(rusagewho); 802 break; 803 case SYS___thrsleep: 804 pn(NULL); 805 pn(clockname); 806 break; 807 case SYS___thrsigdivert: 808 pn(sigset); 809 break; 810 case SYS_faccessat: 811 pn(atfd); 812 pn(NULL); 813 pn(accessmodename); 814 pn(atflagsname); 815 break; 816 case SYS_fchmodat: 817 pn(atfd); 818 pn(NULL); 819 pn(modename); 820 pn(atflagsname); 821 break; 822 case SYS_fchownat: 823 pn(atfd); 824 pn(NULL); 825 pn(NULL); 826 pn(NULL); 827 pn(atflagsname); 828 break; 829 case SYS_fstatat: 830 pn(atfd); 831 pn(NULL); 832 pn(NULL); 833 pn(atflagsname); 834 break; 835 case SYS_linkat: 836 pn(atfd); 837 pn(NULL); 838 pn(atfd); 839 pn(NULL); 840 pn(atflagsname); 841 break; 842 case SYS_mkdirat: 843 case SYS_mkfifoat: 844 case SYS_mknodat: 845 pn(atfd); 846 pn(NULL); 847 pn(modename); 848 break; 849 case SYS_openat: { 850 int flags; 851 int mode; 852 853 pn(atfd); 854 pn(NULL); 855 if (!fancy) 856 break; 857 flags = ap[0]; 858 mode = ap[1]; 859 (void)putchar(','); 860 flagsandmodename(flags, mode); 861 ap += 2; 862 narg -= 2; 863 break; 864 } 865 case SYS_readlinkat: 866 pn(atfd); 867 break; 868 case SYS_renameat: 869 pn(atfd); 870 pn(NULL); 871 pn(atfd); 872 break; 873 case SYS_symlinkat: 874 pn(NULL); 875 pn(atfd); 876 break; 877 case SYS_unlinkat: 878 pn(atfd); 879 pn(NULL); 880 pn(atflagsname); 881 break; 882 case SYS_utimensat: 883 pn(atfd); 884 pn(NULL); 885 pn(NULL); 886 pn(atflagsname); 887 break; 888 case SYS_pathconf: 889 case SYS_fpathconf: 890 pn(NULL); 891 pn(pathconfname); 892 break; 893 case SYS_ktrace: 894 pn(NULL); 895 pn(NULL); 896 pn(ktracefacname); 897 pn(pgid); 898 break; 899 case SYS_setitimer: 900 case SYS_getitimer: 901 pn(itimername); 902 break; 903 } 904 905 nonnative: 906 while (narg) { 907 if (sep) 908 putchar(sep); 909 if (decimal) 910 (void)printf("%ld", (long)*ap); 911 else 912 (void)printf("%#lx", (long)*ap); 913 sep = ','; 914 ap++; 915 narg--; 916 } 917 (void)printf(")\n"); 918 } 919 920 static struct ctlname topname[] = CTL_NAMES; 921 static struct ctlname kernname[] = CTL_KERN_NAMES; 922 static struct ctlname vmname[] = CTL_VM_NAMES; 923 static struct ctlname fsname[] = CTL_FS_NAMES; 924 static struct ctlname netname[] = CTL_NET_NAMES; 925 static struct ctlname hwname[] = CTL_HW_NAMES; 926 static struct ctlname debugname[CTL_DEBUG_MAXID]; 927 static struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES; 928 static struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES; 929 static struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES; 930 static struct ctlname kernprocname[] = 931 { 932 { NULL }, 933 { "all" }, 934 { "pid" }, 935 { "pgrp" }, 936 { "session" }, 937 { "tty" }, 938 { "uid" }, 939 { "ruid" }, 940 { "kthread" }, 941 }; 942 static struct ctlname ttysname[] = CTL_KERN_TTY_NAMES; 943 static struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES; 944 static struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES; 945 static struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES; 946 static struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES; 947 #ifdef CTL_MACHDEP_NAMES 948 static struct ctlname machdepname[] = CTL_MACHDEP_NAMES; 949 #endif 950 static struct ctlname ddbname[] = CTL_DDB_NAMES; 951 952 #ifndef nitems 953 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 954 #endif 955 956 #define SETNAME(name) do { names = (name); limit = nitems(name); } while (0) 957 958 static const char * 959 kresolvsysctl(int depth, int *top, int idx) 960 { 961 struct ctlname *names; 962 size_t limit; 963 964 names = NULL; 965 966 switch (depth) { 967 case 0: 968 SETNAME(topname); 969 break; 970 case 1: 971 switch (top[0]) { 972 case CTL_KERN: 973 SETNAME(kernname); 974 break; 975 case CTL_VM: 976 SETNAME(vmname); 977 break; 978 case CTL_FS: 979 SETNAME(fsname); 980 break; 981 case CTL_NET: 982 SETNAME(netname); 983 break; 984 case CTL_DEBUG: 985 SETNAME(debugname); 986 break; 987 case CTL_HW: 988 SETNAME(hwname); 989 break; 990 #ifdef CTL_MACHDEP_NAMES 991 case CTL_MACHDEP: 992 SETNAME(machdepname); 993 break; 994 #endif 995 case CTL_DDB: 996 SETNAME(ddbname); 997 break; 998 } 999 break; 1000 case 2: 1001 switch (top[0]) { 1002 case CTL_KERN: 1003 switch (top[1]) { 1004 case KERN_MALLOCSTATS: 1005 SETNAME(kernmallocname); 1006 break; 1007 case KERN_FORKSTAT: 1008 SETNAME(forkstatname); 1009 break; 1010 case KERN_NCHSTATS: 1011 SETNAME(nchstatsname); 1012 break; 1013 case KERN_TTY: 1014 SETNAME(ttysname); 1015 break; 1016 case KERN_SEMINFO: 1017 SETNAME(semname); 1018 break; 1019 case KERN_SHMINFO: 1020 SETNAME(shmname); 1021 break; 1022 case KERN_WATCHDOG: 1023 SETNAME(watchdogname); 1024 break; 1025 case KERN_PROC: 1026 idx++; /* zero is valid at this level */ 1027 SETNAME(kernprocname); 1028 break; 1029 case KERN_TIMECOUNTER: 1030 SETNAME(tcname); 1031 break; 1032 } 1033 } 1034 break; 1035 } 1036 if (names != NULL && idx > 0 && idx < limit) 1037 return (names[idx].ctl_name); 1038 return (NULL); 1039 } 1040 1041 static void 1042 ktrsysret(struct ktr_sysret *ktr) 1043 { 1044 register_t ret = ktr->ktr_retval; 1045 int error = ktr->ktr_error; 1046 int code = ktr->ktr_code; 1047 1048 if (code >= current->nsysnames || code < 0) 1049 (void)printf("[%d] ", code); 1050 else { 1051 (void)printf("%s ", current->sysnames[code]); 1052 if (ret > 0 && (strcmp(current->sysnames[code], "fork") == 0 || 1053 strcmp(current->sysnames[code], "vfork") == 0 || 1054 strcmp(current->sysnames[code], "__tfork") == 0 || 1055 strcmp(current->sysnames[code], "clone") == 0)) 1056 mappidtoemul(ret, current); 1057 } 1058 1059 if (error == 0) { 1060 if (fancy) { 1061 switch (current == &emulations[0] ? code : -1) { 1062 case SYS_sigprocmask: 1063 case SYS_sigpending: 1064 sigset(ret); 1065 break; 1066 case SYS___thrsigdivert: 1067 signame(ret); 1068 break; 1069 case -1: /* non-default emulation */ 1070 default: 1071 (void)printf("%ld", (long)ret); 1072 if (ret < 0 || ret > 9) 1073 (void)printf("/%#lx", (long)ret); 1074 } 1075 } else { 1076 if (decimal) 1077 (void)printf("%ld", (long)ret); 1078 else 1079 (void)printf("%#lx", (long)ret); 1080 } 1081 } else if (error == ERESTART) 1082 (void)printf("RESTART"); 1083 else if (error == EJUSTRETURN) 1084 (void)printf("JUSTRETURN"); 1085 else { 1086 (void)printf("-1 errno %d", ktr->ktr_error); 1087 if (fancy) 1088 (void)printf(" %s", strerror(ktr->ktr_error)); 1089 } 1090 (void)putchar('\n'); 1091 } 1092 1093 static void 1094 ktrnamei(const char *cp, size_t len) 1095 { 1096 (void)printf("\"%.*s\"\n", (int)len, cp); 1097 } 1098 1099 static void 1100 ktremul(char *cp, size_t len) 1101 { 1102 char name[1024]; 1103 1104 if (len >= sizeof(name)) 1105 errx(1, "Emulation name too long"); 1106 1107 strncpy(name, cp, len); 1108 name[len] = '\0'; 1109 (void)printf("\"%s\"\n", name); 1110 1111 setemul(name); 1112 } 1113 1114 static void 1115 showbuf(unsigned char *dp, size_t datalen) 1116 { 1117 int i, j; 1118 static int screenwidth; 1119 int col = 0, width, bpl; 1120 unsigned char visbuf[5], *cp, c; 1121 1122 if (screenwidth == 0) { 1123 struct winsize ws; 1124 1125 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 1126 ws.ws_col > 8) 1127 screenwidth = ws.ws_col; 1128 else 1129 screenwidth = 80; 1130 } 1131 if (iohex == 1) { 1132 putchar('\t'); 1133 col = 8; 1134 for (i = 0; i < datalen; i++) { 1135 printf("%02x", dp[i]); 1136 col += 3; 1137 if (i < datalen - 1) { 1138 if (col + 3 > screenwidth) { 1139 printf("\n\t"); 1140 col = 8; 1141 } else 1142 putchar(' '); 1143 } 1144 } 1145 putchar('\n'); 1146 return; 1147 } 1148 if (iohex == 2) { 1149 bpl = (screenwidth - 13)/4; 1150 if (bpl <= 0) 1151 bpl = 1; 1152 for (i = 0; i < datalen; i += bpl) { 1153 printf(" %04x: ", i); 1154 for (j = 0; j < bpl; j++) { 1155 if (i+j >= datalen) 1156 printf(" "); 1157 else 1158 printf("%02x ", dp[i+j]); 1159 } 1160 putchar(' '); 1161 for (j = 0; j < bpl; j++) { 1162 if (i+j >= datalen) 1163 break; 1164 c = dp[i+j]; 1165 if (!isprint(c)) 1166 c = '.'; 1167 putchar(c); 1168 } 1169 putchar('\n'); 1170 } 1171 return; 1172 } 1173 (void)printf(" \""); 1174 col = 8; 1175 for (; datalen > 0; datalen--, dp++) { 1176 (void)vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 1177 cp = visbuf; 1178 1179 /* 1180 * Keep track of printables and 1181 * space chars (like fold(1)). 1182 */ 1183 if (col == 0) { 1184 (void)putchar('\t'); 1185 col = 8; 1186 } 1187 switch (*cp) { 1188 case '\n': 1189 col = 0; 1190 (void)putchar('\n'); 1191 continue; 1192 case '\t': 1193 width = 8 - (col&07); 1194 break; 1195 default: 1196 width = strlen(cp); 1197 } 1198 if (col + width > (screenwidth-2)) { 1199 (void)printf("\\\n\t"); 1200 col = 8; 1201 } 1202 col += width; 1203 do { 1204 (void)putchar(*cp++); 1205 } while (*cp); 1206 } 1207 if (col == 0) 1208 (void)printf(" "); 1209 (void)printf("\"\n"); 1210 } 1211 1212 static void 1213 ktrgenio(struct ktr_genio *ktr, size_t len) 1214 { 1215 unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio); 1216 size_t datalen = len - sizeof(struct ktr_genio); 1217 1218 printf("fd %d %s %zu bytes\n", ktr->ktr_fd, 1219 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen); 1220 if (maxdata == 0) 1221 return; 1222 if (datalen > maxdata) 1223 datalen = maxdata; 1224 if (iohex && !datalen) 1225 return; 1226 showbuf(dp, datalen); 1227 } 1228 1229 static void 1230 ktrpsig(struct ktr_psig *psig) 1231 { 1232 (void)printf("SIG%s ", sys_signame[psig->signo]); 1233 if (psig->action == SIG_DFL) 1234 (void)printf("SIG_DFL"); 1235 else { 1236 (void)printf("caught handler=0x%lx mask=", 1237 (u_long)psig->action); 1238 sigset(psig->mask); 1239 } 1240 if (psig->code) { 1241 printf(" code "); 1242 if (fancy) { 1243 switch (psig->signo) { 1244 case SIGILL: 1245 sigill_name(psig->code); 1246 break; 1247 case SIGTRAP: 1248 sigtrap_name(psig->code); 1249 break; 1250 case SIGEMT: 1251 sigemt_name(psig->code); 1252 break; 1253 case SIGFPE: 1254 sigfpe_name(psig->code); 1255 break; 1256 case SIGBUS: 1257 sigbus_name(psig->code); 1258 break; 1259 case SIGSEGV: 1260 sigsegv_name(psig->code); 1261 break; 1262 case SIGCHLD: 1263 sigchld_name(psig->code); 1264 break; 1265 } 1266 } 1267 printf("<%d>", psig->code); 1268 } 1269 1270 switch (psig->signo) { 1271 case SIGSEGV: 1272 case SIGILL: 1273 case SIGBUS: 1274 case SIGFPE: 1275 printf(" addr=%p trapno=%d", psig->si.si_addr, 1276 psig->si.si_trapno); 1277 break; 1278 default: 1279 break; 1280 } 1281 printf("\n"); 1282 } 1283 1284 static void 1285 ktrcsw(struct ktr_csw *cs) 1286 { 1287 (void)printf("%s %s\n", cs->out ? "stop" : "resume", 1288 cs->user ? "user" : "kernel"); 1289 } 1290 1291 static void 1292 ktruser(struct ktr_user *usr, size_t len) 1293 { 1294 len -= sizeof(struct ktr_user); 1295 printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id); 1296 printf(" %zu bytes\n", len); 1297 showbuf((unsigned char *)(usr + 1), len); 1298 } 1299 1300 static void 1301 usage(void) 1302 { 1303 1304 extern char *__progname; 1305 fprintf(stderr, "usage: %s " 1306 "[-dHlnRrTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n" 1307 "%*s[-t [ceinstuw]]\n", 1308 __progname, (int)(sizeof("usage: ") + strlen(__progname)), ""); 1309 exit(1); 1310 } 1311 1312 static void 1313 setemul(const char *name) 1314 { 1315 int i; 1316 1317 for (i = 0; emulations[i].name != NULL; i++) 1318 if (strcmp(emulations[i].name, name) == 0) { 1319 current = &emulations[i]; 1320 return; 1321 } 1322 warnx("Emulation `%s' unknown", name); 1323 } 1324 1325 static void 1326 atfd(int fd) 1327 { 1328 if (fd == AT_FDCWD) 1329 (void)printf("AT_FDCWD"); 1330 else if (decimal) 1331 (void)printf("%d", fd); 1332 else 1333 (void)printf("%#x", fd); 1334 } 1335 1336 static void 1337 polltimeout(int timeout) 1338 { 1339 if (timeout == INFTIM) 1340 (void)printf("INFTIM"); 1341 else if (decimal) 1342 (void)printf("%d", timeout); 1343 else 1344 (void)printf("%#x", timeout); 1345 } 1346 1347 static void 1348 pgid(int pid) 1349 { 1350 (void)printf("%d", pid); 1351 } 1352 1353 static void 1354 wait4pid(int pid) 1355 { 1356 if (pid == WAIT_ANY) 1357 (void)printf("WAIT_ANY"); 1358 else if (pid == WAIT_MYPGRP) 1359 (void)printf("WAIT_MYPGRP"); 1360 else 1361 pgid(pid); 1362 } 1363 1364 static void 1365 signame(int sig) 1366 { 1367 if (sig > 0 && sig < NSIG) 1368 (void)printf("SIG%s", sys_signame[sig]); 1369 else 1370 (void)printf("SIG %d", sig); 1371 } 1372 1373 void 1374 sigset(int ss) 1375 { 1376 int or = 0; 1377 int cnt = 0; 1378 int i; 1379 1380 for (i = 1; i < NSIG; i++) 1381 if (sigismember(&ss, i)) 1382 cnt++; 1383 if (cnt > (NSIG-1)/2) { 1384 ss = ~ss; 1385 putchar('~'); 1386 } 1387 1388 if (ss == 0) { 1389 (void)printf("0<>"); 1390 return; 1391 } 1392 1393 printf("%#x<", ss); 1394 for (i = 1; i < NSIG; i++) 1395 if (sigismember(&ss, i)) { 1396 if (or) putchar('|'); else or=1; 1397 signame(i); 1398 } 1399 printf(">"); 1400 } 1401 1402 static void 1403 semctlname(int cmd) 1404 { 1405 switch (cmd) { 1406 case GETNCNT: 1407 (void)printf("GETNCNT"); 1408 break; 1409 case GETPID: 1410 (void)printf("GETPID"); 1411 break; 1412 case GETVAL: 1413 (void)printf("GETVAL"); 1414 break; 1415 case GETALL: 1416 (void)printf("GETALL"); 1417 break; 1418 case GETZCNT: 1419 (void)printf("GETZCNT"); 1420 break; 1421 case SETVAL: 1422 (void)printf("SETVAL"); 1423 break; 1424 case SETALL: 1425 (void)printf("SETALL"); 1426 break; 1427 case IPC_RMID: 1428 (void)printf("IPC_RMID"); 1429 break; 1430 case IPC_SET: 1431 (void)printf("IPC_SET"); 1432 break; 1433 case IPC_STAT: 1434 (void)printf("IPC_STAT"); 1435 break; 1436 default: /* Should not reach */ 1437 (void)printf("<invalid=%ld>", (long)cmd); 1438 } 1439 } 1440 1441 static void 1442 shmctlname(int cmd) { 1443 switch (cmd) { 1444 case IPC_RMID: 1445 (void)printf("IPC_RMID"); 1446 break; 1447 case IPC_SET: 1448 (void)printf("IPC_SET"); 1449 break; 1450 case IPC_STAT: 1451 (void)printf("IPC_STAT"); 1452 break; 1453 default: /* Should not reach */ 1454 (void)printf("<invalid=%ld>", (long)cmd); 1455 } 1456 } 1457 1458 1459 static void 1460 semgetname(int flag) { 1461 int or = 0; 1462 if_print_or(flag, IPC_CREAT, or); 1463 if_print_or(flag, IPC_EXCL, or); 1464 if_print_or(flag, SEM_R, or); 1465 if_print_or(flag, SEM_A, or); 1466 if_print_or(flag, (SEM_R>>3), or); 1467 if_print_or(flag, (SEM_A>>3), or); 1468 if_print_or(flag, (SEM_R>>6), or); 1469 if_print_or(flag, (SEM_A>>6), or); 1470 } 1471 1472 1473 /* 1474 * Only used by SYS_open. Unless O_CREAT is set in flags, the 1475 * mode argument is unused (and often bogus and misleading). 1476 */ 1477 static void 1478 flagsandmodename(int flags, int mode) { 1479 flagsname (flags); 1480 if ((flags & O_CREAT) == O_CREAT) { 1481 (void)putchar(','); 1482 modename (mode); 1483 } else if (!fancy) { 1484 (void)putchar(','); 1485 if (decimal) { 1486 (void)printf("<unused>%ld", (long)mode); 1487 } else { 1488 (void)printf("<unused>%#lx", (long)mode); 1489 } 1490 } 1491 } 1492 1493 static void 1494 clockname(int clockid) 1495 { 1496 clocktypename(__CLOCK_TYPE(clockid)); 1497 if (__CLOCK_PTID(clockid) != 0) 1498 printf("(%d)", __CLOCK_PTID(clockid)); 1499 } 1500 1501 /* 1502 * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value 1503 * referring to a line in /etc/protocols . It might be appropriate 1504 * to use getprotoent(3) here. 1505 */ 1506 static void 1507 sockoptlevelname(int level) 1508 { 1509 if (level == SOL_SOCKET) { 1510 (void)printf("SOL_SOCKET"); 1511 } else { 1512 if (decimal) { 1513 (void)printf("%ld", (long)level); 1514 } else { 1515 (void)printf("%#lx", (long)level); 1516 } 1517 } 1518 } 1519 1520