kdump.c revision 175138
124139Sjoerg/*- 224139Sjoerg * Copyright (c) 1988, 1993 324139Sjoerg * The Regents of the University of California. All rights reserved. 424139Sjoerg * 524139Sjoerg * Redistribution and use in source and binary forms, with or without 624139Sjoerg * modification, are permitted provided that the following conditions 724139Sjoerg * are met: 824139Sjoerg * 1. Redistributions of source code must retain the above copyright 924139Sjoerg * notice, this list of conditions and the following disclaimer. 1024139Sjoerg * 2. Redistributions in binary form must reproduce the above copyright 1124139Sjoerg * notice, this list of conditions and the following disclaimer in the 1289757Sdwmalone * documentation and/or other materials provided with the distribution. 1389757Sdwmalone * 3. All advertising materials mentioning features or use of this software 1489757Sdwmalone * must display the following acknowledgement: 1566641Simp * This product includes software developed by the University of 1666641Simp * California, Berkeley and its contributors. 1724139Sjoerg * 4. Neither the name of the University nor the names of its contributors 1824139Sjoerg * may be used to endorse or promote products derived from this software 1924139Sjoerg * without specific prior written permission. 2024139Sjoerg * 2124139Sjoerg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2224139Sjoerg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2324139Sjoerg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2424139Sjoerg * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2524139Sjoerg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2624139Sjoerg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2724139Sjoerg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2824139Sjoerg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2924139Sjoerg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3024139Sjoerg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3124139Sjoerg * SUCH DAMAGE. 3224139Sjoerg */ 3324139Sjoerg 3424139Sjoerg#ifndef lint 3524139Sjoergstatic const char copyright[] = 3624139Sjoerg"@(#) Copyright (c) 1988, 1993\n\ 3786042Sdwmalone The Regents of the University of California. All rights reserved.\n"; 3824139Sjoerg#endif /* not lint */ 3924139Sjoerg 4024139Sjoerg#ifndef lint 4124139Sjoerg#if 0 4224139Sjoergstatic char sccsid[] = "@(#)kdump.c 8.1 (Berkeley) 6/6/93"; 4324139Sjoerg#endif 4424139Sjoerg#endif /* not lint */ 4524139Sjoerg#include <sys/cdefs.h> 4624139Sjoerg__FBSDID("$FreeBSD: head/usr.bin/kdump/kdump.c 175138 2008-01-07 18:50:25Z jhb $"); 4724139Sjoerg 4824139Sjoerg#define _KERNEL 4924139Sjoergextern int errno; 5024139Sjoerg#include <sys/errno.h> 5124139Sjoerg#undef _KERNEL 5224139Sjoerg#include <sys/param.h> 5324139Sjoerg#include <sys/errno.h> 5424139Sjoerg#define _KERNEL 5524139Sjoerg#include <sys/time.h> 5624139Sjoerg#undef _KERNEL 5724139Sjoerg#include <sys/uio.h> 5824139Sjoerg#include <sys/ktrace.h> 5924139Sjoerg#include <sys/ioctl.h> 6024139Sjoerg#include <sys/socket.h> 6124139Sjoerg#include <dlfcn.h> 6224139Sjoerg#include <err.h> 6324139Sjoerg#include <locale.h> 6424139Sjoerg#include <stdio.h> 6524139Sjoerg#include <stdlib.h> 6624139Sjoerg#include <string.h> 6724139Sjoerg#include <unistd.h> 68168710Sstas#include <vis.h> 69175420Speter#include "ktrace.h" 70168710Sstas#include "kdump_subr.h" 7124139Sjoerg 7224139Sjoergint fread_tail(void *, int, int); 7324139Sjoergvoid dumpheader(struct ktr_header *); 7424139Sjoergvoid ktrsyscall(struct ktr_syscall *); 7524139Sjoergvoid ktrsysret(struct ktr_sysret *); 7624139Sjoergvoid ktrnamei(char *, int); 7724139Sjoergvoid hexdump(char *, int, int); 7824139Sjoergvoid visdump(char *, int, int); 7981187Skrisvoid ktrgenio(struct ktr_genio *, int); 8081187Skrisvoid ktrpsig(struct ktr_psig *); 8181187Skrisvoid ktrcsw(struct ktr_csw *); 8281187Skrisvoid ktruser(int, unsigned char *); 8324139Sjoergvoid usage(void); 8424139Sjoergconst char *ioctlname(u_long); 8524139Sjoerg 8624139Sjoergint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata; 8724139Sjoergconst char *tracefile = DEF_TRACEFILE; 8824139Sjoergstruct ktr_header ktr_header; 8924139Sjoerg 90145073Skeramida#define eqs(s1, s2) (strcmp((s1), (s2)) == 0) 9124139Sjoerg 9224139Sjoergint 9324139Sjoergmain(int argc, char *argv[]) 9424139Sjoerg{ 9524139Sjoerg int ch, ktrlen, size; 9624139Sjoerg void *m; 9724139Sjoerg int trpoints = ALL_POINTS; 9824139Sjoerg int drop_logged; 9924139Sjoerg pid_t pid = 0; 10024139Sjoerg 10124139Sjoerg (void) setlocale(LC_CTYPE, ""); 102133817Salfred 10324139Sjoerg while ((ch = getopt(argc,argv,"f:dElm:np:HRsTt:")) != -1) 10424139Sjoerg switch((char)ch) { 105131829Skeramida case 'f': 10624139Sjoerg tracefile = optarg; 10724139Sjoerg break; 10824139Sjoerg case 'd': 10924139Sjoerg decimal = 1; 11024139Sjoerg break; 11124139Sjoerg case 'l': 11224139Sjoerg tail = 1; 11324139Sjoerg break; 11424139Sjoerg case 'm': 11524139Sjoerg maxdata = atoi(optarg); 11624139Sjoerg break; 11724139Sjoerg case 'n': 11824139Sjoerg fancy = 0; 11924139Sjoerg break; 12024139Sjoerg case 'p': 12124139Sjoerg pid = atoi(optarg); 12224139Sjoerg break; 12324139Sjoerg case 's': 12424139Sjoerg suppressdata = 1; 12524142Sjoerg break; 12624142Sjoerg case 'E': 12724139Sjoerg timestamp = 3; /* elapsed timestamp */ 12824139Sjoerg break; 12924139Sjoerg case 'H': 13024139Sjoerg threads = 1; 13124139Sjoerg break; 13224139Sjoerg case 'R': 13324139Sjoerg timestamp = 2; /* relative timestamp */ 13424139Sjoerg break; 13524139Sjoerg case 'T': 13624139Sjoerg timestamp = 1; 13724139Sjoerg break; 13824139Sjoerg case 't': 13924142Sjoerg trpoints = getpoints(optarg); 14024139Sjoerg if (trpoints < 0) 14124139Sjoerg errx(1, "unknown trace point in %s", optarg); 14224139Sjoerg break; 14324139Sjoerg default: 14424139Sjoerg usage(); 14524139Sjoerg } 14624139Sjoerg 14724139Sjoerg if (argc > optind) 14824139Sjoerg usage(); 14924139Sjoerg 15024139Sjoerg m = (void *)malloc(size = 1025); 15124139Sjoerg if (m == NULL) 15224139Sjoerg errx(1, "%s", strerror(ENOMEM)); 15324139Sjoerg if (!freopen(tracefile, "r", stdin)) 15424139Sjoerg err(1, "%s", tracefile); 15524139Sjoerg drop_logged = 0; 15624139Sjoerg while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { 15724139Sjoerg if (ktr_header.ktr_type & KTR_DROP) { 15824139Sjoerg ktr_header.ktr_type &= ~KTR_DROP; 15924139Sjoerg if (!drop_logged && threads) { 16024139Sjoerg (void)printf("%6d %6d %-8.*s Events dropped.\n", 16124139Sjoerg ktr_header.ktr_pid, ktr_header.ktr_tid > 16224139Sjoerg 0 ? ktr_header.ktr_tid : 0, MAXCOMLEN, 16324139Sjoerg ktr_header.ktr_comm); 16424139Sjoerg drop_logged = 1; 16586042Sdwmalone } else if (!drop_logged) { 16624139Sjoerg (void)printf("%6d %-8.*s Events dropped.\n", 16724139Sjoerg ktr_header.ktr_pid, MAXCOMLEN, 16824139Sjoerg ktr_header.ktr_comm); 16924139Sjoerg drop_logged = 1; 17024139Sjoerg } 17124139Sjoerg } 17224139Sjoerg if (trpoints & (1<<ktr_header.ktr_type)) 17324139Sjoerg if (pid == 0 || ktr_header.ktr_pid == pid) 17424139Sjoerg dumpheader(&ktr_header); 17524139Sjoerg if ((ktrlen = ktr_header.ktr_len) < 0) 17624139Sjoerg errx(1, "bogus length 0x%x", ktrlen); 17724139Sjoerg if (ktrlen > size) { 17824139Sjoerg m = (void *)realloc(m, ktrlen+1); 17924139Sjoerg if (m == NULL) 18024139Sjoerg errx(1, "%s", strerror(ENOMEM)); 18124139Sjoerg size = ktrlen; 18224139Sjoerg } 18324139Sjoerg if (ktrlen && fread_tail(m, ktrlen, 1) == 0) 18424139Sjoerg errx(1, "data too short"); 18524139Sjoerg if (pid && ktr_header.ktr_pid != pid) 18624139Sjoerg continue; 18724139Sjoerg if ((trpoints & (1<<ktr_header.ktr_type)) == 0) 18824139Sjoerg continue; 18924139Sjoerg drop_logged = 0; 19024139Sjoerg switch (ktr_header.ktr_type) { 19124139Sjoerg case KTR_SYSCALL: 19224139Sjoerg ktrsyscall((struct ktr_syscall *)m); 19324139Sjoerg break; 19489757Sdwmalone case KTR_SYSRET: 19524139Sjoerg ktrsysret((struct ktr_sysret *)m); 19624139Sjoerg break; 19724139Sjoerg case KTR_NAMEI: 19824139Sjoerg ktrnamei(m, ktrlen); 199223936Sjhb break; 20024139Sjoerg case KTR_GENIO: 201223936Sjhb ktrgenio((struct ktr_genio *)m, ktrlen); 20224139Sjoerg break; 20324139Sjoerg case KTR_PSIG: 20424139Sjoerg ktrpsig((struct ktr_psig *)m); 20524139Sjoerg break; 20624139Sjoerg case KTR_CSW: 20724139Sjoerg ktrcsw((struct ktr_csw *)m); 20824139Sjoerg break; 20924139Sjoerg case KTR_USER: 21024139Sjoerg ktruser(ktrlen, m); 21124139Sjoerg break; 21224139Sjoerg default: 21324139Sjoerg printf("\n"); 21424139Sjoerg break; 21524139Sjoerg } 21624139Sjoerg if (tail) 21724139Sjoerg (void)fflush(stdout); 21824139Sjoerg } 21924139Sjoerg return 0; 22038090Sdes} 221117709Sjulian 222131402Salfredint 223132005Salfredfread_tail(void *buf, int size, int num) 224146342Skeramida{ 225168710Sstas int i; 226168799Srafan 227222530Sjhb while ((i = fread(buf, size, num, stdin)) == 0 && tail) { 228223936Sjhb (void)sleep(1); 22924139Sjoerg clearerr(stdin); 230223936Sjhb } 23124139Sjoerg return (i); 23224139Sjoerg} 23324139Sjoerg 23424139Sjoergvoid 23589757Sdwmalonedumpheader(struct ktr_header *kth) 23689757Sdwmalone{ 23724139Sjoerg static char unknown[64]; 23824139Sjoerg static struct timeval prevtime, temp; 23924139Sjoerg const char *type; 24024139Sjoerg 24124139Sjoerg switch (kth->ktr_type) { 24224139Sjoerg case KTR_SYSCALL: 24324139Sjoerg type = "CALL"; 24424139Sjoerg break; 24524139Sjoerg case KTR_SYSRET: 24624139Sjoerg type = "RET "; 24724139Sjoerg break; 24824139Sjoerg case KTR_NAMEI: 24924139Sjoerg type = "NAMI"; 25024139Sjoerg break; 25124139Sjoerg case KTR_GENIO: 25224139Sjoerg type = "GIO "; 25324139Sjoerg break; 25424139Sjoerg case KTR_PSIG: 25524139Sjoerg type = "PSIG"; 25624139Sjoerg break; 25738090Sdes case KTR_CSW: 25824139Sjoerg type = "CSW "; 25924139Sjoerg break; 260117709Sjulian case KTR_USER: 261146342Skeramida type = "USER"; 262168799Srafan break; 263222530Sjhb default: 26424139Sjoerg (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); 26524139Sjoerg type = unknown; 26624139Sjoerg } 26724139Sjoerg 26824139Sjoerg /* 26924139Sjoerg * The ktr_tid field was previously the ktr_buffer field, which held 27024139Sjoerg * the kernel pointer value for the buffer associated with data 27124139Sjoerg * following the record header. It now holds a threadid, but only 27224139Sjoerg * for trace files after the change. Older trace files still contain 27324139Sjoerg * kernel pointers. Detect this and suppress the results by printing 27424139Sjoerg * negative tid's as 0. 27524139Sjoerg */ 27624139Sjoerg if (threads) 27724139Sjoerg (void)printf("%6d %6d %-8.*s ", kth->ktr_pid, kth->ktr_tid > 27824139Sjoerg 0 ? kth->ktr_tid : 0, MAXCOMLEN, kth->ktr_comm); 27924139Sjoerg else 28024139Sjoerg (void)printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, 28124139Sjoerg kth->ktr_comm); 28224139Sjoerg if (timestamp) { 28324139Sjoerg if (timestamp == 3) { 28424139Sjoerg if (prevtime.tv_sec == 0) 28524139Sjoerg prevtime = kth->ktr_time; 28624139Sjoerg timevalsub(&kth->ktr_time, &prevtime); 28724139Sjoerg } 28824139Sjoerg if (timestamp == 2) { 289222530Sjhb temp = kth->ktr_time; 29024139Sjoerg timevalsub(&kth->ktr_time, &prevtime); 29124139Sjoerg prevtime = temp; 29224139Sjoerg } 29389757Sdwmalone (void)printf("%ld.%06ld ", 29489757Sdwmalone kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); 29589757Sdwmalone } 29689757Sdwmalone (void)printf("%s ", type); 29789757Sdwmalone} 29889757Sdwmalone 29924139Sjoerg#include <sys/syscall.h> 30024139Sjoerg#define KTRACE 30124139Sjoerg#include <sys/kern/syscalls.c> 30224139Sjoerg#undef KTRACE 30324139Sjoergint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); 30424139Sjoerg 30524139Sjoergvoid 30624139Sjoergktrsyscall(struct ktr_syscall *ktr) 30724139Sjoerg{ 30824139Sjoerg int narg = ktr->ktr_narg; 30924139Sjoerg register_t *ip; 31024139Sjoerg 31124139Sjoerg if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) 31224139Sjoerg (void)printf("[%d]", ktr->ktr_code); 31324139Sjoerg else 31424139Sjoerg (void)printf("%s", syscallnames[ktr->ktr_code]); 31524139Sjoerg ip = &ktr->ktr_args[0]; 31624139Sjoerg if (narg) { 31724139Sjoerg char c = '('; 31824139Sjoerg if (fancy) { 31924139Sjoerg 32024139Sjoerg#define print_number(i,n,c) do { \ 32124139Sjoerg if (decimal) \ 32224139Sjoerg (void)printf("%c%ld", c, (long)*i); \ 32324139Sjoerg else \ 32424139Sjoerg (void)printf("%c%#lx", c, (long)*i); \ 32524139Sjoerg i++; \ 32624139Sjoerg n--; \ 32724139Sjoerg c = ','; \ 328168710Sstas } while (0); 329168710Sstas 330168710Sstas if (ktr->ktr_code == SYS_ioctl) { 331168710Sstas const char *cp; 33224139Sjoerg print_number(ip,narg,c); 33324139Sjoerg if ((cp = ioctlname(*ip)) != NULL) 33424139Sjoerg (void)printf(",%s", cp); 33524139Sjoerg else { 33624139Sjoerg if (decimal) 33724139Sjoerg (void)printf(",%ld", (long)*ip); 33824139Sjoerg else 33924139Sjoerg (void)printf(",%#lx ", (long)*ip); 34024139Sjoerg } 34124139Sjoerg c = ','; 34224139Sjoerg ip++; 34324139Sjoerg narg--; 34424139Sjoerg } else if (ktr->ktr_code == SYS_ptrace) { 34524139Sjoerg (void)putchar('('); 34624139Sjoerg ptraceopname ((int)*ip); 34789757Sdwmalone c = ','; 34824139Sjoerg ip++; 34924139Sjoerg narg--; 35089757Sdwmalone } else if (ktr->ktr_code == SYS_access || 35124139Sjoerg ktr->ktr_code == SYS_eaccess) { 35224139Sjoerg print_number(ip,narg,c); 35324139Sjoerg (void)putchar(','); 35424139Sjoerg accessmodename ((int)*ip); 35524139Sjoerg ip++; 35624139Sjoerg narg--; 35724139Sjoerg } else if (ktr->ktr_code == SYS_open) { 35824139Sjoerg int flags; 35924139Sjoerg int mode; 36024139Sjoerg print_number(ip,narg,c); 36124139Sjoerg flags = *ip; 36224139Sjoerg mode = *++ip; 36324139Sjoerg (void)putchar(','); 36424139Sjoerg flagsandmodename (flags, mode, decimal); 36524139Sjoerg ip++; 36624139Sjoerg narg-=2; 36724139Sjoerg } else if (ktr->ktr_code == SYS_wait4) { 36824139Sjoerg print_number(ip,narg,c); 36924139Sjoerg print_number(ip,narg,c); 37024139Sjoerg (void)putchar(','); 37124139Sjoerg wait4optname ((int)*ip); 37224139Sjoerg ip++; 373131616Sdes narg--; 374131402Salfred } else if (ktr->ktr_code == SYS_chmod || 375131402Salfred ktr->ktr_code == SYS_fchmod || 376131402Salfred ktr->ktr_code == SYS_lchmod) { 377131402Salfred print_number(ip,narg,c); 378131402Salfred (void)putchar(','); 379131402Salfred modename ((int)*ip); 380131402Salfred ip++; 381131402Salfred narg--; 382131402Salfred } else if (ktr->ktr_code == SYS_mknod) { 383131402Salfred print_number(ip,narg,c); 384131402Salfred (void)putchar(','); 385131402Salfred modename ((int)*ip); 386131402Salfred ip++; 38724139Sjoerg narg--; 38824139Sjoerg } else if (ktr->ktr_code == SYS_getfsstat) { 38924139Sjoerg print_number(ip,narg,c); 39024139Sjoerg print_number(ip,narg,c); 39124139Sjoerg (void)putchar(','); 39224139Sjoerg getfsstatflagsname ((int)*ip); 39324139Sjoerg ip++; 39424139Sjoerg narg--; 39524139Sjoerg } else if (ktr->ktr_code == SYS_mount) { 39624139Sjoerg print_number(ip,narg,c); 39724139Sjoerg print_number(ip,narg,c); 39838090Sdes (void)putchar(','); 39938090Sdes mountflagsname ((int)*ip); 40038090Sdes ip++; 401146342Skeramida narg--; 402146342Skeramida } else if (ktr->ktr_code == SYS_unmount) { 403146342Skeramida print_number(ip,narg,c); 404146342Skeramida (void)putchar(','); 405146342Skeramida mountflagsname ((int)*ip); 406117709Sjulian ip++; 407117709Sjulian narg--; 408117709Sjulian } else if (ktr->ktr_code == SYS_recvmsg || 409146342Skeramida ktr->ktr_code == SYS_sendmsg) { 410168799Srafan print_number(ip,narg,c); 411168799Srafan print_number(ip,narg,c); 412168799Srafan (void)putchar(','); 413168799Srafan sendrecvflagsname ((int)*ip); 414175420Speter ip++; 415223936Sjhb narg--; 416175420Speter } else if (ktr->ktr_code == SYS_recvfrom || 417175420Speter ktr->ktr_code == SYS_sendto) { 418222530Sjhb print_number(ip,narg,c); 419222530Sjhb print_number(ip,narg,c); 420222530Sjhb print_number(ip,narg,c); 421222530Sjhb (void)putchar(','); 42224139Sjoerg sendrecvflagsname ((int)*ip); 423157842Sru ip++; 424157842Sru narg--; 425222530Sjhb } else if (ktr->ktr_code == SYS_chflags || 426157842Sru ktr->ktr_code == SYS_fchflags || 42724139Sjoerg ktr->ktr_code == SYS_lchflags) { 42824139Sjoerg print_number(ip,narg,c); 42924139Sjoerg (void)putchar(','); 43024139Sjoerg modename((int)*ip); 43124139Sjoerg ip++; 43224139Sjoerg narg--; 43324139Sjoerg } else if (ktr->ktr_code == SYS_kill) { 43424139Sjoerg print_number(ip,narg,c); 43524139Sjoerg (void)putchar(','); 43624139Sjoerg signame((int)*ip); 43724139Sjoerg ip++; 43824139Sjoerg narg--; 43924139Sjoerg } else if (ktr->ktr_code == SYS_reboot) { 44024139Sjoerg (void)putchar('('); 44124139Sjoerg rebootoptname((int)*ip); 44224139Sjoerg ip++; 44324139Sjoerg narg--; 44424139Sjoerg } else if (ktr->ktr_code == SYS_umask) { 44524139Sjoerg (void)putchar('('); 44624139Sjoerg modename((int)*ip); 44724139Sjoerg ip++; 44824139Sjoerg narg--; 44924139Sjoerg } else if (ktr->ktr_code == SYS_msync) { 45024139Sjoerg print_number(ip,narg,c); 45124139Sjoerg print_number(ip,narg,c); 45224139Sjoerg (void)putchar(','); 45324139Sjoerg msyncflagsname((int)*ip); 45424139Sjoerg ip++; 45524139Sjoerg narg--; 45624139Sjoerg#ifdef SYS_freebsd6_mmap 45724139Sjoerg } else if (ktr->ktr_code == SYS_freebsd6_mmap) { 45824139Sjoerg print_number(ip,narg,c); 45924139Sjoerg print_number(ip,narg,c); 46024139Sjoerg (void)putchar(','); 46124139Sjoerg mmapprotname ((int)*ip); 46224139Sjoerg (void)putchar(','); 46324139Sjoerg ip++; 46424139Sjoerg narg--; 465175195Sobrien mmapflagsname ((int)*ip); 46624139Sjoerg ip++; 46724139Sjoerg narg--; 46824139Sjoerg#endif 46924139Sjoerg } else if (ktr->ktr_code == SYS_mmap) { 47024139Sjoerg print_number(ip,narg,c); 47124139Sjoerg print_number(ip,narg,c); 47224139Sjoerg (void)putchar(','); 47324139Sjoerg mmapprotname ((int)*ip); 47424139Sjoerg (void)putchar(','); 47524139Sjoerg ip++; 47624139Sjoerg narg--; 47724139Sjoerg mmapflagsname ((int)*ip); 47824139Sjoerg ip++; 47924139Sjoerg narg--; 48024139Sjoerg } else if (ktr->ktr_code == SYS_mprotect) { 48124139Sjoerg print_number(ip,narg,c); 48224139Sjoerg print_number(ip,narg,c); 48324139Sjoerg (void)putchar(','); 48424139Sjoerg mmapprotname ((int)*ip); 48524139Sjoerg ip++; 48624139Sjoerg narg--; 48724139Sjoerg } else if (ktr->ktr_code == SYS_madvise) { 48824139Sjoerg print_number(ip,narg,c); 48924139Sjoerg print_number(ip,narg,c); 49024139Sjoerg (void)putchar(','); 49124139Sjoerg madvisebehavname((int)*ip); 49224139Sjoerg ip++; 49324139Sjoerg narg--; 49424139Sjoerg } else if (ktr->ktr_code == SYS_setpriority) { 49524139Sjoerg print_number(ip,narg,c); 49624139Sjoerg print_number(ip,narg,c); 49724139Sjoerg (void)putchar(','); 49824139Sjoerg prioname((int)*ip); 49924139Sjoerg ip++; 50024139Sjoerg narg--; 50124139Sjoerg } else if (ktr->ktr_code == SYS_fcntl) { 50224139Sjoerg int cmd; 50324139Sjoerg int arg; 50424139Sjoerg print_number(ip,narg,c); 50524139Sjoerg cmd = *ip; 50624139Sjoerg arg = *++ip; 50724139Sjoerg (void)putchar(','); 50824139Sjoerg fcntlcmdname(cmd, arg, decimal); 50924139Sjoerg ip++; 51024139Sjoerg narg-=2; 51124139Sjoerg } else if (ktr->ktr_code == SYS_socket) { 51224139Sjoerg int sockdomain; 51324139Sjoerg (void)putchar('('); 51424139Sjoerg sockdomain=(int)*ip; 51524139Sjoerg sockdomainname(sockdomain); 51624139Sjoerg ip++; 51724139Sjoerg narg--; 51824139Sjoerg (void)putchar(','); 51924139Sjoerg socktypename((int)*ip); 52024139Sjoerg ip++; 52124139Sjoerg narg--; 52224139Sjoerg if (sockdomain == PF_INET || 52324139Sjoerg sockdomain == PF_INET6) { 52424139Sjoerg (void)putchar(','); 52524139Sjoerg sockipprotoname((int)*ip); 52624139Sjoerg ip++; 52724139Sjoerg narg--; 52824139Sjoerg } 52924139Sjoerg c = ','; 53024139Sjoerg } else if (ktr->ktr_code == SYS_setsockopt || 53124139Sjoerg ktr->ktr_code == SYS_getsockopt) { 53224139Sjoerg print_number(ip,narg,c); 53324139Sjoerg (void)putchar(','); 53424139Sjoerg sockoptlevelname((int)*ip, decimal); 53524139Sjoerg if ((int)*ip == SOL_SOCKET) { 53624139Sjoerg ip++; 53724139Sjoerg narg--; 53824139Sjoerg (void)putchar(','); 53924139Sjoerg sockoptname((int)*ip); 54024139Sjoerg } 54124139Sjoerg ip++; 54224139Sjoerg narg--; 54324139Sjoerg#ifdef SYS_freebsd6_lseek 54424139Sjoerg } else if (ktr->ktr_code == SYS_freebsd6_lseek) { 54524139Sjoerg print_number(ip,narg,c); 54624139Sjoerg /* Hidden 'pad' argument, not in lseek(2) */ 54724139Sjoerg print_number(ip,narg,c); 54824139Sjoerg print_number(ip,narg,c); 54924139Sjoerg (void)putchar(','); 55024139Sjoerg whencename ((int)*ip); 55124139Sjoerg ip++; 55224139Sjoerg narg--; 55324139Sjoerg#endif 55424139Sjoerg } else if (ktr->ktr_code == SYS_lseek) { 55524139Sjoerg print_number(ip,narg,c); 55624139Sjoerg /* Hidden 'pad' argument, not in lseek(2) */ 55724139Sjoerg print_number(ip,narg,c); 55824139Sjoerg (void)putchar(','); 55924139Sjoerg whencename ((int)*ip); 56024139Sjoerg ip++; 56124139Sjoerg narg--; 56224139Sjoerg 56324139Sjoerg } else if (ktr->ktr_code == SYS_flock) { 56424139Sjoerg print_number(ip,narg,c); 56524139Sjoerg (void)putchar(','); 56624139Sjoerg flockname((int)*ip); 56724139Sjoerg ip++; 56824139Sjoerg narg--; 56924139Sjoerg } else if (ktr->ktr_code == SYS_mkfifo || 57024139Sjoerg ktr->ktr_code == SYS_mkdir) { 57124139Sjoerg print_number(ip,narg,c); 57224139Sjoerg (void)putchar(','); 57324139Sjoerg modename((int)*ip); 57424139Sjoerg ip++; 57524139Sjoerg narg--; 57624139Sjoerg } else if (ktr->ktr_code == SYS_shutdown) { 57724139Sjoerg print_number(ip,narg,c); 57824139Sjoerg (void)putchar(','); 57924139Sjoerg shutdownhowname((int)*ip); 58024139Sjoerg ip++; 58124139Sjoerg narg--; 58224139Sjoerg } else if (ktr->ktr_code == SYS_socketpair) { 58324139Sjoerg (void)putchar('('); 58424139Sjoerg sockdomainname((int)*ip); 58524139Sjoerg ip++; 58624139Sjoerg narg--; 58724139Sjoerg (void)putchar(','); 58881187Skris socktypename((int)*ip); 58924139Sjoerg ip++; 59024139Sjoerg narg--; 59124139Sjoerg c = ','; 59224139Sjoerg } else if (ktr->ktr_code == SYS_getrlimit || 59324139Sjoerg ktr->ktr_code == SYS_setrlimit) { 59424139Sjoerg (void)putchar('('); 59524139Sjoerg rlimitname((int)*ip); 59624139Sjoerg ip++; 597131402Salfred narg--; 598131402Salfred c = ','; 599131402Salfred } else if (ktr->ktr_code == SYS_quotactl) { 60024139Sjoerg print_number(ip,narg,c); 60124139Sjoerg (void)putchar(','); 60224139Sjoerg quotactlname((int)*ip); 60324139Sjoerg ip++; 604133817Salfred narg--; 60524139Sjoerg c = ','; 606131829Skeramida } else if (ktr->ktr_code == SYS_nfssvc) { 607131402Salfred (void)putchar('('); 608131829Skeramida nfssvcname((int)*ip); 609131829Skeramida ip++; 61024139Sjoerg narg--; 61124139Sjoerg c = ','; 612131402Salfred } else if (ktr->ktr_code == SYS_rtprio) { 613131402Salfred (void)putchar('('); 614131402Salfred rtprioname((int)*ip); 615131402Salfred ip++; 61624139Sjoerg narg--; 61724139Sjoerg c = ','; 61824139Sjoerg } else if (ktr->ktr_code == SYS___semctl) { 61924139Sjoerg print_number(ip,narg,c); 62024139Sjoerg print_number(ip,narg,c); 62124139Sjoerg (void)putchar(','); 62224139Sjoerg semctlname((int)*ip); 62342447Sobrien ip++; 62424139Sjoerg narg--; 62524139Sjoerg } else if (ktr->ktr_code == SYS_semget) { 62624139Sjoerg print_number(ip,narg,c); 62724139Sjoerg print_number(ip,narg,c); 62824139Sjoerg (void)putchar(','); 62924139Sjoerg semgetname((int)*ip); 63024139Sjoerg ip++; 63124139Sjoerg narg--; 63224139Sjoerg } else if (ktr->ktr_code == SYS_msgctl) { 63324139Sjoerg print_number(ip,narg,c); 63424139Sjoerg (void)putchar(','); 63524139Sjoerg shmctlname((int)*ip); 63624139Sjoerg ip++; 63724139Sjoerg narg--; 63824139Sjoerg } else if (ktr->ktr_code == SYS_shmat) { 63924139Sjoerg print_number(ip,narg,c); 64024139Sjoerg print_number(ip,narg,c); 64124139Sjoerg (void)putchar(','); 64224139Sjoerg shmatname((int)*ip); 64324139Sjoerg ip++; 64424139Sjoerg narg--; 64524139Sjoerg } else if (ktr->ktr_code == SYS_shmctl) { 64624139Sjoerg print_number(ip,narg,c); 64724139Sjoerg (void)putchar(','); 64824139Sjoerg shmctlname((int)*ip); 64924139Sjoerg ip++; 65024139Sjoerg narg--; 65124139Sjoerg } else if (ktr->ktr_code == SYS_minherit) { 65224142Sjoerg print_number(ip,narg,c); 65324142Sjoerg print_number(ip,narg,c); 65424142Sjoerg (void)putchar(','); 65524139Sjoerg minheritname((int)*ip); 65624139Sjoerg ip++; 65724139Sjoerg narg--; 65824139Sjoerg } else if (ktr->ktr_code == SYS_rfork) { 65924139Sjoerg (void)putchar('('); 66024139Sjoerg rforkname((int)*ip); 66124139Sjoerg ip++; 66224139Sjoerg narg--; 66324139Sjoerg c = ','; 66424139Sjoerg } else if (ktr->ktr_code == SYS_lio_listio) { 66524139Sjoerg (void)putchar('('); 66689757Sdwmalone lio_listioname((int)*ip); 66724139Sjoerg ip++; 66824139Sjoerg narg--; 66924139Sjoerg c = ','; 67024139Sjoerg } else if (ktr->ktr_code == SYS_mlockall) { 67124139Sjoerg (void)putchar('('); 67224139Sjoerg mlockallname((int)*ip); 67324139Sjoerg ip++; 67424139Sjoerg narg--; 67524139Sjoerg } else if (ktr->ktr_code == SYS_sched_setscheduler) { 67624139Sjoerg print_number(ip,narg,c); 67724139Sjoerg (void)putchar(','); 67824139Sjoerg schedpolicyname((int)*ip); 679168710Sstas ip++; 680168710Sstas narg--; 68124139Sjoerg } else if (ktr->ktr_code == SYS_sched_get_priority_max || 68224139Sjoerg ktr->ktr_code == SYS_sched_get_priority_min) { 68324139Sjoerg (void)putchar('('); 68424139Sjoerg schedpolicyname((int)*ip); 68524139Sjoerg ip++; 68624139Sjoerg narg--; 68724139Sjoerg } else if (ktr->ktr_code == SYS_sendfile) { 68824139Sjoerg print_number(ip,narg,c); 68924139Sjoerg print_number(ip,narg,c); 69024139Sjoerg print_number(ip,narg,c); 69124139Sjoerg print_number(ip,narg,c); 69289757Sdwmalone print_number(ip,narg,c); 69389757Sdwmalone print_number(ip,narg,c); 69489757Sdwmalone (void)putchar(','); 69589757Sdwmalone sendfileflagsname((int)*ip); 69689757Sdwmalone ip++; 69789757Sdwmalone narg--; 69889757Sdwmalone } else if (ktr->ktr_code == SYS_kldsym) { 69924139Sjoerg print_number(ip,narg,c); 70024139Sjoerg (void)putchar(','); 70124139Sjoerg kldsymcmdname((int)*ip); 70224139Sjoerg ip++; 70324139Sjoerg narg--; 70424139Sjoerg } else if (ktr->ktr_code == SYS_sigprocmask) { 70524139Sjoerg (void)putchar('('); 70624139Sjoerg sigprocmaskhowname((int)*ip); 70724139Sjoerg ip++; 70824139Sjoerg narg--; 70924139Sjoerg c = ','; 71024139Sjoerg } else if (ktr->ktr_code == SYS___acl_get_file || 71124139Sjoerg ktr->ktr_code == SYS___acl_set_file || 71224139Sjoerg ktr->ktr_code == SYS___acl_get_fd || 71324139Sjoerg ktr->ktr_code == SYS___acl_set_fd || 71424139Sjoerg ktr->ktr_code == SYS___acl_delete_file || 71524139Sjoerg ktr->ktr_code == SYS___acl_delete_fd || 71624142Sjoerg ktr->ktr_code == SYS___acl_aclcheck_file || 71724139Sjoerg ktr->ktr_code == SYS___acl_aclcheck_fd || 71824139Sjoerg ktr->ktr_code == SYS___acl_get_link || 71924139Sjoerg ktr->ktr_code == SYS___acl_set_link || 72024139Sjoerg ktr->ktr_code == SYS___acl_delete_link || 72124139Sjoerg ktr->ktr_code == SYS___acl_aclcheck_link) { 72224139Sjoerg print_number(ip,narg,c); 72324139Sjoerg (void)putchar(','); 72424139Sjoerg acltypename((int)*ip); 72524139Sjoerg ip++; 72624139Sjoerg narg--; 72724139Sjoerg } else if (ktr->ktr_code == SYS_sigaction) { 72824139Sjoerg (void)putchar('('); 72924139Sjoerg signame((int)*ip); 73024139Sjoerg ip++; 73124139Sjoerg narg--; 73224139Sjoerg c = ','; 73324139Sjoerg } else if (ktr->ktr_code == SYS_extattrctl) { 73424139Sjoerg print_number(ip,narg,c); 73524139Sjoerg (void)putchar(','); 73624139Sjoerg extattrctlname((int)*ip); 73724139Sjoerg ip++; 73824139Sjoerg narg--; 73924139Sjoerg } else if (ktr->ktr_code == SYS_nmount) { 74089757Sdwmalone print_number(ip,narg,c); 74124139Sjoerg print_number(ip,narg,c); 74224139Sjoerg (void)putchar(','); 74324139Sjoerg mountflagsname ((int)*ip); 74481187Skris ip++; 74581187Skris narg--; 74681187Skris } else if (ktr->ktr_code == SYS_kse_thr_interrupt) { 74781187Skris print_number(ip,narg,c); 74881187Skris (void)putchar(','); 74981187Skris ksethrcmdname ((int)*ip); 75081187Skris ip++; 75181187Skris narg--; 75281187Skris } else if (ktr->ktr_code == SYS_thr_create) { 75381187Skris print_number(ip,narg,c); 75481187Skris print_number(ip,narg,c); 75581187Skris (void)putchar(','); 75681187Skris thrcreateflagsname ((int)*ip); 75781187Skris ip++; 75881187Skris narg--; 75981187Skris } else if (ktr->ktr_code == SYS_thr_kill) { 76081187Skris print_number(ip,narg,c); 76181187Skris (void)putchar(','); 76281187Skris signame ((int)*ip); 76381187Skris ip++; 76481187Skris narg--; 76581187Skris } else if (ktr->ktr_code == SYS_kldunloadf) { 76681187Skris print_number(ip,narg,c); 76781187Skris (void)putchar(','); 76881187Skris kldunloadfflagsname ((int)*ip); 76981187Skris ip++; 77081187Skris narg--; 77181187Skris } 77281187Skris } 77381187Skris while (narg) { 77481187Skris print_number(ip,narg,c); 77581187Skris } 77681187Skris (void)putchar(')'); 77781187Skris } 77881187Skris (void)putchar('\n'); 77981187Skris} 78081187Skris 78181187Skrisvoid 78281187Skrisktrsysret(struct ktr_sysret *ktr) 78381187Skris{ 78481187Skris register_t ret = ktr->ktr_retval; 78581187Skris int error = ktr->ktr_error; 78681187Skris int code = ktr->ktr_code; 78781187Skris 78881187Skris if (code >= nsyscalls || code < 0) 78981187Skris (void)printf("[%d] ", code); 79024139Sjoerg else 79186042Sdwmalone (void)printf("%s ", syscallnames[code]); 79286042Sdwmalone 79386042Sdwmalone if (error == 0) { 79486042Sdwmalone if (fancy) { 79524139Sjoerg (void)printf("%d", ret); 79624139Sjoerg if (ret < 0 || ret > 9) 79724139Sjoerg (void)printf("/%#lx", (long)ret); 79824139Sjoerg } else { 79924139Sjoerg if (decimal) 80024139Sjoerg (void)printf("%ld", (long)ret); 80124139Sjoerg else 80224139Sjoerg (void)printf("%#lx", (long)ret); 80324139Sjoerg } 80486042Sdwmalone } else if (error == ERESTART) 80589757Sdwmalone (void)printf("RESTART"); 80689757Sdwmalone else if (error == EJUSTRETURN) 80789757Sdwmalone (void)printf("JUSTRETURN"); 80889757Sdwmalone else { 80989757Sdwmalone (void)printf("-1 errno %d", ktr->ktr_error); 81089757Sdwmalone if (fancy) 81189757Sdwmalone (void)printf(" %s", strerror(ktr->ktr_error)); 81224139Sjoerg } 81324139Sjoerg (void)putchar('\n'); 81424142Sjoerg} 81524142Sjoerg 81624142Sjoergvoid 81724142Sjoergktrnamei(char *cp, int len) 81824142Sjoerg{ 81924139Sjoerg (void)printf("\"%.*s\"\n", len, cp); 82024139Sjoerg} 82124139Sjoerg 82224139Sjoergvoid 82324139Sjoerghexdump(char *p, int len, int screenwidth) 82424139Sjoerg{ 82524139Sjoerg int n, i; 82624139Sjoerg int width; 82724139Sjoerg 82824139Sjoerg width = 0; 82924139Sjoerg do { 83024139Sjoerg width += 2; 83124139Sjoerg i = 13; /* base offset */ 83224139Sjoerg i += (width / 2) + 1; /* spaces every second byte */ 83324139Sjoerg i += (width * 2); /* width of bytes */ 83424139Sjoerg i += 3; /* " |" */ 83524139Sjoerg i += width; /* each byte */ 83624139Sjoerg i += 1; /* "|" */ 83724139Sjoerg } while (i < screenwidth); 83824139Sjoerg width -= 2; 83924139Sjoerg 84024139Sjoerg for (n = 0; n < len; n += width) { 84124139Sjoerg for (i = n; i < n + width; i++) { 84224139Sjoerg if ((i % width) == 0) { /* beginning of line */ 84324139Sjoerg printf(" 0x%04x", i); 84424139Sjoerg } 84524139Sjoerg if ((i % 2) == 0) { 84624139Sjoerg printf(" "); 84724139Sjoerg } 84824139Sjoerg if (i < len) 84924139Sjoerg printf("%02x", p[i] & 0xff); 85024139Sjoerg else 85124139Sjoerg printf(" "); 85224139Sjoerg } 85324139Sjoerg printf(" |"); 85424139Sjoerg for (i = n; i < n + width; i++) { 85524139Sjoerg if (i >= len) 85624139Sjoerg break; 85724139Sjoerg if (p[i] >= ' ' && p[i] <= '~') 85824139Sjoerg printf("%c", p[i]); 85924139Sjoerg else 86024139Sjoerg printf("."); 86124139Sjoerg } 86224139Sjoerg printf("|\n"); 86324139Sjoerg } 86424139Sjoerg if ((i % width) != 0) 86524139Sjoerg printf("\n"); 86624139Sjoerg} 86724139Sjoerg 86824139Sjoergvoid 86924139Sjoergvisdump(char *dp, int datalen, int screenwidth) 87024139Sjoerg{ 87124139Sjoerg int col = 0; 87224139Sjoerg char *cp; 87324139Sjoerg int width; 87424139Sjoerg char visbuf[5]; 87524139Sjoerg 87624139Sjoerg (void)printf(" \""); 87724139Sjoerg col = 8; 87824139Sjoerg for (;datalen > 0; datalen--, dp++) { 87924139Sjoerg (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); 88024139Sjoerg cp = visbuf; 88124139Sjoerg /* 88224139Sjoerg * Keep track of printables and 88324139Sjoerg * space chars (like fold(1)). 88424139Sjoerg */ 88524139Sjoerg if (col == 0) { 88624139Sjoerg (void)putchar('\t'); 88724139Sjoerg col = 8; 88824139Sjoerg } 88924139Sjoerg switch(*cp) { 89024139Sjoerg case '\n': 89124139Sjoerg col = 0; 89224139Sjoerg (void)putchar('\n'); 89324139Sjoerg continue; 89424139Sjoerg case '\t': 89524139Sjoerg width = 8 - (col&07); 89624139Sjoerg break; 89724139Sjoerg default: 89824139Sjoerg width = strlen(cp); 89924139Sjoerg } 90024139Sjoerg if (col + width > (screenwidth-2)) { 90124139Sjoerg (void)printf("\\\n\t"); 90224139Sjoerg col = 8; 90324139Sjoerg } 90424139Sjoerg col += width; 90524139Sjoerg do { 90624139Sjoerg (void)putchar(*cp++); 90724139Sjoerg } while (*cp); 90824139Sjoerg } 90924139Sjoerg if (col == 0) 91024139Sjoerg (void)printf(" "); 91124139Sjoerg (void)printf("\"\n"); 91224139Sjoerg} 91324139Sjoerg 91424139Sjoergvoid 91524139Sjoergktrgenio(struct ktr_genio *ktr, int len) 91624139Sjoerg{ 91789757Sdwmalone int datalen = len - sizeof (struct ktr_genio); 91889757Sdwmalone char *dp = (char *)ktr + sizeof (struct ktr_genio); 91989757Sdwmalone static int screenwidth = 0; 92089757Sdwmalone int i, binary; 92124139Sjoerg 92224139Sjoerg if (screenwidth == 0) { 92324139Sjoerg struct winsize ws; 92424139Sjoerg 92524139Sjoerg if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && 92624139Sjoerg ws.ws_col > 8) 92724139Sjoerg screenwidth = ws.ws_col; 92824139Sjoerg else 92924139Sjoerg screenwidth = 80; 93024139Sjoerg } 93124139Sjoerg printf("fd %d %s %d byte%s\n", ktr->ktr_fd, 93224139Sjoerg ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, 93324139Sjoerg datalen == 1 ? "" : "s"); 93424139Sjoerg if (suppressdata) 93524139Sjoerg return; 93624139Sjoerg if (maxdata && datalen > maxdata) 93724139Sjoerg datalen = maxdata; 93824139Sjoerg 93924139Sjoerg for (i = 0, binary = 0; i < datalen && binary == 0; i++) { 94024139Sjoerg if (dp[i] >= 32 && dp[i] < 127) 94124139Sjoerg continue; 94224139Sjoerg if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) 94324139Sjoerg continue; 94424139Sjoerg binary = 1; 94524139Sjoerg } 94624139Sjoerg if (binary) 94766641Simp hexdump(dp, datalen, screenwidth); 94824139Sjoerg else 94924139Sjoerg visdump(dp, datalen, screenwidth); 95024139Sjoerg} 95124139Sjoerg 95224139Sjoergconst char *signames[] = { 95324139Sjoerg "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ 95424139Sjoerg "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ 95524139Sjoerg "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ 95624139Sjoerg "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ 95724139Sjoerg "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ 95824139Sjoerg "USR2", NULL, /* 31 - 32 */ 95924139Sjoerg}; 96024139Sjoerg 96124139Sjoergvoid 96224139Sjoergktrpsig(struct ktr_psig *psig) 96324139Sjoerg{ 96468293Simp if (psig->signo > 0 && psig->signo < NSIG) 96524139Sjoerg (void)printf("SIG%s ", signames[psig->signo]); 96624139Sjoerg else 96724139Sjoerg (void)printf("SIG %d ", psig->signo); 96824139Sjoerg if (psig->action == SIG_DFL) 96924139Sjoerg (void)printf("SIG_DFL\n"); 97024139Sjoerg else { 97124139Sjoerg (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", 97224139Sjoerg (u_long)psig->action, psig->mask.__bits[0], psig->code); 97324139Sjoerg } 97424139Sjoerg} 97524139Sjoerg 97624139Sjoergvoid 97724139Sjoergktrcsw(struct ktr_csw *cs) 97824139Sjoerg{ 97924139Sjoerg (void)printf("%s %s\n", cs->out ? "stop" : "resume", 98024139Sjoerg cs->user ? "user" : "kernel"); 98124139Sjoerg} 98224139Sjoerg 98324139Sjoerg#define UTRACE_DLOPEN_START 1 98438090Sdes#define UTRACE_DLOPEN_STOP 2 98538090Sdes#define UTRACE_DLCLOSE_START 3 98638090Sdes#define UTRACE_DLCLOSE_STOP 4 98738090Sdes#define UTRACE_LOAD_OBJECT 5 98838090Sdes#define UTRACE_UNLOAD_OBJECT 6 98938090Sdes#define UTRACE_ADD_RUNDEP 7 99038090Sdes#define UTRACE_PRELOAD_FINISHED 8 99138090Sdes#define UTRACE_INIT_CALL 9 99224139Sjoerg#define UTRACE_FINI_CALL 10 99324139Sjoerg 99424139Sjoergstruct utrace_rtld { 99524139Sjoerg char sig[4]; /* 'RTLD' */ 99624139Sjoerg int event; 99724139Sjoerg void *handle; 99824139Sjoerg void *mapbase; 99924139Sjoerg size_t mapsize; 100024139Sjoerg int refcnt; 100124139Sjoerg char name[MAXPATHLEN]; 100224139Sjoerg}; 100324139Sjoerg 100424139Sjoergvoid 100524139Sjoergktruser_rtld(int len, unsigned char *p) 100624139Sjoerg{ 100724139Sjoerg struct utrace_rtld *ut = (struct utrace_rtld *)p; 100824139Sjoerg void *parent; 100924139Sjoerg int mode; 101024139Sjoerg 101124139Sjoerg switch (ut->event) { 101224139Sjoerg case UTRACE_DLOPEN_START: 101324139Sjoerg mode = ut->refcnt; 101424139Sjoerg printf("dlopen(%s, ", ut->name); 101524139Sjoerg switch (mode & RTLD_MODEMASK) { 101624139Sjoerg case RTLD_NOW: 101724139Sjoerg printf("RTLD_NOW"); 101824139Sjoerg break; 101924139Sjoerg case RTLD_LAZY: 1020117709Sjulian printf("RTLD_LAZY"); 1021117709Sjulian break; 1022117709Sjulian default: 1023223937Sjhb printf("%#x", mode & RTLD_MODEMASK); 1024145073Skeramida } 1025145073Skeramida if (mode & RTLD_GLOBAL) 1026145073Skeramida printf(" | RTLD_GLOBAL"); 1027117709Sjulian if (mode & RTLD_TRACE) 1028117709Sjulian printf(" | RTLD_TRACE"); 1029146342Skeramida if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)) 1030146342Skeramida printf(" | %#x", mode & 1031146342Skeramida ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)); 1032223937Sjhb printf(")\n"); 1033146342Skeramida break; 1034146342Skeramida case UTRACE_DLOPEN_STOP: 1035146342Skeramida printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name, 1036146342Skeramida ut->refcnt); 1037146342Skeramida break; 1038131402Salfred case UTRACE_DLCLOSE_START: 1039131402Salfred printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name, 1040131402Salfred ut->refcnt); 1041131402Salfred break; 1042131402Salfred case UTRACE_DLCLOSE_STOP: 1043131402Salfred printf("dlclose(%p) finished\n", ut->handle); 1044131402Salfred break; 1045131402Salfred case UTRACE_LOAD_OBJECT: 1046132005Salfred printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle, 1047132005Salfred ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 1048132005Salfred ut->name); 1049168710Sstas break; 1050168710Sstas case UTRACE_UNLOAD_OBJECT: 1051168710Sstas printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle, 105224139Sjoerg ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, 105324139Sjoerg ut->name); 105424139Sjoerg break; 105524139Sjoerg case UTRACE_ADD_RUNDEP: 105624139Sjoerg parent = ut->mapbase; 105724139Sjoerg printf("RTLD: %p now depends on %p (%s, %d)\n", parent, 105824139Sjoerg ut->handle, ut->name, ut->refcnt); 105924139Sjoerg break; 106024139Sjoerg case UTRACE_PRELOAD_FINISHED: 106124139Sjoerg printf("RTLD: LD_PRELOAD finished\n"); 106224139Sjoerg break; 106324139Sjoerg case UTRACE_INIT_CALL: 106424139Sjoerg printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle, 106524139Sjoerg ut->name); 106624139Sjoerg break; 106724139Sjoerg case UTRACE_FINI_CALL: 106824139Sjoerg printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle, 106924139Sjoerg ut->name); 107024139Sjoerg break; 107124139Sjoerg default: 107224139Sjoerg p += 4; 107324139Sjoerg len -= 4; 107424139Sjoerg printf("RTLD: %d ", len); 107524139Sjoerg while (len--) 1076168799Srafan if (decimal) 1077168799Srafan printf(" %d", *p++); 1078168799Srafan else 1079169257Srafan printf(" %02x", *p++); 1080168799Srafan printf("\n"); 1081168799Srafan } 1082168799Srafan} 1083168799Srafan 1084168799Srafanstruct utrace_malloc { 1085222530Sjhb void *p; 1086222530Sjhb size_t s; 1087222530Sjhb void *r; 1088222530Sjhb}; 1089222530Sjhb 1090222530Sjhbvoid 1091222530Sjhbktruser_malloc(int len, unsigned char *p) 1092223936Sjhb{ 1093223936Sjhb struct utrace_malloc *ut = (struct utrace_malloc *)p; 1094223936Sjhb 1095223936Sjhb if (ut->p == NULL) { 1096223936Sjhb if (ut->s == 0 && ut->r == NULL) 1097223936Sjhb printf("malloc_init()\n"); 1098223936Sjhb else 1099223936Sjhb printf("%p = malloc(%zu)\n", ut->r, ut->s); 1100223936Sjhb } else { 1101223936Sjhb if (ut->s == 0) 110224139Sjoerg printf("free(%p)\n", ut->p); 110324139Sjoerg else 110424139Sjoerg printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); 110524139Sjoerg } 110624139Sjoerg} 110724139Sjoerg 110824139Sjoergvoid 110924139Sjoergktruser(int len, unsigned char *p) 111024139Sjoerg{ 111124139Sjoerg 111224139Sjoerg if (len >= 8 && bcmp(p, "RTLD", 4) == 0) { 111324139Sjoerg ktruser_rtld(len, p); 111424139Sjoerg return; 111589757Sdwmalone } 111689757Sdwmalone 111789757Sdwmalone if (len == sizeof(struct utrace_malloc)) { 111824139Sjoerg ktruser_malloc(len, p); 111924139Sjoerg return; 112024139Sjoerg } 112124139Sjoerg 112224139Sjoerg (void)printf("%d ", len); 112324139Sjoerg while (len--) 112424139Sjoerg if (decimal) 112524139Sjoerg (void)printf(" %d", *p++); 112624139Sjoerg else 112724139Sjoerg (void)printf(" %02x", *p++); 112824139Sjoerg (void)printf("\n"); 112924139Sjoerg} 113024139Sjoerg 113124139Sjoergvoid 113224139Sjoergusage(void) 113324139Sjoerg{ 113424142Sjoerg (void)fprintf(stderr, 113524139Sjoerg "usage: kdump [-dEnlHRsT] [-f trfile] [-m maxdata] [-p pid] [-t [cnisuw]]\n"); 113624139Sjoerg exit(1); 113724139Sjoerg} 113824139Sjoerg