kdump.c revision 240820
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 240820 2012-09-22 12:40:00Z jilles $");
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 *);
98234494Sjhbvoid ktrcsw_old(struct ktr_csw_old *);
99226329Sdesvoid ktruser_malloc(unsigned char *);
100226329Sdesvoid ktruser_rtld(int, unsigned char *);
101100824Sdwmalonevoid ktruser(int, unsigned char *);
102176471Sdesvoid ktrsockaddr(struct sockaddr *);
103176471Sdesvoid ktrstat(struct stat *);
104176471Sdesvoid ktrstruct(char *, size_t);
105226269Sdesvoid ktrcapfail(struct ktr_cap_fail *);
106233925Sjhbvoid ktrfault(struct ktr_fault *);
107233925Sjhbvoid ktrfaultend(struct ktr_faultend *);
108100824Sdwmalonevoid usage(void);
109226157Sdesvoid ioctlname(unsigned long, int);
110100824Sdwmalone
111176471Sdesint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
112219043Sdchagin    resolv = 0, abiflag = 0;
113100824Sdwmaloneconst char *tracefile = DEF_TRACEFILE;
1141590Srgrimesstruct ktr_header ktr_header;
1151590Srgrimes
116176471Sdes#define TIME_FORMAT	"%b %e %T %Y"
1171590Srgrimes#define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
1181590Srgrimes
119226262Sdes#define print_number(i,n,c) do {					\
120226262Sdes	if (decimal)							\
121226262Sdes		printf("%c%jd", c, (intmax_t)*i);			\
122226262Sdes	else								\
123226262Sdes		printf("%c%#jx", c, (uintmax_t)(u_register_t)*i);	\
124226262Sdes	i++;								\
125226262Sdes	n--;								\
126226262Sdes	c = ',';							\
127226164Sdes} while (0)
128219138Sdchagin
129219138Sdchagin#if defined(__amd64__) || defined(__i386__)
130219138Sdchagin
131219138Sdchaginvoid linux_ktrsyscall(struct ktr_syscall *);
132219138Sdchaginvoid linux_ktrsysret(struct ktr_sysret *);
133219138Sdchaginextern char *linux_syscallnames[];
134219138Sdchaginextern int nlinux_syscalls;
135219138Sdchagin
136219138Sdchagin/*
137219138Sdchagin * from linux.h
138219138Sdchagin * Linux syscalls return negative errno's, we do positive and map them
139219138Sdchagin */
140219138Sdchaginstatic int bsd_to_linux_errno[ELAST + 1] = {
141219138Sdchagin	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
142219138Sdchagin	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
143219138Sdchagin	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
144219138Sdchagin	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
145219138Sdchagin	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
146219138Sdchagin	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
147219138Sdchagin	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
148219138Sdchagin	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
149219138Sdchagin	-6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
150219138Sdchagin	-72, -67, -71
151219138Sdchagin};
152219138Sdchagin#endif
153219138Sdchagin
154219043Sdchaginstruct proc_info
155219043Sdchagin{
156219043Sdchagin	TAILQ_ENTRY(proc_info)	info;
157219043Sdchagin	u_int			sv_flags;
158219043Sdchagin	pid_t			pid;
159219043Sdchagin};
160219043Sdchagin
161219043SdchaginTAILQ_HEAD(trace_procs, proc_info) trace_procs;
162219043Sdchagin
163100824Sdwmaloneint
164100824Sdwmalonemain(int argc, char *argv[])
1651590Srgrimes{
1661590Srgrimes	int ch, ktrlen, size;
167100824Sdwmalone	void *m;
1681590Srgrimes	int trpoints = ALL_POINTS;
169112201Sjhb	int drop_logged;
170115759Speter	pid_t pid = 0;
171219043Sdchagin	u_int sv_flags;
1721590Srgrimes
173226153Sdes	setlocale(LC_CTYPE, "");
17411823Sache
175219043Sdchagin	while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1)
176226153Sdes		switch (ch) {
177219043Sdchagin		case 'A':
178219043Sdchagin			abiflag = 1;
179219043Sdchagin			break;
1801590Srgrimes		case 'f':
1811590Srgrimes			tracefile = optarg;
1821590Srgrimes			break;
1831590Srgrimes		case 'd':
1841590Srgrimes			decimal = 1;
1851590Srgrimes			break;
1861590Srgrimes		case 'l':
1871590Srgrimes			tail = 1;
1881590Srgrimes			break;
1891590Srgrimes		case 'm':
1901590Srgrimes			maxdata = atoi(optarg);
1911590Srgrimes			break;
1921590Srgrimes		case 'n':
1931590Srgrimes			fancy = 0;
1941590Srgrimes			break;
195115759Speter		case 'p':
196115759Speter			pid = atoi(optarg);
197115759Speter			break;
198176471Sdes		case 'r':
199176471Sdes			resolv = 1;
200176471Sdes			break;
201152331Srwatson		case 's':
202152331Srwatson			suppressdata = 1;
203152331Srwatson			break;
204123187Speter		case 'E':
205123187Speter			timestamp = 3;	/* elapsed timestamp */
206123187Speter			break;
207151930Srwatson		case 'H':
208151930Srwatson			threads = 1;
209151930Srwatson			break;
2101590Srgrimes		case 'R':
2111590Srgrimes			timestamp = 2;	/* relative timestamp */
2121590Srgrimes			break;
2131590Srgrimes		case 'T':
2141590Srgrimes			timestamp = 1;
2151590Srgrimes			break;
2161590Srgrimes		case 't':
2171590Srgrimes			trpoints = getpoints(optarg);
21827443Scharnier			if (trpoints < 0)
21927443Scharnier				errx(1, "unknown trace point in %s", optarg);
2201590Srgrimes			break;
2211590Srgrimes		default:
2221590Srgrimes			usage();
2231590Srgrimes		}
2241590Srgrimes
22519853Sfenner	if (argc > optind)
2261590Srgrimes		usage();
2271590Srgrimes
228226153Sdes	m = malloc(size = 1025);
22927443Scharnier	if (m == NULL)
23027443Scharnier		errx(1, "%s", strerror(ENOMEM));
23127443Scharnier	if (!freopen(tracefile, "r", stdin))
23227443Scharnier		err(1, "%s", tracefile);
233219043Sdchagin	TAILQ_INIT(&trace_procs);
234112201Sjhb	drop_logged = 0;
2351590Srgrimes	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
236112201Sjhb		if (ktr_header.ktr_type & KTR_DROP) {
237112201Sjhb			ktr_header.ktr_type &= ~KTR_DROP;
238151930Srwatson			if (!drop_logged && threads) {
239226153Sdes				printf(
240203551Sjh				    "%6jd %6jd %-8.*s Events dropped.\n",
241203551Sjh				    (intmax_t)ktr_header.ktr_pid,
242203551Sjh				    ktr_header.ktr_tid > 0 ?
243203551Sjh				    (intmax_t)ktr_header.ktr_tid : 0,
244203551Sjh				    MAXCOMLEN, ktr_header.ktr_comm);
245151930Srwatson				drop_logged = 1;
246151930Srwatson			} else if (!drop_logged) {
247226153Sdes				printf("%6jd %-8.*s Events dropped.\n",
248203551Sjh				    (intmax_t)ktr_header.ktr_pid, MAXCOMLEN,
249112201Sjhb				    ktr_header.ktr_comm);
250112201Sjhb				drop_logged = 1;
251112201Sjhb			}
252112201Sjhb		}
2531590Srgrimes		if (trpoints & (1<<ktr_header.ktr_type))
254236577Sjhb			if (pid == 0 || ktr_header.ktr_pid == pid ||
255236577Sjhb			    ktr_header.ktr_tid == pid)
256115759Speter				dumpheader(&ktr_header);
25727443Scharnier		if ((ktrlen = ktr_header.ktr_len) < 0)
25827443Scharnier			errx(1, "bogus length 0x%x", ktrlen);
2591590Srgrimes		if (ktrlen > size) {
260226153Sdes			m = realloc(m, ktrlen+1);
26127443Scharnier			if (m == NULL)
26227443Scharnier				errx(1, "%s", strerror(ENOMEM));
2631590Srgrimes			size = ktrlen;
2641590Srgrimes		}
26527443Scharnier		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
26627443Scharnier			errx(1, "data too short");
267219043Sdchagin		if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
268219043Sdchagin			continue;
269219043Sdchagin		sv_flags = abidump(&ktr_header);
270236577Sjhb		if (pid && ktr_header.ktr_pid != pid &&
271236577Sjhb		    ktr_header.ktr_tid != pid)
272115759Speter			continue;
2731590Srgrimes		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
2741590Srgrimes			continue;
275112201Sjhb		drop_logged = 0;
2761590Srgrimes		switch (ktr_header.ktr_type) {
2771590Srgrimes		case KTR_SYSCALL:
278219138Sdchagin#if defined(__amd64__) || defined(__i386__)
279219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
280219138Sdchagin				linux_ktrsyscall((struct ktr_syscall *)m);
281219138Sdchagin			else
282219138Sdchagin#endif
283219138Sdchagin				ktrsyscall((struct ktr_syscall *)m, sv_flags);
2841590Srgrimes			break;
2851590Srgrimes		case KTR_SYSRET:
286219138Sdchagin#if defined(__amd64__) || defined(__i386__)
287219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
288219138Sdchagin				linux_ktrsysret((struct ktr_sysret *)m);
289219138Sdchagin			else
290219138Sdchagin#endif
291219138Sdchagin				ktrsysret((struct ktr_sysret *)m, sv_flags);
2921590Srgrimes			break;
2931590Srgrimes		case KTR_NAMEI:
294189707Sjhb		case KTR_SYSCTL:
2951590Srgrimes			ktrnamei(m, ktrlen);
2961590Srgrimes			break;
2971590Srgrimes		case KTR_GENIO:
2981590Srgrimes			ktrgenio((struct ktr_genio *)m, ktrlen);
2991590Srgrimes			break;
3001590Srgrimes		case KTR_PSIG:
301219138Sdchagin			ktrpsig((struct ktr_psig *)m);
3021590Srgrimes			break;
3031590Srgrimes		case KTR_CSW:
304234494Sjhb			if (ktrlen == sizeof(struct ktr_csw_old))
305234494Sjhb				ktrcsw_old((struct ktr_csw_old *)m);
306234494Sjhb			else
307234494Sjhb				ktrcsw((struct ktr_csw *)m);
3081590Srgrimes			break;
30918400Sphk		case KTR_USER:
31018470Sphk			ktruser(ktrlen, m);
31118400Sphk			break;
312176471Sdes		case KTR_STRUCT:
313176471Sdes			ktrstruct(m, ktrlen);
314176471Sdes			break;
315226269Sdes		case KTR_CAPFAIL:
316226269Sdes			ktrcapfail((struct ktr_cap_fail *)m);
317233925Sjhb			break;
318233925Sjhb		case KTR_FAULT:
319233925Sjhb			ktrfault((struct ktr_fault *)m);
320233925Sjhb			break;
321233925Sjhb		case KTR_FAULTEND:
322233925Sjhb			ktrfaultend((struct ktr_faultend *)m);
323233925Sjhb			break;
324112203Sjhb		default:
325112203Sjhb			printf("\n");
326112203Sjhb			break;
3271590Srgrimes		}
3281590Srgrimes		if (tail)
329226153Sdes			fflush(stdout);
3301590Srgrimes	}
331100824Sdwmalone	return 0;
3321590Srgrimes}
3331590Srgrimes
334100824Sdwmaloneint
335100824Sdwmalonefread_tail(void *buf, int size, int num)
3361590Srgrimes{
3371590Srgrimes	int i;
3381590Srgrimes
3391590Srgrimes	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
340226153Sdes		sleep(1);
3411590Srgrimes		clearerr(stdin);
3421590Srgrimes	}
3431590Srgrimes	return (i);
3441590Srgrimes}
3451590Srgrimes
346219043Sdchaginint
347219043Sdchaginfetchprocinfo(struct ktr_header *kth, u_int *flags)
348219043Sdchagin{
349219043Sdchagin	struct proc_info *pi;
350219043Sdchagin
351219043Sdchagin	switch (kth->ktr_type) {
352219043Sdchagin	case KTR_PROCCTOR:
353219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
354219043Sdchagin			if (pi->pid == kth->ktr_pid) {
355219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
356219043Sdchagin				break;
357219043Sdchagin			}
358219043Sdchagin		}
359219043Sdchagin		pi = malloc(sizeof(struct proc_info));
360219043Sdchagin		if (pi == NULL)
361219043Sdchagin			errx(1, "%s", strerror(ENOMEM));
362219043Sdchagin		pi->sv_flags = *flags;
363219043Sdchagin		pi->pid = kth->ktr_pid;
364219043Sdchagin		TAILQ_INSERT_TAIL(&trace_procs, pi, info);
365219043Sdchagin		return (1);
366219043Sdchagin
367219043Sdchagin	case KTR_PROCDTOR:
368219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
369219043Sdchagin			if (pi->pid == kth->ktr_pid) {
370219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
371219043Sdchagin				free(pi);
372219043Sdchagin				break;
373219043Sdchagin			}
374219043Sdchagin		}
375219043Sdchagin		return (1);
376219043Sdchagin	}
377219043Sdchagin
378219043Sdchagin	return (0);
379219043Sdchagin}
380219043Sdchagin
381219043Sdchaginu_int
382219043Sdchaginabidump(struct ktr_header *kth)
383219043Sdchagin{
384219043Sdchagin	struct proc_info *pi;
385219043Sdchagin	const char *abi;
386219043Sdchagin	const char *arch;
387219043Sdchagin	u_int flags = 0;
388219043Sdchagin
389219043Sdchagin	TAILQ_FOREACH(pi, &trace_procs, info) {
390219043Sdchagin		if (pi->pid == kth->ktr_pid) {
391219043Sdchagin			flags = pi->sv_flags;
392219043Sdchagin			break;
393219043Sdchagin		}
394219043Sdchagin	}
395219043Sdchagin
396219043Sdchagin	if (abiflag == 0)
397219043Sdchagin		return (flags);
398219043Sdchagin
399219043Sdchagin	switch (flags & SV_ABI_MASK) {
400219043Sdchagin	case SV_ABI_LINUX:
401219043Sdchagin		abi = "L";
402219043Sdchagin		break;
403219043Sdchagin	case SV_ABI_FREEBSD:
404219043Sdchagin		abi = "F";
405219043Sdchagin		break;
406219043Sdchagin	default:
407219043Sdchagin		abi = "U";
408219043Sdchagin		break;
409219043Sdchagin	}
410219043Sdchagin
411219043Sdchagin	if (flags != 0) {
412219043Sdchagin		if (flags & SV_LP64)
413219043Sdchagin			arch = "64";
414219043Sdchagin		else
415219043Sdchagin			arch = "32";
416219043Sdchagin	} else
417219043Sdchagin		arch = "00";
418219043Sdchagin
419219043Sdchagin	printf("%s%s  ", abi, arch);
420219043Sdchagin
421219043Sdchagin	return (flags);
422219043Sdchagin}
423219043Sdchagin
424100824Sdwmalonevoid
425100824Sdwmalonedumpheader(struct ktr_header *kth)
4261590Srgrimes{
4271590Srgrimes	static char unknown[64];
4281590Srgrimes	static struct timeval prevtime, temp;
429100824Sdwmalone	const char *type;
4301590Srgrimes
4311590Srgrimes	switch (kth->ktr_type) {
4321590Srgrimes	case KTR_SYSCALL:
4331590Srgrimes		type = "CALL";
4341590Srgrimes		break;
4351590Srgrimes	case KTR_SYSRET:
4361590Srgrimes		type = "RET ";
4371590Srgrimes		break;
4381590Srgrimes	case KTR_NAMEI:
4391590Srgrimes		type = "NAMI";
4401590Srgrimes		break;
4411590Srgrimes	case KTR_GENIO:
4421590Srgrimes		type = "GIO ";
4431590Srgrimes		break;
4441590Srgrimes	case KTR_PSIG:
4451590Srgrimes		type = "PSIG";
4461590Srgrimes		break;
4471590Srgrimes	case KTR_CSW:
448171333Sjhb		type = "CSW ";
4491590Srgrimes		break;
45018400Sphk	case KTR_USER:
45118400Sphk		type = "USER";
45218400Sphk		break;
453176471Sdes	case KTR_STRUCT:
454176471Sdes		type = "STRU";
455176471Sdes		break;
456189707Sjhb	case KTR_SYSCTL:
457189707Sjhb		type = "SCTL";
458189707Sjhb		break;
459219043Sdchagin	case KTR_PROCCTOR:
460219043Sdchagin		/* FALLTHROUGH */
461219043Sdchagin	case KTR_PROCDTOR:
462219043Sdchagin		return;
463226269Sdes	case KTR_CAPFAIL:
464226269Sdes		type = "CAP ";
465226269Sdes		break;
466233925Sjhb	case KTR_FAULT:
467233925Sjhb		type = "PFLT";
468233925Sjhb		break;
469233925Sjhb	case KTR_FAULTEND:
470233925Sjhb		type = "PRET";
471233925Sjhb		break;
4721590Srgrimes	default:
473226153Sdes		sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
4741590Srgrimes		type = unknown;
4751590Srgrimes	}
4761590Srgrimes
477151930Srwatson	/*
478151930Srwatson	 * The ktr_tid field was previously the ktr_buffer field, which held
479151930Srwatson	 * the kernel pointer value for the buffer associated with data
480151930Srwatson	 * following the record header.  It now holds a threadid, but only
481151930Srwatson	 * for trace files after the change.  Older trace files still contain
482151930Srwatson	 * kernel pointers.  Detect this and suppress the results by printing
483151930Srwatson	 * negative tid's as 0.
484151930Srwatson	 */
485151930Srwatson	if (threads)
486226153Sdes		printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid,
487203551Sjh		    kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0,
488203551Sjh		    MAXCOMLEN, kth->ktr_comm);
489151930Srwatson	else
490226153Sdes		printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN,
491151930Srwatson		    kth->ktr_comm);
4921590Srgrimes	if (timestamp) {
493123187Speter		if (timestamp == 3) {
494123187Speter			if (prevtime.tv_sec == 0)
495123187Speter				prevtime = kth->ktr_time;
496123187Speter			timevalsub(&kth->ktr_time, &prevtime);
497123187Speter		}
4981590Srgrimes		if (timestamp == 2) {
4991590Srgrimes			temp = kth->ktr_time;
5001590Srgrimes			timevalsub(&kth->ktr_time, &prevtime);
5011590Srgrimes			prevtime = temp;
5021590Srgrimes		}
503226153Sdes		printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
504203551Sjh		    kth->ktr_time.tv_usec);
5051590Srgrimes	}
506226153Sdes	printf("%s  ", type);
5071590Srgrimes}
5081590Srgrimes
5091590Srgrimes#include <sys/syscall.h>
5101590Srgrimes#define KTRACE
5114721Sphk#include <sys/kern/syscalls.c>
5121590Srgrimes#undef KTRACE
5131590Srgrimesint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
5141590Srgrimes
515100824Sdwmalonevoid
516219043Sdchaginktrsyscall(struct ktr_syscall *ktr, u_int flags)
5171590Srgrimes{
518100824Sdwmalone	int narg = ktr->ktr_narg;
519100824Sdwmalone	register_t *ip;
520226269Sdes	intmax_t arg;
5211590Srgrimes
522219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
523219043Sdchagin	    (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
524226153Sdes		printf("[%d]", ktr->ktr_code);
5251590Srgrimes	else
526226153Sdes		printf("%s", syscallnames[ktr->ktr_code]);
52747957Sdt	ip = &ktr->ktr_args[0];
5281590Srgrimes	if (narg) {
5291590Srgrimes		char c = '(';
530219043Sdchagin		if (fancy &&
531219043Sdchagin		    (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
532226148Sdes			switch (ktr->ktr_code) {
533226148Sdes			case SYS_ioctl: {
534226150Sdes				print_number(ip, narg, c);
535226157Sdes				putchar(c);
536226157Sdes				ioctlname(*ip, decimal);
5371590Srgrimes				c = ',';
5381590Srgrimes				ip++;
5391590Srgrimes				narg--;
540226148Sdes				break;
541226148Sdes			}
542226148Sdes			case SYS_ptrace:
543226153Sdes				putchar('(');
544226164Sdes				ptraceopname(*ip);
5451590Srgrimes				c = ',';
5461590Srgrimes				ip++;
5471590Srgrimes				narg--;
548226148Sdes				break;
549226148Sdes			case SYS_access:
550226148Sdes			case SYS_eaccess:
551226150Sdes				print_number(ip, narg, c);
552226153Sdes				putchar(',');
553226164Sdes				accessmodename(*ip);
554158766Snetchild				ip++;
555158766Snetchild				narg--;
556226148Sdes				break;
557226148Sdes			case SYS_open:
558226150Sdes				print_number(ip, narg, c);
559226153Sdes				putchar(',');
560226164Sdes				flagsandmodename(ip[0], ip[1], decimal);
561226148Sdes				ip += 2;
562226148Sdes				narg -= 2;
563226148Sdes				break;
564226148Sdes			case SYS_wait4:
565226150Sdes				print_number(ip, narg, c);
566226150Sdes				print_number(ip, narg, c);
567226153Sdes				putchar(',');
568226164Sdes				wait4optname(*ip);
569158766Snetchild				ip++;
570158766Snetchild				narg--;
571226148Sdes				break;
572226148Sdes			case SYS_chmod:
573226148Sdes			case SYS_fchmod:
574226148Sdes			case SYS_lchmod:
575226150Sdes				print_number(ip, narg, c);
576226153Sdes				putchar(',');
577226164Sdes				modename(*ip);
578158766Snetchild				ip++;
579158766Snetchild				narg--;
580226148Sdes				break;
581226148Sdes			case SYS_mknod:
582226150Sdes				print_number(ip, narg, c);
583226153Sdes				putchar(',');
584226164Sdes				modename(*ip);
585158766Snetchild				ip++;
586158766Snetchild				narg--;
587226148Sdes				break;
588226148Sdes			case SYS_getfsstat:
589226150Sdes				print_number(ip, narg, c);
590226150Sdes				print_number(ip, narg, c);
591226153Sdes				putchar(',');
592226164Sdes				getfsstatflagsname(*ip);
593158766Snetchild				ip++;
594158766Snetchild				narg--;
595226148Sdes				break;
596226148Sdes			case SYS_mount:
597226150Sdes				print_number(ip, narg, c);
598226150Sdes				print_number(ip, narg, c);
599226153Sdes				putchar(',');
600226164Sdes				mountflagsname(*ip);
601158766Snetchild				ip++;
602158766Snetchild				narg--;
603226148Sdes				break;
604226148Sdes			case SYS_unmount:
605226150Sdes				print_number(ip, narg, c);
606226153Sdes				putchar(',');
607226164Sdes				mountflagsname(*ip);
608158766Snetchild				ip++;
609158766Snetchild				narg--;
610226148Sdes				break;
611226148Sdes			case SYS_recvmsg:
612226148Sdes			case SYS_sendmsg:
613226150Sdes				print_number(ip, narg, c);
614226150Sdes				print_number(ip, narg, c);
615226153Sdes				putchar(',');
616226164Sdes				sendrecvflagsname(*ip);
617158766Snetchild				ip++;
618158766Snetchild				narg--;
619226148Sdes				break;
620226148Sdes			case SYS_recvfrom:
621226148Sdes			case SYS_sendto:
622226150Sdes				print_number(ip, narg, c);
623226150Sdes				print_number(ip, narg, c);
624226150Sdes				print_number(ip, narg, c);
625226153Sdes				putchar(',');
626226164Sdes				sendrecvflagsname(*ip);
627158766Snetchild				ip++;
628158766Snetchild				narg--;
629226148Sdes				break;
630226148Sdes			case SYS_chflags:
631226148Sdes			case SYS_fchflags:
632226148Sdes			case SYS_lchflags:
633226150Sdes				print_number(ip, narg, c);
634226153Sdes				putchar(',');
635226164Sdes				modename(*ip);
636158766Snetchild				ip++;
637158766Snetchild				narg--;
638226148Sdes				break;
639226148Sdes			case SYS_kill:
640226150Sdes				print_number(ip, narg, c);
641226153Sdes				putchar(',');
642226164Sdes				signame(*ip);
643158766Snetchild				ip++;
644158766Snetchild				narg--;
645226148Sdes				break;
646226148Sdes			case SYS_reboot:
647226153Sdes				putchar('(');
648226164Sdes				rebootoptname(*ip);
649158766Snetchild				ip++;
650158766Snetchild				narg--;
651226148Sdes				break;
652226148Sdes			case SYS_umask:
653226153Sdes				putchar('(');
654226164Sdes				modename(*ip);
655158766Snetchild				ip++;
656158766Snetchild				narg--;
657226148Sdes				break;
658226148Sdes			case SYS_msync:
659226150Sdes				print_number(ip, narg, c);
660226150Sdes				print_number(ip, narg, c);
661226153Sdes				putchar(',');
662226164Sdes				msyncflagsname(*ip);
663158766Snetchild				ip++;
664158766Snetchild				narg--;
665226148Sdes				break;
666171221Speter#ifdef SYS_freebsd6_mmap
667226148Sdes			case SYS_freebsd6_mmap:
668226150Sdes				print_number(ip, narg, c);
669226150Sdes				print_number(ip, narg, c);
670226153Sdes				putchar(',');
671226164Sdes				mmapprotname(*ip);
672226153Sdes				putchar(',');
673171221Speter				ip++;
674171221Speter				narg--;
675226164Sdes				mmapflagsname(*ip);
676171221Speter				ip++;
677171221Speter				narg--;
678226148Sdes				break;
679171221Speter#endif
680226148Sdes			case SYS_mmap:
681226150Sdes				print_number(ip, narg, c);
682226150Sdes				print_number(ip, narg, c);
683226153Sdes				putchar(',');
684226164Sdes				mmapprotname(*ip);
685226153Sdes				putchar(',');
686158766Snetchild				ip++;
687158766Snetchild				narg--;
688226164Sdes				mmapflagsname(*ip);
689158766Snetchild				ip++;
690158766Snetchild				narg--;
691226148Sdes				break;
692226148Sdes			case SYS_mprotect:
693226150Sdes				print_number(ip, narg, c);
694226150Sdes				print_number(ip, narg, c);
695226153Sdes				putchar(',');
696226164Sdes				mmapprotname(*ip);
697158766Snetchild				ip++;
698158766Snetchild				narg--;
699226148Sdes				break;
700226148Sdes			case SYS_madvise:
701226150Sdes				print_number(ip, narg, c);
702226150Sdes				print_number(ip, narg, c);
703226153Sdes				putchar(',');
704226164Sdes				madvisebehavname(*ip);
705158766Snetchild				ip++;
706158766Snetchild				narg--;
707226148Sdes				break;
708226148Sdes			case SYS_setpriority:
709226150Sdes				print_number(ip, narg, c);
710226150Sdes				print_number(ip, narg, c);
711226153Sdes				putchar(',');
712226164Sdes				prioname(*ip);
713158766Snetchild				ip++;
714158766Snetchild				narg--;
715226148Sdes				break;
716226148Sdes			case SYS_fcntl:
717226150Sdes				print_number(ip, narg, c);
718226153Sdes				putchar(',');
719226164Sdes				fcntlcmdname(ip[0], ip[1], decimal);
720226148Sdes				ip += 2;
721226148Sdes				narg -= 2;
722226148Sdes				break;
723226148Sdes			case SYS_socket: {
724165758Srodrigc				int sockdomain;
725226153Sdes				putchar('(');
726226164Sdes				sockdomain = *ip;
727165758Srodrigc				sockdomainname(sockdomain);
728158766Snetchild				ip++;
729158766Snetchild				narg--;
730226153Sdes				putchar(',');
731226164Sdes				socktypename(*ip);
732158766Snetchild				ip++;
733158766Snetchild				narg--;
734165758Srodrigc				if (sockdomain == PF_INET ||
735165758Srodrigc				    sockdomain == PF_INET6) {
736226153Sdes					putchar(',');
737226164Sdes					sockipprotoname(*ip);
738165758Srodrigc					ip++;
739165758Srodrigc					narg--;
740165758Srodrigc				}
741158766Snetchild				c = ',';
742226148Sdes				break;
743226148Sdes			}
744226148Sdes			case SYS_setsockopt:
745226148Sdes			case SYS_getsockopt:
746226150Sdes				print_number(ip, narg, c);
747226153Sdes				putchar(',');
748226164Sdes				sockoptlevelname(*ip, decimal);
749226151Sdes				if (*ip == SOL_SOCKET) {
750175138Sjhb					ip++;
751175138Sjhb					narg--;
752226153Sdes					putchar(',');
753226164Sdes					sockoptname(*ip);
754175138Sjhb				}
755158766Snetchild				ip++;
756158766Snetchild				narg--;
757226148Sdes				break;
758171221Speter#ifdef SYS_freebsd6_lseek
759226148Sdes			case SYS_freebsd6_lseek:
760226150Sdes				print_number(ip, narg, c);
761158766Snetchild				/* Hidden 'pad' argument, not in lseek(2) */
762226150Sdes				print_number(ip, narg, c);
763226150Sdes				print_number(ip, narg, c);
764226153Sdes				putchar(',');
765226164Sdes				whencename(*ip);
766158766Snetchild				ip++;
767158766Snetchild				narg--;
768226148Sdes				break;
769171221Speter#endif
770226148Sdes			case SYS_lseek:
771226150Sdes				print_number(ip, narg, c);
772171221Speter				/* Hidden 'pad' argument, not in lseek(2) */
773226150Sdes				print_number(ip, narg, c);
774226153Sdes				putchar(',');
775226164Sdes				whencename(*ip);
776171221Speter				ip++;
777171221Speter				narg--;
778226148Sdes				break;
779226148Sdes			case SYS_flock:
780226150Sdes				print_number(ip, narg, c);
781226153Sdes				putchar(',');
782226164Sdes				flockname(*ip);
783158766Snetchild				ip++;
784158766Snetchild				narg--;
785226148Sdes				break;
786226148Sdes			case SYS_mkfifo:
787226148Sdes			case SYS_mkdir:
788226150Sdes				print_number(ip, narg, c);
789226153Sdes				putchar(',');
790226164Sdes				modename(*ip);
791158766Snetchild				ip++;
792158766Snetchild				narg--;
793226148Sdes				break;
794226148Sdes			case SYS_shutdown:
795226150Sdes				print_number(ip, narg, c);
796226153Sdes				putchar(',');
797226164Sdes				shutdownhowname(*ip);
798158766Snetchild				ip++;
799158766Snetchild				narg--;
800226148Sdes				break;
801226148Sdes			case SYS_socketpair:
802226153Sdes				putchar('(');
803226164Sdes				sockdomainname(*ip);
804158766Snetchild				ip++;
805158766Snetchild				narg--;
806226153Sdes				putchar(',');
807226164Sdes				socktypename(*ip);
808158766Snetchild				ip++;
809158766Snetchild				narg--;
810158766Snetchild				c = ',';
811226148Sdes				break;
812226148Sdes			case SYS_getrlimit:
813226148Sdes			case SYS_setrlimit:
814226153Sdes				putchar('(');
815226164Sdes				rlimitname(*ip);
816158766Snetchild				ip++;
817158766Snetchild				narg--;
818158766Snetchild				c = ',';
819226148Sdes				break;
820226148Sdes			case SYS_quotactl:
821226150Sdes				print_number(ip, narg, c);
822226153Sdes				putchar(',');
823226164Sdes				quotactlname(*ip);
824158766Snetchild				ip++;
825158766Snetchild				narg--;
826158766Snetchild				c = ',';
827226148Sdes				break;
828226148Sdes			case SYS_nfssvc:
829226153Sdes				putchar('(');
830226164Sdes				nfssvcname(*ip);
831158766Snetchild				ip++;
832158766Snetchild				narg--;
833158766Snetchild				c = ',';
834226148Sdes				break;
835226148Sdes			case SYS_rtprio:
836226153Sdes				putchar('(');
837226164Sdes				rtprioname(*ip);
838158766Snetchild				ip++;
839158766Snetchild				narg--;
840158766Snetchild				c = ',';
841226148Sdes				break;
842226148Sdes			case SYS___semctl:
843226150Sdes				print_number(ip, narg, c);
844226150Sdes				print_number(ip, narg, c);
845226153Sdes				putchar(',');
846226164Sdes				semctlname(*ip);
847158766Snetchild				ip++;
848158766Snetchild				narg--;
849226148Sdes				break;
850226148Sdes			case SYS_semget:
851226150Sdes				print_number(ip, narg, c);
852226150Sdes				print_number(ip, narg, c);
853226153Sdes				putchar(',');
854226164Sdes				semgetname(*ip);
855158766Snetchild				ip++;
856158766Snetchild				narg--;
857226148Sdes				break;
858226148Sdes			case SYS_msgctl:
859226150Sdes				print_number(ip, narg, c);
860226153Sdes				putchar(',');
861226164Sdes				shmctlname(*ip);
862158766Snetchild				ip++;
863158766Snetchild				narg--;
864226148Sdes				break;
865226148Sdes			case SYS_shmat:
866226150Sdes				print_number(ip, narg, c);
867226150Sdes				print_number(ip, narg, c);
868226153Sdes				putchar(',');
869226164Sdes				shmatname(*ip);
870158766Snetchild				ip++;
871158766Snetchild				narg--;
872226148Sdes				break;
873226148Sdes			case SYS_shmctl:
874226150Sdes				print_number(ip, narg, c);
875226153Sdes				putchar(',');
876226164Sdes				shmctlname(*ip);
877158766Snetchild				ip++;
878158766Snetchild				narg--;
879226148Sdes				break;
880226148Sdes			case SYS_minherit:
881226150Sdes				print_number(ip, narg, c);
882226150Sdes				print_number(ip, narg, c);
883226153Sdes				putchar(',');
884226164Sdes				minheritname(*ip);
885158766Snetchild				ip++;
886158766Snetchild				narg--;
887226148Sdes				break;
888226148Sdes			case SYS_rfork:
889226153Sdes				putchar('(');
890226164Sdes				rforkname(*ip);
891158766Snetchild				ip++;
892158766Snetchild				narg--;
893158766Snetchild				c = ',';
894226148Sdes				break;
895226148Sdes			case SYS_lio_listio:
896226153Sdes				putchar('(');
897226164Sdes				lio_listioname(*ip);
898158766Snetchild				ip++;
899158766Snetchild				narg--;
900158766Snetchild				c = ',';
901226148Sdes				break;
902226148Sdes			case SYS_mlockall:
903226153Sdes				putchar('(');
904226164Sdes				mlockallname(*ip);
905158766Snetchild				ip++;
906158766Snetchild				narg--;
907226148Sdes				break;
908226148Sdes			case SYS_sched_setscheduler:
909226150Sdes				print_number(ip, narg, c);
910226153Sdes				putchar(',');
911226164Sdes				schedpolicyname(*ip);
912158766Snetchild				ip++;
913158766Snetchild				narg--;
914226148Sdes				break;
915226148Sdes			case SYS_sched_get_priority_max:
916226148Sdes			case SYS_sched_get_priority_min:
917226153Sdes				putchar('(');
918226164Sdes				schedpolicyname(*ip);
919158766Snetchild				ip++;
920158766Snetchild				narg--;
921226148Sdes				break;
922226148Sdes			case SYS_sendfile:
923226150Sdes				print_number(ip, narg, c);
924226150Sdes				print_number(ip, narg, c);
925226150Sdes				print_number(ip, narg, c);
926226150Sdes				print_number(ip, narg, c);
927226150Sdes				print_number(ip, narg, c);
928226150Sdes				print_number(ip, narg, c);
929226153Sdes				putchar(',');
930226164Sdes				sendfileflagsname(*ip);
931158766Snetchild				ip++;
932158766Snetchild				narg--;
933226148Sdes				break;
934226148Sdes			case SYS_kldsym:
935226150Sdes				print_number(ip, narg, c);
936226153Sdes				putchar(',');
937226164Sdes				kldsymcmdname(*ip);
938158766Snetchild				ip++;
939158766Snetchild				narg--;
940226148Sdes				break;
941226148Sdes			case SYS_sigprocmask:
942226153Sdes				putchar('(');
943226164Sdes				sigprocmaskhowname(*ip);
944158766Snetchild				ip++;
945158766Snetchild				narg--;
946158766Snetchild				c = ',';
947226148Sdes				break;
948226148Sdes			case SYS___acl_get_file:
949226148Sdes			case SYS___acl_set_file:
950226148Sdes			case SYS___acl_get_fd:
951226148Sdes			case SYS___acl_set_fd:
952226148Sdes			case SYS___acl_delete_file:
953226148Sdes			case SYS___acl_delete_fd:
954226148Sdes			case SYS___acl_aclcheck_file:
955226148Sdes			case SYS___acl_aclcheck_fd:
956226148Sdes			case SYS___acl_get_link:
957226148Sdes			case SYS___acl_set_link:
958226148Sdes			case SYS___acl_delete_link:
959226148Sdes			case SYS___acl_aclcheck_link:
960226150Sdes				print_number(ip, narg, c);
961226153Sdes				putchar(',');
962226164Sdes				acltypename(*ip);
963158766Snetchild				ip++;
964158766Snetchild				narg--;
965226148Sdes				break;
966226148Sdes			case SYS_sigaction:
967226153Sdes				putchar('(');
968226164Sdes				signame(*ip);
969158766Snetchild				ip++;
970158766Snetchild				narg--;
971158766Snetchild				c = ',';
972226148Sdes				break;
973226148Sdes			case SYS_extattrctl:
974226150Sdes				print_number(ip, narg, c);
975226153Sdes				putchar(',');
976226164Sdes				extattrctlname(*ip);
977158766Snetchild				ip++;
978158766Snetchild				narg--;
979226148Sdes				break;
980226148Sdes			case SYS_nmount:
981226150Sdes				print_number(ip, narg, c);
982226150Sdes				print_number(ip, narg, c);
983226153Sdes				putchar(',');
984226164Sdes				mountflagsname(*ip);
985158766Snetchild				ip++;
986158766Snetchild				narg--;
987226148Sdes				break;
988226148Sdes			case SYS_thr_create:
989226150Sdes				print_number(ip, narg, c);
990226150Sdes				print_number(ip, narg, c);
991226153Sdes				putchar(',');
992226164Sdes				thrcreateflagsname(*ip);
993158766Snetchild				ip++;
994158766Snetchild				narg--;
995226148Sdes				break;
996226148Sdes			case SYS_thr_kill:
997226150Sdes				print_number(ip, narg, c);
998226153Sdes				putchar(',');
999226164Sdes				signame(*ip);
1000158766Snetchild				ip++;
1001158766Snetchild				narg--;
1002226148Sdes				break;
1003226148Sdes			case SYS_kldunloadf:
1004226150Sdes				print_number(ip, narg, c);
1005226153Sdes				putchar(',');
1006226164Sdes				kldunloadfflagsname(*ip);
1007158766Snetchild				ip++;
1008158766Snetchild				narg--;
1009226148Sdes				break;
1010226269Sdes			case SYS_cap_new:
1011226269Sdes				print_number(ip, narg, c);
1012226269Sdes				putchar(',');
1013226269Sdes				arg = *ip;
1014226269Sdes				ip++;
1015226269Sdes				narg--;
1016226269Sdes				/*
1017226269Sdes				 * Hack: the second argument is a
1018226269Sdes				 * cap_rights_t, which 64 bits wide, so on
1019226269Sdes				 * 32-bit systems, it is split between two
1020226269Sdes				 * registers.
1021226269Sdes				 *
1022226269Sdes				 * Since sizeof() is not evaluated by the
1023226269Sdes				 * preprocessor, we can't use an #ifdef,
1024226269Sdes				 * but the compiler will probably optimize
1025226269Sdes				 * the code out anyway.
1026226269Sdes				 */
1027226269Sdes				if (sizeof(cap_rights_t) > sizeof(register_t)) {
1028226269Sdes#if _BYTE_ORDER == _LITTLE_ENDIAN
1029226269Sdes					arg = ((intmax_t)*ip << 32) + arg;
1030226269Sdes#else
1031226269Sdes					arg = (arg << 32) + *ip;
1032226269Sdes#endif
1033226269Sdes					ip++;
1034226269Sdes					narg--;
1035226269Sdes				}
1036226269Sdes				capname(arg);
1037226159Sdes				break;
1038232072Sjhb			case SYS_posix_fadvise:
1039232128Sjhb				print_number(ip, narg, c);
1040232128Sjhb				print_number(ip, narg, c);
1041232128Sjhb				print_number(ip, narg, c);
1042232072Sjhb				(void)putchar(',');
1043232072Sjhb				fadvisebehavname((int)*ip);
1044232072Sjhb				ip++;
1045232072Sjhb				narg--;
1046232072Sjhb				break;
10471590Srgrimes			}
10481590Srgrimes		}
1049199024Sattilio		while (narg > 0) {
1050226150Sdes			print_number(ip, narg, c);
10511590Srgrimes		}
1052226153Sdes		putchar(')');
10531590Srgrimes	}
1054226153Sdes	putchar('\n');
10551590Srgrimes}
10561590Srgrimes
1057100824Sdwmalonevoid
1058219043Sdchaginktrsysret(struct ktr_sysret *ktr, u_int flags)
10591590Srgrimes{
1060100824Sdwmalone	register_t ret = ktr->ktr_retval;
1061100824Sdwmalone	int error = ktr->ktr_error;
1062100824Sdwmalone	int code = ktr->ktr_code;
10631590Srgrimes
1064219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
1065219043Sdchagin	    (code >= nsyscalls || code < 0))
1066226153Sdes		printf("[%d] ", code);
10671590Srgrimes	else
1068226153Sdes		printf("%s ", syscallnames[code]);
10691590Srgrimes
10701590Srgrimes	if (error == 0) {
10711590Srgrimes		if (fancy) {
1072226153Sdes			printf("%ld", (long)ret);
10731590Srgrimes			if (ret < 0 || ret > 9)
1074226153Sdes				printf("/%#lx", (unsigned long)ret);
10751590Srgrimes		} else {
10761590Srgrimes			if (decimal)
1077226153Sdes				printf("%ld", (long)ret);
10781590Srgrimes			else
1079226153Sdes				printf("%#lx", (unsigned long)ret);
10801590Srgrimes		}
10811590Srgrimes	} else if (error == ERESTART)
1082226153Sdes		printf("RESTART");
10831590Srgrimes	else if (error == EJUSTRETURN)
1084226153Sdes		printf("JUSTRETURN");
10851590Srgrimes	else {
1086226153Sdes		printf("-1 errno %d", ktr->ktr_error);
10871590Srgrimes		if (fancy)
1088226153Sdes			printf(" %s", strerror(ktr->ktr_error));
10891590Srgrimes	}
1090226153Sdes	putchar('\n');
10911590Srgrimes}
10921590Srgrimes
1093100824Sdwmalonevoid
1094100824Sdwmalonektrnamei(char *cp, int len)
10951590Srgrimes{
1096226153Sdes	printf("\"%.*s\"\n", len, cp);
10971590Srgrimes}
10981590Srgrimes
1099100824Sdwmalonevoid
1100115759Speterhexdump(char *p, int len, int screenwidth)
11011590Srgrimes{
1102115759Speter	int n, i;
1103115759Speter	int width;
1104115759Speter
1105115759Speter	width = 0;
1106115759Speter	do {
1107115759Speter		width += 2;
1108115759Speter		i = 13;			/* base offset */
1109115759Speter		i += (width / 2) + 1;	/* spaces every second byte */
1110115759Speter		i += (width * 2);	/* width of bytes */
1111115759Speter		i += 3;			/* "  |" */
1112115759Speter		i += width;		/* each byte */
1113115759Speter		i += 1;			/* "|" */
1114115759Speter	} while (i < screenwidth);
1115115759Speter	width -= 2;
1116115759Speter
1117115759Speter	for (n = 0; n < len; n += width) {
1118115759Speter		for (i = n; i < n + width; i++) {
1119115759Speter			if ((i % width) == 0) {	/* beginning of line */
1120115759Speter				printf("       0x%04x", i);
1121115759Speter			}
1122115759Speter			if ((i % 2) == 0) {
1123115759Speter				printf(" ");
1124115759Speter			}
1125115759Speter			if (i < len)
1126115759Speter				printf("%02x", p[i] & 0xff);
1127115759Speter			else
1128115759Speter				printf("  ");
1129115759Speter		}
1130115759Speter		printf("  |");
1131115759Speter		for (i = n; i < n + width; i++) {
1132115759Speter			if (i >= len)
1133115759Speter				break;
1134115759Speter			if (p[i] >= ' ' && p[i] <= '~')
1135115759Speter				printf("%c", p[i]);
1136115759Speter			else
1137115759Speter				printf(".");
1138115759Speter		}
1139115759Speter		printf("|\n");
1140115759Speter	}
1141115759Speter	if ((i % width) != 0)
1142115759Speter		printf("\n");
1143115759Speter}
1144115759Speter
1145115759Spetervoid
1146115759Spetervisdump(char *dp, int datalen, int screenwidth)
1147115759Speter{
1148115759Speter	int col = 0;
1149100824Sdwmalone	char *cp;
1150100824Sdwmalone	int width;
11511590Srgrimes	char visbuf[5];
11521590Srgrimes
1153226153Sdes	printf("       \"");
11541590Srgrimes	col = 8;
11551590Srgrimes	for (;datalen > 0; datalen--, dp++) {
1156226153Sdes		 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
11571590Srgrimes		cp = visbuf;
11581590Srgrimes		/*
11591590Srgrimes		 * Keep track of printables and
11601590Srgrimes		 * space chars (like fold(1)).
11611590Srgrimes		 */
11621590Srgrimes		if (col == 0) {
1163226153Sdes			putchar('\t');
11641590Srgrimes			col = 8;
11651590Srgrimes		}
11661590Srgrimes		switch(*cp) {
11671590Srgrimes		case '\n':
11681590Srgrimes			col = 0;
1169226153Sdes			putchar('\n');
11701590Srgrimes			continue;
11711590Srgrimes		case '\t':
11721590Srgrimes			width = 8 - (col&07);
11731590Srgrimes			break;
11741590Srgrimes		default:
11751590Srgrimes			width = strlen(cp);
11761590Srgrimes		}
11771590Srgrimes		if (col + width > (screenwidth-2)) {
1178226153Sdes			printf("\\\n\t");
11791590Srgrimes			col = 8;
11801590Srgrimes		}
11811590Srgrimes		col += width;
11821590Srgrimes		do {
1183226153Sdes			putchar(*cp++);
11841590Srgrimes		} while (*cp);
11851590Srgrimes	}
11861590Srgrimes	if (col == 0)
1187226153Sdes		printf("       ");
1188226153Sdes	printf("\"\n");
11891590Srgrimes}
11901590Srgrimes
1191115759Spetervoid
1192115759Speterktrgenio(struct ktr_genio *ktr, int len)
1193115759Speter{
1194115759Speter	int datalen = len - sizeof (struct ktr_genio);
1195115759Speter	char *dp = (char *)ktr + sizeof (struct ktr_genio);
1196115759Speter	static int screenwidth = 0;
1197115759Speter	int i, binary;
1198115759Speter
1199115759Speter	if (screenwidth == 0) {
1200115759Speter		struct winsize ws;
1201115759Speter
1202115759Speter		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1203115759Speter		    ws.ws_col > 8)
1204115759Speter			screenwidth = ws.ws_col;
1205115759Speter		else
1206115759Speter			screenwidth = 80;
1207115759Speter	}
1208115759Speter	printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1209115759Speter		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1210115759Speter		datalen == 1 ? "" : "s");
1211152331Srwatson	if (suppressdata)
1212152331Srwatson		return;
1213115759Speter	if (maxdata && datalen > maxdata)
1214115759Speter		datalen = maxdata;
1215115759Speter
1216115759Speter	for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1217115759Speter		if (dp[i] >= 32 && dp[i] < 127)
1218115759Speter			continue;
1219115759Speter		if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1220115759Speter			continue;
1221115759Speter		binary = 1;
1222115759Speter	}
1223115759Speter	if (binary)
1224115759Speter		hexdump(dp, datalen, screenwidth);
1225115759Speter	else
1226115759Speter		visdump(dp, datalen, screenwidth);
1227115759Speter}
1228115759Speter
1229100824Sdwmaloneconst char *signames[] = {
12301590Srgrimes	"NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",	/*  1 - 6  */
12311590Srgrimes	"EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",		/*  7 - 12 */
12321590Srgrimes	"PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",		/* 13 - 18 */
12331590Srgrimes	"CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",		/* 19 - 24 */
12341590Srgrimes	"XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",	/* 25 - 30 */
12351590Srgrimes	"USR2", NULL,						/* 31 - 32 */
12361590Srgrimes};
12371590Srgrimes
1238100824Sdwmalonevoid
1239219138Sdchaginktrpsig(struct ktr_psig *psig)
12401590Srgrimes{
1241219138Sdchagin	if (psig->signo > 0 && psig->signo < NSIG)
1242226153Sdes		printf("SIG%s ", signames[psig->signo]);
1243160294Skib	else
1244226153Sdes		printf("SIG %d ", psig->signo);
1245240820Sjilles	if (psig->action == SIG_DFL) {
1246240820Sjilles		printf("SIG_DFL code=");
1247240820Sjilles		sigcodename(psig->signo, psig->code);
1248240820Sjilles		putchar('\n');
1249240820Sjilles	} else {
1250240820Sjilles		printf("caught handler=0x%lx mask=0x%x code=",
1251240820Sjilles		    (u_long)psig->action, psig->mask.__bits[0]);
1252240820Sjilles		sigcodename(psig->signo, psig->code);
1253240820Sjilles		putchar('\n');
1254100824Sdwmalone	}
12551590Srgrimes}
12561590Srgrimes
1257100824Sdwmalonevoid
1258234494Sjhbktrcsw_old(struct ktr_csw_old *cs)
12591590Srgrimes{
1260226153Sdes	printf("%s %s\n", cs->out ? "stop" : "resume",
12611590Srgrimes		cs->user ? "user" : "kernel");
12621590Srgrimes}
12631590Srgrimes
1264234494Sjhbvoid
1265234494Sjhbktrcsw(struct ktr_csw *cs)
1266234494Sjhb{
1267234494Sjhb	printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume",
1268234494Sjhb	    cs->user ? "user" : "kernel", cs->wmesg);
1269234494Sjhb}
1270234494Sjhb
1271165916Sjhb#define	UTRACE_DLOPEN_START		1
1272165916Sjhb#define	UTRACE_DLOPEN_STOP		2
1273165916Sjhb#define	UTRACE_DLCLOSE_START		3
1274165916Sjhb#define	UTRACE_DLCLOSE_STOP		4
1275165916Sjhb#define	UTRACE_LOAD_OBJECT		5
1276165916Sjhb#define	UTRACE_UNLOAD_OBJECT		6
1277165916Sjhb#define	UTRACE_ADD_RUNDEP		7
1278165916Sjhb#define	UTRACE_PRELOAD_FINISHED		8
1279165916Sjhb#define	UTRACE_INIT_CALL		9
1280165916Sjhb#define	UTRACE_FINI_CALL		10
1281165916Sjhb
1282165916Sjhbstruct utrace_rtld {
1283165916Sjhb	char sig[4];				/* 'RTLD' */
1284165916Sjhb	int event;
1285165916Sjhb	void *handle;
1286165916Sjhb	void *mapbase;
1287165916Sjhb	size_t mapsize;
1288165916Sjhb	int refcnt;
1289165916Sjhb	char name[MAXPATHLEN];
1290165916Sjhb};
1291165916Sjhb
1292165916Sjhbvoid
1293165916Sjhbktruser_rtld(int len, unsigned char *p)
1294165916Sjhb{
1295165916Sjhb	struct utrace_rtld *ut = (struct utrace_rtld *)p;
1296165916Sjhb	void *parent;
1297165916Sjhb	int mode;
1298165916Sjhb
1299165916Sjhb	switch (ut->event) {
1300165916Sjhb	case UTRACE_DLOPEN_START:
1301165916Sjhb		mode = ut->refcnt;
1302165916Sjhb		printf("dlopen(%s, ", ut->name);
1303165916Sjhb		switch (mode & RTLD_MODEMASK) {
1304165916Sjhb		case RTLD_NOW:
1305165916Sjhb			printf("RTLD_NOW");
1306165916Sjhb			break;
1307165916Sjhb		case RTLD_LAZY:
1308165916Sjhb			printf("RTLD_LAZY");
1309165916Sjhb			break;
1310165916Sjhb		default:
1311165916Sjhb			printf("%#x", mode & RTLD_MODEMASK);
1312165916Sjhb		}
1313165916Sjhb		if (mode & RTLD_GLOBAL)
1314165916Sjhb			printf(" | RTLD_GLOBAL");
1315165916Sjhb		if (mode & RTLD_TRACE)
1316165916Sjhb			printf(" | RTLD_TRACE");
1317165916Sjhb		if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
1318165916Sjhb			printf(" | %#x", mode &
1319165916Sjhb			    ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
1320165916Sjhb		printf(")\n");
1321165916Sjhb		break;
1322165916Sjhb	case UTRACE_DLOPEN_STOP:
1323165916Sjhb		printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
1324165916Sjhb		    ut->refcnt);
1325165916Sjhb		break;
1326165916Sjhb	case UTRACE_DLCLOSE_START:
1327165916Sjhb		printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
1328165916Sjhb		    ut->refcnt);
1329165916Sjhb		break;
1330165916Sjhb	case UTRACE_DLCLOSE_STOP:
1331165916Sjhb		printf("dlclose(%p) finished\n", ut->handle);
1332165916Sjhb		break;
1333165916Sjhb	case UTRACE_LOAD_OBJECT:
1334165916Sjhb		printf("RTLD: loaded   %p @ %p - %p (%s)\n", ut->handle,
1335165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1336165916Sjhb		    ut->name);
1337165916Sjhb		break;
1338165916Sjhb	case UTRACE_UNLOAD_OBJECT:
1339165916Sjhb		printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
1340165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1341165916Sjhb		    ut->name);
1342165916Sjhb		break;
1343165916Sjhb	case UTRACE_ADD_RUNDEP:
1344165916Sjhb		parent = ut->mapbase;
1345165916Sjhb		printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
1346165916Sjhb		    ut->handle, ut->name, ut->refcnt);
1347165916Sjhb		break;
1348165916Sjhb	case UTRACE_PRELOAD_FINISHED:
1349165916Sjhb		printf("RTLD: LD_PRELOAD finished\n");
1350165916Sjhb		break;
1351165916Sjhb	case UTRACE_INIT_CALL:
1352165916Sjhb		printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1353165916Sjhb		    ut->name);
1354165916Sjhb		break;
1355165916Sjhb	case UTRACE_FINI_CALL:
1356165916Sjhb		printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1357165916Sjhb		    ut->name);
1358165916Sjhb		break;
1359165916Sjhb	default:
1360165916Sjhb		p += 4;
1361165916Sjhb		len -= 4;
1362165916Sjhb		printf("RTLD: %d ", len);
1363165916Sjhb		while (len--)
1364165916Sjhb			if (decimal)
1365165916Sjhb				printf(" %d", *p++);
1366165916Sjhb			else
1367165916Sjhb				printf(" %02x", *p++);
1368165916Sjhb		printf("\n");
1369165916Sjhb	}
1370165916Sjhb}
1371165916Sjhb
1372165812Sjhbstruct utrace_malloc {
1373165812Sjhb	void *p;
1374165812Sjhb	size_t s;
1375165812Sjhb	void *r;
1376165812Sjhb};
1377165812Sjhb
1378100824Sdwmalonevoid
1379226329Sdesktruser_malloc(unsigned char *p)
1380165812Sjhb{
1381165812Sjhb	struct utrace_malloc *ut = (struct utrace_malloc *)p;
1382165812Sjhb
1383199265Scperciva	if (ut->p == (void *)(intptr_t)(-1))
1384199265Scperciva		printf("malloc_init()\n");
1385199265Scperciva	else if (ut->s == 0)
1386199265Scperciva		printf("free(%p)\n", ut->p);
1387199265Scperciva	else if (ut->p == NULL)
1388199265Scperciva		printf("%p = malloc(%zu)\n", ut->r, ut->s);
1389199265Scperciva	else
1390199265Scperciva		printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1391165812Sjhb}
1392165812Sjhb
1393165812Sjhbvoid
1394100824Sdwmalonektruser(int len, unsigned char *p)
139518400Sphk{
1396165812Sjhb
1397165916Sjhb	if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1398165916Sjhb		ktruser_rtld(len, p);
1399165916Sjhb		return;
1400165916Sjhb	}
1401165916Sjhb
1402165812Sjhb	if (len == sizeof(struct utrace_malloc)) {
1403226329Sdes		ktruser_malloc(p);
1404165812Sjhb		return;
1405165812Sjhb	}
1406165812Sjhb
1407226153Sdes	printf("%d ", len);
140818470Sphk	while (len--)
1409127402Sphk		if (decimal)
1410226153Sdes			printf(" %d", *p++);
1411127402Sphk		else
1412226153Sdes			printf(" %02x", *p++);
1413226153Sdes	printf("\n");
141418400Sphk}
141518400Sphk
1416100824Sdwmalonevoid
1417176471Sdesktrsockaddr(struct sockaddr *sa)
1418176471Sdes{
1419176471Sdes/*
1420176471Sdes TODO: Support additional address families
1421176471Sdes	#include <netnatm/natm.h>
1422176471Sdes	struct sockaddr_natm	*natm;
1423176471Sdes	#include <netsmb/netbios.h>
1424176471Sdes	struct sockaddr_nb	*nb;
1425176471Sdes*/
1426176471Sdes	char addr[64];
1427176471Sdes
1428176471Sdes	/*
1429176471Sdes	 * note: ktrstruct() has already verified that sa points to a
1430176471Sdes	 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1431176471Sdes	 * sa->sa_len bytes long.
1432176471Sdes	 */
1433176471Sdes	printf("struct sockaddr { ");
1434176471Sdes	sockfamilyname(sa->sa_family);
1435176471Sdes	printf(", ");
1436176471Sdes
1437176471Sdes#define check_sockaddr_len(n)					\
1438226329Sdes	if (sa_##n.s##n##_len < sizeof(struct sockaddr_##n)) {	\
1439176471Sdes		printf("invalid");				\
1440176471Sdes		break;						\
1441176471Sdes	}
1442176471Sdes
1443176471Sdes	switch(sa->sa_family) {
1444176471Sdes	case AF_INET: {
1445226329Sdes		struct sockaddr_in sa_in;
1446176471Sdes
1447226329Sdes		memset(&sa_in, 0, sizeof(sa_in));
1448226329Sdes		memcpy(&sa_in, sa, sizeof(sa));
1449176471Sdes		check_sockaddr_len(in);
1450226329Sdes		inet_ntop(AF_INET, &sa_in.sin_addr, addr, sizeof addr);
1451226329Sdes		printf("%s:%u", addr, ntohs(sa_in.sin_port));
1452176471Sdes		break;
1453176471Sdes	}
1454176471Sdes#ifdef NETATALK
1455176471Sdes	case AF_APPLETALK: {
1456226329Sdes		struct sockaddr_at	sa_at;
1457176471Sdes		struct netrange		*nr;
1458176471Sdes
1459226329Sdes		memset(&sa_at, 0, sizeof(sa_at));
1460226329Sdes		memcpy(&sa_at, sa, sizeof(sa));
1461176471Sdes		check_sockaddr_len(at);
1462226329Sdes		nr = &sa_at.sat_range.r_netrange;
1463226329Sdes		printf("%d.%d, %d-%d, %d", ntohs(sa_at.sat_addr.s_net),
1464226329Sdes			sa_at.sat_addr.s_node, ntohs(nr->nr_firstnet),
1465176471Sdes			ntohs(nr->nr_lastnet), nr->nr_phase);
1466176471Sdes		break;
1467176471Sdes	}
1468176471Sdes#endif
1469176471Sdes	case AF_INET6: {
1470226329Sdes		struct sockaddr_in6 sa_in6;
1471176471Sdes
1472226329Sdes		memset(&sa_in6, 0, sizeof(sa_in6));
1473226329Sdes		memcpy(&sa_in6, sa, sizeof(sa));
1474176471Sdes		check_sockaddr_len(in6);
1475226329Sdes		inet_ntop(AF_INET6, &sa_in6.sin6_addr, addr, sizeof addr);
1476226329Sdes		printf("[%s]:%u", addr, htons(sa_in6.sin6_port));
1477176471Sdes		break;
1478176471Sdes	}
1479176471Sdes#ifdef IPX
1480176471Sdes	case AF_IPX: {
1481226329Sdes		struct sockaddr_ipx sa_ipx;
1482176471Sdes
1483226329Sdes		memset(&sa_ipx, 0, sizeof(sa_ipx));
1484226329Sdes		memcpy(&sa_ipx, sa, sizeof(sa));
1485176471Sdes		check_sockaddr_len(ipx);
1486176471Sdes		/* XXX wish we had ipx_ntop */
1487226329Sdes		printf("%s", ipx_ntoa(sa_ipx.sipx_addr));
1488226329Sdes		free(sa_ipx);
1489176471Sdes		break;
1490176471Sdes	}
1491176471Sdes#endif
1492176471Sdes	case AF_UNIX: {
1493226329Sdes		struct sockaddr_un sa_un;
1494176471Sdes
1495226329Sdes		memset(&sa_un, 0, sizeof(sa_un));
1496226329Sdes		memcpy(&sa_un, sa, sizeof(sa));
1497176471Sdes		check_sockaddr_len(un);
1498226329Sdes		printf("%.*s", (int)sizeof(sa_un.sun_path), sa_un.sun_path);
1499176471Sdes		break;
1500176471Sdes	}
1501176471Sdes	default:
1502176471Sdes		printf("unknown address family");
1503176471Sdes	}
1504176471Sdes	printf(" }\n");
1505176471Sdes}
1506176471Sdes
1507176471Sdesvoid
1508176471Sdesktrstat(struct stat *statp)
1509176471Sdes{
1510176471Sdes	char mode[12], timestr[PATH_MAX + 4];
1511176471Sdes	struct passwd *pwd;
1512176471Sdes	struct group  *grp;
1513176471Sdes	struct tm *tm;
1514176471Sdes
1515176471Sdes	/*
1516176471Sdes	 * note: ktrstruct() has already verified that statp points to a
1517176471Sdes	 * buffer exactly sizeof(struct stat) bytes long.
1518176471Sdes	 */
1519176471Sdes	printf("struct stat {");
1520176471Sdes	strmode(statp->st_mode, mode);
1521176471Sdes	printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ",
1522176471Sdes		(uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode,
1523176471Sdes		(uintmax_t)statp->st_nlink);
1524176471Sdes	if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1525176471Sdes		printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1526176471Sdes	else
1527176471Sdes		printf("uid=\"%s\", ", pwd->pw_name);
1528176471Sdes	if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1529176471Sdes		printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1530176471Sdes	else
1531176471Sdes		printf("gid=\"%s\", ", grp->gr_name);
1532176471Sdes	printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1533176471Sdes	printf("atime=");
1534176471Sdes	if (resolv == 0)
1535205793Sed		printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1536176471Sdes	else {
1537205793Sed		tm = localtime(&statp->st_atim.tv_sec);
1538226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1539176471Sdes		printf("\"%s\"", timestr);
1540176471Sdes	}
1541205793Sed	if (statp->st_atim.tv_nsec != 0)
1542205793Sed		printf(".%09ld, ", statp->st_atim.tv_nsec);
1543176471Sdes	else
1544176471Sdes		printf(", ");
1545176471Sdes	printf("stime=");
1546176471Sdes	if (resolv == 0)
1547205793Sed		printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1548176471Sdes	else {
1549205793Sed		tm = localtime(&statp->st_mtim.tv_sec);
1550226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1551176471Sdes		printf("\"%s\"", timestr);
1552176471Sdes	}
1553205793Sed	if (statp->st_mtim.tv_nsec != 0)
1554205793Sed		printf(".%09ld, ", statp->st_mtim.tv_nsec);
1555176471Sdes	else
1556176471Sdes		printf(", ");
1557176471Sdes	printf("ctime=");
1558176471Sdes	if (resolv == 0)
1559205793Sed		printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1560176471Sdes	else {
1561205793Sed		tm = localtime(&statp->st_ctim.tv_sec);
1562226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1563176471Sdes		printf("\"%s\"", timestr);
1564176471Sdes	}
1565205793Sed	if (statp->st_ctim.tv_nsec != 0)
1566205793Sed		printf(".%09ld, ", statp->st_ctim.tv_nsec);
1567176471Sdes	else
1568176471Sdes		printf(", ");
1569176471Sdes	printf("birthtime=");
1570176471Sdes	if (resolv == 0)
1571205793Sed		printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
1572176471Sdes	else {
1573205793Sed		tm = localtime(&statp->st_birthtim.tv_sec);
1574226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1575176471Sdes		printf("\"%s\"", timestr);
1576176471Sdes	}
1577205793Sed	if (statp->st_birthtim.tv_nsec != 0)
1578205793Sed		printf(".%09ld, ", statp->st_birthtim.tv_nsec);
1579176471Sdes	else
1580176471Sdes		printf(", ");
1581176471Sdes	printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1582176471Sdes		(uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
1583176471Sdes		(intmax_t)statp->st_blocks, statp->st_flags);
1584176471Sdes	printf(" }\n");
1585176471Sdes}
1586176471Sdes
1587176471Sdesvoid
1588176471Sdesktrstruct(char *buf, size_t buflen)
1589176471Sdes{
1590176471Sdes	char *name, *data;
1591176471Sdes	size_t namelen, datalen;
1592176471Sdes	int i;
1593204045Simp	struct stat sb;
1594204045Simp	struct sockaddr_storage ss;
1595176471Sdes
1596176471Sdes	for (name = buf, namelen = 0;
1597176471Sdes	     namelen < buflen && name[namelen] != '\0';
1598176471Sdes	     ++namelen)
1599176471Sdes		/* nothing */;
1600176471Sdes	if (namelen == buflen)
1601176471Sdes		goto invalid;
1602176471Sdes	if (name[namelen] != '\0')
1603176471Sdes		goto invalid;
1604176471Sdes	data = buf + namelen + 1;
1605176471Sdes	datalen = buflen - namelen - 1;
1606176471Sdes	if (datalen == 0)
1607176471Sdes		goto invalid;
1608176471Sdes	/* sanity check */
1609226329Sdes	for (i = 0; i < (int)namelen; ++i)
1610226329Sdes		if (!isalpha(name[i]))
1611176471Sdes			goto invalid;
1612176471Sdes	if (strcmp(name, "stat") == 0) {
1613176471Sdes		if (datalen != sizeof(struct stat))
1614176471Sdes			goto invalid;
1615204045Simp		memcpy(&sb, data, datalen);
1616204045Simp		ktrstat(&sb);
1617176471Sdes	} else if (strcmp(name, "sockaddr") == 0) {
1618204045Simp		if (datalen > sizeof(ss))
1619204045Simp			goto invalid;
1620204045Simp		memcpy(&ss, data, datalen);
1621176471Sdes		if (datalen < sizeof(struct sockaddr) ||
1622204045Simp		    datalen != ss.ss_len)
1623176471Sdes			goto invalid;
1624204045Simp		ktrsockaddr((struct sockaddr *)&ss);
1625176471Sdes	} else {
1626176471Sdes		printf("unknown structure\n");
1627176471Sdes	}
1628176471Sdes	return;
1629176471Sdesinvalid:
1630176471Sdes	printf("invalid record\n");
1631176471Sdes}
1632176471Sdes
1633226269Sdesvoid
1634226269Sdesktrcapfail(struct ktr_cap_fail *ktr)
1635226269Sdes{
1636226495Sdes	switch (ktr->cap_type) {
1637226495Sdes	case CAPFAIL_NOTCAPABLE:
1638226495Sdes		/* operation on fd with insufficient capabilities */
1639226495Sdes		printf("operation requires ");
1640226495Sdes		capname((intmax_t)ktr->cap_needed);
1641226495Sdes		printf(", process holds ");
1642226495Sdes		capname((intmax_t)ktr->cap_held);
1643226495Sdes		break;
1644226495Sdes	case CAPFAIL_INCREASE:
1645226495Sdes		/* requested more capabilities than fd already has */
1646226495Sdes		printf("attempt to increase capabilities from ");
1647226505Sdes		capname((intmax_t)ktr->cap_held);
1648226505Sdes		printf(" to ");
1649226495Sdes		capname((intmax_t)ktr->cap_needed);
1650226495Sdes		break;
1651226495Sdes	case CAPFAIL_SYSCALL:
1652226495Sdes		/* called restricted syscall */
1653226495Sdes		printf("disallowed system call");
1654226495Sdes		break;
1655226495Sdes	case CAPFAIL_LOOKUP:
1656226495Sdes		/* used ".." in strict-relative mode */
1657226495Sdes		printf("restricted VFS lookup");
1658226495Sdes		break;
1659226495Sdes	default:
1660226495Sdes		printf("unknown capability failure: ");
1661226495Sdes		capname((intmax_t)ktr->cap_needed);
1662226495Sdes		printf(" ");
1663226495Sdes		capname((intmax_t)ktr->cap_held);
1664226495Sdes		break;
1665226495Sdes	}
1666233925Sjhb	printf("\n");
1667226269Sdes}
1668226269Sdes
1669233925Sjhbvoid
1670233925Sjhbktrfault(struct ktr_fault *ktr)
1671233925Sjhb{
1672233925Sjhb
1673233925Sjhb	printf("0x%jx ", ktr->vaddr);
1674233925Sjhb	vmprotname(ktr->type);
1675233925Sjhb	printf("\n");
1676233925Sjhb}
1677233925Sjhb
1678233925Sjhbvoid
1679233925Sjhbktrfaultend(struct ktr_faultend *ktr)
1680233925Sjhb{
1681233925Sjhb
1682233925Sjhb	vmresultname(ktr->result);
1683233925Sjhb	printf("\n");
1684233925Sjhb}
1685233925Sjhb
1686219138Sdchagin#if defined(__amd64__) || defined(__i386__)
1687176471Sdesvoid
1688219138Sdchaginlinux_ktrsyscall(struct ktr_syscall *ktr)
1689219138Sdchagin{
1690219138Sdchagin	int narg = ktr->ktr_narg;
1691219138Sdchagin	register_t *ip;
1692219138Sdchagin
1693219138Sdchagin	if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
1694219138Sdchagin		printf("[%d]", ktr->ktr_code);
1695219138Sdchagin	else
1696219138Sdchagin		printf("%s", linux_syscallnames[ktr->ktr_code]);
1697219138Sdchagin	ip = &ktr->ktr_args[0];
1698219138Sdchagin	if (narg) {
1699219138Sdchagin		char c = '(';
1700219138Sdchagin		while (narg > 0)
1701219138Sdchagin			print_number(ip, narg, c);
1702219138Sdchagin		putchar(')');
1703219138Sdchagin	}
1704219138Sdchagin	putchar('\n');
1705219138Sdchagin}
1706219138Sdchagin
1707219138Sdchaginvoid
1708219138Sdchaginlinux_ktrsysret(struct ktr_sysret *ktr)
1709219138Sdchagin{
1710219138Sdchagin	register_t ret = ktr->ktr_retval;
1711219138Sdchagin	int error = ktr->ktr_error;
1712219138Sdchagin	int code = ktr->ktr_code;
1713219138Sdchagin
1714219138Sdchagin	if (code >= nlinux_syscalls || code < 0)
1715219138Sdchagin		printf("[%d] ", code);
1716219138Sdchagin	else
1717219138Sdchagin		printf("%s ", linux_syscallnames[code]);
1718219138Sdchagin
1719219138Sdchagin	if (error == 0) {
1720219138Sdchagin		if (fancy) {
1721219138Sdchagin			printf("%ld", (long)ret);
1722219138Sdchagin			if (ret < 0 || ret > 9)
1723226153Sdes				printf("/%#lx", (unsigned long)ret);
1724219138Sdchagin		} else {
1725219138Sdchagin			if (decimal)
1726219138Sdchagin				printf("%ld", (long)ret);
1727219138Sdchagin			else
1728226153Sdes				printf("%#lx", (unsigned long)ret);
1729219138Sdchagin		}
1730219138Sdchagin	} else if (error == ERESTART)
1731219138Sdchagin		printf("RESTART");
1732219138Sdchagin	else if (error == EJUSTRETURN)
1733219138Sdchagin		printf("JUSTRETURN");
1734219138Sdchagin	else {
1735219138Sdchagin		if (ktr->ktr_error <= ELAST + 1)
1736219138Sdchagin			error = abs(bsd_to_linux_errno[ktr->ktr_error]);
1737219138Sdchagin		else
1738219138Sdchagin			error = 999;
1739219138Sdchagin		printf("-1 errno %d", error);
1740219138Sdchagin		if (fancy)
1741219138Sdchagin			printf(" %s", strerror(ktr->ktr_error));
1742219138Sdchagin	}
1743219138Sdchagin	putchar('\n');
1744219138Sdchagin}
1745219138Sdchagin#endif
1746219138Sdchagin
1747219138Sdchaginvoid
1748100824Sdwmaloneusage(void)
17491590Srgrimes{
1750219043Sdchagin	fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] "
1751177856Sru	    "[-m maxdata] [-p pid] [-t trstr]\n");
17521590Srgrimes	exit(1);
17531590Srgrimes}
1754