kdump.c revision 255219
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 255219 2013-09-05 00:09:56Z pjd $");
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 *);
106255219Spjdvoid ktrcaprights(cap_rights_t *);
107176471Sdesvoid ktrsockaddr(struct sockaddr *);
108176471Sdesvoid ktrstat(struct stat *);
109176471Sdesvoid ktrstruct(char *, size_t);
110226269Sdesvoid ktrcapfail(struct ktr_cap_fail *);
111233925Sjhbvoid ktrfault(struct ktr_fault *);
112233925Sjhbvoid ktrfaultend(struct ktr_faultend *);
113251073Spjdvoid limitfd(int fd);
114100824Sdwmalonevoid usage(void);
115226157Sdesvoid ioctlname(unsigned long, int);
116100824Sdwmalone
117176471Sdesint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
118219043Sdchagin    resolv = 0, abiflag = 0;
119100824Sdwmaloneconst char *tracefile = DEF_TRACEFILE;
1201590Srgrimesstruct ktr_header ktr_header;
1211590Srgrimes
122176471Sdes#define TIME_FORMAT	"%b %e %T %Y"
1231590Srgrimes#define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
1241590Srgrimes
125226262Sdes#define print_number(i,n,c) do {					\
126226262Sdes	if (decimal)							\
127226262Sdes		printf("%c%jd", c, (intmax_t)*i);			\
128226262Sdes	else								\
129226262Sdes		printf("%c%#jx", c, (uintmax_t)(u_register_t)*i);	\
130226262Sdes	i++;								\
131226262Sdes	n--;								\
132226262Sdes	c = ',';							\
133226164Sdes} while (0)
134219138Sdchagin
135219138Sdchagin#if defined(__amd64__) || defined(__i386__)
136219138Sdchagin
137219138Sdchaginvoid linux_ktrsyscall(struct ktr_syscall *);
138219138Sdchaginvoid linux_ktrsysret(struct ktr_sysret *);
139219138Sdchaginextern char *linux_syscallnames[];
140219138Sdchaginextern int nlinux_syscalls;
141219138Sdchagin
142219138Sdchagin/*
143219138Sdchagin * from linux.h
144219138Sdchagin * Linux syscalls return negative errno's, we do positive and map them
145219138Sdchagin */
146219138Sdchaginstatic int bsd_to_linux_errno[ELAST + 1] = {
147219138Sdchagin	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
148219138Sdchagin	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
149219138Sdchagin	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
150219138Sdchagin	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
151219138Sdchagin	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
152219138Sdchagin	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
153219138Sdchagin	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
154219138Sdchagin	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
155219138Sdchagin	-6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
156219138Sdchagin	-72, -67, -71
157219138Sdchagin};
158219138Sdchagin#endif
159219138Sdchagin
160219043Sdchaginstruct proc_info
161219043Sdchagin{
162219043Sdchagin	TAILQ_ENTRY(proc_info)	info;
163219043Sdchagin	u_int			sv_flags;
164219043Sdchagin	pid_t			pid;
165219043Sdchagin};
166219043Sdchagin
167219043SdchaginTAILQ_HEAD(trace_procs, proc_info) trace_procs;
168219043Sdchagin
169253456Spjdstatic void
170253456Spjdstrerror_init(void)
171253456Spjd{
172253456Spjd
173253456Spjd	/*
174253456Spjd	 * Cache NLS data before entering capability mode.
175253456Spjd	 * XXXPJD: There should be strerror_init() and strsignal_init() in libc.
176253456Spjd	 */
177253456Spjd	(void)catopen("libc", NL_CAT_LOCALE);
178253456Spjd}
179253456Spjd
180253456Spjdstatic void
181253456Spjdlocaltime_init(void)
182253456Spjd{
183253456Spjd	time_t ltime;
184253456Spjd
185253456Spjd	/*
186253456Spjd	 * Allow localtime(3) to cache /etc/localtime content before entering
187253456Spjd	 * capability mode.
188253456Spjd	 * XXXPJD: There should be localtime_init() in libc.
189253456Spjd	 */
190253456Spjd	(void)time(&ltime);
191253456Spjd	(void)localtime(&ltime);
192253456Spjd}
193253456Spjd
194100824Sdwmaloneint
195100824Sdwmalonemain(int argc, char *argv[])
1961590Srgrimes{
1971590Srgrimes	int ch, ktrlen, size;
198100824Sdwmalone	void *m;
1991590Srgrimes	int trpoints = ALL_POINTS;
200112201Sjhb	int drop_logged;
201115759Speter	pid_t pid = 0;
202219043Sdchagin	u_int sv_flags;
2031590Srgrimes
204226153Sdes	setlocale(LC_CTYPE, "");
20511823Sache
206219043Sdchagin	while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1)
207226153Sdes		switch (ch) {
208219043Sdchagin		case 'A':
209219043Sdchagin			abiflag = 1;
210219043Sdchagin			break;
2111590Srgrimes		case 'f':
2121590Srgrimes			tracefile = optarg;
2131590Srgrimes			break;
2141590Srgrimes		case 'd':
2151590Srgrimes			decimal = 1;
2161590Srgrimes			break;
2171590Srgrimes		case 'l':
2181590Srgrimes			tail = 1;
2191590Srgrimes			break;
2201590Srgrimes		case 'm':
2211590Srgrimes			maxdata = atoi(optarg);
2221590Srgrimes			break;
2231590Srgrimes		case 'n':
2241590Srgrimes			fancy = 0;
2251590Srgrimes			break;
226115759Speter		case 'p':
227115759Speter			pid = atoi(optarg);
228115759Speter			break;
229176471Sdes		case 'r':
230176471Sdes			resolv = 1;
231176471Sdes			break;
232152331Srwatson		case 's':
233152331Srwatson			suppressdata = 1;
234152331Srwatson			break;
235123187Speter		case 'E':
236123187Speter			timestamp = 3;	/* elapsed timestamp */
237123187Speter			break;
238151930Srwatson		case 'H':
239151930Srwatson			threads = 1;
240151930Srwatson			break;
2411590Srgrimes		case 'R':
2421590Srgrimes			timestamp = 2;	/* relative timestamp */
2431590Srgrimes			break;
2441590Srgrimes		case 'T':
2451590Srgrimes			timestamp = 1;
2461590Srgrimes			break;
2471590Srgrimes		case 't':
2481590Srgrimes			trpoints = getpoints(optarg);
24927443Scharnier			if (trpoints < 0)
25027443Scharnier				errx(1, "unknown trace point in %s", optarg);
2511590Srgrimes			break;
2521590Srgrimes		default:
2531590Srgrimes			usage();
2541590Srgrimes		}
2551590Srgrimes
25619853Sfenner	if (argc > optind)
2571590Srgrimes		usage();
2581590Srgrimes
259226153Sdes	m = malloc(size = 1025);
26027443Scharnier	if (m == NULL)
26127443Scharnier		errx(1, "%s", strerror(ENOMEM));
26227443Scharnier	if (!freopen(tracefile, "r", stdin))
26327443Scharnier		err(1, "%s", tracefile);
264251073Spjd
265253456Spjd	strerror_init();
266253456Spjd	localtime_init();
267253456Spjd
268251167Spjd	if (resolv == 0) {
269251167Spjd		if (cap_enter() < 0 && errno != ENOSYS)
270251167Spjd			err(1, "unable to enter capability mode");
271251167Spjd	}
272251073Spjd	limitfd(STDIN_FILENO);
273251073Spjd	limitfd(STDOUT_FILENO);
274251073Spjd	limitfd(STDERR_FILENO);
275251073Spjd
276219043Sdchagin	TAILQ_INIT(&trace_procs);
277112201Sjhb	drop_logged = 0;
2781590Srgrimes	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
279112201Sjhb		if (ktr_header.ktr_type & KTR_DROP) {
280112201Sjhb			ktr_header.ktr_type &= ~KTR_DROP;
281151930Srwatson			if (!drop_logged && threads) {
282226153Sdes				printf(
283203551Sjh				    "%6jd %6jd %-8.*s Events dropped.\n",
284203551Sjh				    (intmax_t)ktr_header.ktr_pid,
285203551Sjh				    ktr_header.ktr_tid > 0 ?
286203551Sjh				    (intmax_t)ktr_header.ktr_tid : 0,
287203551Sjh				    MAXCOMLEN, ktr_header.ktr_comm);
288151930Srwatson				drop_logged = 1;
289151930Srwatson			} else if (!drop_logged) {
290226153Sdes				printf("%6jd %-8.*s Events dropped.\n",
291203551Sjh				    (intmax_t)ktr_header.ktr_pid, MAXCOMLEN,
292112201Sjhb				    ktr_header.ktr_comm);
293112201Sjhb				drop_logged = 1;
294112201Sjhb			}
295112201Sjhb		}
2961590Srgrimes		if (trpoints & (1<<ktr_header.ktr_type))
297236577Sjhb			if (pid == 0 || ktr_header.ktr_pid == pid ||
298236577Sjhb			    ktr_header.ktr_tid == pid)
299115759Speter				dumpheader(&ktr_header);
30027443Scharnier		if ((ktrlen = ktr_header.ktr_len) < 0)
30127443Scharnier			errx(1, "bogus length 0x%x", ktrlen);
3021590Srgrimes		if (ktrlen > size) {
303226153Sdes			m = realloc(m, ktrlen+1);
30427443Scharnier			if (m == NULL)
30527443Scharnier				errx(1, "%s", strerror(ENOMEM));
3061590Srgrimes			size = ktrlen;
3071590Srgrimes		}
30827443Scharnier		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
30927443Scharnier			errx(1, "data too short");
310219043Sdchagin		if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
311219043Sdchagin			continue;
312219043Sdchagin		sv_flags = abidump(&ktr_header);
313236577Sjhb		if (pid && ktr_header.ktr_pid != pid &&
314236577Sjhb		    ktr_header.ktr_tid != pid)
315115759Speter			continue;
3161590Srgrimes		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
3171590Srgrimes			continue;
318112201Sjhb		drop_logged = 0;
3191590Srgrimes		switch (ktr_header.ktr_type) {
3201590Srgrimes		case KTR_SYSCALL:
321219138Sdchagin#if defined(__amd64__) || defined(__i386__)
322219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
323219138Sdchagin				linux_ktrsyscall((struct ktr_syscall *)m);
324219138Sdchagin			else
325219138Sdchagin#endif
326219138Sdchagin				ktrsyscall((struct ktr_syscall *)m, sv_flags);
3271590Srgrimes			break;
3281590Srgrimes		case KTR_SYSRET:
329219138Sdchagin#if defined(__amd64__) || defined(__i386__)
330219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
331219138Sdchagin				linux_ktrsysret((struct ktr_sysret *)m);
332219138Sdchagin			else
333219138Sdchagin#endif
334219138Sdchagin				ktrsysret((struct ktr_sysret *)m, sv_flags);
3351590Srgrimes			break;
3361590Srgrimes		case KTR_NAMEI:
337189707Sjhb		case KTR_SYSCTL:
3381590Srgrimes			ktrnamei(m, ktrlen);
3391590Srgrimes			break;
3401590Srgrimes		case KTR_GENIO:
3411590Srgrimes			ktrgenio((struct ktr_genio *)m, ktrlen);
3421590Srgrimes			break;
3431590Srgrimes		case KTR_PSIG:
344219138Sdchagin			ktrpsig((struct ktr_psig *)m);
3451590Srgrimes			break;
3461590Srgrimes		case KTR_CSW:
347234494Sjhb			if (ktrlen == sizeof(struct ktr_csw_old))
348234494Sjhb				ktrcsw_old((struct ktr_csw_old *)m);
349234494Sjhb			else
350234494Sjhb				ktrcsw((struct ktr_csw *)m);
3511590Srgrimes			break;
35218400Sphk		case KTR_USER:
35318470Sphk			ktruser(ktrlen, m);
35418400Sphk			break;
355176471Sdes		case KTR_STRUCT:
356176471Sdes			ktrstruct(m, ktrlen);
357176471Sdes			break;
358226269Sdes		case KTR_CAPFAIL:
359226269Sdes			ktrcapfail((struct ktr_cap_fail *)m);
360233925Sjhb			break;
361233925Sjhb		case KTR_FAULT:
362233925Sjhb			ktrfault((struct ktr_fault *)m);
363233925Sjhb			break;
364233925Sjhb		case KTR_FAULTEND:
365233925Sjhb			ktrfaultend((struct ktr_faultend *)m);
366233925Sjhb			break;
367112203Sjhb		default:
368112203Sjhb			printf("\n");
369112203Sjhb			break;
3701590Srgrimes		}
3711590Srgrimes		if (tail)
372226153Sdes			fflush(stdout);
3731590Srgrimes	}
374100824Sdwmalone	return 0;
3751590Srgrimes}
3761590Srgrimes
377251073Spjdvoid
378251073Spjdlimitfd(int fd)
379251073Spjd{
380251073Spjd	cap_rights_t rights;
381251073Spjd	unsigned long cmd;
382251073Spjd
383255219Spjd	cap_rights_init(&rights, CAP_FSTAT);
384251073Spjd	cmd = -1;
385251073Spjd
386251073Spjd	switch (fd) {
387251073Spjd	case STDIN_FILENO:
388255219Spjd		cap_rights_set(&rights, CAP_READ);
389251073Spjd		break;
390251073Spjd	case STDOUT_FILENO:
391255219Spjd		cap_rights_set(&rights, CAP_IOCTL, CAP_WRITE);
392251073Spjd		cmd = TIOCGETA;	/* required by isatty(3) in printf(3) */
393251073Spjd		break;
394251073Spjd	case STDERR_FILENO:
395255219Spjd		cap_rights_set(&rights, CAP_WRITE);
396251073Spjd		if (!suppressdata) {
397255219Spjd			cap_rights_set(&rights, CAP_IOCTL);
398251073Spjd			cmd = TIOCGWINSZ;
399251073Spjd		}
400251073Spjd		break;
401251073Spjd	default:
402251073Spjd		abort();
403251073Spjd	}
404251073Spjd
405255219Spjd	if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS)
406251073Spjd		err(1, "unable to limit rights for descriptor %d", fd);
407251073Spjd	if (cmd != -1 && cap_ioctls_limit(fd, &cmd, 1) < 0 && errno != ENOSYS)
408251073Spjd		err(1, "unable to limit ioctls for descriptor %d", fd);
409251073Spjd}
410251073Spjd
411100824Sdwmaloneint
412100824Sdwmalonefread_tail(void *buf, int size, int num)
4131590Srgrimes{
4141590Srgrimes	int i;
4151590Srgrimes
4161590Srgrimes	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
417226153Sdes		sleep(1);
4181590Srgrimes		clearerr(stdin);
4191590Srgrimes	}
4201590Srgrimes	return (i);
4211590Srgrimes}
4221590Srgrimes
423219043Sdchaginint
424219043Sdchaginfetchprocinfo(struct ktr_header *kth, u_int *flags)
425219043Sdchagin{
426219043Sdchagin	struct proc_info *pi;
427219043Sdchagin
428219043Sdchagin	switch (kth->ktr_type) {
429219043Sdchagin	case KTR_PROCCTOR:
430219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
431219043Sdchagin			if (pi->pid == kth->ktr_pid) {
432219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
433219043Sdchagin				break;
434219043Sdchagin			}
435219043Sdchagin		}
436219043Sdchagin		pi = malloc(sizeof(struct proc_info));
437219043Sdchagin		if (pi == NULL)
438219043Sdchagin			errx(1, "%s", strerror(ENOMEM));
439219043Sdchagin		pi->sv_flags = *flags;
440219043Sdchagin		pi->pid = kth->ktr_pid;
441219043Sdchagin		TAILQ_INSERT_TAIL(&trace_procs, pi, info);
442219043Sdchagin		return (1);
443219043Sdchagin
444219043Sdchagin	case KTR_PROCDTOR:
445219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
446219043Sdchagin			if (pi->pid == kth->ktr_pid) {
447219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
448219043Sdchagin				free(pi);
449219043Sdchagin				break;
450219043Sdchagin			}
451219043Sdchagin		}
452219043Sdchagin		return (1);
453219043Sdchagin	}
454219043Sdchagin
455219043Sdchagin	return (0);
456219043Sdchagin}
457219043Sdchagin
458219043Sdchaginu_int
459219043Sdchaginabidump(struct ktr_header *kth)
460219043Sdchagin{
461219043Sdchagin	struct proc_info *pi;
462219043Sdchagin	const char *abi;
463219043Sdchagin	const char *arch;
464219043Sdchagin	u_int flags = 0;
465219043Sdchagin
466219043Sdchagin	TAILQ_FOREACH(pi, &trace_procs, info) {
467219043Sdchagin		if (pi->pid == kth->ktr_pid) {
468219043Sdchagin			flags = pi->sv_flags;
469219043Sdchagin			break;
470219043Sdchagin		}
471219043Sdchagin	}
472219043Sdchagin
473219043Sdchagin	if (abiflag == 0)
474219043Sdchagin		return (flags);
475219043Sdchagin
476219043Sdchagin	switch (flags & SV_ABI_MASK) {
477219043Sdchagin	case SV_ABI_LINUX:
478219043Sdchagin		abi = "L";
479219043Sdchagin		break;
480219043Sdchagin	case SV_ABI_FREEBSD:
481219043Sdchagin		abi = "F";
482219043Sdchagin		break;
483219043Sdchagin	default:
484219043Sdchagin		abi = "U";
485219043Sdchagin		break;
486219043Sdchagin	}
487219043Sdchagin
488219043Sdchagin	if (flags != 0) {
489219043Sdchagin		if (flags & SV_LP64)
490219043Sdchagin			arch = "64";
491219043Sdchagin		else
492219043Sdchagin			arch = "32";
493219043Sdchagin	} else
494219043Sdchagin		arch = "00";
495219043Sdchagin
496219043Sdchagin	printf("%s%s  ", abi, arch);
497219043Sdchagin
498219043Sdchagin	return (flags);
499219043Sdchagin}
500219043Sdchagin
501100824Sdwmalonevoid
502100824Sdwmalonedumpheader(struct ktr_header *kth)
5031590Srgrimes{
5041590Srgrimes	static char unknown[64];
5051590Srgrimes	static struct timeval prevtime, temp;
506100824Sdwmalone	const char *type;
5071590Srgrimes
5081590Srgrimes	switch (kth->ktr_type) {
5091590Srgrimes	case KTR_SYSCALL:
5101590Srgrimes		type = "CALL";
5111590Srgrimes		break;
5121590Srgrimes	case KTR_SYSRET:
5131590Srgrimes		type = "RET ";
5141590Srgrimes		break;
5151590Srgrimes	case KTR_NAMEI:
5161590Srgrimes		type = "NAMI";
5171590Srgrimes		break;
5181590Srgrimes	case KTR_GENIO:
5191590Srgrimes		type = "GIO ";
5201590Srgrimes		break;
5211590Srgrimes	case KTR_PSIG:
5221590Srgrimes		type = "PSIG";
5231590Srgrimes		break;
5241590Srgrimes	case KTR_CSW:
525171333Sjhb		type = "CSW ";
5261590Srgrimes		break;
52718400Sphk	case KTR_USER:
52818400Sphk		type = "USER";
52918400Sphk		break;
530176471Sdes	case KTR_STRUCT:
531176471Sdes		type = "STRU";
532176471Sdes		break;
533189707Sjhb	case KTR_SYSCTL:
534189707Sjhb		type = "SCTL";
535189707Sjhb		break;
536219043Sdchagin	case KTR_PROCCTOR:
537219043Sdchagin		/* FALLTHROUGH */
538219043Sdchagin	case KTR_PROCDTOR:
539219043Sdchagin		return;
540226269Sdes	case KTR_CAPFAIL:
541226269Sdes		type = "CAP ";
542226269Sdes		break;
543233925Sjhb	case KTR_FAULT:
544233925Sjhb		type = "PFLT";
545233925Sjhb		break;
546233925Sjhb	case KTR_FAULTEND:
547233925Sjhb		type = "PRET";
548233925Sjhb		break;
5491590Srgrimes	default:
550226153Sdes		sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
5511590Srgrimes		type = unknown;
5521590Srgrimes	}
5531590Srgrimes
554151930Srwatson	/*
555151930Srwatson	 * The ktr_tid field was previously the ktr_buffer field, which held
556151930Srwatson	 * the kernel pointer value for the buffer associated with data
557151930Srwatson	 * following the record header.  It now holds a threadid, but only
558151930Srwatson	 * for trace files after the change.  Older trace files still contain
559151930Srwatson	 * kernel pointers.  Detect this and suppress the results by printing
560151930Srwatson	 * negative tid's as 0.
561151930Srwatson	 */
562151930Srwatson	if (threads)
563226153Sdes		printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid,
564203551Sjh		    kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0,
565203551Sjh		    MAXCOMLEN, kth->ktr_comm);
566151930Srwatson	else
567226153Sdes		printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN,
568151930Srwatson		    kth->ktr_comm);
5691590Srgrimes	if (timestamp) {
570123187Speter		if (timestamp == 3) {
571123187Speter			if (prevtime.tv_sec == 0)
572123187Speter				prevtime = kth->ktr_time;
573123187Speter			timevalsub(&kth->ktr_time, &prevtime);
574123187Speter		}
5751590Srgrimes		if (timestamp == 2) {
5761590Srgrimes			temp = kth->ktr_time;
5771590Srgrimes			timevalsub(&kth->ktr_time, &prevtime);
5781590Srgrimes			prevtime = temp;
5791590Srgrimes		}
580226153Sdes		printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
581203551Sjh		    kth->ktr_time.tv_usec);
5821590Srgrimes	}
583226153Sdes	printf("%s  ", type);
5841590Srgrimes}
5851590Srgrimes
5861590Srgrimes#include <sys/syscall.h>
5871590Srgrimes#define KTRACE
5884721Sphk#include <sys/kern/syscalls.c>
5891590Srgrimes#undef KTRACE
5901590Srgrimesint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
5911590Srgrimes
592100824Sdwmalonevoid
593219043Sdchaginktrsyscall(struct ktr_syscall *ktr, u_int flags)
5941590Srgrimes{
595100824Sdwmalone	int narg = ktr->ktr_narg;
596100824Sdwmalone	register_t *ip;
597226269Sdes	intmax_t arg;
5981590Srgrimes
599219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
600219043Sdchagin	    (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
601226153Sdes		printf("[%d]", ktr->ktr_code);
6021590Srgrimes	else
603226153Sdes		printf("%s", syscallnames[ktr->ktr_code]);
60447957Sdt	ip = &ktr->ktr_args[0];
6051590Srgrimes	if (narg) {
6061590Srgrimes		char c = '(';
607219043Sdchagin		if (fancy &&
608219043Sdchagin		    (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
609226148Sdes			switch (ktr->ktr_code) {
610254296Sjilles			case SYS_bindat:
611254296Sjilles			case SYS_connectat:
612254291Sjilles			case SYS_faccessat:
613254291Sjilles			case SYS_fchmodat:
614254291Sjilles			case SYS_fchownat:
615254291Sjilles			case SYS_fstatat:
616254291Sjilles			case SYS_futimesat:
617254291Sjilles			case SYS_linkat:
618254291Sjilles			case SYS_mkdirat:
619254291Sjilles			case SYS_mkfifoat:
620254291Sjilles			case SYS_mknodat:
621254291Sjilles			case SYS_openat:
622254291Sjilles			case SYS_readlinkat:
623254291Sjilles			case SYS_renameat:
624254291Sjilles			case SYS_unlinkat:
625254291Sjilles				putchar('(');
626254291Sjilles				atfdname(*ip, decimal);
627254291Sjilles				c = ',';
628254291Sjilles				ip++;
629254291Sjilles				narg--;
630254291Sjilles				break;
631254291Sjilles			}
632254291Sjilles			switch (ktr->ktr_code) {
633226148Sdes			case SYS_ioctl: {
634226150Sdes				print_number(ip, narg, c);
635226157Sdes				putchar(c);
636226157Sdes				ioctlname(*ip, decimal);
6371590Srgrimes				c = ',';
6381590Srgrimes				ip++;
6391590Srgrimes				narg--;
640226148Sdes				break;
641226148Sdes			}
642226148Sdes			case SYS_ptrace:
643226153Sdes				putchar('(');
644226164Sdes				ptraceopname(*ip);
6451590Srgrimes				c = ',';
6461590Srgrimes				ip++;
6471590Srgrimes				narg--;
648226148Sdes				break;
649226148Sdes			case SYS_access:
650226148Sdes			case SYS_eaccess:
651254291Sjilles			case SYS_faccessat:
652226150Sdes				print_number(ip, narg, c);
653226153Sdes				putchar(',');
654226164Sdes				accessmodename(*ip);
655158766Snetchild				ip++;
656158766Snetchild				narg--;
657226148Sdes				break;
658226148Sdes			case SYS_open:
659254291Sjilles			case SYS_openat:
660226150Sdes				print_number(ip, narg, c);
661226153Sdes				putchar(',');
662226164Sdes				flagsandmodename(ip[0], ip[1], decimal);
663226148Sdes				ip += 2;
664226148Sdes				narg -= 2;
665226148Sdes				break;
666226148Sdes			case SYS_wait4:
667226150Sdes				print_number(ip, narg, c);
668226150Sdes				print_number(ip, narg, c);
669226153Sdes				putchar(',');
670226164Sdes				wait4optname(*ip);
671158766Snetchild				ip++;
672158766Snetchild				narg--;
673226148Sdes				break;
674226148Sdes			case SYS_chmod:
675226148Sdes			case SYS_fchmod:
676226148Sdes			case SYS_lchmod:
677226150Sdes				print_number(ip, narg, c);
678226153Sdes				putchar(',');
679226164Sdes				modename(*ip);
680158766Snetchild				ip++;
681158766Snetchild				narg--;
682226148Sdes				break;
683226148Sdes			case SYS_mknod:
684254291Sjilles			case SYS_mknodat:
685226150Sdes				print_number(ip, narg, c);
686226153Sdes				putchar(',');
687226164Sdes				modename(*ip);
688158766Snetchild				ip++;
689158766Snetchild				narg--;
690226148Sdes				break;
691226148Sdes			case SYS_getfsstat:
692226150Sdes				print_number(ip, narg, c);
693226150Sdes				print_number(ip, narg, c);
694226153Sdes				putchar(',');
695226164Sdes				getfsstatflagsname(*ip);
696158766Snetchild				ip++;
697158766Snetchild				narg--;
698226148Sdes				break;
699226148Sdes			case SYS_mount:
700226150Sdes				print_number(ip, narg, c);
701226150Sdes				print_number(ip, narg, c);
702226153Sdes				putchar(',');
703226164Sdes				mountflagsname(*ip);
704158766Snetchild				ip++;
705158766Snetchild				narg--;
706226148Sdes				break;
707226148Sdes			case SYS_unmount:
708226150Sdes				print_number(ip, narg, c);
709226153Sdes				putchar(',');
710226164Sdes				mountflagsname(*ip);
711158766Snetchild				ip++;
712158766Snetchild				narg--;
713226148Sdes				break;
714226148Sdes			case SYS_recvmsg:
715226148Sdes			case SYS_sendmsg:
716226150Sdes				print_number(ip, narg, c);
717226150Sdes				print_number(ip, narg, c);
718226153Sdes				putchar(',');
719226164Sdes				sendrecvflagsname(*ip);
720158766Snetchild				ip++;
721158766Snetchild				narg--;
722226148Sdes				break;
723226148Sdes			case SYS_recvfrom:
724226148Sdes			case SYS_sendto:
725226150Sdes				print_number(ip, narg, c);
726226150Sdes				print_number(ip, narg, c);
727226150Sdes				print_number(ip, narg, c);
728226153Sdes				putchar(',');
729226164Sdes				sendrecvflagsname(*ip);
730158766Snetchild				ip++;
731158766Snetchild				narg--;
732226148Sdes				break;
733226148Sdes			case SYS_chflags:
734226148Sdes			case SYS_fchflags:
735226148Sdes			case SYS_lchflags:
736226150Sdes				print_number(ip, narg, c);
737226153Sdes				putchar(',');
738226164Sdes				modename(*ip);
739158766Snetchild				ip++;
740158766Snetchild				narg--;
741226148Sdes				break;
742226148Sdes			case SYS_kill:
743226150Sdes				print_number(ip, narg, c);
744226153Sdes				putchar(',');
745226164Sdes				signame(*ip);
746158766Snetchild				ip++;
747158766Snetchild				narg--;
748226148Sdes				break;
749226148Sdes			case SYS_reboot:
750226153Sdes				putchar('(');
751226164Sdes				rebootoptname(*ip);
752158766Snetchild				ip++;
753158766Snetchild				narg--;
754226148Sdes				break;
755226148Sdes			case SYS_umask:
756226153Sdes				putchar('(');
757226164Sdes				modename(*ip);
758158766Snetchild				ip++;
759158766Snetchild				narg--;
760226148Sdes				break;
761226148Sdes			case SYS_msync:
762226150Sdes				print_number(ip, narg, c);
763226150Sdes				print_number(ip, narg, c);
764226153Sdes				putchar(',');
765226164Sdes				msyncflagsname(*ip);
766158766Snetchild				ip++;
767158766Snetchild				narg--;
768226148Sdes				break;
769171221Speter#ifdef SYS_freebsd6_mmap
770226148Sdes			case SYS_freebsd6_mmap:
771226150Sdes				print_number(ip, narg, c);
772226150Sdes				print_number(ip, narg, c);
773226153Sdes				putchar(',');
774226164Sdes				mmapprotname(*ip);
775226153Sdes				putchar(',');
776171221Speter				ip++;
777171221Speter				narg--;
778226164Sdes				mmapflagsname(*ip);
779171221Speter				ip++;
780171221Speter				narg--;
781226148Sdes				break;
782171221Speter#endif
783226148Sdes			case SYS_mmap:
784226150Sdes				print_number(ip, narg, c);
785226150Sdes				print_number(ip, narg, c);
786226153Sdes				putchar(',');
787226164Sdes				mmapprotname(*ip);
788226153Sdes				putchar(',');
789158766Snetchild				ip++;
790158766Snetchild				narg--;
791226164Sdes				mmapflagsname(*ip);
792158766Snetchild				ip++;
793158766Snetchild				narg--;
794226148Sdes				break;
795226148Sdes			case SYS_mprotect:
796226150Sdes				print_number(ip, narg, c);
797226150Sdes				print_number(ip, narg, c);
798226153Sdes				putchar(',');
799226164Sdes				mmapprotname(*ip);
800158766Snetchild				ip++;
801158766Snetchild				narg--;
802226148Sdes				break;
803226148Sdes			case SYS_madvise:
804226150Sdes				print_number(ip, narg, c);
805226150Sdes				print_number(ip, narg, c);
806226153Sdes				putchar(',');
807226164Sdes				madvisebehavname(*ip);
808158766Snetchild				ip++;
809158766Snetchild				narg--;
810226148Sdes				break;
811226148Sdes			case SYS_setpriority:
812226150Sdes				print_number(ip, narg, c);
813226150Sdes				print_number(ip, narg, c);
814226153Sdes				putchar(',');
815226164Sdes				prioname(*ip);
816158766Snetchild				ip++;
817158766Snetchild				narg--;
818226148Sdes				break;
819226148Sdes			case SYS_fcntl:
820226150Sdes				print_number(ip, narg, c);
821226153Sdes				putchar(',');
822226164Sdes				fcntlcmdname(ip[0], ip[1], decimal);
823226148Sdes				ip += 2;
824226148Sdes				narg -= 2;
825226148Sdes				break;
826226148Sdes			case SYS_socket: {
827165758Srodrigc				int sockdomain;
828226153Sdes				putchar('(');
829226164Sdes				sockdomain = *ip;
830165758Srodrigc				sockdomainname(sockdomain);
831158766Snetchild				ip++;
832158766Snetchild				narg--;
833226153Sdes				putchar(',');
834254922Sjilles				socktypenamewithflags(*ip);
835158766Snetchild				ip++;
836158766Snetchild				narg--;
837165758Srodrigc				if (sockdomain == PF_INET ||
838165758Srodrigc				    sockdomain == PF_INET6) {
839226153Sdes					putchar(',');
840226164Sdes					sockipprotoname(*ip);
841165758Srodrigc					ip++;
842165758Srodrigc					narg--;
843165758Srodrigc				}
844158766Snetchild				c = ',';
845226148Sdes				break;
846226148Sdes			}
847226148Sdes			case SYS_setsockopt:
848226148Sdes			case SYS_getsockopt:
849226150Sdes				print_number(ip, narg, c);
850226153Sdes				putchar(',');
851226164Sdes				sockoptlevelname(*ip, decimal);
852226151Sdes				if (*ip == SOL_SOCKET) {
853175138Sjhb					ip++;
854175138Sjhb					narg--;
855226153Sdes					putchar(',');
856226164Sdes					sockoptname(*ip);
857175138Sjhb				}
858158766Snetchild				ip++;
859158766Snetchild				narg--;
860226148Sdes				break;
861171221Speter#ifdef SYS_freebsd6_lseek
862226148Sdes			case SYS_freebsd6_lseek:
863226150Sdes				print_number(ip, narg, c);
864158766Snetchild				/* Hidden 'pad' argument, not in lseek(2) */
865226150Sdes				print_number(ip, narg, c);
866226150Sdes				print_number(ip, narg, c);
867226153Sdes				putchar(',');
868226164Sdes				whencename(*ip);
869158766Snetchild				ip++;
870158766Snetchild				narg--;
871226148Sdes				break;
872171221Speter#endif
873226148Sdes			case SYS_lseek:
874226150Sdes				print_number(ip, narg, c);
875171221Speter				/* Hidden 'pad' argument, not in lseek(2) */
876226150Sdes				print_number(ip, narg, c);
877226153Sdes				putchar(',');
878226164Sdes				whencename(*ip);
879171221Speter				ip++;
880171221Speter				narg--;
881226148Sdes				break;
882226148Sdes			case SYS_flock:
883226150Sdes				print_number(ip, narg, c);
884226153Sdes				putchar(',');
885226164Sdes				flockname(*ip);
886158766Snetchild				ip++;
887158766Snetchild				narg--;
888226148Sdes				break;
889226148Sdes			case SYS_mkfifo:
890254291Sjilles			case SYS_mkfifoat:
891226148Sdes			case SYS_mkdir:
892254291Sjilles			case SYS_mkdirat:
893226150Sdes				print_number(ip, narg, c);
894226153Sdes				putchar(',');
895226164Sdes				modename(*ip);
896158766Snetchild				ip++;
897158766Snetchild				narg--;
898226148Sdes				break;
899226148Sdes			case SYS_shutdown:
900226150Sdes				print_number(ip, narg, c);
901226153Sdes				putchar(',');
902226164Sdes				shutdownhowname(*ip);
903158766Snetchild				ip++;
904158766Snetchild				narg--;
905226148Sdes				break;
906226148Sdes			case SYS_socketpair:
907226153Sdes				putchar('(');
908226164Sdes				sockdomainname(*ip);
909158766Snetchild				ip++;
910158766Snetchild				narg--;
911226153Sdes				putchar(',');
912254922Sjilles				socktypenamewithflags(*ip);
913158766Snetchild				ip++;
914158766Snetchild				narg--;
915158766Snetchild				c = ',';
916226148Sdes				break;
917226148Sdes			case SYS_getrlimit:
918226148Sdes			case SYS_setrlimit:
919226153Sdes				putchar('(');
920226164Sdes				rlimitname(*ip);
921158766Snetchild				ip++;
922158766Snetchild				narg--;
923158766Snetchild				c = ',';
924226148Sdes				break;
925226148Sdes			case SYS_quotactl:
926226150Sdes				print_number(ip, narg, c);
927226153Sdes				putchar(',');
928226164Sdes				quotactlname(*ip);
929158766Snetchild				ip++;
930158766Snetchild				narg--;
931158766Snetchild				c = ',';
932226148Sdes				break;
933226148Sdes			case SYS_nfssvc:
934226153Sdes				putchar('(');
935226164Sdes				nfssvcname(*ip);
936158766Snetchild				ip++;
937158766Snetchild				narg--;
938158766Snetchild				c = ',';
939226148Sdes				break;
940226148Sdes			case SYS_rtprio:
941226153Sdes				putchar('(');
942226164Sdes				rtprioname(*ip);
943158766Snetchild				ip++;
944158766Snetchild				narg--;
945158766Snetchild				c = ',';
946226148Sdes				break;
947226148Sdes			case SYS___semctl:
948226150Sdes				print_number(ip, narg, c);
949226150Sdes				print_number(ip, narg, c);
950226153Sdes				putchar(',');
951226164Sdes				semctlname(*ip);
952158766Snetchild				ip++;
953158766Snetchild				narg--;
954226148Sdes				break;
955226148Sdes			case SYS_semget:
956226150Sdes				print_number(ip, narg, c);
957226150Sdes				print_number(ip, narg, c);
958226153Sdes				putchar(',');
959226164Sdes				semgetname(*ip);
960158766Snetchild				ip++;
961158766Snetchild				narg--;
962226148Sdes				break;
963226148Sdes			case SYS_msgctl:
964226150Sdes				print_number(ip, narg, c);
965226153Sdes				putchar(',');
966226164Sdes				shmctlname(*ip);
967158766Snetchild				ip++;
968158766Snetchild				narg--;
969226148Sdes				break;
970226148Sdes			case SYS_shmat:
971226150Sdes				print_number(ip, narg, c);
972226150Sdes				print_number(ip, narg, c);
973226153Sdes				putchar(',');
974226164Sdes				shmatname(*ip);
975158766Snetchild				ip++;
976158766Snetchild				narg--;
977226148Sdes				break;
978226148Sdes			case SYS_shmctl:
979226150Sdes				print_number(ip, narg, c);
980226153Sdes				putchar(',');
981226164Sdes				shmctlname(*ip);
982158766Snetchild				ip++;
983158766Snetchild				narg--;
984226148Sdes				break;
985226148Sdes			case SYS_minherit:
986226150Sdes				print_number(ip, narg, c);
987226150Sdes				print_number(ip, narg, c);
988226153Sdes				putchar(',');
989226164Sdes				minheritname(*ip);
990158766Snetchild				ip++;
991158766Snetchild				narg--;
992226148Sdes				break;
993226148Sdes			case SYS_rfork:
994226153Sdes				putchar('(');
995226164Sdes				rforkname(*ip);
996158766Snetchild				ip++;
997158766Snetchild				narg--;
998158766Snetchild				c = ',';
999226148Sdes				break;
1000226148Sdes			case SYS_lio_listio:
1001226153Sdes				putchar('(');
1002226164Sdes				lio_listioname(*ip);
1003158766Snetchild				ip++;
1004158766Snetchild				narg--;
1005158766Snetchild				c = ',';
1006226148Sdes				break;
1007226148Sdes			case SYS_mlockall:
1008226153Sdes				putchar('(');
1009226164Sdes				mlockallname(*ip);
1010158766Snetchild				ip++;
1011158766Snetchild				narg--;
1012226148Sdes				break;
1013226148Sdes			case SYS_sched_setscheduler:
1014226150Sdes				print_number(ip, narg, c);
1015226153Sdes				putchar(',');
1016226164Sdes				schedpolicyname(*ip);
1017158766Snetchild				ip++;
1018158766Snetchild				narg--;
1019226148Sdes				break;
1020226148Sdes			case SYS_sched_get_priority_max:
1021226148Sdes			case SYS_sched_get_priority_min:
1022226153Sdes				putchar('(');
1023226164Sdes				schedpolicyname(*ip);
1024158766Snetchild				ip++;
1025158766Snetchild				narg--;
1026226148Sdes				break;
1027226148Sdes			case SYS_sendfile:
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);
1033226150Sdes				print_number(ip, narg, c);
1034226153Sdes				putchar(',');
1035226164Sdes				sendfileflagsname(*ip);
1036158766Snetchild				ip++;
1037158766Snetchild				narg--;
1038226148Sdes				break;
1039226148Sdes			case SYS_kldsym:
1040226150Sdes				print_number(ip, narg, c);
1041226153Sdes				putchar(',');
1042226164Sdes				kldsymcmdname(*ip);
1043158766Snetchild				ip++;
1044158766Snetchild				narg--;
1045226148Sdes				break;
1046226148Sdes			case SYS_sigprocmask:
1047226153Sdes				putchar('(');
1048226164Sdes				sigprocmaskhowname(*ip);
1049158766Snetchild				ip++;
1050158766Snetchild				narg--;
1051158766Snetchild				c = ',';
1052226148Sdes				break;
1053226148Sdes			case SYS___acl_get_file:
1054226148Sdes			case SYS___acl_set_file:
1055226148Sdes			case SYS___acl_get_fd:
1056226148Sdes			case SYS___acl_set_fd:
1057226148Sdes			case SYS___acl_delete_file:
1058226148Sdes			case SYS___acl_delete_fd:
1059226148Sdes			case SYS___acl_aclcheck_file:
1060226148Sdes			case SYS___acl_aclcheck_fd:
1061226148Sdes			case SYS___acl_get_link:
1062226148Sdes			case SYS___acl_set_link:
1063226148Sdes			case SYS___acl_delete_link:
1064226148Sdes			case SYS___acl_aclcheck_link:
1065226150Sdes				print_number(ip, narg, c);
1066226153Sdes				putchar(',');
1067226164Sdes				acltypename(*ip);
1068158766Snetchild				ip++;
1069158766Snetchild				narg--;
1070226148Sdes				break;
1071226148Sdes			case SYS_sigaction:
1072226153Sdes				putchar('(');
1073226164Sdes				signame(*ip);
1074158766Snetchild				ip++;
1075158766Snetchild				narg--;
1076158766Snetchild				c = ',';
1077226148Sdes				break;
1078226148Sdes			case SYS_extattrctl:
1079226150Sdes				print_number(ip, narg, c);
1080226153Sdes				putchar(',');
1081226164Sdes				extattrctlname(*ip);
1082158766Snetchild				ip++;
1083158766Snetchild				narg--;
1084226148Sdes				break;
1085226148Sdes			case SYS_nmount:
1086226150Sdes				print_number(ip, narg, c);
1087226150Sdes				print_number(ip, narg, c);
1088226153Sdes				putchar(',');
1089226164Sdes				mountflagsname(*ip);
1090158766Snetchild				ip++;
1091158766Snetchild				narg--;
1092226148Sdes				break;
1093226148Sdes			case SYS_thr_create:
1094226150Sdes				print_number(ip, narg, c);
1095226150Sdes				print_number(ip, narg, c);
1096226153Sdes				putchar(',');
1097226164Sdes				thrcreateflagsname(*ip);
1098158766Snetchild				ip++;
1099158766Snetchild				narg--;
1100226148Sdes				break;
1101226148Sdes			case SYS_thr_kill:
1102226150Sdes				print_number(ip, narg, c);
1103226153Sdes				putchar(',');
1104226164Sdes				signame(*ip);
1105158766Snetchild				ip++;
1106158766Snetchild				narg--;
1107226148Sdes				break;
1108226148Sdes			case SYS_kldunloadf:
1109226150Sdes				print_number(ip, narg, c);
1110226153Sdes				putchar(',');
1111226164Sdes				kldunloadfflagsname(*ip);
1112158766Snetchild				ip++;
1113158766Snetchild				narg--;
1114226148Sdes				break;
1115254291Sjilles			case SYS_linkat:
1116254291Sjilles			case SYS_renameat:
1117254291Sjilles			case SYS_symlinkat:
1118254291Sjilles				print_number(ip, narg, c);
1119254291Sjilles				putchar(',');
1120254291Sjilles				atfdname(*ip, decimal);
1121254291Sjilles				ip++;
1122254291Sjilles				narg--;
1123254291Sjilles				break;
1124247602Spjd			case SYS_cap_fcntls_limit:
1125247602Spjd				print_number(ip, narg, c);
1126247602Spjd				putchar(',');
1127247602Spjd				arg = *ip;
1128247602Spjd				ip++;
1129247602Spjd				narg--;
1130247602Spjd				capfcntlname(arg);
1131247602Spjd				break;
1132232072Sjhb			case SYS_posix_fadvise:
1133232128Sjhb				print_number(ip, narg, c);
1134232128Sjhb				print_number(ip, narg, c);
1135232128Sjhb				print_number(ip, narg, c);
1136232072Sjhb				(void)putchar(',');
1137232072Sjhb				fadvisebehavname((int)*ip);
1138232072Sjhb				ip++;
1139232072Sjhb				narg--;
1140232072Sjhb				break;
11411590Srgrimes			}
11421590Srgrimes		}
1143199024Sattilio		while (narg > 0) {
1144226150Sdes			print_number(ip, narg, c);
11451590Srgrimes		}
1146226153Sdes		putchar(')');
11471590Srgrimes	}
1148226153Sdes	putchar('\n');
11491590Srgrimes}
11501590Srgrimes
1151100824Sdwmalonevoid
1152219043Sdchaginktrsysret(struct ktr_sysret *ktr, u_int flags)
11531590Srgrimes{
1154100824Sdwmalone	register_t ret = ktr->ktr_retval;
1155100824Sdwmalone	int error = ktr->ktr_error;
1156100824Sdwmalone	int code = ktr->ktr_code;
11571590Srgrimes
1158219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
1159219043Sdchagin	    (code >= nsyscalls || code < 0))
1160226153Sdes		printf("[%d] ", code);
11611590Srgrimes	else
1162226153Sdes		printf("%s ", syscallnames[code]);
11631590Srgrimes
11641590Srgrimes	if (error == 0) {
11651590Srgrimes		if (fancy) {
1166226153Sdes			printf("%ld", (long)ret);
11671590Srgrimes			if (ret < 0 || ret > 9)
1168226153Sdes				printf("/%#lx", (unsigned long)ret);
11691590Srgrimes		} else {
11701590Srgrimes			if (decimal)
1171226153Sdes				printf("%ld", (long)ret);
11721590Srgrimes			else
1173226153Sdes				printf("%#lx", (unsigned long)ret);
11741590Srgrimes		}
11751590Srgrimes	} else if (error == ERESTART)
1176226153Sdes		printf("RESTART");
11771590Srgrimes	else if (error == EJUSTRETURN)
1178226153Sdes		printf("JUSTRETURN");
11791590Srgrimes	else {
1180226153Sdes		printf("-1 errno %d", ktr->ktr_error);
11811590Srgrimes		if (fancy)
1182226153Sdes			printf(" %s", strerror(ktr->ktr_error));
11831590Srgrimes	}
1184226153Sdes	putchar('\n');
11851590Srgrimes}
11861590Srgrimes
1187100824Sdwmalonevoid
1188100824Sdwmalonektrnamei(char *cp, int len)
11891590Srgrimes{
1190226153Sdes	printf("\"%.*s\"\n", len, cp);
11911590Srgrimes}
11921590Srgrimes
1193100824Sdwmalonevoid
1194115759Speterhexdump(char *p, int len, int screenwidth)
11951590Srgrimes{
1196115759Speter	int n, i;
1197115759Speter	int width;
1198115759Speter
1199115759Speter	width = 0;
1200115759Speter	do {
1201115759Speter		width += 2;
1202115759Speter		i = 13;			/* base offset */
1203115759Speter		i += (width / 2) + 1;	/* spaces every second byte */
1204115759Speter		i += (width * 2);	/* width of bytes */
1205115759Speter		i += 3;			/* "  |" */
1206115759Speter		i += width;		/* each byte */
1207115759Speter		i += 1;			/* "|" */
1208115759Speter	} while (i < screenwidth);
1209115759Speter	width -= 2;
1210115759Speter
1211115759Speter	for (n = 0; n < len; n += width) {
1212115759Speter		for (i = n; i < n + width; i++) {
1213115759Speter			if ((i % width) == 0) {	/* beginning of line */
1214115759Speter				printf("       0x%04x", i);
1215115759Speter			}
1216115759Speter			if ((i % 2) == 0) {
1217115759Speter				printf(" ");
1218115759Speter			}
1219115759Speter			if (i < len)
1220115759Speter				printf("%02x", p[i] & 0xff);
1221115759Speter			else
1222115759Speter				printf("  ");
1223115759Speter		}
1224115759Speter		printf("  |");
1225115759Speter		for (i = n; i < n + width; i++) {
1226115759Speter			if (i >= len)
1227115759Speter				break;
1228115759Speter			if (p[i] >= ' ' && p[i] <= '~')
1229115759Speter				printf("%c", p[i]);
1230115759Speter			else
1231115759Speter				printf(".");
1232115759Speter		}
1233115759Speter		printf("|\n");
1234115759Speter	}
1235115759Speter	if ((i % width) != 0)
1236115759Speter		printf("\n");
1237115759Speter}
1238115759Speter
1239115759Spetervoid
1240115759Spetervisdump(char *dp, int datalen, int screenwidth)
1241115759Speter{
1242115759Speter	int col = 0;
1243100824Sdwmalone	char *cp;
1244100824Sdwmalone	int width;
12451590Srgrimes	char visbuf[5];
12461590Srgrimes
1247226153Sdes	printf("       \"");
12481590Srgrimes	col = 8;
12491590Srgrimes	for (;datalen > 0; datalen--, dp++) {
1250226153Sdes		 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
12511590Srgrimes		cp = visbuf;
12521590Srgrimes		/*
12531590Srgrimes		 * Keep track of printables and
12541590Srgrimes		 * space chars (like fold(1)).
12551590Srgrimes		 */
12561590Srgrimes		if (col == 0) {
1257226153Sdes			putchar('\t');
12581590Srgrimes			col = 8;
12591590Srgrimes		}
12601590Srgrimes		switch(*cp) {
12611590Srgrimes		case '\n':
12621590Srgrimes			col = 0;
1263226153Sdes			putchar('\n');
12641590Srgrimes			continue;
12651590Srgrimes		case '\t':
12661590Srgrimes			width = 8 - (col&07);
12671590Srgrimes			break;
12681590Srgrimes		default:
12691590Srgrimes			width = strlen(cp);
12701590Srgrimes		}
12711590Srgrimes		if (col + width > (screenwidth-2)) {
1272226153Sdes			printf("\\\n\t");
12731590Srgrimes			col = 8;
12741590Srgrimes		}
12751590Srgrimes		col += width;
12761590Srgrimes		do {
1277226153Sdes			putchar(*cp++);
12781590Srgrimes		} while (*cp);
12791590Srgrimes	}
12801590Srgrimes	if (col == 0)
1281226153Sdes		printf("       ");
1282226153Sdes	printf("\"\n");
12831590Srgrimes}
12841590Srgrimes
1285115759Spetervoid
1286115759Speterktrgenio(struct ktr_genio *ktr, int len)
1287115759Speter{
1288115759Speter	int datalen = len - sizeof (struct ktr_genio);
1289115759Speter	char *dp = (char *)ktr + sizeof (struct ktr_genio);
1290115759Speter	static int screenwidth = 0;
1291115759Speter	int i, binary;
1292115759Speter
1293251072Spjd	printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1294251072Spjd		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1295251072Spjd		datalen == 1 ? "" : "s");
1296251072Spjd	if (suppressdata)
1297251072Spjd		return;
1298115759Speter	if (screenwidth == 0) {
1299115759Speter		struct winsize ws;
1300115759Speter
1301115759Speter		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1302115759Speter		    ws.ws_col > 8)
1303115759Speter			screenwidth = ws.ws_col;
1304115759Speter		else
1305115759Speter			screenwidth = 80;
1306115759Speter	}
1307115759Speter	if (maxdata && datalen > maxdata)
1308115759Speter		datalen = maxdata;
1309115759Speter
1310115759Speter	for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1311115759Speter		if (dp[i] >= 32 && dp[i] < 127)
1312115759Speter			continue;
1313115759Speter		if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1314115759Speter			continue;
1315115759Speter		binary = 1;
1316115759Speter	}
1317115759Speter	if (binary)
1318115759Speter		hexdump(dp, datalen, screenwidth);
1319115759Speter	else
1320115759Speter		visdump(dp, datalen, screenwidth);
1321115759Speter}
1322115759Speter
1323100824Sdwmaloneconst char *signames[] = {
13241590Srgrimes	"NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",	/*  1 - 6  */
13251590Srgrimes	"EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",		/*  7 - 12 */
13261590Srgrimes	"PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",		/* 13 - 18 */
13271590Srgrimes	"CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",		/* 19 - 24 */
13281590Srgrimes	"XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",	/* 25 - 30 */
13291590Srgrimes	"USR2", NULL,						/* 31 - 32 */
13301590Srgrimes};
13311590Srgrimes
1332100824Sdwmalonevoid
1333219138Sdchaginktrpsig(struct ktr_psig *psig)
13341590Srgrimes{
1335219138Sdchagin	if (psig->signo > 0 && psig->signo < NSIG)
1336226153Sdes		printf("SIG%s ", signames[psig->signo]);
1337160294Skib	else
1338226153Sdes		printf("SIG %d ", psig->signo);
1339240820Sjilles	if (psig->action == SIG_DFL) {
1340240820Sjilles		printf("SIG_DFL code=");
1341240820Sjilles		sigcodename(psig->signo, psig->code);
1342240820Sjilles		putchar('\n');
1343240820Sjilles	} else {
1344240820Sjilles		printf("caught handler=0x%lx mask=0x%x code=",
1345240820Sjilles		    (u_long)psig->action, psig->mask.__bits[0]);
1346240820Sjilles		sigcodename(psig->signo, psig->code);
1347240820Sjilles		putchar('\n');
1348100824Sdwmalone	}
13491590Srgrimes}
13501590Srgrimes
1351100824Sdwmalonevoid
1352234494Sjhbktrcsw_old(struct ktr_csw_old *cs)
13531590Srgrimes{
1354226153Sdes	printf("%s %s\n", cs->out ? "stop" : "resume",
13551590Srgrimes		cs->user ? "user" : "kernel");
13561590Srgrimes}
13571590Srgrimes
1358234494Sjhbvoid
1359234494Sjhbktrcsw(struct ktr_csw *cs)
1360234494Sjhb{
1361234494Sjhb	printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume",
1362234494Sjhb	    cs->user ? "user" : "kernel", cs->wmesg);
1363234494Sjhb}
1364234494Sjhb
1365165916Sjhb#define	UTRACE_DLOPEN_START		1
1366165916Sjhb#define	UTRACE_DLOPEN_STOP		2
1367165916Sjhb#define	UTRACE_DLCLOSE_START		3
1368165916Sjhb#define	UTRACE_DLCLOSE_STOP		4
1369165916Sjhb#define	UTRACE_LOAD_OBJECT		5
1370165916Sjhb#define	UTRACE_UNLOAD_OBJECT		6
1371165916Sjhb#define	UTRACE_ADD_RUNDEP		7
1372165916Sjhb#define	UTRACE_PRELOAD_FINISHED		8
1373165916Sjhb#define	UTRACE_INIT_CALL		9
1374165916Sjhb#define	UTRACE_FINI_CALL		10
1375165916Sjhb
1376165916Sjhbstruct utrace_rtld {
1377165916Sjhb	char sig[4];				/* 'RTLD' */
1378165916Sjhb	int event;
1379165916Sjhb	void *handle;
1380165916Sjhb	void *mapbase;
1381165916Sjhb	size_t mapsize;
1382165916Sjhb	int refcnt;
1383165916Sjhb	char name[MAXPATHLEN];
1384165916Sjhb};
1385165916Sjhb
1386165916Sjhbvoid
1387165916Sjhbktruser_rtld(int len, unsigned char *p)
1388165916Sjhb{
1389165916Sjhb	struct utrace_rtld *ut = (struct utrace_rtld *)p;
1390165916Sjhb	void *parent;
1391165916Sjhb	int mode;
1392165916Sjhb
1393165916Sjhb	switch (ut->event) {
1394165916Sjhb	case UTRACE_DLOPEN_START:
1395165916Sjhb		mode = ut->refcnt;
1396165916Sjhb		printf("dlopen(%s, ", ut->name);
1397165916Sjhb		switch (mode & RTLD_MODEMASK) {
1398165916Sjhb		case RTLD_NOW:
1399165916Sjhb			printf("RTLD_NOW");
1400165916Sjhb			break;
1401165916Sjhb		case RTLD_LAZY:
1402165916Sjhb			printf("RTLD_LAZY");
1403165916Sjhb			break;
1404165916Sjhb		default:
1405165916Sjhb			printf("%#x", mode & RTLD_MODEMASK);
1406165916Sjhb		}
1407165916Sjhb		if (mode & RTLD_GLOBAL)
1408165916Sjhb			printf(" | RTLD_GLOBAL");
1409165916Sjhb		if (mode & RTLD_TRACE)
1410165916Sjhb			printf(" | RTLD_TRACE");
1411165916Sjhb		if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
1412165916Sjhb			printf(" | %#x", mode &
1413165916Sjhb			    ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
1414165916Sjhb		printf(")\n");
1415165916Sjhb		break;
1416165916Sjhb	case UTRACE_DLOPEN_STOP:
1417165916Sjhb		printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
1418165916Sjhb		    ut->refcnt);
1419165916Sjhb		break;
1420165916Sjhb	case UTRACE_DLCLOSE_START:
1421165916Sjhb		printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
1422165916Sjhb		    ut->refcnt);
1423165916Sjhb		break;
1424165916Sjhb	case UTRACE_DLCLOSE_STOP:
1425165916Sjhb		printf("dlclose(%p) finished\n", ut->handle);
1426165916Sjhb		break;
1427165916Sjhb	case UTRACE_LOAD_OBJECT:
1428165916Sjhb		printf("RTLD: loaded   %p @ %p - %p (%s)\n", ut->handle,
1429165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1430165916Sjhb		    ut->name);
1431165916Sjhb		break;
1432165916Sjhb	case UTRACE_UNLOAD_OBJECT:
1433165916Sjhb		printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
1434165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1435165916Sjhb		    ut->name);
1436165916Sjhb		break;
1437165916Sjhb	case UTRACE_ADD_RUNDEP:
1438165916Sjhb		parent = ut->mapbase;
1439165916Sjhb		printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
1440165916Sjhb		    ut->handle, ut->name, ut->refcnt);
1441165916Sjhb		break;
1442165916Sjhb	case UTRACE_PRELOAD_FINISHED:
1443165916Sjhb		printf("RTLD: LD_PRELOAD finished\n");
1444165916Sjhb		break;
1445165916Sjhb	case UTRACE_INIT_CALL:
1446165916Sjhb		printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1447165916Sjhb		    ut->name);
1448165916Sjhb		break;
1449165916Sjhb	case UTRACE_FINI_CALL:
1450165916Sjhb		printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1451165916Sjhb		    ut->name);
1452165916Sjhb		break;
1453165916Sjhb	default:
1454165916Sjhb		p += 4;
1455165916Sjhb		len -= 4;
1456165916Sjhb		printf("RTLD: %d ", len);
1457165916Sjhb		while (len--)
1458165916Sjhb			if (decimal)
1459165916Sjhb				printf(" %d", *p++);
1460165916Sjhb			else
1461165916Sjhb				printf(" %02x", *p++);
1462165916Sjhb		printf("\n");
1463165916Sjhb	}
1464165916Sjhb}
1465165916Sjhb
1466165812Sjhbstruct utrace_malloc {
1467165812Sjhb	void *p;
1468165812Sjhb	size_t s;
1469165812Sjhb	void *r;
1470165812Sjhb};
1471165812Sjhb
1472100824Sdwmalonevoid
1473226329Sdesktruser_malloc(unsigned char *p)
1474165812Sjhb{
1475165812Sjhb	struct utrace_malloc *ut = (struct utrace_malloc *)p;
1476165812Sjhb
1477199265Scperciva	if (ut->p == (void *)(intptr_t)(-1))
1478199265Scperciva		printf("malloc_init()\n");
1479199265Scperciva	else if (ut->s == 0)
1480199265Scperciva		printf("free(%p)\n", ut->p);
1481199265Scperciva	else if (ut->p == NULL)
1482199265Scperciva		printf("%p = malloc(%zu)\n", ut->r, ut->s);
1483199265Scperciva	else
1484199265Scperciva		printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1485165812Sjhb}
1486165812Sjhb
1487165812Sjhbvoid
1488100824Sdwmalonektruser(int len, unsigned char *p)
148918400Sphk{
1490165812Sjhb
1491165916Sjhb	if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1492165916Sjhb		ktruser_rtld(len, p);
1493165916Sjhb		return;
1494165916Sjhb	}
1495165916Sjhb
1496165812Sjhb	if (len == sizeof(struct utrace_malloc)) {
1497226329Sdes		ktruser_malloc(p);
1498165812Sjhb		return;
1499165812Sjhb	}
1500165812Sjhb
1501226153Sdes	printf("%d ", len);
150218470Sphk	while (len--)
1503127402Sphk		if (decimal)
1504226153Sdes			printf(" %d", *p++);
1505127402Sphk		else
1506226153Sdes			printf(" %02x", *p++);
1507226153Sdes	printf("\n");
150818400Sphk}
150918400Sphk
1510100824Sdwmalonevoid
1511255219Spjdktrcaprights(cap_rights_t *rightsp)
1512255219Spjd{
1513255219Spjd
1514255219Spjd	printf("cap_rights_t ");
1515255219Spjd	capname(rightsp);
1516255219Spjd	printf("\n");
1517255219Spjd}
1518255219Spjd
1519255219Spjdvoid
1520176471Sdesktrsockaddr(struct sockaddr *sa)
1521176471Sdes{
1522176471Sdes/*
1523176471Sdes TODO: Support additional address families
1524176471Sdes	#include <netnatm/natm.h>
1525176471Sdes	struct sockaddr_natm	*natm;
1526252356Sdavide	#include <netsmb/netbios.h>
1527252356Sdavide	struct sockaddr_nb	*nb;
1528176471Sdes*/
1529176471Sdes	char addr[64];
1530176471Sdes
1531176471Sdes	/*
1532176471Sdes	 * note: ktrstruct() has already verified that sa points to a
1533176471Sdes	 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1534176471Sdes	 * sa->sa_len bytes long.
1535176471Sdes	 */
1536176471Sdes	printf("struct sockaddr { ");
1537176471Sdes	sockfamilyname(sa->sa_family);
1538176471Sdes	printf(", ");
1539176471Sdes
1540176471Sdes#define check_sockaddr_len(n)					\
1541226329Sdes	if (sa_##n.s##n##_len < sizeof(struct sockaddr_##n)) {	\
1542176471Sdes		printf("invalid");				\
1543176471Sdes		break;						\
1544176471Sdes	}
1545176471Sdes
1546176471Sdes	switch(sa->sa_family) {
1547176471Sdes	case AF_INET: {
1548226329Sdes		struct sockaddr_in sa_in;
1549176471Sdes
1550226329Sdes		memset(&sa_in, 0, sizeof(sa_in));
1551246719Szont		memcpy(&sa_in, sa, sa->sa_len);
1552176471Sdes		check_sockaddr_len(in);
1553226329Sdes		inet_ntop(AF_INET, &sa_in.sin_addr, addr, sizeof addr);
1554226329Sdes		printf("%s:%u", addr, ntohs(sa_in.sin_port));
1555176471Sdes		break;
1556176471Sdes	}
1557176471Sdes#ifdef NETATALK
1558176471Sdes	case AF_APPLETALK: {
1559226329Sdes		struct sockaddr_at	sa_at;
1560176471Sdes		struct netrange		*nr;
1561176471Sdes
1562226329Sdes		memset(&sa_at, 0, sizeof(sa_at));
1563246719Szont		memcpy(&sa_at, sa, sa->sa_len);
1564176471Sdes		check_sockaddr_len(at);
1565226329Sdes		nr = &sa_at.sat_range.r_netrange;
1566226329Sdes		printf("%d.%d, %d-%d, %d", ntohs(sa_at.sat_addr.s_net),
1567226329Sdes			sa_at.sat_addr.s_node, ntohs(nr->nr_firstnet),
1568176471Sdes			ntohs(nr->nr_lastnet), nr->nr_phase);
1569176471Sdes		break;
1570176471Sdes	}
1571176471Sdes#endif
1572176471Sdes	case AF_INET6: {
1573226329Sdes		struct sockaddr_in6 sa_in6;
1574176471Sdes
1575226329Sdes		memset(&sa_in6, 0, sizeof(sa_in6));
1576246719Szont		memcpy(&sa_in6, sa, sa->sa_len);
1577176471Sdes		check_sockaddr_len(in6);
1578251486Sae		getnameinfo((struct sockaddr *)&sa_in6, sizeof(sa_in6),
1579251486Sae		    addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
1580226329Sdes		printf("[%s]:%u", addr, htons(sa_in6.sin6_port));
1581176471Sdes		break;
1582176471Sdes	}
1583176471Sdes#ifdef IPX
1584176471Sdes	case AF_IPX: {
1585226329Sdes		struct sockaddr_ipx sa_ipx;
1586176471Sdes
1587226329Sdes		memset(&sa_ipx, 0, sizeof(sa_ipx));
1588246719Szont		memcpy(&sa_ipx, sa, sa->sa_len);
1589176471Sdes		check_sockaddr_len(ipx);
1590176471Sdes		/* XXX wish we had ipx_ntop */
1591226329Sdes		printf("%s", ipx_ntoa(sa_ipx.sipx_addr));
1592226329Sdes		free(sa_ipx);
1593176471Sdes		break;
1594176471Sdes	}
1595176471Sdes#endif
1596176471Sdes	case AF_UNIX: {
1597226329Sdes		struct sockaddr_un sa_un;
1598176471Sdes
1599226329Sdes		memset(&sa_un, 0, sizeof(sa_un));
1600246719Szont		memcpy(&sa_un, sa, sa->sa_len);
1601226329Sdes		printf("%.*s", (int)sizeof(sa_un.sun_path), sa_un.sun_path);
1602176471Sdes		break;
1603176471Sdes	}
1604176471Sdes	default:
1605176471Sdes		printf("unknown address family");
1606176471Sdes	}
1607176471Sdes	printf(" }\n");
1608176471Sdes}
1609176471Sdes
1610176471Sdesvoid
1611176471Sdesktrstat(struct stat *statp)
1612176471Sdes{
1613176471Sdes	char mode[12], timestr[PATH_MAX + 4];
1614176471Sdes	struct passwd *pwd;
1615176471Sdes	struct group  *grp;
1616176471Sdes	struct tm *tm;
1617176471Sdes
1618176471Sdes	/*
1619176471Sdes	 * note: ktrstruct() has already verified that statp points to a
1620176471Sdes	 * buffer exactly sizeof(struct stat) bytes long.
1621176471Sdes	 */
1622176471Sdes	printf("struct stat {");
1623176471Sdes	strmode(statp->st_mode, mode);
1624176471Sdes	printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ",
1625176471Sdes		(uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode,
1626176471Sdes		(uintmax_t)statp->st_nlink);
1627176471Sdes	if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1628176471Sdes		printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1629176471Sdes	else
1630176471Sdes		printf("uid=\"%s\", ", pwd->pw_name);
1631176471Sdes	if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1632176471Sdes		printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1633176471Sdes	else
1634176471Sdes		printf("gid=\"%s\", ", grp->gr_name);
1635176471Sdes	printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1636176471Sdes	printf("atime=");
1637176471Sdes	if (resolv == 0)
1638205793Sed		printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1639176471Sdes	else {
1640205793Sed		tm = localtime(&statp->st_atim.tv_sec);
1641226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1642176471Sdes		printf("\"%s\"", timestr);
1643176471Sdes	}
1644205793Sed	if (statp->st_atim.tv_nsec != 0)
1645205793Sed		printf(".%09ld, ", statp->st_atim.tv_nsec);
1646176471Sdes	else
1647176471Sdes		printf(", ");
1648176471Sdes	printf("stime=");
1649176471Sdes	if (resolv == 0)
1650205793Sed		printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1651176471Sdes	else {
1652205793Sed		tm = localtime(&statp->st_mtim.tv_sec);
1653226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1654176471Sdes		printf("\"%s\"", timestr);
1655176471Sdes	}
1656205793Sed	if (statp->st_mtim.tv_nsec != 0)
1657205793Sed		printf(".%09ld, ", statp->st_mtim.tv_nsec);
1658176471Sdes	else
1659176471Sdes		printf(", ");
1660176471Sdes	printf("ctime=");
1661176471Sdes	if (resolv == 0)
1662205793Sed		printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1663176471Sdes	else {
1664205793Sed		tm = localtime(&statp->st_ctim.tv_sec);
1665226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1666176471Sdes		printf("\"%s\"", timestr);
1667176471Sdes	}
1668205793Sed	if (statp->st_ctim.tv_nsec != 0)
1669205793Sed		printf(".%09ld, ", statp->st_ctim.tv_nsec);
1670176471Sdes	else
1671176471Sdes		printf(", ");
1672176471Sdes	printf("birthtime=");
1673176471Sdes	if (resolv == 0)
1674205793Sed		printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
1675176471Sdes	else {
1676205793Sed		tm = localtime(&statp->st_birthtim.tv_sec);
1677226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1678176471Sdes		printf("\"%s\"", timestr);
1679176471Sdes	}
1680205793Sed	if (statp->st_birthtim.tv_nsec != 0)
1681205793Sed		printf(".%09ld, ", statp->st_birthtim.tv_nsec);
1682176471Sdes	else
1683176471Sdes		printf(", ");
1684176471Sdes	printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1685176471Sdes		(uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
1686176471Sdes		(intmax_t)statp->st_blocks, statp->st_flags);
1687176471Sdes	printf(" }\n");
1688176471Sdes}
1689176471Sdes
1690176471Sdesvoid
1691176471Sdesktrstruct(char *buf, size_t buflen)
1692176471Sdes{
1693176471Sdes	char *name, *data;
1694176471Sdes	size_t namelen, datalen;
1695176471Sdes	int i;
1696255219Spjd	cap_rights_t rights;
1697204045Simp	struct stat sb;
1698204045Simp	struct sockaddr_storage ss;
1699176471Sdes
1700176471Sdes	for (name = buf, namelen = 0;
1701176471Sdes	     namelen < buflen && name[namelen] != '\0';
1702176471Sdes	     ++namelen)
1703176471Sdes		/* nothing */;
1704176471Sdes	if (namelen == buflen)
1705176471Sdes		goto invalid;
1706176471Sdes	if (name[namelen] != '\0')
1707176471Sdes		goto invalid;
1708176471Sdes	data = buf + namelen + 1;
1709176471Sdes	datalen = buflen - namelen - 1;
1710176471Sdes	if (datalen == 0)
1711176471Sdes		goto invalid;
1712176471Sdes	/* sanity check */
1713226329Sdes	for (i = 0; i < (int)namelen; ++i)
1714226329Sdes		if (!isalpha(name[i]))
1715176471Sdes			goto invalid;
1716255219Spjd	if (strcmp(name, "caprights") == 0) {
1717255219Spjd		if (datalen != sizeof(cap_rights_t))
1718255219Spjd			goto invalid;
1719255219Spjd		memcpy(&rights, data, datalen);
1720255219Spjd		ktrcaprights(&rights);
1721255219Spjd	} else if (strcmp(name, "stat") == 0) {
1722176471Sdes		if (datalen != sizeof(struct stat))
1723176471Sdes			goto invalid;
1724204045Simp		memcpy(&sb, data, datalen);
1725204045Simp		ktrstat(&sb);
1726176471Sdes	} else if (strcmp(name, "sockaddr") == 0) {
1727204045Simp		if (datalen > sizeof(ss))
1728204045Simp			goto invalid;
1729204045Simp		memcpy(&ss, data, datalen);
1730246720Szont		if (datalen != ss.ss_len)
1731176471Sdes			goto invalid;
1732204045Simp		ktrsockaddr((struct sockaddr *)&ss);
1733176471Sdes	} else {
1734176471Sdes		printf("unknown structure\n");
1735176471Sdes	}
1736176471Sdes	return;
1737176471Sdesinvalid:
1738176471Sdes	printf("invalid record\n");
1739176471Sdes}
1740176471Sdes
1741226269Sdesvoid
1742226269Sdesktrcapfail(struct ktr_cap_fail *ktr)
1743226269Sdes{
1744226495Sdes	switch (ktr->cap_type) {
1745226495Sdes	case CAPFAIL_NOTCAPABLE:
1746226495Sdes		/* operation on fd with insufficient capabilities */
1747226495Sdes		printf("operation requires ");
1748255219Spjd		capname(&ktr->cap_needed);
1749226495Sdes		printf(", process holds ");
1750255219Spjd		capname(&ktr->cap_held);
1751226495Sdes		break;
1752226495Sdes	case CAPFAIL_INCREASE:
1753226495Sdes		/* requested more capabilities than fd already has */
1754226495Sdes		printf("attempt to increase capabilities from ");
1755255219Spjd		capname(&ktr->cap_held);
1756226505Sdes		printf(" to ");
1757255219Spjd		capname(&ktr->cap_needed);
1758226495Sdes		break;
1759226495Sdes	case CAPFAIL_SYSCALL:
1760226495Sdes		/* called restricted syscall */
1761226495Sdes		printf("disallowed system call");
1762226495Sdes		break;
1763226495Sdes	case CAPFAIL_LOOKUP:
1764226495Sdes		/* used ".." in strict-relative mode */
1765226495Sdes		printf("restricted VFS lookup");
1766226495Sdes		break;
1767226495Sdes	default:
1768226495Sdes		printf("unknown capability failure: ");
1769255219Spjd		capname(&ktr->cap_needed);
1770226495Sdes		printf(" ");
1771255219Spjd		capname(&ktr->cap_held);
1772226495Sdes		break;
1773226495Sdes	}
1774233925Sjhb	printf("\n");
1775226269Sdes}
1776226269Sdes
1777233925Sjhbvoid
1778233925Sjhbktrfault(struct ktr_fault *ktr)
1779233925Sjhb{
1780233925Sjhb
1781233925Sjhb	printf("0x%jx ", ktr->vaddr);
1782233925Sjhb	vmprotname(ktr->type);
1783233925Sjhb	printf("\n");
1784233925Sjhb}
1785233925Sjhb
1786233925Sjhbvoid
1787233925Sjhbktrfaultend(struct ktr_faultend *ktr)
1788233925Sjhb{
1789233925Sjhb
1790233925Sjhb	vmresultname(ktr->result);
1791233925Sjhb	printf("\n");
1792233925Sjhb}
1793233925Sjhb
1794219138Sdchagin#if defined(__amd64__) || defined(__i386__)
1795176471Sdesvoid
1796219138Sdchaginlinux_ktrsyscall(struct ktr_syscall *ktr)
1797219138Sdchagin{
1798219138Sdchagin	int narg = ktr->ktr_narg;
1799219138Sdchagin	register_t *ip;
1800219138Sdchagin
1801219138Sdchagin	if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
1802219138Sdchagin		printf("[%d]", ktr->ktr_code);
1803219138Sdchagin	else
1804219138Sdchagin		printf("%s", linux_syscallnames[ktr->ktr_code]);
1805219138Sdchagin	ip = &ktr->ktr_args[0];
1806219138Sdchagin	if (narg) {
1807219138Sdchagin		char c = '(';
1808219138Sdchagin		while (narg > 0)
1809219138Sdchagin			print_number(ip, narg, c);
1810219138Sdchagin		putchar(')');
1811219138Sdchagin	}
1812219138Sdchagin	putchar('\n');
1813219138Sdchagin}
1814219138Sdchagin
1815219138Sdchaginvoid
1816219138Sdchaginlinux_ktrsysret(struct ktr_sysret *ktr)
1817219138Sdchagin{
1818219138Sdchagin	register_t ret = ktr->ktr_retval;
1819219138Sdchagin	int error = ktr->ktr_error;
1820219138Sdchagin	int code = ktr->ktr_code;
1821219138Sdchagin
1822219138Sdchagin	if (code >= nlinux_syscalls || code < 0)
1823219138Sdchagin		printf("[%d] ", code);
1824219138Sdchagin	else
1825219138Sdchagin		printf("%s ", linux_syscallnames[code]);
1826219138Sdchagin
1827219138Sdchagin	if (error == 0) {
1828219138Sdchagin		if (fancy) {
1829219138Sdchagin			printf("%ld", (long)ret);
1830219138Sdchagin			if (ret < 0 || ret > 9)
1831226153Sdes				printf("/%#lx", (unsigned long)ret);
1832219138Sdchagin		} else {
1833219138Sdchagin			if (decimal)
1834219138Sdchagin				printf("%ld", (long)ret);
1835219138Sdchagin			else
1836226153Sdes				printf("%#lx", (unsigned long)ret);
1837219138Sdchagin		}
1838219138Sdchagin	} else if (error == ERESTART)
1839219138Sdchagin		printf("RESTART");
1840219138Sdchagin	else if (error == EJUSTRETURN)
1841219138Sdchagin		printf("JUSTRETURN");
1842219138Sdchagin	else {
1843219138Sdchagin		if (ktr->ktr_error <= ELAST + 1)
1844219138Sdchagin			error = abs(bsd_to_linux_errno[ktr->ktr_error]);
1845219138Sdchagin		else
1846219138Sdchagin			error = 999;
1847219138Sdchagin		printf("-1 errno %d", error);
1848219138Sdchagin		if (fancy)
1849219138Sdchagin			printf(" %s", strerror(ktr->ktr_error));
1850219138Sdchagin	}
1851219138Sdchagin	putchar('\n');
1852219138Sdchagin}
1853219138Sdchagin#endif
1854219138Sdchagin
1855219138Sdchaginvoid
1856100824Sdwmaloneusage(void)
18571590Srgrimes{
1858219043Sdchagin	fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] "
1859177856Sru	    "[-m maxdata] [-p pid] [-t trstr]\n");
18601590Srgrimes	exit(1);
18611590Srgrimes}
1862