kdump.c revision 252356
11590Srgrimes/*-
21590Srgrimes * Copyright (c) 1988, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 4. Neither the name of the University nor the names of its contributors
141590Srgrimes *    may be used to endorse or promote products derived from this software
151590Srgrimes *    without specific prior written permission.
161590Srgrimes *
171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271590Srgrimes * SUCH DAMAGE.
281590Srgrimes */
291590Srgrimes
301590Srgrimes#ifndef lint
3127443Scharnierstatic const char copyright[] =
321590Srgrimes"@(#) Copyright (c) 1988, 1993\n\
331590Srgrimes	The Regents of the University of California.  All rights reserved.\n";
341590Srgrimes#endif /* not lint */
351590Srgrimes
361590Srgrimes#ifndef lint
3727443Scharnier#if 0
381590Srgrimesstatic char sccsid[] = "@(#)kdump.c	8.1 (Berkeley) 6/6/93";
3927443Scharnier#endif
401590Srgrimes#endif /* not lint */
4199112Sobrien#include <sys/cdefs.h>
4299112Sobrien__FBSDID("$FreeBSD: head/usr.bin/kdump/kdump.c 252356 2013-06-28 21:00:08Z davide $");
431590Srgrimes
4455206Speter#define _KERNEL
452215Scsgrextern int errno;
462215Scsgr#include <sys/errno.h>
4755206Speter#undef _KERNEL
481590Srgrimes#include <sys/param.h>
49251073Spjd#include <sys/capability.h>
501590Srgrimes#include <sys/errno.h>
51100824Sdwmalone#define _KERNEL
521590Srgrimes#include <sys/time.h>
53100824Sdwmalone#undef _KERNEL
541590Srgrimes#include <sys/uio.h>
551590Srgrimes#include <sys/ktrace.h>
561590Srgrimes#include <sys/ioctl.h>
57165758Srodrigc#include <sys/socket.h>
58176471Sdes#include <sys/stat.h>
59219043Sdchagin#include <sys/sysent.h>
60176471Sdes#include <sys/un.h>
61219043Sdchagin#include <sys/queue.h>
62176471Sdes#ifdef IPX
63176471Sdes#include <sys/types.h>
64176471Sdes#include <netipx/ipx.h>
65176471Sdes#endif
66176471Sdes#ifdef NETATALK
67176471Sdes#include <netatalk/at.h>
68176471Sdes#endif
69190168Sdelphij#include <arpa/inet.h>
70176471Sdes#include <netinet/in.h>
71190168Sdelphij#include <ctype.h>
72165916Sjhb#include <dlfcn.h>
7327443Scharnier#include <err.h>
74176471Sdes#include <grp.h>
75176471Sdes#include <inttypes.h>
7627443Scharnier#include <locale.h>
77251486Sae#include <netdb.h>
78251073Spjd#include <nl_types.h>
79176471Sdes#include <pwd.h>
801590Srgrimes#include <stdio.h>
811590Srgrimes#include <stdlib.h>
821590Srgrimes#include <string.h>
83251073Spjd#include <termios.h>
84176471Sdes#include <time.h>
8527443Scharnier#include <unistd.h>
8627443Scharnier#include <vis.h>
871590Srgrimes#include "ktrace.h"
88158766Snetchild#include "kdump_subr.h"
891590Srgrimes
90219043Sdchaginu_int abidump(struct ktr_header *);
91219043Sdchaginint fetchprocinfo(struct ktr_header *, u_int *);
92100824Sdwmaloneint fread_tail(void *, int, int);
93100824Sdwmalonevoid dumpheader(struct ktr_header *);
94219043Sdchaginvoid ktrsyscall(struct ktr_syscall *, u_int);
95219043Sdchaginvoid ktrsysret(struct ktr_sysret *, u_int);
96100824Sdwmalonevoid ktrnamei(char *, int);
97115759Spetervoid hexdump(char *, int, int);
98115759Spetervoid visdump(char *, int, int);
99100824Sdwmalonevoid ktrgenio(struct ktr_genio *, int);
100219138Sdchaginvoid ktrpsig(struct ktr_psig *);
101100824Sdwmalonevoid ktrcsw(struct ktr_csw *);
102234494Sjhbvoid ktrcsw_old(struct ktr_csw_old *);
103226329Sdesvoid ktruser_malloc(unsigned char *);
104226329Sdesvoid ktruser_rtld(int, unsigned char *);
105100824Sdwmalonevoid ktruser(int, unsigned char *);
106176471Sdesvoid ktrsockaddr(struct sockaddr *);
107176471Sdesvoid ktrstat(struct stat *);
108176471Sdesvoid ktrstruct(char *, size_t);
109226269Sdesvoid ktrcapfail(struct ktr_cap_fail *);
110233925Sjhbvoid ktrfault(struct ktr_fault *);
111233925Sjhbvoid ktrfaultend(struct ktr_faultend *);
112251073Spjdvoid limitfd(int fd);
113100824Sdwmalonevoid usage(void);
114226157Sdesvoid ioctlname(unsigned long, int);
115100824Sdwmalone
116176471Sdesint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
117219043Sdchagin    resolv = 0, abiflag = 0;
118100824Sdwmaloneconst char *tracefile = DEF_TRACEFILE;
1191590Srgrimesstruct ktr_header ktr_header;
1201590Srgrimes
121176471Sdes#define TIME_FORMAT	"%b %e %T %Y"
1221590Srgrimes#define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
1231590Srgrimes
124226262Sdes#define print_number(i,n,c) do {					\
125226262Sdes	if (decimal)							\
126226262Sdes		printf("%c%jd", c, (intmax_t)*i);			\
127226262Sdes	else								\
128226262Sdes		printf("%c%#jx", c, (uintmax_t)(u_register_t)*i);	\
129226262Sdes	i++;								\
130226262Sdes	n--;								\
131226262Sdes	c = ',';							\
132226164Sdes} while (0)
133219138Sdchagin
134219138Sdchagin#if defined(__amd64__) || defined(__i386__)
135219138Sdchagin
136219138Sdchaginvoid linux_ktrsyscall(struct ktr_syscall *);
137219138Sdchaginvoid linux_ktrsysret(struct ktr_sysret *);
138219138Sdchaginextern char *linux_syscallnames[];
139219138Sdchaginextern int nlinux_syscalls;
140219138Sdchagin
141219138Sdchagin/*
142219138Sdchagin * from linux.h
143219138Sdchagin * Linux syscalls return negative errno's, we do positive and map them
144219138Sdchagin */
145219138Sdchaginstatic int bsd_to_linux_errno[ELAST + 1] = {
146219138Sdchagin	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
147219138Sdchagin	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
148219138Sdchagin	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
149219138Sdchagin	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
150219138Sdchagin	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
151219138Sdchagin	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
152219138Sdchagin	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
153219138Sdchagin	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
154219138Sdchagin	-6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
155219138Sdchagin	-72, -67, -71
156219138Sdchagin};
157219138Sdchagin#endif
158219138Sdchagin
159219043Sdchaginstruct proc_info
160219043Sdchagin{
161219043Sdchagin	TAILQ_ENTRY(proc_info)	info;
162219043Sdchagin	u_int			sv_flags;
163219043Sdchagin	pid_t			pid;
164219043Sdchagin};
165219043Sdchagin
166219043SdchaginTAILQ_HEAD(trace_procs, proc_info) trace_procs;
167219043Sdchagin
168100824Sdwmaloneint
169100824Sdwmalonemain(int argc, char *argv[])
1701590Srgrimes{
1711590Srgrimes	int ch, ktrlen, size;
172100824Sdwmalone	void *m;
1731590Srgrimes	int trpoints = ALL_POINTS;
174112201Sjhb	int drop_logged;
175115759Speter	pid_t pid = 0;
176219043Sdchagin	u_int sv_flags;
1771590Srgrimes
178226153Sdes	setlocale(LC_CTYPE, "");
17911823Sache
180219043Sdchagin	while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1)
181226153Sdes		switch (ch) {
182219043Sdchagin		case 'A':
183219043Sdchagin			abiflag = 1;
184219043Sdchagin			break;
1851590Srgrimes		case 'f':
1861590Srgrimes			tracefile = optarg;
1871590Srgrimes			break;
1881590Srgrimes		case 'd':
1891590Srgrimes			decimal = 1;
1901590Srgrimes			break;
1911590Srgrimes		case 'l':
1921590Srgrimes			tail = 1;
1931590Srgrimes			break;
1941590Srgrimes		case 'm':
1951590Srgrimes			maxdata = atoi(optarg);
1961590Srgrimes			break;
1971590Srgrimes		case 'n':
1981590Srgrimes			fancy = 0;
1991590Srgrimes			break;
200115759Speter		case 'p':
201115759Speter			pid = atoi(optarg);
202115759Speter			break;
203176471Sdes		case 'r':
204176471Sdes			resolv = 1;
205176471Sdes			break;
206152331Srwatson		case 's':
207152331Srwatson			suppressdata = 1;
208152331Srwatson			break;
209123187Speter		case 'E':
210123187Speter			timestamp = 3;	/* elapsed timestamp */
211123187Speter			break;
212151930Srwatson		case 'H':
213151930Srwatson			threads = 1;
214151930Srwatson			break;
2151590Srgrimes		case 'R':
2161590Srgrimes			timestamp = 2;	/* relative timestamp */
2171590Srgrimes			break;
2181590Srgrimes		case 'T':
2191590Srgrimes			timestamp = 1;
2201590Srgrimes			break;
2211590Srgrimes		case 't':
2221590Srgrimes			trpoints = getpoints(optarg);
22327443Scharnier			if (trpoints < 0)
22427443Scharnier				errx(1, "unknown trace point in %s", optarg);
2251590Srgrimes			break;
2261590Srgrimes		default:
2271590Srgrimes			usage();
2281590Srgrimes		}
2291590Srgrimes
23019853Sfenner	if (argc > optind)
2311590Srgrimes		usage();
2321590Srgrimes
233226153Sdes	m = malloc(size = 1025);
23427443Scharnier	if (m == NULL)
23527443Scharnier		errx(1, "%s", strerror(ENOMEM));
23627443Scharnier	if (!freopen(tracefile, "r", stdin))
23727443Scharnier		err(1, "%s", tracefile);
238251073Spjd
239251073Spjd	/*
240251073Spjd	 * Cache NLS data before entering capability mode.
241251073Spjd	 * XXXPJD: There should be strerror_init() and strsignal_init() in libc.
242251073Spjd	 */
243251073Spjd	(void)catopen("libc", NL_CAT_LOCALE);
244251167Spjd	if (resolv == 0) {
245251167Spjd		if (cap_enter() < 0 && errno != ENOSYS)
246251167Spjd			err(1, "unable to enter capability mode");
247251167Spjd	}
248251073Spjd	limitfd(STDIN_FILENO);
249251073Spjd	limitfd(STDOUT_FILENO);
250251073Spjd	limitfd(STDERR_FILENO);
251251073Spjd
252219043Sdchagin	TAILQ_INIT(&trace_procs);
253112201Sjhb	drop_logged = 0;
2541590Srgrimes	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
255112201Sjhb		if (ktr_header.ktr_type & KTR_DROP) {
256112201Sjhb			ktr_header.ktr_type &= ~KTR_DROP;
257151930Srwatson			if (!drop_logged && threads) {
258226153Sdes				printf(
259203551Sjh				    "%6jd %6jd %-8.*s Events dropped.\n",
260203551Sjh				    (intmax_t)ktr_header.ktr_pid,
261203551Sjh				    ktr_header.ktr_tid > 0 ?
262203551Sjh				    (intmax_t)ktr_header.ktr_tid : 0,
263203551Sjh				    MAXCOMLEN, ktr_header.ktr_comm);
264151930Srwatson				drop_logged = 1;
265151930Srwatson			} else if (!drop_logged) {
266226153Sdes				printf("%6jd %-8.*s Events dropped.\n",
267203551Sjh				    (intmax_t)ktr_header.ktr_pid, MAXCOMLEN,
268112201Sjhb				    ktr_header.ktr_comm);
269112201Sjhb				drop_logged = 1;
270112201Sjhb			}
271112201Sjhb		}
2721590Srgrimes		if (trpoints & (1<<ktr_header.ktr_type))
273236577Sjhb			if (pid == 0 || ktr_header.ktr_pid == pid ||
274236577Sjhb			    ktr_header.ktr_tid == pid)
275115759Speter				dumpheader(&ktr_header);
27627443Scharnier		if ((ktrlen = ktr_header.ktr_len) < 0)
27727443Scharnier			errx(1, "bogus length 0x%x", ktrlen);
2781590Srgrimes		if (ktrlen > size) {
279226153Sdes			m = realloc(m, ktrlen+1);
28027443Scharnier			if (m == NULL)
28127443Scharnier				errx(1, "%s", strerror(ENOMEM));
2821590Srgrimes			size = ktrlen;
2831590Srgrimes		}
28427443Scharnier		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
28527443Scharnier			errx(1, "data too short");
286219043Sdchagin		if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
287219043Sdchagin			continue;
288219043Sdchagin		sv_flags = abidump(&ktr_header);
289236577Sjhb		if (pid && ktr_header.ktr_pid != pid &&
290236577Sjhb		    ktr_header.ktr_tid != pid)
291115759Speter			continue;
2921590Srgrimes		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
2931590Srgrimes			continue;
294112201Sjhb		drop_logged = 0;
2951590Srgrimes		switch (ktr_header.ktr_type) {
2961590Srgrimes		case KTR_SYSCALL:
297219138Sdchagin#if defined(__amd64__) || defined(__i386__)
298219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
299219138Sdchagin				linux_ktrsyscall((struct ktr_syscall *)m);
300219138Sdchagin			else
301219138Sdchagin#endif
302219138Sdchagin				ktrsyscall((struct ktr_syscall *)m, sv_flags);
3031590Srgrimes			break;
3041590Srgrimes		case KTR_SYSRET:
305219138Sdchagin#if defined(__amd64__) || defined(__i386__)
306219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
307219138Sdchagin				linux_ktrsysret((struct ktr_sysret *)m);
308219138Sdchagin			else
309219138Sdchagin#endif
310219138Sdchagin				ktrsysret((struct ktr_sysret *)m, sv_flags);
3111590Srgrimes			break;
3121590Srgrimes		case KTR_NAMEI:
313189707Sjhb		case KTR_SYSCTL:
3141590Srgrimes			ktrnamei(m, ktrlen);
3151590Srgrimes			break;
3161590Srgrimes		case KTR_GENIO:
3171590Srgrimes			ktrgenio((struct ktr_genio *)m, ktrlen);
3181590Srgrimes			break;
3191590Srgrimes		case KTR_PSIG:
320219138Sdchagin			ktrpsig((struct ktr_psig *)m);
3211590Srgrimes			break;
3221590Srgrimes		case KTR_CSW:
323234494Sjhb			if (ktrlen == sizeof(struct ktr_csw_old))
324234494Sjhb				ktrcsw_old((struct ktr_csw_old *)m);
325234494Sjhb			else
326234494Sjhb				ktrcsw((struct ktr_csw *)m);
3271590Srgrimes			break;
32818400Sphk		case KTR_USER:
32918470Sphk			ktruser(ktrlen, m);
33018400Sphk			break;
331176471Sdes		case KTR_STRUCT:
332176471Sdes			ktrstruct(m, ktrlen);
333176471Sdes			break;
334226269Sdes		case KTR_CAPFAIL:
335226269Sdes			ktrcapfail((struct ktr_cap_fail *)m);
336233925Sjhb			break;
337233925Sjhb		case KTR_FAULT:
338233925Sjhb			ktrfault((struct ktr_fault *)m);
339233925Sjhb			break;
340233925Sjhb		case KTR_FAULTEND:
341233925Sjhb			ktrfaultend((struct ktr_faultend *)m);
342233925Sjhb			break;
343112203Sjhb		default:
344112203Sjhb			printf("\n");
345112203Sjhb			break;
3461590Srgrimes		}
3471590Srgrimes		if (tail)
348226153Sdes			fflush(stdout);
3491590Srgrimes	}
350100824Sdwmalone	return 0;
3511590Srgrimes}
3521590Srgrimes
353251073Spjdvoid
354251073Spjdlimitfd(int fd)
355251073Spjd{
356251073Spjd	cap_rights_t rights;
357251073Spjd	unsigned long cmd;
358251073Spjd
359251073Spjd	rights = CAP_FSTAT;
360251073Spjd	cmd = -1;
361251073Spjd
362251073Spjd	switch (fd) {
363251073Spjd	case STDIN_FILENO:
364251073Spjd		rights |= CAP_READ;
365251073Spjd		break;
366251073Spjd	case STDOUT_FILENO:
367251073Spjd		rights |= CAP_IOCTL | CAP_WRITE;
368251073Spjd		cmd = TIOCGETA;	/* required by isatty(3) in printf(3) */
369251073Spjd		break;
370251073Spjd	case STDERR_FILENO:
371251073Spjd		rights |= CAP_WRITE;
372251073Spjd		if (!suppressdata) {
373251073Spjd			rights |= CAP_IOCTL;
374251073Spjd			cmd = TIOCGWINSZ;
375251073Spjd		}
376251073Spjd		break;
377251073Spjd	default:
378251073Spjd		abort();
379251073Spjd	}
380251073Spjd
381251073Spjd	if (cap_rights_limit(fd, rights) < 0 && errno != ENOSYS)
382251073Spjd		err(1, "unable to limit rights for descriptor %d", fd);
383251073Spjd	if (cmd != -1 && cap_ioctls_limit(fd, &cmd, 1) < 0 && errno != ENOSYS)
384251073Spjd		err(1, "unable to limit ioctls for descriptor %d", fd);
385251073Spjd}
386251073Spjd
387100824Sdwmaloneint
388100824Sdwmalonefread_tail(void *buf, int size, int num)
3891590Srgrimes{
3901590Srgrimes	int i;
3911590Srgrimes
3921590Srgrimes	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
393226153Sdes		sleep(1);
3941590Srgrimes		clearerr(stdin);
3951590Srgrimes	}
3961590Srgrimes	return (i);
3971590Srgrimes}
3981590Srgrimes
399219043Sdchaginint
400219043Sdchaginfetchprocinfo(struct ktr_header *kth, u_int *flags)
401219043Sdchagin{
402219043Sdchagin	struct proc_info *pi;
403219043Sdchagin
404219043Sdchagin	switch (kth->ktr_type) {
405219043Sdchagin	case KTR_PROCCTOR:
406219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
407219043Sdchagin			if (pi->pid == kth->ktr_pid) {
408219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
409219043Sdchagin				break;
410219043Sdchagin			}
411219043Sdchagin		}
412219043Sdchagin		pi = malloc(sizeof(struct proc_info));
413219043Sdchagin		if (pi == NULL)
414219043Sdchagin			errx(1, "%s", strerror(ENOMEM));
415219043Sdchagin		pi->sv_flags = *flags;
416219043Sdchagin		pi->pid = kth->ktr_pid;
417219043Sdchagin		TAILQ_INSERT_TAIL(&trace_procs, pi, info);
418219043Sdchagin		return (1);
419219043Sdchagin
420219043Sdchagin	case KTR_PROCDTOR:
421219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
422219043Sdchagin			if (pi->pid == kth->ktr_pid) {
423219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
424219043Sdchagin				free(pi);
425219043Sdchagin				break;
426219043Sdchagin			}
427219043Sdchagin		}
428219043Sdchagin		return (1);
429219043Sdchagin	}
430219043Sdchagin
431219043Sdchagin	return (0);
432219043Sdchagin}
433219043Sdchagin
434219043Sdchaginu_int
435219043Sdchaginabidump(struct ktr_header *kth)
436219043Sdchagin{
437219043Sdchagin	struct proc_info *pi;
438219043Sdchagin	const char *abi;
439219043Sdchagin	const char *arch;
440219043Sdchagin	u_int flags = 0;
441219043Sdchagin
442219043Sdchagin	TAILQ_FOREACH(pi, &trace_procs, info) {
443219043Sdchagin		if (pi->pid == kth->ktr_pid) {
444219043Sdchagin			flags = pi->sv_flags;
445219043Sdchagin			break;
446219043Sdchagin		}
447219043Sdchagin	}
448219043Sdchagin
449219043Sdchagin	if (abiflag == 0)
450219043Sdchagin		return (flags);
451219043Sdchagin
452219043Sdchagin	switch (flags & SV_ABI_MASK) {
453219043Sdchagin	case SV_ABI_LINUX:
454219043Sdchagin		abi = "L";
455219043Sdchagin		break;
456219043Sdchagin	case SV_ABI_FREEBSD:
457219043Sdchagin		abi = "F";
458219043Sdchagin		break;
459219043Sdchagin	default:
460219043Sdchagin		abi = "U";
461219043Sdchagin		break;
462219043Sdchagin	}
463219043Sdchagin
464219043Sdchagin	if (flags != 0) {
465219043Sdchagin		if (flags & SV_LP64)
466219043Sdchagin			arch = "64";
467219043Sdchagin		else
468219043Sdchagin			arch = "32";
469219043Sdchagin	} else
470219043Sdchagin		arch = "00";
471219043Sdchagin
472219043Sdchagin	printf("%s%s  ", abi, arch);
473219043Sdchagin
474219043Sdchagin	return (flags);
475219043Sdchagin}
476219043Sdchagin
477100824Sdwmalonevoid
478100824Sdwmalonedumpheader(struct ktr_header *kth)
4791590Srgrimes{
4801590Srgrimes	static char unknown[64];
4811590Srgrimes	static struct timeval prevtime, temp;
482100824Sdwmalone	const char *type;
4831590Srgrimes
4841590Srgrimes	switch (kth->ktr_type) {
4851590Srgrimes	case KTR_SYSCALL:
4861590Srgrimes		type = "CALL";
4871590Srgrimes		break;
4881590Srgrimes	case KTR_SYSRET:
4891590Srgrimes		type = "RET ";
4901590Srgrimes		break;
4911590Srgrimes	case KTR_NAMEI:
4921590Srgrimes		type = "NAMI";
4931590Srgrimes		break;
4941590Srgrimes	case KTR_GENIO:
4951590Srgrimes		type = "GIO ";
4961590Srgrimes		break;
4971590Srgrimes	case KTR_PSIG:
4981590Srgrimes		type = "PSIG";
4991590Srgrimes		break;
5001590Srgrimes	case KTR_CSW:
501171333Sjhb		type = "CSW ";
5021590Srgrimes		break;
50318400Sphk	case KTR_USER:
50418400Sphk		type = "USER";
50518400Sphk		break;
506176471Sdes	case KTR_STRUCT:
507176471Sdes		type = "STRU";
508176471Sdes		break;
509189707Sjhb	case KTR_SYSCTL:
510189707Sjhb		type = "SCTL";
511189707Sjhb		break;
512219043Sdchagin	case KTR_PROCCTOR:
513219043Sdchagin		/* FALLTHROUGH */
514219043Sdchagin	case KTR_PROCDTOR:
515219043Sdchagin		return;
516226269Sdes	case KTR_CAPFAIL:
517226269Sdes		type = "CAP ";
518226269Sdes		break;
519233925Sjhb	case KTR_FAULT:
520233925Sjhb		type = "PFLT";
521233925Sjhb		break;
522233925Sjhb	case KTR_FAULTEND:
523233925Sjhb		type = "PRET";
524233925Sjhb		break;
5251590Srgrimes	default:
526226153Sdes		sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
5271590Srgrimes		type = unknown;
5281590Srgrimes	}
5291590Srgrimes
530151930Srwatson	/*
531151930Srwatson	 * The ktr_tid field was previously the ktr_buffer field, which held
532151930Srwatson	 * the kernel pointer value for the buffer associated with data
533151930Srwatson	 * following the record header.  It now holds a threadid, but only
534151930Srwatson	 * for trace files after the change.  Older trace files still contain
535151930Srwatson	 * kernel pointers.  Detect this and suppress the results by printing
536151930Srwatson	 * negative tid's as 0.
537151930Srwatson	 */
538151930Srwatson	if (threads)
539226153Sdes		printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid,
540203551Sjh		    kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0,
541203551Sjh		    MAXCOMLEN, kth->ktr_comm);
542151930Srwatson	else
543226153Sdes		printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN,
544151930Srwatson		    kth->ktr_comm);
5451590Srgrimes	if (timestamp) {
546123187Speter		if (timestamp == 3) {
547123187Speter			if (prevtime.tv_sec == 0)
548123187Speter				prevtime = kth->ktr_time;
549123187Speter			timevalsub(&kth->ktr_time, &prevtime);
550123187Speter		}
5511590Srgrimes		if (timestamp == 2) {
5521590Srgrimes			temp = kth->ktr_time;
5531590Srgrimes			timevalsub(&kth->ktr_time, &prevtime);
5541590Srgrimes			prevtime = temp;
5551590Srgrimes		}
556226153Sdes		printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
557203551Sjh		    kth->ktr_time.tv_usec);
5581590Srgrimes	}
559226153Sdes	printf("%s  ", type);
5601590Srgrimes}
5611590Srgrimes
5621590Srgrimes#include <sys/syscall.h>
5631590Srgrimes#define KTRACE
5644721Sphk#include <sys/kern/syscalls.c>
5651590Srgrimes#undef KTRACE
5661590Srgrimesint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
5671590Srgrimes
568100824Sdwmalonevoid
569219043Sdchaginktrsyscall(struct ktr_syscall *ktr, u_int flags)
5701590Srgrimes{
571100824Sdwmalone	int narg = ktr->ktr_narg;
572100824Sdwmalone	register_t *ip;
573226269Sdes	intmax_t arg;
5741590Srgrimes
575219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
576219043Sdchagin	    (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
577226153Sdes		printf("[%d]", ktr->ktr_code);
5781590Srgrimes	else
579226153Sdes		printf("%s", syscallnames[ktr->ktr_code]);
58047957Sdt	ip = &ktr->ktr_args[0];
5811590Srgrimes	if (narg) {
5821590Srgrimes		char c = '(';
583219043Sdchagin		if (fancy &&
584219043Sdchagin		    (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
585226148Sdes			switch (ktr->ktr_code) {
586226148Sdes			case SYS_ioctl: {
587226150Sdes				print_number(ip, narg, c);
588226157Sdes				putchar(c);
589226157Sdes				ioctlname(*ip, decimal);
5901590Srgrimes				c = ',';
5911590Srgrimes				ip++;
5921590Srgrimes				narg--;
593226148Sdes				break;
594226148Sdes			}
595226148Sdes			case SYS_ptrace:
596226153Sdes				putchar('(');
597226164Sdes				ptraceopname(*ip);
5981590Srgrimes				c = ',';
5991590Srgrimes				ip++;
6001590Srgrimes				narg--;
601226148Sdes				break;
602226148Sdes			case SYS_access:
603226148Sdes			case SYS_eaccess:
604226150Sdes				print_number(ip, narg, c);
605226153Sdes				putchar(',');
606226164Sdes				accessmodename(*ip);
607158766Snetchild				ip++;
608158766Snetchild				narg--;
609226148Sdes				break;
610226148Sdes			case SYS_open:
611226150Sdes				print_number(ip, narg, c);
612226153Sdes				putchar(',');
613226164Sdes				flagsandmodename(ip[0], ip[1], decimal);
614226148Sdes				ip += 2;
615226148Sdes				narg -= 2;
616226148Sdes				break;
617226148Sdes			case SYS_wait4:
618226150Sdes				print_number(ip, narg, c);
619226150Sdes				print_number(ip, narg, c);
620226153Sdes				putchar(',');
621226164Sdes				wait4optname(*ip);
622158766Snetchild				ip++;
623158766Snetchild				narg--;
624226148Sdes				break;
625226148Sdes			case SYS_chmod:
626226148Sdes			case SYS_fchmod:
627226148Sdes			case SYS_lchmod:
628226150Sdes				print_number(ip, narg, c);
629226153Sdes				putchar(',');
630226164Sdes				modename(*ip);
631158766Snetchild				ip++;
632158766Snetchild				narg--;
633226148Sdes				break;
634226148Sdes			case SYS_mknod:
635226150Sdes				print_number(ip, narg, c);
636226153Sdes				putchar(',');
637226164Sdes				modename(*ip);
638158766Snetchild				ip++;
639158766Snetchild				narg--;
640226148Sdes				break;
641226148Sdes			case SYS_getfsstat:
642226150Sdes				print_number(ip, narg, c);
643226150Sdes				print_number(ip, narg, c);
644226153Sdes				putchar(',');
645226164Sdes				getfsstatflagsname(*ip);
646158766Snetchild				ip++;
647158766Snetchild				narg--;
648226148Sdes				break;
649226148Sdes			case SYS_mount:
650226150Sdes				print_number(ip, narg, c);
651226150Sdes				print_number(ip, narg, c);
652226153Sdes				putchar(',');
653226164Sdes				mountflagsname(*ip);
654158766Snetchild				ip++;
655158766Snetchild				narg--;
656226148Sdes				break;
657226148Sdes			case SYS_unmount:
658226150Sdes				print_number(ip, narg, c);
659226153Sdes				putchar(',');
660226164Sdes				mountflagsname(*ip);
661158766Snetchild				ip++;
662158766Snetchild				narg--;
663226148Sdes				break;
664226148Sdes			case SYS_recvmsg:
665226148Sdes			case SYS_sendmsg:
666226150Sdes				print_number(ip, narg, c);
667226150Sdes				print_number(ip, narg, c);
668226153Sdes				putchar(',');
669226164Sdes				sendrecvflagsname(*ip);
670158766Snetchild				ip++;
671158766Snetchild				narg--;
672226148Sdes				break;
673226148Sdes			case SYS_recvfrom:
674226148Sdes			case SYS_sendto:
675226150Sdes				print_number(ip, narg, c);
676226150Sdes				print_number(ip, narg, c);
677226150Sdes				print_number(ip, narg, c);
678226153Sdes				putchar(',');
679226164Sdes				sendrecvflagsname(*ip);
680158766Snetchild				ip++;
681158766Snetchild				narg--;
682226148Sdes				break;
683226148Sdes			case SYS_chflags:
684226148Sdes			case SYS_fchflags:
685226148Sdes			case SYS_lchflags:
686226150Sdes				print_number(ip, narg, c);
687226153Sdes				putchar(',');
688226164Sdes				modename(*ip);
689158766Snetchild				ip++;
690158766Snetchild				narg--;
691226148Sdes				break;
692226148Sdes			case SYS_kill:
693226150Sdes				print_number(ip, narg, c);
694226153Sdes				putchar(',');
695226164Sdes				signame(*ip);
696158766Snetchild				ip++;
697158766Snetchild				narg--;
698226148Sdes				break;
699226148Sdes			case SYS_reboot:
700226153Sdes				putchar('(');
701226164Sdes				rebootoptname(*ip);
702158766Snetchild				ip++;
703158766Snetchild				narg--;
704226148Sdes				break;
705226148Sdes			case SYS_umask:
706226153Sdes				putchar('(');
707226164Sdes				modename(*ip);
708158766Snetchild				ip++;
709158766Snetchild				narg--;
710226148Sdes				break;
711226148Sdes			case SYS_msync:
712226150Sdes				print_number(ip, narg, c);
713226150Sdes				print_number(ip, narg, c);
714226153Sdes				putchar(',');
715226164Sdes				msyncflagsname(*ip);
716158766Snetchild				ip++;
717158766Snetchild				narg--;
718226148Sdes				break;
719171221Speter#ifdef SYS_freebsd6_mmap
720226148Sdes			case SYS_freebsd6_mmap:
721226150Sdes				print_number(ip, narg, c);
722226150Sdes				print_number(ip, narg, c);
723226153Sdes				putchar(',');
724226164Sdes				mmapprotname(*ip);
725226153Sdes				putchar(',');
726171221Speter				ip++;
727171221Speter				narg--;
728226164Sdes				mmapflagsname(*ip);
729171221Speter				ip++;
730171221Speter				narg--;
731226148Sdes				break;
732171221Speter#endif
733226148Sdes			case SYS_mmap:
734226150Sdes				print_number(ip, narg, c);
735226150Sdes				print_number(ip, narg, c);
736226153Sdes				putchar(',');
737226164Sdes				mmapprotname(*ip);
738226153Sdes				putchar(',');
739158766Snetchild				ip++;
740158766Snetchild				narg--;
741226164Sdes				mmapflagsname(*ip);
742158766Snetchild				ip++;
743158766Snetchild				narg--;
744226148Sdes				break;
745226148Sdes			case SYS_mprotect:
746226150Sdes				print_number(ip, narg, c);
747226150Sdes				print_number(ip, narg, c);
748226153Sdes				putchar(',');
749226164Sdes				mmapprotname(*ip);
750158766Snetchild				ip++;
751158766Snetchild				narg--;
752226148Sdes				break;
753226148Sdes			case SYS_madvise:
754226150Sdes				print_number(ip, narg, c);
755226150Sdes				print_number(ip, narg, c);
756226153Sdes				putchar(',');
757226164Sdes				madvisebehavname(*ip);
758158766Snetchild				ip++;
759158766Snetchild				narg--;
760226148Sdes				break;
761226148Sdes			case SYS_setpriority:
762226150Sdes				print_number(ip, narg, c);
763226150Sdes				print_number(ip, narg, c);
764226153Sdes				putchar(',');
765226164Sdes				prioname(*ip);
766158766Snetchild				ip++;
767158766Snetchild				narg--;
768226148Sdes				break;
769226148Sdes			case SYS_fcntl:
770226150Sdes				print_number(ip, narg, c);
771226153Sdes				putchar(',');
772226164Sdes				fcntlcmdname(ip[0], ip[1], decimal);
773226148Sdes				ip += 2;
774226148Sdes				narg -= 2;
775226148Sdes				break;
776226148Sdes			case SYS_socket: {
777165758Srodrigc				int sockdomain;
778226153Sdes				putchar('(');
779226164Sdes				sockdomain = *ip;
780165758Srodrigc				sockdomainname(sockdomain);
781158766Snetchild				ip++;
782158766Snetchild				narg--;
783226153Sdes				putchar(',');
784226164Sdes				socktypename(*ip);
785158766Snetchild				ip++;
786158766Snetchild				narg--;
787165758Srodrigc				if (sockdomain == PF_INET ||
788165758Srodrigc				    sockdomain == PF_INET6) {
789226153Sdes					putchar(',');
790226164Sdes					sockipprotoname(*ip);
791165758Srodrigc					ip++;
792165758Srodrigc					narg--;
793165758Srodrigc				}
794158766Snetchild				c = ',';
795226148Sdes				break;
796226148Sdes			}
797226148Sdes			case SYS_setsockopt:
798226148Sdes			case SYS_getsockopt:
799226150Sdes				print_number(ip, narg, c);
800226153Sdes				putchar(',');
801226164Sdes				sockoptlevelname(*ip, decimal);
802226151Sdes				if (*ip == SOL_SOCKET) {
803175138Sjhb					ip++;
804175138Sjhb					narg--;
805226153Sdes					putchar(',');
806226164Sdes					sockoptname(*ip);
807175138Sjhb				}
808158766Snetchild				ip++;
809158766Snetchild				narg--;
810226148Sdes				break;
811171221Speter#ifdef SYS_freebsd6_lseek
812226148Sdes			case SYS_freebsd6_lseek:
813226150Sdes				print_number(ip, narg, c);
814158766Snetchild				/* Hidden 'pad' argument, not in lseek(2) */
815226150Sdes				print_number(ip, narg, c);
816226150Sdes				print_number(ip, narg, c);
817226153Sdes				putchar(',');
818226164Sdes				whencename(*ip);
819158766Snetchild				ip++;
820158766Snetchild				narg--;
821226148Sdes				break;
822171221Speter#endif
823226148Sdes			case SYS_lseek:
824226150Sdes				print_number(ip, narg, c);
825171221Speter				/* Hidden 'pad' argument, not in lseek(2) */
826226150Sdes				print_number(ip, narg, c);
827226153Sdes				putchar(',');
828226164Sdes				whencename(*ip);
829171221Speter				ip++;
830171221Speter				narg--;
831226148Sdes				break;
832226148Sdes			case SYS_flock:
833226150Sdes				print_number(ip, narg, c);
834226153Sdes				putchar(',');
835226164Sdes				flockname(*ip);
836158766Snetchild				ip++;
837158766Snetchild				narg--;
838226148Sdes				break;
839226148Sdes			case SYS_mkfifo:
840226148Sdes			case SYS_mkdir:
841226150Sdes				print_number(ip, narg, c);
842226153Sdes				putchar(',');
843226164Sdes				modename(*ip);
844158766Snetchild				ip++;
845158766Snetchild				narg--;
846226148Sdes				break;
847226148Sdes			case SYS_shutdown:
848226150Sdes				print_number(ip, narg, c);
849226153Sdes				putchar(',');
850226164Sdes				shutdownhowname(*ip);
851158766Snetchild				ip++;
852158766Snetchild				narg--;
853226148Sdes				break;
854226148Sdes			case SYS_socketpair:
855226153Sdes				putchar('(');
856226164Sdes				sockdomainname(*ip);
857158766Snetchild				ip++;
858158766Snetchild				narg--;
859226153Sdes				putchar(',');
860226164Sdes				socktypename(*ip);
861158766Snetchild				ip++;
862158766Snetchild				narg--;
863158766Snetchild				c = ',';
864226148Sdes				break;
865226148Sdes			case SYS_getrlimit:
866226148Sdes			case SYS_setrlimit:
867226153Sdes				putchar('(');
868226164Sdes				rlimitname(*ip);
869158766Snetchild				ip++;
870158766Snetchild				narg--;
871158766Snetchild				c = ',';
872226148Sdes				break;
873226148Sdes			case SYS_quotactl:
874226150Sdes				print_number(ip, narg, c);
875226153Sdes				putchar(',');
876226164Sdes				quotactlname(*ip);
877158766Snetchild				ip++;
878158766Snetchild				narg--;
879158766Snetchild				c = ',';
880226148Sdes				break;
881226148Sdes			case SYS_nfssvc:
882226153Sdes				putchar('(');
883226164Sdes				nfssvcname(*ip);
884158766Snetchild				ip++;
885158766Snetchild				narg--;
886158766Snetchild				c = ',';
887226148Sdes				break;
888226148Sdes			case SYS_rtprio:
889226153Sdes				putchar('(');
890226164Sdes				rtprioname(*ip);
891158766Snetchild				ip++;
892158766Snetchild				narg--;
893158766Snetchild				c = ',';
894226148Sdes				break;
895226148Sdes			case SYS___semctl:
896226150Sdes				print_number(ip, narg, c);
897226150Sdes				print_number(ip, narg, c);
898226153Sdes				putchar(',');
899226164Sdes				semctlname(*ip);
900158766Snetchild				ip++;
901158766Snetchild				narg--;
902226148Sdes				break;
903226148Sdes			case SYS_semget:
904226150Sdes				print_number(ip, narg, c);
905226150Sdes				print_number(ip, narg, c);
906226153Sdes				putchar(',');
907226164Sdes				semgetname(*ip);
908158766Snetchild				ip++;
909158766Snetchild				narg--;
910226148Sdes				break;
911226148Sdes			case SYS_msgctl:
912226150Sdes				print_number(ip, narg, c);
913226153Sdes				putchar(',');
914226164Sdes				shmctlname(*ip);
915158766Snetchild				ip++;
916158766Snetchild				narg--;
917226148Sdes				break;
918226148Sdes			case SYS_shmat:
919226150Sdes				print_number(ip, narg, c);
920226150Sdes				print_number(ip, narg, c);
921226153Sdes				putchar(',');
922226164Sdes				shmatname(*ip);
923158766Snetchild				ip++;
924158766Snetchild				narg--;
925226148Sdes				break;
926226148Sdes			case SYS_shmctl:
927226150Sdes				print_number(ip, narg, c);
928226153Sdes				putchar(',');
929226164Sdes				shmctlname(*ip);
930158766Snetchild				ip++;
931158766Snetchild				narg--;
932226148Sdes				break;
933226148Sdes			case SYS_minherit:
934226150Sdes				print_number(ip, narg, c);
935226150Sdes				print_number(ip, narg, c);
936226153Sdes				putchar(',');
937226164Sdes				minheritname(*ip);
938158766Snetchild				ip++;
939158766Snetchild				narg--;
940226148Sdes				break;
941226148Sdes			case SYS_rfork:
942226153Sdes				putchar('(');
943226164Sdes				rforkname(*ip);
944158766Snetchild				ip++;
945158766Snetchild				narg--;
946158766Snetchild				c = ',';
947226148Sdes				break;
948226148Sdes			case SYS_lio_listio:
949226153Sdes				putchar('(');
950226164Sdes				lio_listioname(*ip);
951158766Snetchild				ip++;
952158766Snetchild				narg--;
953158766Snetchild				c = ',';
954226148Sdes				break;
955226148Sdes			case SYS_mlockall:
956226153Sdes				putchar('(');
957226164Sdes				mlockallname(*ip);
958158766Snetchild				ip++;
959158766Snetchild				narg--;
960226148Sdes				break;
961226148Sdes			case SYS_sched_setscheduler:
962226150Sdes				print_number(ip, narg, c);
963226153Sdes				putchar(',');
964226164Sdes				schedpolicyname(*ip);
965158766Snetchild				ip++;
966158766Snetchild				narg--;
967226148Sdes				break;
968226148Sdes			case SYS_sched_get_priority_max:
969226148Sdes			case SYS_sched_get_priority_min:
970226153Sdes				putchar('(');
971226164Sdes				schedpolicyname(*ip);
972158766Snetchild				ip++;
973158766Snetchild				narg--;
974226148Sdes				break;
975226148Sdes			case SYS_sendfile:
976226150Sdes				print_number(ip, narg, c);
977226150Sdes				print_number(ip, narg, c);
978226150Sdes				print_number(ip, narg, c);
979226150Sdes				print_number(ip, narg, c);
980226150Sdes				print_number(ip, narg, c);
981226150Sdes				print_number(ip, narg, c);
982226153Sdes				putchar(',');
983226164Sdes				sendfileflagsname(*ip);
984158766Snetchild				ip++;
985158766Snetchild				narg--;
986226148Sdes				break;
987226148Sdes			case SYS_kldsym:
988226150Sdes				print_number(ip, narg, c);
989226153Sdes				putchar(',');
990226164Sdes				kldsymcmdname(*ip);
991158766Snetchild				ip++;
992158766Snetchild				narg--;
993226148Sdes				break;
994226148Sdes			case SYS_sigprocmask:
995226153Sdes				putchar('(');
996226164Sdes				sigprocmaskhowname(*ip);
997158766Snetchild				ip++;
998158766Snetchild				narg--;
999158766Snetchild				c = ',';
1000226148Sdes				break;
1001226148Sdes			case SYS___acl_get_file:
1002226148Sdes			case SYS___acl_set_file:
1003226148Sdes			case SYS___acl_get_fd:
1004226148Sdes			case SYS___acl_set_fd:
1005226148Sdes			case SYS___acl_delete_file:
1006226148Sdes			case SYS___acl_delete_fd:
1007226148Sdes			case SYS___acl_aclcheck_file:
1008226148Sdes			case SYS___acl_aclcheck_fd:
1009226148Sdes			case SYS___acl_get_link:
1010226148Sdes			case SYS___acl_set_link:
1011226148Sdes			case SYS___acl_delete_link:
1012226148Sdes			case SYS___acl_aclcheck_link:
1013226150Sdes				print_number(ip, narg, c);
1014226153Sdes				putchar(',');
1015226164Sdes				acltypename(*ip);
1016158766Snetchild				ip++;
1017158766Snetchild				narg--;
1018226148Sdes				break;
1019226148Sdes			case SYS_sigaction:
1020226153Sdes				putchar('(');
1021226164Sdes				signame(*ip);
1022158766Snetchild				ip++;
1023158766Snetchild				narg--;
1024158766Snetchild				c = ',';
1025226148Sdes				break;
1026226148Sdes			case SYS_extattrctl:
1027226150Sdes				print_number(ip, narg, c);
1028226153Sdes				putchar(',');
1029226164Sdes				extattrctlname(*ip);
1030158766Snetchild				ip++;
1031158766Snetchild				narg--;
1032226148Sdes				break;
1033226148Sdes			case SYS_nmount:
1034226150Sdes				print_number(ip, narg, c);
1035226150Sdes				print_number(ip, narg, c);
1036226153Sdes				putchar(',');
1037226164Sdes				mountflagsname(*ip);
1038158766Snetchild				ip++;
1039158766Snetchild				narg--;
1040226148Sdes				break;
1041226148Sdes			case SYS_thr_create:
1042226150Sdes				print_number(ip, narg, c);
1043226150Sdes				print_number(ip, narg, c);
1044226153Sdes				putchar(',');
1045226164Sdes				thrcreateflagsname(*ip);
1046158766Snetchild				ip++;
1047158766Snetchild				narg--;
1048226148Sdes				break;
1049226148Sdes			case SYS_thr_kill:
1050226150Sdes				print_number(ip, narg, c);
1051226153Sdes				putchar(',');
1052226164Sdes				signame(*ip);
1053158766Snetchild				ip++;
1054158766Snetchild				narg--;
1055226148Sdes				break;
1056226148Sdes			case SYS_kldunloadf:
1057226150Sdes				print_number(ip, narg, c);
1058226153Sdes				putchar(',');
1059226164Sdes				kldunloadfflagsname(*ip);
1060158766Snetchild				ip++;
1061158766Snetchild				narg--;
1062226148Sdes				break;
1063226269Sdes			case SYS_cap_new:
1064247602Spjd			case SYS_cap_rights_limit:
1065226269Sdes				print_number(ip, narg, c);
1066226269Sdes				putchar(',');
1067226269Sdes				arg = *ip;
1068226269Sdes				ip++;
1069226269Sdes				narg--;
1070226269Sdes				/*
1071226269Sdes				 * Hack: the second argument is a
1072226269Sdes				 * cap_rights_t, which 64 bits wide, so on
1073226269Sdes				 * 32-bit systems, it is split between two
1074226269Sdes				 * registers.
1075226269Sdes				 *
1076226269Sdes				 * Since sizeof() is not evaluated by the
1077226269Sdes				 * preprocessor, we can't use an #ifdef,
1078226269Sdes				 * but the compiler will probably optimize
1079226269Sdes				 * the code out anyway.
1080226269Sdes				 */
1081226269Sdes				if (sizeof(cap_rights_t) > sizeof(register_t)) {
1082226269Sdes#if _BYTE_ORDER == _LITTLE_ENDIAN
1083226269Sdes					arg = ((intmax_t)*ip << 32) + arg;
1084226269Sdes#else
1085226269Sdes					arg = (arg << 32) + *ip;
1086226269Sdes#endif
1087226269Sdes					ip++;
1088226269Sdes					narg--;
1089226269Sdes				}
1090226269Sdes				capname(arg);
1091226159Sdes				break;
1092247602Spjd			case SYS_cap_fcntls_limit:
1093247602Spjd				print_number(ip, narg, c);
1094247602Spjd				putchar(',');
1095247602Spjd				arg = *ip;
1096247602Spjd				ip++;
1097247602Spjd				narg--;
1098247602Spjd				capfcntlname(arg);
1099247602Spjd				break;
1100232072Sjhb			case SYS_posix_fadvise:
1101232128Sjhb				print_number(ip, narg, c);
1102232128Sjhb				print_number(ip, narg, c);
1103232128Sjhb				print_number(ip, narg, c);
1104232072Sjhb				(void)putchar(',');
1105232072Sjhb				fadvisebehavname((int)*ip);
1106232072Sjhb				ip++;
1107232072Sjhb				narg--;
1108232072Sjhb				break;
11091590Srgrimes			}
11101590Srgrimes		}
1111199024Sattilio		while (narg > 0) {
1112226150Sdes			print_number(ip, narg, c);
11131590Srgrimes		}
1114226153Sdes		putchar(')');
11151590Srgrimes	}
1116226153Sdes	putchar('\n');
11171590Srgrimes}
11181590Srgrimes
1119100824Sdwmalonevoid
1120219043Sdchaginktrsysret(struct ktr_sysret *ktr, u_int flags)
11211590Srgrimes{
1122100824Sdwmalone	register_t ret = ktr->ktr_retval;
1123100824Sdwmalone	int error = ktr->ktr_error;
1124100824Sdwmalone	int code = ktr->ktr_code;
11251590Srgrimes
1126219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
1127219043Sdchagin	    (code >= nsyscalls || code < 0))
1128226153Sdes		printf("[%d] ", code);
11291590Srgrimes	else
1130226153Sdes		printf("%s ", syscallnames[code]);
11311590Srgrimes
11321590Srgrimes	if (error == 0) {
11331590Srgrimes		if (fancy) {
1134226153Sdes			printf("%ld", (long)ret);
11351590Srgrimes			if (ret < 0 || ret > 9)
1136226153Sdes				printf("/%#lx", (unsigned long)ret);
11371590Srgrimes		} else {
11381590Srgrimes			if (decimal)
1139226153Sdes				printf("%ld", (long)ret);
11401590Srgrimes			else
1141226153Sdes				printf("%#lx", (unsigned long)ret);
11421590Srgrimes		}
11431590Srgrimes	} else if (error == ERESTART)
1144226153Sdes		printf("RESTART");
11451590Srgrimes	else if (error == EJUSTRETURN)
1146226153Sdes		printf("JUSTRETURN");
11471590Srgrimes	else {
1148226153Sdes		printf("-1 errno %d", ktr->ktr_error);
11491590Srgrimes		if (fancy)
1150226153Sdes			printf(" %s", strerror(ktr->ktr_error));
11511590Srgrimes	}
1152226153Sdes	putchar('\n');
11531590Srgrimes}
11541590Srgrimes
1155100824Sdwmalonevoid
1156100824Sdwmalonektrnamei(char *cp, int len)
11571590Srgrimes{
1158226153Sdes	printf("\"%.*s\"\n", len, cp);
11591590Srgrimes}
11601590Srgrimes
1161100824Sdwmalonevoid
1162115759Speterhexdump(char *p, int len, int screenwidth)
11631590Srgrimes{
1164115759Speter	int n, i;
1165115759Speter	int width;
1166115759Speter
1167115759Speter	width = 0;
1168115759Speter	do {
1169115759Speter		width += 2;
1170115759Speter		i = 13;			/* base offset */
1171115759Speter		i += (width / 2) + 1;	/* spaces every second byte */
1172115759Speter		i += (width * 2);	/* width of bytes */
1173115759Speter		i += 3;			/* "  |" */
1174115759Speter		i += width;		/* each byte */
1175115759Speter		i += 1;			/* "|" */
1176115759Speter	} while (i < screenwidth);
1177115759Speter	width -= 2;
1178115759Speter
1179115759Speter	for (n = 0; n < len; n += width) {
1180115759Speter		for (i = n; i < n + width; i++) {
1181115759Speter			if ((i % width) == 0) {	/* beginning of line */
1182115759Speter				printf("       0x%04x", i);
1183115759Speter			}
1184115759Speter			if ((i % 2) == 0) {
1185115759Speter				printf(" ");
1186115759Speter			}
1187115759Speter			if (i < len)
1188115759Speter				printf("%02x", p[i] & 0xff);
1189115759Speter			else
1190115759Speter				printf("  ");
1191115759Speter		}
1192115759Speter		printf("  |");
1193115759Speter		for (i = n; i < n + width; i++) {
1194115759Speter			if (i >= len)
1195115759Speter				break;
1196115759Speter			if (p[i] >= ' ' && p[i] <= '~')
1197115759Speter				printf("%c", p[i]);
1198115759Speter			else
1199115759Speter				printf(".");
1200115759Speter		}
1201115759Speter		printf("|\n");
1202115759Speter	}
1203115759Speter	if ((i % width) != 0)
1204115759Speter		printf("\n");
1205115759Speter}
1206115759Speter
1207115759Spetervoid
1208115759Spetervisdump(char *dp, int datalen, int screenwidth)
1209115759Speter{
1210115759Speter	int col = 0;
1211100824Sdwmalone	char *cp;
1212100824Sdwmalone	int width;
12131590Srgrimes	char visbuf[5];
12141590Srgrimes
1215226153Sdes	printf("       \"");
12161590Srgrimes	col = 8;
12171590Srgrimes	for (;datalen > 0; datalen--, dp++) {
1218226153Sdes		 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
12191590Srgrimes		cp = visbuf;
12201590Srgrimes		/*
12211590Srgrimes		 * Keep track of printables and
12221590Srgrimes		 * space chars (like fold(1)).
12231590Srgrimes		 */
12241590Srgrimes		if (col == 0) {
1225226153Sdes			putchar('\t');
12261590Srgrimes			col = 8;
12271590Srgrimes		}
12281590Srgrimes		switch(*cp) {
12291590Srgrimes		case '\n':
12301590Srgrimes			col = 0;
1231226153Sdes			putchar('\n');
12321590Srgrimes			continue;
12331590Srgrimes		case '\t':
12341590Srgrimes			width = 8 - (col&07);
12351590Srgrimes			break;
12361590Srgrimes		default:
12371590Srgrimes			width = strlen(cp);
12381590Srgrimes		}
12391590Srgrimes		if (col + width > (screenwidth-2)) {
1240226153Sdes			printf("\\\n\t");
12411590Srgrimes			col = 8;
12421590Srgrimes		}
12431590Srgrimes		col += width;
12441590Srgrimes		do {
1245226153Sdes			putchar(*cp++);
12461590Srgrimes		} while (*cp);
12471590Srgrimes	}
12481590Srgrimes	if (col == 0)
1249226153Sdes		printf("       ");
1250226153Sdes	printf("\"\n");
12511590Srgrimes}
12521590Srgrimes
1253115759Spetervoid
1254115759Speterktrgenio(struct ktr_genio *ktr, int len)
1255115759Speter{
1256115759Speter	int datalen = len - sizeof (struct ktr_genio);
1257115759Speter	char *dp = (char *)ktr + sizeof (struct ktr_genio);
1258115759Speter	static int screenwidth = 0;
1259115759Speter	int i, binary;
1260115759Speter
1261251072Spjd	printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1262251072Spjd		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1263251072Spjd		datalen == 1 ? "" : "s");
1264251072Spjd	if (suppressdata)
1265251072Spjd		return;
1266115759Speter	if (screenwidth == 0) {
1267115759Speter		struct winsize ws;
1268115759Speter
1269115759Speter		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1270115759Speter		    ws.ws_col > 8)
1271115759Speter			screenwidth = ws.ws_col;
1272115759Speter		else
1273115759Speter			screenwidth = 80;
1274115759Speter	}
1275115759Speter	if (maxdata && datalen > maxdata)
1276115759Speter		datalen = maxdata;
1277115759Speter
1278115759Speter	for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1279115759Speter		if (dp[i] >= 32 && dp[i] < 127)
1280115759Speter			continue;
1281115759Speter		if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1282115759Speter			continue;
1283115759Speter		binary = 1;
1284115759Speter	}
1285115759Speter	if (binary)
1286115759Speter		hexdump(dp, datalen, screenwidth);
1287115759Speter	else
1288115759Speter		visdump(dp, datalen, screenwidth);
1289115759Speter}
1290115759Speter
1291100824Sdwmaloneconst char *signames[] = {
12921590Srgrimes	"NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",	/*  1 - 6  */
12931590Srgrimes	"EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",		/*  7 - 12 */
12941590Srgrimes	"PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",		/* 13 - 18 */
12951590Srgrimes	"CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",		/* 19 - 24 */
12961590Srgrimes	"XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",	/* 25 - 30 */
12971590Srgrimes	"USR2", NULL,						/* 31 - 32 */
12981590Srgrimes};
12991590Srgrimes
1300100824Sdwmalonevoid
1301219138Sdchaginktrpsig(struct ktr_psig *psig)
13021590Srgrimes{
1303219138Sdchagin	if (psig->signo > 0 && psig->signo < NSIG)
1304226153Sdes		printf("SIG%s ", signames[psig->signo]);
1305160294Skib	else
1306226153Sdes		printf("SIG %d ", psig->signo);
1307240820Sjilles	if (psig->action == SIG_DFL) {
1308240820Sjilles		printf("SIG_DFL code=");
1309240820Sjilles		sigcodename(psig->signo, psig->code);
1310240820Sjilles		putchar('\n');
1311240820Sjilles	} else {
1312240820Sjilles		printf("caught handler=0x%lx mask=0x%x code=",
1313240820Sjilles		    (u_long)psig->action, psig->mask.__bits[0]);
1314240820Sjilles		sigcodename(psig->signo, psig->code);
1315240820Sjilles		putchar('\n');
1316100824Sdwmalone	}
13171590Srgrimes}
13181590Srgrimes
1319100824Sdwmalonevoid
1320234494Sjhbktrcsw_old(struct ktr_csw_old *cs)
13211590Srgrimes{
1322226153Sdes	printf("%s %s\n", cs->out ? "stop" : "resume",
13231590Srgrimes		cs->user ? "user" : "kernel");
13241590Srgrimes}
13251590Srgrimes
1326234494Sjhbvoid
1327234494Sjhbktrcsw(struct ktr_csw *cs)
1328234494Sjhb{
1329234494Sjhb	printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume",
1330234494Sjhb	    cs->user ? "user" : "kernel", cs->wmesg);
1331234494Sjhb}
1332234494Sjhb
1333165916Sjhb#define	UTRACE_DLOPEN_START		1
1334165916Sjhb#define	UTRACE_DLOPEN_STOP		2
1335165916Sjhb#define	UTRACE_DLCLOSE_START		3
1336165916Sjhb#define	UTRACE_DLCLOSE_STOP		4
1337165916Sjhb#define	UTRACE_LOAD_OBJECT		5
1338165916Sjhb#define	UTRACE_UNLOAD_OBJECT		6
1339165916Sjhb#define	UTRACE_ADD_RUNDEP		7
1340165916Sjhb#define	UTRACE_PRELOAD_FINISHED		8
1341165916Sjhb#define	UTRACE_INIT_CALL		9
1342165916Sjhb#define	UTRACE_FINI_CALL		10
1343165916Sjhb
1344165916Sjhbstruct utrace_rtld {
1345165916Sjhb	char sig[4];				/* 'RTLD' */
1346165916Sjhb	int event;
1347165916Sjhb	void *handle;
1348165916Sjhb	void *mapbase;
1349165916Sjhb	size_t mapsize;
1350165916Sjhb	int refcnt;
1351165916Sjhb	char name[MAXPATHLEN];
1352165916Sjhb};
1353165916Sjhb
1354165916Sjhbvoid
1355165916Sjhbktruser_rtld(int len, unsigned char *p)
1356165916Sjhb{
1357165916Sjhb	struct utrace_rtld *ut = (struct utrace_rtld *)p;
1358165916Sjhb	void *parent;
1359165916Sjhb	int mode;
1360165916Sjhb
1361165916Sjhb	switch (ut->event) {
1362165916Sjhb	case UTRACE_DLOPEN_START:
1363165916Sjhb		mode = ut->refcnt;
1364165916Sjhb		printf("dlopen(%s, ", ut->name);
1365165916Sjhb		switch (mode & RTLD_MODEMASK) {
1366165916Sjhb		case RTLD_NOW:
1367165916Sjhb			printf("RTLD_NOW");
1368165916Sjhb			break;
1369165916Sjhb		case RTLD_LAZY:
1370165916Sjhb			printf("RTLD_LAZY");
1371165916Sjhb			break;
1372165916Sjhb		default:
1373165916Sjhb			printf("%#x", mode & RTLD_MODEMASK);
1374165916Sjhb		}
1375165916Sjhb		if (mode & RTLD_GLOBAL)
1376165916Sjhb			printf(" | RTLD_GLOBAL");
1377165916Sjhb		if (mode & RTLD_TRACE)
1378165916Sjhb			printf(" | RTLD_TRACE");
1379165916Sjhb		if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
1380165916Sjhb			printf(" | %#x", mode &
1381165916Sjhb			    ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
1382165916Sjhb		printf(")\n");
1383165916Sjhb		break;
1384165916Sjhb	case UTRACE_DLOPEN_STOP:
1385165916Sjhb		printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
1386165916Sjhb		    ut->refcnt);
1387165916Sjhb		break;
1388165916Sjhb	case UTRACE_DLCLOSE_START:
1389165916Sjhb		printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
1390165916Sjhb		    ut->refcnt);
1391165916Sjhb		break;
1392165916Sjhb	case UTRACE_DLCLOSE_STOP:
1393165916Sjhb		printf("dlclose(%p) finished\n", ut->handle);
1394165916Sjhb		break;
1395165916Sjhb	case UTRACE_LOAD_OBJECT:
1396165916Sjhb		printf("RTLD: loaded   %p @ %p - %p (%s)\n", ut->handle,
1397165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1398165916Sjhb		    ut->name);
1399165916Sjhb		break;
1400165916Sjhb	case UTRACE_UNLOAD_OBJECT:
1401165916Sjhb		printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
1402165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1403165916Sjhb		    ut->name);
1404165916Sjhb		break;
1405165916Sjhb	case UTRACE_ADD_RUNDEP:
1406165916Sjhb		parent = ut->mapbase;
1407165916Sjhb		printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
1408165916Sjhb		    ut->handle, ut->name, ut->refcnt);
1409165916Sjhb		break;
1410165916Sjhb	case UTRACE_PRELOAD_FINISHED:
1411165916Sjhb		printf("RTLD: LD_PRELOAD finished\n");
1412165916Sjhb		break;
1413165916Sjhb	case UTRACE_INIT_CALL:
1414165916Sjhb		printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1415165916Sjhb		    ut->name);
1416165916Sjhb		break;
1417165916Sjhb	case UTRACE_FINI_CALL:
1418165916Sjhb		printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1419165916Sjhb		    ut->name);
1420165916Sjhb		break;
1421165916Sjhb	default:
1422165916Sjhb		p += 4;
1423165916Sjhb		len -= 4;
1424165916Sjhb		printf("RTLD: %d ", len);
1425165916Sjhb		while (len--)
1426165916Sjhb			if (decimal)
1427165916Sjhb				printf(" %d", *p++);
1428165916Sjhb			else
1429165916Sjhb				printf(" %02x", *p++);
1430165916Sjhb		printf("\n");
1431165916Sjhb	}
1432165916Sjhb}
1433165916Sjhb
1434165812Sjhbstruct utrace_malloc {
1435165812Sjhb	void *p;
1436165812Sjhb	size_t s;
1437165812Sjhb	void *r;
1438165812Sjhb};
1439165812Sjhb
1440100824Sdwmalonevoid
1441226329Sdesktruser_malloc(unsigned char *p)
1442165812Sjhb{
1443165812Sjhb	struct utrace_malloc *ut = (struct utrace_malloc *)p;
1444165812Sjhb
1445199265Scperciva	if (ut->p == (void *)(intptr_t)(-1))
1446199265Scperciva		printf("malloc_init()\n");
1447199265Scperciva	else if (ut->s == 0)
1448199265Scperciva		printf("free(%p)\n", ut->p);
1449199265Scperciva	else if (ut->p == NULL)
1450199265Scperciva		printf("%p = malloc(%zu)\n", ut->r, ut->s);
1451199265Scperciva	else
1452199265Scperciva		printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1453165812Sjhb}
1454165812Sjhb
1455165812Sjhbvoid
1456100824Sdwmalonektruser(int len, unsigned char *p)
145718400Sphk{
1458165812Sjhb
1459165916Sjhb	if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1460165916Sjhb		ktruser_rtld(len, p);
1461165916Sjhb		return;
1462165916Sjhb	}
1463165916Sjhb
1464165812Sjhb	if (len == sizeof(struct utrace_malloc)) {
1465226329Sdes		ktruser_malloc(p);
1466165812Sjhb		return;
1467165812Sjhb	}
1468165812Sjhb
1469226153Sdes	printf("%d ", len);
147018470Sphk	while (len--)
1471127402Sphk		if (decimal)
1472226153Sdes			printf(" %d", *p++);
1473127402Sphk		else
1474226153Sdes			printf(" %02x", *p++);
1475226153Sdes	printf("\n");
147618400Sphk}
147718400Sphk
1478100824Sdwmalonevoid
1479176471Sdesktrsockaddr(struct sockaddr *sa)
1480176471Sdes{
1481176471Sdes/*
1482176471Sdes TODO: Support additional address families
1483176471Sdes	#include <netnatm/natm.h>
1484176471Sdes	struct sockaddr_natm	*natm;
1485252356Sdavide	#include <netsmb/netbios.h>
1486252356Sdavide	struct sockaddr_nb	*nb;
1487176471Sdes*/
1488176471Sdes	char addr[64];
1489176471Sdes
1490176471Sdes	/*
1491176471Sdes	 * note: ktrstruct() has already verified that sa points to a
1492176471Sdes	 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1493176471Sdes	 * sa->sa_len bytes long.
1494176471Sdes	 */
1495176471Sdes	printf("struct sockaddr { ");
1496176471Sdes	sockfamilyname(sa->sa_family);
1497176471Sdes	printf(", ");
1498176471Sdes
1499176471Sdes#define check_sockaddr_len(n)					\
1500226329Sdes	if (sa_##n.s##n##_len < sizeof(struct sockaddr_##n)) {	\
1501176471Sdes		printf("invalid");				\
1502176471Sdes		break;						\
1503176471Sdes	}
1504176471Sdes
1505176471Sdes	switch(sa->sa_family) {
1506176471Sdes	case AF_INET: {
1507226329Sdes		struct sockaddr_in sa_in;
1508176471Sdes
1509226329Sdes		memset(&sa_in, 0, sizeof(sa_in));
1510246719Szont		memcpy(&sa_in, sa, sa->sa_len);
1511176471Sdes		check_sockaddr_len(in);
1512226329Sdes		inet_ntop(AF_INET, &sa_in.sin_addr, addr, sizeof addr);
1513226329Sdes		printf("%s:%u", addr, ntohs(sa_in.sin_port));
1514176471Sdes		break;
1515176471Sdes	}
1516176471Sdes#ifdef NETATALK
1517176471Sdes	case AF_APPLETALK: {
1518226329Sdes		struct sockaddr_at	sa_at;
1519176471Sdes		struct netrange		*nr;
1520176471Sdes
1521226329Sdes		memset(&sa_at, 0, sizeof(sa_at));
1522246719Szont		memcpy(&sa_at, sa, sa->sa_len);
1523176471Sdes		check_sockaddr_len(at);
1524226329Sdes		nr = &sa_at.sat_range.r_netrange;
1525226329Sdes		printf("%d.%d, %d-%d, %d", ntohs(sa_at.sat_addr.s_net),
1526226329Sdes			sa_at.sat_addr.s_node, ntohs(nr->nr_firstnet),
1527176471Sdes			ntohs(nr->nr_lastnet), nr->nr_phase);
1528176471Sdes		break;
1529176471Sdes	}
1530176471Sdes#endif
1531176471Sdes	case AF_INET6: {
1532226329Sdes		struct sockaddr_in6 sa_in6;
1533176471Sdes
1534226329Sdes		memset(&sa_in6, 0, sizeof(sa_in6));
1535246719Szont		memcpy(&sa_in6, sa, sa->sa_len);
1536176471Sdes		check_sockaddr_len(in6);
1537251486Sae		getnameinfo((struct sockaddr *)&sa_in6, sizeof(sa_in6),
1538251486Sae		    addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
1539226329Sdes		printf("[%s]:%u", addr, htons(sa_in6.sin6_port));
1540176471Sdes		break;
1541176471Sdes	}
1542176471Sdes#ifdef IPX
1543176471Sdes	case AF_IPX: {
1544226329Sdes		struct sockaddr_ipx sa_ipx;
1545176471Sdes
1546226329Sdes		memset(&sa_ipx, 0, sizeof(sa_ipx));
1547246719Szont		memcpy(&sa_ipx, sa, sa->sa_len);
1548176471Sdes		check_sockaddr_len(ipx);
1549176471Sdes		/* XXX wish we had ipx_ntop */
1550226329Sdes		printf("%s", ipx_ntoa(sa_ipx.sipx_addr));
1551226329Sdes		free(sa_ipx);
1552176471Sdes		break;
1553176471Sdes	}
1554176471Sdes#endif
1555176471Sdes	case AF_UNIX: {
1556226329Sdes		struct sockaddr_un sa_un;
1557176471Sdes
1558226329Sdes		memset(&sa_un, 0, sizeof(sa_un));
1559246719Szont		memcpy(&sa_un, sa, sa->sa_len);
1560226329Sdes		printf("%.*s", (int)sizeof(sa_un.sun_path), sa_un.sun_path);
1561176471Sdes		break;
1562176471Sdes	}
1563176471Sdes	default:
1564176471Sdes		printf("unknown address family");
1565176471Sdes	}
1566176471Sdes	printf(" }\n");
1567176471Sdes}
1568176471Sdes
1569176471Sdesvoid
1570176471Sdesktrstat(struct stat *statp)
1571176471Sdes{
1572176471Sdes	char mode[12], timestr[PATH_MAX + 4];
1573176471Sdes	struct passwd *pwd;
1574176471Sdes	struct group  *grp;
1575176471Sdes	struct tm *tm;
1576176471Sdes
1577176471Sdes	/*
1578176471Sdes	 * note: ktrstruct() has already verified that statp points to a
1579176471Sdes	 * buffer exactly sizeof(struct stat) bytes long.
1580176471Sdes	 */
1581176471Sdes	printf("struct stat {");
1582176471Sdes	strmode(statp->st_mode, mode);
1583176471Sdes	printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ",
1584176471Sdes		(uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode,
1585176471Sdes		(uintmax_t)statp->st_nlink);
1586176471Sdes	if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1587176471Sdes		printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1588176471Sdes	else
1589176471Sdes		printf("uid=\"%s\", ", pwd->pw_name);
1590176471Sdes	if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1591176471Sdes		printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1592176471Sdes	else
1593176471Sdes		printf("gid=\"%s\", ", grp->gr_name);
1594176471Sdes	printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1595176471Sdes	printf("atime=");
1596176471Sdes	if (resolv == 0)
1597205793Sed		printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1598176471Sdes	else {
1599205793Sed		tm = localtime(&statp->st_atim.tv_sec);
1600226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1601176471Sdes		printf("\"%s\"", timestr);
1602176471Sdes	}
1603205793Sed	if (statp->st_atim.tv_nsec != 0)
1604205793Sed		printf(".%09ld, ", statp->st_atim.tv_nsec);
1605176471Sdes	else
1606176471Sdes		printf(", ");
1607176471Sdes	printf("stime=");
1608176471Sdes	if (resolv == 0)
1609205793Sed		printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1610176471Sdes	else {
1611205793Sed		tm = localtime(&statp->st_mtim.tv_sec);
1612226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1613176471Sdes		printf("\"%s\"", timestr);
1614176471Sdes	}
1615205793Sed	if (statp->st_mtim.tv_nsec != 0)
1616205793Sed		printf(".%09ld, ", statp->st_mtim.tv_nsec);
1617176471Sdes	else
1618176471Sdes		printf(", ");
1619176471Sdes	printf("ctime=");
1620176471Sdes	if (resolv == 0)
1621205793Sed		printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1622176471Sdes	else {
1623205793Sed		tm = localtime(&statp->st_ctim.tv_sec);
1624226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1625176471Sdes		printf("\"%s\"", timestr);
1626176471Sdes	}
1627205793Sed	if (statp->st_ctim.tv_nsec != 0)
1628205793Sed		printf(".%09ld, ", statp->st_ctim.tv_nsec);
1629176471Sdes	else
1630176471Sdes		printf(", ");
1631176471Sdes	printf("birthtime=");
1632176471Sdes	if (resolv == 0)
1633205793Sed		printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
1634176471Sdes	else {
1635205793Sed		tm = localtime(&statp->st_birthtim.tv_sec);
1636226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1637176471Sdes		printf("\"%s\"", timestr);
1638176471Sdes	}
1639205793Sed	if (statp->st_birthtim.tv_nsec != 0)
1640205793Sed		printf(".%09ld, ", statp->st_birthtim.tv_nsec);
1641176471Sdes	else
1642176471Sdes		printf(", ");
1643176471Sdes	printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1644176471Sdes		(uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
1645176471Sdes		(intmax_t)statp->st_blocks, statp->st_flags);
1646176471Sdes	printf(" }\n");
1647176471Sdes}
1648176471Sdes
1649176471Sdesvoid
1650176471Sdesktrstruct(char *buf, size_t buflen)
1651176471Sdes{
1652176471Sdes	char *name, *data;
1653176471Sdes	size_t namelen, datalen;
1654176471Sdes	int i;
1655204045Simp	struct stat sb;
1656204045Simp	struct sockaddr_storage ss;
1657176471Sdes
1658176471Sdes	for (name = buf, namelen = 0;
1659176471Sdes	     namelen < buflen && name[namelen] != '\0';
1660176471Sdes	     ++namelen)
1661176471Sdes		/* nothing */;
1662176471Sdes	if (namelen == buflen)
1663176471Sdes		goto invalid;
1664176471Sdes	if (name[namelen] != '\0')
1665176471Sdes		goto invalid;
1666176471Sdes	data = buf + namelen + 1;
1667176471Sdes	datalen = buflen - namelen - 1;
1668176471Sdes	if (datalen == 0)
1669176471Sdes		goto invalid;
1670176471Sdes	/* sanity check */
1671226329Sdes	for (i = 0; i < (int)namelen; ++i)
1672226329Sdes		if (!isalpha(name[i]))
1673176471Sdes			goto invalid;
1674176471Sdes	if (strcmp(name, "stat") == 0) {
1675176471Sdes		if (datalen != sizeof(struct stat))
1676176471Sdes			goto invalid;
1677204045Simp		memcpy(&sb, data, datalen);
1678204045Simp		ktrstat(&sb);
1679176471Sdes	} else if (strcmp(name, "sockaddr") == 0) {
1680204045Simp		if (datalen > sizeof(ss))
1681204045Simp			goto invalid;
1682204045Simp		memcpy(&ss, data, datalen);
1683246720Szont		if (datalen != ss.ss_len)
1684176471Sdes			goto invalid;
1685204045Simp		ktrsockaddr((struct sockaddr *)&ss);
1686176471Sdes	} else {
1687176471Sdes		printf("unknown structure\n");
1688176471Sdes	}
1689176471Sdes	return;
1690176471Sdesinvalid:
1691176471Sdes	printf("invalid record\n");
1692176471Sdes}
1693176471Sdes
1694226269Sdesvoid
1695226269Sdesktrcapfail(struct ktr_cap_fail *ktr)
1696226269Sdes{
1697226495Sdes	switch (ktr->cap_type) {
1698226495Sdes	case CAPFAIL_NOTCAPABLE:
1699226495Sdes		/* operation on fd with insufficient capabilities */
1700226495Sdes		printf("operation requires ");
1701226495Sdes		capname((intmax_t)ktr->cap_needed);
1702226495Sdes		printf(", process holds ");
1703226495Sdes		capname((intmax_t)ktr->cap_held);
1704226495Sdes		break;
1705226495Sdes	case CAPFAIL_INCREASE:
1706226495Sdes		/* requested more capabilities than fd already has */
1707226495Sdes		printf("attempt to increase capabilities from ");
1708226505Sdes		capname((intmax_t)ktr->cap_held);
1709226505Sdes		printf(" to ");
1710226495Sdes		capname((intmax_t)ktr->cap_needed);
1711226495Sdes		break;
1712226495Sdes	case CAPFAIL_SYSCALL:
1713226495Sdes		/* called restricted syscall */
1714226495Sdes		printf("disallowed system call");
1715226495Sdes		break;
1716226495Sdes	case CAPFAIL_LOOKUP:
1717226495Sdes		/* used ".." in strict-relative mode */
1718226495Sdes		printf("restricted VFS lookup");
1719226495Sdes		break;
1720226495Sdes	default:
1721226495Sdes		printf("unknown capability failure: ");
1722226495Sdes		capname((intmax_t)ktr->cap_needed);
1723226495Sdes		printf(" ");
1724226495Sdes		capname((intmax_t)ktr->cap_held);
1725226495Sdes		break;
1726226495Sdes	}
1727233925Sjhb	printf("\n");
1728226269Sdes}
1729226269Sdes
1730233925Sjhbvoid
1731233925Sjhbktrfault(struct ktr_fault *ktr)
1732233925Sjhb{
1733233925Sjhb
1734233925Sjhb	printf("0x%jx ", ktr->vaddr);
1735233925Sjhb	vmprotname(ktr->type);
1736233925Sjhb	printf("\n");
1737233925Sjhb}
1738233925Sjhb
1739233925Sjhbvoid
1740233925Sjhbktrfaultend(struct ktr_faultend *ktr)
1741233925Sjhb{
1742233925Sjhb
1743233925Sjhb	vmresultname(ktr->result);
1744233925Sjhb	printf("\n");
1745233925Sjhb}
1746233925Sjhb
1747219138Sdchagin#if defined(__amd64__) || defined(__i386__)
1748176471Sdesvoid
1749219138Sdchaginlinux_ktrsyscall(struct ktr_syscall *ktr)
1750219138Sdchagin{
1751219138Sdchagin	int narg = ktr->ktr_narg;
1752219138Sdchagin	register_t *ip;
1753219138Sdchagin
1754219138Sdchagin	if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
1755219138Sdchagin		printf("[%d]", ktr->ktr_code);
1756219138Sdchagin	else
1757219138Sdchagin		printf("%s", linux_syscallnames[ktr->ktr_code]);
1758219138Sdchagin	ip = &ktr->ktr_args[0];
1759219138Sdchagin	if (narg) {
1760219138Sdchagin		char c = '(';
1761219138Sdchagin		while (narg > 0)
1762219138Sdchagin			print_number(ip, narg, c);
1763219138Sdchagin		putchar(')');
1764219138Sdchagin	}
1765219138Sdchagin	putchar('\n');
1766219138Sdchagin}
1767219138Sdchagin
1768219138Sdchaginvoid
1769219138Sdchaginlinux_ktrsysret(struct ktr_sysret *ktr)
1770219138Sdchagin{
1771219138Sdchagin	register_t ret = ktr->ktr_retval;
1772219138Sdchagin	int error = ktr->ktr_error;
1773219138Sdchagin	int code = ktr->ktr_code;
1774219138Sdchagin
1775219138Sdchagin	if (code >= nlinux_syscalls || code < 0)
1776219138Sdchagin		printf("[%d] ", code);
1777219138Sdchagin	else
1778219138Sdchagin		printf("%s ", linux_syscallnames[code]);
1779219138Sdchagin
1780219138Sdchagin	if (error == 0) {
1781219138Sdchagin		if (fancy) {
1782219138Sdchagin			printf("%ld", (long)ret);
1783219138Sdchagin			if (ret < 0 || ret > 9)
1784226153Sdes				printf("/%#lx", (unsigned long)ret);
1785219138Sdchagin		} else {
1786219138Sdchagin			if (decimal)
1787219138Sdchagin				printf("%ld", (long)ret);
1788219138Sdchagin			else
1789226153Sdes				printf("%#lx", (unsigned long)ret);
1790219138Sdchagin		}
1791219138Sdchagin	} else if (error == ERESTART)
1792219138Sdchagin		printf("RESTART");
1793219138Sdchagin	else if (error == EJUSTRETURN)
1794219138Sdchagin		printf("JUSTRETURN");
1795219138Sdchagin	else {
1796219138Sdchagin		if (ktr->ktr_error <= ELAST + 1)
1797219138Sdchagin			error = abs(bsd_to_linux_errno[ktr->ktr_error]);
1798219138Sdchagin		else
1799219138Sdchagin			error = 999;
1800219138Sdchagin		printf("-1 errno %d", error);
1801219138Sdchagin		if (fancy)
1802219138Sdchagin			printf(" %s", strerror(ktr->ktr_error));
1803219138Sdchagin	}
1804219138Sdchagin	putchar('\n');
1805219138Sdchagin}
1806219138Sdchagin#endif
1807219138Sdchagin
1808219138Sdchaginvoid
1809100824Sdwmaloneusage(void)
18101590Srgrimes{
1811219043Sdchagin	fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] "
1812177856Sru	    "[-m maxdata] [-p pid] [-t trstr]\n");
18131590Srgrimes	exit(1);
18141590Srgrimes}
1815