1 /*- 2 * Copyright (c) 1988, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #ifndef lint 31 static const char copyright[] = 32 "@(#) Copyright (c) 1988, 1993\n\ 33 The Regents of the University of California. All rights reserved.\n"; 34 #endif /* not lint */ 35 36 #ifndef lint 37 #if 0 38 static char sccsid[] = "@(#)kdump.c 8.1 (Berkeley) 6/6/93"; 39 #endif 40 #endif /* not lint */ 41 #include <sys/cdefs.h> 42 __FBSDID("$FreeBSD$"); 43 44 #define _KERNEL 45 extern int errno; 46 #include <sys/errno.h> 47 #undef _KERNEL 48 #include <sys/param.h> 49 #include <sys/errno.h> 50 #define _KERNEL 51 #include <sys/time.h> 52 #undef _KERNEL 53 #include <sys/uio.h> 54 #include <sys/ktrace.h> 55 #include <sys/ioctl.h> 56 #include <sys/socket.h> 57 #include <sys/stat.h> 58 #include <sys/sysent.h> 59 #include <sys/un.h> 60 #include <sys/queue.h> 61 #ifdef IPX 62 #include <sys/types.h> 63 #include <netipx/ipx.h> 64 #endif 65 #ifdef NETATALK 66 #include <netatalk/at.h> 67 #endif 68 #include <arpa/inet.h> 69 #include <netinet/in.h> 70 #include <ctype.h> 71 #include <dlfcn.h> 72 #include <err.h> 73 #include <grp.h> 74 #include <inttypes.h> 75 #include <locale.h> 76 #include <pwd.h> 77 #include <stdio.h> 78 #include <stdlib.h> 79 #include <string.h> 80 #include <time.h> 81 #include <unistd.h> 82 #include <vis.h> 83 #include "ktrace.h" 84 #include "kdump_subr.h" 85 86 u_int abidump(struct ktr_header *); 87 int fetchprocinfo(struct ktr_header *, u_int *); 88 int fread_tail(void *, int, int); 89 void dumpheader(struct ktr_header *); 90 void ktrsyscall(struct ktr_syscall *, u_int); 91 void ktrsysret(struct ktr_sysret *, u_int); 92 void ktrnamei(char *, int); 93 void hexdump(char *, int, int); 94 void visdump(char *, int, int); 95 void ktrgenio(struct ktr_genio *, int); 96 void ktrpsig(struct ktr_psig *); 97 void ktrcsw(struct ktr_csw *); 98 void ktruser(int, unsigned char *); 99 void ktrsockaddr(struct sockaddr *); 100 void ktrstat(struct stat *); 101 void ktrstruct(char *, size_t); 102 void usage(void); 103 void sockfamilyname(int); 104 const char *ioctlname(u_long); 105 106 int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata, 107 resolv = 0, abiflag = 0; 108 const char *tracefile = DEF_TRACEFILE; 109 struct ktr_header ktr_header; 110 111 #define TIME_FORMAT "%b %e %T %Y" 112 #define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 113 114 #define print_number(i,n,c) do { \ 115 if (decimal) \ 116 printf("%c%ld", c, (long)*i); \ 117 else \ 118 printf("%c%#lx", c, (long)*i); \ 119 i++; \ 120 n--; \ 121 c = ','; \ 122 } while (0); 123 124 #if defined(__amd64__) || defined(__i386__) 125 126 void linux_ktrsyscall(struct ktr_syscall *); 127 void linux_ktrsysret(struct ktr_sysret *); 128 extern char *linux_syscallnames[]; 129 extern int nlinux_syscalls; 130 131 /* 132 * from linux.h 133 * Linux syscalls return negative errno's, we do positive and map them 134 */ 135 static int bsd_to_linux_errno[ELAST + 1] = { 136 -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, 137 -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, 138 -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, 139 -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, 140 -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, 141 -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, 142 -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, 143 -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, 144 -6, -6, -43, -42, -75,-125, -84, -95, -16, -74, 145 -72, -67, -71 146 }; 147 #endif 148 149 struct proc_info 150 { 151 TAILQ_ENTRY(proc_info) info; 152 u_int sv_flags; 153 pid_t pid; 154 }; 155 156 TAILQ_HEAD(trace_procs, proc_info) trace_procs; 157 158 int 159 main(int argc, char *argv[]) 160 { 161 int ch, ktrlen, size; 162 void *m; 163 int trpoints = ALL_POINTS; 164 int drop_logged; 165 pid_t pid = 0; 166 u_int sv_flags; 167 168 (void) setlocale(LC_CTYPE, ""); 169 170 while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1) 171 switch((char)ch) { 172 case 'A': 173 abiflag = 1; 174 break; 175 case 'f': 176 tracefile = optarg; 177 break; 178 case 'd': 179 decimal = 1; 180 break; 181 case 'l': 182 tail = 1; 183 break; 184 case 'm': 185 maxdata = atoi(optarg); 186 break; 187 case 'n': 188 fancy = 0; 189 break; 190 case 'p': 191 pid = atoi(optarg); 192 break; 193 case 'r': 194 resolv = 1; 195 break; 196 case 's': 197 suppressdata = 1; 198 break; 199 case 'E': 200 timestamp = 3; /* elapsed timestamp */ 201 break; 202 case 'H': 203 threads = 1; 204 break; 205 case 'R': 206 timestamp = 2; /* relative timestamp */ 207 break; 208 case 'T': 209 timestamp = 1; 210 break; 211 case 't': 212 trpoints = getpoints(optarg); 213 if (trpoints < 0) 214 errx(1, "unknown trace point in %s", optarg); 215 break; 216 default: 217 usage(); 218 } 219 220 if (argc > optind) 221 usage(); 222 223 m = (void *)malloc(size = 1025); 224 if (m == NULL) 225 errx(1, "%s", strerror(ENOMEM)); 226 if (!freopen(tracefile, "r", stdin)) 227 err(1, "%s", tracefile); 228 TAILQ_INIT(&trace_procs); 229 drop_logged = 0; 230 while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 231 if (ktr_header.ktr_type & KTR_DROP) { 232 ktr_header.ktr_type &= ~KTR_DROP; 233 if (!drop_logged && threads) { 234 (void)printf( 235 "%6jd %6jd %-8.*s Events dropped.\n", 236 (intmax_t)ktr_header.ktr_pid, 237 ktr_header.ktr_tid > 0 ? 238 (intmax_t)ktr_header.ktr_tid : 0, 239 MAXCOMLEN, ktr_header.ktr_comm); 240 drop_logged = 1; 241 } else if (!drop_logged) { 242 (void)printf("%6jd %-8.*s Events dropped.\n", 243 (intmax_t)ktr_header.ktr_pid, MAXCOMLEN, 244 ktr_header.ktr_comm); 245 drop_logged = 1; 246 } 247 } 248 if (trpoints & (1<<ktr_header.ktr_type)) 249 if (pid == 0 || ktr_header.ktr_pid == pid) 250 dumpheader(&ktr_header); 251 if ((ktrlen = ktr_header.ktr_len) < 0) 252 errx(1, "bogus length 0x%x", ktrlen); 253 if (ktrlen > size) { 254 m = (void *)realloc(m, ktrlen+1); 255 if (m == NULL) 256 errx(1, "%s", strerror(ENOMEM)); 257 size = ktrlen; 258 } 259 if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 260 errx(1, "data too short"); 261 if (fetchprocinfo(&ktr_header, (u_int *)m) != 0) 262 continue; 263 sv_flags = abidump(&ktr_header); 264 if (pid && ktr_header.ktr_pid != pid) 265 continue; 266 if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 267 continue; 268 drop_logged = 0; 269 switch (ktr_header.ktr_type) { 270 case KTR_SYSCALL: 271 #if defined(__amd64__) || defined(__i386__) 272 if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX) 273 linux_ktrsyscall((struct ktr_syscall *)m); 274 else 275 #endif 276 ktrsyscall((struct ktr_syscall *)m, sv_flags); 277 break; 278 case KTR_SYSRET: 279 #if defined(__amd64__) || defined(__i386__) 280 if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX) 281 linux_ktrsysret((struct ktr_sysret *)m); 282 else 283 #endif 284 ktrsysret((struct ktr_sysret *)m, sv_flags); 285 break; 286 case KTR_NAMEI: 287 case KTR_SYSCTL: 288 ktrnamei(m, ktrlen); 289 break; 290 case KTR_GENIO: 291 ktrgenio((struct ktr_genio *)m, ktrlen); 292 break; 293 case KTR_PSIG: 294 ktrpsig((struct ktr_psig *)m); 295 break; 296 case KTR_CSW: 297 ktrcsw((struct ktr_csw *)m); 298 break; 299 case KTR_USER: 300 ktruser(ktrlen, m); 301 break; 302 case KTR_STRUCT: 303 ktrstruct(m, ktrlen); 304 break; 305 default: 306 printf("\n"); 307 break; 308 } 309 if (tail) 310 (void)fflush(stdout); 311 } 312 return 0; 313 } 314 315 int 316 fread_tail(void *buf, int size, int num) 317 { 318 int i; 319 320 while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 321 (void)sleep(1); 322 clearerr(stdin); 323 } 324 return (i); 325 } 326 327 int 328 fetchprocinfo(struct ktr_header *kth, u_int *flags) 329 { 330 struct proc_info *pi; 331 332 switch (kth->ktr_type) { 333 case KTR_PROCCTOR: 334 TAILQ_FOREACH(pi, &trace_procs, info) { 335 if (pi->pid == kth->ktr_pid) { 336 TAILQ_REMOVE(&trace_procs, pi, info); 337 break; 338 } 339 } 340 pi = malloc(sizeof(struct proc_info)); 341 if (pi == NULL) 342 errx(1, "%s", strerror(ENOMEM)); 343 pi->sv_flags = *flags; 344 pi->pid = kth->ktr_pid; 345 TAILQ_INSERT_TAIL(&trace_procs, pi, info); 346 return (1); 347 348 case KTR_PROCDTOR: 349 TAILQ_FOREACH(pi, &trace_procs, info) { 350 if (pi->pid == kth->ktr_pid) { 351 TAILQ_REMOVE(&trace_procs, pi, info); 352 free(pi); 353 break; 354 } 355 } 356 return (1); 357 } 358 359 return (0); 360 } 361 362 u_int 363 abidump(struct ktr_header *kth) 364 { 365 struct proc_info *pi; 366 const char *abi; 367 const char *arch; 368 u_int flags = 0; 369 370 TAILQ_FOREACH(pi, &trace_procs, info) { 371 if (pi->pid == kth->ktr_pid) { 372 flags = pi->sv_flags; 373 break; 374 } 375 } 376 377 if (abiflag == 0) 378 return (flags); 379 380 switch (flags & SV_ABI_MASK) { 381 case SV_ABI_LINUX: 382 abi = "L"; 383 break; 384 case SV_ABI_FREEBSD: 385 abi = "F"; 386 break; 387 default: 388 abi = "U"; 389 break; 390 } 391 392 if (flags != 0) { 393 if (flags & SV_LP64) 394 arch = "64"; 395 else 396 arch = "32"; 397 } else 398 arch = "00"; 399 400 printf("%s%s ", abi, arch); 401 402 return (flags); 403 } 404 405 void 406 dumpheader(struct ktr_header *kth) 407 { 408 static char unknown[64]; 409 static struct timeval prevtime, temp; 410 const char *type; 411 412 switch (kth->ktr_type) { 413 case KTR_SYSCALL: 414 type = "CALL"; 415 break; 416 case KTR_SYSRET: 417 type = "RET "; 418 break; 419 case KTR_NAMEI: 420 type = "NAMI"; 421 break; 422 case KTR_GENIO: 423 type = "GIO "; 424 break; 425 case KTR_PSIG: 426 type = "PSIG"; 427 break; 428 case KTR_CSW: 429 type = "CSW "; 430 break; 431 case KTR_USER: 432 type = "USER"; 433 break; 434 case KTR_STRUCT: 435 type = "STRU"; 436 break; 437 case KTR_SYSCTL: 438 type = "SCTL"; 439 break; 440 case KTR_PROCCTOR: 441 /* FALLTHROUGH */ 442 case KTR_PROCDTOR: 443 return; 444 default: 445 (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 446 type = unknown; 447 } 448 449 /* 450 * The ktr_tid field was previously the ktr_buffer field, which held 451 * the kernel pointer value for the buffer associated with data 452 * following the record header. It now holds a threadid, but only 453 * for trace files after the change. Older trace files still contain 454 * kernel pointers. Detect this and suppress the results by printing 455 * negative tid's as 0. 456 */ 457 if (threads) 458 (void)printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid, 459 kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0, 460 MAXCOMLEN, kth->ktr_comm); 461 else 462 (void)printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN, 463 kth->ktr_comm); 464 if (timestamp) { 465 if (timestamp == 3) { 466 if (prevtime.tv_sec == 0) 467 prevtime = kth->ktr_time; 468 timevalsub(&kth->ktr_time, &prevtime); 469 } 470 if (timestamp == 2) { 471 temp = kth->ktr_time; 472 timevalsub(&kth->ktr_time, &prevtime); 473 prevtime = temp; 474 } 475 (void)printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, 476 kth->ktr_time.tv_usec); 477 } 478 (void)printf("%s ", type); 479 } 480 481 #include <sys/syscall.h> 482 #define KTRACE 483 #include <sys/kern/syscalls.c> 484 #undef KTRACE 485 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 486 487 void 488 ktrsyscall(struct ktr_syscall *ktr, u_int flags) 489 { 490 int narg = ktr->ktr_narg; 491 register_t *ip; 492 493 if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) || 494 (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0)) 495 (void)printf("[%d]", ktr->ktr_code); 496 else 497 (void)printf("%s", syscallnames[ktr->ktr_code]); 498 ip = &ktr->ktr_args[0]; 499 if (narg) { 500 char c = '('; 501 if (fancy && 502 (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) { 503 if (ktr->ktr_code == SYS_ioctl) { 504 const char *cp; 505 print_number(ip,narg,c); 506 if ((cp = ioctlname(*ip)) != NULL) 507 (void)printf(",%s", cp); 508 else { 509 if (decimal) 510 (void)printf(",%ld", (long)*ip); 511 else 512 (void)printf(",%#lx ", (long)*ip); 513 } 514 c = ','; 515 ip++; 516 narg--; 517 } else if (ktr->ktr_code == SYS_ptrace) { 518 (void)putchar('('); 519 ptraceopname ((int)*ip); 520 c = ','; 521 ip++; 522 narg--; 523 } else if (ktr->ktr_code == SYS_access || 524 ktr->ktr_code == SYS_eaccess) { 525 print_number(ip,narg,c); 526 (void)putchar(','); 527 accessmodename ((int)*ip); 528 ip++; 529 narg--; 530 } else if (ktr->ktr_code == SYS_open) { 531 int flags; 532 int mode; 533 print_number(ip,narg,c); 534 flags = *ip; 535 mode = *++ip; 536 (void)putchar(','); 537 flagsandmodename (flags, mode, decimal); 538 ip++; 539 narg-=2; 540 } else if (ktr->ktr_code == SYS_wait4) { 541 print_number(ip,narg,c); 542 print_number(ip,narg,c); 543 (void)putchar(','); 544 wait4optname ((int)*ip); 545 ip++; 546 narg--; 547 } else if (ktr->ktr_code == SYS_chmod || 548 ktr->ktr_code == SYS_fchmod || 549 ktr->ktr_code == SYS_lchmod) { 550 print_number(ip,narg,c); 551 (void)putchar(','); 552 modename ((int)*ip); 553 ip++; 554 narg--; 555 } else if (ktr->ktr_code == SYS_mknod) { 556 print_number(ip,narg,c); 557 (void)putchar(','); 558 modename ((int)*ip); 559 ip++; 560 narg--; 561 } else if (ktr->ktr_code == SYS_getfsstat) { 562 print_number(ip,narg,c); 563 print_number(ip,narg,c); 564 (void)putchar(','); 565 getfsstatflagsname ((int)*ip); 566 ip++; 567 narg--; 568 } else if (ktr->ktr_code == SYS_mount) { 569 print_number(ip,narg,c); 570 print_number(ip,narg,c); 571 (void)putchar(','); 572 mountflagsname ((int)*ip); 573 ip++; 574 narg--; 575 } else if (ktr->ktr_code == SYS_unmount) { 576 print_number(ip,narg,c); 577 (void)putchar(','); 578 mountflagsname ((int)*ip); 579 ip++; 580 narg--; 581 } else if (ktr->ktr_code == SYS_recvmsg || 582 ktr->ktr_code == SYS_sendmsg) { 583 print_number(ip,narg,c); 584 print_number(ip,narg,c); 585 (void)putchar(','); 586 sendrecvflagsname ((int)*ip); 587 ip++; 588 narg--; 589 } else if (ktr->ktr_code == SYS_recvfrom || 590 ktr->ktr_code == SYS_sendto) { 591 print_number(ip,narg,c); 592 print_number(ip,narg,c); 593 print_number(ip,narg,c); 594 (void)putchar(','); 595 sendrecvflagsname ((int)*ip); 596 ip++; 597 narg--; 598 } else if (ktr->ktr_code == SYS_chflags || 599 ktr->ktr_code == SYS_fchflags || 600 ktr->ktr_code == SYS_lchflags) { 601 print_number(ip,narg,c); 602 (void)putchar(','); 603 modename((int)*ip); 604 ip++; 605 narg--; 606 } else if (ktr->ktr_code == SYS_kill) { 607 print_number(ip,narg,c); 608 (void)putchar(','); 609 signame((int)*ip); 610 ip++; 611 narg--; 612 } else if (ktr->ktr_code == SYS_reboot) { 613 (void)putchar('('); 614 rebootoptname((int)*ip); 615 ip++; 616 narg--; 617 } else if (ktr->ktr_code == SYS_umask) { 618 (void)putchar('('); 619 modename((int)*ip); 620 ip++; 621 narg--; 622 } else if (ktr->ktr_code == SYS_msync) { 623 print_number(ip,narg,c); 624 print_number(ip,narg,c); 625 (void)putchar(','); 626 msyncflagsname((int)*ip); 627 ip++; 628 narg--; 629 #ifdef SYS_freebsd6_mmap 630 } else if (ktr->ktr_code == SYS_freebsd6_mmap) { 631 print_number(ip,narg,c); 632 print_number(ip,narg,c); 633 (void)putchar(','); 634 mmapprotname ((int)*ip); 635 (void)putchar(','); 636 ip++; 637 narg--; 638 mmapflagsname ((int)*ip); 639 ip++; 640 narg--; 641 #endif 642 } else if (ktr->ktr_code == SYS_mmap) { 643 print_number(ip,narg,c); 644 print_number(ip,narg,c); 645 (void)putchar(','); 646 mmapprotname ((int)*ip); 647 (void)putchar(','); 648 ip++; 649 narg--; 650 mmapflagsname ((int)*ip); 651 ip++; 652 narg--; 653 } else if (ktr->ktr_code == SYS_mprotect) { 654 print_number(ip,narg,c); 655 print_number(ip,narg,c); 656 (void)putchar(','); 657 mmapprotname ((int)*ip); 658 ip++; 659 narg--; 660 } else if (ktr->ktr_code == SYS_madvise) { 661 print_number(ip,narg,c); 662 print_number(ip,narg,c); 663 (void)putchar(','); 664 madvisebehavname((int)*ip); 665 ip++; 666 narg--; 667 } else if (ktr->ktr_code == SYS_setpriority) { 668 print_number(ip,narg,c); 669 print_number(ip,narg,c); 670 (void)putchar(','); 671 prioname((int)*ip); 672 ip++; 673 narg--; 674 } else if (ktr->ktr_code == SYS_fcntl) { 675 int cmd; 676 int arg; 677 print_number(ip,narg,c); 678 cmd = *ip; 679 arg = *++ip; 680 (void)putchar(','); 681 fcntlcmdname(cmd, arg, decimal); 682 ip++; 683 narg-=2; 684 } else if (ktr->ktr_code == SYS_socket) { 685 int sockdomain; 686 (void)putchar('('); 687 sockdomain=(int)*ip; 688 sockdomainname(sockdomain); 689 ip++; 690 narg--; 691 (void)putchar(','); 692 socktypename((int)*ip); 693 ip++; 694 narg--; 695 if (sockdomain == PF_INET || 696 sockdomain == PF_INET6) { 697 (void)putchar(','); 698 sockipprotoname((int)*ip); 699 ip++; 700 narg--; 701 } 702 c = ','; 703 } else if (ktr->ktr_code == SYS_setsockopt || 704 ktr->ktr_code == SYS_getsockopt) { 705 print_number(ip,narg,c); 706 (void)putchar(','); 707 sockoptlevelname((int)*ip, decimal); 708 if ((int)*ip == SOL_SOCKET) { 709 ip++; 710 narg--; 711 (void)putchar(','); 712 sockoptname((int)*ip); 713 } 714 ip++; 715 narg--; 716 #ifdef SYS_freebsd6_lseek 717 } else if (ktr->ktr_code == SYS_freebsd6_lseek) { 718 print_number(ip,narg,c); 719 /* Hidden 'pad' argument, not in lseek(2) */ 720 print_number(ip,narg,c); 721 print_number(ip,narg,c); 722 (void)putchar(','); 723 whencename ((int)*ip); 724 ip++; 725 narg--; 726 #endif 727 } else if (ktr->ktr_code == SYS_lseek) { 728 print_number(ip,narg,c); 729 /* Hidden 'pad' argument, not in lseek(2) */ 730 print_number(ip,narg,c); 731 (void)putchar(','); 732 whencename ((int)*ip); 733 ip++; 734 narg--; 735 736 } else if (ktr->ktr_code == SYS_flock) { 737 print_number(ip,narg,c); 738 (void)putchar(','); 739 flockname((int)*ip); 740 ip++; 741 narg--; 742 } else if (ktr->ktr_code == SYS_mkfifo || 743 ktr->ktr_code == SYS_mkdir) { 744 print_number(ip,narg,c); 745 (void)putchar(','); 746 modename((int)*ip); 747 ip++; 748 narg--; 749 } else if (ktr->ktr_code == SYS_shutdown) { 750 print_number(ip,narg,c); 751 (void)putchar(','); 752 shutdownhowname((int)*ip); 753 ip++; 754 narg--; 755 } else if (ktr->ktr_code == SYS_socketpair) { 756 (void)putchar('('); 757 sockdomainname((int)*ip); 758 ip++; 759 narg--; 760 (void)putchar(','); 761 socktypename((int)*ip); 762 ip++; 763 narg--; 764 c = ','; 765 } else if (ktr->ktr_code == SYS_getrlimit || 766 ktr->ktr_code == SYS_setrlimit) { 767 (void)putchar('('); 768 rlimitname((int)*ip); 769 ip++; 770 narg--; 771 c = ','; 772 } else if (ktr->ktr_code == SYS_quotactl) { 773 print_number(ip,narg,c); 774 (void)putchar(','); 775 quotactlname((int)*ip); 776 ip++; 777 narg--; 778 c = ','; 779 } else if (ktr->ktr_code == SYS_nfssvc) { 780 (void)putchar('('); 781 nfssvcname((int)*ip); 782 ip++; 783 narg--; 784 c = ','; 785 } else if (ktr->ktr_code == SYS_rtprio) { 786 (void)putchar('('); 787 rtprioname((int)*ip); 788 ip++; 789 narg--; 790 c = ','; 791 } else if (ktr->ktr_code == SYS___semctl) { 792 print_number(ip,narg,c); 793 print_number(ip,narg,c); 794 (void)putchar(','); 795 semctlname((int)*ip); 796 ip++; 797 narg--; 798 } else if (ktr->ktr_code == SYS_semget) { 799 print_number(ip,narg,c); 800 print_number(ip,narg,c); 801 (void)putchar(','); 802 semgetname((int)*ip); 803 ip++; 804 narg--; 805 } else if (ktr->ktr_code == SYS_msgctl) { 806 print_number(ip,narg,c); 807 (void)putchar(','); 808 shmctlname((int)*ip); 809 ip++; 810 narg--; 811 } else if (ktr->ktr_code == SYS_shmat) { 812 print_number(ip,narg,c); 813 print_number(ip,narg,c); 814 (void)putchar(','); 815 shmatname((int)*ip); 816 ip++; 817 narg--; 818 } else if (ktr->ktr_code == SYS_shmctl) { 819 print_number(ip,narg,c); 820 (void)putchar(','); 821 shmctlname((int)*ip); 822 ip++; 823 narg--; 824 } else if (ktr->ktr_code == SYS_minherit) { 825 print_number(ip,narg,c); 826 print_number(ip,narg,c); 827 (void)putchar(','); 828 minheritname((int)*ip); 829 ip++; 830 narg--; 831 } else if (ktr->ktr_code == SYS_rfork) { 832 (void)putchar('('); 833 rforkname((int)*ip); 834 ip++; 835 narg--; 836 c = ','; 837 } else if (ktr->ktr_code == SYS_lio_listio) { 838 (void)putchar('('); 839 lio_listioname((int)*ip); 840 ip++; 841 narg--; 842 c = ','; 843 } else if (ktr->ktr_code == SYS_mlockall) { 844 (void)putchar('('); 845 mlockallname((int)*ip); 846 ip++; 847 narg--; 848 } else if (ktr->ktr_code == SYS_sched_setscheduler) { 849 print_number(ip,narg,c); 850 (void)putchar(','); 851 schedpolicyname((int)*ip); 852 ip++; 853 narg--; 854 } else if (ktr->ktr_code == SYS_sched_get_priority_max || 855 ktr->ktr_code == SYS_sched_get_priority_min) { 856 (void)putchar('('); 857 schedpolicyname((int)*ip); 858 ip++; 859 narg--; 860 } else if (ktr->ktr_code == SYS_sendfile) { 861 print_number(ip,narg,c); 862 print_number(ip,narg,c); 863 print_number(ip,narg,c); 864 print_number(ip,narg,c); 865 print_number(ip,narg,c); 866 print_number(ip,narg,c); 867 (void)putchar(','); 868 sendfileflagsname((int)*ip); 869 ip++; 870 narg--; 871 } else if (ktr->ktr_code == SYS_kldsym) { 872 print_number(ip,narg,c); 873 (void)putchar(','); 874 kldsymcmdname((int)*ip); 875 ip++; 876 narg--; 877 } else if (ktr->ktr_code == SYS_sigprocmask) { 878 (void)putchar('('); 879 sigprocmaskhowname((int)*ip); 880 ip++; 881 narg--; 882 c = ','; 883 } else if (ktr->ktr_code == SYS___acl_get_file || 884 ktr->ktr_code == SYS___acl_set_file || 885 ktr->ktr_code == SYS___acl_get_fd || 886 ktr->ktr_code == SYS___acl_set_fd || 887 ktr->ktr_code == SYS___acl_delete_file || 888 ktr->ktr_code == SYS___acl_delete_fd || 889 ktr->ktr_code == SYS___acl_aclcheck_file || 890 ktr->ktr_code == SYS___acl_aclcheck_fd || 891 ktr->ktr_code == SYS___acl_get_link || 892 ktr->ktr_code == SYS___acl_set_link || 893 ktr->ktr_code == SYS___acl_delete_link || 894 ktr->ktr_code == SYS___acl_aclcheck_link) { 895 print_number(ip,narg,c); 896 (void)putchar(','); 897 acltypename((int)*ip); 898 ip++; 899 narg--; 900 } else if (ktr->ktr_code == SYS_sigaction) { 901 (void)putchar('('); 902 signame((int)*ip); 903 ip++; 904 narg--; 905 c = ','; 906 } else if (ktr->ktr_code == SYS_extattrctl) { 907 print_number(ip,narg,c); 908 (void)putchar(','); 909 extattrctlname((int)*ip); 910 ip++; 911 narg--; 912 } else if (ktr->ktr_code == SYS_nmount) { 913 print_number(ip,narg,c); 914 print_number(ip,narg,c); 915 (void)putchar(','); 916 mountflagsname ((int)*ip); 917 ip++; 918 narg--; 919 } else if (ktr->ktr_code == SYS_thr_create) { 920 print_number(ip,narg,c); 921 print_number(ip,narg,c); 922 (void)putchar(','); 923 thrcreateflagsname ((int)*ip); 924 ip++; 925 narg--; 926 } else if (ktr->ktr_code == SYS_thr_kill) { 927 print_number(ip,narg,c); 928 (void)putchar(','); 929 signame ((int)*ip); 930 ip++; 931 narg--; 932 } else if (ktr->ktr_code == SYS_kldunloadf) { 933 print_number(ip,narg,c); 934 (void)putchar(','); 935 kldunloadfflagsname ((int)*ip); 936 ip++; 937 narg--; 938 } 939 } 940 while (narg > 0) { 941 print_number(ip,narg,c); 942 } 943 (void)putchar(')'); 944 } 945 (void)putchar('\n'); 946 } 947 948 void 949 ktrsysret(struct ktr_sysret *ktr, u_int flags) 950 { 951 register_t ret = ktr->ktr_retval; 952 int error = ktr->ktr_error; 953 int code = ktr->ktr_code; 954 955 if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) || 956 (code >= nsyscalls || code < 0)) 957 (void)printf("[%d] ", code); 958 else 959 (void)printf("%s ", syscallnames[code]); 960 961 if (error == 0) { 962 if (fancy) { 963 (void)printf("%ld", (long)ret); 964 if (ret < 0 || ret > 9) 965 (void)printf("/%#lx", (long)ret); 966 } else { 967 if (decimal) 968 (void)printf("%ld", (long)ret); 969 else 970 (void)printf("%#lx", (long)ret); 971 } 972 } else if (error == ERESTART) 973 (void)printf("RESTART"); 974 else if (error == EJUSTRETURN) 975 (void)printf("JUSTRETURN"); 976 else { 977 (void)printf("-1 errno %d", ktr->ktr_error); 978 if (fancy) 979 (void)printf(" %s", strerror(ktr->ktr_error)); 980 } 981 (void)putchar('\n'); 982 } 983 984 void 985 ktrnamei(char *cp, int len) 986 { 987 (void)printf("\"%.*s\"\n", len, cp); 988 } 989 990 void 991 hexdump(char *p, int len, int screenwidth) 992 { 993 int n, i; 994 int width; 995 996 width = 0; 997 do { 998 width += 2; 999 i = 13; /* base offset */ 1000 i += (width / 2) + 1; /* spaces every second byte */ 1001 i += (width * 2); /* width of bytes */ 1002 i += 3; /* " |" */ 1003 i += width; /* each byte */ 1004 i += 1; /* "|" */ 1005 } while (i < screenwidth); 1006 width -= 2; 1007 1008 for (n = 0; n < len; n += width) { 1009 for (i = n; i < n + width; i++) { 1010 if ((i % width) == 0) { /* beginning of line */ 1011 printf(" 0x%04x", i); 1012 } 1013 if ((i % 2) == 0) { 1014 printf(" "); 1015 } 1016 if (i < len) 1017 printf("%02x", p[i] & 0xff); 1018 else 1019 printf(" "); 1020 } 1021 printf(" |"); 1022 for (i = n; i < n + width; i++) { 1023 if (i >= len) 1024 break; 1025 if (p[i] >= ' ' && p[i] <= '~') 1026 printf("%c", p[i]); 1027 else 1028 printf("."); 1029 } 1030 printf("|\n"); 1031 } 1032 if ((i % width) != 0) 1033 printf("\n"); 1034 } 1035 1036 void 1037 visdump(char *dp, int datalen, int screenwidth) 1038 { 1039 int col = 0; 1040 char *cp; 1041 int width; 1042 char visbuf[5]; 1043 1044 (void)printf(" \""); 1045 col = 8; 1046 for (;datalen > 0; datalen--, dp++) { 1047 (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 1048 cp = visbuf; 1049 /* 1050 * Keep track of printables and 1051 * space chars (like fold(1)). 1052 */ 1053 if (col == 0) { 1054 (void)putchar('\t'); 1055 col = 8; 1056 } 1057 switch(*cp) { 1058 case '\n': 1059 col = 0; 1060 (void)putchar('\n'); 1061 continue; 1062 case '\t': 1063 width = 8 - (col&07); 1064 break; 1065 default: 1066 width = strlen(cp); 1067 } 1068 if (col + width > (screenwidth-2)) { 1069 (void)printf("\\\n\t"); 1070 col = 8; 1071 } 1072 col += width; 1073 do { 1074 (void)putchar(*cp++); 1075 } while (*cp); 1076 } 1077 if (col == 0) 1078 (void)printf(" "); 1079 (void)printf("\"\n"); 1080 } 1081 1082 void 1083 ktrgenio(struct ktr_genio *ktr, int len) 1084 { 1085 int datalen = len - sizeof (struct ktr_genio); 1086 char *dp = (char *)ktr + sizeof (struct ktr_genio); 1087 static int screenwidth = 0; 1088 int i, binary; 1089 1090 if (screenwidth == 0) { 1091 struct winsize ws; 1092 1093 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 1094 ws.ws_col > 8) 1095 screenwidth = ws.ws_col; 1096 else 1097 screenwidth = 80; 1098 } 1099 printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 1100 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 1101 datalen == 1 ? "" : "s"); 1102 if (suppressdata) 1103 return; 1104 if (maxdata && datalen > maxdata) 1105 datalen = maxdata; 1106 1107 for (i = 0, binary = 0; i < datalen && binary == 0; i++) { 1108 if (dp[i] >= 32 && dp[i] < 127) 1109 continue; 1110 if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) 1111 continue; 1112 binary = 1; 1113 } 1114 if (binary) 1115 hexdump(dp, datalen, screenwidth); 1116 else 1117 visdump(dp, datalen, screenwidth); 1118 } 1119 1120 const char *signames[] = { 1121 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 1122 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 1123 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 1124 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 1125 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 1126 "USR2", NULL, /* 31 - 32 */ 1127 }; 1128 1129 void 1130 ktrpsig(struct ktr_psig *psig) 1131 { 1132 if (psig->signo > 0 && psig->signo < NSIG) 1133 (void)printf("SIG%s ", signames[psig->signo]); 1134 else 1135 (void)printf("SIG %d ", psig->signo); 1136 if (psig->action == SIG_DFL) 1137 (void)printf("SIG_DFL\n"); 1138 else { 1139 (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 1140 (u_long)psig->action, psig->mask.__bits[0], psig->code); 1141 } 1142 } 1143 1144 void 1145 ktrcsw(struct ktr_csw *cs) 1146 { 1147 (void)printf("%s %s\n", cs->out ? "stop" : "resume", 1148 cs->user ? "user" : "kernel"); 1149 } 1150 1151 #define UTRACE_DLOPEN_START 1 1152 #define UTRACE_DLOPEN_STOP 2 1153 #define UTRACE_DLCLOSE_START 3 1154 #define UTRACE_DLCLOSE_STOP 4 1155 #define UTRACE_LOAD_OBJECT 5 1156 #define UTRACE_UNLOAD_OBJECT 6 1157 #define UTRACE_ADD_RUNDEP 7 1158 #define UTRACE_PRELOAD_FINISHED 8 1159 #define UTRACE_INIT_CALL 9 1160 #define UTRACE_FINI_CALL 10 1161 1162 struct utrace_rtld { 1163 char sig[4]; /* 'RTLD' */ 1164 int event; 1165 void *handle; 1166 void *mapbase; 1167 size_t mapsize; 1168 int refcnt; 1169 char name[MAXPATHLEN]; 1170 }; 1171 1172 void 1173 ktruser_rtld(int len, unsigned char *p) 1174 { 1175 struct utrace_rtld *ut = (struct utrace_rtld *)p; 1176 void *parent; 1177 int mode; 1178 1179 switch (ut->event) { 1180 case UTRACE_DLOPEN_START: 1181 mode = ut->refcnt; 1182 printf("dlopen(%s, ", ut->name); 1183 switch (mode & RTLD_MODEMASK) { 1184 case RTLD_NOW: 1185 printf("RTLD_NOW"); 1186 break; 1187 case RTLD_LAZY: 1188 printf("RTLD_LAZY"); 1189 break; 1190 default: 1191 printf("%#x", mode & RTLD_MODEMASK); 1192 } 1193 if (mode & RTLD_GLOBAL) 1194 printf(" | RTLD_GLOBAL"); 1195 if (mode & RTLD_TRACE) 1196 printf(" | RTLD_TRACE"); 1197 if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)) 1198 printf(" | %#x", mode & 1199 ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)); 1200 printf(")\n"); 1201 break; 1202 case UTRACE_DLOPEN_STOP: 1203 printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name, 1204 ut->refcnt); 1205 break; 1206 case UTRACE_DLCLOSE_START: 1207 printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name, 1208 ut->refcnt); 1209 break; 1210 case UTRACE_DLCLOSE_STOP: 1211 printf("dlclose(%p) finished\n", ut->handle); 1212 break; 1213 case UTRACE_LOAD_OBJECT: 1214 printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle, 1215 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1216 ut->name); 1217 break; 1218 case UTRACE_UNLOAD_OBJECT: 1219 printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle, 1220 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1221 ut->name); 1222 break; 1223 case UTRACE_ADD_RUNDEP: 1224 parent = ut->mapbase; 1225 printf("RTLD: %p now depends on %p (%s, %d)\n", parent, 1226 ut->handle, ut->name, ut->refcnt); 1227 break; 1228 case UTRACE_PRELOAD_FINISHED: 1229 printf("RTLD: LD_PRELOAD finished\n"); 1230 break; 1231 case UTRACE_INIT_CALL: 1232 printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle, 1233 ut->name); 1234 break; 1235 case UTRACE_FINI_CALL: 1236 printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle, 1237 ut->name); 1238 break; 1239 default: 1240 p += 4; 1241 len -= 4; 1242 printf("RTLD: %d ", len); 1243 while (len--) 1244 if (decimal) 1245 printf(" %d", *p++); 1246 else 1247 printf(" %02x", *p++); 1248 printf("\n"); 1249 } 1250 } 1251 1252 struct utrace_malloc { 1253 void *p; 1254 size_t s; 1255 void *r; 1256 }; 1257 1258 void 1259 ktruser_malloc(int len, unsigned char *p) 1260 { 1261 struct utrace_malloc *ut = (struct utrace_malloc *)p; 1262 1263 if (ut->p == (void *)(intptr_t)(-1)) 1264 printf("malloc_init()\n"); 1265 else if (ut->s == 0) 1266 printf("free(%p)\n", ut->p); 1267 else if (ut->p == NULL) 1268 printf("%p = malloc(%zu)\n", ut->r, ut->s); 1269 else 1270 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 1271 } 1272 1273 void 1274 ktruser(int len, unsigned char *p) 1275 { 1276 1277 if (len >= 8 && bcmp(p, "RTLD", 4) == 0) { 1278 ktruser_rtld(len, p); 1279 return; 1280 } 1281 1282 if (len == sizeof(struct utrace_malloc)) { 1283 ktruser_malloc(len, p); 1284 return; 1285 } 1286 1287 (void)printf("%d ", len); 1288 while (len--) 1289 if (decimal) 1290 (void)printf(" %d", *p++); 1291 else 1292 (void)printf(" %02x", *p++); 1293 (void)printf("\n"); 1294 } 1295 1296 void 1297 ktrsockaddr(struct sockaddr *sa) 1298 { 1299 /* 1300 TODO: Support additional address families 1301 #include <netnatm/natm.h> 1302 struct sockaddr_natm *natm; 1303 #include <netsmb/netbios.h> 1304 struct sockaddr_nb *nb; 1305 */ 1306 char addr[64]; 1307 1308 /* 1309 * note: ktrstruct() has already verified that sa points to a 1310 * buffer at least sizeof(struct sockaddr) bytes long and exactly 1311 * sa->sa_len bytes long. 1312 */ 1313 printf("struct sockaddr { "); 1314 sockfamilyname(sa->sa_family); 1315 printf(", "); 1316 1317 #define check_sockaddr_len(n) \ 1318 if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \ 1319 printf("invalid"); \ 1320 break; \ 1321 } 1322 1323 switch(sa->sa_family) { 1324 case AF_INET: { 1325 struct sockaddr_in *sa_in; 1326 1327 sa_in = (struct sockaddr_in *)sa; 1328 check_sockaddr_len(in); 1329 inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr); 1330 printf("%s:%u", addr, ntohs(sa_in->sin_port)); 1331 break; 1332 } 1333 #ifdef NETATALK 1334 case AF_APPLETALK: { 1335 struct sockaddr_at *sa_at; 1336 struct netrange *nr; 1337 1338 sa_at = (struct sockaddr_at *)sa; 1339 check_sockaddr_len(at); 1340 nr = &sa_at->sat_range.r_netrange; 1341 printf("%d.%d, %d-%d, %d", ntohs(sa_at->sat_addr.s_net), 1342 sa_at->sat_addr.s_node, ntohs(nr->nr_firstnet), 1343 ntohs(nr->nr_lastnet), nr->nr_phase); 1344 break; 1345 } 1346 #endif 1347 case AF_INET6: { 1348 struct sockaddr_in6 *sa_in6; 1349 1350 sa_in6 = (struct sockaddr_in6 *)sa; 1351 check_sockaddr_len(in6); 1352 inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr); 1353 printf("[%s]:%u", addr, htons(sa_in6->sin6_port)); 1354 break; 1355 } 1356 #ifdef IPX 1357 case AF_IPX: { 1358 struct sockaddr_ipx *sa_ipx; 1359 1360 sa_ipx = (struct sockaddr_ipx *)sa; 1361 check_sockaddr_len(ipx); 1362 /* XXX wish we had ipx_ntop */ 1363 printf("%s", ipx_ntoa(sa_ipx->sipx_addr)); 1364 break; 1365 } 1366 #endif 1367 case AF_UNIX: { 1368 struct sockaddr_un *sa_un; 1369 1370 sa_un = (struct sockaddr_un *)sa; 1371 check_sockaddr_len(un); 1372 printf("%.*s", (int)sizeof(sa_un->sun_path), sa_un->sun_path); 1373 break; 1374 } 1375 default: 1376 printf("unknown address family"); 1377 } 1378 printf(" }\n"); 1379 } 1380 1381 void 1382 ktrstat(struct stat *statp) 1383 { 1384 char mode[12], timestr[PATH_MAX + 4]; 1385 struct passwd *pwd; 1386 struct group *grp; 1387 struct tm *tm; 1388 1389 /* 1390 * note: ktrstruct() has already verified that statp points to a 1391 * buffer exactly sizeof(struct stat) bytes long. 1392 */ 1393 printf("struct stat {"); 1394 strmode(statp->st_mode, mode); 1395 printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ", 1396 (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode, 1397 (uintmax_t)statp->st_nlink); 1398 if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL) 1399 printf("uid=%ju, ", (uintmax_t)statp->st_uid); 1400 else 1401 printf("uid=\"%s\", ", pwd->pw_name); 1402 if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL) 1403 printf("gid=%ju, ", (uintmax_t)statp->st_gid); 1404 else 1405 printf("gid=\"%s\", ", grp->gr_name); 1406 printf("rdev=%ju, ", (uintmax_t)statp->st_rdev); 1407 printf("atime="); 1408 if (resolv == 0) 1409 printf("%jd", (intmax_t)statp->st_atim.tv_sec); 1410 else { 1411 tm = localtime(&statp->st_atim.tv_sec); 1412 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1413 printf("\"%s\"", timestr); 1414 } 1415 if (statp->st_atim.tv_nsec != 0) 1416 printf(".%09ld, ", statp->st_atim.tv_nsec); 1417 else 1418 printf(", "); 1419 printf("stime="); 1420 if (resolv == 0) 1421 printf("%jd", (intmax_t)statp->st_mtim.tv_sec); 1422 else { 1423 tm = localtime(&statp->st_mtim.tv_sec); 1424 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1425 printf("\"%s\"", timestr); 1426 } 1427 if (statp->st_mtim.tv_nsec != 0) 1428 printf(".%09ld, ", statp->st_mtim.tv_nsec); 1429 else 1430 printf(", "); 1431 printf("ctime="); 1432 if (resolv == 0) 1433 printf("%jd", (intmax_t)statp->st_ctim.tv_sec); 1434 else { 1435 tm = localtime(&statp->st_ctim.tv_sec); 1436 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1437 printf("\"%s\"", timestr); 1438 } 1439 if (statp->st_ctim.tv_nsec != 0) 1440 printf(".%09ld, ", statp->st_ctim.tv_nsec); 1441 else 1442 printf(", "); 1443 printf("birthtime="); 1444 if (resolv == 0) 1445 printf("%jd", (intmax_t)statp->st_birthtim.tv_sec); 1446 else { 1447 tm = localtime(&statp->st_birthtim.tv_sec); 1448 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1449 printf("\"%s\"", timestr); 1450 } 1451 if (statp->st_birthtim.tv_nsec != 0) 1452 printf(".%09ld, ", statp->st_birthtim.tv_nsec); 1453 else 1454 printf(", "); 1455 printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x", 1456 (uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize, 1457 (intmax_t)statp->st_blocks, statp->st_flags); 1458 printf(" }\n"); 1459 } 1460 1461 void 1462 ktrstruct(char *buf, size_t buflen) 1463 { 1464 char *name, *data; 1465 size_t namelen, datalen; 1466 int i; 1467 struct stat sb; 1468 struct sockaddr_storage ss; 1469 1470 for (name = buf, namelen = 0; 1471 namelen < buflen && name[namelen] != '\0'; 1472 ++namelen) 1473 /* nothing */; 1474 if (namelen == buflen) 1475 goto invalid; 1476 if (name[namelen] != '\0') 1477 goto invalid; 1478 data = buf + namelen + 1; 1479 datalen = buflen - namelen - 1; 1480 if (datalen == 0) 1481 goto invalid; 1482 /* sanity check */ 1483 for (i = 0; i < namelen; ++i) 1484 if (!isalpha((unsigned char)name[i])) 1485 goto invalid; 1486 if (strcmp(name, "stat") == 0) { 1487 if (datalen != sizeof(struct stat)) 1488 goto invalid; 1489 memcpy(&sb, data, datalen); 1490 ktrstat(&sb); 1491 } else if (strcmp(name, "sockaddr") == 0) { 1492 if (datalen > sizeof(ss)) 1493 goto invalid; 1494 memcpy(&ss, data, datalen); 1495 if (datalen < sizeof(struct sockaddr) || 1496 datalen != ss.ss_len) 1497 goto invalid; 1498 ktrsockaddr((struct sockaddr *)&ss); 1499 } else { 1500 printf("unknown structure\n"); 1501 } 1502 return; 1503 invalid: 1504 printf("invalid record\n"); 1505 } 1506 1507 #if defined(__amd64__) || defined(__i386__) 1508 void 1509 linux_ktrsyscall(struct ktr_syscall *ktr) 1510 { 1511 int narg = ktr->ktr_narg; 1512 register_t *ip; 1513 1514 if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0) 1515 printf("[%d]", ktr->ktr_code); 1516 else 1517 printf("%s", linux_syscallnames[ktr->ktr_code]); 1518 ip = &ktr->ktr_args[0]; 1519 if (narg) { 1520 char c = '('; 1521 while (narg > 0) 1522 print_number(ip, narg, c); 1523 putchar(')'); 1524 } 1525 putchar('\n'); 1526 } 1527 1528 void 1529 linux_ktrsysret(struct ktr_sysret *ktr) 1530 { 1531 register_t ret = ktr->ktr_retval; 1532 int error = ktr->ktr_error; 1533 int code = ktr->ktr_code; 1534 1535 if (code >= nlinux_syscalls || code < 0) 1536 printf("[%d] ", code); 1537 else 1538 printf("%s ", linux_syscallnames[code]); 1539 1540 if (error == 0) { 1541 if (fancy) { 1542 printf("%ld", (long)ret); 1543 if (ret < 0 || ret > 9) 1544 printf("/%#lx", (long)ret); 1545 } else { 1546 if (decimal) 1547 printf("%ld", (long)ret); 1548 else 1549 printf("%#lx", (long)ret); 1550 } 1551 } else if (error == ERESTART) 1552 printf("RESTART"); 1553 else if (error == EJUSTRETURN) 1554 printf("JUSTRETURN"); 1555 else { 1556 if (ktr->ktr_error <= ELAST + 1) 1557 error = abs(bsd_to_linux_errno[ktr->ktr_error]); 1558 else 1559 error = 999; 1560 printf("-1 errno %d", error); 1561 if (fancy) 1562 printf(" %s", strerror(ktr->ktr_error)); 1563 } 1564 putchar('\n'); 1565 } 1566 #endif 1567 1568 void 1569 usage(void) 1570 { 1571 fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] " 1572 "[-m maxdata] [-p pid] [-t trstr]\n"); 1573 exit(1); 1574 } 1575