kdump.c revision 219138
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 219138 2011-03-01 16:42:28Z dchagin $");
431590Srgrimes
4455206Speter#define _KERNEL
452215Scsgrextern int errno;
462215Scsgr#include <sys/errno.h>
4755206Speter#undef _KERNEL
481590Srgrimes#include <sys/param.h>
491590Srgrimes#include <sys/errno.h>
50100824Sdwmalone#define _KERNEL
511590Srgrimes#include <sys/time.h>
52100824Sdwmalone#undef _KERNEL
531590Srgrimes#include <sys/uio.h>
541590Srgrimes#include <sys/ktrace.h>
551590Srgrimes#include <sys/ioctl.h>
56165758Srodrigc#include <sys/socket.h>
57176471Sdes#include <sys/stat.h>
58219043Sdchagin#include <sys/sysent.h>
59176471Sdes#include <sys/un.h>
60219043Sdchagin#include <sys/queue.h>
61176471Sdes#ifdef IPX
62176471Sdes#include <sys/types.h>
63176471Sdes#include <netipx/ipx.h>
64176471Sdes#endif
65176471Sdes#ifdef NETATALK
66176471Sdes#include <netatalk/at.h>
67176471Sdes#endif
68190168Sdelphij#include <arpa/inet.h>
69176471Sdes#include <netinet/in.h>
70190168Sdelphij#include <ctype.h>
71165916Sjhb#include <dlfcn.h>
7227443Scharnier#include <err.h>
73176471Sdes#include <grp.h>
74176471Sdes#include <inttypes.h>
7527443Scharnier#include <locale.h>
76176471Sdes#include <pwd.h>
771590Srgrimes#include <stdio.h>
781590Srgrimes#include <stdlib.h>
791590Srgrimes#include <string.h>
80176471Sdes#include <time.h>
8127443Scharnier#include <unistd.h>
8227443Scharnier#include <vis.h>
831590Srgrimes#include "ktrace.h"
84158766Snetchild#include "kdump_subr.h"
851590Srgrimes
86219043Sdchaginu_int abidump(struct ktr_header *);
87219043Sdchaginint fetchprocinfo(struct ktr_header *, u_int *);
88100824Sdwmaloneint fread_tail(void *, int, int);
89100824Sdwmalonevoid dumpheader(struct ktr_header *);
90219043Sdchaginvoid ktrsyscall(struct ktr_syscall *, u_int);
91219043Sdchaginvoid ktrsysret(struct ktr_sysret *, u_int);
92100824Sdwmalonevoid ktrnamei(char *, int);
93115759Spetervoid hexdump(char *, int, int);
94115759Spetervoid visdump(char *, int, int);
95100824Sdwmalonevoid ktrgenio(struct ktr_genio *, int);
96219138Sdchaginvoid ktrpsig(struct ktr_psig *);
97100824Sdwmalonevoid ktrcsw(struct ktr_csw *);
98100824Sdwmalonevoid ktruser(int, unsigned char *);
99176471Sdesvoid ktrsockaddr(struct sockaddr *);
100176471Sdesvoid ktrstat(struct stat *);
101176471Sdesvoid ktrstruct(char *, size_t);
102100824Sdwmalonevoid usage(void);
103190168Sdelphijvoid sockfamilyname(int);
104135466Sruconst char *ioctlname(u_long);
105100824Sdwmalone
106176471Sdesint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
107219043Sdchagin    resolv = 0, abiflag = 0;
108100824Sdwmaloneconst char *tracefile = DEF_TRACEFILE;
1091590Srgrimesstruct ktr_header ktr_header;
1101590Srgrimes
111176471Sdes#define TIME_FORMAT	"%b %e %T %Y"
1121590Srgrimes#define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
1131590Srgrimes
114219138Sdchagin#define print_number(i,n,c) do {		\
115219138Sdchagin	if (decimal)				\
116219138Sdchagin		printf("%c%ld", c, (long)*i);	\
117219138Sdchagin	else					\
118219138Sdchagin		printf("%c%#lx", c, (long)*i);	\
119219138Sdchagin	i++;					\
120219138Sdchagin	n--;					\
121219138Sdchagin	c = ',';				\
122219138Sdchagin	} while (0);
123219138Sdchagin
124219138Sdchagin#if defined(__amd64__) || defined(__i386__)
125219138Sdchagin
126219138Sdchaginvoid linux_ktrsyscall(struct ktr_syscall *);
127219138Sdchaginvoid linux_ktrsysret(struct ktr_sysret *);
128219138Sdchaginextern char *linux_syscallnames[];
129219138Sdchaginextern int nlinux_syscalls;
130219138Sdchagin
131219138Sdchagin/*
132219138Sdchagin * from linux.h
133219138Sdchagin * Linux syscalls return negative errno's, we do positive and map them
134219138Sdchagin */
135219138Sdchaginstatic int bsd_to_linux_errno[ELAST + 1] = {
136219138Sdchagin	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
137219138Sdchagin	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
138219138Sdchagin	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
139219138Sdchagin	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
140219138Sdchagin	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
141219138Sdchagin	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
142219138Sdchagin	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
143219138Sdchagin	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
144219138Sdchagin	-6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
145219138Sdchagin	-72, -67, -71
146219138Sdchagin};
147219138Sdchagin#endif
148219138Sdchagin
149219043Sdchaginstruct proc_info
150219043Sdchagin{
151219043Sdchagin	TAILQ_ENTRY(proc_info)	info;
152219043Sdchagin	u_int			sv_flags;
153219043Sdchagin	pid_t			pid;
154219043Sdchagin};
155219043Sdchagin
156219043SdchaginTAILQ_HEAD(trace_procs, proc_info) trace_procs;
157219043Sdchagin
158100824Sdwmaloneint
159100824Sdwmalonemain(int argc, char *argv[])
1601590Srgrimes{
1611590Srgrimes	int ch, ktrlen, size;
162100824Sdwmalone	void *m;
1631590Srgrimes	int trpoints = ALL_POINTS;
164112201Sjhb	int drop_logged;
165115759Speter	pid_t pid = 0;
166219043Sdchagin	u_int sv_flags;
1671590Srgrimes
16811823Sache	(void) setlocale(LC_CTYPE, "");
16911823Sache
170219043Sdchagin	while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1)
1711590Srgrimes		switch((char)ch) {
172219043Sdchagin		case 'A':
173219043Sdchagin			abiflag = 1;
174219043Sdchagin			break;
1751590Srgrimes		case 'f':
1761590Srgrimes			tracefile = optarg;
1771590Srgrimes			break;
1781590Srgrimes		case 'd':
1791590Srgrimes			decimal = 1;
1801590Srgrimes			break;
1811590Srgrimes		case 'l':
1821590Srgrimes			tail = 1;
1831590Srgrimes			break;
1841590Srgrimes		case 'm':
1851590Srgrimes			maxdata = atoi(optarg);
1861590Srgrimes			break;
1871590Srgrimes		case 'n':
1881590Srgrimes			fancy = 0;
1891590Srgrimes			break;
190115759Speter		case 'p':
191115759Speter			pid = atoi(optarg);
192115759Speter			break;
193176471Sdes		case 'r':
194176471Sdes			resolv = 1;
195176471Sdes			break;
196152331Srwatson		case 's':
197152331Srwatson			suppressdata = 1;
198152331Srwatson			break;
199123187Speter		case 'E':
200123187Speter			timestamp = 3;	/* elapsed timestamp */
201123187Speter			break;
202151930Srwatson		case 'H':
203151930Srwatson			threads = 1;
204151930Srwatson			break;
2051590Srgrimes		case 'R':
2061590Srgrimes			timestamp = 2;	/* relative timestamp */
2071590Srgrimes			break;
2081590Srgrimes		case 'T':
2091590Srgrimes			timestamp = 1;
2101590Srgrimes			break;
2111590Srgrimes		case 't':
2121590Srgrimes			trpoints = getpoints(optarg);
21327443Scharnier			if (trpoints < 0)
21427443Scharnier				errx(1, "unknown trace point in %s", optarg);
2151590Srgrimes			break;
2161590Srgrimes		default:
2171590Srgrimes			usage();
2181590Srgrimes		}
2191590Srgrimes
22019853Sfenner	if (argc > optind)
2211590Srgrimes		usage();
2221590Srgrimes
2231590Srgrimes	m = (void *)malloc(size = 1025);
22427443Scharnier	if (m == NULL)
22527443Scharnier		errx(1, "%s", strerror(ENOMEM));
22627443Scharnier	if (!freopen(tracefile, "r", stdin))
22727443Scharnier		err(1, "%s", tracefile);
228219043Sdchagin	TAILQ_INIT(&trace_procs);
229112201Sjhb	drop_logged = 0;
2301590Srgrimes	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
231112201Sjhb		if (ktr_header.ktr_type & KTR_DROP) {
232112201Sjhb			ktr_header.ktr_type &= ~KTR_DROP;
233151930Srwatson			if (!drop_logged && threads) {
234203551Sjh				(void)printf(
235203551Sjh				    "%6jd %6jd %-8.*s Events dropped.\n",
236203551Sjh				    (intmax_t)ktr_header.ktr_pid,
237203551Sjh				    ktr_header.ktr_tid > 0 ?
238203551Sjh				    (intmax_t)ktr_header.ktr_tid : 0,
239203551Sjh				    MAXCOMLEN, ktr_header.ktr_comm);
240151930Srwatson				drop_logged = 1;
241151930Srwatson			} else if (!drop_logged) {
242203551Sjh				(void)printf("%6jd %-8.*s Events dropped.\n",
243203551Sjh				    (intmax_t)ktr_header.ktr_pid, MAXCOMLEN,
244112201Sjhb				    ktr_header.ktr_comm);
245112201Sjhb				drop_logged = 1;
246112201Sjhb			}
247112201Sjhb		}
2481590Srgrimes		if (trpoints & (1<<ktr_header.ktr_type))
249115759Speter			if (pid == 0 || ktr_header.ktr_pid == pid)
250115759Speter				dumpheader(&ktr_header);
25127443Scharnier		if ((ktrlen = ktr_header.ktr_len) < 0)
25227443Scharnier			errx(1, "bogus length 0x%x", ktrlen);
2531590Srgrimes		if (ktrlen > size) {
2541590Srgrimes			m = (void *)realloc(m, ktrlen+1);
25527443Scharnier			if (m == NULL)
25627443Scharnier				errx(1, "%s", strerror(ENOMEM));
2571590Srgrimes			size = ktrlen;
2581590Srgrimes		}
25927443Scharnier		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
26027443Scharnier			errx(1, "data too short");
261219043Sdchagin		if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
262219043Sdchagin			continue;
263219043Sdchagin		sv_flags = abidump(&ktr_header);
264115759Speter		if (pid && ktr_header.ktr_pid != pid)
265115759Speter			continue;
2661590Srgrimes		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
2671590Srgrimes			continue;
268112201Sjhb		drop_logged = 0;
2691590Srgrimes		switch (ktr_header.ktr_type) {
2701590Srgrimes		case KTR_SYSCALL:
271219138Sdchagin#if defined(__amd64__) || defined(__i386__)
272219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
273219138Sdchagin				linux_ktrsyscall((struct ktr_syscall *)m);
274219138Sdchagin			else
275219138Sdchagin#endif
276219138Sdchagin				ktrsyscall((struct ktr_syscall *)m, sv_flags);
2771590Srgrimes			break;
2781590Srgrimes		case KTR_SYSRET:
279219138Sdchagin#if defined(__amd64__) || defined(__i386__)
280219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
281219138Sdchagin				linux_ktrsysret((struct ktr_sysret *)m);
282219138Sdchagin			else
283219138Sdchagin#endif
284219138Sdchagin				ktrsysret((struct ktr_sysret *)m, sv_flags);
2851590Srgrimes			break;
2861590Srgrimes		case KTR_NAMEI:
287189707Sjhb		case KTR_SYSCTL:
2881590Srgrimes			ktrnamei(m, ktrlen);
2891590Srgrimes			break;
2901590Srgrimes		case KTR_GENIO:
2911590Srgrimes			ktrgenio((struct ktr_genio *)m, ktrlen);
2921590Srgrimes			break;
2931590Srgrimes		case KTR_PSIG:
294219138Sdchagin			ktrpsig((struct ktr_psig *)m);
2951590Srgrimes			break;
2961590Srgrimes		case KTR_CSW:
2971590Srgrimes			ktrcsw((struct ktr_csw *)m);
2981590Srgrimes			break;
29918400Sphk		case KTR_USER:
30018470Sphk			ktruser(ktrlen, m);
30118400Sphk			break;
302176471Sdes		case KTR_STRUCT:
303176471Sdes			ktrstruct(m, ktrlen);
304176471Sdes			break;
305112203Sjhb		default:
306112203Sjhb			printf("\n");
307112203Sjhb			break;
3081590Srgrimes		}
3091590Srgrimes		if (tail)
3101590Srgrimes			(void)fflush(stdout);
3111590Srgrimes	}
312100824Sdwmalone	return 0;
3131590Srgrimes}
3141590Srgrimes
315100824Sdwmaloneint
316100824Sdwmalonefread_tail(void *buf, int size, int num)
3171590Srgrimes{
3181590Srgrimes	int i;
3191590Srgrimes
3201590Srgrimes	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
3211590Srgrimes		(void)sleep(1);
3221590Srgrimes		clearerr(stdin);
3231590Srgrimes	}
3241590Srgrimes	return (i);
3251590Srgrimes}
3261590Srgrimes
327219043Sdchaginint
328219043Sdchaginfetchprocinfo(struct ktr_header *kth, u_int *flags)
329219043Sdchagin{
330219043Sdchagin	struct proc_info *pi;
331219043Sdchagin
332219043Sdchagin	switch (kth->ktr_type) {
333219043Sdchagin	case KTR_PROCCTOR:
334219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
335219043Sdchagin			if (pi->pid == kth->ktr_pid) {
336219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
337219043Sdchagin				break;
338219043Sdchagin			}
339219043Sdchagin		}
340219043Sdchagin		pi = malloc(sizeof(struct proc_info));
341219043Sdchagin		if (pi == NULL)
342219043Sdchagin			errx(1, "%s", strerror(ENOMEM));
343219043Sdchagin		pi->sv_flags = *flags;
344219043Sdchagin		pi->pid = kth->ktr_pid;
345219043Sdchagin		TAILQ_INSERT_TAIL(&trace_procs, pi, info);
346219043Sdchagin		return (1);
347219043Sdchagin
348219043Sdchagin	case KTR_PROCDTOR:
349219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
350219043Sdchagin			if (pi->pid == kth->ktr_pid) {
351219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
352219043Sdchagin				free(pi);
353219043Sdchagin				break;
354219043Sdchagin			}
355219043Sdchagin		}
356219043Sdchagin		return (1);
357219043Sdchagin	}
358219043Sdchagin
359219043Sdchagin	return (0);
360219043Sdchagin}
361219043Sdchagin
362219043Sdchaginu_int
363219043Sdchaginabidump(struct ktr_header *kth)
364219043Sdchagin{
365219043Sdchagin	struct proc_info *pi;
366219043Sdchagin	const char *abi;
367219043Sdchagin	const char *arch;
368219043Sdchagin	u_int flags = 0;
369219043Sdchagin
370219043Sdchagin	TAILQ_FOREACH(pi, &trace_procs, info) {
371219043Sdchagin		if (pi->pid == kth->ktr_pid) {
372219043Sdchagin			flags = pi->sv_flags;
373219043Sdchagin			break;
374219043Sdchagin		}
375219043Sdchagin	}
376219043Sdchagin
377219043Sdchagin	if (abiflag == 0)
378219043Sdchagin		return (flags);
379219043Sdchagin
380219043Sdchagin	switch (flags & SV_ABI_MASK) {
381219043Sdchagin	case SV_ABI_LINUX:
382219043Sdchagin		abi = "L";
383219043Sdchagin		break;
384219043Sdchagin	case SV_ABI_FREEBSD:
385219043Sdchagin		abi = "F";
386219043Sdchagin		break;
387219043Sdchagin	default:
388219043Sdchagin		abi = "U";
389219043Sdchagin		break;
390219043Sdchagin	}
391219043Sdchagin
392219043Sdchagin	if (flags != 0) {
393219043Sdchagin		if (flags & SV_LP64)
394219043Sdchagin			arch = "64";
395219043Sdchagin		else
396219043Sdchagin			arch = "32";
397219043Sdchagin	} else
398219043Sdchagin		arch = "00";
399219043Sdchagin
400219043Sdchagin	printf("%s%s  ", abi, arch);
401219043Sdchagin
402219043Sdchagin	return (flags);
403219043Sdchagin}
404219043Sdchagin
405100824Sdwmalonevoid
406100824Sdwmalonedumpheader(struct ktr_header *kth)
4071590Srgrimes{
4081590Srgrimes	static char unknown[64];
4091590Srgrimes	static struct timeval prevtime, temp;
410100824Sdwmalone	const char *type;
4111590Srgrimes
4121590Srgrimes	switch (kth->ktr_type) {
4131590Srgrimes	case KTR_SYSCALL:
4141590Srgrimes		type = "CALL";
4151590Srgrimes		break;
4161590Srgrimes	case KTR_SYSRET:
4171590Srgrimes		type = "RET ";
4181590Srgrimes		break;
4191590Srgrimes	case KTR_NAMEI:
4201590Srgrimes		type = "NAMI";
4211590Srgrimes		break;
4221590Srgrimes	case KTR_GENIO:
4231590Srgrimes		type = "GIO ";
4241590Srgrimes		break;
4251590Srgrimes	case KTR_PSIG:
4261590Srgrimes		type = "PSIG";
4271590Srgrimes		break;
4281590Srgrimes	case KTR_CSW:
429171333Sjhb		type = "CSW ";
4301590Srgrimes		break;
43118400Sphk	case KTR_USER:
43218400Sphk		type = "USER";
43318400Sphk		break;
434176471Sdes	case KTR_STRUCT:
435176471Sdes		type = "STRU";
436176471Sdes		break;
437189707Sjhb	case KTR_SYSCTL:
438189707Sjhb		type = "SCTL";
439189707Sjhb		break;
440219043Sdchagin	case KTR_PROCCTOR:
441219043Sdchagin		/* FALLTHROUGH */
442219043Sdchagin	case KTR_PROCDTOR:
443219043Sdchagin		return;
4441590Srgrimes	default:
4451590Srgrimes		(void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
4461590Srgrimes		type = unknown;
4471590Srgrimes	}
4481590Srgrimes
449151930Srwatson	/*
450151930Srwatson	 * The ktr_tid field was previously the ktr_buffer field, which held
451151930Srwatson	 * the kernel pointer value for the buffer associated with data
452151930Srwatson	 * following the record header.  It now holds a threadid, but only
453151930Srwatson	 * for trace files after the change.  Older trace files still contain
454151930Srwatson	 * kernel pointers.  Detect this and suppress the results by printing
455151930Srwatson	 * negative tid's as 0.
456151930Srwatson	 */
457151930Srwatson	if (threads)
458203551Sjh		(void)printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid,
459203551Sjh		    kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0,
460203551Sjh		    MAXCOMLEN, kth->ktr_comm);
461151930Srwatson	else
462203551Sjh		(void)printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN,
463151930Srwatson		    kth->ktr_comm);
4641590Srgrimes	if (timestamp) {
465123187Speter		if (timestamp == 3) {
466123187Speter			if (prevtime.tv_sec == 0)
467123187Speter				prevtime = kth->ktr_time;
468123187Speter			timevalsub(&kth->ktr_time, &prevtime);
469123187Speter		}
4701590Srgrimes		if (timestamp == 2) {
4711590Srgrimes			temp = kth->ktr_time;
4721590Srgrimes			timevalsub(&kth->ktr_time, &prevtime);
4731590Srgrimes			prevtime = temp;
4741590Srgrimes		}
475203551Sjh		(void)printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
476203551Sjh		    kth->ktr_time.tv_usec);
4771590Srgrimes	}
4781590Srgrimes	(void)printf("%s  ", type);
4791590Srgrimes}
4801590Srgrimes
4811590Srgrimes#include <sys/syscall.h>
4821590Srgrimes#define KTRACE
4834721Sphk#include <sys/kern/syscalls.c>
4841590Srgrimes#undef KTRACE
4851590Srgrimesint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
4861590Srgrimes
487100824Sdwmalonevoid
488219043Sdchaginktrsyscall(struct ktr_syscall *ktr, u_int flags)
4891590Srgrimes{
490100824Sdwmalone	int narg = ktr->ktr_narg;
491100824Sdwmalone	register_t *ip;
4921590Srgrimes
493219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
494219043Sdchagin	    (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
4951590Srgrimes		(void)printf("[%d]", ktr->ktr_code);
4961590Srgrimes	else
4971590Srgrimes		(void)printf("%s", syscallnames[ktr->ktr_code]);
49847957Sdt	ip = &ktr->ktr_args[0];
4991590Srgrimes	if (narg) {
5001590Srgrimes		char c = '(';
501219043Sdchagin		if (fancy &&
502219043Sdchagin		    (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
5031590Srgrimes			if (ktr->ktr_code == SYS_ioctl) {
504100824Sdwmalone				const char *cp;
505158766Snetchild				print_number(ip,narg,c);
5061590Srgrimes				if ((cp = ioctlname(*ip)) != NULL)
5071590Srgrimes					(void)printf(",%s", cp);
5081590Srgrimes				else {
5091590Srgrimes					if (decimal)
51047957Sdt						(void)printf(",%ld", (long)*ip);
5111590Srgrimes					else
51247957Sdt						(void)printf(",%#lx ", (long)*ip);
5131590Srgrimes				}
5141590Srgrimes				c = ',';
5151590Srgrimes				ip++;
5161590Srgrimes				narg--;
5171590Srgrimes			} else if (ktr->ktr_code == SYS_ptrace) {
518168543Semaste				(void)putchar('(');
519168543Semaste				ptraceopname ((int)*ip);
5201590Srgrimes				c = ',';
5211590Srgrimes				ip++;
5221590Srgrimes				narg--;
523158766Snetchild			} else if (ktr->ktr_code == SYS_access ||
524158766Snetchild				   ktr->ktr_code == SYS_eaccess) {
525158766Snetchild				print_number(ip,narg,c);
526158766Snetchild				(void)putchar(',');
527158766Snetchild				accessmodename ((int)*ip);
528158766Snetchild				ip++;
529158766Snetchild				narg--;
530158766Snetchild			} else if (ktr->ktr_code == SYS_open) {
531158766Snetchild				int	flags;
532158766Snetchild				int	mode;
533158766Snetchild				print_number(ip,narg,c);
534158766Snetchild				flags = *ip;
535158766Snetchild				mode = *++ip;
536158766Snetchild				(void)putchar(',');
537158766Snetchild				flagsandmodename (flags, mode, decimal);
538158766Snetchild				ip++;
539158766Snetchild				narg-=2;
540158766Snetchild			} else if (ktr->ktr_code == SYS_wait4) {
541158766Snetchild				print_number(ip,narg,c);
542158766Snetchild				print_number(ip,narg,c);
543158766Snetchild				(void)putchar(',');
544158766Snetchild				wait4optname ((int)*ip);
545158766Snetchild				ip++;
546158766Snetchild				narg--;
547158766Snetchild			} else if (ktr->ktr_code == SYS_chmod ||
548158766Snetchild				   ktr->ktr_code == SYS_fchmod ||
549158766Snetchild				   ktr->ktr_code == SYS_lchmod) {
550158766Snetchild				print_number(ip,narg,c);
551158766Snetchild				(void)putchar(',');
552158766Snetchild				modename ((int)*ip);
553158766Snetchild				ip++;
554158766Snetchild				narg--;
555158766Snetchild			} else if (ktr->ktr_code == SYS_mknod) {
556158766Snetchild				print_number(ip,narg,c);
557158766Snetchild				(void)putchar(',');
558158766Snetchild				modename ((int)*ip);
559158766Snetchild				ip++;
560158766Snetchild				narg--;
561158766Snetchild			} else if (ktr->ktr_code == SYS_getfsstat) {
562158766Snetchild				print_number(ip,narg,c);
563158766Snetchild				print_number(ip,narg,c);
564158766Snetchild				(void)putchar(',');
565158766Snetchild				getfsstatflagsname ((int)*ip);
566158766Snetchild				ip++;
567158766Snetchild				narg--;
568158766Snetchild			} else if (ktr->ktr_code == SYS_mount) {
569158766Snetchild				print_number(ip,narg,c);
570158766Snetchild				print_number(ip,narg,c);
571158766Snetchild				(void)putchar(',');
572158766Snetchild				mountflagsname ((int)*ip);
573158766Snetchild				ip++;
574158766Snetchild				narg--;
575158766Snetchild			} else if (ktr->ktr_code == SYS_unmount) {
576158766Snetchild				print_number(ip,narg,c);
577158766Snetchild				(void)putchar(',');
578158766Snetchild				mountflagsname ((int)*ip);
579158766Snetchild				ip++;
580158766Snetchild				narg--;
581158766Snetchild			} else if (ktr->ktr_code == SYS_recvmsg ||
582158766Snetchild				   ktr->ktr_code == SYS_sendmsg) {
583158766Snetchild				print_number(ip,narg,c);
584158766Snetchild				print_number(ip,narg,c);
585158766Snetchild				(void)putchar(',');
586158766Snetchild				sendrecvflagsname ((int)*ip);
587158766Snetchild				ip++;
588158766Snetchild				narg--;
589158766Snetchild			} else if (ktr->ktr_code == SYS_recvfrom ||
590158766Snetchild				   ktr->ktr_code == SYS_sendto) {
591158766Snetchild				print_number(ip,narg,c);
592158766Snetchild				print_number(ip,narg,c);
593158766Snetchild				print_number(ip,narg,c);
594158766Snetchild				(void)putchar(',');
595158766Snetchild				sendrecvflagsname ((int)*ip);
596158766Snetchild				ip++;
597158766Snetchild				narg--;
598158766Snetchild			} else if (ktr->ktr_code == SYS_chflags ||
599158766Snetchild				   ktr->ktr_code == SYS_fchflags ||
600158766Snetchild				   ktr->ktr_code == SYS_lchflags) {
601158766Snetchild				print_number(ip,narg,c);
602158766Snetchild				(void)putchar(',');
603158766Snetchild				modename((int)*ip);
604158766Snetchild				ip++;
605158766Snetchild				narg--;
606158766Snetchild			} else if (ktr->ktr_code == SYS_kill) {
607158766Snetchild				print_number(ip,narg,c);
608158766Snetchild				(void)putchar(',');
609158766Snetchild				signame((int)*ip);
610158766Snetchild				ip++;
611158766Snetchild				narg--;
612158766Snetchild			} else if (ktr->ktr_code == SYS_reboot) {
613158766Snetchild				(void)putchar('(');
614158766Snetchild				rebootoptname((int)*ip);
615158766Snetchild				ip++;
616158766Snetchild				narg--;
617158766Snetchild			} else if (ktr->ktr_code == SYS_umask) {
618158766Snetchild				(void)putchar('(');
619158766Snetchild				modename((int)*ip);
620158766Snetchild				ip++;
621158766Snetchild				narg--;
622158766Snetchild			} else if (ktr->ktr_code == SYS_msync) {
623158766Snetchild				print_number(ip,narg,c);
624158766Snetchild				print_number(ip,narg,c);
625158766Snetchild				(void)putchar(',');
626158766Snetchild				msyncflagsname((int)*ip);
627158766Snetchild				ip++;
628158766Snetchild				narg--;
629171221Speter#ifdef SYS_freebsd6_mmap
630171221Speter			} else if (ktr->ktr_code == SYS_freebsd6_mmap) {
631171221Speter				print_number(ip,narg,c);
632171221Speter				print_number(ip,narg,c);
633171221Speter				(void)putchar(',');
634171221Speter				mmapprotname ((int)*ip);
635171221Speter				(void)putchar(',');
636171221Speter				ip++;
637171221Speter				narg--;
638171221Speter				mmapflagsname ((int)*ip);
639171221Speter				ip++;
640171221Speter				narg--;
641171221Speter#endif
642158766Snetchild			} else if (ktr->ktr_code == SYS_mmap) {
643158766Snetchild				print_number(ip,narg,c);
644158766Snetchild				print_number(ip,narg,c);
645158766Snetchild				(void)putchar(',');
646158766Snetchild				mmapprotname ((int)*ip);
647158766Snetchild				(void)putchar(',');
648158766Snetchild				ip++;
649158766Snetchild				narg--;
650158766Snetchild				mmapflagsname ((int)*ip);
651158766Snetchild				ip++;
652158766Snetchild				narg--;
653158766Snetchild			} else if (ktr->ktr_code == SYS_mprotect) {
654158766Snetchild				print_number(ip,narg,c);
655158766Snetchild				print_number(ip,narg,c);
656158766Snetchild				(void)putchar(',');
657158766Snetchild				mmapprotname ((int)*ip);
658158766Snetchild				ip++;
659158766Snetchild				narg--;
660158766Snetchild			} else if (ktr->ktr_code == SYS_madvise) {
661158766Snetchild				print_number(ip,narg,c);
662158766Snetchild				print_number(ip,narg,c);
663158766Snetchild				(void)putchar(',');
664158766Snetchild				madvisebehavname((int)*ip);
665158766Snetchild				ip++;
666158766Snetchild				narg--;
667158766Snetchild			} else if (ktr->ktr_code == SYS_setpriority) {
668158766Snetchild				print_number(ip,narg,c);
669158766Snetchild				print_number(ip,narg,c);
670158766Snetchild				(void)putchar(',');
671158766Snetchild				prioname((int)*ip);
672158766Snetchild				ip++;
673158766Snetchild				narg--;
674158766Snetchild			} else if (ktr->ktr_code == SYS_fcntl) {
675158766Snetchild				int cmd;
676158766Snetchild				int arg;
677158766Snetchild				print_number(ip,narg,c);
678158766Snetchild				cmd = *ip;
679158766Snetchild				arg = *++ip;
680158766Snetchild				(void)putchar(',');
681158766Snetchild				fcntlcmdname(cmd, arg, decimal);
682158766Snetchild				ip++;
683158766Snetchild				narg-=2;
684158766Snetchild			} else if (ktr->ktr_code == SYS_socket) {
685165758Srodrigc				int sockdomain;
686158766Snetchild				(void)putchar('(');
687165758Srodrigc				sockdomain=(int)*ip;
688165758Srodrigc				sockdomainname(sockdomain);
689158766Snetchild				ip++;
690158766Snetchild				narg--;
691158766Snetchild				(void)putchar(',');
692158766Snetchild				socktypename((int)*ip);
693158766Snetchild				ip++;
694158766Snetchild				narg--;
695165758Srodrigc				if (sockdomain == PF_INET ||
696165758Srodrigc				    sockdomain == PF_INET6) {
697165758Srodrigc					(void)putchar(',');
698165758Srodrigc					sockipprotoname((int)*ip);
699165758Srodrigc					ip++;
700165758Srodrigc					narg--;
701165758Srodrigc				}
702158766Snetchild				c = ',';
703158766Snetchild			} else if (ktr->ktr_code == SYS_setsockopt ||
704158766Snetchild				   ktr->ktr_code == SYS_getsockopt) {
705158766Snetchild				print_number(ip,narg,c);
706158766Snetchild				(void)putchar(',');
707158766Snetchild				sockoptlevelname((int)*ip, decimal);
708175138Sjhb				if ((int)*ip == SOL_SOCKET) {
709175138Sjhb					ip++;
710175138Sjhb					narg--;
711175138Sjhb					(void)putchar(',');
712175138Sjhb					sockoptname((int)*ip);
713175138Sjhb				}
714158766Snetchild				ip++;
715158766Snetchild				narg--;
716171221Speter#ifdef SYS_freebsd6_lseek
717171221Speter			} else if (ktr->ktr_code == SYS_freebsd6_lseek) {
718158766Snetchild				print_number(ip,narg,c);
719158766Snetchild				/* Hidden 'pad' argument, not in lseek(2) */
720158766Snetchild				print_number(ip,narg,c);
721158766Snetchild				print_number(ip,narg,c);
722158766Snetchild				(void)putchar(',');
723158766Snetchild				whencename ((int)*ip);
724158766Snetchild				ip++;
725158766Snetchild				narg--;
726171221Speter#endif
727171221Speter			} else if (ktr->ktr_code == SYS_lseek) {
728171221Speter				print_number(ip,narg,c);
729171221Speter				/* Hidden 'pad' argument, not in lseek(2) */
730171221Speter				print_number(ip,narg,c);
731171221Speter				(void)putchar(',');
732171221Speter				whencename ((int)*ip);
733171221Speter				ip++;
734171221Speter				narg--;
735171221Speter
736158766Snetchild			} else if (ktr->ktr_code == SYS_flock) {
737158766Snetchild				print_number(ip,narg,c);
738158766Snetchild				(void)putchar(',');
739158766Snetchild				flockname((int)*ip);
740158766Snetchild				ip++;
741158766Snetchild				narg--;
742158766Snetchild			} else if (ktr->ktr_code == SYS_mkfifo ||
743158766Snetchild				   ktr->ktr_code == SYS_mkdir) {
744158766Snetchild				print_number(ip,narg,c);
745158766Snetchild				(void)putchar(',');
746158766Snetchild				modename((int)*ip);
747158766Snetchild				ip++;
748158766Snetchild				narg--;
749158766Snetchild			} else if (ktr->ktr_code == SYS_shutdown) {
750158766Snetchild				print_number(ip,narg,c);
751158766Snetchild				(void)putchar(',');
752158766Snetchild				shutdownhowname((int)*ip);
753158766Snetchild				ip++;
754158766Snetchild				narg--;
755158766Snetchild			} else if (ktr->ktr_code == SYS_socketpair) {
756158766Snetchild				(void)putchar('(');
757158766Snetchild				sockdomainname((int)*ip);
758158766Snetchild				ip++;
759158766Snetchild				narg--;
760158766Snetchild				(void)putchar(',');
761158766Snetchild				socktypename((int)*ip);
762158766Snetchild				ip++;
763158766Snetchild				narg--;
764158766Snetchild				c = ',';
765158766Snetchild			} else if (ktr->ktr_code == SYS_getrlimit ||
766158766Snetchild				   ktr->ktr_code == SYS_setrlimit) {
767158766Snetchild				(void)putchar('(');
768158766Snetchild				rlimitname((int)*ip);
769158766Snetchild				ip++;
770158766Snetchild				narg--;
771158766Snetchild				c = ',';
772158766Snetchild			} else if (ktr->ktr_code == SYS_quotactl) {
773158766Snetchild				print_number(ip,narg,c);
774174346Sjhb				(void)putchar(',');
775158766Snetchild				quotactlname((int)*ip);
776158766Snetchild				ip++;
777158766Snetchild				narg--;
778158766Snetchild				c = ',';
779158766Snetchild			} else if (ktr->ktr_code == SYS_nfssvc) {
780158766Snetchild				(void)putchar('(');
781158766Snetchild				nfssvcname((int)*ip);
782158766Snetchild				ip++;
783158766Snetchild				narg--;
784158766Snetchild				c = ',';
785158766Snetchild			} else if (ktr->ktr_code == SYS_rtprio) {
786158766Snetchild				(void)putchar('(');
787158766Snetchild				rtprioname((int)*ip);
788158766Snetchild				ip++;
789158766Snetchild				narg--;
790158766Snetchild				c = ',';
791158766Snetchild			} else if (ktr->ktr_code == SYS___semctl) {
792158766Snetchild				print_number(ip,narg,c);
793158766Snetchild				print_number(ip,narg,c);
794174346Sjhb				(void)putchar(',');
795158766Snetchild				semctlname((int)*ip);
796158766Snetchild				ip++;
797158766Snetchild				narg--;
798158766Snetchild			} else if (ktr->ktr_code == SYS_semget) {
799158766Snetchild				print_number(ip,narg,c);
800158766Snetchild				print_number(ip,narg,c);
801174346Sjhb				(void)putchar(',');
802158766Snetchild				semgetname((int)*ip);
803158766Snetchild				ip++;
804158766Snetchild				narg--;
805158766Snetchild			} else if (ktr->ktr_code == SYS_msgctl) {
806158766Snetchild				print_number(ip,narg,c);
807174346Sjhb				(void)putchar(',');
808158766Snetchild				shmctlname((int)*ip);
809158766Snetchild				ip++;
810158766Snetchild				narg--;
811158766Snetchild			} else if (ktr->ktr_code == SYS_shmat) {
812158766Snetchild				print_number(ip,narg,c);
813158766Snetchild				print_number(ip,narg,c);
814174346Sjhb				(void)putchar(',');
815158766Snetchild				shmatname((int)*ip);
816158766Snetchild				ip++;
817158766Snetchild				narg--;
818158766Snetchild			} else if (ktr->ktr_code == SYS_shmctl) {
819158766Snetchild				print_number(ip,narg,c);
820174346Sjhb				(void)putchar(',');
821158766Snetchild				shmctlname((int)*ip);
822158766Snetchild				ip++;
823158766Snetchild				narg--;
824158766Snetchild			} else if (ktr->ktr_code == SYS_minherit) {
825158766Snetchild				print_number(ip,narg,c);
826158766Snetchild				print_number(ip,narg,c);
827174346Sjhb				(void)putchar(',');
828158766Snetchild				minheritname((int)*ip);
829158766Snetchild				ip++;
830158766Snetchild				narg--;
831158766Snetchild			} else if (ktr->ktr_code == SYS_rfork) {
832158766Snetchild				(void)putchar('(');
833158766Snetchild				rforkname((int)*ip);
834158766Snetchild				ip++;
835158766Snetchild				narg--;
836158766Snetchild				c = ',';
837158766Snetchild			} else if (ktr->ktr_code == SYS_lio_listio) {
838158766Snetchild				(void)putchar('(');
839158766Snetchild				lio_listioname((int)*ip);
840158766Snetchild				ip++;
841158766Snetchild				narg--;
842158766Snetchild				c = ',';
843158766Snetchild			} else if (ktr->ktr_code == SYS_mlockall) {
844158766Snetchild				(void)putchar('(');
845158766Snetchild				mlockallname((int)*ip);
846158766Snetchild				ip++;
847158766Snetchild				narg--;
848158766Snetchild			} else if (ktr->ktr_code == SYS_sched_setscheduler) {
849158766Snetchild				print_number(ip,narg,c);
850174346Sjhb				(void)putchar(',');
851158766Snetchild				schedpolicyname((int)*ip);
852158766Snetchild				ip++;
853158766Snetchild				narg--;
854158766Snetchild			} else if (ktr->ktr_code == SYS_sched_get_priority_max ||
855158766Snetchild				   ktr->ktr_code == SYS_sched_get_priority_min) {
856158766Snetchild				(void)putchar('(');
857158766Snetchild				schedpolicyname((int)*ip);
858158766Snetchild				ip++;
859158766Snetchild				narg--;
860158766Snetchild			} else if (ktr->ktr_code == SYS_sendfile) {
861158766Snetchild				print_number(ip,narg,c);
862158766Snetchild				print_number(ip,narg,c);
863158766Snetchild				print_number(ip,narg,c);
864158766Snetchild				print_number(ip,narg,c);
865158766Snetchild				print_number(ip,narg,c);
866158766Snetchild				print_number(ip,narg,c);
867174346Sjhb				(void)putchar(',');
868158766Snetchild				sendfileflagsname((int)*ip);
869158766Snetchild				ip++;
870158766Snetchild				narg--;
871158766Snetchild			} else if (ktr->ktr_code == SYS_kldsym) {
872158766Snetchild				print_number(ip,narg,c);
873174346Sjhb				(void)putchar(',');
874158766Snetchild				kldsymcmdname((int)*ip);
875158766Snetchild				ip++;
876158766Snetchild				narg--;
877158766Snetchild			} else if (ktr->ktr_code == SYS_sigprocmask) {
878158766Snetchild				(void)putchar('(');
879158766Snetchild				sigprocmaskhowname((int)*ip);
880158766Snetchild				ip++;
881158766Snetchild				narg--;
882158766Snetchild				c = ',';
883158766Snetchild			} else if (ktr->ktr_code == SYS___acl_get_file ||
884158766Snetchild				   ktr->ktr_code == SYS___acl_set_file ||
885158766Snetchild				   ktr->ktr_code == SYS___acl_get_fd ||
886158766Snetchild				   ktr->ktr_code == SYS___acl_set_fd ||
887158766Snetchild				   ktr->ktr_code == SYS___acl_delete_file ||
888158766Snetchild				   ktr->ktr_code == SYS___acl_delete_fd ||
889158766Snetchild				   ktr->ktr_code == SYS___acl_aclcheck_file ||
890158766Snetchild				   ktr->ktr_code == SYS___acl_aclcheck_fd ||
891158766Snetchild				   ktr->ktr_code == SYS___acl_get_link ||
892158766Snetchild				   ktr->ktr_code == SYS___acl_set_link ||
893158766Snetchild				   ktr->ktr_code == SYS___acl_delete_link ||
894158766Snetchild				   ktr->ktr_code == SYS___acl_aclcheck_link) {
895158766Snetchild				print_number(ip,narg,c);
896174346Sjhb				(void)putchar(',');
897158766Snetchild				acltypename((int)*ip);
898158766Snetchild				ip++;
899158766Snetchild				narg--;
900158766Snetchild			} else if (ktr->ktr_code == SYS_sigaction) {
901158766Snetchild				(void)putchar('(');
902158766Snetchild				signame((int)*ip);
903158766Snetchild				ip++;
904158766Snetchild				narg--;
905158766Snetchild				c = ',';
906158766Snetchild			} else if (ktr->ktr_code == SYS_extattrctl) {
907158766Snetchild				print_number(ip,narg,c);
908174346Sjhb				(void)putchar(',');
909158766Snetchild				extattrctlname((int)*ip);
910158766Snetchild				ip++;
911158766Snetchild				narg--;
912158766Snetchild			} else if (ktr->ktr_code == SYS_nmount) {
913158766Snetchild				print_number(ip,narg,c);
914158766Snetchild				print_number(ip,narg,c);
915158766Snetchild				(void)putchar(',');
916158766Snetchild				mountflagsname ((int)*ip);
917158766Snetchild				ip++;
918158766Snetchild				narg--;
919158766Snetchild			} else if (ktr->ktr_code == SYS_thr_create) {
920158766Snetchild				print_number(ip,narg,c);
921158766Snetchild				print_number(ip,narg,c);
922158766Snetchild				(void)putchar(',');
923158766Snetchild				thrcreateflagsname ((int)*ip);
924158766Snetchild				ip++;
925158766Snetchild				narg--;
926158766Snetchild			} else if (ktr->ktr_code == SYS_thr_kill) {
927158766Snetchild				print_number(ip,narg,c);
928158766Snetchild				(void)putchar(',');
929158766Snetchild				signame ((int)*ip);
930158766Snetchild				ip++;
931158766Snetchild				narg--;
932158766Snetchild			} else if (ktr->ktr_code == SYS_kldunloadf) {
933158766Snetchild				print_number(ip,narg,c);
934158766Snetchild				(void)putchar(',');
935158766Snetchild				kldunloadfflagsname ((int)*ip);
936158766Snetchild				ip++;
937158766Snetchild				narg--;
9381590Srgrimes			}
9391590Srgrimes		}
940199024Sattilio		while (narg > 0) {
941158766Snetchild			print_number(ip,narg,c);
9421590Srgrimes		}
9431590Srgrimes		(void)putchar(')');
9441590Srgrimes	}
9451590Srgrimes	(void)putchar('\n');
9461590Srgrimes}
9471590Srgrimes
948100824Sdwmalonevoid
949219043Sdchaginktrsysret(struct ktr_sysret *ktr, u_int flags)
9501590Srgrimes{
951100824Sdwmalone	register_t ret = ktr->ktr_retval;
952100824Sdwmalone	int error = ktr->ktr_error;
953100824Sdwmalone	int code = ktr->ktr_code;
9541590Srgrimes
955219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
956219043Sdchagin	    (code >= nsyscalls || code < 0))
9571590Srgrimes		(void)printf("[%d] ", code);
9581590Srgrimes	else
9591590Srgrimes		(void)printf("%s ", syscallnames[code]);
9601590Srgrimes
9611590Srgrimes	if (error == 0) {
9621590Srgrimes		if (fancy) {
963203551Sjh			(void)printf("%ld", (long)ret);
9641590Srgrimes			if (ret < 0 || ret > 9)
96547957Sdt				(void)printf("/%#lx", (long)ret);
9661590Srgrimes		} else {
9671590Srgrimes			if (decimal)
96847957Sdt				(void)printf("%ld", (long)ret);
9691590Srgrimes			else
97047957Sdt				(void)printf("%#lx", (long)ret);
9711590Srgrimes		}
9721590Srgrimes	} else if (error == ERESTART)
9731590Srgrimes		(void)printf("RESTART");
9741590Srgrimes	else if (error == EJUSTRETURN)
9751590Srgrimes		(void)printf("JUSTRETURN");
9761590Srgrimes	else {
9771590Srgrimes		(void)printf("-1 errno %d", ktr->ktr_error);
9781590Srgrimes		if (fancy)
9791590Srgrimes			(void)printf(" %s", strerror(ktr->ktr_error));
9801590Srgrimes	}
9811590Srgrimes	(void)putchar('\n');
9821590Srgrimes}
9831590Srgrimes
984100824Sdwmalonevoid
985100824Sdwmalonektrnamei(char *cp, int len)
9861590Srgrimes{
9871590Srgrimes	(void)printf("\"%.*s\"\n", len, cp);
9881590Srgrimes}
9891590Srgrimes
990100824Sdwmalonevoid
991115759Speterhexdump(char *p, int len, int screenwidth)
9921590Srgrimes{
993115759Speter	int n, i;
994115759Speter	int width;
995115759Speter
996115759Speter	width = 0;
997115759Speter	do {
998115759Speter		width += 2;
999115759Speter		i = 13;			/* base offset */
1000115759Speter		i += (width / 2) + 1;	/* spaces every second byte */
1001115759Speter		i += (width * 2);	/* width of bytes */
1002115759Speter		i += 3;			/* "  |" */
1003115759Speter		i += width;		/* each byte */
1004115759Speter		i += 1;			/* "|" */
1005115759Speter	} while (i < screenwidth);
1006115759Speter	width -= 2;
1007115759Speter
1008115759Speter	for (n = 0; n < len; n += width) {
1009115759Speter		for (i = n; i < n + width; i++) {
1010115759Speter			if ((i % width) == 0) {	/* beginning of line */
1011115759Speter				printf("       0x%04x", i);
1012115759Speter			}
1013115759Speter			if ((i % 2) == 0) {
1014115759Speter				printf(" ");
1015115759Speter			}
1016115759Speter			if (i < len)
1017115759Speter				printf("%02x", p[i] & 0xff);
1018115759Speter			else
1019115759Speter				printf("  ");
1020115759Speter		}
1021115759Speter		printf("  |");
1022115759Speter		for (i = n; i < n + width; i++) {
1023115759Speter			if (i >= len)
1024115759Speter				break;
1025115759Speter			if (p[i] >= ' ' && p[i] <= '~')
1026115759Speter				printf("%c", p[i]);
1027115759Speter			else
1028115759Speter				printf(".");
1029115759Speter		}
1030115759Speter		printf("|\n");
1031115759Speter	}
1032115759Speter	if ((i % width) != 0)
1033115759Speter		printf("\n");
1034115759Speter}
1035115759Speter
1036115759Spetervoid
1037115759Spetervisdump(char *dp, int datalen, int screenwidth)
1038115759Speter{
1039115759Speter	int col = 0;
1040100824Sdwmalone	char *cp;
1041100824Sdwmalone	int width;
10421590Srgrimes	char visbuf[5];
10431590Srgrimes
10441590Srgrimes	(void)printf("       \"");
10451590Srgrimes	col = 8;
10461590Srgrimes	for (;datalen > 0; datalen--, dp++) {
10471590Srgrimes		(void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
10481590Srgrimes		cp = visbuf;
10491590Srgrimes		/*
10501590Srgrimes		 * Keep track of printables and
10511590Srgrimes		 * space chars (like fold(1)).
10521590Srgrimes		 */
10531590Srgrimes		if (col == 0) {
10541590Srgrimes			(void)putchar('\t');
10551590Srgrimes			col = 8;
10561590Srgrimes		}
10571590Srgrimes		switch(*cp) {
10581590Srgrimes		case '\n':
10591590Srgrimes			col = 0;
10601590Srgrimes			(void)putchar('\n');
10611590Srgrimes			continue;
10621590Srgrimes		case '\t':
10631590Srgrimes			width = 8 - (col&07);
10641590Srgrimes			break;
10651590Srgrimes		default:
10661590Srgrimes			width = strlen(cp);
10671590Srgrimes		}
10681590Srgrimes		if (col + width > (screenwidth-2)) {
10691590Srgrimes			(void)printf("\\\n\t");
10701590Srgrimes			col = 8;
10711590Srgrimes		}
10721590Srgrimes		col += width;
10731590Srgrimes		do {
10741590Srgrimes			(void)putchar(*cp++);
10751590Srgrimes		} while (*cp);
10761590Srgrimes	}
10771590Srgrimes	if (col == 0)
10781590Srgrimes		(void)printf("       ");
10791590Srgrimes	(void)printf("\"\n");
10801590Srgrimes}
10811590Srgrimes
1082115759Spetervoid
1083115759Speterktrgenio(struct ktr_genio *ktr, int len)
1084115759Speter{
1085115759Speter	int datalen = len - sizeof (struct ktr_genio);
1086115759Speter	char *dp = (char *)ktr + sizeof (struct ktr_genio);
1087115759Speter	static int screenwidth = 0;
1088115759Speter	int i, binary;
1089115759Speter
1090115759Speter	if (screenwidth == 0) {
1091115759Speter		struct winsize ws;
1092115759Speter
1093115759Speter		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1094115759Speter		    ws.ws_col > 8)
1095115759Speter			screenwidth = ws.ws_col;
1096115759Speter		else
1097115759Speter			screenwidth = 80;
1098115759Speter	}
1099115759Speter	printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1100115759Speter		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1101115759Speter		datalen == 1 ? "" : "s");
1102152331Srwatson	if (suppressdata)
1103152331Srwatson		return;
1104115759Speter	if (maxdata && datalen > maxdata)
1105115759Speter		datalen = maxdata;
1106115759Speter
1107115759Speter	for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1108115759Speter		if (dp[i] >= 32 && dp[i] < 127)
1109115759Speter			continue;
1110115759Speter		if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1111115759Speter			continue;
1112115759Speter		binary = 1;
1113115759Speter	}
1114115759Speter	if (binary)
1115115759Speter		hexdump(dp, datalen, screenwidth);
1116115759Speter	else
1117115759Speter		visdump(dp, datalen, screenwidth);
1118115759Speter}
1119115759Speter
1120100824Sdwmaloneconst char *signames[] = {
11211590Srgrimes	"NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",	/*  1 - 6  */
11221590Srgrimes	"EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",		/*  7 - 12 */
11231590Srgrimes	"PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",		/* 13 - 18 */
11241590Srgrimes	"CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",		/* 19 - 24 */
11251590Srgrimes	"XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",	/* 25 - 30 */
11261590Srgrimes	"USR2", NULL,						/* 31 - 32 */
11271590Srgrimes};
11281590Srgrimes
1129100824Sdwmalonevoid
1130219138Sdchaginktrpsig(struct ktr_psig *psig)
11311590Srgrimes{
1132219138Sdchagin	if (psig->signo > 0 && psig->signo < NSIG)
1133160296Smaxim		(void)printf("SIG%s ", signames[psig->signo]);
1134160294Skib	else
1135160296Smaxim		(void)printf("SIG %d ", psig->signo);
11361590Srgrimes	if (psig->action == SIG_DFL)
11371590Srgrimes		(void)printf("SIG_DFL\n");
1138100824Sdwmalone	else {
113947957Sdt		(void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n",
1140100824Sdwmalone		    (u_long)psig->action, psig->mask.__bits[0], psig->code);
1141100824Sdwmalone	}
11421590Srgrimes}
11431590Srgrimes
1144100824Sdwmalonevoid
1145100824Sdwmalonektrcsw(struct ktr_csw *cs)
11461590Srgrimes{
11471590Srgrimes	(void)printf("%s %s\n", cs->out ? "stop" : "resume",
11481590Srgrimes		cs->user ? "user" : "kernel");
11491590Srgrimes}
11501590Srgrimes
1151165916Sjhb#define	UTRACE_DLOPEN_START		1
1152165916Sjhb#define	UTRACE_DLOPEN_STOP		2
1153165916Sjhb#define	UTRACE_DLCLOSE_START		3
1154165916Sjhb#define	UTRACE_DLCLOSE_STOP		4
1155165916Sjhb#define	UTRACE_LOAD_OBJECT		5
1156165916Sjhb#define	UTRACE_UNLOAD_OBJECT		6
1157165916Sjhb#define	UTRACE_ADD_RUNDEP		7
1158165916Sjhb#define	UTRACE_PRELOAD_FINISHED		8
1159165916Sjhb#define	UTRACE_INIT_CALL		9
1160165916Sjhb#define	UTRACE_FINI_CALL		10
1161165916Sjhb
1162165916Sjhbstruct utrace_rtld {
1163165916Sjhb	char sig[4];				/* 'RTLD' */
1164165916Sjhb	int event;
1165165916Sjhb	void *handle;
1166165916Sjhb	void *mapbase;
1167165916Sjhb	size_t mapsize;
1168165916Sjhb	int refcnt;
1169165916Sjhb	char name[MAXPATHLEN];
1170165916Sjhb};
1171165916Sjhb
1172165916Sjhbvoid
1173165916Sjhbktruser_rtld(int len, unsigned char *p)
1174165916Sjhb{
1175165916Sjhb	struct utrace_rtld *ut = (struct utrace_rtld *)p;
1176165916Sjhb	void *parent;
1177165916Sjhb	int mode;
1178165916Sjhb
1179165916Sjhb	switch (ut->event) {
1180165916Sjhb	case UTRACE_DLOPEN_START:
1181165916Sjhb		mode = ut->refcnt;
1182165916Sjhb		printf("dlopen(%s, ", ut->name);
1183165916Sjhb		switch (mode & RTLD_MODEMASK) {
1184165916Sjhb		case RTLD_NOW:
1185165916Sjhb			printf("RTLD_NOW");
1186165916Sjhb			break;
1187165916Sjhb		case RTLD_LAZY:
1188165916Sjhb			printf("RTLD_LAZY");
1189165916Sjhb			break;
1190165916Sjhb		default:
1191165916Sjhb			printf("%#x", mode & RTLD_MODEMASK);
1192165916Sjhb		}
1193165916Sjhb		if (mode & RTLD_GLOBAL)
1194165916Sjhb			printf(" | RTLD_GLOBAL");
1195165916Sjhb		if (mode & RTLD_TRACE)
1196165916Sjhb			printf(" | RTLD_TRACE");
1197165916Sjhb		if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
1198165916Sjhb			printf(" | %#x", mode &
1199165916Sjhb			    ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
1200165916Sjhb		printf(")\n");
1201165916Sjhb		break;
1202165916Sjhb	case UTRACE_DLOPEN_STOP:
1203165916Sjhb		printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
1204165916Sjhb		    ut->refcnt);
1205165916Sjhb		break;
1206165916Sjhb	case UTRACE_DLCLOSE_START:
1207165916Sjhb		printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
1208165916Sjhb		    ut->refcnt);
1209165916Sjhb		break;
1210165916Sjhb	case UTRACE_DLCLOSE_STOP:
1211165916Sjhb		printf("dlclose(%p) finished\n", ut->handle);
1212165916Sjhb		break;
1213165916Sjhb	case UTRACE_LOAD_OBJECT:
1214165916Sjhb		printf("RTLD: loaded   %p @ %p - %p (%s)\n", ut->handle,
1215165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1216165916Sjhb		    ut->name);
1217165916Sjhb		break;
1218165916Sjhb	case UTRACE_UNLOAD_OBJECT:
1219165916Sjhb		printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
1220165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1221165916Sjhb		    ut->name);
1222165916Sjhb		break;
1223165916Sjhb	case UTRACE_ADD_RUNDEP:
1224165916Sjhb		parent = ut->mapbase;
1225165916Sjhb		printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
1226165916Sjhb		    ut->handle, ut->name, ut->refcnt);
1227165916Sjhb		break;
1228165916Sjhb	case UTRACE_PRELOAD_FINISHED:
1229165916Sjhb		printf("RTLD: LD_PRELOAD finished\n");
1230165916Sjhb		break;
1231165916Sjhb	case UTRACE_INIT_CALL:
1232165916Sjhb		printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1233165916Sjhb		    ut->name);
1234165916Sjhb		break;
1235165916Sjhb	case UTRACE_FINI_CALL:
1236165916Sjhb		printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1237165916Sjhb		    ut->name);
1238165916Sjhb		break;
1239165916Sjhb	default:
1240165916Sjhb		p += 4;
1241165916Sjhb		len -= 4;
1242165916Sjhb		printf("RTLD: %d ", len);
1243165916Sjhb		while (len--)
1244165916Sjhb			if (decimal)
1245165916Sjhb				printf(" %d", *p++);
1246165916Sjhb			else
1247165916Sjhb				printf(" %02x", *p++);
1248165916Sjhb		printf("\n");
1249165916Sjhb	}
1250165916Sjhb}
1251165916Sjhb
1252165812Sjhbstruct utrace_malloc {
1253165812Sjhb	void *p;
1254165812Sjhb	size_t s;
1255165812Sjhb	void *r;
1256165812Sjhb};
1257165812Sjhb
1258100824Sdwmalonevoid
1259165812Sjhbktruser_malloc(int len, unsigned char *p)
1260165812Sjhb{
1261165812Sjhb	struct utrace_malloc *ut = (struct utrace_malloc *)p;
1262165812Sjhb
1263199265Scperciva	if (ut->p == (void *)(intptr_t)(-1))
1264199265Scperciva		printf("malloc_init()\n");
1265199265Scperciva	else if (ut->s == 0)
1266199265Scperciva		printf("free(%p)\n", ut->p);
1267199265Scperciva	else if (ut->p == NULL)
1268199265Scperciva		printf("%p = malloc(%zu)\n", ut->r, ut->s);
1269199265Scperciva	else
1270199265Scperciva		printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1271165812Sjhb}
1272165812Sjhb
1273165812Sjhbvoid
1274100824Sdwmalonektruser(int len, unsigned char *p)
127518400Sphk{
1276165812Sjhb
1277165916Sjhb	if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1278165916Sjhb		ktruser_rtld(len, p);
1279165916Sjhb		return;
1280165916Sjhb	}
1281165916Sjhb
1282165812Sjhb	if (len == sizeof(struct utrace_malloc)) {
1283165812Sjhb		ktruser_malloc(len, p);
1284165812Sjhb		return;
1285165812Sjhb	}
1286165812Sjhb
128718470Sphk	(void)printf("%d ", len);
128818470Sphk	while (len--)
1289127402Sphk		if (decimal)
1290127402Sphk			(void)printf(" %d", *p++);
1291127402Sphk		else
1292127402Sphk			(void)printf(" %02x", *p++);
129318400Sphk	(void)printf("\n");
129418400Sphk}
129518400Sphk
1296100824Sdwmalonevoid
1297176471Sdesktrsockaddr(struct sockaddr *sa)
1298176471Sdes{
1299176471Sdes/*
1300176471Sdes TODO: Support additional address families
1301176471Sdes	#include <netnatm/natm.h>
1302176471Sdes	struct sockaddr_natm	*natm;
1303176471Sdes	#include <netsmb/netbios.h>
1304176471Sdes	struct sockaddr_nb	*nb;
1305176471Sdes*/
1306176471Sdes	char addr[64];
1307176471Sdes
1308176471Sdes	/*
1309176471Sdes	 * note: ktrstruct() has already verified that sa points to a
1310176471Sdes	 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1311176471Sdes	 * sa->sa_len bytes long.
1312176471Sdes	 */
1313176471Sdes	printf("struct sockaddr { ");
1314176471Sdes	sockfamilyname(sa->sa_family);
1315176471Sdes	printf(", ");
1316176471Sdes
1317176471Sdes#define check_sockaddr_len(n)					\
1318176471Sdes	if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) {	\
1319176471Sdes		printf("invalid");				\
1320176471Sdes		break;						\
1321176471Sdes	}
1322176471Sdes
1323176471Sdes	switch(sa->sa_family) {
1324176471Sdes	case AF_INET: {
1325176471Sdes		struct sockaddr_in	*sa_in;
1326176471Sdes
1327176471Sdes		sa_in = (struct sockaddr_in *)sa;
1328176471Sdes		check_sockaddr_len(in);
1329176471Sdes		inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr);
1330176471Sdes		printf("%s:%u", addr, ntohs(sa_in->sin_port));
1331176471Sdes		break;
1332176471Sdes	}
1333176471Sdes#ifdef NETATALK
1334176471Sdes	case AF_APPLETALK: {
1335176471Sdes		struct sockaddr_at	*sa_at;
1336176471Sdes		struct netrange		*nr;
1337176471Sdes
1338176471Sdes		sa_at = (struct sockaddr_at *)sa;
1339176471Sdes		check_sockaddr_len(at);
1340176471Sdes		nr = &sa_at->sat_range.r_netrange;
1341176471Sdes		printf("%d.%d, %d-%d, %d", ntohs(sa_at->sat_addr.s_net),
1342176471Sdes			sa_at->sat_addr.s_node, ntohs(nr->nr_firstnet),
1343176471Sdes			ntohs(nr->nr_lastnet), nr->nr_phase);
1344176471Sdes		break;
1345176471Sdes	}
1346176471Sdes#endif
1347176471Sdes	case AF_INET6: {
1348176471Sdes		struct sockaddr_in6	*sa_in6;
1349176471Sdes
1350176471Sdes		sa_in6 = (struct sockaddr_in6 *)sa;
1351176471Sdes		check_sockaddr_len(in6);
1352176471Sdes		inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr);
1353176471Sdes		printf("[%s]:%u", addr, htons(sa_in6->sin6_port));
1354176471Sdes		break;
1355176471Sdes	}
1356176471Sdes#ifdef IPX
1357176471Sdes	case AF_IPX: {
1358176471Sdes		struct sockaddr_ipx	*sa_ipx;
1359176471Sdes
1360176471Sdes		sa_ipx = (struct sockaddr_ipx *)sa;
1361176471Sdes		check_sockaddr_len(ipx);
1362176471Sdes		/* XXX wish we had ipx_ntop */
1363176471Sdes		printf("%s", ipx_ntoa(sa_ipx->sipx_addr));
1364176471Sdes		break;
1365176471Sdes	}
1366176471Sdes#endif
1367176471Sdes	case AF_UNIX: {
1368176471Sdes		struct sockaddr_un *sa_un;
1369176471Sdes
1370176471Sdes		sa_un = (struct sockaddr_un *)sa;
1371176471Sdes		check_sockaddr_len(un);
1372176471Sdes		printf("%.*s", (int)sizeof(sa_un->sun_path), sa_un->sun_path);
1373176471Sdes		break;
1374176471Sdes	}
1375176471Sdes	default:
1376176471Sdes		printf("unknown address family");
1377176471Sdes	}
1378176471Sdes	printf(" }\n");
1379176471Sdes}
1380176471Sdes
1381176471Sdesvoid
1382176471Sdesktrstat(struct stat *statp)
1383176471Sdes{
1384176471Sdes	char mode[12], timestr[PATH_MAX + 4];
1385176471Sdes	struct passwd *pwd;
1386176471Sdes	struct group  *grp;
1387176471Sdes	struct tm *tm;
1388176471Sdes
1389176471Sdes	/*
1390176471Sdes	 * note: ktrstruct() has already verified that statp points to a
1391176471Sdes	 * buffer exactly sizeof(struct stat) bytes long.
1392176471Sdes	 */
1393176471Sdes	printf("struct stat {");
1394176471Sdes	strmode(statp->st_mode, mode);
1395176471Sdes	printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ",
1396176471Sdes		(uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode,
1397176471Sdes		(uintmax_t)statp->st_nlink);
1398176471Sdes	if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1399176471Sdes		printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1400176471Sdes	else
1401176471Sdes		printf("uid=\"%s\", ", pwd->pw_name);
1402176471Sdes	if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1403176471Sdes		printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1404176471Sdes	else
1405176471Sdes		printf("gid=\"%s\", ", grp->gr_name);
1406176471Sdes	printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1407176471Sdes	printf("atime=");
1408176471Sdes	if (resolv == 0)
1409205793Sed		printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1410176471Sdes	else {
1411205793Sed		tm = localtime(&statp->st_atim.tv_sec);
1412176471Sdes		(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1413176471Sdes		printf("\"%s\"", timestr);
1414176471Sdes	}
1415205793Sed	if (statp->st_atim.tv_nsec != 0)
1416205793Sed		printf(".%09ld, ", statp->st_atim.tv_nsec);
1417176471Sdes	else
1418176471Sdes		printf(", ");
1419176471Sdes	printf("stime=");
1420176471Sdes	if (resolv == 0)
1421205793Sed		printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1422176471Sdes	else {
1423205793Sed		tm = localtime(&statp->st_mtim.tv_sec);
1424176471Sdes		(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1425176471Sdes		printf("\"%s\"", timestr);
1426176471Sdes	}
1427205793Sed	if (statp->st_mtim.tv_nsec != 0)
1428205793Sed		printf(".%09ld, ", statp->st_mtim.tv_nsec);
1429176471Sdes	else
1430176471Sdes		printf(", ");
1431176471Sdes	printf("ctime=");
1432176471Sdes	if (resolv == 0)
1433205793Sed		printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1434176471Sdes	else {
1435205793Sed		tm = localtime(&statp->st_ctim.tv_sec);
1436176471Sdes		(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1437176471Sdes		printf("\"%s\"", timestr);
1438176471Sdes	}
1439205793Sed	if (statp->st_ctim.tv_nsec != 0)
1440205793Sed		printf(".%09ld, ", statp->st_ctim.tv_nsec);
1441176471Sdes	else
1442176471Sdes		printf(", ");
1443176471Sdes	printf("birthtime=");
1444176471Sdes	if (resolv == 0)
1445205793Sed		printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
1446176471Sdes	else {
1447205793Sed		tm = localtime(&statp->st_birthtim.tv_sec);
1448176471Sdes		(void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1449176471Sdes		printf("\"%s\"", timestr);
1450176471Sdes	}
1451205793Sed	if (statp->st_birthtim.tv_nsec != 0)
1452205793Sed		printf(".%09ld, ", statp->st_birthtim.tv_nsec);
1453176471Sdes	else
1454176471Sdes		printf(", ");
1455176471Sdes	printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1456176471Sdes		(uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
1457176471Sdes		(intmax_t)statp->st_blocks, statp->st_flags);
1458176471Sdes	printf(" }\n");
1459176471Sdes}
1460176471Sdes
1461176471Sdesvoid
1462176471Sdesktrstruct(char *buf, size_t buflen)
1463176471Sdes{
1464176471Sdes	char *name, *data;
1465176471Sdes	size_t namelen, datalen;
1466176471Sdes	int i;
1467204045Simp	struct stat sb;
1468204045Simp	struct sockaddr_storage ss;
1469176471Sdes
1470176471Sdes	for (name = buf, namelen = 0;
1471176471Sdes	     namelen < buflen && name[namelen] != '\0';
1472176471Sdes	     ++namelen)
1473176471Sdes		/* nothing */;
1474176471Sdes	if (namelen == buflen)
1475176471Sdes		goto invalid;
1476176471Sdes	if (name[namelen] != '\0')
1477176471Sdes		goto invalid;
1478176471Sdes	data = buf + namelen + 1;
1479176471Sdes	datalen = buflen - namelen - 1;
1480176471Sdes	if (datalen == 0)
1481176471Sdes		goto invalid;
1482176471Sdes	/* sanity check */
1483176471Sdes	for (i = 0; i < namelen; ++i)
1484176471Sdes		if (!isalpha((unsigned char)name[i]))
1485176471Sdes			goto invalid;
1486176471Sdes	if (strcmp(name, "stat") == 0) {
1487176471Sdes		if (datalen != sizeof(struct stat))
1488176471Sdes			goto invalid;
1489204045Simp		memcpy(&sb, data, datalen);
1490204045Simp		ktrstat(&sb);
1491176471Sdes	} else if (strcmp(name, "sockaddr") == 0) {
1492204045Simp		if (datalen > sizeof(ss))
1493204045Simp			goto invalid;
1494204045Simp		memcpy(&ss, data, datalen);
1495176471Sdes		if (datalen < sizeof(struct sockaddr) ||
1496204045Simp		    datalen != ss.ss_len)
1497176471Sdes			goto invalid;
1498204045Simp		ktrsockaddr((struct sockaddr *)&ss);
1499176471Sdes	} else {
1500176471Sdes		printf("unknown structure\n");
1501176471Sdes	}
1502176471Sdes	return;
1503176471Sdesinvalid:
1504176471Sdes	printf("invalid record\n");
1505176471Sdes}
1506176471Sdes
1507219138Sdchagin#if defined(__amd64__) || defined(__i386__)
1508176471Sdesvoid
1509219138Sdchaginlinux_ktrsyscall(struct ktr_syscall *ktr)
1510219138Sdchagin{
1511219138Sdchagin	int narg = ktr->ktr_narg;
1512219138Sdchagin	register_t *ip;
1513219138Sdchagin
1514219138Sdchagin	if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
1515219138Sdchagin		printf("[%d]", ktr->ktr_code);
1516219138Sdchagin	else
1517219138Sdchagin		printf("%s", linux_syscallnames[ktr->ktr_code]);
1518219138Sdchagin	ip = &ktr->ktr_args[0];
1519219138Sdchagin	if (narg) {
1520219138Sdchagin		char c = '(';
1521219138Sdchagin		while (narg > 0)
1522219138Sdchagin			print_number(ip, narg, c);
1523219138Sdchagin		putchar(')');
1524219138Sdchagin	}
1525219138Sdchagin	putchar('\n');
1526219138Sdchagin}
1527219138Sdchagin
1528219138Sdchaginvoid
1529219138Sdchaginlinux_ktrsysret(struct ktr_sysret *ktr)
1530219138Sdchagin{
1531219138Sdchagin	register_t ret = ktr->ktr_retval;
1532219138Sdchagin	int error = ktr->ktr_error;
1533219138Sdchagin	int code = ktr->ktr_code;
1534219138Sdchagin
1535219138Sdchagin	if (code >= nlinux_syscalls || code < 0)
1536219138Sdchagin		printf("[%d] ", code);
1537219138Sdchagin	else
1538219138Sdchagin		printf("%s ", linux_syscallnames[code]);
1539219138Sdchagin
1540219138Sdchagin	if (error == 0) {
1541219138Sdchagin		if (fancy) {
1542219138Sdchagin			printf("%ld", (long)ret);
1543219138Sdchagin			if (ret < 0 || ret > 9)
1544219138Sdchagin				printf("/%#lx", (long)ret);
1545219138Sdchagin		} else {
1546219138Sdchagin			if (decimal)
1547219138Sdchagin				printf("%ld", (long)ret);
1548219138Sdchagin			else
1549219138Sdchagin				printf("%#lx", (long)ret);
1550219138Sdchagin		}
1551219138Sdchagin	} else if (error == ERESTART)
1552219138Sdchagin		printf("RESTART");
1553219138Sdchagin	else if (error == EJUSTRETURN)
1554219138Sdchagin		printf("JUSTRETURN");
1555219138Sdchagin	else {
1556219138Sdchagin		if (ktr->ktr_error <= ELAST + 1)
1557219138Sdchagin			error = abs(bsd_to_linux_errno[ktr->ktr_error]);
1558219138Sdchagin		else
1559219138Sdchagin			error = 999;
1560219138Sdchagin		printf("-1 errno %d", error);
1561219138Sdchagin		if (fancy)
1562219138Sdchagin			printf(" %s", strerror(ktr->ktr_error));
1563219138Sdchagin	}
1564219138Sdchagin	putchar('\n');
1565219138Sdchagin}
1566219138Sdchagin#endif
1567219138Sdchagin
1568219138Sdchaginvoid
1569100824Sdwmaloneusage(void)
15701590Srgrimes{
1571219043Sdchagin	fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] "
1572177856Sru	    "[-m maxdata] [-p pid] [-t trstr]\n");
15731590Srgrimes	exit(1);
15741590Srgrimes}
1575