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