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