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