kdump.c revision 203551
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 203551 2010-02-06 16:01:38Z jh $"); 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 70190168Sdelphij#include <arpa/inet.h> 71176471Sdes#include <netinet/in.h> 72190168Sdelphij#include <ctype.h> 73165916Sjhb#include <dlfcn.h> 7427443Scharnier#include <err.h> 75176471Sdes#include <grp.h> 76176471Sdes#include <inttypes.h> 7727443Scharnier#include <locale.h> 78176471Sdes#include <pwd.h> 791590Srgrimes#include <stdio.h> 801590Srgrimes#include <stdlib.h> 811590Srgrimes#include <string.h> 82176471Sdes#include <time.h> 8327443Scharnier#include <unistd.h> 8427443Scharnier#include <vis.h> 851590Srgrimes#include "ktrace.h" 86158766Snetchild#include "kdump_subr.h" 871590Srgrimes 88100824Sdwmaloneint fread_tail(void *, int, int); 89100824Sdwmalonevoid dumpheader(struct ktr_header *); 90100824Sdwmalonevoid ktrsyscall(struct ktr_syscall *); 91100824Sdwmalonevoid ktrsysret(struct ktr_sysret *); 92100824Sdwmalonevoid ktrnamei(char *, int); 93115759Spetervoid hexdump(char *, int, int); 94115759Spetervoid visdump(char *, int, int); 95100824Sdwmalonevoid ktrgenio(struct ktr_genio *, int); 96100824Sdwmalonevoid ktrpsig(struct ktr_psig *); 97100824Sdwmalonevoid ktrcsw(struct ktr_csw *); 98100824Sdwmalonevoid ktruser(int, unsigned char *); 99176471Sdesvoid ktrsockaddr(struct sockaddr *); 100176471Sdesvoid ktrstat(struct stat *); 101176471Sdesvoid ktrstruct(char *, size_t); 102100824Sdwmalonevoid usage(void); 103190168Sdelphijvoid sockfamilyname(int); 104135466Sruconst char *ioctlname(u_long); 105100824Sdwmalone 106176471Sdesint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata, 107176471Sdes resolv = 0; 108100824Sdwmaloneconst char *tracefile = DEF_TRACEFILE; 1091590Srgrimesstruct ktr_header ktr_header; 1101590Srgrimes 111176471Sdes#define TIME_FORMAT "%b %e %T %Y" 1121590Srgrimes#define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 1131590Srgrimes 114100824Sdwmaloneint 115100824Sdwmalonemain(int argc, char *argv[]) 1161590Srgrimes{ 1171590Srgrimes int ch, ktrlen, size; 118100824Sdwmalone void *m; 1191590Srgrimes int trpoints = ALL_POINTS; 120112201Sjhb int drop_logged; 121115759Speter pid_t pid = 0; 1221590Srgrimes 12311823Sache (void) setlocale(LC_CTYPE, ""); 12411823Sache 125176471Sdes while ((ch = getopt(argc,argv,"f:dElm:np:HRrsTt:")) != -1) 1261590Srgrimes switch((char)ch) { 1271590Srgrimes case 'f': 1281590Srgrimes tracefile = optarg; 1291590Srgrimes break; 1301590Srgrimes case 'd': 1311590Srgrimes decimal = 1; 1321590Srgrimes break; 1331590Srgrimes case 'l': 1341590Srgrimes tail = 1; 1351590Srgrimes break; 1361590Srgrimes case 'm': 1371590Srgrimes maxdata = atoi(optarg); 1381590Srgrimes break; 1391590Srgrimes case 'n': 1401590Srgrimes fancy = 0; 1411590Srgrimes break; 142115759Speter case 'p': 143115759Speter pid = atoi(optarg); 144115759Speter break; 145176471Sdes case 'r': 146176471Sdes resolv = 1; 147176471Sdes break; 148152331Srwatson case 's': 149152331Srwatson suppressdata = 1; 150152331Srwatson break; 151123187Speter case 'E': 152123187Speter timestamp = 3; /* elapsed timestamp */ 153123187Speter break; 154151930Srwatson case 'H': 155151930Srwatson threads = 1; 156151930Srwatson break; 1571590Srgrimes case 'R': 1581590Srgrimes timestamp = 2; /* relative timestamp */ 1591590Srgrimes break; 1601590Srgrimes case 'T': 1611590Srgrimes timestamp = 1; 1621590Srgrimes break; 1631590Srgrimes case 't': 1641590Srgrimes trpoints = getpoints(optarg); 16527443Scharnier if (trpoints < 0) 16627443Scharnier errx(1, "unknown trace point in %s", optarg); 1671590Srgrimes break; 1681590Srgrimes default: 1691590Srgrimes usage(); 1701590Srgrimes } 1711590Srgrimes 17219853Sfenner if (argc > optind) 1731590Srgrimes usage(); 1741590Srgrimes 1751590Srgrimes m = (void *)malloc(size = 1025); 17627443Scharnier if (m == NULL) 17727443Scharnier errx(1, "%s", strerror(ENOMEM)); 17827443Scharnier if (!freopen(tracefile, "r", stdin)) 17927443Scharnier err(1, "%s", tracefile); 180112201Sjhb drop_logged = 0; 1811590Srgrimes while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 182112201Sjhb if (ktr_header.ktr_type & KTR_DROP) { 183112201Sjhb ktr_header.ktr_type &= ~KTR_DROP; 184151930Srwatson if (!drop_logged && threads) { 185203551Sjh (void)printf( 186203551Sjh "%6jd %6jd %-8.*s Events dropped.\n", 187203551Sjh (intmax_t)ktr_header.ktr_pid, 188203551Sjh ktr_header.ktr_tid > 0 ? 189203551Sjh (intmax_t)ktr_header.ktr_tid : 0, 190203551Sjh MAXCOMLEN, ktr_header.ktr_comm); 191151930Srwatson drop_logged = 1; 192151930Srwatson } else if (!drop_logged) { 193203551Sjh (void)printf("%6jd %-8.*s Events dropped.\n", 194203551Sjh (intmax_t)ktr_header.ktr_pid, MAXCOMLEN, 195112201Sjhb ktr_header.ktr_comm); 196112201Sjhb drop_logged = 1; 197112201Sjhb } 198112201Sjhb } 1991590Srgrimes if (trpoints & (1<<ktr_header.ktr_type)) 200115759Speter if (pid == 0 || ktr_header.ktr_pid == pid) 201115759Speter dumpheader(&ktr_header); 20227443Scharnier if ((ktrlen = ktr_header.ktr_len) < 0) 20327443Scharnier errx(1, "bogus length 0x%x", ktrlen); 2041590Srgrimes if (ktrlen > size) { 2051590Srgrimes m = (void *)realloc(m, ktrlen+1); 20627443Scharnier if (m == NULL) 20727443Scharnier errx(1, "%s", strerror(ENOMEM)); 2081590Srgrimes size = ktrlen; 2091590Srgrimes } 21027443Scharnier if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 21127443Scharnier errx(1, "data too short"); 212115759Speter if (pid && ktr_header.ktr_pid != pid) 213115759Speter continue; 2141590Srgrimes if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 2151590Srgrimes continue; 216112201Sjhb drop_logged = 0; 2171590Srgrimes switch (ktr_header.ktr_type) { 2181590Srgrimes case KTR_SYSCALL: 2191590Srgrimes ktrsyscall((struct ktr_syscall *)m); 2201590Srgrimes break; 2211590Srgrimes case KTR_SYSRET: 2221590Srgrimes ktrsysret((struct ktr_sysret *)m); 2231590Srgrimes break; 2241590Srgrimes case KTR_NAMEI: 225189707Sjhb case KTR_SYSCTL: 2261590Srgrimes ktrnamei(m, ktrlen); 2271590Srgrimes break; 2281590Srgrimes case KTR_GENIO: 2291590Srgrimes ktrgenio((struct ktr_genio *)m, ktrlen); 2301590Srgrimes break; 2311590Srgrimes case KTR_PSIG: 2321590Srgrimes ktrpsig((struct ktr_psig *)m); 2331590Srgrimes break; 2341590Srgrimes case KTR_CSW: 2351590Srgrimes ktrcsw((struct ktr_csw *)m); 2361590Srgrimes break; 23718400Sphk case KTR_USER: 23818470Sphk ktruser(ktrlen, m); 23918400Sphk break; 240176471Sdes case KTR_STRUCT: 241176471Sdes ktrstruct(m, ktrlen); 242176471Sdes break; 243112203Sjhb default: 244112203Sjhb printf("\n"); 245112203Sjhb break; 2461590Srgrimes } 2471590Srgrimes if (tail) 2481590Srgrimes (void)fflush(stdout); 2491590Srgrimes } 250100824Sdwmalone return 0; 2511590Srgrimes} 2521590Srgrimes 253100824Sdwmaloneint 254100824Sdwmalonefread_tail(void *buf, int size, int num) 2551590Srgrimes{ 2561590Srgrimes int i; 2571590Srgrimes 2581590Srgrimes while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 2591590Srgrimes (void)sleep(1); 2601590Srgrimes clearerr(stdin); 2611590Srgrimes } 2621590Srgrimes return (i); 2631590Srgrimes} 2641590Srgrimes 265100824Sdwmalonevoid 266100824Sdwmalonedumpheader(struct ktr_header *kth) 2671590Srgrimes{ 2681590Srgrimes static char unknown[64]; 2691590Srgrimes static struct timeval prevtime, temp; 270100824Sdwmalone const char *type; 2711590Srgrimes 2721590Srgrimes switch (kth->ktr_type) { 2731590Srgrimes case KTR_SYSCALL: 2741590Srgrimes type = "CALL"; 2751590Srgrimes break; 2761590Srgrimes case KTR_SYSRET: 2771590Srgrimes type = "RET "; 2781590Srgrimes break; 2791590Srgrimes case KTR_NAMEI: 2801590Srgrimes type = "NAMI"; 2811590Srgrimes break; 2821590Srgrimes case KTR_GENIO: 2831590Srgrimes type = "GIO "; 2841590Srgrimes break; 2851590Srgrimes case KTR_PSIG: 2861590Srgrimes type = "PSIG"; 2871590Srgrimes break; 2881590Srgrimes case KTR_CSW: 289171333Sjhb type = "CSW "; 2901590Srgrimes break; 29118400Sphk case KTR_USER: 29218400Sphk type = "USER"; 29318400Sphk break; 294176471Sdes case KTR_STRUCT: 295176471Sdes type = "STRU"; 296176471Sdes break; 297189707Sjhb case KTR_SYSCTL: 298189707Sjhb type = "SCTL"; 299189707Sjhb break; 3001590Srgrimes default: 3011590Srgrimes (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 3021590Srgrimes type = unknown; 3031590Srgrimes } 3041590Srgrimes 305151930Srwatson /* 306151930Srwatson * The ktr_tid field was previously the ktr_buffer field, which held 307151930Srwatson * the kernel pointer value for the buffer associated with data 308151930Srwatson * following the record header. It now holds a threadid, but only 309151930Srwatson * for trace files after the change. Older trace files still contain 310151930Srwatson * kernel pointers. Detect this and suppress the results by printing 311151930Srwatson * negative tid's as 0. 312151930Srwatson */ 313151930Srwatson if (threads) 314203551Sjh (void)printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid, 315203551Sjh kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0, 316203551Sjh MAXCOMLEN, kth->ktr_comm); 317151930Srwatson else 318203551Sjh (void)printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN, 319151930Srwatson kth->ktr_comm); 3201590Srgrimes if (timestamp) { 321123187Speter if (timestamp == 3) { 322123187Speter if (prevtime.tv_sec == 0) 323123187Speter prevtime = kth->ktr_time; 324123187Speter timevalsub(&kth->ktr_time, &prevtime); 325123187Speter } 3261590Srgrimes if (timestamp == 2) { 3271590Srgrimes temp = kth->ktr_time; 3281590Srgrimes timevalsub(&kth->ktr_time, &prevtime); 3291590Srgrimes prevtime = temp; 3301590Srgrimes } 331203551Sjh (void)printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, 332203551Sjh kth->ktr_time.tv_usec); 3331590Srgrimes } 3341590Srgrimes (void)printf("%s ", type); 3351590Srgrimes} 3361590Srgrimes 3371590Srgrimes#include <sys/syscall.h> 3381590Srgrimes#define KTRACE 3394721Sphk#include <sys/kern/syscalls.c> 3401590Srgrimes#undef KTRACE 3411590Srgrimesint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 3421590Srgrimes 343100824Sdwmalonevoid 344100824Sdwmalonektrsyscall(struct ktr_syscall *ktr) 3451590Srgrimes{ 346100824Sdwmalone int narg = ktr->ktr_narg; 347100824Sdwmalone register_t *ip; 3481590Srgrimes 3491590Srgrimes if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) 3501590Srgrimes (void)printf("[%d]", ktr->ktr_code); 3511590Srgrimes else 3521590Srgrimes (void)printf("%s", syscallnames[ktr->ktr_code]); 35347957Sdt ip = &ktr->ktr_args[0]; 3541590Srgrimes if (narg) { 3551590Srgrimes char c = '('; 3561590Srgrimes if (fancy) { 357158766Snetchild 358158766Snetchild#define print_number(i,n,c) do { \ 359158766Snetchild if (decimal) \ 360158766Snetchild (void)printf("%c%ld", c, (long)*i); \ 361158766Snetchild else \ 362158766Snetchild (void)printf("%c%#lx", c, (long)*i); \ 363158766Snetchild i++; \ 364158766Snetchild n--; \ 365158766Snetchild c = ','; \ 366158766Snetchild } while (0); 367158766Snetchild 3681590Srgrimes if (ktr->ktr_code == SYS_ioctl) { 369100824Sdwmalone const char *cp; 370158766Snetchild print_number(ip,narg,c); 3711590Srgrimes if ((cp = ioctlname(*ip)) != NULL) 3721590Srgrimes (void)printf(",%s", cp); 3731590Srgrimes else { 3741590Srgrimes if (decimal) 37547957Sdt (void)printf(",%ld", (long)*ip); 3761590Srgrimes else 37747957Sdt (void)printf(",%#lx ", (long)*ip); 3781590Srgrimes } 3791590Srgrimes c = ','; 3801590Srgrimes ip++; 3811590Srgrimes narg--; 3821590Srgrimes } else if (ktr->ktr_code == SYS_ptrace) { 383168543Semaste (void)putchar('('); 384168543Semaste ptraceopname ((int)*ip); 3851590Srgrimes c = ','; 3861590Srgrimes ip++; 3871590Srgrimes narg--; 388158766Snetchild } else if (ktr->ktr_code == SYS_access || 389158766Snetchild ktr->ktr_code == SYS_eaccess) { 390158766Snetchild print_number(ip,narg,c); 391158766Snetchild (void)putchar(','); 392158766Snetchild accessmodename ((int)*ip); 393158766Snetchild ip++; 394158766Snetchild narg--; 395158766Snetchild } else if (ktr->ktr_code == SYS_open) { 396158766Snetchild int flags; 397158766Snetchild int mode; 398158766Snetchild print_number(ip,narg,c); 399158766Snetchild flags = *ip; 400158766Snetchild mode = *++ip; 401158766Snetchild (void)putchar(','); 402158766Snetchild flagsandmodename (flags, mode, decimal); 403158766Snetchild ip++; 404158766Snetchild narg-=2; 405158766Snetchild } else if (ktr->ktr_code == SYS_wait4) { 406158766Snetchild print_number(ip,narg,c); 407158766Snetchild print_number(ip,narg,c); 408158766Snetchild (void)putchar(','); 409158766Snetchild wait4optname ((int)*ip); 410158766Snetchild ip++; 411158766Snetchild narg--; 412158766Snetchild } else if (ktr->ktr_code == SYS_chmod || 413158766Snetchild ktr->ktr_code == SYS_fchmod || 414158766Snetchild ktr->ktr_code == SYS_lchmod) { 415158766Snetchild print_number(ip,narg,c); 416158766Snetchild (void)putchar(','); 417158766Snetchild modename ((int)*ip); 418158766Snetchild ip++; 419158766Snetchild narg--; 420158766Snetchild } else if (ktr->ktr_code == SYS_mknod) { 421158766Snetchild print_number(ip,narg,c); 422158766Snetchild (void)putchar(','); 423158766Snetchild modename ((int)*ip); 424158766Snetchild ip++; 425158766Snetchild narg--; 426158766Snetchild } else if (ktr->ktr_code == SYS_getfsstat) { 427158766Snetchild print_number(ip,narg,c); 428158766Snetchild print_number(ip,narg,c); 429158766Snetchild (void)putchar(','); 430158766Snetchild getfsstatflagsname ((int)*ip); 431158766Snetchild ip++; 432158766Snetchild narg--; 433158766Snetchild } else if (ktr->ktr_code == SYS_mount) { 434158766Snetchild print_number(ip,narg,c); 435158766Snetchild print_number(ip,narg,c); 436158766Snetchild (void)putchar(','); 437158766Snetchild mountflagsname ((int)*ip); 438158766Snetchild ip++; 439158766Snetchild narg--; 440158766Snetchild } else if (ktr->ktr_code == SYS_unmount) { 441158766Snetchild print_number(ip,narg,c); 442158766Snetchild (void)putchar(','); 443158766Snetchild mountflagsname ((int)*ip); 444158766Snetchild ip++; 445158766Snetchild narg--; 446158766Snetchild } else if (ktr->ktr_code == SYS_recvmsg || 447158766Snetchild ktr->ktr_code == SYS_sendmsg) { 448158766Snetchild print_number(ip,narg,c); 449158766Snetchild print_number(ip,narg,c); 450158766Snetchild (void)putchar(','); 451158766Snetchild sendrecvflagsname ((int)*ip); 452158766Snetchild ip++; 453158766Snetchild narg--; 454158766Snetchild } else if (ktr->ktr_code == SYS_recvfrom || 455158766Snetchild ktr->ktr_code == SYS_sendto) { 456158766Snetchild print_number(ip,narg,c); 457158766Snetchild print_number(ip,narg,c); 458158766Snetchild print_number(ip,narg,c); 459158766Snetchild (void)putchar(','); 460158766Snetchild sendrecvflagsname ((int)*ip); 461158766Snetchild ip++; 462158766Snetchild narg--; 463158766Snetchild } else if (ktr->ktr_code == SYS_chflags || 464158766Snetchild ktr->ktr_code == SYS_fchflags || 465158766Snetchild ktr->ktr_code == SYS_lchflags) { 466158766Snetchild print_number(ip,narg,c); 467158766Snetchild (void)putchar(','); 468158766Snetchild modename((int)*ip); 469158766Snetchild ip++; 470158766Snetchild narg--; 471158766Snetchild } else if (ktr->ktr_code == SYS_kill) { 472158766Snetchild print_number(ip,narg,c); 473158766Snetchild (void)putchar(','); 474158766Snetchild signame((int)*ip); 475158766Snetchild ip++; 476158766Snetchild narg--; 477158766Snetchild } else if (ktr->ktr_code == SYS_reboot) { 478158766Snetchild (void)putchar('('); 479158766Snetchild rebootoptname((int)*ip); 480158766Snetchild ip++; 481158766Snetchild narg--; 482158766Snetchild } else if (ktr->ktr_code == SYS_umask) { 483158766Snetchild (void)putchar('('); 484158766Snetchild modename((int)*ip); 485158766Snetchild ip++; 486158766Snetchild narg--; 487158766Snetchild } else if (ktr->ktr_code == SYS_msync) { 488158766Snetchild print_number(ip,narg,c); 489158766Snetchild print_number(ip,narg,c); 490158766Snetchild (void)putchar(','); 491158766Snetchild msyncflagsname((int)*ip); 492158766Snetchild ip++; 493158766Snetchild narg--; 494171221Speter#ifdef SYS_freebsd6_mmap 495171221Speter } else if (ktr->ktr_code == SYS_freebsd6_mmap) { 496171221Speter print_number(ip,narg,c); 497171221Speter print_number(ip,narg,c); 498171221Speter (void)putchar(','); 499171221Speter mmapprotname ((int)*ip); 500171221Speter (void)putchar(','); 501171221Speter ip++; 502171221Speter narg--; 503171221Speter mmapflagsname ((int)*ip); 504171221Speter ip++; 505171221Speter narg--; 506171221Speter#endif 507158766Snetchild } else if (ktr->ktr_code == SYS_mmap) { 508158766Snetchild print_number(ip,narg,c); 509158766Snetchild print_number(ip,narg,c); 510158766Snetchild (void)putchar(','); 511158766Snetchild mmapprotname ((int)*ip); 512158766Snetchild (void)putchar(','); 513158766Snetchild ip++; 514158766Snetchild narg--; 515158766Snetchild mmapflagsname ((int)*ip); 516158766Snetchild ip++; 517158766Snetchild narg--; 518158766Snetchild } else if (ktr->ktr_code == SYS_mprotect) { 519158766Snetchild print_number(ip,narg,c); 520158766Snetchild print_number(ip,narg,c); 521158766Snetchild (void)putchar(','); 522158766Snetchild mmapprotname ((int)*ip); 523158766Snetchild ip++; 524158766Snetchild narg--; 525158766Snetchild } else if (ktr->ktr_code == SYS_madvise) { 526158766Snetchild print_number(ip,narg,c); 527158766Snetchild print_number(ip,narg,c); 528158766Snetchild (void)putchar(','); 529158766Snetchild madvisebehavname((int)*ip); 530158766Snetchild ip++; 531158766Snetchild narg--; 532158766Snetchild } else if (ktr->ktr_code == SYS_setpriority) { 533158766Snetchild print_number(ip,narg,c); 534158766Snetchild print_number(ip,narg,c); 535158766Snetchild (void)putchar(','); 536158766Snetchild prioname((int)*ip); 537158766Snetchild ip++; 538158766Snetchild narg--; 539158766Snetchild } else if (ktr->ktr_code == SYS_fcntl) { 540158766Snetchild int cmd; 541158766Snetchild int arg; 542158766Snetchild print_number(ip,narg,c); 543158766Snetchild cmd = *ip; 544158766Snetchild arg = *++ip; 545158766Snetchild (void)putchar(','); 546158766Snetchild fcntlcmdname(cmd, arg, decimal); 547158766Snetchild ip++; 548158766Snetchild narg-=2; 549158766Snetchild } else if (ktr->ktr_code == SYS_socket) { 550165758Srodrigc int sockdomain; 551158766Snetchild (void)putchar('('); 552165758Srodrigc sockdomain=(int)*ip; 553165758Srodrigc sockdomainname(sockdomain); 554158766Snetchild ip++; 555158766Snetchild narg--; 556158766Snetchild (void)putchar(','); 557158766Snetchild socktypename((int)*ip); 558158766Snetchild ip++; 559158766Snetchild narg--; 560165758Srodrigc if (sockdomain == PF_INET || 561165758Srodrigc sockdomain == PF_INET6) { 562165758Srodrigc (void)putchar(','); 563165758Srodrigc sockipprotoname((int)*ip); 564165758Srodrigc ip++; 565165758Srodrigc narg--; 566165758Srodrigc } 567158766Snetchild c = ','; 568158766Snetchild } else if (ktr->ktr_code == SYS_setsockopt || 569158766Snetchild ktr->ktr_code == SYS_getsockopt) { 570158766Snetchild print_number(ip,narg,c); 571158766Snetchild (void)putchar(','); 572158766Snetchild sockoptlevelname((int)*ip, decimal); 573175138Sjhb if ((int)*ip == SOL_SOCKET) { 574175138Sjhb ip++; 575175138Sjhb narg--; 576175138Sjhb (void)putchar(','); 577175138Sjhb sockoptname((int)*ip); 578175138Sjhb } 579158766Snetchild ip++; 580158766Snetchild narg--; 581171221Speter#ifdef SYS_freebsd6_lseek 582171221Speter } else if (ktr->ktr_code == SYS_freebsd6_lseek) { 583158766Snetchild print_number(ip,narg,c); 584158766Snetchild /* Hidden 'pad' argument, not in lseek(2) */ 585158766Snetchild print_number(ip,narg,c); 586158766Snetchild print_number(ip,narg,c); 587158766Snetchild (void)putchar(','); 588158766Snetchild whencename ((int)*ip); 589158766Snetchild ip++; 590158766Snetchild narg--; 591171221Speter#endif 592171221Speter } else if (ktr->ktr_code == SYS_lseek) { 593171221Speter print_number(ip,narg,c); 594171221Speter /* Hidden 'pad' argument, not in lseek(2) */ 595171221Speter print_number(ip,narg,c); 596171221Speter (void)putchar(','); 597171221Speter whencename ((int)*ip); 598171221Speter ip++; 599171221Speter narg--; 600171221Speter 601158766Snetchild } else if (ktr->ktr_code == SYS_flock) { 602158766Snetchild print_number(ip,narg,c); 603158766Snetchild (void)putchar(','); 604158766Snetchild flockname((int)*ip); 605158766Snetchild ip++; 606158766Snetchild narg--; 607158766Snetchild } else if (ktr->ktr_code == SYS_mkfifo || 608158766Snetchild ktr->ktr_code == SYS_mkdir) { 609158766Snetchild print_number(ip,narg,c); 610158766Snetchild (void)putchar(','); 611158766Snetchild modename((int)*ip); 612158766Snetchild ip++; 613158766Snetchild narg--; 614158766Snetchild } else if (ktr->ktr_code == SYS_shutdown) { 615158766Snetchild print_number(ip,narg,c); 616158766Snetchild (void)putchar(','); 617158766Snetchild shutdownhowname((int)*ip); 618158766Snetchild ip++; 619158766Snetchild narg--; 620158766Snetchild } else if (ktr->ktr_code == SYS_socketpair) { 621158766Snetchild (void)putchar('('); 622158766Snetchild sockdomainname((int)*ip); 623158766Snetchild ip++; 624158766Snetchild narg--; 625158766Snetchild (void)putchar(','); 626158766Snetchild socktypename((int)*ip); 627158766Snetchild ip++; 628158766Snetchild narg--; 629158766Snetchild c = ','; 630158766Snetchild } else if (ktr->ktr_code == SYS_getrlimit || 631158766Snetchild ktr->ktr_code == SYS_setrlimit) { 632158766Snetchild (void)putchar('('); 633158766Snetchild rlimitname((int)*ip); 634158766Snetchild ip++; 635158766Snetchild narg--; 636158766Snetchild c = ','; 637158766Snetchild } else if (ktr->ktr_code == SYS_quotactl) { 638158766Snetchild print_number(ip,narg,c); 639174346Sjhb (void)putchar(','); 640158766Snetchild quotactlname((int)*ip); 641158766Snetchild ip++; 642158766Snetchild narg--; 643158766Snetchild c = ','; 644158766Snetchild } else if (ktr->ktr_code == SYS_nfssvc) { 645158766Snetchild (void)putchar('('); 646158766Snetchild nfssvcname((int)*ip); 647158766Snetchild ip++; 648158766Snetchild narg--; 649158766Snetchild c = ','; 650158766Snetchild } else if (ktr->ktr_code == SYS_rtprio) { 651158766Snetchild (void)putchar('('); 652158766Snetchild rtprioname((int)*ip); 653158766Snetchild ip++; 654158766Snetchild narg--; 655158766Snetchild c = ','; 656158766Snetchild } else if (ktr->ktr_code == SYS___semctl) { 657158766Snetchild print_number(ip,narg,c); 658158766Snetchild print_number(ip,narg,c); 659174346Sjhb (void)putchar(','); 660158766Snetchild semctlname((int)*ip); 661158766Snetchild ip++; 662158766Snetchild narg--; 663158766Snetchild } else if (ktr->ktr_code == SYS_semget) { 664158766Snetchild print_number(ip,narg,c); 665158766Snetchild print_number(ip,narg,c); 666174346Sjhb (void)putchar(','); 667158766Snetchild semgetname((int)*ip); 668158766Snetchild ip++; 669158766Snetchild narg--; 670158766Snetchild } else if (ktr->ktr_code == SYS_msgctl) { 671158766Snetchild print_number(ip,narg,c); 672174346Sjhb (void)putchar(','); 673158766Snetchild shmctlname((int)*ip); 674158766Snetchild ip++; 675158766Snetchild narg--; 676158766Snetchild } else if (ktr->ktr_code == SYS_shmat) { 677158766Snetchild print_number(ip,narg,c); 678158766Snetchild print_number(ip,narg,c); 679174346Sjhb (void)putchar(','); 680158766Snetchild shmatname((int)*ip); 681158766Snetchild ip++; 682158766Snetchild narg--; 683158766Snetchild } else if (ktr->ktr_code == SYS_shmctl) { 684158766Snetchild print_number(ip,narg,c); 685174346Sjhb (void)putchar(','); 686158766Snetchild shmctlname((int)*ip); 687158766Snetchild ip++; 688158766Snetchild narg--; 689158766Snetchild } else if (ktr->ktr_code == SYS_minherit) { 690158766Snetchild print_number(ip,narg,c); 691158766Snetchild print_number(ip,narg,c); 692174346Sjhb (void)putchar(','); 693158766Snetchild minheritname((int)*ip); 694158766Snetchild ip++; 695158766Snetchild narg--; 696158766Snetchild } else if (ktr->ktr_code == SYS_rfork) { 697158766Snetchild (void)putchar('('); 698158766Snetchild rforkname((int)*ip); 699158766Snetchild ip++; 700158766Snetchild narg--; 701158766Snetchild c = ','; 702158766Snetchild } else if (ktr->ktr_code == SYS_lio_listio) { 703158766Snetchild (void)putchar('('); 704158766Snetchild lio_listioname((int)*ip); 705158766Snetchild ip++; 706158766Snetchild narg--; 707158766Snetchild c = ','; 708158766Snetchild } else if (ktr->ktr_code == SYS_mlockall) { 709158766Snetchild (void)putchar('('); 710158766Snetchild mlockallname((int)*ip); 711158766Snetchild ip++; 712158766Snetchild narg--; 713158766Snetchild } else if (ktr->ktr_code == SYS_sched_setscheduler) { 714158766Snetchild print_number(ip,narg,c); 715174346Sjhb (void)putchar(','); 716158766Snetchild schedpolicyname((int)*ip); 717158766Snetchild ip++; 718158766Snetchild narg--; 719158766Snetchild } else if (ktr->ktr_code == SYS_sched_get_priority_max || 720158766Snetchild ktr->ktr_code == SYS_sched_get_priority_min) { 721158766Snetchild (void)putchar('('); 722158766Snetchild schedpolicyname((int)*ip); 723158766Snetchild ip++; 724158766Snetchild narg--; 725158766Snetchild } else if (ktr->ktr_code == SYS_sendfile) { 726158766Snetchild print_number(ip,narg,c); 727158766Snetchild print_number(ip,narg,c); 728158766Snetchild print_number(ip,narg,c); 729158766Snetchild print_number(ip,narg,c); 730158766Snetchild print_number(ip,narg,c); 731158766Snetchild print_number(ip,narg,c); 732174346Sjhb (void)putchar(','); 733158766Snetchild sendfileflagsname((int)*ip); 734158766Snetchild ip++; 735158766Snetchild narg--; 736158766Snetchild } else if (ktr->ktr_code == SYS_kldsym) { 737158766Snetchild print_number(ip,narg,c); 738174346Sjhb (void)putchar(','); 739158766Snetchild kldsymcmdname((int)*ip); 740158766Snetchild ip++; 741158766Snetchild narg--; 742158766Snetchild } else if (ktr->ktr_code == SYS_sigprocmask) { 743158766Snetchild (void)putchar('('); 744158766Snetchild sigprocmaskhowname((int)*ip); 745158766Snetchild ip++; 746158766Snetchild narg--; 747158766Snetchild c = ','; 748158766Snetchild } else if (ktr->ktr_code == SYS___acl_get_file || 749158766Snetchild ktr->ktr_code == SYS___acl_set_file || 750158766Snetchild ktr->ktr_code == SYS___acl_get_fd || 751158766Snetchild ktr->ktr_code == SYS___acl_set_fd || 752158766Snetchild ktr->ktr_code == SYS___acl_delete_file || 753158766Snetchild ktr->ktr_code == SYS___acl_delete_fd || 754158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_file || 755158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_fd || 756158766Snetchild ktr->ktr_code == SYS___acl_get_link || 757158766Snetchild ktr->ktr_code == SYS___acl_set_link || 758158766Snetchild ktr->ktr_code == SYS___acl_delete_link || 759158766Snetchild ktr->ktr_code == SYS___acl_aclcheck_link) { 760158766Snetchild print_number(ip,narg,c); 761174346Sjhb (void)putchar(','); 762158766Snetchild acltypename((int)*ip); 763158766Snetchild ip++; 764158766Snetchild narg--; 765158766Snetchild } else if (ktr->ktr_code == SYS_sigaction) { 766158766Snetchild (void)putchar('('); 767158766Snetchild signame((int)*ip); 768158766Snetchild ip++; 769158766Snetchild narg--; 770158766Snetchild c = ','; 771158766Snetchild } else if (ktr->ktr_code == SYS_extattrctl) { 772158766Snetchild print_number(ip,narg,c); 773174346Sjhb (void)putchar(','); 774158766Snetchild extattrctlname((int)*ip); 775158766Snetchild ip++; 776158766Snetchild narg--; 777158766Snetchild } else if (ktr->ktr_code == SYS_nmount) { 778158766Snetchild print_number(ip,narg,c); 779158766Snetchild print_number(ip,narg,c); 780158766Snetchild (void)putchar(','); 781158766Snetchild mountflagsname ((int)*ip); 782158766Snetchild ip++; 783158766Snetchild narg--; 784158766Snetchild } else if (ktr->ktr_code == SYS_thr_create) { 785158766Snetchild print_number(ip,narg,c); 786158766Snetchild print_number(ip,narg,c); 787158766Snetchild (void)putchar(','); 788158766Snetchild thrcreateflagsname ((int)*ip); 789158766Snetchild ip++; 790158766Snetchild narg--; 791158766Snetchild } else if (ktr->ktr_code == SYS_thr_kill) { 792158766Snetchild print_number(ip,narg,c); 793158766Snetchild (void)putchar(','); 794158766Snetchild signame ((int)*ip); 795158766Snetchild ip++; 796158766Snetchild narg--; 797158766Snetchild } else if (ktr->ktr_code == SYS_kldunloadf) { 798158766Snetchild print_number(ip,narg,c); 799158766Snetchild (void)putchar(','); 800158766Snetchild kldunloadfflagsname ((int)*ip); 801158766Snetchild ip++; 802158766Snetchild narg--; 8031590Srgrimes } 8041590Srgrimes } 805199024Sattilio while (narg > 0) { 806158766Snetchild print_number(ip,narg,c); 8071590Srgrimes } 8081590Srgrimes (void)putchar(')'); 8091590Srgrimes } 8101590Srgrimes (void)putchar('\n'); 8111590Srgrimes} 8121590Srgrimes 813100824Sdwmalonevoid 814100824Sdwmalonektrsysret(struct ktr_sysret *ktr) 8151590Srgrimes{ 816100824Sdwmalone register_t ret = ktr->ktr_retval; 817100824Sdwmalone int error = ktr->ktr_error; 818100824Sdwmalone int code = ktr->ktr_code; 8191590Srgrimes 8201590Srgrimes if (code >= nsyscalls || code < 0) 8211590Srgrimes (void)printf("[%d] ", code); 8221590Srgrimes else 8231590Srgrimes (void)printf("%s ", syscallnames[code]); 8241590Srgrimes 8251590Srgrimes if (error == 0) { 8261590Srgrimes if (fancy) { 827203551Sjh (void)printf("%ld", (long)ret); 8281590Srgrimes if (ret < 0 || ret > 9) 82947957Sdt (void)printf("/%#lx", (long)ret); 8301590Srgrimes } else { 8311590Srgrimes if (decimal) 83247957Sdt (void)printf("%ld", (long)ret); 8331590Srgrimes else 83447957Sdt (void)printf("%#lx", (long)ret); 8351590Srgrimes } 8361590Srgrimes } else if (error == ERESTART) 8371590Srgrimes (void)printf("RESTART"); 8381590Srgrimes else if (error == EJUSTRETURN) 8391590Srgrimes (void)printf("JUSTRETURN"); 8401590Srgrimes else { 8411590Srgrimes (void)printf("-1 errno %d", ktr->ktr_error); 8421590Srgrimes if (fancy) 8431590Srgrimes (void)printf(" %s", strerror(ktr->ktr_error)); 8441590Srgrimes } 8451590Srgrimes (void)putchar('\n'); 8461590Srgrimes} 8471590Srgrimes 848100824Sdwmalonevoid 849100824Sdwmalonektrnamei(char *cp, int len) 8501590Srgrimes{ 8511590Srgrimes (void)printf("\"%.*s\"\n", len, cp); 8521590Srgrimes} 8531590Srgrimes 854100824Sdwmalonevoid 855115759Speterhexdump(char *p, int len, int screenwidth) 8561590Srgrimes{ 857115759Speter int n, i; 858115759Speter int width; 859115759Speter 860115759Speter width = 0; 861115759Speter do { 862115759Speter width += 2; 863115759Speter i = 13; /* base offset */ 864115759Speter i += (width / 2) + 1; /* spaces every second byte */ 865115759Speter i += (width * 2); /* width of bytes */ 866115759Speter i += 3; /* " |" */ 867115759Speter i += width; /* each byte */ 868115759Speter i += 1; /* "|" */ 869115759Speter } while (i < screenwidth); 870115759Speter width -= 2; 871115759Speter 872115759Speter for (n = 0; n < len; n += width) { 873115759Speter for (i = n; i < n + width; i++) { 874115759Speter if ((i % width) == 0) { /* beginning of line */ 875115759Speter printf(" 0x%04x", i); 876115759Speter } 877115759Speter if ((i % 2) == 0) { 878115759Speter printf(" "); 879115759Speter } 880115759Speter if (i < len) 881115759Speter printf("%02x", p[i] & 0xff); 882115759Speter else 883115759Speter printf(" "); 884115759Speter } 885115759Speter printf(" |"); 886115759Speter for (i = n; i < n + width; i++) { 887115759Speter if (i >= len) 888115759Speter break; 889115759Speter if (p[i] >= ' ' && p[i] <= '~') 890115759Speter printf("%c", p[i]); 891115759Speter else 892115759Speter printf("."); 893115759Speter } 894115759Speter printf("|\n"); 895115759Speter } 896115759Speter if ((i % width) != 0) 897115759Speter printf("\n"); 898115759Speter} 899115759Speter 900115759Spetervoid 901115759Spetervisdump(char *dp, int datalen, int screenwidth) 902115759Speter{ 903115759Speter int col = 0; 904100824Sdwmalone char *cp; 905100824Sdwmalone int width; 9061590Srgrimes char visbuf[5]; 9071590Srgrimes 9081590Srgrimes (void)printf(" \""); 9091590Srgrimes col = 8; 9101590Srgrimes for (;datalen > 0; datalen--, dp++) { 9111590Srgrimes (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 9121590Srgrimes cp = visbuf; 9131590Srgrimes /* 9141590Srgrimes * Keep track of printables and 9151590Srgrimes * space chars (like fold(1)). 9161590Srgrimes */ 9171590Srgrimes if (col == 0) { 9181590Srgrimes (void)putchar('\t'); 9191590Srgrimes col = 8; 9201590Srgrimes } 9211590Srgrimes switch(*cp) { 9221590Srgrimes case '\n': 9231590Srgrimes col = 0; 9241590Srgrimes (void)putchar('\n'); 9251590Srgrimes continue; 9261590Srgrimes case '\t': 9271590Srgrimes width = 8 - (col&07); 9281590Srgrimes break; 9291590Srgrimes default: 9301590Srgrimes width = strlen(cp); 9311590Srgrimes } 9321590Srgrimes if (col + width > (screenwidth-2)) { 9331590Srgrimes (void)printf("\\\n\t"); 9341590Srgrimes col = 8; 9351590Srgrimes } 9361590Srgrimes col += width; 9371590Srgrimes do { 9381590Srgrimes (void)putchar(*cp++); 9391590Srgrimes } while (*cp); 9401590Srgrimes } 9411590Srgrimes if (col == 0) 9421590Srgrimes (void)printf(" "); 9431590Srgrimes (void)printf("\"\n"); 9441590Srgrimes} 9451590Srgrimes 946115759Spetervoid 947115759Speterktrgenio(struct ktr_genio *ktr, int len) 948115759Speter{ 949115759Speter int datalen = len - sizeof (struct ktr_genio); 950115759Speter char *dp = (char *)ktr + sizeof (struct ktr_genio); 951115759Speter static int screenwidth = 0; 952115759Speter int i, binary; 953115759Speter 954115759Speter if (screenwidth == 0) { 955115759Speter struct winsize ws; 956115759Speter 957115759Speter if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 958115759Speter ws.ws_col > 8) 959115759Speter screenwidth = ws.ws_col; 960115759Speter else 961115759Speter screenwidth = 80; 962115759Speter } 963115759Speter printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 964115759Speter ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 965115759Speter datalen == 1 ? "" : "s"); 966152331Srwatson if (suppressdata) 967152331Srwatson return; 968115759Speter if (maxdata && datalen > maxdata) 969115759Speter datalen = maxdata; 970115759Speter 971115759Speter for (i = 0, binary = 0; i < datalen && binary == 0; i++) { 972115759Speter if (dp[i] >= 32 && dp[i] < 127) 973115759Speter continue; 974115759Speter if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) 975115759Speter continue; 976115759Speter binary = 1; 977115759Speter } 978115759Speter if (binary) 979115759Speter hexdump(dp, datalen, screenwidth); 980115759Speter else 981115759Speter visdump(dp, datalen, screenwidth); 982115759Speter} 983115759Speter 984100824Sdwmaloneconst char *signames[] = { 9851590Srgrimes "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 9861590Srgrimes "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 9871590Srgrimes "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 9881590Srgrimes "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 9891590Srgrimes "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 9901590Srgrimes "USR2", NULL, /* 31 - 32 */ 9911590Srgrimes}; 9921590Srgrimes 993100824Sdwmalonevoid 994100824Sdwmalonektrpsig(struct ktr_psig *psig) 9951590Srgrimes{ 996160294Skib if (psig->signo > 0 && psig->signo < NSIG) 997160296Smaxim (void)printf("SIG%s ", signames[psig->signo]); 998160294Skib else 999160296Smaxim (void)printf("SIG %d ", psig->signo); 10001590Srgrimes if (psig->action == SIG_DFL) 10011590Srgrimes (void)printf("SIG_DFL\n"); 1002100824Sdwmalone else { 100347957Sdt (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 1004100824Sdwmalone (u_long)psig->action, psig->mask.__bits[0], psig->code); 1005100824Sdwmalone } 10061590Srgrimes} 10071590Srgrimes 1008100824Sdwmalonevoid 1009100824Sdwmalonektrcsw(struct ktr_csw *cs) 10101590Srgrimes{ 10111590Srgrimes (void)printf("%s %s\n", cs->out ? "stop" : "resume", 10121590Srgrimes cs->user ? "user" : "kernel"); 10131590Srgrimes} 10141590Srgrimes 1015165916Sjhb#define UTRACE_DLOPEN_START 1 1016165916Sjhb#define UTRACE_DLOPEN_STOP 2 1017165916Sjhb#define UTRACE_DLCLOSE_START 3 1018165916Sjhb#define UTRACE_DLCLOSE_STOP 4 1019165916Sjhb#define UTRACE_LOAD_OBJECT 5 1020165916Sjhb#define UTRACE_UNLOAD_OBJECT 6 1021165916Sjhb#define UTRACE_ADD_RUNDEP 7 1022165916Sjhb#define UTRACE_PRELOAD_FINISHED 8 1023165916Sjhb#define UTRACE_INIT_CALL 9 1024165916Sjhb#define UTRACE_FINI_CALL 10 1025165916Sjhb 1026165916Sjhbstruct utrace_rtld { 1027165916Sjhb char sig[4]; /* 'RTLD' */ 1028165916Sjhb int event; 1029165916Sjhb void *handle; 1030165916Sjhb void *mapbase; 1031165916Sjhb size_t mapsize; 1032165916Sjhb int refcnt; 1033165916Sjhb char name[MAXPATHLEN]; 1034165916Sjhb}; 1035165916Sjhb 1036165916Sjhbvoid 1037165916Sjhbktruser_rtld(int len, unsigned char *p) 1038165916Sjhb{ 1039165916Sjhb struct utrace_rtld *ut = (struct utrace_rtld *)p; 1040165916Sjhb void *parent; 1041165916Sjhb int mode; 1042165916Sjhb 1043165916Sjhb switch (ut->event) { 1044165916Sjhb case UTRACE_DLOPEN_START: 1045165916Sjhb mode = ut->refcnt; 1046165916Sjhb printf("dlopen(%s, ", ut->name); 1047165916Sjhb switch (mode & RTLD_MODEMASK) { 1048165916Sjhb case RTLD_NOW: 1049165916Sjhb printf("RTLD_NOW"); 1050165916Sjhb break; 1051165916Sjhb case RTLD_LAZY: 1052165916Sjhb printf("RTLD_LAZY"); 1053165916Sjhb break; 1054165916Sjhb default: 1055165916Sjhb printf("%#x", mode & RTLD_MODEMASK); 1056165916Sjhb } 1057165916Sjhb if (mode & RTLD_GLOBAL) 1058165916Sjhb printf(" | RTLD_GLOBAL"); 1059165916Sjhb if (mode & RTLD_TRACE) 1060165916Sjhb printf(" | RTLD_TRACE"); 1061165916Sjhb if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)) 1062165916Sjhb printf(" | %#x", mode & 1063165916Sjhb ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)); 1064165916Sjhb printf(")\n"); 1065165916Sjhb break; 1066165916Sjhb case UTRACE_DLOPEN_STOP: 1067165916Sjhb printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name, 1068165916Sjhb ut->refcnt); 1069165916Sjhb break; 1070165916Sjhb case UTRACE_DLCLOSE_START: 1071165916Sjhb printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name, 1072165916Sjhb ut->refcnt); 1073165916Sjhb break; 1074165916Sjhb case UTRACE_DLCLOSE_STOP: 1075165916Sjhb printf("dlclose(%p) finished\n", ut->handle); 1076165916Sjhb break; 1077165916Sjhb case UTRACE_LOAD_OBJECT: 1078165916Sjhb printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle, 1079165916Sjhb ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1080165916Sjhb ut->name); 1081165916Sjhb break; 1082165916Sjhb case UTRACE_UNLOAD_OBJECT: 1083165916Sjhb printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle, 1084165916Sjhb ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1085165916Sjhb ut->name); 1086165916Sjhb break; 1087165916Sjhb case UTRACE_ADD_RUNDEP: 1088165916Sjhb parent = ut->mapbase; 1089165916Sjhb printf("RTLD: %p now depends on %p (%s, %d)\n", parent, 1090165916Sjhb ut->handle, ut->name, ut->refcnt); 1091165916Sjhb break; 1092165916Sjhb case UTRACE_PRELOAD_FINISHED: 1093165916Sjhb printf("RTLD: LD_PRELOAD finished\n"); 1094165916Sjhb break; 1095165916Sjhb case UTRACE_INIT_CALL: 1096165916Sjhb printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle, 1097165916Sjhb ut->name); 1098165916Sjhb break; 1099165916Sjhb case UTRACE_FINI_CALL: 1100165916Sjhb printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle, 1101165916Sjhb ut->name); 1102165916Sjhb break; 1103165916Sjhb default: 1104165916Sjhb p += 4; 1105165916Sjhb len -= 4; 1106165916Sjhb printf("RTLD: %d ", len); 1107165916Sjhb while (len--) 1108165916Sjhb if (decimal) 1109165916Sjhb printf(" %d", *p++); 1110165916Sjhb else 1111165916Sjhb printf(" %02x", *p++); 1112165916Sjhb printf("\n"); 1113165916Sjhb } 1114165916Sjhb} 1115165916Sjhb 1116165812Sjhbstruct utrace_malloc { 1117165812Sjhb void *p; 1118165812Sjhb size_t s; 1119165812Sjhb void *r; 1120165812Sjhb}; 1121165812Sjhb 1122100824Sdwmalonevoid 1123165812Sjhbktruser_malloc(int len, unsigned char *p) 1124165812Sjhb{ 1125165812Sjhb struct utrace_malloc *ut = (struct utrace_malloc *)p; 1126165812Sjhb 1127199265Scperciva if (ut->p == (void *)(intptr_t)(-1)) 1128199265Scperciva printf("malloc_init()\n"); 1129199265Scperciva else if (ut->s == 0) 1130199265Scperciva printf("free(%p)\n", ut->p); 1131199265Scperciva else if (ut->p == NULL) 1132199265Scperciva printf("%p = malloc(%zu)\n", ut->r, ut->s); 1133199265Scperciva else 1134199265Scperciva printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 1135165812Sjhb} 1136165812Sjhb 1137165812Sjhbvoid 1138100824Sdwmalonektruser(int len, unsigned char *p) 113918400Sphk{ 1140165812Sjhb 1141165916Sjhb if (len >= 8 && bcmp(p, "RTLD", 4) == 0) { 1142165916Sjhb ktruser_rtld(len, p); 1143165916Sjhb return; 1144165916Sjhb } 1145165916Sjhb 1146165812Sjhb if (len == sizeof(struct utrace_malloc)) { 1147165812Sjhb ktruser_malloc(len, p); 1148165812Sjhb return; 1149165812Sjhb } 1150165812Sjhb 115118470Sphk (void)printf("%d ", len); 115218470Sphk while (len--) 1153127402Sphk if (decimal) 1154127402Sphk (void)printf(" %d", *p++); 1155127402Sphk else 1156127402Sphk (void)printf(" %02x", *p++); 115718400Sphk (void)printf("\n"); 115818400Sphk} 115918400Sphk 1160100824Sdwmalonevoid 1161176471Sdesktrsockaddr(struct sockaddr *sa) 1162176471Sdes{ 1163176471Sdes/* 1164176471Sdes TODO: Support additional address families 1165176471Sdes #include <netnatm/natm.h> 1166176471Sdes struct sockaddr_natm *natm; 1167176471Sdes #include <netsmb/netbios.h> 1168176471Sdes struct sockaddr_nb *nb; 1169176471Sdes*/ 1170176471Sdes char addr[64]; 1171176471Sdes 1172176471Sdes /* 1173176471Sdes * note: ktrstruct() has already verified that sa points to a 1174176471Sdes * buffer at least sizeof(struct sockaddr) bytes long and exactly 1175176471Sdes * sa->sa_len bytes long. 1176176471Sdes */ 1177176471Sdes printf("struct sockaddr { "); 1178176471Sdes sockfamilyname(sa->sa_family); 1179176471Sdes printf(", "); 1180176471Sdes 1181176471Sdes#define check_sockaddr_len(n) \ 1182176471Sdes if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \ 1183176471Sdes printf("invalid"); \ 1184176471Sdes break; \ 1185176471Sdes } 1186176471Sdes 1187176471Sdes switch(sa->sa_family) { 1188176471Sdes case AF_INET: { 1189176471Sdes struct sockaddr_in *sa_in; 1190176471Sdes 1191176471Sdes sa_in = (struct sockaddr_in *)sa; 1192176471Sdes check_sockaddr_len(in); 1193176471Sdes inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr); 1194176471Sdes printf("%s:%u", addr, ntohs(sa_in->sin_port)); 1195176471Sdes break; 1196176471Sdes } 1197176471Sdes#ifdef NETATALK 1198176471Sdes case AF_APPLETALK: { 1199176471Sdes struct sockaddr_at *sa_at; 1200176471Sdes struct netrange *nr; 1201176471Sdes 1202176471Sdes sa_at = (struct sockaddr_at *)sa; 1203176471Sdes check_sockaddr_len(at); 1204176471Sdes nr = &sa_at->sat_range.r_netrange; 1205176471Sdes printf("%d.%d, %d-%d, %d", ntohs(sa_at->sat_addr.s_net), 1206176471Sdes sa_at->sat_addr.s_node, ntohs(nr->nr_firstnet), 1207176471Sdes ntohs(nr->nr_lastnet), nr->nr_phase); 1208176471Sdes break; 1209176471Sdes } 1210176471Sdes#endif 1211176471Sdes case AF_INET6: { 1212176471Sdes struct sockaddr_in6 *sa_in6; 1213176471Sdes 1214176471Sdes sa_in6 = (struct sockaddr_in6 *)sa; 1215176471Sdes check_sockaddr_len(in6); 1216176471Sdes inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr); 1217176471Sdes printf("[%s]:%u", addr, htons(sa_in6->sin6_port)); 1218176471Sdes break; 1219176471Sdes } 1220176471Sdes#ifdef IPX 1221176471Sdes case AF_IPX: { 1222176471Sdes struct sockaddr_ipx *sa_ipx; 1223176471Sdes 1224176471Sdes sa_ipx = (struct sockaddr_ipx *)sa; 1225176471Sdes check_sockaddr_len(ipx); 1226176471Sdes /* XXX wish we had ipx_ntop */ 1227176471Sdes printf("%s", ipx_ntoa(sa_ipx->sipx_addr)); 1228176471Sdes break; 1229176471Sdes } 1230176471Sdes#endif 1231176471Sdes case AF_UNIX: { 1232176471Sdes struct sockaddr_un *sa_un; 1233176471Sdes 1234176471Sdes sa_un = (struct sockaddr_un *)sa; 1235176471Sdes check_sockaddr_len(un); 1236176471Sdes printf("%.*s", (int)sizeof(sa_un->sun_path), sa_un->sun_path); 1237176471Sdes break; 1238176471Sdes } 1239176471Sdes default: 1240176471Sdes printf("unknown address family"); 1241176471Sdes } 1242176471Sdes printf(" }\n"); 1243176471Sdes} 1244176471Sdes 1245176471Sdesvoid 1246176471Sdesktrstat(struct stat *statp) 1247176471Sdes{ 1248176471Sdes char mode[12], timestr[PATH_MAX + 4]; 1249176471Sdes struct passwd *pwd; 1250176471Sdes struct group *grp; 1251176471Sdes struct tm *tm; 1252176471Sdes 1253176471Sdes /* 1254176471Sdes * note: ktrstruct() has already verified that statp points to a 1255176471Sdes * buffer exactly sizeof(struct stat) bytes long. 1256176471Sdes */ 1257176471Sdes printf("struct stat {"); 1258176471Sdes strmode(statp->st_mode, mode); 1259176471Sdes printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ", 1260176471Sdes (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode, 1261176471Sdes (uintmax_t)statp->st_nlink); 1262176471Sdes if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL) 1263176471Sdes printf("uid=%ju, ", (uintmax_t)statp->st_uid); 1264176471Sdes else 1265176471Sdes printf("uid=\"%s\", ", pwd->pw_name); 1266176471Sdes if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL) 1267176471Sdes printf("gid=%ju, ", (uintmax_t)statp->st_gid); 1268176471Sdes else 1269176471Sdes printf("gid=\"%s\", ", grp->gr_name); 1270176471Sdes printf("rdev=%ju, ", (uintmax_t)statp->st_rdev); 1271176471Sdes printf("atime="); 1272176471Sdes if (resolv == 0) 1273203551Sjh printf("%jd", (intmax_t)statp->st_atimespec.tv_sec); 1274176471Sdes else { 1275176471Sdes tm = localtime(&statp->st_atimespec.tv_sec); 1276176471Sdes (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1277176471Sdes printf("\"%s\"", timestr); 1278176471Sdes } 1279176471Sdes if (statp->st_atimespec.tv_nsec != 0) 1280176471Sdes printf(".%09ld, ", statp->st_atimespec.tv_nsec); 1281176471Sdes else 1282176471Sdes printf(", "); 1283176471Sdes printf("stime="); 1284176471Sdes if (resolv == 0) 1285203551Sjh printf("%jd", (intmax_t)statp->st_mtimespec.tv_sec); 1286176471Sdes else { 1287176471Sdes tm = localtime(&statp->st_mtimespec.tv_sec); 1288176471Sdes (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1289176471Sdes printf("\"%s\"", timestr); 1290176471Sdes } 1291176471Sdes if (statp->st_mtimespec.tv_nsec != 0) 1292176471Sdes printf(".%09ld, ", statp->st_mtimespec.tv_nsec); 1293176471Sdes else 1294176471Sdes printf(", "); 1295176471Sdes printf("ctime="); 1296176471Sdes if (resolv == 0) 1297203551Sjh printf("%jd", (intmax_t)statp->st_ctimespec.tv_sec); 1298176471Sdes else { 1299176471Sdes tm = localtime(&statp->st_ctimespec.tv_sec); 1300176471Sdes (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1301176471Sdes printf("\"%s\"", timestr); 1302176471Sdes } 1303176471Sdes if (statp->st_ctimespec.tv_nsec != 0) 1304176471Sdes printf(".%09ld, ", statp->st_ctimespec.tv_nsec); 1305176471Sdes else 1306176471Sdes printf(", "); 1307176471Sdes printf("birthtime="); 1308176471Sdes if (resolv == 0) 1309203551Sjh printf("%jd", (intmax_t)statp->st_birthtimespec.tv_sec); 1310176471Sdes else { 1311176471Sdes tm = localtime(&statp->st_birthtimespec.tv_sec); 1312176471Sdes (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); 1313176471Sdes printf("\"%s\"", timestr); 1314176471Sdes } 1315176471Sdes if (statp->st_birthtimespec.tv_nsec != 0) 1316176471Sdes printf(".%09ld, ", statp->st_birthtimespec.tv_nsec); 1317176471Sdes else 1318176471Sdes printf(", "); 1319176471Sdes printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x", 1320176471Sdes (uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize, 1321176471Sdes (intmax_t)statp->st_blocks, statp->st_flags); 1322176471Sdes printf(" }\n"); 1323176471Sdes} 1324176471Sdes 1325176471Sdesvoid 1326176471Sdesktrstruct(char *buf, size_t buflen) 1327176471Sdes{ 1328176471Sdes char *name, *data; 1329176471Sdes size_t namelen, datalen; 1330176471Sdes int i; 1331176471Sdes 1332176471Sdes for (name = buf, namelen = 0; 1333176471Sdes namelen < buflen && name[namelen] != '\0'; 1334176471Sdes ++namelen) 1335176471Sdes /* nothing */; 1336176471Sdes if (namelen == buflen) 1337176471Sdes goto invalid; 1338176471Sdes if (name[namelen] != '\0') 1339176471Sdes goto invalid; 1340176471Sdes data = buf + namelen + 1; 1341176471Sdes datalen = buflen - namelen - 1; 1342176471Sdes if (datalen == 0) 1343176471Sdes goto invalid; 1344176471Sdes /* sanity check */ 1345176471Sdes for (i = 0; i < namelen; ++i) 1346176471Sdes if (!isalpha((unsigned char)name[i])) 1347176471Sdes goto invalid; 1348176471Sdes if (strcmp(name, "stat") == 0) { 1349176471Sdes if (datalen != sizeof(struct stat)) 1350176471Sdes goto invalid; 1351176471Sdes ktrstat((struct stat *)data); 1352176471Sdes } else if (strcmp(name, "sockaddr") == 0) { 1353176471Sdes if (datalen < sizeof(struct sockaddr) || 1354176471Sdes datalen != ((struct sockaddr *)(data))->sa_len) 1355176471Sdes goto invalid; 1356176471Sdes ktrsockaddr((struct sockaddr *)data); 1357176471Sdes } else { 1358176471Sdes printf("unknown structure\n"); 1359176471Sdes } 1360176471Sdes return; 1361176471Sdesinvalid: 1362176471Sdes printf("invalid record\n"); 1363176471Sdes} 1364176471Sdes 1365176471Sdesvoid 1366100824Sdwmaloneusage(void) 13671590Srgrimes{ 1368176471Sdes fprintf(stderr, "usage: kdump [-dEnlHRrsT] [-f trfile] " 1369177856Sru "[-m maxdata] [-p pid] [-t trstr]\n"); 13701590Srgrimes exit(1); 13711590Srgrimes} 1372