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