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