kdump.c revision 254922
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 254922 2013-08-26 17:22:51Z jilles $");
431590Srgrimes
4455206Speter#define _KERNEL
452215Scsgrextern int errno;
462215Scsgr#include <sys/errno.h>
4755206Speter#undef _KERNEL
481590Srgrimes#include <sys/param.h>
49251073Spjd#include <sys/capability.h>
501590Srgrimes#include <sys/errno.h>
51100824Sdwmalone#define _KERNEL
521590Srgrimes#include <sys/time.h>
53100824Sdwmalone#undef _KERNEL
541590Srgrimes#include <sys/uio.h>
551590Srgrimes#include <sys/ktrace.h>
561590Srgrimes#include <sys/ioctl.h>
57165758Srodrigc#include <sys/socket.h>
58176471Sdes#include <sys/stat.h>
59219043Sdchagin#include <sys/sysent.h>
60176471Sdes#include <sys/un.h>
61219043Sdchagin#include <sys/queue.h>
62176471Sdes#ifdef IPX
63176471Sdes#include <sys/types.h>
64176471Sdes#include <netipx/ipx.h>
65176471Sdes#endif
66176471Sdes#ifdef NETATALK
67176471Sdes#include <netatalk/at.h>
68176471Sdes#endif
69190168Sdelphij#include <arpa/inet.h>
70176471Sdes#include <netinet/in.h>
71190168Sdelphij#include <ctype.h>
72165916Sjhb#include <dlfcn.h>
7327443Scharnier#include <err.h>
74176471Sdes#include <grp.h>
75176471Sdes#include <inttypes.h>
7627443Scharnier#include <locale.h>
77251486Sae#include <netdb.h>
78251073Spjd#include <nl_types.h>
79176471Sdes#include <pwd.h>
801590Srgrimes#include <stdio.h>
811590Srgrimes#include <stdlib.h>
821590Srgrimes#include <string.h>
83251073Spjd#include <termios.h>
84176471Sdes#include <time.h>
8527443Scharnier#include <unistd.h>
8627443Scharnier#include <vis.h>
871590Srgrimes#include "ktrace.h"
88158766Snetchild#include "kdump_subr.h"
891590Srgrimes
90219043Sdchaginu_int abidump(struct ktr_header *);
91219043Sdchaginint fetchprocinfo(struct ktr_header *, u_int *);
92100824Sdwmaloneint fread_tail(void *, int, int);
93100824Sdwmalonevoid dumpheader(struct ktr_header *);
94219043Sdchaginvoid ktrsyscall(struct ktr_syscall *, u_int);
95219043Sdchaginvoid ktrsysret(struct ktr_sysret *, u_int);
96100824Sdwmalonevoid ktrnamei(char *, int);
97115759Spetervoid hexdump(char *, int, int);
98115759Spetervoid visdump(char *, int, int);
99100824Sdwmalonevoid ktrgenio(struct ktr_genio *, int);
100219138Sdchaginvoid ktrpsig(struct ktr_psig *);
101100824Sdwmalonevoid ktrcsw(struct ktr_csw *);
102234494Sjhbvoid ktrcsw_old(struct ktr_csw_old *);
103226329Sdesvoid ktruser_malloc(unsigned char *);
104226329Sdesvoid ktruser_rtld(int, unsigned char *);
105100824Sdwmalonevoid ktruser(int, unsigned char *);
106176471Sdesvoid ktrsockaddr(struct sockaddr *);
107176471Sdesvoid ktrstat(struct stat *);
108176471Sdesvoid ktrstruct(char *, size_t);
109226269Sdesvoid ktrcapfail(struct ktr_cap_fail *);
110233925Sjhbvoid ktrfault(struct ktr_fault *);
111233925Sjhbvoid ktrfaultend(struct ktr_faultend *);
112251073Spjdvoid limitfd(int fd);
113100824Sdwmalonevoid usage(void);
114226157Sdesvoid ioctlname(unsigned long, int);
115100824Sdwmalone
116176471Sdesint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
117219043Sdchagin    resolv = 0, abiflag = 0;
118100824Sdwmaloneconst char *tracefile = DEF_TRACEFILE;
1191590Srgrimesstruct ktr_header ktr_header;
1201590Srgrimes
121176471Sdes#define TIME_FORMAT	"%b %e %T %Y"
1221590Srgrimes#define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
1231590Srgrimes
124226262Sdes#define print_number(i,n,c) do {					\
125226262Sdes	if (decimal)							\
126226262Sdes		printf("%c%jd", c, (intmax_t)*i);			\
127226262Sdes	else								\
128226262Sdes		printf("%c%#jx", c, (uintmax_t)(u_register_t)*i);	\
129226262Sdes	i++;								\
130226262Sdes	n--;								\
131226262Sdes	c = ',';							\
132226164Sdes} while (0)
133219138Sdchagin
134219138Sdchagin#if defined(__amd64__) || defined(__i386__)
135219138Sdchagin
136219138Sdchaginvoid linux_ktrsyscall(struct ktr_syscall *);
137219138Sdchaginvoid linux_ktrsysret(struct ktr_sysret *);
138219138Sdchaginextern char *linux_syscallnames[];
139219138Sdchaginextern int nlinux_syscalls;
140219138Sdchagin
141219138Sdchagin/*
142219138Sdchagin * from linux.h
143219138Sdchagin * Linux syscalls return negative errno's, we do positive and map them
144219138Sdchagin */
145219138Sdchaginstatic int bsd_to_linux_errno[ELAST + 1] = {
146219138Sdchagin	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
147219138Sdchagin	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
148219138Sdchagin	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
149219138Sdchagin	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
150219138Sdchagin	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
151219138Sdchagin	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
152219138Sdchagin	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
153219138Sdchagin	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
154219138Sdchagin	-6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
155219138Sdchagin	-72, -67, -71
156219138Sdchagin};
157219138Sdchagin#endif
158219138Sdchagin
159219043Sdchaginstruct proc_info
160219043Sdchagin{
161219043Sdchagin	TAILQ_ENTRY(proc_info)	info;
162219043Sdchagin	u_int			sv_flags;
163219043Sdchagin	pid_t			pid;
164219043Sdchagin};
165219043Sdchagin
166219043SdchaginTAILQ_HEAD(trace_procs, proc_info) trace_procs;
167219043Sdchagin
168253456Spjdstatic void
169253456Spjdstrerror_init(void)
170253456Spjd{
171253456Spjd
172253456Spjd	/*
173253456Spjd	 * Cache NLS data before entering capability mode.
174253456Spjd	 * XXXPJD: There should be strerror_init() and strsignal_init() in libc.
175253456Spjd	 */
176253456Spjd	(void)catopen("libc", NL_CAT_LOCALE);
177253456Spjd}
178253456Spjd
179253456Spjdstatic void
180253456Spjdlocaltime_init(void)
181253456Spjd{
182253456Spjd	time_t ltime;
183253456Spjd
184253456Spjd	/*
185253456Spjd	 * Allow localtime(3) to cache /etc/localtime content before entering
186253456Spjd	 * capability mode.
187253456Spjd	 * XXXPJD: There should be localtime_init() in libc.
188253456Spjd	 */
189253456Spjd	(void)time(&ltime);
190253456Spjd	(void)localtime(&ltime);
191253456Spjd}
192253456Spjd
193100824Sdwmaloneint
194100824Sdwmalonemain(int argc, char *argv[])
1951590Srgrimes{
1961590Srgrimes	int ch, ktrlen, size;
197100824Sdwmalone	void *m;
1981590Srgrimes	int trpoints = ALL_POINTS;
199112201Sjhb	int drop_logged;
200115759Speter	pid_t pid = 0;
201219043Sdchagin	u_int sv_flags;
2021590Srgrimes
203226153Sdes	setlocale(LC_CTYPE, "");
20411823Sache
205219043Sdchagin	while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1)
206226153Sdes		switch (ch) {
207219043Sdchagin		case 'A':
208219043Sdchagin			abiflag = 1;
209219043Sdchagin			break;
2101590Srgrimes		case 'f':
2111590Srgrimes			tracefile = optarg;
2121590Srgrimes			break;
2131590Srgrimes		case 'd':
2141590Srgrimes			decimal = 1;
2151590Srgrimes			break;
2161590Srgrimes		case 'l':
2171590Srgrimes			tail = 1;
2181590Srgrimes			break;
2191590Srgrimes		case 'm':
2201590Srgrimes			maxdata = atoi(optarg);
2211590Srgrimes			break;
2221590Srgrimes		case 'n':
2231590Srgrimes			fancy = 0;
2241590Srgrimes			break;
225115759Speter		case 'p':
226115759Speter			pid = atoi(optarg);
227115759Speter			break;
228176471Sdes		case 'r':
229176471Sdes			resolv = 1;
230176471Sdes			break;
231152331Srwatson		case 's':
232152331Srwatson			suppressdata = 1;
233152331Srwatson			break;
234123187Speter		case 'E':
235123187Speter			timestamp = 3;	/* elapsed timestamp */
236123187Speter			break;
237151930Srwatson		case 'H':
238151930Srwatson			threads = 1;
239151930Srwatson			break;
2401590Srgrimes		case 'R':
2411590Srgrimes			timestamp = 2;	/* relative timestamp */
2421590Srgrimes			break;
2431590Srgrimes		case 'T':
2441590Srgrimes			timestamp = 1;
2451590Srgrimes			break;
2461590Srgrimes		case 't':
2471590Srgrimes			trpoints = getpoints(optarg);
24827443Scharnier			if (trpoints < 0)
24927443Scharnier				errx(1, "unknown trace point in %s", optarg);
2501590Srgrimes			break;
2511590Srgrimes		default:
2521590Srgrimes			usage();
2531590Srgrimes		}
2541590Srgrimes
25519853Sfenner	if (argc > optind)
2561590Srgrimes		usage();
2571590Srgrimes
258226153Sdes	m = malloc(size = 1025);
25927443Scharnier	if (m == NULL)
26027443Scharnier		errx(1, "%s", strerror(ENOMEM));
26127443Scharnier	if (!freopen(tracefile, "r", stdin))
26227443Scharnier		err(1, "%s", tracefile);
263251073Spjd
264253456Spjd	strerror_init();
265253456Spjd	localtime_init();
266253456Spjd
267251167Spjd	if (resolv == 0) {
268251167Spjd		if (cap_enter() < 0 && errno != ENOSYS)
269251167Spjd			err(1, "unable to enter capability mode");
270251167Spjd	}
271251073Spjd	limitfd(STDIN_FILENO);
272251073Spjd	limitfd(STDOUT_FILENO);
273251073Spjd	limitfd(STDERR_FILENO);
274251073Spjd
275219043Sdchagin	TAILQ_INIT(&trace_procs);
276112201Sjhb	drop_logged = 0;
2771590Srgrimes	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
278112201Sjhb		if (ktr_header.ktr_type & KTR_DROP) {
279112201Sjhb			ktr_header.ktr_type &= ~KTR_DROP;
280151930Srwatson			if (!drop_logged && threads) {
281226153Sdes				printf(
282203551Sjh				    "%6jd %6jd %-8.*s Events dropped.\n",
283203551Sjh				    (intmax_t)ktr_header.ktr_pid,
284203551Sjh				    ktr_header.ktr_tid > 0 ?
285203551Sjh				    (intmax_t)ktr_header.ktr_tid : 0,
286203551Sjh				    MAXCOMLEN, ktr_header.ktr_comm);
287151930Srwatson				drop_logged = 1;
288151930Srwatson			} else if (!drop_logged) {
289226153Sdes				printf("%6jd %-8.*s Events dropped.\n",
290203551Sjh				    (intmax_t)ktr_header.ktr_pid, MAXCOMLEN,
291112201Sjhb				    ktr_header.ktr_comm);
292112201Sjhb				drop_logged = 1;
293112201Sjhb			}
294112201Sjhb		}
2951590Srgrimes		if (trpoints & (1<<ktr_header.ktr_type))
296236577Sjhb			if (pid == 0 || ktr_header.ktr_pid == pid ||
297236577Sjhb			    ktr_header.ktr_tid == pid)
298115759Speter				dumpheader(&ktr_header);
29927443Scharnier		if ((ktrlen = ktr_header.ktr_len) < 0)
30027443Scharnier			errx(1, "bogus length 0x%x", ktrlen);
3011590Srgrimes		if (ktrlen > size) {
302226153Sdes			m = realloc(m, ktrlen+1);
30327443Scharnier			if (m == NULL)
30427443Scharnier				errx(1, "%s", strerror(ENOMEM));
3051590Srgrimes			size = ktrlen;
3061590Srgrimes		}
30727443Scharnier		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
30827443Scharnier			errx(1, "data too short");
309219043Sdchagin		if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
310219043Sdchagin			continue;
311219043Sdchagin		sv_flags = abidump(&ktr_header);
312236577Sjhb		if (pid && ktr_header.ktr_pid != pid &&
313236577Sjhb		    ktr_header.ktr_tid != pid)
314115759Speter			continue;
3151590Srgrimes		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
3161590Srgrimes			continue;
317112201Sjhb		drop_logged = 0;
3181590Srgrimes		switch (ktr_header.ktr_type) {
3191590Srgrimes		case KTR_SYSCALL:
320219138Sdchagin#if defined(__amd64__) || defined(__i386__)
321219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
322219138Sdchagin				linux_ktrsyscall((struct ktr_syscall *)m);
323219138Sdchagin			else
324219138Sdchagin#endif
325219138Sdchagin				ktrsyscall((struct ktr_syscall *)m, sv_flags);
3261590Srgrimes			break;
3271590Srgrimes		case KTR_SYSRET:
328219138Sdchagin#if defined(__amd64__) || defined(__i386__)
329219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
330219138Sdchagin				linux_ktrsysret((struct ktr_sysret *)m);
331219138Sdchagin			else
332219138Sdchagin#endif
333219138Sdchagin				ktrsysret((struct ktr_sysret *)m, sv_flags);
3341590Srgrimes			break;
3351590Srgrimes		case KTR_NAMEI:
336189707Sjhb		case KTR_SYSCTL:
3371590Srgrimes			ktrnamei(m, ktrlen);
3381590Srgrimes			break;
3391590Srgrimes		case KTR_GENIO:
3401590Srgrimes			ktrgenio((struct ktr_genio *)m, ktrlen);
3411590Srgrimes			break;
3421590Srgrimes		case KTR_PSIG:
343219138Sdchagin			ktrpsig((struct ktr_psig *)m);
3441590Srgrimes			break;
3451590Srgrimes		case KTR_CSW:
346234494Sjhb			if (ktrlen == sizeof(struct ktr_csw_old))
347234494Sjhb				ktrcsw_old((struct ktr_csw_old *)m);
348234494Sjhb			else
349234494Sjhb				ktrcsw((struct ktr_csw *)m);
3501590Srgrimes			break;
35118400Sphk		case KTR_USER:
35218470Sphk			ktruser(ktrlen, m);
35318400Sphk			break;
354176471Sdes		case KTR_STRUCT:
355176471Sdes			ktrstruct(m, ktrlen);
356176471Sdes			break;
357226269Sdes		case KTR_CAPFAIL:
358226269Sdes			ktrcapfail((struct ktr_cap_fail *)m);
359233925Sjhb			break;
360233925Sjhb		case KTR_FAULT:
361233925Sjhb			ktrfault((struct ktr_fault *)m);
362233925Sjhb			break;
363233925Sjhb		case KTR_FAULTEND:
364233925Sjhb			ktrfaultend((struct ktr_faultend *)m);
365233925Sjhb			break;
366112203Sjhb		default:
367112203Sjhb			printf("\n");
368112203Sjhb			break;
3691590Srgrimes		}
3701590Srgrimes		if (tail)
371226153Sdes			fflush(stdout);
3721590Srgrimes	}
373100824Sdwmalone	return 0;
3741590Srgrimes}
3751590Srgrimes
376251073Spjdvoid
377251073Spjdlimitfd(int fd)
378251073Spjd{
379251073Spjd	cap_rights_t rights;
380251073Spjd	unsigned long cmd;
381251073Spjd
382251073Spjd	rights = CAP_FSTAT;
383251073Spjd	cmd = -1;
384251073Spjd
385251073Spjd	switch (fd) {
386251073Spjd	case STDIN_FILENO:
387251073Spjd		rights |= CAP_READ;
388251073Spjd		break;
389251073Spjd	case STDOUT_FILENO:
390251073Spjd		rights |= CAP_IOCTL | CAP_WRITE;
391251073Spjd		cmd = TIOCGETA;	/* required by isatty(3) in printf(3) */
392251073Spjd		break;
393251073Spjd	case STDERR_FILENO:
394251073Spjd		rights |= CAP_WRITE;
395251073Spjd		if (!suppressdata) {
396251073Spjd			rights |= CAP_IOCTL;
397251073Spjd			cmd = TIOCGWINSZ;
398251073Spjd		}
399251073Spjd		break;
400251073Spjd	default:
401251073Spjd		abort();
402251073Spjd	}
403251073Spjd
404251073Spjd	if (cap_rights_limit(fd, rights) < 0 && errno != ENOSYS)
405251073Spjd		err(1, "unable to limit rights for descriptor %d", fd);
406251073Spjd	if (cmd != -1 && cap_ioctls_limit(fd, &cmd, 1) < 0 && errno != ENOSYS)
407251073Spjd		err(1, "unable to limit ioctls for descriptor %d", fd);
408251073Spjd}
409251073Spjd
410100824Sdwmaloneint
411100824Sdwmalonefread_tail(void *buf, int size, int num)
4121590Srgrimes{
4131590Srgrimes	int i;
4141590Srgrimes
4151590Srgrimes	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
416226153Sdes		sleep(1);
4171590Srgrimes		clearerr(stdin);
4181590Srgrimes	}
4191590Srgrimes	return (i);
4201590Srgrimes}
4211590Srgrimes
422219043Sdchaginint
423219043Sdchaginfetchprocinfo(struct ktr_header *kth, u_int *flags)
424219043Sdchagin{
425219043Sdchagin	struct proc_info *pi;
426219043Sdchagin
427219043Sdchagin	switch (kth->ktr_type) {
428219043Sdchagin	case KTR_PROCCTOR:
429219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
430219043Sdchagin			if (pi->pid == kth->ktr_pid) {
431219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
432219043Sdchagin				break;
433219043Sdchagin			}
434219043Sdchagin		}
435219043Sdchagin		pi = malloc(sizeof(struct proc_info));
436219043Sdchagin		if (pi == NULL)
437219043Sdchagin			errx(1, "%s", strerror(ENOMEM));
438219043Sdchagin		pi->sv_flags = *flags;
439219043Sdchagin		pi->pid = kth->ktr_pid;
440219043Sdchagin		TAILQ_INSERT_TAIL(&trace_procs, pi, info);
441219043Sdchagin		return (1);
442219043Sdchagin
443219043Sdchagin	case KTR_PROCDTOR:
444219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
445219043Sdchagin			if (pi->pid == kth->ktr_pid) {
446219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
447219043Sdchagin				free(pi);
448219043Sdchagin				break;
449219043Sdchagin			}
450219043Sdchagin		}
451219043Sdchagin		return (1);
452219043Sdchagin	}
453219043Sdchagin
454219043Sdchagin	return (0);
455219043Sdchagin}
456219043Sdchagin
457219043Sdchaginu_int
458219043Sdchaginabidump(struct ktr_header *kth)
459219043Sdchagin{
460219043Sdchagin	struct proc_info *pi;
461219043Sdchagin	const char *abi;
462219043Sdchagin	const char *arch;
463219043Sdchagin	u_int flags = 0;
464219043Sdchagin
465219043Sdchagin	TAILQ_FOREACH(pi, &trace_procs, info) {
466219043Sdchagin		if (pi->pid == kth->ktr_pid) {
467219043Sdchagin			flags = pi->sv_flags;
468219043Sdchagin			break;
469219043Sdchagin		}
470219043Sdchagin	}
471219043Sdchagin
472219043Sdchagin	if (abiflag == 0)
473219043Sdchagin		return (flags);
474219043Sdchagin
475219043Sdchagin	switch (flags & SV_ABI_MASK) {
476219043Sdchagin	case SV_ABI_LINUX:
477219043Sdchagin		abi = "L";
478219043Sdchagin		break;
479219043Sdchagin	case SV_ABI_FREEBSD:
480219043Sdchagin		abi = "F";
481219043Sdchagin		break;
482219043Sdchagin	default:
483219043Sdchagin		abi = "U";
484219043Sdchagin		break;
485219043Sdchagin	}
486219043Sdchagin
487219043Sdchagin	if (flags != 0) {
488219043Sdchagin		if (flags & SV_LP64)
489219043Sdchagin			arch = "64";
490219043Sdchagin		else
491219043Sdchagin			arch = "32";
492219043Sdchagin	} else
493219043Sdchagin		arch = "00";
494219043Sdchagin
495219043Sdchagin	printf("%s%s  ", abi, arch);
496219043Sdchagin
497219043Sdchagin	return (flags);
498219043Sdchagin}
499219043Sdchagin
500100824Sdwmalonevoid
501100824Sdwmalonedumpheader(struct ktr_header *kth)
5021590Srgrimes{
5031590Srgrimes	static char unknown[64];
5041590Srgrimes	static struct timeval prevtime, temp;
505100824Sdwmalone	const char *type;
5061590Srgrimes
5071590Srgrimes	switch (kth->ktr_type) {
5081590Srgrimes	case KTR_SYSCALL:
5091590Srgrimes		type = "CALL";
5101590Srgrimes		break;
5111590Srgrimes	case KTR_SYSRET:
5121590Srgrimes		type = "RET ";
5131590Srgrimes		break;
5141590Srgrimes	case KTR_NAMEI:
5151590Srgrimes		type = "NAMI";
5161590Srgrimes		break;
5171590Srgrimes	case KTR_GENIO:
5181590Srgrimes		type = "GIO ";
5191590Srgrimes		break;
5201590Srgrimes	case KTR_PSIG:
5211590Srgrimes		type = "PSIG";
5221590Srgrimes		break;
5231590Srgrimes	case KTR_CSW:
524171333Sjhb		type = "CSW ";
5251590Srgrimes		break;
52618400Sphk	case KTR_USER:
52718400Sphk		type = "USER";
52818400Sphk		break;
529176471Sdes	case KTR_STRUCT:
530176471Sdes		type = "STRU";
531176471Sdes		break;
532189707Sjhb	case KTR_SYSCTL:
533189707Sjhb		type = "SCTL";
534189707Sjhb		break;
535219043Sdchagin	case KTR_PROCCTOR:
536219043Sdchagin		/* FALLTHROUGH */
537219043Sdchagin	case KTR_PROCDTOR:
538219043Sdchagin		return;
539226269Sdes	case KTR_CAPFAIL:
540226269Sdes		type = "CAP ";
541226269Sdes		break;
542233925Sjhb	case KTR_FAULT:
543233925Sjhb		type = "PFLT";
544233925Sjhb		break;
545233925Sjhb	case KTR_FAULTEND:
546233925Sjhb		type = "PRET";
547233925Sjhb		break;
5481590Srgrimes	default:
549226153Sdes		sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
5501590Srgrimes		type = unknown;
5511590Srgrimes	}
5521590Srgrimes
553151930Srwatson	/*
554151930Srwatson	 * The ktr_tid field was previously the ktr_buffer field, which held
555151930Srwatson	 * the kernel pointer value for the buffer associated with data
556151930Srwatson	 * following the record header.  It now holds a threadid, but only
557151930Srwatson	 * for trace files after the change.  Older trace files still contain
558151930Srwatson	 * kernel pointers.  Detect this and suppress the results by printing
559151930Srwatson	 * negative tid's as 0.
560151930Srwatson	 */
561151930Srwatson	if (threads)
562226153Sdes		printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid,
563203551Sjh		    kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0,
564203551Sjh		    MAXCOMLEN, kth->ktr_comm);
565151930Srwatson	else
566226153Sdes		printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN,
567151930Srwatson		    kth->ktr_comm);
5681590Srgrimes	if (timestamp) {
569123187Speter		if (timestamp == 3) {
570123187Speter			if (prevtime.tv_sec == 0)
571123187Speter				prevtime = kth->ktr_time;
572123187Speter			timevalsub(&kth->ktr_time, &prevtime);
573123187Speter		}
5741590Srgrimes		if (timestamp == 2) {
5751590Srgrimes			temp = kth->ktr_time;
5761590Srgrimes			timevalsub(&kth->ktr_time, &prevtime);
5771590Srgrimes			prevtime = temp;
5781590Srgrimes		}
579226153Sdes		printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
580203551Sjh		    kth->ktr_time.tv_usec);
5811590Srgrimes	}
582226153Sdes	printf("%s  ", type);
5831590Srgrimes}
5841590Srgrimes
5851590Srgrimes#include <sys/syscall.h>
5861590Srgrimes#define KTRACE
5874721Sphk#include <sys/kern/syscalls.c>
5881590Srgrimes#undef KTRACE
5891590Srgrimesint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
5901590Srgrimes
591100824Sdwmalonevoid
592219043Sdchaginktrsyscall(struct ktr_syscall *ktr, u_int flags)
5931590Srgrimes{
594100824Sdwmalone	int narg = ktr->ktr_narg;
595100824Sdwmalone	register_t *ip;
596226269Sdes	intmax_t arg;
5971590Srgrimes
598219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
599219043Sdchagin	    (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
600226153Sdes		printf("[%d]", ktr->ktr_code);
6011590Srgrimes	else
602226153Sdes		printf("%s", syscallnames[ktr->ktr_code]);
60347957Sdt	ip = &ktr->ktr_args[0];
6041590Srgrimes	if (narg) {
6051590Srgrimes		char c = '(';
606219043Sdchagin		if (fancy &&
607219043Sdchagin		    (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
608226148Sdes			switch (ktr->ktr_code) {
609254296Sjilles			case SYS_bindat:
610254296Sjilles			case SYS_connectat:
611254291Sjilles			case SYS_faccessat:
612254291Sjilles			case SYS_fchmodat:
613254291Sjilles			case SYS_fchownat:
614254291Sjilles			case SYS_fstatat:
615254291Sjilles			case SYS_futimesat:
616254291Sjilles			case SYS_linkat:
617254291Sjilles			case SYS_mkdirat:
618254291Sjilles			case SYS_mkfifoat:
619254291Sjilles			case SYS_mknodat:
620254291Sjilles			case SYS_openat:
621254291Sjilles			case SYS_readlinkat:
622254291Sjilles			case SYS_renameat:
623254291Sjilles			case SYS_unlinkat:
624254291Sjilles				putchar('(');
625254291Sjilles				atfdname(*ip, decimal);
626254291Sjilles				c = ',';
627254291Sjilles				ip++;
628254291Sjilles				narg--;
629254291Sjilles				break;
630254291Sjilles			}
631254291Sjilles			switch (ktr->ktr_code) {
632226148Sdes			case SYS_ioctl: {
633226150Sdes				print_number(ip, narg, c);
634226157Sdes				putchar(c);
635226157Sdes				ioctlname(*ip, decimal);
6361590Srgrimes				c = ',';
6371590Srgrimes				ip++;
6381590Srgrimes				narg--;
639226148Sdes				break;
640226148Sdes			}
641226148Sdes			case SYS_ptrace:
642226153Sdes				putchar('(');
643226164Sdes				ptraceopname(*ip);
6441590Srgrimes				c = ',';
6451590Srgrimes				ip++;
6461590Srgrimes				narg--;
647226148Sdes				break;
648226148Sdes			case SYS_access:
649226148Sdes			case SYS_eaccess:
650254291Sjilles			case SYS_faccessat:
651226150Sdes				print_number(ip, narg, c);
652226153Sdes				putchar(',');
653226164Sdes				accessmodename(*ip);
654158766Snetchild				ip++;
655158766Snetchild				narg--;
656226148Sdes				break;
657226148Sdes			case SYS_open:
658254291Sjilles			case SYS_openat:
659226150Sdes				print_number(ip, narg, c);
660226153Sdes				putchar(',');
661226164Sdes				flagsandmodename(ip[0], ip[1], decimal);
662226148Sdes				ip += 2;
663226148Sdes				narg -= 2;
664226148Sdes				break;
665226148Sdes			case SYS_wait4:
666226150Sdes				print_number(ip, narg, c);
667226150Sdes				print_number(ip, narg, c);
668226153Sdes				putchar(',');
669226164Sdes				wait4optname(*ip);
670158766Snetchild				ip++;
671158766Snetchild				narg--;
672226148Sdes				break;
673226148Sdes			case SYS_chmod:
674226148Sdes			case SYS_fchmod:
675226148Sdes			case SYS_lchmod:
676226150Sdes				print_number(ip, narg, c);
677226153Sdes				putchar(',');
678226164Sdes				modename(*ip);
679158766Snetchild				ip++;
680158766Snetchild				narg--;
681226148Sdes				break;
682226148Sdes			case SYS_mknod:
683254291Sjilles			case SYS_mknodat:
684226150Sdes				print_number(ip, narg, c);
685226153Sdes				putchar(',');
686226164Sdes				modename(*ip);
687158766Snetchild				ip++;
688158766Snetchild				narg--;
689226148Sdes				break;
690226148Sdes			case SYS_getfsstat:
691226150Sdes				print_number(ip, narg, c);
692226150Sdes				print_number(ip, narg, c);
693226153Sdes				putchar(',');
694226164Sdes				getfsstatflagsname(*ip);
695158766Snetchild				ip++;
696158766Snetchild				narg--;
697226148Sdes				break;
698226148Sdes			case SYS_mount:
699226150Sdes				print_number(ip, narg, c);
700226150Sdes				print_number(ip, narg, c);
701226153Sdes				putchar(',');
702226164Sdes				mountflagsname(*ip);
703158766Snetchild				ip++;
704158766Snetchild				narg--;
705226148Sdes				break;
706226148Sdes			case SYS_unmount:
707226150Sdes				print_number(ip, narg, c);
708226153Sdes				putchar(',');
709226164Sdes				mountflagsname(*ip);
710158766Snetchild				ip++;
711158766Snetchild				narg--;
712226148Sdes				break;
713226148Sdes			case SYS_recvmsg:
714226148Sdes			case SYS_sendmsg:
715226150Sdes				print_number(ip, narg, c);
716226150Sdes				print_number(ip, narg, c);
717226153Sdes				putchar(',');
718226164Sdes				sendrecvflagsname(*ip);
719158766Snetchild				ip++;
720158766Snetchild				narg--;
721226148Sdes				break;
722226148Sdes			case SYS_recvfrom:
723226148Sdes			case SYS_sendto:
724226150Sdes				print_number(ip, narg, c);
725226150Sdes				print_number(ip, narg, c);
726226150Sdes				print_number(ip, narg, c);
727226153Sdes				putchar(',');
728226164Sdes				sendrecvflagsname(*ip);
729158766Snetchild				ip++;
730158766Snetchild				narg--;
731226148Sdes				break;
732226148Sdes			case SYS_chflags:
733226148Sdes			case SYS_fchflags:
734226148Sdes			case SYS_lchflags:
735226150Sdes				print_number(ip, narg, c);
736226153Sdes				putchar(',');
737226164Sdes				modename(*ip);
738158766Snetchild				ip++;
739158766Snetchild				narg--;
740226148Sdes				break;
741226148Sdes			case SYS_kill:
742226150Sdes				print_number(ip, narg, c);
743226153Sdes				putchar(',');
744226164Sdes				signame(*ip);
745158766Snetchild				ip++;
746158766Snetchild				narg--;
747226148Sdes				break;
748226148Sdes			case SYS_reboot:
749226153Sdes				putchar('(');
750226164Sdes				rebootoptname(*ip);
751158766Snetchild				ip++;
752158766Snetchild				narg--;
753226148Sdes				break;
754226148Sdes			case SYS_umask:
755226153Sdes				putchar('(');
756226164Sdes				modename(*ip);
757158766Snetchild				ip++;
758158766Snetchild				narg--;
759226148Sdes				break;
760226148Sdes			case SYS_msync:
761226150Sdes				print_number(ip, narg, c);
762226150Sdes				print_number(ip, narg, c);
763226153Sdes				putchar(',');
764226164Sdes				msyncflagsname(*ip);
765158766Snetchild				ip++;
766158766Snetchild				narg--;
767226148Sdes				break;
768171221Speter#ifdef SYS_freebsd6_mmap
769226148Sdes			case SYS_freebsd6_mmap:
770226150Sdes				print_number(ip, narg, c);
771226150Sdes				print_number(ip, narg, c);
772226153Sdes				putchar(',');
773226164Sdes				mmapprotname(*ip);
774226153Sdes				putchar(',');
775171221Speter				ip++;
776171221Speter				narg--;
777226164Sdes				mmapflagsname(*ip);
778171221Speter				ip++;
779171221Speter				narg--;
780226148Sdes				break;
781171221Speter#endif
782226148Sdes			case SYS_mmap:
783226150Sdes				print_number(ip, narg, c);
784226150Sdes				print_number(ip, narg, c);
785226153Sdes				putchar(',');
786226164Sdes				mmapprotname(*ip);
787226153Sdes				putchar(',');
788158766Snetchild				ip++;
789158766Snetchild				narg--;
790226164Sdes				mmapflagsname(*ip);
791158766Snetchild				ip++;
792158766Snetchild				narg--;
793226148Sdes				break;
794226148Sdes			case SYS_mprotect:
795226150Sdes				print_number(ip, narg, c);
796226150Sdes				print_number(ip, narg, c);
797226153Sdes				putchar(',');
798226164Sdes				mmapprotname(*ip);
799158766Snetchild				ip++;
800158766Snetchild				narg--;
801226148Sdes				break;
802226148Sdes			case SYS_madvise:
803226150Sdes				print_number(ip, narg, c);
804226150Sdes				print_number(ip, narg, c);
805226153Sdes				putchar(',');
806226164Sdes				madvisebehavname(*ip);
807158766Snetchild				ip++;
808158766Snetchild				narg--;
809226148Sdes				break;
810226148Sdes			case SYS_setpriority:
811226150Sdes				print_number(ip, narg, c);
812226150Sdes				print_number(ip, narg, c);
813226153Sdes				putchar(',');
814226164Sdes				prioname(*ip);
815158766Snetchild				ip++;
816158766Snetchild				narg--;
817226148Sdes				break;
818226148Sdes			case SYS_fcntl:
819226150Sdes				print_number(ip, narg, c);
820226153Sdes				putchar(',');
821226164Sdes				fcntlcmdname(ip[0], ip[1], decimal);
822226148Sdes				ip += 2;
823226148Sdes				narg -= 2;
824226148Sdes				break;
825226148Sdes			case SYS_socket: {
826165758Srodrigc				int sockdomain;
827226153Sdes				putchar('(');
828226164Sdes				sockdomain = *ip;
829165758Srodrigc				sockdomainname(sockdomain);
830158766Snetchild				ip++;
831158766Snetchild				narg--;
832226153Sdes				putchar(',');
833254922Sjilles				socktypenamewithflags(*ip);
834158766Snetchild				ip++;
835158766Snetchild				narg--;
836165758Srodrigc				if (sockdomain == PF_INET ||
837165758Srodrigc				    sockdomain == PF_INET6) {
838226153Sdes					putchar(',');
839226164Sdes					sockipprotoname(*ip);
840165758Srodrigc					ip++;
841165758Srodrigc					narg--;
842165758Srodrigc				}
843158766Snetchild				c = ',';
844226148Sdes				break;
845226148Sdes			}
846226148Sdes			case SYS_setsockopt:
847226148Sdes			case SYS_getsockopt:
848226150Sdes				print_number(ip, narg, c);
849226153Sdes				putchar(',');
850226164Sdes				sockoptlevelname(*ip, decimal);
851226151Sdes				if (*ip == SOL_SOCKET) {
852175138Sjhb					ip++;
853175138Sjhb					narg--;
854226153Sdes					putchar(',');
855226164Sdes					sockoptname(*ip);
856175138Sjhb				}
857158766Snetchild				ip++;
858158766Snetchild				narg--;
859226148Sdes				break;
860171221Speter#ifdef SYS_freebsd6_lseek
861226148Sdes			case SYS_freebsd6_lseek:
862226150Sdes				print_number(ip, narg, c);
863158766Snetchild				/* Hidden 'pad' argument, not in lseek(2) */
864226150Sdes				print_number(ip, narg, c);
865226150Sdes				print_number(ip, narg, c);
866226153Sdes				putchar(',');
867226164Sdes				whencename(*ip);
868158766Snetchild				ip++;
869158766Snetchild				narg--;
870226148Sdes				break;
871171221Speter#endif
872226148Sdes			case SYS_lseek:
873226150Sdes				print_number(ip, narg, c);
874171221Speter				/* Hidden 'pad' argument, not in lseek(2) */
875226150Sdes				print_number(ip, narg, c);
876226153Sdes				putchar(',');
877226164Sdes				whencename(*ip);
878171221Speter				ip++;
879171221Speter				narg--;
880226148Sdes				break;
881226148Sdes			case SYS_flock:
882226150Sdes				print_number(ip, narg, c);
883226153Sdes				putchar(',');
884226164Sdes				flockname(*ip);
885158766Snetchild				ip++;
886158766Snetchild				narg--;
887226148Sdes				break;
888226148Sdes			case SYS_mkfifo:
889254291Sjilles			case SYS_mkfifoat:
890226148Sdes			case SYS_mkdir:
891254291Sjilles			case SYS_mkdirat:
892226150Sdes				print_number(ip, narg, c);
893226153Sdes				putchar(',');
894226164Sdes				modename(*ip);
895158766Snetchild				ip++;
896158766Snetchild				narg--;
897226148Sdes				break;
898226148Sdes			case SYS_shutdown:
899226150Sdes				print_number(ip, narg, c);
900226153Sdes				putchar(',');
901226164Sdes				shutdownhowname(*ip);
902158766Snetchild				ip++;
903158766Snetchild				narg--;
904226148Sdes				break;
905226148Sdes			case SYS_socketpair:
906226153Sdes				putchar('(');
907226164Sdes				sockdomainname(*ip);
908158766Snetchild				ip++;
909158766Snetchild				narg--;
910226153Sdes				putchar(',');
911254922Sjilles				socktypenamewithflags(*ip);
912158766Snetchild				ip++;
913158766Snetchild				narg--;
914158766Snetchild				c = ',';
915226148Sdes				break;
916226148Sdes			case SYS_getrlimit:
917226148Sdes			case SYS_setrlimit:
918226153Sdes				putchar('(');
919226164Sdes				rlimitname(*ip);
920158766Snetchild				ip++;
921158766Snetchild				narg--;
922158766Snetchild				c = ',';
923226148Sdes				break;
924226148Sdes			case SYS_quotactl:
925226150Sdes				print_number(ip, narg, c);
926226153Sdes				putchar(',');
927226164Sdes				quotactlname(*ip);
928158766Snetchild				ip++;
929158766Snetchild				narg--;
930158766Snetchild				c = ',';
931226148Sdes				break;
932226148Sdes			case SYS_nfssvc:
933226153Sdes				putchar('(');
934226164Sdes				nfssvcname(*ip);
935158766Snetchild				ip++;
936158766Snetchild				narg--;
937158766Snetchild				c = ',';
938226148Sdes				break;
939226148Sdes			case SYS_rtprio:
940226153Sdes				putchar('(');
941226164Sdes				rtprioname(*ip);
942158766Snetchild				ip++;
943158766Snetchild				narg--;
944158766Snetchild				c = ',';
945226148Sdes				break;
946226148Sdes			case SYS___semctl:
947226150Sdes				print_number(ip, narg, c);
948226150Sdes				print_number(ip, narg, c);
949226153Sdes				putchar(',');
950226164Sdes				semctlname(*ip);
951158766Snetchild				ip++;
952158766Snetchild				narg--;
953226148Sdes				break;
954226148Sdes			case SYS_semget:
955226150Sdes				print_number(ip, narg, c);
956226150Sdes				print_number(ip, narg, c);
957226153Sdes				putchar(',');
958226164Sdes				semgetname(*ip);
959158766Snetchild				ip++;
960158766Snetchild				narg--;
961226148Sdes				break;
962226148Sdes			case SYS_msgctl:
963226150Sdes				print_number(ip, narg, c);
964226153Sdes				putchar(',');
965226164Sdes				shmctlname(*ip);
966158766Snetchild				ip++;
967158766Snetchild				narg--;
968226148Sdes				break;
969226148Sdes			case SYS_shmat:
970226150Sdes				print_number(ip, narg, c);
971226150Sdes				print_number(ip, narg, c);
972226153Sdes				putchar(',');
973226164Sdes				shmatname(*ip);
974158766Snetchild				ip++;
975158766Snetchild				narg--;
976226148Sdes				break;
977226148Sdes			case SYS_shmctl:
978226150Sdes				print_number(ip, narg, c);
979226153Sdes				putchar(',');
980226164Sdes				shmctlname(*ip);
981158766Snetchild				ip++;
982158766Snetchild				narg--;
983226148Sdes				break;
984226148Sdes			case SYS_minherit:
985226150Sdes				print_number(ip, narg, c);
986226150Sdes				print_number(ip, narg, c);
987226153Sdes				putchar(',');
988226164Sdes				minheritname(*ip);
989158766Snetchild				ip++;
990158766Snetchild				narg--;
991226148Sdes				break;
992226148Sdes			case SYS_rfork:
993226153Sdes				putchar('(');
994226164Sdes				rforkname(*ip);
995158766Snetchild				ip++;
996158766Snetchild				narg--;
997158766Snetchild				c = ',';
998226148Sdes				break;
999226148Sdes			case SYS_lio_listio:
1000226153Sdes				putchar('(');
1001226164Sdes				lio_listioname(*ip);
1002158766Snetchild				ip++;
1003158766Snetchild				narg--;
1004158766Snetchild				c = ',';
1005226148Sdes				break;
1006226148Sdes			case SYS_mlockall:
1007226153Sdes				putchar('(');
1008226164Sdes				mlockallname(*ip);
1009158766Snetchild				ip++;
1010158766Snetchild				narg--;
1011226148Sdes				break;
1012226148Sdes			case SYS_sched_setscheduler:
1013226150Sdes				print_number(ip, narg, c);
1014226153Sdes				putchar(',');
1015226164Sdes				schedpolicyname(*ip);
1016158766Snetchild				ip++;
1017158766Snetchild				narg--;
1018226148Sdes				break;
1019226148Sdes			case SYS_sched_get_priority_max:
1020226148Sdes			case SYS_sched_get_priority_min:
1021226153Sdes				putchar('(');
1022226164Sdes				schedpolicyname(*ip);
1023158766Snetchild				ip++;
1024158766Snetchild				narg--;
1025226148Sdes				break;
1026226148Sdes			case SYS_sendfile:
1027226150Sdes				print_number(ip, narg, c);
1028226150Sdes				print_number(ip, narg, c);
1029226150Sdes				print_number(ip, narg, c);
1030226150Sdes				print_number(ip, narg, c);
1031226150Sdes				print_number(ip, narg, c);
1032226150Sdes				print_number(ip, narg, c);
1033226153Sdes				putchar(',');
1034226164Sdes				sendfileflagsname(*ip);
1035158766Snetchild				ip++;
1036158766Snetchild				narg--;
1037226148Sdes				break;
1038226148Sdes			case SYS_kldsym:
1039226150Sdes				print_number(ip, narg, c);
1040226153Sdes				putchar(',');
1041226164Sdes				kldsymcmdname(*ip);
1042158766Snetchild				ip++;
1043158766Snetchild				narg--;
1044226148Sdes				break;
1045226148Sdes			case SYS_sigprocmask:
1046226153Sdes				putchar('(');
1047226164Sdes				sigprocmaskhowname(*ip);
1048158766Snetchild				ip++;
1049158766Snetchild				narg--;
1050158766Snetchild				c = ',';
1051226148Sdes				break;
1052226148Sdes			case SYS___acl_get_file:
1053226148Sdes			case SYS___acl_set_file:
1054226148Sdes			case SYS___acl_get_fd:
1055226148Sdes			case SYS___acl_set_fd:
1056226148Sdes			case SYS___acl_delete_file:
1057226148Sdes			case SYS___acl_delete_fd:
1058226148Sdes			case SYS___acl_aclcheck_file:
1059226148Sdes			case SYS___acl_aclcheck_fd:
1060226148Sdes			case SYS___acl_get_link:
1061226148Sdes			case SYS___acl_set_link:
1062226148Sdes			case SYS___acl_delete_link:
1063226148Sdes			case SYS___acl_aclcheck_link:
1064226150Sdes				print_number(ip, narg, c);
1065226153Sdes				putchar(',');
1066226164Sdes				acltypename(*ip);
1067158766Snetchild				ip++;
1068158766Snetchild				narg--;
1069226148Sdes				break;
1070226148Sdes			case SYS_sigaction:
1071226153Sdes				putchar('(');
1072226164Sdes				signame(*ip);
1073158766Snetchild				ip++;
1074158766Snetchild				narg--;
1075158766Snetchild				c = ',';
1076226148Sdes				break;
1077226148Sdes			case SYS_extattrctl:
1078226150Sdes				print_number(ip, narg, c);
1079226153Sdes				putchar(',');
1080226164Sdes				extattrctlname(*ip);
1081158766Snetchild				ip++;
1082158766Snetchild				narg--;
1083226148Sdes				break;
1084226148Sdes			case SYS_nmount:
1085226150Sdes				print_number(ip, narg, c);
1086226150Sdes				print_number(ip, narg, c);
1087226153Sdes				putchar(',');
1088226164Sdes				mountflagsname(*ip);
1089158766Snetchild				ip++;
1090158766Snetchild				narg--;
1091226148Sdes				break;
1092226148Sdes			case SYS_thr_create:
1093226150Sdes				print_number(ip, narg, c);
1094226150Sdes				print_number(ip, narg, c);
1095226153Sdes				putchar(',');
1096226164Sdes				thrcreateflagsname(*ip);
1097158766Snetchild				ip++;
1098158766Snetchild				narg--;
1099226148Sdes				break;
1100226148Sdes			case SYS_thr_kill:
1101226150Sdes				print_number(ip, narg, c);
1102226153Sdes				putchar(',');
1103226164Sdes				signame(*ip);
1104158766Snetchild				ip++;
1105158766Snetchild				narg--;
1106226148Sdes				break;
1107226148Sdes			case SYS_kldunloadf:
1108226150Sdes				print_number(ip, narg, c);
1109226153Sdes				putchar(',');
1110226164Sdes				kldunloadfflagsname(*ip);
1111158766Snetchild				ip++;
1112158766Snetchild				narg--;
1113226148Sdes				break;
1114254291Sjilles			case SYS_linkat:
1115254291Sjilles			case SYS_renameat:
1116254291Sjilles			case SYS_symlinkat:
1117254291Sjilles				print_number(ip, narg, c);
1118254291Sjilles				putchar(',');
1119254291Sjilles				atfdname(*ip, decimal);
1120254291Sjilles				ip++;
1121254291Sjilles				narg--;
1122254291Sjilles				break;
1123226269Sdes			case SYS_cap_new:
1124247602Spjd			case SYS_cap_rights_limit:
1125226269Sdes				print_number(ip, narg, c);
1126226269Sdes				putchar(',');
1127226269Sdes				arg = *ip;
1128226269Sdes				ip++;
1129226269Sdes				narg--;
1130226269Sdes				/*
1131226269Sdes				 * Hack: the second argument is a
1132226269Sdes				 * cap_rights_t, which 64 bits wide, so on
1133226269Sdes				 * 32-bit systems, it is split between two
1134226269Sdes				 * registers.
1135226269Sdes				 *
1136226269Sdes				 * Since sizeof() is not evaluated by the
1137226269Sdes				 * preprocessor, we can't use an #ifdef,
1138226269Sdes				 * but the compiler will probably optimize
1139226269Sdes				 * the code out anyway.
1140226269Sdes				 */
1141226269Sdes				if (sizeof(cap_rights_t) > sizeof(register_t)) {
1142226269Sdes#if _BYTE_ORDER == _LITTLE_ENDIAN
1143226269Sdes					arg = ((intmax_t)*ip << 32) + arg;
1144226269Sdes#else
1145226269Sdes					arg = (arg << 32) + *ip;
1146226269Sdes#endif
1147226269Sdes					ip++;
1148226269Sdes					narg--;
1149226269Sdes				}
1150226269Sdes				capname(arg);
1151226159Sdes				break;
1152247602Spjd			case SYS_cap_fcntls_limit:
1153247602Spjd				print_number(ip, narg, c);
1154247602Spjd				putchar(',');
1155247602Spjd				arg = *ip;
1156247602Spjd				ip++;
1157247602Spjd				narg--;
1158247602Spjd				capfcntlname(arg);
1159247602Spjd				break;
1160232072Sjhb			case SYS_posix_fadvise:
1161232128Sjhb				print_number(ip, narg, c);
1162232128Sjhb				print_number(ip, narg, c);
1163232128Sjhb				print_number(ip, narg, c);
1164232072Sjhb				(void)putchar(',');
1165232072Sjhb				fadvisebehavname((int)*ip);
1166232072Sjhb				ip++;
1167232072Sjhb				narg--;
1168232072Sjhb				break;
11691590Srgrimes			}
11701590Srgrimes		}
1171199024Sattilio		while (narg > 0) {
1172226150Sdes			print_number(ip, narg, c);
11731590Srgrimes		}
1174226153Sdes		putchar(')');
11751590Srgrimes	}
1176226153Sdes	putchar('\n');
11771590Srgrimes}
11781590Srgrimes
1179100824Sdwmalonevoid
1180219043Sdchaginktrsysret(struct ktr_sysret *ktr, u_int flags)
11811590Srgrimes{
1182100824Sdwmalone	register_t ret = ktr->ktr_retval;
1183100824Sdwmalone	int error = ktr->ktr_error;
1184100824Sdwmalone	int code = ktr->ktr_code;
11851590Srgrimes
1186219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
1187219043Sdchagin	    (code >= nsyscalls || code < 0))
1188226153Sdes		printf("[%d] ", code);
11891590Srgrimes	else
1190226153Sdes		printf("%s ", syscallnames[code]);
11911590Srgrimes
11921590Srgrimes	if (error == 0) {
11931590Srgrimes		if (fancy) {
1194226153Sdes			printf("%ld", (long)ret);
11951590Srgrimes			if (ret < 0 || ret > 9)
1196226153Sdes				printf("/%#lx", (unsigned long)ret);
11971590Srgrimes		} else {
11981590Srgrimes			if (decimal)
1199226153Sdes				printf("%ld", (long)ret);
12001590Srgrimes			else
1201226153Sdes				printf("%#lx", (unsigned long)ret);
12021590Srgrimes		}
12031590Srgrimes	} else if (error == ERESTART)
1204226153Sdes		printf("RESTART");
12051590Srgrimes	else if (error == EJUSTRETURN)
1206226153Sdes		printf("JUSTRETURN");
12071590Srgrimes	else {
1208226153Sdes		printf("-1 errno %d", ktr->ktr_error);
12091590Srgrimes		if (fancy)
1210226153Sdes			printf(" %s", strerror(ktr->ktr_error));
12111590Srgrimes	}
1212226153Sdes	putchar('\n');
12131590Srgrimes}
12141590Srgrimes
1215100824Sdwmalonevoid
1216100824Sdwmalonektrnamei(char *cp, int len)
12171590Srgrimes{
1218226153Sdes	printf("\"%.*s\"\n", len, cp);
12191590Srgrimes}
12201590Srgrimes
1221100824Sdwmalonevoid
1222115759Speterhexdump(char *p, int len, int screenwidth)
12231590Srgrimes{
1224115759Speter	int n, i;
1225115759Speter	int width;
1226115759Speter
1227115759Speter	width = 0;
1228115759Speter	do {
1229115759Speter		width += 2;
1230115759Speter		i = 13;			/* base offset */
1231115759Speter		i += (width / 2) + 1;	/* spaces every second byte */
1232115759Speter		i += (width * 2);	/* width of bytes */
1233115759Speter		i += 3;			/* "  |" */
1234115759Speter		i += width;		/* each byte */
1235115759Speter		i += 1;			/* "|" */
1236115759Speter	} while (i < screenwidth);
1237115759Speter	width -= 2;
1238115759Speter
1239115759Speter	for (n = 0; n < len; n += width) {
1240115759Speter		for (i = n; i < n + width; i++) {
1241115759Speter			if ((i % width) == 0) {	/* beginning of line */
1242115759Speter				printf("       0x%04x", i);
1243115759Speter			}
1244115759Speter			if ((i % 2) == 0) {
1245115759Speter				printf(" ");
1246115759Speter			}
1247115759Speter			if (i < len)
1248115759Speter				printf("%02x", p[i] & 0xff);
1249115759Speter			else
1250115759Speter				printf("  ");
1251115759Speter		}
1252115759Speter		printf("  |");
1253115759Speter		for (i = n; i < n + width; i++) {
1254115759Speter			if (i >= len)
1255115759Speter				break;
1256115759Speter			if (p[i] >= ' ' && p[i] <= '~')
1257115759Speter				printf("%c", p[i]);
1258115759Speter			else
1259115759Speter				printf(".");
1260115759Speter		}
1261115759Speter		printf("|\n");
1262115759Speter	}
1263115759Speter	if ((i % width) != 0)
1264115759Speter		printf("\n");
1265115759Speter}
1266115759Speter
1267115759Spetervoid
1268115759Spetervisdump(char *dp, int datalen, int screenwidth)
1269115759Speter{
1270115759Speter	int col = 0;
1271100824Sdwmalone	char *cp;
1272100824Sdwmalone	int width;
12731590Srgrimes	char visbuf[5];
12741590Srgrimes
1275226153Sdes	printf("       \"");
12761590Srgrimes	col = 8;
12771590Srgrimes	for (;datalen > 0; datalen--, dp++) {
1278226153Sdes		 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
12791590Srgrimes		cp = visbuf;
12801590Srgrimes		/*
12811590Srgrimes		 * Keep track of printables and
12821590Srgrimes		 * space chars (like fold(1)).
12831590Srgrimes		 */
12841590Srgrimes		if (col == 0) {
1285226153Sdes			putchar('\t');
12861590Srgrimes			col = 8;
12871590Srgrimes		}
12881590Srgrimes		switch(*cp) {
12891590Srgrimes		case '\n':
12901590Srgrimes			col = 0;
1291226153Sdes			putchar('\n');
12921590Srgrimes			continue;
12931590Srgrimes		case '\t':
12941590Srgrimes			width = 8 - (col&07);
12951590Srgrimes			break;
12961590Srgrimes		default:
12971590Srgrimes			width = strlen(cp);
12981590Srgrimes		}
12991590Srgrimes		if (col + width > (screenwidth-2)) {
1300226153Sdes			printf("\\\n\t");
13011590Srgrimes			col = 8;
13021590Srgrimes		}
13031590Srgrimes		col += width;
13041590Srgrimes		do {
1305226153Sdes			putchar(*cp++);
13061590Srgrimes		} while (*cp);
13071590Srgrimes	}
13081590Srgrimes	if (col == 0)
1309226153Sdes		printf("       ");
1310226153Sdes	printf("\"\n");
13111590Srgrimes}
13121590Srgrimes
1313115759Spetervoid
1314115759Speterktrgenio(struct ktr_genio *ktr, int len)
1315115759Speter{
1316115759Speter	int datalen = len - sizeof (struct ktr_genio);
1317115759Speter	char *dp = (char *)ktr + sizeof (struct ktr_genio);
1318115759Speter	static int screenwidth = 0;
1319115759Speter	int i, binary;
1320115759Speter
1321251072Spjd	printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1322251072Spjd		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1323251072Spjd		datalen == 1 ? "" : "s");
1324251072Spjd	if (suppressdata)
1325251072Spjd		return;
1326115759Speter	if (screenwidth == 0) {
1327115759Speter		struct winsize ws;
1328115759Speter
1329115759Speter		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1330115759Speter		    ws.ws_col > 8)
1331115759Speter			screenwidth = ws.ws_col;
1332115759Speter		else
1333115759Speter			screenwidth = 80;
1334115759Speter	}
1335115759Speter	if (maxdata && datalen > maxdata)
1336115759Speter		datalen = maxdata;
1337115759Speter
1338115759Speter	for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1339115759Speter		if (dp[i] >= 32 && dp[i] < 127)
1340115759Speter			continue;
1341115759Speter		if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1342115759Speter			continue;
1343115759Speter		binary = 1;
1344115759Speter	}
1345115759Speter	if (binary)
1346115759Speter		hexdump(dp, datalen, screenwidth);
1347115759Speter	else
1348115759Speter		visdump(dp, datalen, screenwidth);
1349115759Speter}
1350115759Speter
1351100824Sdwmaloneconst char *signames[] = {
13521590Srgrimes	"NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",	/*  1 - 6  */
13531590Srgrimes	"EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",		/*  7 - 12 */
13541590Srgrimes	"PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",		/* 13 - 18 */
13551590Srgrimes	"CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",		/* 19 - 24 */
13561590Srgrimes	"XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",	/* 25 - 30 */
13571590Srgrimes	"USR2", NULL,						/* 31 - 32 */
13581590Srgrimes};
13591590Srgrimes
1360100824Sdwmalonevoid
1361219138Sdchaginktrpsig(struct ktr_psig *psig)
13621590Srgrimes{
1363219138Sdchagin	if (psig->signo > 0 && psig->signo < NSIG)
1364226153Sdes		printf("SIG%s ", signames[psig->signo]);
1365160294Skib	else
1366226153Sdes		printf("SIG %d ", psig->signo);
1367240820Sjilles	if (psig->action == SIG_DFL) {
1368240820Sjilles		printf("SIG_DFL code=");
1369240820Sjilles		sigcodename(psig->signo, psig->code);
1370240820Sjilles		putchar('\n');
1371240820Sjilles	} else {
1372240820Sjilles		printf("caught handler=0x%lx mask=0x%x code=",
1373240820Sjilles		    (u_long)psig->action, psig->mask.__bits[0]);
1374240820Sjilles		sigcodename(psig->signo, psig->code);
1375240820Sjilles		putchar('\n');
1376100824Sdwmalone	}
13771590Srgrimes}
13781590Srgrimes
1379100824Sdwmalonevoid
1380234494Sjhbktrcsw_old(struct ktr_csw_old *cs)
13811590Srgrimes{
1382226153Sdes	printf("%s %s\n", cs->out ? "stop" : "resume",
13831590Srgrimes		cs->user ? "user" : "kernel");
13841590Srgrimes}
13851590Srgrimes
1386234494Sjhbvoid
1387234494Sjhbktrcsw(struct ktr_csw *cs)
1388234494Sjhb{
1389234494Sjhb	printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume",
1390234494Sjhb	    cs->user ? "user" : "kernel", cs->wmesg);
1391234494Sjhb}
1392234494Sjhb
1393165916Sjhb#define	UTRACE_DLOPEN_START		1
1394165916Sjhb#define	UTRACE_DLOPEN_STOP		2
1395165916Sjhb#define	UTRACE_DLCLOSE_START		3
1396165916Sjhb#define	UTRACE_DLCLOSE_STOP		4
1397165916Sjhb#define	UTRACE_LOAD_OBJECT		5
1398165916Sjhb#define	UTRACE_UNLOAD_OBJECT		6
1399165916Sjhb#define	UTRACE_ADD_RUNDEP		7
1400165916Sjhb#define	UTRACE_PRELOAD_FINISHED		8
1401165916Sjhb#define	UTRACE_INIT_CALL		9
1402165916Sjhb#define	UTRACE_FINI_CALL		10
1403165916Sjhb
1404165916Sjhbstruct utrace_rtld {
1405165916Sjhb	char sig[4];				/* 'RTLD' */
1406165916Sjhb	int event;
1407165916Sjhb	void *handle;
1408165916Sjhb	void *mapbase;
1409165916Sjhb	size_t mapsize;
1410165916Sjhb	int refcnt;
1411165916Sjhb	char name[MAXPATHLEN];
1412165916Sjhb};
1413165916Sjhb
1414165916Sjhbvoid
1415165916Sjhbktruser_rtld(int len, unsigned char *p)
1416165916Sjhb{
1417165916Sjhb	struct utrace_rtld *ut = (struct utrace_rtld *)p;
1418165916Sjhb	void *parent;
1419165916Sjhb	int mode;
1420165916Sjhb
1421165916Sjhb	switch (ut->event) {
1422165916Sjhb	case UTRACE_DLOPEN_START:
1423165916Sjhb		mode = ut->refcnt;
1424165916Sjhb		printf("dlopen(%s, ", ut->name);
1425165916Sjhb		switch (mode & RTLD_MODEMASK) {
1426165916Sjhb		case RTLD_NOW:
1427165916Sjhb			printf("RTLD_NOW");
1428165916Sjhb			break;
1429165916Sjhb		case RTLD_LAZY:
1430165916Sjhb			printf("RTLD_LAZY");
1431165916Sjhb			break;
1432165916Sjhb		default:
1433165916Sjhb			printf("%#x", mode & RTLD_MODEMASK);
1434165916Sjhb		}
1435165916Sjhb		if (mode & RTLD_GLOBAL)
1436165916Sjhb			printf(" | RTLD_GLOBAL");
1437165916Sjhb		if (mode & RTLD_TRACE)
1438165916Sjhb			printf(" | RTLD_TRACE");
1439165916Sjhb		if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
1440165916Sjhb			printf(" | %#x", mode &
1441165916Sjhb			    ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
1442165916Sjhb		printf(")\n");
1443165916Sjhb		break;
1444165916Sjhb	case UTRACE_DLOPEN_STOP:
1445165916Sjhb		printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
1446165916Sjhb		    ut->refcnt);
1447165916Sjhb		break;
1448165916Sjhb	case UTRACE_DLCLOSE_START:
1449165916Sjhb		printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
1450165916Sjhb		    ut->refcnt);
1451165916Sjhb		break;
1452165916Sjhb	case UTRACE_DLCLOSE_STOP:
1453165916Sjhb		printf("dlclose(%p) finished\n", ut->handle);
1454165916Sjhb		break;
1455165916Sjhb	case UTRACE_LOAD_OBJECT:
1456165916Sjhb		printf("RTLD: loaded   %p @ %p - %p (%s)\n", ut->handle,
1457165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1458165916Sjhb		    ut->name);
1459165916Sjhb		break;
1460165916Sjhb	case UTRACE_UNLOAD_OBJECT:
1461165916Sjhb		printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
1462165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1463165916Sjhb		    ut->name);
1464165916Sjhb		break;
1465165916Sjhb	case UTRACE_ADD_RUNDEP:
1466165916Sjhb		parent = ut->mapbase;
1467165916Sjhb		printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
1468165916Sjhb		    ut->handle, ut->name, ut->refcnt);
1469165916Sjhb		break;
1470165916Sjhb	case UTRACE_PRELOAD_FINISHED:
1471165916Sjhb		printf("RTLD: LD_PRELOAD finished\n");
1472165916Sjhb		break;
1473165916Sjhb	case UTRACE_INIT_CALL:
1474165916Sjhb		printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1475165916Sjhb		    ut->name);
1476165916Sjhb		break;
1477165916Sjhb	case UTRACE_FINI_CALL:
1478165916Sjhb		printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1479165916Sjhb		    ut->name);
1480165916Sjhb		break;
1481165916Sjhb	default:
1482165916Sjhb		p += 4;
1483165916Sjhb		len -= 4;
1484165916Sjhb		printf("RTLD: %d ", len);
1485165916Sjhb		while (len--)
1486165916Sjhb			if (decimal)
1487165916Sjhb				printf(" %d", *p++);
1488165916Sjhb			else
1489165916Sjhb				printf(" %02x", *p++);
1490165916Sjhb		printf("\n");
1491165916Sjhb	}
1492165916Sjhb}
1493165916Sjhb
1494165812Sjhbstruct utrace_malloc {
1495165812Sjhb	void *p;
1496165812Sjhb	size_t s;
1497165812Sjhb	void *r;
1498165812Sjhb};
1499165812Sjhb
1500100824Sdwmalonevoid
1501226329Sdesktruser_malloc(unsigned char *p)
1502165812Sjhb{
1503165812Sjhb	struct utrace_malloc *ut = (struct utrace_malloc *)p;
1504165812Sjhb
1505199265Scperciva	if (ut->p == (void *)(intptr_t)(-1))
1506199265Scperciva		printf("malloc_init()\n");
1507199265Scperciva	else if (ut->s == 0)
1508199265Scperciva		printf("free(%p)\n", ut->p);
1509199265Scperciva	else if (ut->p == NULL)
1510199265Scperciva		printf("%p = malloc(%zu)\n", ut->r, ut->s);
1511199265Scperciva	else
1512199265Scperciva		printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1513165812Sjhb}
1514165812Sjhb
1515165812Sjhbvoid
1516100824Sdwmalonektruser(int len, unsigned char *p)
151718400Sphk{
1518165812Sjhb
1519165916Sjhb	if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1520165916Sjhb		ktruser_rtld(len, p);
1521165916Sjhb		return;
1522165916Sjhb	}
1523165916Sjhb
1524165812Sjhb	if (len == sizeof(struct utrace_malloc)) {
1525226329Sdes		ktruser_malloc(p);
1526165812Sjhb		return;
1527165812Sjhb	}
1528165812Sjhb
1529226153Sdes	printf("%d ", len);
153018470Sphk	while (len--)
1531127402Sphk		if (decimal)
1532226153Sdes			printf(" %d", *p++);
1533127402Sphk		else
1534226153Sdes			printf(" %02x", *p++);
1535226153Sdes	printf("\n");
153618400Sphk}
153718400Sphk
1538100824Sdwmalonevoid
1539176471Sdesktrsockaddr(struct sockaddr *sa)
1540176471Sdes{
1541176471Sdes/*
1542176471Sdes TODO: Support additional address families
1543176471Sdes	#include <netnatm/natm.h>
1544176471Sdes	struct sockaddr_natm	*natm;
1545252356Sdavide	#include <netsmb/netbios.h>
1546252356Sdavide	struct sockaddr_nb	*nb;
1547176471Sdes*/
1548176471Sdes	char addr[64];
1549176471Sdes
1550176471Sdes	/*
1551176471Sdes	 * note: ktrstruct() has already verified that sa points to a
1552176471Sdes	 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1553176471Sdes	 * sa->sa_len bytes long.
1554176471Sdes	 */
1555176471Sdes	printf("struct sockaddr { ");
1556176471Sdes	sockfamilyname(sa->sa_family);
1557176471Sdes	printf(", ");
1558176471Sdes
1559176471Sdes#define check_sockaddr_len(n)					\
1560226329Sdes	if (sa_##n.s##n##_len < sizeof(struct sockaddr_##n)) {	\
1561176471Sdes		printf("invalid");				\
1562176471Sdes		break;						\
1563176471Sdes	}
1564176471Sdes
1565176471Sdes	switch(sa->sa_family) {
1566176471Sdes	case AF_INET: {
1567226329Sdes		struct sockaddr_in sa_in;
1568176471Sdes
1569226329Sdes		memset(&sa_in, 0, sizeof(sa_in));
1570246719Szont		memcpy(&sa_in, sa, sa->sa_len);
1571176471Sdes		check_sockaddr_len(in);
1572226329Sdes		inet_ntop(AF_INET, &sa_in.sin_addr, addr, sizeof addr);
1573226329Sdes		printf("%s:%u", addr, ntohs(sa_in.sin_port));
1574176471Sdes		break;
1575176471Sdes	}
1576176471Sdes#ifdef NETATALK
1577176471Sdes	case AF_APPLETALK: {
1578226329Sdes		struct sockaddr_at	sa_at;
1579176471Sdes		struct netrange		*nr;
1580176471Sdes
1581226329Sdes		memset(&sa_at, 0, sizeof(sa_at));
1582246719Szont		memcpy(&sa_at, sa, sa->sa_len);
1583176471Sdes		check_sockaddr_len(at);
1584226329Sdes		nr = &sa_at.sat_range.r_netrange;
1585226329Sdes		printf("%d.%d, %d-%d, %d", ntohs(sa_at.sat_addr.s_net),
1586226329Sdes			sa_at.sat_addr.s_node, ntohs(nr->nr_firstnet),
1587176471Sdes			ntohs(nr->nr_lastnet), nr->nr_phase);
1588176471Sdes		break;
1589176471Sdes	}
1590176471Sdes#endif
1591176471Sdes	case AF_INET6: {
1592226329Sdes		struct sockaddr_in6 sa_in6;
1593176471Sdes
1594226329Sdes		memset(&sa_in6, 0, sizeof(sa_in6));
1595246719Szont		memcpy(&sa_in6, sa, sa->sa_len);
1596176471Sdes		check_sockaddr_len(in6);
1597251486Sae		getnameinfo((struct sockaddr *)&sa_in6, sizeof(sa_in6),
1598251486Sae		    addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
1599226329Sdes		printf("[%s]:%u", addr, htons(sa_in6.sin6_port));
1600176471Sdes		break;
1601176471Sdes	}
1602176471Sdes#ifdef IPX
1603176471Sdes	case AF_IPX: {
1604226329Sdes		struct sockaddr_ipx sa_ipx;
1605176471Sdes
1606226329Sdes		memset(&sa_ipx, 0, sizeof(sa_ipx));
1607246719Szont		memcpy(&sa_ipx, sa, sa->sa_len);
1608176471Sdes		check_sockaddr_len(ipx);
1609176471Sdes		/* XXX wish we had ipx_ntop */
1610226329Sdes		printf("%s", ipx_ntoa(sa_ipx.sipx_addr));
1611226329Sdes		free(sa_ipx);
1612176471Sdes		break;
1613176471Sdes	}
1614176471Sdes#endif
1615176471Sdes	case AF_UNIX: {
1616226329Sdes		struct sockaddr_un sa_un;
1617176471Sdes
1618226329Sdes		memset(&sa_un, 0, sizeof(sa_un));
1619246719Szont		memcpy(&sa_un, sa, sa->sa_len);
1620226329Sdes		printf("%.*s", (int)sizeof(sa_un.sun_path), sa_un.sun_path);
1621176471Sdes		break;
1622176471Sdes	}
1623176471Sdes	default:
1624176471Sdes		printf("unknown address family");
1625176471Sdes	}
1626176471Sdes	printf(" }\n");
1627176471Sdes}
1628176471Sdes
1629176471Sdesvoid
1630176471Sdesktrstat(struct stat *statp)
1631176471Sdes{
1632176471Sdes	char mode[12], timestr[PATH_MAX + 4];
1633176471Sdes	struct passwd *pwd;
1634176471Sdes	struct group  *grp;
1635176471Sdes	struct tm *tm;
1636176471Sdes
1637176471Sdes	/*
1638176471Sdes	 * note: ktrstruct() has already verified that statp points to a
1639176471Sdes	 * buffer exactly sizeof(struct stat) bytes long.
1640176471Sdes	 */
1641176471Sdes	printf("struct stat {");
1642176471Sdes	strmode(statp->st_mode, mode);
1643176471Sdes	printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ",
1644176471Sdes		(uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode,
1645176471Sdes		(uintmax_t)statp->st_nlink);
1646176471Sdes	if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1647176471Sdes		printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1648176471Sdes	else
1649176471Sdes		printf("uid=\"%s\", ", pwd->pw_name);
1650176471Sdes	if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1651176471Sdes		printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1652176471Sdes	else
1653176471Sdes		printf("gid=\"%s\", ", grp->gr_name);
1654176471Sdes	printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1655176471Sdes	printf("atime=");
1656176471Sdes	if (resolv == 0)
1657205793Sed		printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1658176471Sdes	else {
1659205793Sed		tm = localtime(&statp->st_atim.tv_sec);
1660226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1661176471Sdes		printf("\"%s\"", timestr);
1662176471Sdes	}
1663205793Sed	if (statp->st_atim.tv_nsec != 0)
1664205793Sed		printf(".%09ld, ", statp->st_atim.tv_nsec);
1665176471Sdes	else
1666176471Sdes		printf(", ");
1667176471Sdes	printf("stime=");
1668176471Sdes	if (resolv == 0)
1669205793Sed		printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1670176471Sdes	else {
1671205793Sed		tm = localtime(&statp->st_mtim.tv_sec);
1672226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1673176471Sdes		printf("\"%s\"", timestr);
1674176471Sdes	}
1675205793Sed	if (statp->st_mtim.tv_nsec != 0)
1676205793Sed		printf(".%09ld, ", statp->st_mtim.tv_nsec);
1677176471Sdes	else
1678176471Sdes		printf(", ");
1679176471Sdes	printf("ctime=");
1680176471Sdes	if (resolv == 0)
1681205793Sed		printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1682176471Sdes	else {
1683205793Sed		tm = localtime(&statp->st_ctim.tv_sec);
1684226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1685176471Sdes		printf("\"%s\"", timestr);
1686176471Sdes	}
1687205793Sed	if (statp->st_ctim.tv_nsec != 0)
1688205793Sed		printf(".%09ld, ", statp->st_ctim.tv_nsec);
1689176471Sdes	else
1690176471Sdes		printf(", ");
1691176471Sdes	printf("birthtime=");
1692176471Sdes	if (resolv == 0)
1693205793Sed		printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
1694176471Sdes	else {
1695205793Sed		tm = localtime(&statp->st_birthtim.tv_sec);
1696226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1697176471Sdes		printf("\"%s\"", timestr);
1698176471Sdes	}
1699205793Sed	if (statp->st_birthtim.tv_nsec != 0)
1700205793Sed		printf(".%09ld, ", statp->st_birthtim.tv_nsec);
1701176471Sdes	else
1702176471Sdes		printf(", ");
1703176471Sdes	printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1704176471Sdes		(uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
1705176471Sdes		(intmax_t)statp->st_blocks, statp->st_flags);
1706176471Sdes	printf(" }\n");
1707176471Sdes}
1708176471Sdes
1709176471Sdesvoid
1710176471Sdesktrstruct(char *buf, size_t buflen)
1711176471Sdes{
1712176471Sdes	char *name, *data;
1713176471Sdes	size_t namelen, datalen;
1714176471Sdes	int i;
1715204045Simp	struct stat sb;
1716204045Simp	struct sockaddr_storage ss;
1717176471Sdes
1718176471Sdes	for (name = buf, namelen = 0;
1719176471Sdes	     namelen < buflen && name[namelen] != '\0';
1720176471Sdes	     ++namelen)
1721176471Sdes		/* nothing */;
1722176471Sdes	if (namelen == buflen)
1723176471Sdes		goto invalid;
1724176471Sdes	if (name[namelen] != '\0')
1725176471Sdes		goto invalid;
1726176471Sdes	data = buf + namelen + 1;
1727176471Sdes	datalen = buflen - namelen - 1;
1728176471Sdes	if (datalen == 0)
1729176471Sdes		goto invalid;
1730176471Sdes	/* sanity check */
1731226329Sdes	for (i = 0; i < (int)namelen; ++i)
1732226329Sdes		if (!isalpha(name[i]))
1733176471Sdes			goto invalid;
1734176471Sdes	if (strcmp(name, "stat") == 0) {
1735176471Sdes		if (datalen != sizeof(struct stat))
1736176471Sdes			goto invalid;
1737204045Simp		memcpy(&sb, data, datalen);
1738204045Simp		ktrstat(&sb);
1739176471Sdes	} else if (strcmp(name, "sockaddr") == 0) {
1740204045Simp		if (datalen > sizeof(ss))
1741204045Simp			goto invalid;
1742204045Simp		memcpy(&ss, data, datalen);
1743246720Szont		if (datalen != ss.ss_len)
1744176471Sdes			goto invalid;
1745204045Simp		ktrsockaddr((struct sockaddr *)&ss);
1746176471Sdes	} else {
1747176471Sdes		printf("unknown structure\n");
1748176471Sdes	}
1749176471Sdes	return;
1750176471Sdesinvalid:
1751176471Sdes	printf("invalid record\n");
1752176471Sdes}
1753176471Sdes
1754226269Sdesvoid
1755226269Sdesktrcapfail(struct ktr_cap_fail *ktr)
1756226269Sdes{
1757226495Sdes	switch (ktr->cap_type) {
1758226495Sdes	case CAPFAIL_NOTCAPABLE:
1759226495Sdes		/* operation on fd with insufficient capabilities */
1760226495Sdes		printf("operation requires ");
1761226495Sdes		capname((intmax_t)ktr->cap_needed);
1762226495Sdes		printf(", process holds ");
1763226495Sdes		capname((intmax_t)ktr->cap_held);
1764226495Sdes		break;
1765226495Sdes	case CAPFAIL_INCREASE:
1766226495Sdes		/* requested more capabilities than fd already has */
1767226495Sdes		printf("attempt to increase capabilities from ");
1768226505Sdes		capname((intmax_t)ktr->cap_held);
1769226505Sdes		printf(" to ");
1770226495Sdes		capname((intmax_t)ktr->cap_needed);
1771226495Sdes		break;
1772226495Sdes	case CAPFAIL_SYSCALL:
1773226495Sdes		/* called restricted syscall */
1774226495Sdes		printf("disallowed system call");
1775226495Sdes		break;
1776226495Sdes	case CAPFAIL_LOOKUP:
1777226495Sdes		/* used ".." in strict-relative mode */
1778226495Sdes		printf("restricted VFS lookup");
1779226495Sdes		break;
1780226495Sdes	default:
1781226495Sdes		printf("unknown capability failure: ");
1782226495Sdes		capname((intmax_t)ktr->cap_needed);
1783226495Sdes		printf(" ");
1784226495Sdes		capname((intmax_t)ktr->cap_held);
1785226495Sdes		break;
1786226495Sdes	}
1787233925Sjhb	printf("\n");
1788226269Sdes}
1789226269Sdes
1790233925Sjhbvoid
1791233925Sjhbktrfault(struct ktr_fault *ktr)
1792233925Sjhb{
1793233925Sjhb
1794233925Sjhb	printf("0x%jx ", ktr->vaddr);
1795233925Sjhb	vmprotname(ktr->type);
1796233925Sjhb	printf("\n");
1797233925Sjhb}
1798233925Sjhb
1799233925Sjhbvoid
1800233925Sjhbktrfaultend(struct ktr_faultend *ktr)
1801233925Sjhb{
1802233925Sjhb
1803233925Sjhb	vmresultname(ktr->result);
1804233925Sjhb	printf("\n");
1805233925Sjhb}
1806233925Sjhb
1807219138Sdchagin#if defined(__amd64__) || defined(__i386__)
1808176471Sdesvoid
1809219138Sdchaginlinux_ktrsyscall(struct ktr_syscall *ktr)
1810219138Sdchagin{
1811219138Sdchagin	int narg = ktr->ktr_narg;
1812219138Sdchagin	register_t *ip;
1813219138Sdchagin
1814219138Sdchagin	if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
1815219138Sdchagin		printf("[%d]", ktr->ktr_code);
1816219138Sdchagin	else
1817219138Sdchagin		printf("%s", linux_syscallnames[ktr->ktr_code]);
1818219138Sdchagin	ip = &ktr->ktr_args[0];
1819219138Sdchagin	if (narg) {
1820219138Sdchagin		char c = '(';
1821219138Sdchagin		while (narg > 0)
1822219138Sdchagin			print_number(ip, narg, c);
1823219138Sdchagin		putchar(')');
1824219138Sdchagin	}
1825219138Sdchagin	putchar('\n');
1826219138Sdchagin}
1827219138Sdchagin
1828219138Sdchaginvoid
1829219138Sdchaginlinux_ktrsysret(struct ktr_sysret *ktr)
1830219138Sdchagin{
1831219138Sdchagin	register_t ret = ktr->ktr_retval;
1832219138Sdchagin	int error = ktr->ktr_error;
1833219138Sdchagin	int code = ktr->ktr_code;
1834219138Sdchagin
1835219138Sdchagin	if (code >= nlinux_syscalls || code < 0)
1836219138Sdchagin		printf("[%d] ", code);
1837219138Sdchagin	else
1838219138Sdchagin		printf("%s ", linux_syscallnames[code]);
1839219138Sdchagin
1840219138Sdchagin	if (error == 0) {
1841219138Sdchagin		if (fancy) {
1842219138Sdchagin			printf("%ld", (long)ret);
1843219138Sdchagin			if (ret < 0 || ret > 9)
1844226153Sdes				printf("/%#lx", (unsigned long)ret);
1845219138Sdchagin		} else {
1846219138Sdchagin			if (decimal)
1847219138Sdchagin				printf("%ld", (long)ret);
1848219138Sdchagin			else
1849226153Sdes				printf("%#lx", (unsigned long)ret);
1850219138Sdchagin		}
1851219138Sdchagin	} else if (error == ERESTART)
1852219138Sdchagin		printf("RESTART");
1853219138Sdchagin	else if (error == EJUSTRETURN)
1854219138Sdchagin		printf("JUSTRETURN");
1855219138Sdchagin	else {
1856219138Sdchagin		if (ktr->ktr_error <= ELAST + 1)
1857219138Sdchagin			error = abs(bsd_to_linux_errno[ktr->ktr_error]);
1858219138Sdchagin		else
1859219138Sdchagin			error = 999;
1860219138Sdchagin		printf("-1 errno %d", error);
1861219138Sdchagin		if (fancy)
1862219138Sdchagin			printf(" %s", strerror(ktr->ktr_error));
1863219138Sdchagin	}
1864219138Sdchagin	putchar('\n');
1865219138Sdchagin}
1866219138Sdchagin#endif
1867219138Sdchagin
1868219138Sdchaginvoid
1869100824Sdwmaloneusage(void)
18701590Srgrimes{
1871219043Sdchagin	fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] "
1872177856Sru	    "[-m maxdata] [-p pid] [-t trstr]\n");
18731590Srgrimes	exit(1);
18741590Srgrimes}
1875