kdump.c revision 189707
11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1988, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 3. All advertising materials mentioning features or use of this software 141590Srgrimes * must display the following acknowledgement: 151590Srgrimes * This product includes software developed by the University of 161590Srgrimes * California, Berkeley and its contributors. 171590Srgrimes * 4. Neither the name of the University nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#ifndef lint 3527443Scharnierstatic const char copyright[] = 361590Srgrimes"@(#) Copyright (c) 1988, 1993\n\ 371590Srgrimes The Regents of the University of California. All rights reserved.\n"; 381590Srgrimes#endif /* not lint */ 391590Srgrimes 401590Srgrimes#ifndef lint 4127443Scharnier#if 0 421590Srgrimesstatic char sccsid[] = "@(#)kdump.c 8.1 (Berkeley) 6/6/93"; 4327443Scharnier#endif 441590Srgrimes#endif /* not lint */ 4599112Sobrien#include <sys/cdefs.h> 4699112Sobrien__FBSDID("$FreeBSD: head/usr.bin/kdump/kdump.c 189707 2009-03-11 21:48:36Z jhb $"); 471590Srgrimes 4855206Speter#define _KERNEL 492215Scsgrextern int errno; 502215Scsgr#include <sys/errno.h> 5155206Speter#undef _KERNEL 521590Srgrimes#include <sys/param.h> 531590Srgrimes#include <sys/errno.h> 54100824Sdwmalone#define _KERNEL 551590Srgrimes#include <sys/time.h> 56100824Sdwmalone#undef _KERNEL 571590Srgrimes#include <sys/uio.h> 581590Srgrimes#include <sys/ktrace.h> 591590Srgrimes#include <sys/ioctl.h> 60165758Srodrigc#include <sys/socket.h> 61176471Sdes#include <sys/stat.h> 62176471Sdes#include <sys/un.h> 63176471Sdes#ifdef IPX 64176471Sdes#include <sys/types.h> 65176471Sdes#include <netipx/ipx.h> 66176471Sdes#endif 67176471Sdes#ifdef NETATALK 68176471Sdes#include <netatalk/at.h> 69176471Sdes#endif 70176471Sdes#include <netinet/in.h> 71165916Sjhb#include <dlfcn.h> 7227443Scharnier#include <err.h> 73176471Sdes#include <grp.h> 74176471Sdes#include <inttypes.h> 7527443Scharnier#include <locale.h> 76176471Sdes#include <pwd.h> 771590Srgrimes#include <stdio.h> 781590Srgrimes#include <stdlib.h> 791590Srgrimes#include <string.h> 80176471Sdes#include <time.h> 8127443Scharnier#include <unistd.h> 8227443Scharnier#include <vis.h> 831590Srgrimes#include "ktrace.h" 84158766Snetchild#include "kdump_subr.h" 851590Srgrimes 86100824Sdwmaloneint fread_tail(void *, int, int); 87100824Sdwmalonevoid dumpheader(struct ktr_header *); 88100824Sdwmalonevoid ktrsyscall(struct ktr_syscall *); 89100824Sdwmalonevoid ktrsysret(struct ktr_sysret *); 90100824Sdwmalonevoid ktrnamei(char *, int); 91115759Spetervoid hexdump(char *, int, int); 92115759Spetervoid visdump(char *, int, int); 93100824Sdwmalonevoid ktrgenio(struct ktr_genio *, int); 94100824Sdwmalonevoid ktrpsig(struct ktr_psig *); 95100824Sdwmalonevoid ktrcsw(struct ktr_csw *); 96100824Sdwmalonevoid ktruser(int, unsigned char *); 97176471Sdesvoid ktrsockaddr(struct sockaddr *); 98176471Sdesvoid ktrstat(struct stat *); 99176471Sdesvoid ktrstruct(char *, size_t); 100100824Sdwmalonevoid usage(void); 101135466Sruconst char *ioctlname(u_long); 102100824Sdwmalone 103176471Sdesint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata, 104176471Sdes resolv = 0; 105100824Sdwmaloneconst char *tracefile = DEF_TRACEFILE; 1061590Srgrimesstruct ktr_header ktr_header; 1071590Srgrimes 108176471Sdes#define TIME_FORMAT "%b %e %T %Y" 1091590Srgrimes#define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 1101590Srgrimes 111100824Sdwmaloneint 112100824Sdwmalonemain(int argc, char *argv[]) 1131590Srgrimes{ 1141590Srgrimes int ch, ktrlen, size; 115100824Sdwmalone void *m; 1161590Srgrimes int trpoints = ALL_POINTS; 117112201Sjhb int drop_logged; 118115759Speter pid_t pid = 0; 1191590Srgrimes 12011823Sache (void) setlocale(LC_CTYPE, ""); 12111823Sache 122176471Sdes while ((ch = getopt(argc,argv,"f:dElm:np:HRrsTt:")) != -1) 1231590Srgrimes switch((char)ch) { 1241590Srgrimes case 'f': 1251590Srgrimes tracefile = optarg; 1261590Srgrimes break; 1271590Srgrimes case 'd': 1281590Srgrimes decimal = 1; 1291590Srgrimes break; 1301590Srgrimes case 'l': 1311590Srgrimes tail = 1; 1321590Srgrimes break; 1331590Srgrimes case 'm': 1341590Srgrimes maxdata = atoi(optarg); 1351590Srgrimes break; 1361590Srgrimes case 'n': 1371590Srgrimes fancy = 0; 1381590Srgrimes break; 139115759Speter case 'p': 140115759Speter pid = atoi(optarg); 141115759Speter break; 142176471Sdes case 'r': 143176471Sdes resolv = 1; 144176471Sdes break; 145152331Srwatson case 's': 146152331Srwatson suppressdata = 1; 147152331Srwatson break; 148123187Speter case 'E': 149123187Speter timestamp = 3; /* elapsed timestamp */ 150123187Speter break; 151151930Srwatson case 'H': 152151930Srwatson threads = 1; 153151930Srwatson break; 1541590Srgrimes case 'R': 1551590Srgrimes timestamp = 2; /* relative timestamp */ 1561590Srgrimes break; 1571590Srgrimes case 'T': 1581590Srgrimes timestamp = 1; 1591590Srgrimes break; 1601590Srgrimes case 't': 1611590Srgrimes trpoints = getpoints(optarg); 16227443Scharnier if (trpoints < 0) 16327443Scharnier errx(1, "unknown trace point in %s", optarg); 1641590Srgrimes break; 1651590Srgrimes default: 1661590Srgrimes usage(); 1671590Srgrimes } 1681590Srgrimes 16919853Sfenner if (argc > optind) 1701590Srgrimes usage(); 1711590Srgrimes 1721590Srgrimes m = (void *)malloc(size = 1025); 17327443Scharnier if (m == NULL) 17427443Scharnier errx(1, "%s", strerror(ENOMEM)); 17527443Scharnier if (!freopen(tracefile, "r", stdin)) 17627443Scharnier err(1, "%s", tracefile); 177112201Sjhb drop_logged = 0; 1781590Srgrimes while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 179112201Sjhb if (ktr_header.ktr_type & KTR_DROP) { 180112201Sjhb ktr_header.ktr_type &= ~KTR_DROP; 181151930Srwatson if (!drop_logged && threads) { 182151930Srwatson (void)printf("%6d %6d %-8.*s Events dropped.\n", 183151930Srwatson ktr_header.ktr_pid, ktr_header.ktr_tid > 184151930Srwatson 0 ? ktr_header.ktr_tid : 0, MAXCOMLEN, 185151930Srwatson ktr_header.ktr_comm); 186151930Srwatson drop_logged = 1; 187151930Srwatson } else if (!drop_logged) { 188112201Sjhb (void)printf("%6d %-8.*s Events dropped.\n", 189112201Sjhb ktr_header.ktr_pid, MAXCOMLEN, 190112201Sjhb ktr_header.ktr_comm); 191112201Sjhb drop_logged = 1; 192112201Sjhb } 193112201Sjhb } 1941590Srgrimes if (trpoints & (1<<ktr_header.ktr_type)) 195115759Speter if (pid == 0 || ktr_header.ktr_pid == pid) 196115759Speter dumpheader(&ktr_header); 19727443Scharnier if ((ktrlen = ktr_header.ktr_len) < 0) 19827443Scharnier errx(1, "bogus length 0x%x", ktrlen); 1991590Srgrimes if (ktrlen > size) { 2001590Srgrimes m = (void *)realloc(m, ktrlen+1); 20127443Scharnier if (m == NULL) 20227443Scharnier errx(1, "%s", strerror(ENOMEM)); 2031590Srgrimes size = ktrlen; 2041590Srgrimes } 20527443Scharnier if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 20627443Scharnier errx(1, "data too short"); 207115759Speter if (pid && ktr_header.ktr_pid != pid) 208115759Speter continue; 2091590Srgrimes if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 2101590Srgrimes continue; 211112201Sjhb drop_logged = 0; 2121590Srgrimes switch (ktr_header.ktr_type) { 2131590Srgrimes case KTR_SYSCALL: 2141590Srgrimes ktrsyscall((struct ktr_syscall *)m); 2151590Srgrimes break; 2161590Srgrimes case KTR_SYSRET: 2171590Srgrimes ktrsysret((struct ktr_sysret *)m); 2181590Srgrimes break; 2191590Srgrimes case KTR_NAMEI: 220189707Sjhb case KTR_SYSCTL: 2211590Srgrimes ktrnamei(m, ktrlen); 2221590Srgrimes break; 2231590Srgrimes case KTR_GENIO: 2241590Srgrimes ktrgenio((struct ktr_genio *)m, ktrlen); 2251590Srgrimes break; 2261590Srgrimes case KTR_PSIG: 2271590Srgrimes ktrpsig((struct ktr_psig *)m); 2281590Srgrimes break; 2291590Srgrimes case KTR_CSW: 2301590Srgrimes ktrcsw((struct ktr_csw *)m); 2311590Srgrimes break; 23218400Sphk case KTR_USER: 23318470Sphk ktruser(ktrlen, m); 23418400Sphk break; 235176471Sdes case KTR_STRUCT: 236176471Sdes ktrstruct(m, ktrlen); 237176471Sdes break; 238112203Sjhb default: 239112203Sjhb printf("\n"); 240112203Sjhb break; 2411590Srgrimes } 2421590Srgrimes if (tail) 2431590Srgrimes (void)fflush(stdout); 2441590Srgrimes } 245100824Sdwmalone return 0; 2461590Srgrimes} 2471590Srgrimes 248100824Sdwmaloneint 249100824Sdwmalonefread_tail(void *buf, int size, int num) 2501590Srgrimes{ 2511590Srgrimes int i; 2521590Srgrimes 2531590Srgrimes while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 2541590Srgrimes (void)sleep(1); 2551590Srgrimes clearerr(stdin); 2561590Srgrimes } 2571590Srgrimes return (i); 2581590Srgrimes} 2591590Srgrimes 260100824Sdwmalonevoid 261100824Sdwmalonedumpheader(struct ktr_header *kth) 2621590Srgrimes{ 2631590Srgrimes static char unknown[64]; 2641590Srgrimes static struct timeval prevtime, temp; 265100824Sdwmalone const char *type; 2661590Srgrimes 2671590Srgrimes switch (kth->ktr_type) { 2681590Srgrimes case KTR_SYSCALL: 2691590Srgrimes type = "CALL"; 2701590Srgrimes break; 2711590Srgrimes case KTR_SYSRET: 2721590Srgrimes type = "RET "; 2731590Srgrimes break; 2741590Srgrimes case KTR_NAMEI: 2751590Srgrimes type = "NAMI"; 2761590Srgrimes break; 2771590Srgrimes case KTR_GENIO: 2781590Srgrimes type = "GIO "; 2791590Srgrimes break; 2801590Srgrimes case KTR_PSIG: 2811590Srgrimes type = "PSIG"; 2821590Srgrimes break; 2831590Srgrimes case KTR_CSW: 284171333Sjhb type = "CSW "; 2851590Srgrimes break; 28618400Sphk case KTR_USER: 28718400Sphk type = "USER"; 28818400Sphk break; 289176471Sdes case KTR_STRUCT: 290176471Sdes type = "STRU"; 291176471Sdes break; 292189707Sjhb case KTR_SYSCTL: 293189707Sjhb type = "SCTL"; 294189707Sjhb break; 2951590Srgrimes default: 2961590Srgrimes (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 2971590Srgrimes type = unknown; 2981590Srgrimes } 2991590Srgrimes 300151930Srwatson /* 301151930Srwatson * The ktr_tid field was previously the ktr_buffer field, which held 302151930Srwatson * the kernel pointer value for the buffer associated with data 303151930Srwatson * following the record header. It now holds a threadid, but only 304151930Srwatson * for trace files after the change. Older trace files still contain 305151930Srwatson * kernel pointers. Detect this and suppress the results by printing 306151930Srwatson * negative tid's as 0. 307151930Srwatson */ 308151930Srwatson if (threads) 309151930Srwatson (void)printf("%6d %6d %-8.*s ", kth->ktr_pid, kth->ktr_tid > 310151930Srwatson 0 ? kth->ktr_tid : 0, MAXCOMLEN, kth->ktr_comm); 311151930Srwatson else 312151930Srwatson (void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, 313151930Srwatson kth->ktr_comm); 3141590Srgrimes if (timestamp) { 315123187Speter if (timestamp == 3) { 316123187Speter if (prevtime.tv_sec == 0) 317123187Speter prevtime = kth->ktr_time; 318123187Speter timevalsub(&kth->ktr_time, &prevtime); 319123187Speter } 3201590Srgrimes if (timestamp == 2) { 3211590Srgrimes temp = kth->ktr_time; 3221590Srgrimes timevalsub(&kth->ktr_time, &prevtime); 3231590Srgrimes prevtime = temp; 3241590Srgrimes } 3251590Srgrimes (void)printf("%ld.%06ld ", 3261590Srgrimes kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); 3271590Srgrimes } 3281590Srgrimes (void)printf("%s ", type); 3291590Srgrimes} 3301590Srgrimes 3311590Srgrimes#include <sys/syscall.h> 3321590Srgrimes#define KTRACE 3334721Sphk#include <sys/kern/syscalls.c> 3341590Srgrimes#undef KTRACE 3351590Srgrimesint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 3361590Srgrimes 337100824Sdwmalonevoid 338100824Sdwmalonektrsyscall(struct ktr_syscall *ktr) 3391590Srgrimes{ 340100824Sdwmalone int narg = ktr->ktr_narg; 341100824Sdwmalone register_t *ip; 3421590Srgrimes 3431590Srgrimes if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) 3441590Srgrimes (void)printf("[%d]", ktr->ktr_code); 3451590Srgrimes else 3461590Srgrimes (void)printf("%s", syscallnames[ktr->ktr_code]); 34747957Sdt ip = &ktr->ktr_args[0]; 3481590Srgrimes if (narg) { 3491590Srgrimes char c = '('; 3501590Srgrimes if (fancy) { 351158766Snetchild 352158766Snetchild#define print_number(i,n,c) do { \ 353158766Snetchild if (decimal) \ 354158766Snetchild (void)printf("%c%ld", c, (long)*i); \ 355158766Snetchild else \ 356158766Snetchild (void)printf("%c%#lx", c, (long)*i); \ 357158766Snetchild i++; \ 358158766Snetchild n--; \ 359158766Snetchild c = ','; \ 360158766Snetchild } while (0); 361158766Snetchild 3621590Srgrimes if (ktr->ktr_code == SYS_ioctl) { 363100824Sdwmalone const char *cp; 364158766Snetchild print_number(ip,narg,c); 3651590Srgrimes if ((cp = ioctlname(*ip)) != NULL) 3661590Srgrimes (void)printf(",%s", cp); 3671590Srgrimes else { 3681590Srgrimes if (decimal) 36947957Sdt (void)printf(",%ld", (long)*ip); 3701590Srgrimes else 37147957Sdt (void)printf(",%#lx ", (long)*ip); 3721590Srgrimes } 3731590Srgrimes c = ','; 3741590Srgrimes ip++; 3751590Srgrimes narg--; 3761590Srgrimes } else if (ktr->ktr_code == SYS_ptrace) { 377168543Semaste (void)putchar('('); 378168543Semaste ptraceopname ((int)*ip); 3791590Srgrimes c = ','; 3801590Srgrimes ip++; 3811590Srgrimes narg--; 382158766Snetchild } else if (ktr->ktr_code == SYS_access || 383158766Snetchild ktr->ktr_code == SYS_eaccess) { 384158766Snetchild print_number(ip,narg,c); 385158766Snetchild (void)putchar(','); 386158766Snetchild accessmodename ((int)*ip); 387158766Snetchild ip++; 388158766Snetchild narg--; 389158766Snetchild } else if (ktr->ktr_code == SYS_open) { 390158766Snetchild int flags; 391158766Snetchild int mode; 392158766Snetchild print_number(ip,narg,c); 393158766Snetchild flags = *ip; 394158766Snetchild mode = *++ip; 395158766Snetchild (void)putchar(','); 396158766Snetchild flagsandmodename (flags, mode, decimal); 397158766Snetchild ip++; 398158766Snetchild narg-=2; 399158766Snetchild } else if (ktr->ktr_code == SYS_wait4) { 400158766Snetchild print_number(ip,narg,c); 401158766Snetchild print_number(ip,narg,c); 402158766Snetchild (void)putchar(','); 403158766Snetchild wait4optname ((int)*ip); 404158766Snetchild ip++; 405158766Snetchild narg--; 406158766Snetchild } else if (ktr->ktr_code == SYS_chmod || 407158766Snetchild ktr->ktr_code == SYS_fchmod || 408158766Snetchild ktr->ktr_code == SYS_lchmod) { 409158766Snetchild print_number(ip,narg,c); 410158766Snetchild (void)putchar(','); 411158766Snetchild modename ((int)*ip); 412158766Snetchild ip++; 413158766Snetchild narg--; 414158766Snetchild } else if (ktr->ktr_code == SYS_mknod) { 415158766Snetchild print_number(ip,narg,c); 416158766Snetchild (void)putchar(','); 417158766Snetchild modename ((int)*ip); 418158766Snetchild ip++; 419158766Snetchild narg--; 420158766Snetchild } else if (ktr->ktr_code == SYS_getfsstat) { 421158766Snetchild print_number(ip,narg,c); 422158766Snetchild print_number(ip,narg,c); 423158766Snetchild (void)putchar(','); 424158766Snetchild getfsstatflagsname ((int)*ip); 425158766Snetchild ip++; 426158766Snetchild narg--; 427158766Snetchild } else if (ktr->ktr_code == SYS_mount) { 428158766Snetchild print_number(ip,narg,c); 429158766Snetchild print_number(ip,narg,c); 430158766Snetchild (void)putchar(','); 431158766Snetchild mountflagsname ((int)*ip); 432158766Snetchild ip++; 433158766Snetchild narg--; 434158766Snetchild } else if (ktr->ktr_code == SYS_unmount) { 435158766Snetchild print_number(ip,narg,c); 436158766Snetchild (void)putchar(','); 437158766Snetchild mountflagsname ((int)*ip); 438158766Snetchild ip++; 439158766Snetchild narg--; 440158766Snetchild } else if (ktr->ktr_code == SYS_recvmsg || 441158766Snetchild ktr->ktr_code == SYS_sendmsg) { 442158766Snetchild print_number(ip,narg,c); 443158766Snetchild print_number(ip,narg,c); 444158766Snetchild (void)putchar(','); 445158766Snetchild sendrecvflagsname ((int)*ip); 446158766Snetchild ip++; 447158766Snetchild narg--; 448158766Snetchild } else if (ktr->ktr_code == SYS_recvfrom || 449158766Snetchild ktr->ktr_code == SYS_sendto) { 450158766Snetchild print_number(ip,narg,c); 451158766Snetchild print_number(ip,narg,c); 452158766Snetchild print_number(ip,narg,c); 453158766Snetchild (void)putchar(','); 454158766Snetchild sendrecvflagsname ((int)*ip); 455158766Snetchild ip++; 456158766Snetchild narg--; 457158766Snetchild } else if (ktr->ktr_code == SYS_chflags || 458158766Snetchild ktr->ktr_code == SYS_fchflags || 459158766Snetchild ktr->ktr_code == SYS_lchflags) { 460158766Snetchild print_number(ip,narg,c); 461158766Snetchild (void)putchar(','); 462158766Snetchild modename((int)*ip); 463158766Snetchild ip++; 464158766Snetchild narg--; 465158766Snetchild } else if (ktr->ktr_code == SYS_kill) { 466158766Snetchild print_number(ip,narg,c); 467158766Snetchild (void)putchar(','); 468158766Snetchild signame((int)*ip); 469158766Snetchild ip++; 470158766Snetchild narg--; 471158766Snetchild } else if (ktr->ktr_code == SYS_reboot) { 472158766Snetchild (void)putchar('('); 473158766Snetchild rebootoptname((int)*ip); 474158766Snetchild ip++; 475158766Snetchild narg--; 476158766Snetchild } else if (ktr->ktr_code == SYS_umask) { 477158766Snetchild (void)putchar('('); 478158766Snetchild modename((int)*ip); 479158766Snetchild ip++; 480158766Snetchild narg--; 481158766Snetchild } else if (ktr->ktr_code == SYS_msync) { 482158766Snetchild print_number(ip,narg,c); 483158766Snetchild print_number(ip,narg,c); 484158766Snetchild (void)putchar(','); 485158766Snetchild msyncflagsname((int)*ip); 486158766Snetchild ip++; 487158766Snetchild narg--; 488171221Speter#ifdef SYS_freebsd6_mmap 489171221Speter } else if (ktr->ktr_code == SYS_freebsd6_mmap) { 490171221Speter print_number(ip,narg,c); 491171221Speter print_number(ip,narg,c); 492171221Speter (void)putchar(','); 493171221Speter mmapprotname ((int)*ip); 494171221Speter (void)putchar(','); 495171221Speter ip++; 496171221Speter narg--; 497171221Speter mmapflagsname ((int)*ip); 498171221Speter ip++; 499171221Speter narg--; 500171221Speter#endif 501158766Snetchild } else if (ktr->ktr_code == SYS_mmap) { 502158766Snetchild print_number(ip,narg,c); 503158766Snetchild print_number(ip,narg,c); 504158766Snetchild (void)putchar(','); 505158766Snetchild mmapprotname ((int)*ip); 506158766Snetchild (void)putchar(','); 507158766Snetchild ip++; 508158766Snetchild narg--; 509158766Snetchild mmapflagsname ((int)*ip); 510158766Snetchild ip++; 511158766Snetchild narg--; 512158766Snetchild } else if (ktr->ktr_code == SYS_mprotect) { 513158766Snetchild print_number(ip,narg,c); 514158766Snetchild print_number(ip,narg,c); 515158766Snetchild (void)putchar(','); 516158766Snetchild mmapprotname ((int)*ip); 517158766Snetchild ip++; 518158766Snetchild narg--; 519158766Snetchild } else if (ktr->ktr_code == SYS_madvise) { 520158766Snetchild print_number(ip,narg,c); 521158766Snetchild print_number(ip,narg,c); 522158766Snetchild (void)putchar(','); 523158766Snetchild madvisebehavname((int)*ip); 524158766Snetchild ip++; 525158766Snetchild narg--; 526158766Snetchild } else if (ktr->ktr_code == SYS_setpriority) { 527158766Snetchild print_number(ip,narg,c); 528158766Snetchild print_number(ip,narg,c); 529158766Snetchild (void)putchar(','); 530158766Snetchild prioname((int)*ip); 531158766Snetchild ip++; 532158766Snetchild narg--; 533158766Snetchild } else if (ktr->ktr_code == SYS_fcntl) { 534158766Snetchild int cmd; 535158766Snetchild int arg; 536158766Snetchild print_number(ip,narg,c); 537158766Snetchild cmd = *ip; 538158766Snetchild arg = *++ip; 539158766Snetchild (void)putchar(','); 540158766Snetchild fcntlcmdname(cmd, arg, decimal); 541158766Snetchild ip++; 542158766Snetchild narg-=2; 543158766Snetchild } else if (ktr->ktr_code == SYS_socket) { 544165758Srodrigc int sockdomain; 545158766Snetchild (void)putchar('('); 546165758Srodrigc sockdomain=(int)*ip; 547165758Srodrigc sockdomainname(sockdomain); 548158766Snetchild ip++; 549158766Snetchild narg--; 550158766Snetchild (void)putchar(','); 551158766Snetchild socktypename((int)*ip); 552158766Snetchild ip++; 553158766Snetchild narg--; 554165758Srodrigc if (sockdomain == PF_INET || 555165758Srodrigc sockdomain == PF_INET6) { 556165758Srodrigc (void)putchar(','); 557165758Srodrigc sockipprotoname((int)*ip); 558165758Srodrigc ip++; 559165758Srodrigc narg--; 560165758Srodrigc } 561158766Snetchild c = ','; 562158766Snetchild } else if (ktr->ktr_code == SYS_setsockopt || 563158766Snetchild ktr->ktr_code == SYS_getsockopt) { 564158766Snetchild print_number(ip,narg,c); 565158766Snetchild (void)putchar(','); 566158766Snetchild sockoptlevelname((int)*ip, decimal); 567175138Sjhb if ((int)*ip == SOL_SOCKET) { 568175138Sjhb ip++; 569175138Sjhb narg--; 570175138Sjhb (void)putchar(','); 571175138Sjhb sockoptname((int)*ip); 572175138Sjhb } 573158766Snetchild ip++; 574158766Snetchild narg--; 575171221Speter#ifdef SYS_freebsd6_lseek 576171221Speter } else if (ktr->ktr_code == SYS_freebsd6_lseek) { 577158766Snetchild print_number(ip,narg,c); 578158766Snetchild /* Hidden 'pad' argument, not in lseek(2) */ 579158766Snetchild print_number(ip,narg,c); 580158766Snetchild print_number(ip,narg,c); 581158766Snetchild (void)putchar(','); 582158766Snetchild whencename ((int)*ip); 583158766Snetchild ip++; 584158766Snetchild narg--; 585171221Speter#endif 586171221Speter } else if (ktr->ktr_code == SYS_lseek) { 587171221Speter print_number(ip,narg,c); 588171221Speter /* Hidden 'pad' argument, not in lseek(2) */ 589171221Speter print_number(ip,narg,c); 590171221Speter (void)putchar(','); 591171221Speter whencename ((int)*ip); 592171221Speter ip++; 593171221Speter narg--; 594171221Speter 595158766Snetchild } else if (ktr->ktr_code == SYS_flock) { 596158766Snetchild print_number(ip,narg,c); 597158766Snetchild (void)putchar(','); 598158766Snetchild flockname((int)*ip); 599158766Snetchild ip++; 600158766Snetchild narg--; 601158766Snetchild } else if (ktr->ktr_code == SYS_mkfifo || 602158766Snetchild ktr->ktr_code == SYS_mkdir) { 603158766Snetchild print_number(ip,narg,c); 604158766Snetchild (void)putchar(','); 605158766Snetchild modename((int)*ip); 606158766Snetchild ip++; 607158766Snetchild narg--; 608158766Snetchild } else if (ktr->ktr_code == SYS_shutdown) { 609158766Snetchild print_number(ip,narg,c); 610158766Snetchild (void)putchar(','); 611158766Snetchild shutdownhowname((int)*ip); 612158766Snetchild ip++; 613158766Snetchild narg--; 614158766Snetchild } else if (ktr->ktr_code == SYS_socketpair) { 615158766Snetchild (void)putchar('('); 616158766Snetchild sockdomainname((int)*ip); 617158766Snetchild ip++; 618158766Snetchild narg--; 619158766Snetchild (void)putchar(','); 620158766Snetchild socktypename((int)*ip); 621158766Snetchild ip++; 622158766Snetchild narg--; 623158766Snetchild c = ','; 624158766Snetchild } else if (ktr->ktr_code == SYS_getrlimit || 625158766Snetchild ktr->ktr_code == SYS_setrlimit) { 626158766Snetchild (void)putchar('('); 627158766Snetchild rlimitname((int)*ip); 628158766Snetchild ip++; 629158766Snetchild narg--; 630158766Snetchild c = ','; 631158766Snetchild } else if (ktr->ktr_code == SYS_quotactl) { 632158766Snetchild print_number(ip,narg,c); 633174346Sjhb (void)putchar(','); 634158766Snetchild quotactlname((int)*ip); 635158766Snetchild ip++; 636158766Snetchild narg--; 637158766Snetchild c = ','; 638158766Snetchild } else if (ktr->ktr_code == SYS_nfssvc) { 639158766Snetchild (void)putchar('('); 640158766Snetchild nfssvcname((int)*ip); 641158766Snetchild ip++; 642158766Snetchild narg--; 643158766Snetchild c = ','; 644158766Snetchild } else if (ktr->ktr_code == SYS_rtprio) { 645158766Snetchild (void)putchar('('); 646158766Snetchild rtprioname((int)*ip); 647158766Snetchild ip++; 648158766Snetchild narg--; 649158766Snetchild c = ','; 650158766Snetchild } else if (ktr->ktr_code == SYS___semctl) { 651158766Snetchild print_number(ip,narg,c); 652158766Snetchild print_number(ip,narg,c); 653174346Sjhb (void)putchar(','); 654158766Snetchild semctlname((int)*ip); 655158766Snetchild ip++; 656158766Snetchild narg--; 657158766Snetchild } else if (ktr->ktr_code == SYS_semget) { 658158766Snetchild print_number(ip,narg,c); 659158766Snetchild print_number(ip,narg,c); 660174346Sjhb (void)putchar(','); 661158766Snetchild semgetname((int)*ip); 662158766Snetchild ip++; 663158766Snetchild narg--; 664158766Snetchild } else if (ktr->ktr_code == SYS_msgctl) { 665158766Snetchild print_number(ip,narg,c); 666174346Sjhb (void)putchar(','); 667158766Snetchild shmctlname((int)*ip); 668158766Snetchild ip++; 669158766Snetchild narg--; 670158766Snetchild } else if (ktr->ktr_code == SYS_shmat) { 671158766Snetchild print_number(ip,narg,c); 672158766Snetchild print_number(ip,narg,c); 673174346Sjhb (void)putchar(','); 674158766Snetchild shmatname((int)*ip); 675158766Snetchild ip++; 676158766Snetchild narg--; 677158766Snetchild } else if (ktr->ktr_code == SYS_shmctl) { 678158766Snetchild print_number(ip,narg,c); 679174346Sjhb (void)putchar(','); 680158766Snetchild shmctlname((int)*ip); 681158766Snetchild ip++; 682158766Snetchild narg--; 683158766Snetchild } else if (ktr->ktr_code == SYS_minherit) { 684158766Snetchild print_number(ip,narg,c); 685158766Snetchild print_number(ip,narg,c); 686174346Sjhb (void)putchar(','); 687158766Snetchild minheritname((int)*ip); 688158766Snetchild ip++; 689158766Snetchild narg--; 690158766Snetchild } else if (ktr->ktr_code == SYS_rfork) { 691158766Snetchild (void)putchar('('); 692158766Snetchild rforkname((int)*ip); 693158766Snetchild ip++; 694158766Snetchild narg--; 695158766Snetchild c = ','; 696158766Snetchild } else if (ktr->ktr_code == SYS_lio_listio) { 697158766Snetchild (void)putchar('('); 698158766Snetchild lio_listioname((int)*ip); 699158766Snetchild ip++; 700158766Snetchild narg--; 701158766Snetchild c = ','; 702158766Snetchild } else if (ktr->ktr_code == SYS_mlockall) { 703158766Snetchild (void)putchar('('); 704158766Snetchild mlockallname((int)*ip); 705158766Snetchild ip++; 706158766Snetchild narg--; 707158766Snetchild } else if (ktr->ktr_code == SYS_sched_setscheduler) { 708158766Snetchild print_number(ip,narg,c); 709174346Sjhb (void)putchar(','); 710158766Snetchild schedpolicyname((int)*ip); 711158766Snetchild ip++; 712158766Snetchild narg--; 713158766Snetchild } else if (ktr->ktr_code == SYS_sched_get_priority_max || 714158766Snetchild ktr->ktr_code == SYS_sched_get_priority_min) { 715158766Snetchild (void)putchar('('); 716158766Snetchild schedpolicyname((int)*ip); 717158766Snetchild ip++; 718158766Snetchild narg--; 719158766Snetchild } else if (ktr->ktr_code == SYS_sendfile) { 720158766Snetchild print_number(ip,narg,c); 721158766Snetchild print_number(ip,narg,c); 722158766Snetchild print_number(ip,narg,c); 723158766Snetchild print_number(ip,narg,c); 724158766Snetchild print_number(ip,narg,c); 725158766Snetchild print_number(ip,narg,c); 726174346Sjhb (void)putchar(','); 727158766Snetchild sendfileflagsname((int)*ip); 728158766Snetchild ip++; 729158766Snetchild narg--; 730158766Snetchild } else if (ktr->ktr_code == SYS_kldsym) { 731158766Snetchild print_number(ip,narg,c); 732174346Sjhb (void)putchar(','); 733158766Snetchild kldsymcmdname((int)*ip); 734158766Snetchild ip++; 735158766Snetchild narg--; 736158766Snetchild } else if (ktr->ktr_code == SYS_sigprocmask) { 737158766Snetchild (void)putchar('('); 738158766Snetchild sigprocmaskhowname((int)*ip); 739158766Snetchild ip++; 740158766Snetchild narg--; 741158766Snetchild c = ','; 742158766Snetchild } else if (ktr->ktr_code == SYS___acl_get_file || 743158766Snetchild ktr->ktr_code == SYS___acl_set_file || 744158766Snetchild ktr->ktr_code == SYS___acl_get_fd || 745158766Snetchild ktr->ktr_code == SYS___acl_set_fd || 746158766Snetchild ktr->ktr_code == SYS___acl_delete_file || 747158766Snetchild ktr->ktr_code == SYS___acl_delete_fd || 748158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_file || 749158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_fd || 750158766Snetchild ktr->ktr_code == SYS___acl_get_link || 751158766Snetchild ktr->ktr_code == SYS___acl_set_link || 752158766Snetchild ktr->ktr_code == SYS___acl_delete_link || 753158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_link) { 754158766Snetchild print_number(ip,narg,c); 755174346Sjhb (void)putchar(','); 756158766Snetchild acltypename((int)*ip); 757158766Snetchild ip++; 758158766Snetchild narg--; 759158766Snetchild } else if (ktr->ktr_code == SYS_sigaction) { 760158766Snetchild (void)putchar('('); 761158766Snetchild signame((int)*ip); 762158766Snetchild ip++; 763158766Snetchild narg--; 764158766Snetchild c = ','; 765158766Snetchild } else if (ktr->ktr_code == SYS_extattrctl) { 766158766Snetchild print_number(ip,narg,c); 767174346Sjhb (void)putchar(','); 768158766Snetchild extattrctlname((int)*ip); 769158766Snetchild ip++; 770158766Snetchild narg--; 771158766Snetchild } else if (ktr->ktr_code == SYS_nmount) { 772158766Snetchild print_number(ip,narg,c); 773158766Snetchild print_number(ip,narg,c); 774158766Snetchild (void)putchar(','); 775158766Snetchild mountflagsname ((int)*ip); 776158766Snetchild ip++; 777158766Snetchild narg--; 778158766Snetchild } else if (ktr->ktr_code == SYS_thr_create) { 779158766Snetchild print_number(ip,narg,c); 780158766Snetchild print_number(ip,narg,c); 781158766Snetchild (void)putchar(','); 782158766Snetchild thrcreateflagsname ((int)*ip); 783158766Snetchild ip++; 784158766Snetchild narg--; 785158766Snetchild } else if (ktr->ktr_code == SYS_thr_kill) { 786158766Snetchild print_number(ip,narg,c); 787158766Snetchild (void)putchar(','); 788158766Snetchild signame ((int)*ip); 789158766Snetchild ip++; 790158766Snetchild narg--; 791158766Snetchild } else if (ktr->ktr_code == SYS_kldunloadf) { 792158766Snetchild print_number(ip,narg,c); 793158766Snetchild (void)putchar(','); 794158766Snetchild kldunloadfflagsname ((int)*ip); 795158766Snetchild ip++; 796158766Snetchild narg--; 7971590Srgrimes } 7981590Srgrimes } 7991590Srgrimes while (narg) { 800158766Snetchild print_number(ip,narg,c); 8011590Srgrimes } 8021590Srgrimes (void)putchar(')'); 8031590Srgrimes } 8041590Srgrimes (void)putchar('\n'); 8051590Srgrimes} 8061590Srgrimes 807100824Sdwmalonevoid 808100824Sdwmalonektrsysret(struct ktr_sysret *ktr) 8091590Srgrimes{ 810100824Sdwmalone register_t ret = ktr->ktr_retval; 811100824Sdwmalone int error = ktr->ktr_error; 812100824Sdwmalone int code = ktr->ktr_code; 8131590Srgrimes 8141590Srgrimes if (code >= nsyscalls || code < 0) 8151590Srgrimes (void)printf("[%d] ", code); 8161590Srgrimes else 8171590Srgrimes (void)printf("%s ", syscallnames[code]); 8181590Srgrimes 8191590Srgrimes if (error == 0) { 8201590Srgrimes if (fancy) { 8211590Srgrimes (void)printf("%d", ret); 8221590Srgrimes if (ret < 0 || ret > 9) 82347957Sdt (void)printf("/%#lx", (long)ret); 8241590Srgrimes } else { 8251590Srgrimes if (decimal) 82647957Sdt (void)printf("%ld", (long)ret); 8271590Srgrimes else 82847957Sdt (void)printf("%#lx", (long)ret); 8291590Srgrimes } 8301590Srgrimes } else if (error == ERESTART) 8311590Srgrimes (void)printf("RESTART"); 8321590Srgrimes else if (error == EJUSTRETURN) 8331590Srgrimes (void)printf("JUSTRETURN"); 8341590Srgrimes else { 8351590Srgrimes (void)printf("-1 errno %d", ktr->ktr_error); 8361590Srgrimes if (fancy) 8371590Srgrimes (void)printf(" %s", strerror(ktr->ktr_error)); 8381590Srgrimes } 8391590Srgrimes (void)putchar('\n'); 8401590Srgrimes} 8411590Srgrimes 842100824Sdwmalonevoid 843100824Sdwmalonektrnamei(char *cp, int len) 8441590Srgrimes{ 8451590Srgrimes (void)printf("\"%.*s\"\n", len, cp); 8461590Srgrimes} 8471590Srgrimes 848100824Sdwmalonevoid 849115759Speterhexdump(char *p, int len, int screenwidth) 8501590Srgrimes{ 851115759Speter int n, i; 852115759Speter int width; 853115759Speter 854115759Speter width = 0; 855115759Speter do { 856115759Speter width += 2; 857115759Speter i = 13; /* base offset */ 858115759Speter i += (width / 2) + 1; /* spaces every second byte */ 859115759Speter i += (width * 2); /* width of bytes */ 860115759Speter i += 3; /* " |" */ 861115759Speter i += width; /* each byte */ 862115759Speter i += 1; /* "|" */ 863115759Speter } while (i < screenwidth); 864115759Speter width -= 2; 865115759Speter 866115759Speter for (n = 0; n < len; n += width) { 867115759Speter for (i = n; i < n + width; i++) { 868115759Speter if ((i % width) == 0) { /* beginning of line */ 869115759Speter printf(" 0x%04x", i); 870115759Speter } 871115759Speter if ((i % 2) == 0) { 872115759Speter printf(" "); 873115759Speter } 874115759Speter if (i < len) 875115759Speter printf("%02x", p[i] & 0xff); 876115759Speter else 877115759Speter printf(" "); 878115759Speter } 879115759Speter printf(" |"); 880115759Speter for (i = n; i < n + width; i++) { 881115759Speter if (i >= len) 882115759Speter break; 883115759Speter if (p[i] >= ' ' && p[i] <= '~') 884115759Speter printf("%c", p[i]); 885115759Speter else 886115759Speter printf("."); 887115759Speter } 888115759Speter printf("|\n"); 889115759Speter } 890115759Speter if ((i % width) != 0) 891115759Speter printf("\n"); 892115759Speter} 893115759Speter 894115759Spetervoid 895115759Spetervisdump(char *dp, int datalen, int screenwidth) 896115759Speter{ 897115759Speter int col = 0; 898100824Sdwmalone char *cp; 899100824Sdwmalone int width; 9001590Srgrimes char visbuf[5]; 9011590Srgrimes 9021590Srgrimes (void)printf(" \""); 9031590Srgrimes col = 8; 9041590Srgrimes for (;datalen > 0; datalen--, dp++) { 9051590Srgrimes (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 9061590Srgrimes cp = visbuf; 9071590Srgrimes /* 9081590Srgrimes * Keep track of printables and 9091590Srgrimes * space chars (like fold(1)). 9101590Srgrimes */ 9111590Srgrimes if (col == 0) { 9121590Srgrimes (void)putchar('\t'); 9131590Srgrimes col = 8; 9141590Srgrimes } 9151590Srgrimes switch(*cp) { 9161590Srgrimes case '\n': 9171590Srgrimes col = 0; 9181590Srgrimes (void)putchar('\n'); 9191590Srgrimes continue; 9201590Srgrimes case '\t': 9211590Srgrimes width = 8 - (col&07); 9221590Srgrimes break; 9231590Srgrimes default: 9241590Srgrimes width = strlen(cp); 9251590Srgrimes } 9261590Srgrimes if (col + width > (screenwidth-2)) { 9271590Srgrimes (void)printf("\\\n\t"); 9281590Srgrimes col = 8; 9291590Srgrimes } 9301590Srgrimes col += width; 9311590Srgrimes do { 9321590Srgrimes (void)putchar(*cp++); 9331590Srgrimes } while (*cp); 9341590Srgrimes } 9351590Srgrimes if (col == 0) 9361590Srgrimes (void)printf(" "); 9371590Srgrimes (void)printf("\"\n"); 9381590Srgrimes} 9391590Srgrimes 940115759Spetervoid 941115759Speterktrgenio(struct ktr_genio *ktr, int len) 942115759Speter{ 943115759Speter int datalen = len - sizeof (struct ktr_genio); 944115759Speter char *dp = (char *)ktr + sizeof (struct ktr_genio); 945115759Speter static int screenwidth = 0; 946115759Speter int i, binary; 947115759Speter 948115759Speter if (screenwidth == 0) { 949115759Speter struct winsize ws; 950115759Speter 951115759Speter if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 952115759Speter ws.ws_col > 8) 953115759Speter screenwidth = ws.ws_col; 954115759Speter else 955115759Speter screenwidth = 80; 956115759Speter } 957115759Speter printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 958115759Speter ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 959115759Speter datalen == 1 ? "" : "s"); 960152331Srwatson if (suppressdata) 961152331Srwatson return; 962115759Speter if (maxdata && datalen > maxdata) 963115759Speter datalen = maxdata; 964115759Speter 965115759Speter for (i = 0, binary = 0; i < datalen && binary == 0; i++) { 966115759Speter if (dp[i] >= 32 && dp[i] < 127) 967115759Speter continue; 968115759Speter if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) 969115759Speter continue; 970115759Speter binary = 1; 971115759Speter } 972115759Speter if (binary) 973115759Speter hexdump(dp, datalen, screenwidth); 974115759Speter else 975115759Speter visdump(dp, datalen, screenwidth); 976115759Speter} 977115759Speter 978100824Sdwmaloneconst char *signames[] = { 9791590Srgrimes "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 9801590Srgrimes "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 9811590Srgrimes "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 9821590Srgrimes "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 9831590Srgrimes "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 9841590Srgrimes "USR2", NULL, /* 31 - 32 */ 9851590Srgrimes}; 9861590Srgrimes 987100824Sdwmalonevoid 988100824Sdwmalonektrpsig(struct ktr_psig *psig) 9891590Srgrimes{ 990160294Skib if (psig->signo > 0 && psig->signo < NSIG) 991160296Smaxim (void)printf("SIG%s ", signames[psig->signo]); 992160294Skib else 993160296Smaxim (void)printf("SIG %d ", psig->signo); 9941590Srgrimes if (psig->action == SIG_DFL) 9951590Srgrimes (void)printf("SIG_DFL\n"); 996100824Sdwmalone else { 99747957Sdt (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 998100824Sdwmalone (u_long)psig->action, psig->mask.__bits[0], psig->code); 999100824Sdwmalone } 10001590Srgrimes} 10011590Srgrimes 1002100824Sdwmalonevoid 1003100824Sdwmalonektrcsw(struct ktr_csw *cs) 10041590Srgrimes{ 10051590Srgrimes (void)printf("%s %s\n", cs->out ? "stop" : "resume", 10061590Srgrimes cs->user ? "user" : "kernel"); 10071590Srgrimes} 10081590Srgrimes 1009165916Sjhb#define UTRACE_DLOPEN_START 1 1010165916Sjhb#define UTRACE_DLOPEN_STOP 2 1011165916Sjhb#define UTRACE_DLCLOSE_START 3 1012165916Sjhb#define UTRACE_DLCLOSE_STOP 4 1013165916Sjhb#define UTRACE_LOAD_OBJECT 5 1014165916Sjhb#define UTRACE_UNLOAD_OBJECT 6 1015165916Sjhb#define UTRACE_ADD_RUNDEP 7 1016165916Sjhb#define UTRACE_PRELOAD_FINISHED 8 1017165916Sjhb#define UTRACE_INIT_CALL 9 1018165916Sjhb#define UTRACE_FINI_CALL 10 1019165916Sjhb 1020165916Sjhbstruct utrace_rtld { 1021165916Sjhb char sig[4]; /* 'RTLD' */ 1022165916Sjhb int event; 1023165916Sjhb void *handle; 1024165916Sjhb void *mapbase; 1025165916Sjhb size_t mapsize; 1026165916Sjhb int refcnt; 1027165916Sjhb char name[MAXPATHLEN]; 1028165916Sjhb}; 1029165916Sjhb 1030165916Sjhbvoid 1031165916Sjhbktruser_rtld(int len, unsigned char *p) 1032165916Sjhb{ 1033165916Sjhb struct utrace_rtld *ut = (struct utrace_rtld *)p; 1034165916Sjhb void *parent; 1035165916Sjhb int mode; 1036165916Sjhb 1037165916Sjhb switch (ut->event) { 1038165916Sjhb case UTRACE_DLOPEN_START: 1039165916Sjhb mode = ut->refcnt; 1040165916Sjhb printf("dlopen(%s, ", ut->name); 1041165916Sjhb switch (mode & RTLD_MODEMASK) { 1042165916Sjhb case RTLD_NOW: 1043165916Sjhb printf("RTLD_NOW"); 1044165916Sjhb break; 1045165916Sjhb case RTLD_LAZY: 1046165916Sjhb printf("RTLD_LAZY"); 1047165916Sjhb break; 1048165916Sjhb default: 1049165916Sjhb printf("%#x", mode & RTLD_MODEMASK); 1050165916Sjhb } 1051165916Sjhb if (mode & RTLD_GLOBAL) 1052165916Sjhb printf(" | RTLD_GLOBAL"); 1053165916Sjhb if (mode & RTLD_TRACE) 1054165916Sjhb printf(" | RTLD_TRACE"); 1055165916Sjhb if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)) 1056165916Sjhb printf(" | %#x", mode & 1057165916Sjhb ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)); 1058165916Sjhb printf(")\n"); 1059165916Sjhb break; 1060165916Sjhb case UTRACE_DLOPEN_STOP: 1061165916Sjhb printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name, 1062165916Sjhb ut->refcnt); 1063165916Sjhb break; 1064165916Sjhb case UTRACE_DLCLOSE_START: 1065165916Sjhb printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name, 1066165916Sjhb ut->refcnt); 1067165916Sjhb break; 1068165916Sjhb case UTRACE_DLCLOSE_STOP: 1069165916Sjhb printf("dlclose(%p) finished\n", ut->handle); 1070165916Sjhb break; 1071165916Sjhb case UTRACE_LOAD_OBJECT: 1072165916Sjhb printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle, 1073165916Sjhb ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1074165916Sjhb ut->name); 1075165916Sjhb break; 1076165916Sjhb case UTRACE_UNLOAD_OBJECT: 1077165916Sjhb printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle, 1078165916Sjhb ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1079165916Sjhb ut->name); 1080165916Sjhb break; 1081165916Sjhb case UTRACE_ADD_RUNDEP: 1082165916Sjhb parent = ut->mapbase; 1083165916Sjhb printf("RTLD: %p now depends on %p (%s, %d)\n", parent, 1084165916Sjhb ut->handle, ut->name, ut->refcnt); 1085165916Sjhb break; 1086165916Sjhb case UTRACE_PRELOAD_FINISHED: 1087165916Sjhb printf("RTLD: LD_PRELOAD finished\n"); 1088165916Sjhb break; 1089165916Sjhb case UTRACE_INIT_CALL: 1090165916Sjhb printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle, 1091165916Sjhb ut->name); 1092165916Sjhb break; 1093165916Sjhb case UTRACE_FINI_CALL: 1094165916Sjhb printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle, 1095165916Sjhb ut->name); 1096165916Sjhb break; 1097165916Sjhb default: 1098165916Sjhb p += 4; 1099165916Sjhb len -= 4; 1100165916Sjhb printf("RTLD: %d ", len); 1101165916Sjhb while (len--) 1102165916Sjhb if (decimal) 1103165916Sjhb printf(" %d", *p++); 1104165916Sjhb else 1105165916Sjhb printf(" %02x", *p++); 1106165916Sjhb printf("\n"); 1107165916Sjhb } 1108165916Sjhb} 1109165916Sjhb 1110165812Sjhbstruct utrace_malloc { 1111165812Sjhb void *p; 1112165812Sjhb size_t s; 1113165812Sjhb void *r; 1114165812Sjhb}; 1115165812Sjhb 1116100824Sdwmalonevoid 1117165812Sjhbktruser_malloc(int len, unsigned char *p) 1118165812Sjhb{ 1119165812Sjhb struct utrace_malloc *ut = (struct utrace_malloc *)p; 1120165812Sjhb 1121165812Sjhb if (ut->p == NULL) { 1122165812Sjhb if (ut->s == 0 && ut->r == NULL) 1123165812Sjhb printf("malloc_init()\n"); 1124165812Sjhb else 1125165812Sjhb printf("%p = malloc(%zu)\n", ut->r, ut->s); 1126165812Sjhb } else { 1127165812Sjhb if (ut->s == 0) 1128165812Sjhb printf("free(%p)\n", ut->p); 1129165812Sjhb else 1130165812Sjhb printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 1131165812Sjhb } 1132165812Sjhb} 1133165812Sjhb 1134165812Sjhbvoid 1135100824Sdwmalonektruser(int len, unsigned char *p) 113618400Sphk{ 1137165812Sjhb 1138165916Sjhb if (len >= 8 && bcmp(p, "RTLD", 4) == 0) { 1139165916Sjhb ktruser_rtld(len, p); 1140165916Sjhb return; 1141165916Sjhb } 1142165916Sjhb 1143165812Sjhb if (len == sizeof(struct utrace_malloc)) { 1144165812Sjhb ktruser_malloc(len, p); 1145165812Sjhb return; 1146165812Sjhb } 1147165812Sjhb 114818470Sphk (void)printf("%d ", len); 114918470Sphk while (len--) 1150127402Sphk if (decimal) 1151127402Sphk (void)printf(" %d", *p++); 1152127402Sphk else 1153127402Sphk (void)printf(" %02x", *p++); 115418400Sphk (void)printf("\n"); 115518400Sphk} 115618400Sphk 1157100824Sdwmalonevoid 1158176471Sdesktrsockaddr(struct sockaddr *sa) 1159176471Sdes{ 1160176471Sdes/* 1161176471Sdes TODO: Support additional address families 1162176471Sdes #include <netnatm/natm.h> 1163176471Sdes struct sockaddr_natm *natm; 1164176471Sdes #include <netsmb/netbios.h> 1165176471Sdes struct sockaddr_nb *nb; 1166176471Sdes*/ 1167176471Sdes char addr[64]; 1168176471Sdes 1169176471Sdes /* 1170176471Sdes * note: ktrstruct() has already verified that sa points to a 1171176471Sdes * buffer at least sizeof(struct sockaddr) bytes long and exactly 1172176471Sdes * sa->sa_len bytes long. 1173176471Sdes */ 1174176471Sdes printf("struct sockaddr { "); 1175176471Sdes sockfamilyname(sa->sa_family); 1176176471Sdes printf(", "); 1177176471Sdes 1178176471Sdes#define check_sockaddr_len(n) \ 1179176471Sdes if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \ 1180176471Sdes printf("invalid"); \ 1181176471Sdes break; \ 1182176471Sdes } 1183176471Sdes 1184176471Sdes switch(sa->sa_family) { 1185176471Sdes case AF_INET: { 1186176471Sdes struct sockaddr_in *sa_in; 1187176471Sdes 1188176471Sdes sa_in = (struct sockaddr_in *)sa; 1189176471Sdes check_sockaddr_len(in); 1190176471Sdes inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr); 1191176471Sdes printf("%s:%u", addr, ntohs(sa_in->sin_port)); 1192176471Sdes break; 1193176471Sdes } 1194176471Sdes#ifdef NETATALK 1195176471Sdes case AF_APPLETALK: { 1196176471Sdes struct sockaddr_at *sa_at; 1197176471Sdes struct netrange *nr; 1198176471Sdes 1199176471Sdes sa_at = (struct sockaddr_at *)sa; 1200176471Sdes check_sockaddr_len(at); 1201176471Sdes nr = &sa_at->sat_range.r_netrange; 1202176471Sdes printf("%d.%d, %d-%d, %d", ntohs(sa_at->sat_addr.s_net), 1203176471Sdes sa_at->sat_addr.s_node, ntohs(nr->nr_firstnet), 1204176471Sdes ntohs(nr->nr_lastnet), nr->nr_phase); 1205176471Sdes break; 1206176471Sdes } 1207176471Sdes#endif 1208176471Sdes case AF_INET6: { 1209176471Sdes struct sockaddr_in6 *sa_in6; 1210176471Sdes 1211176471Sdes sa_in6 = (struct sockaddr_in6 *)sa; 1212176471Sdes check_sockaddr_len(in6); 1213176471Sdes inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr); 1214176471Sdes printf("[%s]:%u", addr, htons(sa_in6->sin6_port)); 1215176471Sdes break; 1216176471Sdes } 1217176471Sdes#ifdef IPX 1218176471Sdes case AF_IPX: { 1219176471Sdes struct sockaddr_ipx *sa_ipx; 1220176471Sdes 1221176471Sdes sa_ipx = (struct sockaddr_ipx *)sa; 1222176471Sdes check_sockaddr_len(ipx); 1223176471Sdes /* XXX wish we had ipx_ntop */ 1224176471Sdes printf("%s", ipx_ntoa(sa_ipx->sipx_addr)); 1225176471Sdes break; 1226176471Sdes } 1227176471Sdes#endif 1228176471Sdes case AF_UNIX: { 1229176471Sdes struct sockaddr_un *sa_un; 1230176471Sdes 1231176471Sdes sa_un = (struct sockaddr_un *)sa; 1232176471Sdes check_sockaddr_len(un); 1233176471Sdes printf("%.*s", (int)sizeof(sa_un->sun_path), sa_un->sun_path); 1234176471Sdes break; 1235176471Sdes } 1236176471Sdes default: 1237176471Sdes printf("unknown address family"); 1238176471Sdes } 1239176471Sdes printf(" }\n"); 1240176471Sdes} 1241176471Sdes 1242176471Sdesvoid 1243176471Sdesktrstat(struct stat *statp) 1244176471Sdes{ 1245176471Sdes char mode[12], timestr[PATH_MAX + 4]; 1246176471Sdes struct passwd *pwd; 1247176471Sdes struct group *grp; 1248176471Sdes struct tm *tm; 1249176471Sdes 1250176471Sdes /* 1251176471Sdes * note: ktrstruct() has already verified that statp points to a 1252176471Sdes * buffer exactly sizeof(struct stat) bytes long. 1253176471Sdes */ 1254176471Sdes printf("struct stat {"); 1255176471Sdes strmode(statp->st_mode, mode); 1256176471Sdes printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ", 1257176471Sdes (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode, 1258176471Sdes (uintmax_t)statp->st_nlink); 1259176471Sdes if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL) 1260176471Sdes printf("uid=%ju, ", (uintmax_t)statp->st_uid); 1261176471Sdes else 1262176471Sdes printf("uid=\"%s\", ", pwd->pw_name); 1263176471Sdes if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL) 1264176471Sdes printf("gid=%ju, ", (uintmax_t)statp->st_gid); 1265176471Sdes else 1266176471Sdes printf("gid=\"%s\", ", grp->gr_name); 1267176471Sdes printf("rdev=%ju, ", (uintmax_t)statp->st_rdev); 1268176471Sdes printf("atime="); 1269176471Sdes if (resolv == 0) 1270176471Sdes printf("%ld", statp->st_atimespec.tv_sec); 1271176471Sdes else { 1272176471Sdes tm = localtime(&statp->st_atimespec.tv_sec); 1273176471Sdes (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1274176471Sdes printf("\"%s\"", timestr); 1275176471Sdes } 1276176471Sdes if (statp->st_atimespec.tv_nsec != 0) 1277176471Sdes printf(".%09ld, ", statp->st_atimespec.tv_nsec); 1278176471Sdes else 1279176471Sdes printf(", "); 1280176471Sdes printf("stime="); 1281176471Sdes if (resolv == 0) 1282176471Sdes printf("%ld", statp->st_mtimespec.tv_sec); 1283176471Sdes else { 1284176471Sdes tm = localtime(&statp->st_mtimespec.tv_sec); 1285176471Sdes (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1286176471Sdes printf("\"%s\"", timestr); 1287176471Sdes } 1288176471Sdes if (statp->st_mtimespec.tv_nsec != 0) 1289176471Sdes printf(".%09ld, ", statp->st_mtimespec.tv_nsec); 1290176471Sdes else 1291176471Sdes printf(", "); 1292176471Sdes printf("ctime="); 1293176471Sdes if (resolv == 0) 1294176471Sdes printf("%ld", statp->st_ctimespec.tv_sec); 1295176471Sdes else { 1296176471Sdes tm = localtime(&statp->st_ctimespec.tv_sec); 1297176471Sdes (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1298176471Sdes printf("\"%s\"", timestr); 1299176471Sdes } 1300176471Sdes if (statp->st_ctimespec.tv_nsec != 0) 1301176471Sdes printf(".%09ld, ", statp->st_ctimespec.tv_nsec); 1302176471Sdes else 1303176471Sdes printf(", "); 1304176471Sdes printf("birthtime="); 1305176471Sdes if (resolv == 0) 1306176471Sdes printf("%ld", statp->st_birthtimespec.tv_sec); 1307176471Sdes else { 1308176471Sdes tm = localtime(&statp->st_birthtimespec.tv_sec); 1309176471Sdes (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1310176471Sdes printf("\"%s\"", timestr); 1311176471Sdes } 1312176471Sdes if (statp->st_birthtimespec.tv_nsec != 0) 1313176471Sdes printf(".%09ld, ", statp->st_birthtimespec.tv_nsec); 1314176471Sdes else 1315176471Sdes printf(", "); 1316176471Sdes printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x", 1317176471Sdes (uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize, 1318176471Sdes (intmax_t)statp->st_blocks, statp->st_flags); 1319176471Sdes printf(" }\n"); 1320176471Sdes} 1321176471Sdes 1322176471Sdesvoid 1323176471Sdesktrstruct(char *buf, size_t buflen) 1324176471Sdes{ 1325176471Sdes char *name, *data; 1326176471Sdes size_t namelen, datalen; 1327176471Sdes int i; 1328176471Sdes 1329176471Sdes for (name = buf, namelen = 0; 1330176471Sdes namelen < buflen && name[namelen] != '\0'; 1331176471Sdes ++namelen) 1332176471Sdes /* nothing */; 1333176471Sdes if (namelen == buflen) 1334176471Sdes goto invalid; 1335176471Sdes if (name[namelen] != '\0') 1336176471Sdes goto invalid; 1337176471Sdes data = buf + namelen + 1; 1338176471Sdes datalen = buflen - namelen - 1; 1339176471Sdes if (datalen == 0) 1340176471Sdes goto invalid; 1341176471Sdes /* sanity check */ 1342176471Sdes for (i = 0; i < namelen; ++i) 1343176471Sdes if (!isalpha((unsigned char)name[i])) 1344176471Sdes goto invalid; 1345176471Sdes if (strcmp(name, "stat") == 0) { 1346176471Sdes if (datalen != sizeof(struct stat)) 1347176471Sdes goto invalid; 1348176471Sdes ktrstat((struct stat *)data); 1349176471Sdes } else if (strcmp(name, "sockaddr") == 0) { 1350176471Sdes if (datalen < sizeof(struct sockaddr) || 1351176471Sdes datalen != ((struct sockaddr *)(data))->sa_len) 1352176471Sdes goto invalid; 1353176471Sdes ktrsockaddr((struct sockaddr *)data); 1354176471Sdes } else { 1355176471Sdes printf("unknown structure\n"); 1356176471Sdes } 1357176471Sdes return; 1358176471Sdesinvalid: 1359176471Sdes printf("invalid record\n"); 1360176471Sdes} 1361176471Sdes 1362176471Sdesvoid 1363100824Sdwmaloneusage(void) 13641590Srgrimes{ 1365176471Sdes fprintf(stderr, "usage: kdump [-dEnlHRrsT] [-f trfile] " 1366177856Sru "[-m maxdata] [-p pid] [-t trstr]\n"); 13671590Srgrimes exit(1); 13681590Srgrimes} 1369