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$");
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>
62255493Sjhb#include <sys/wait.h>
63176471Sdes#ifdef IPX
64176471Sdes#include <sys/types.h>
65176471Sdes#include <netipx/ipx.h>
66176471Sdes#endif
67176471Sdes#ifdef NETATALK
68176471Sdes#include <netatalk/at.h>
69176471Sdes#endif
70190168Sdelphij#include <arpa/inet.h>
71176471Sdes#include <netinet/in.h>
72190168Sdelphij#include <ctype.h>
73165916Sjhb#include <dlfcn.h>
7427443Scharnier#include <err.h>
75176471Sdes#include <grp.h>
76176471Sdes#include <inttypes.h>
7727443Scharnier#include <locale.h>
78251486Sae#include <netdb.h>
79251073Spjd#include <nl_types.h>
80176471Sdes#include <pwd.h>
811590Srgrimes#include <stdio.h>
821590Srgrimes#include <stdlib.h>
831590Srgrimes#include <string.h>
84251073Spjd#include <termios.h>
85176471Sdes#include <time.h>
8627443Scharnier#include <unistd.h>
8727443Scharnier#include <vis.h>
881590Srgrimes#include "ktrace.h"
89158766Snetchild#include "kdump_subr.h"
901590Srgrimes
91219043Sdchaginu_int abidump(struct ktr_header *);
92219043Sdchaginint fetchprocinfo(struct ktr_header *, u_int *);
93100824Sdwmaloneint fread_tail(void *, int, int);
94100824Sdwmalonevoid dumpheader(struct ktr_header *);
95219043Sdchaginvoid ktrsyscall(struct ktr_syscall *, u_int);
96219043Sdchaginvoid ktrsysret(struct ktr_sysret *, u_int);
97100824Sdwmalonevoid ktrnamei(char *, int);
98115759Spetervoid hexdump(char *, int, int);
99115759Spetervoid visdump(char *, int, int);
100100824Sdwmalonevoid ktrgenio(struct ktr_genio *, int);
101219138Sdchaginvoid ktrpsig(struct ktr_psig *);
102100824Sdwmalonevoid ktrcsw(struct ktr_csw *);
103234494Sjhbvoid ktrcsw_old(struct ktr_csw_old *);
104226329Sdesvoid ktruser_malloc(unsigned char *);
105226329Sdesvoid ktruser_rtld(int, unsigned char *);
106100824Sdwmalonevoid ktruser(int, unsigned char *);
107255219Spjdvoid ktrcaprights(cap_rights_t *);
108176471Sdesvoid ktrsockaddr(struct sockaddr *);
109176471Sdesvoid ktrstat(struct stat *);
110176471Sdesvoid ktrstruct(char *, size_t);
111226269Sdesvoid ktrcapfail(struct ktr_cap_fail *);
112233925Sjhbvoid ktrfault(struct ktr_fault *);
113233925Sjhbvoid ktrfaultend(struct ktr_faultend *);
114251073Spjdvoid limitfd(int fd);
115100824Sdwmalonevoid usage(void);
116226157Sdesvoid ioctlname(unsigned long, int);
117100824Sdwmalone
118176471Sdesint timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
119219043Sdchagin    resolv = 0, abiflag = 0;
120100824Sdwmaloneconst char *tracefile = DEF_TRACEFILE;
1211590Srgrimesstruct ktr_header ktr_header;
1221590Srgrimes
123176471Sdes#define TIME_FORMAT	"%b %e %T %Y"
1241590Srgrimes#define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
1251590Srgrimes
126226262Sdes#define print_number(i,n,c) do {					\
127226262Sdes	if (decimal)							\
128226262Sdes		printf("%c%jd", c, (intmax_t)*i);			\
129226262Sdes	else								\
130226262Sdes		printf("%c%#jx", c, (uintmax_t)(u_register_t)*i);	\
131226262Sdes	i++;								\
132226262Sdes	n--;								\
133226262Sdes	c = ',';							\
134226164Sdes} while (0)
135219138Sdchagin
136219138Sdchagin#if defined(__amd64__) || defined(__i386__)
137219138Sdchagin
138219138Sdchaginvoid linux_ktrsyscall(struct ktr_syscall *);
139219138Sdchaginvoid linux_ktrsysret(struct ktr_sysret *);
140219138Sdchaginextern char *linux_syscallnames[];
141219138Sdchaginextern int nlinux_syscalls;
142219138Sdchagin
143219138Sdchagin/*
144219138Sdchagin * from linux.h
145219138Sdchagin * Linux syscalls return negative errno's, we do positive and map them
146219138Sdchagin */
147219138Sdchaginstatic int bsd_to_linux_errno[ELAST + 1] = {
148219138Sdchagin	-0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
149219138Sdchagin	-10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
150219138Sdchagin	-20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
151219138Sdchagin	-30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
152219138Sdchagin	-90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
153219138Sdchagin	-100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
154219138Sdchagin	-110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
155219138Sdchagin	-116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
156219138Sdchagin	-6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
157219138Sdchagin	-72, -67, -71
158219138Sdchagin};
159219138Sdchagin#endif
160219138Sdchagin
161219043Sdchaginstruct proc_info
162219043Sdchagin{
163219043Sdchagin	TAILQ_ENTRY(proc_info)	info;
164219043Sdchagin	u_int			sv_flags;
165219043Sdchagin	pid_t			pid;
166219043Sdchagin};
167219043Sdchagin
168219043SdchaginTAILQ_HEAD(trace_procs, proc_info) trace_procs;
169219043Sdchagin
170253456Spjdstatic void
171253456Spjdstrerror_init(void)
172253456Spjd{
173253456Spjd
174253456Spjd	/*
175253456Spjd	 * Cache NLS data before entering capability mode.
176253456Spjd	 * XXXPJD: There should be strerror_init() and strsignal_init() in libc.
177253456Spjd	 */
178253456Spjd	(void)catopen("libc", NL_CAT_LOCALE);
179253456Spjd}
180253456Spjd
181253456Spjdstatic void
182253456Spjdlocaltime_init(void)
183253456Spjd{
184253456Spjd	time_t ltime;
185253456Spjd
186253456Spjd	/*
187253456Spjd	 * Allow localtime(3) to cache /etc/localtime content before entering
188253456Spjd	 * capability mode.
189253456Spjd	 * XXXPJD: There should be localtime_init() in libc.
190253456Spjd	 */
191253456Spjd	(void)time(&ltime);
192253456Spjd	(void)localtime(&ltime);
193253456Spjd}
194253456Spjd
195100824Sdwmaloneint
196100824Sdwmalonemain(int argc, char *argv[])
1971590Srgrimes{
1981590Srgrimes	int ch, ktrlen, size;
199100824Sdwmalone	void *m;
2001590Srgrimes	int trpoints = ALL_POINTS;
201112201Sjhb	int drop_logged;
202115759Speter	pid_t pid = 0;
203219043Sdchagin	u_int sv_flags;
2041590Srgrimes
205226153Sdes	setlocale(LC_CTYPE, "");
20611823Sache
207219043Sdchagin	while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1)
208226153Sdes		switch (ch) {
209219043Sdchagin		case 'A':
210219043Sdchagin			abiflag = 1;
211219043Sdchagin			break;
2121590Srgrimes		case 'f':
2131590Srgrimes			tracefile = optarg;
2141590Srgrimes			break;
2151590Srgrimes		case 'd':
2161590Srgrimes			decimal = 1;
2171590Srgrimes			break;
2181590Srgrimes		case 'l':
2191590Srgrimes			tail = 1;
2201590Srgrimes			break;
2211590Srgrimes		case 'm':
2221590Srgrimes			maxdata = atoi(optarg);
2231590Srgrimes			break;
2241590Srgrimes		case 'n':
2251590Srgrimes			fancy = 0;
2261590Srgrimes			break;
227115759Speter		case 'p':
228115759Speter			pid = atoi(optarg);
229115759Speter			break;
230176471Sdes		case 'r':
231176471Sdes			resolv = 1;
232176471Sdes			break;
233152331Srwatson		case 's':
234152331Srwatson			suppressdata = 1;
235152331Srwatson			break;
236123187Speter		case 'E':
237123187Speter			timestamp = 3;	/* elapsed timestamp */
238123187Speter			break;
239151930Srwatson		case 'H':
240151930Srwatson			threads = 1;
241151930Srwatson			break;
2421590Srgrimes		case 'R':
2431590Srgrimes			timestamp = 2;	/* relative timestamp */
2441590Srgrimes			break;
2451590Srgrimes		case 'T':
2461590Srgrimes			timestamp = 1;
2471590Srgrimes			break;
2481590Srgrimes		case 't':
2491590Srgrimes			trpoints = getpoints(optarg);
25027443Scharnier			if (trpoints < 0)
25127443Scharnier				errx(1, "unknown trace point in %s", optarg);
2521590Srgrimes			break;
2531590Srgrimes		default:
2541590Srgrimes			usage();
2551590Srgrimes		}
2561590Srgrimes
25719853Sfenner	if (argc > optind)
2581590Srgrimes		usage();
2591590Srgrimes
260226153Sdes	m = malloc(size = 1025);
26127443Scharnier	if (m == NULL)
26227443Scharnier		errx(1, "%s", strerror(ENOMEM));
26327443Scharnier	if (!freopen(tracefile, "r", stdin))
26427443Scharnier		err(1, "%s", tracefile);
265251073Spjd
266253456Spjd	strerror_init();
267253456Spjd	localtime_init();
268253456Spjd
269251167Spjd	if (resolv == 0) {
270251167Spjd		if (cap_enter() < 0 && errno != ENOSYS)
271251167Spjd			err(1, "unable to enter capability mode");
272251167Spjd	}
273251073Spjd	limitfd(STDIN_FILENO);
274251073Spjd	limitfd(STDOUT_FILENO);
275251073Spjd	limitfd(STDERR_FILENO);
276251073Spjd
277219043Sdchagin	TAILQ_INIT(&trace_procs);
278112201Sjhb	drop_logged = 0;
2791590Srgrimes	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
280112201Sjhb		if (ktr_header.ktr_type & KTR_DROP) {
281112201Sjhb			ktr_header.ktr_type &= ~KTR_DROP;
282151930Srwatson			if (!drop_logged && threads) {
283226153Sdes				printf(
284203551Sjh				    "%6jd %6jd %-8.*s Events dropped.\n",
285203551Sjh				    (intmax_t)ktr_header.ktr_pid,
286203551Sjh				    ktr_header.ktr_tid > 0 ?
287203551Sjh				    (intmax_t)ktr_header.ktr_tid : 0,
288203551Sjh				    MAXCOMLEN, ktr_header.ktr_comm);
289151930Srwatson				drop_logged = 1;
290151930Srwatson			} else if (!drop_logged) {
291226153Sdes				printf("%6jd %-8.*s Events dropped.\n",
292203551Sjh				    (intmax_t)ktr_header.ktr_pid, MAXCOMLEN,
293112201Sjhb				    ktr_header.ktr_comm);
294112201Sjhb				drop_logged = 1;
295112201Sjhb			}
296112201Sjhb		}
2971590Srgrimes		if (trpoints & (1<<ktr_header.ktr_type))
298236577Sjhb			if (pid == 0 || ktr_header.ktr_pid == pid ||
299236577Sjhb			    ktr_header.ktr_tid == pid)
300115759Speter				dumpheader(&ktr_header);
30127443Scharnier		if ((ktrlen = ktr_header.ktr_len) < 0)
30227443Scharnier			errx(1, "bogus length 0x%x", ktrlen);
3031590Srgrimes		if (ktrlen > size) {
304226153Sdes			m = realloc(m, ktrlen+1);
30527443Scharnier			if (m == NULL)
30627443Scharnier				errx(1, "%s", strerror(ENOMEM));
3071590Srgrimes			size = ktrlen;
3081590Srgrimes		}
30927443Scharnier		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
31027443Scharnier			errx(1, "data too short");
311219043Sdchagin		if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
312219043Sdchagin			continue;
313219043Sdchagin		sv_flags = abidump(&ktr_header);
314236577Sjhb		if (pid && ktr_header.ktr_pid != pid &&
315236577Sjhb		    ktr_header.ktr_tid != pid)
316115759Speter			continue;
3171590Srgrimes		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
3181590Srgrimes			continue;
319112201Sjhb		drop_logged = 0;
3201590Srgrimes		switch (ktr_header.ktr_type) {
3211590Srgrimes		case KTR_SYSCALL:
322219138Sdchagin#if defined(__amd64__) || defined(__i386__)
323219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
324219138Sdchagin				linux_ktrsyscall((struct ktr_syscall *)m);
325219138Sdchagin			else
326219138Sdchagin#endif
327219138Sdchagin				ktrsyscall((struct ktr_syscall *)m, sv_flags);
3281590Srgrimes			break;
3291590Srgrimes		case KTR_SYSRET:
330219138Sdchagin#if defined(__amd64__) || defined(__i386__)
331219138Sdchagin			if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
332219138Sdchagin				linux_ktrsysret((struct ktr_sysret *)m);
333219138Sdchagin			else
334219138Sdchagin#endif
335219138Sdchagin				ktrsysret((struct ktr_sysret *)m, sv_flags);
3361590Srgrimes			break;
3371590Srgrimes		case KTR_NAMEI:
338189707Sjhb		case KTR_SYSCTL:
3391590Srgrimes			ktrnamei(m, ktrlen);
3401590Srgrimes			break;
3411590Srgrimes		case KTR_GENIO:
3421590Srgrimes			ktrgenio((struct ktr_genio *)m, ktrlen);
3431590Srgrimes			break;
3441590Srgrimes		case KTR_PSIG:
345219138Sdchagin			ktrpsig((struct ktr_psig *)m);
3461590Srgrimes			break;
3471590Srgrimes		case KTR_CSW:
348234494Sjhb			if (ktrlen == sizeof(struct ktr_csw_old))
349234494Sjhb				ktrcsw_old((struct ktr_csw_old *)m);
350234494Sjhb			else
351234494Sjhb				ktrcsw((struct ktr_csw *)m);
3521590Srgrimes			break;
35318400Sphk		case KTR_USER:
35418470Sphk			ktruser(ktrlen, m);
35518400Sphk			break;
356176471Sdes		case KTR_STRUCT:
357176471Sdes			ktrstruct(m, ktrlen);
358176471Sdes			break;
359226269Sdes		case KTR_CAPFAIL:
360226269Sdes			ktrcapfail((struct ktr_cap_fail *)m);
361233925Sjhb			break;
362233925Sjhb		case KTR_FAULT:
363233925Sjhb			ktrfault((struct ktr_fault *)m);
364233925Sjhb			break;
365233925Sjhb		case KTR_FAULTEND:
366233925Sjhb			ktrfaultend((struct ktr_faultend *)m);
367233925Sjhb			break;
368112203Sjhb		default:
369112203Sjhb			printf("\n");
370112203Sjhb			break;
3711590Srgrimes		}
3721590Srgrimes		if (tail)
373226153Sdes			fflush(stdout);
3741590Srgrimes	}
375100824Sdwmalone	return 0;
3761590Srgrimes}
3771590Srgrimes
378251073Spjdvoid
379251073Spjdlimitfd(int fd)
380251073Spjd{
381251073Spjd	cap_rights_t rights;
382251073Spjd	unsigned long cmd;
383251073Spjd
384255219Spjd	cap_rights_init(&rights, CAP_FSTAT);
385251073Spjd	cmd = -1;
386251073Spjd
387251073Spjd	switch (fd) {
388251073Spjd	case STDIN_FILENO:
389255219Spjd		cap_rights_set(&rights, CAP_READ);
390251073Spjd		break;
391251073Spjd	case STDOUT_FILENO:
392255219Spjd		cap_rights_set(&rights, CAP_IOCTL, CAP_WRITE);
393251073Spjd		cmd = TIOCGETA;	/* required by isatty(3) in printf(3) */
394251073Spjd		break;
395251073Spjd	case STDERR_FILENO:
396255219Spjd		cap_rights_set(&rights, CAP_WRITE);
397251073Spjd		if (!suppressdata) {
398255219Spjd			cap_rights_set(&rights, CAP_IOCTL);
399251073Spjd			cmd = TIOCGWINSZ;
400251073Spjd		}
401251073Spjd		break;
402251073Spjd	default:
403251073Spjd		abort();
404251073Spjd	}
405251073Spjd
406255219Spjd	if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS)
407251073Spjd		err(1, "unable to limit rights for descriptor %d", fd);
408251073Spjd	if (cmd != -1 && cap_ioctls_limit(fd, &cmd, 1) < 0 && errno != ENOSYS)
409251073Spjd		err(1, "unable to limit ioctls for descriptor %d", fd);
410251073Spjd}
411251073Spjd
412100824Sdwmaloneint
413100824Sdwmalonefread_tail(void *buf, int size, int num)
4141590Srgrimes{
4151590Srgrimes	int i;
4161590Srgrimes
4171590Srgrimes	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
418226153Sdes		sleep(1);
4191590Srgrimes		clearerr(stdin);
4201590Srgrimes	}
4211590Srgrimes	return (i);
4221590Srgrimes}
4231590Srgrimes
424219043Sdchaginint
425219043Sdchaginfetchprocinfo(struct ktr_header *kth, u_int *flags)
426219043Sdchagin{
427219043Sdchagin	struct proc_info *pi;
428219043Sdchagin
429219043Sdchagin	switch (kth->ktr_type) {
430219043Sdchagin	case KTR_PROCCTOR:
431219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
432219043Sdchagin			if (pi->pid == kth->ktr_pid) {
433219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
434219043Sdchagin				break;
435219043Sdchagin			}
436219043Sdchagin		}
437219043Sdchagin		pi = malloc(sizeof(struct proc_info));
438219043Sdchagin		if (pi == NULL)
439219043Sdchagin			errx(1, "%s", strerror(ENOMEM));
440219043Sdchagin		pi->sv_flags = *flags;
441219043Sdchagin		pi->pid = kth->ktr_pid;
442219043Sdchagin		TAILQ_INSERT_TAIL(&trace_procs, pi, info);
443219043Sdchagin		return (1);
444219043Sdchagin
445219043Sdchagin	case KTR_PROCDTOR:
446219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
447219043Sdchagin			if (pi->pid == kth->ktr_pid) {
448219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
449219043Sdchagin				free(pi);
450219043Sdchagin				break;
451219043Sdchagin			}
452219043Sdchagin		}
453219043Sdchagin		return (1);
454219043Sdchagin	}
455219043Sdchagin
456219043Sdchagin	return (0);
457219043Sdchagin}
458219043Sdchagin
459219043Sdchaginu_int
460219043Sdchaginabidump(struct ktr_header *kth)
461219043Sdchagin{
462219043Sdchagin	struct proc_info *pi;
463219043Sdchagin	const char *abi;
464219043Sdchagin	const char *arch;
465219043Sdchagin	u_int flags = 0;
466219043Sdchagin
467219043Sdchagin	TAILQ_FOREACH(pi, &trace_procs, info) {
468219043Sdchagin		if (pi->pid == kth->ktr_pid) {
469219043Sdchagin			flags = pi->sv_flags;
470219043Sdchagin			break;
471219043Sdchagin		}
472219043Sdchagin	}
473219043Sdchagin
474219043Sdchagin	if (abiflag == 0)
475219043Sdchagin		return (flags);
476219043Sdchagin
477219043Sdchagin	switch (flags & SV_ABI_MASK) {
478219043Sdchagin	case SV_ABI_LINUX:
479219043Sdchagin		abi = "L";
480219043Sdchagin		break;
481219043Sdchagin	case SV_ABI_FREEBSD:
482219043Sdchagin		abi = "F";
483219043Sdchagin		break;
484219043Sdchagin	default:
485219043Sdchagin		abi = "U";
486219043Sdchagin		break;
487219043Sdchagin	}
488219043Sdchagin
489219043Sdchagin	if (flags != 0) {
490219043Sdchagin		if (flags & SV_LP64)
491219043Sdchagin			arch = "64";
492219043Sdchagin		else
493219043Sdchagin			arch = "32";
494219043Sdchagin	} else
495219043Sdchagin		arch = "00";
496219043Sdchagin
497219043Sdchagin	printf("%s%s  ", abi, arch);
498219043Sdchagin
499219043Sdchagin	return (flags);
500219043Sdchagin}
501219043Sdchagin
502100824Sdwmalonevoid
503100824Sdwmalonedumpheader(struct ktr_header *kth)
5041590Srgrimes{
5051590Srgrimes	static char unknown[64];
5061590Srgrimes	static struct timeval prevtime, temp;
507100824Sdwmalone	const char *type;
5081590Srgrimes
5091590Srgrimes	switch (kth->ktr_type) {
5101590Srgrimes	case KTR_SYSCALL:
5111590Srgrimes		type = "CALL";
5121590Srgrimes		break;
5131590Srgrimes	case KTR_SYSRET:
5141590Srgrimes		type = "RET ";
5151590Srgrimes		break;
5161590Srgrimes	case KTR_NAMEI:
5171590Srgrimes		type = "NAMI";
5181590Srgrimes		break;
5191590Srgrimes	case KTR_GENIO:
5201590Srgrimes		type = "GIO ";
5211590Srgrimes		break;
5221590Srgrimes	case KTR_PSIG:
5231590Srgrimes		type = "PSIG";
5241590Srgrimes		break;
5251590Srgrimes	case KTR_CSW:
526171333Sjhb		type = "CSW ";
5271590Srgrimes		break;
52818400Sphk	case KTR_USER:
52918400Sphk		type = "USER";
53018400Sphk		break;
531176471Sdes	case KTR_STRUCT:
532176471Sdes		type = "STRU";
533176471Sdes		break;
534189707Sjhb	case KTR_SYSCTL:
535189707Sjhb		type = "SCTL";
536189707Sjhb		break;
537219043Sdchagin	case KTR_PROCCTOR:
538219043Sdchagin		/* FALLTHROUGH */
539219043Sdchagin	case KTR_PROCDTOR:
540219043Sdchagin		return;
541226269Sdes	case KTR_CAPFAIL:
542226269Sdes		type = "CAP ";
543226269Sdes		break;
544233925Sjhb	case KTR_FAULT:
545233925Sjhb		type = "PFLT";
546233925Sjhb		break;
547233925Sjhb	case KTR_FAULTEND:
548233925Sjhb		type = "PRET";
549233925Sjhb		break;
5501590Srgrimes	default:
551226153Sdes		sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
5521590Srgrimes		type = unknown;
5531590Srgrimes	}
5541590Srgrimes
555151930Srwatson	/*
556151930Srwatson	 * The ktr_tid field was previously the ktr_buffer field, which held
557151930Srwatson	 * the kernel pointer value for the buffer associated with data
558151930Srwatson	 * following the record header.  It now holds a threadid, but only
559151930Srwatson	 * for trace files after the change.  Older trace files still contain
560151930Srwatson	 * kernel pointers.  Detect this and suppress the results by printing
561151930Srwatson	 * negative tid's as 0.
562151930Srwatson	 */
563151930Srwatson	if (threads)
564226153Sdes		printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid,
565203551Sjh		    kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0,
566203551Sjh		    MAXCOMLEN, kth->ktr_comm);
567151930Srwatson	else
568226153Sdes		printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN,
569151930Srwatson		    kth->ktr_comm);
5701590Srgrimes	if (timestamp) {
571123187Speter		if (timestamp == 3) {
572123187Speter			if (prevtime.tv_sec == 0)
573123187Speter				prevtime = kth->ktr_time;
574123187Speter			timevalsub(&kth->ktr_time, &prevtime);
575123187Speter		}
5761590Srgrimes		if (timestamp == 2) {
5771590Srgrimes			temp = kth->ktr_time;
5781590Srgrimes			timevalsub(&kth->ktr_time, &prevtime);
5791590Srgrimes			prevtime = temp;
5801590Srgrimes		}
581226153Sdes		printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
582203551Sjh		    kth->ktr_time.tv_usec);
5831590Srgrimes	}
584226153Sdes	printf("%s  ", type);
5851590Srgrimes}
5861590Srgrimes
5871590Srgrimes#include <sys/syscall.h>
5881590Srgrimes#define KTRACE
5894721Sphk#include <sys/kern/syscalls.c>
5901590Srgrimes#undef KTRACE
5911590Srgrimesint nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
5921590Srgrimes
593100824Sdwmalonevoid
594219043Sdchaginktrsyscall(struct ktr_syscall *ktr, u_int flags)
5951590Srgrimes{
596100824Sdwmalone	int narg = ktr->ktr_narg;
597100824Sdwmalone	register_t *ip;
598226269Sdes	intmax_t arg;
5991590Srgrimes
600219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
601219043Sdchagin	    (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
602226153Sdes		printf("[%d]", ktr->ktr_code);
6031590Srgrimes	else
604226153Sdes		printf("%s", syscallnames[ktr->ktr_code]);
60547957Sdt	ip = &ktr->ktr_args[0];
6061590Srgrimes	if (narg) {
6071590Srgrimes		char c = '(';
608219043Sdchagin		if (fancy &&
609219043Sdchagin		    (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
610226148Sdes			switch (ktr->ktr_code) {
611254296Sjilles			case SYS_bindat:
612254296Sjilles			case SYS_connectat:
613254291Sjilles			case SYS_faccessat:
614254291Sjilles			case SYS_fchmodat:
615254291Sjilles			case SYS_fchownat:
616254291Sjilles			case SYS_fstatat:
617254291Sjilles			case SYS_futimesat:
618254291Sjilles			case SYS_linkat:
619254291Sjilles			case SYS_mkdirat:
620254291Sjilles			case SYS_mkfifoat:
621254291Sjilles			case SYS_mknodat:
622254291Sjilles			case SYS_openat:
623254291Sjilles			case SYS_readlinkat:
624254291Sjilles			case SYS_renameat:
625254291Sjilles			case SYS_unlinkat:
626254291Sjilles				putchar('(');
627254291Sjilles				atfdname(*ip, decimal);
628254291Sjilles				c = ',';
629254291Sjilles				ip++;
630254291Sjilles				narg--;
631254291Sjilles				break;
632254291Sjilles			}
633254291Sjilles			switch (ktr->ktr_code) {
634226148Sdes			case SYS_ioctl: {
635226150Sdes				print_number(ip, narg, c);
636226157Sdes				putchar(c);
637226157Sdes				ioctlname(*ip, decimal);
6381590Srgrimes				c = ',';
6391590Srgrimes				ip++;
6401590Srgrimes				narg--;
641226148Sdes				break;
642226148Sdes			}
643226148Sdes			case SYS_ptrace:
644226153Sdes				putchar('(');
645226164Sdes				ptraceopname(*ip);
6461590Srgrimes				c = ',';
6471590Srgrimes				ip++;
6481590Srgrimes				narg--;
649226148Sdes				break;
650226148Sdes			case SYS_access:
651226148Sdes			case SYS_eaccess:
652254291Sjilles			case SYS_faccessat:
653226150Sdes				print_number(ip, narg, c);
654226153Sdes				putchar(',');
655226164Sdes				accessmodename(*ip);
656158766Snetchild				ip++;
657158766Snetchild				narg--;
658226148Sdes				break;
659226148Sdes			case SYS_open:
660254291Sjilles			case SYS_openat:
661226150Sdes				print_number(ip, narg, c);
662226153Sdes				putchar(',');
663226164Sdes				flagsandmodename(ip[0], ip[1], decimal);
664226148Sdes				ip += 2;
665226148Sdes				narg -= 2;
666226148Sdes				break;
667226148Sdes			case SYS_wait4:
668226150Sdes				print_number(ip, narg, c);
669226150Sdes				print_number(ip, narg, c);
670255493Sjhb				/*
671255493Sjhb				 * A flags value of zero is valid for
672255493Sjhb				 * wait4() but not for wait6(), so
673255493Sjhb				 * handle zero special here.
674255493Sjhb				 */
675255493Sjhb				if (*ip == 0) {
676255493Sjhb					print_number(ip, narg, c);
677255493Sjhb				} else {
678255493Sjhb					putchar(',');
679255493Sjhb					wait6optname(*ip);
680255493Sjhb					ip++;
681255493Sjhb					narg--;
682255493Sjhb				}
683255493Sjhb				break;
684255493Sjhb			case SYS_wait6:
685255493Sjhb				putchar('(');
686255493Sjhb				idtypename(*ip, decimal);
687255493Sjhb				c = ',';
688255493Sjhb				ip++;
689255493Sjhb				narg--;
690255493Sjhb				print_number(ip, narg, c);
691255493Sjhb				print_number(ip, narg, c);
692226153Sdes				putchar(',');
693255493Sjhb				wait6optname(*ip);
694158766Snetchild				ip++;
695158766Snetchild				narg--;
696226148Sdes				break;
697226148Sdes			case SYS_chmod:
698226148Sdes			case SYS_fchmod:
699226148Sdes			case SYS_lchmod:
700226150Sdes				print_number(ip, narg, c);
701226153Sdes				putchar(',');
702226164Sdes				modename(*ip);
703158766Snetchild				ip++;
704158766Snetchild				narg--;
705226148Sdes				break;
706226148Sdes			case SYS_mknod:
707254291Sjilles			case SYS_mknodat:
708226150Sdes				print_number(ip, narg, c);
709226153Sdes				putchar(',');
710226164Sdes				modename(*ip);
711158766Snetchild				ip++;
712158766Snetchild				narg--;
713226148Sdes				break;
714226148Sdes			case SYS_getfsstat:
715226150Sdes				print_number(ip, narg, c);
716226150Sdes				print_number(ip, narg, c);
717226153Sdes				putchar(',');
718226164Sdes				getfsstatflagsname(*ip);
719158766Snetchild				ip++;
720158766Snetchild				narg--;
721226148Sdes				break;
722226148Sdes			case SYS_mount:
723226150Sdes				print_number(ip, narg, c);
724226150Sdes				print_number(ip, narg, c);
725226153Sdes				putchar(',');
726226164Sdes				mountflagsname(*ip);
727158766Snetchild				ip++;
728158766Snetchild				narg--;
729226148Sdes				break;
730226148Sdes			case SYS_unmount:
731226150Sdes				print_number(ip, narg, c);
732226153Sdes				putchar(',');
733226164Sdes				mountflagsname(*ip);
734158766Snetchild				ip++;
735158766Snetchild				narg--;
736226148Sdes				break;
737226148Sdes			case SYS_recvmsg:
738226148Sdes			case SYS_sendmsg:
739226150Sdes				print_number(ip, narg, c);
740226150Sdes				print_number(ip, narg, c);
741226153Sdes				putchar(',');
742226164Sdes				sendrecvflagsname(*ip);
743158766Snetchild				ip++;
744158766Snetchild				narg--;
745226148Sdes				break;
746226148Sdes			case SYS_recvfrom:
747226148Sdes			case SYS_sendto:
748226150Sdes				print_number(ip, narg, c);
749226150Sdes				print_number(ip, narg, c);
750226150Sdes				print_number(ip, narg, c);
751226153Sdes				putchar(',');
752226164Sdes				sendrecvflagsname(*ip);
753158766Snetchild				ip++;
754158766Snetchild				narg--;
755226148Sdes				break;
756226148Sdes			case SYS_chflags:
757226148Sdes			case SYS_fchflags:
758226148Sdes			case SYS_lchflags:
759226150Sdes				print_number(ip, narg, c);
760226153Sdes				putchar(',');
761226164Sdes				modename(*ip);
762158766Snetchild				ip++;
763158766Snetchild				narg--;
764226148Sdes				break;
765226148Sdes			case SYS_kill:
766226150Sdes				print_number(ip, narg, c);
767226153Sdes				putchar(',');
768226164Sdes				signame(*ip);
769158766Snetchild				ip++;
770158766Snetchild				narg--;
771226148Sdes				break;
772226148Sdes			case SYS_reboot:
773226153Sdes				putchar('(');
774226164Sdes				rebootoptname(*ip);
775158766Snetchild				ip++;
776158766Snetchild				narg--;
777226148Sdes				break;
778226148Sdes			case SYS_umask:
779226153Sdes				putchar('(');
780226164Sdes				modename(*ip);
781158766Snetchild				ip++;
782158766Snetchild				narg--;
783226148Sdes				break;
784226148Sdes			case SYS_msync:
785226150Sdes				print_number(ip, narg, c);
786226150Sdes				print_number(ip, narg, c);
787226153Sdes				putchar(',');
788226164Sdes				msyncflagsname(*ip);
789158766Snetchild				ip++;
790158766Snetchild				narg--;
791226148Sdes				break;
792171221Speter#ifdef SYS_freebsd6_mmap
793226148Sdes			case SYS_freebsd6_mmap:
794226150Sdes				print_number(ip, narg, c);
795226150Sdes				print_number(ip, narg, c);
796226153Sdes				putchar(',');
797226164Sdes				mmapprotname(*ip);
798226153Sdes				putchar(',');
799171221Speter				ip++;
800171221Speter				narg--;
801226164Sdes				mmapflagsname(*ip);
802171221Speter				ip++;
803171221Speter				narg--;
804226148Sdes				break;
805171221Speter#endif
806226148Sdes			case SYS_mmap:
807226150Sdes				print_number(ip, narg, c);
808226150Sdes				print_number(ip, narg, c);
809226153Sdes				putchar(',');
810226164Sdes				mmapprotname(*ip);
811226153Sdes				putchar(',');
812158766Snetchild				ip++;
813158766Snetchild				narg--;
814226164Sdes				mmapflagsname(*ip);
815158766Snetchild				ip++;
816158766Snetchild				narg--;
817226148Sdes				break;
818226148Sdes			case SYS_mprotect:
819226150Sdes				print_number(ip, narg, c);
820226150Sdes				print_number(ip, narg, c);
821226153Sdes				putchar(',');
822226164Sdes				mmapprotname(*ip);
823158766Snetchild				ip++;
824158766Snetchild				narg--;
825226148Sdes				break;
826226148Sdes			case SYS_madvise:
827226150Sdes				print_number(ip, narg, c);
828226150Sdes				print_number(ip, narg, c);
829226153Sdes				putchar(',');
830226164Sdes				madvisebehavname(*ip);
831158766Snetchild				ip++;
832158766Snetchild				narg--;
833226148Sdes				break;
834226148Sdes			case SYS_setpriority:
835226150Sdes				print_number(ip, narg, c);
836226150Sdes				print_number(ip, narg, c);
837226153Sdes				putchar(',');
838226164Sdes				prioname(*ip);
839158766Snetchild				ip++;
840158766Snetchild				narg--;
841226148Sdes				break;
842226148Sdes			case SYS_fcntl:
843226150Sdes				print_number(ip, narg, c);
844226153Sdes				putchar(',');
845226164Sdes				fcntlcmdname(ip[0], ip[1], decimal);
846226148Sdes				ip += 2;
847226148Sdes				narg -= 2;
848226148Sdes				break;
849226148Sdes			case SYS_socket: {
850165758Srodrigc				int sockdomain;
851226153Sdes				putchar('(');
852226164Sdes				sockdomain = *ip;
853165758Srodrigc				sockdomainname(sockdomain);
854158766Snetchild				ip++;
855158766Snetchild				narg--;
856226153Sdes				putchar(',');
857254922Sjilles				socktypenamewithflags(*ip);
858158766Snetchild				ip++;
859158766Snetchild				narg--;
860165758Srodrigc				if (sockdomain == PF_INET ||
861165758Srodrigc				    sockdomain == PF_INET6) {
862226153Sdes					putchar(',');
863226164Sdes					sockipprotoname(*ip);
864165758Srodrigc					ip++;
865165758Srodrigc					narg--;
866165758Srodrigc				}
867158766Snetchild				c = ',';
868226148Sdes				break;
869226148Sdes			}
870226148Sdes			case SYS_setsockopt:
871226148Sdes			case SYS_getsockopt:
872226150Sdes				print_number(ip, narg, c);
873226153Sdes				putchar(',');
874226164Sdes				sockoptlevelname(*ip, decimal);
875226151Sdes				if (*ip == SOL_SOCKET) {
876175138Sjhb					ip++;
877175138Sjhb					narg--;
878226153Sdes					putchar(',');
879226164Sdes					sockoptname(*ip);
880175138Sjhb				}
881158766Snetchild				ip++;
882158766Snetchild				narg--;
883226148Sdes				break;
884171221Speter#ifdef SYS_freebsd6_lseek
885226148Sdes			case SYS_freebsd6_lseek:
886226150Sdes				print_number(ip, narg, c);
887158766Snetchild				/* Hidden 'pad' argument, not in lseek(2) */
888226150Sdes				print_number(ip, narg, c);
889226150Sdes				print_number(ip, narg, c);
890226153Sdes				putchar(',');
891226164Sdes				whencename(*ip);
892158766Snetchild				ip++;
893158766Snetchild				narg--;
894226148Sdes				break;
895171221Speter#endif
896226148Sdes			case SYS_lseek:
897226150Sdes				print_number(ip, narg, c);
898171221Speter				/* Hidden 'pad' argument, not in lseek(2) */
899226150Sdes				print_number(ip, narg, c);
900226153Sdes				putchar(',');
901226164Sdes				whencename(*ip);
902171221Speter				ip++;
903171221Speter				narg--;
904226148Sdes				break;
905226148Sdes			case SYS_flock:
906226150Sdes				print_number(ip, narg, c);
907226153Sdes				putchar(',');
908226164Sdes				flockname(*ip);
909158766Snetchild				ip++;
910158766Snetchild				narg--;
911226148Sdes				break;
912226148Sdes			case SYS_mkfifo:
913254291Sjilles			case SYS_mkfifoat:
914226148Sdes			case SYS_mkdir:
915254291Sjilles			case SYS_mkdirat:
916226150Sdes				print_number(ip, narg, c);
917226153Sdes				putchar(',');
918226164Sdes				modename(*ip);
919158766Snetchild				ip++;
920158766Snetchild				narg--;
921226148Sdes				break;
922226148Sdes			case SYS_shutdown:
923226150Sdes				print_number(ip, narg, c);
924226153Sdes				putchar(',');
925226164Sdes				shutdownhowname(*ip);
926158766Snetchild				ip++;
927158766Snetchild				narg--;
928226148Sdes				break;
929226148Sdes			case SYS_socketpair:
930226153Sdes				putchar('(');
931226164Sdes				sockdomainname(*ip);
932158766Snetchild				ip++;
933158766Snetchild				narg--;
934226153Sdes				putchar(',');
935254922Sjilles				socktypenamewithflags(*ip);
936158766Snetchild				ip++;
937158766Snetchild				narg--;
938158766Snetchild				c = ',';
939226148Sdes				break;
940226148Sdes			case SYS_getrlimit:
941226148Sdes			case SYS_setrlimit:
942226153Sdes				putchar('(');
943226164Sdes				rlimitname(*ip);
944158766Snetchild				ip++;
945158766Snetchild				narg--;
946158766Snetchild				c = ',';
947226148Sdes				break;
948226148Sdes			case SYS_quotactl:
949226150Sdes				print_number(ip, narg, c);
950226153Sdes				putchar(',');
951226164Sdes				quotactlname(*ip);
952158766Snetchild				ip++;
953158766Snetchild				narg--;
954158766Snetchild				c = ',';
955226148Sdes				break;
956226148Sdes			case SYS_nfssvc:
957226153Sdes				putchar('(');
958226164Sdes				nfssvcname(*ip);
959158766Snetchild				ip++;
960158766Snetchild				narg--;
961158766Snetchild				c = ',';
962226148Sdes				break;
963226148Sdes			case SYS_rtprio:
964226153Sdes				putchar('(');
965226164Sdes				rtprioname(*ip);
966158766Snetchild				ip++;
967158766Snetchild				narg--;
968158766Snetchild				c = ',';
969226148Sdes				break;
970226148Sdes			case SYS___semctl:
971226150Sdes				print_number(ip, narg, c);
972226150Sdes				print_number(ip, narg, c);
973226153Sdes				putchar(',');
974226164Sdes				semctlname(*ip);
975158766Snetchild				ip++;
976158766Snetchild				narg--;
977226148Sdes				break;
978226148Sdes			case SYS_semget:
979226150Sdes				print_number(ip, narg, c);
980226150Sdes				print_number(ip, narg, c);
981226153Sdes				putchar(',');
982226164Sdes				semgetname(*ip);
983158766Snetchild				ip++;
984158766Snetchild				narg--;
985226148Sdes				break;
986226148Sdes			case SYS_msgctl:
987226150Sdes				print_number(ip, narg, c);
988226153Sdes				putchar(',');
989226164Sdes				shmctlname(*ip);
990158766Snetchild				ip++;
991158766Snetchild				narg--;
992226148Sdes				break;
993226148Sdes			case SYS_shmat:
994226150Sdes				print_number(ip, narg, c);
995226150Sdes				print_number(ip, narg, c);
996226153Sdes				putchar(',');
997226164Sdes				shmatname(*ip);
998158766Snetchild				ip++;
999158766Snetchild				narg--;
1000226148Sdes				break;
1001226148Sdes			case SYS_shmctl:
1002226150Sdes				print_number(ip, narg, c);
1003226153Sdes				putchar(',');
1004226164Sdes				shmctlname(*ip);
1005158766Snetchild				ip++;
1006158766Snetchild				narg--;
1007226148Sdes				break;
1008226148Sdes			case SYS_minherit:
1009226150Sdes				print_number(ip, narg, c);
1010226150Sdes				print_number(ip, narg, c);
1011226153Sdes				putchar(',');
1012226164Sdes				minheritname(*ip);
1013158766Snetchild				ip++;
1014158766Snetchild				narg--;
1015226148Sdes				break;
1016226148Sdes			case SYS_rfork:
1017226153Sdes				putchar('(');
1018226164Sdes				rforkname(*ip);
1019158766Snetchild				ip++;
1020158766Snetchild				narg--;
1021158766Snetchild				c = ',';
1022226148Sdes				break;
1023226148Sdes			case SYS_lio_listio:
1024226153Sdes				putchar('(');
1025226164Sdes				lio_listioname(*ip);
1026158766Snetchild				ip++;
1027158766Snetchild				narg--;
1028158766Snetchild				c = ',';
1029226148Sdes				break;
1030226148Sdes			case SYS_mlockall:
1031226153Sdes				putchar('(');
1032226164Sdes				mlockallname(*ip);
1033158766Snetchild				ip++;
1034158766Snetchild				narg--;
1035226148Sdes				break;
1036226148Sdes			case SYS_sched_setscheduler:
1037226150Sdes				print_number(ip, narg, c);
1038226153Sdes				putchar(',');
1039226164Sdes				schedpolicyname(*ip);
1040158766Snetchild				ip++;
1041158766Snetchild				narg--;
1042226148Sdes				break;
1043226148Sdes			case SYS_sched_get_priority_max:
1044226148Sdes			case SYS_sched_get_priority_min:
1045226153Sdes				putchar('(');
1046226164Sdes				schedpolicyname(*ip);
1047158766Snetchild				ip++;
1048158766Snetchild				narg--;
1049226148Sdes				break;
1050226148Sdes			case SYS_sendfile:
1051226150Sdes				print_number(ip, narg, c);
1052226150Sdes				print_number(ip, narg, c);
1053226150Sdes				print_number(ip, narg, c);
1054226150Sdes				print_number(ip, narg, c);
1055226150Sdes				print_number(ip, narg, c);
1056226150Sdes				print_number(ip, narg, c);
1057226153Sdes				putchar(',');
1058226164Sdes				sendfileflagsname(*ip);
1059158766Snetchild				ip++;
1060158766Snetchild				narg--;
1061226148Sdes				break;
1062226148Sdes			case SYS_kldsym:
1063226150Sdes				print_number(ip, narg, c);
1064226153Sdes				putchar(',');
1065226164Sdes				kldsymcmdname(*ip);
1066158766Snetchild				ip++;
1067158766Snetchild				narg--;
1068226148Sdes				break;
1069226148Sdes			case SYS_sigprocmask:
1070226153Sdes				putchar('(');
1071226164Sdes				sigprocmaskhowname(*ip);
1072158766Snetchild				ip++;
1073158766Snetchild				narg--;
1074158766Snetchild				c = ',';
1075226148Sdes				break;
1076226148Sdes			case SYS___acl_get_file:
1077226148Sdes			case SYS___acl_set_file:
1078226148Sdes			case SYS___acl_get_fd:
1079226148Sdes			case SYS___acl_set_fd:
1080226148Sdes			case SYS___acl_delete_file:
1081226148Sdes			case SYS___acl_delete_fd:
1082226148Sdes			case SYS___acl_aclcheck_file:
1083226148Sdes			case SYS___acl_aclcheck_fd:
1084226148Sdes			case SYS___acl_get_link:
1085226148Sdes			case SYS___acl_set_link:
1086226148Sdes			case SYS___acl_delete_link:
1087226148Sdes			case SYS___acl_aclcheck_link:
1088226150Sdes				print_number(ip, narg, c);
1089226153Sdes				putchar(',');
1090226164Sdes				acltypename(*ip);
1091158766Snetchild				ip++;
1092158766Snetchild				narg--;
1093226148Sdes				break;
1094226148Sdes			case SYS_sigaction:
1095226153Sdes				putchar('(');
1096226164Sdes				signame(*ip);
1097158766Snetchild				ip++;
1098158766Snetchild				narg--;
1099158766Snetchild				c = ',';
1100226148Sdes				break;
1101226148Sdes			case SYS_extattrctl:
1102226150Sdes				print_number(ip, narg, c);
1103226153Sdes				putchar(',');
1104226164Sdes				extattrctlname(*ip);
1105158766Snetchild				ip++;
1106158766Snetchild				narg--;
1107226148Sdes				break;
1108226148Sdes			case SYS_nmount:
1109226150Sdes				print_number(ip, narg, c);
1110226150Sdes				print_number(ip, narg, c);
1111226153Sdes				putchar(',');
1112226164Sdes				mountflagsname(*ip);
1113158766Snetchild				ip++;
1114158766Snetchild				narg--;
1115226148Sdes				break;
1116226148Sdes			case SYS_thr_create:
1117226150Sdes				print_number(ip, narg, c);
1118226150Sdes				print_number(ip, narg, c);
1119226153Sdes				putchar(',');
1120226164Sdes				thrcreateflagsname(*ip);
1121158766Snetchild				ip++;
1122158766Snetchild				narg--;
1123226148Sdes				break;
1124226148Sdes			case SYS_thr_kill:
1125226150Sdes				print_number(ip, narg, c);
1126226153Sdes				putchar(',');
1127226164Sdes				signame(*ip);
1128158766Snetchild				ip++;
1129158766Snetchild				narg--;
1130226148Sdes				break;
1131226148Sdes			case SYS_kldunloadf:
1132226150Sdes				print_number(ip, narg, c);
1133226153Sdes				putchar(',');
1134226164Sdes				kldunloadfflagsname(*ip);
1135158766Snetchild				ip++;
1136158766Snetchild				narg--;
1137226148Sdes				break;
1138254291Sjilles			case SYS_linkat:
1139254291Sjilles			case SYS_renameat:
1140254291Sjilles			case SYS_symlinkat:
1141254291Sjilles				print_number(ip, narg, c);
1142254291Sjilles				putchar(',');
1143254291Sjilles				atfdname(*ip, decimal);
1144254291Sjilles				ip++;
1145254291Sjilles				narg--;
1146254291Sjilles				break;
1147247602Spjd			case SYS_cap_fcntls_limit:
1148247602Spjd				print_number(ip, narg, c);
1149247602Spjd				putchar(',');
1150247602Spjd				arg = *ip;
1151247602Spjd				ip++;
1152247602Spjd				narg--;
1153247602Spjd				capfcntlname(arg);
1154247602Spjd				break;
1155232072Sjhb			case SYS_posix_fadvise:
1156232128Sjhb				print_number(ip, narg, c);
1157232128Sjhb				print_number(ip, narg, c);
1158232128Sjhb				print_number(ip, narg, c);
1159232072Sjhb				(void)putchar(',');
1160232072Sjhb				fadvisebehavname((int)*ip);
1161232072Sjhb				ip++;
1162232072Sjhb				narg--;
1163232072Sjhb				break;
1164255708Sjhb			case SYS_procctl:
1165255708Sjhb				putchar('(');
1166255708Sjhb				idtypename(*ip, decimal);
1167255708Sjhb				c = ',';
1168255708Sjhb				ip++;
1169255708Sjhb				narg--;
1170255708Sjhb				print_number(ip, narg, c);
1171255708Sjhb				putchar(',');
1172255708Sjhb				procctlcmdname(*ip);
1173255708Sjhb				ip++;
1174255708Sjhb				narg--;
1175255708Sjhb				break;
11761590Srgrimes			}
11771590Srgrimes		}
1178199024Sattilio		while (narg > 0) {
1179226150Sdes			print_number(ip, narg, c);
11801590Srgrimes		}
1181226153Sdes		putchar(')');
11821590Srgrimes	}
1183226153Sdes	putchar('\n');
11841590Srgrimes}
11851590Srgrimes
1186100824Sdwmalonevoid
1187219043Sdchaginktrsysret(struct ktr_sysret *ktr, u_int flags)
11881590Srgrimes{
1189100824Sdwmalone	register_t ret = ktr->ktr_retval;
1190100824Sdwmalone	int error = ktr->ktr_error;
1191100824Sdwmalone	int code = ktr->ktr_code;
11921590Srgrimes
1193219043Sdchagin	if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
1194219043Sdchagin	    (code >= nsyscalls || code < 0))
1195226153Sdes		printf("[%d] ", code);
11961590Srgrimes	else
1197226153Sdes		printf("%s ", syscallnames[code]);
11981590Srgrimes
11991590Srgrimes	if (error == 0) {
12001590Srgrimes		if (fancy) {
1201226153Sdes			printf("%ld", (long)ret);
12021590Srgrimes			if (ret < 0 || ret > 9)
1203226153Sdes				printf("/%#lx", (unsigned long)ret);
12041590Srgrimes		} else {
12051590Srgrimes			if (decimal)
1206226153Sdes				printf("%ld", (long)ret);
12071590Srgrimes			else
1208226153Sdes				printf("%#lx", (unsigned long)ret);
12091590Srgrimes		}
12101590Srgrimes	} else if (error == ERESTART)
1211226153Sdes		printf("RESTART");
12121590Srgrimes	else if (error == EJUSTRETURN)
1213226153Sdes		printf("JUSTRETURN");
12141590Srgrimes	else {
1215226153Sdes		printf("-1 errno %d", ktr->ktr_error);
12161590Srgrimes		if (fancy)
1217226153Sdes			printf(" %s", strerror(ktr->ktr_error));
12181590Srgrimes	}
1219226153Sdes	putchar('\n');
12201590Srgrimes}
12211590Srgrimes
1222100824Sdwmalonevoid
1223100824Sdwmalonektrnamei(char *cp, int len)
12241590Srgrimes{
1225226153Sdes	printf("\"%.*s\"\n", len, cp);
12261590Srgrimes}
12271590Srgrimes
1228100824Sdwmalonevoid
1229115759Speterhexdump(char *p, int len, int screenwidth)
12301590Srgrimes{
1231115759Speter	int n, i;
1232115759Speter	int width;
1233115759Speter
1234115759Speter	width = 0;
1235115759Speter	do {
1236115759Speter		width += 2;
1237115759Speter		i = 13;			/* base offset */
1238115759Speter		i += (width / 2) + 1;	/* spaces every second byte */
1239115759Speter		i += (width * 2);	/* width of bytes */
1240115759Speter		i += 3;			/* "  |" */
1241115759Speter		i += width;		/* each byte */
1242115759Speter		i += 1;			/* "|" */
1243115759Speter	} while (i < screenwidth);
1244115759Speter	width -= 2;
1245115759Speter
1246115759Speter	for (n = 0; n < len; n += width) {
1247115759Speter		for (i = n; i < n + width; i++) {
1248115759Speter			if ((i % width) == 0) {	/* beginning of line */
1249115759Speter				printf("       0x%04x", i);
1250115759Speter			}
1251115759Speter			if ((i % 2) == 0) {
1252115759Speter				printf(" ");
1253115759Speter			}
1254115759Speter			if (i < len)
1255115759Speter				printf("%02x", p[i] & 0xff);
1256115759Speter			else
1257115759Speter				printf("  ");
1258115759Speter		}
1259115759Speter		printf("  |");
1260115759Speter		for (i = n; i < n + width; i++) {
1261115759Speter			if (i >= len)
1262115759Speter				break;
1263115759Speter			if (p[i] >= ' ' && p[i] <= '~')
1264115759Speter				printf("%c", p[i]);
1265115759Speter			else
1266115759Speter				printf(".");
1267115759Speter		}
1268115759Speter		printf("|\n");
1269115759Speter	}
1270115759Speter	if ((i % width) != 0)
1271115759Speter		printf("\n");
1272115759Speter}
1273115759Speter
1274115759Spetervoid
1275115759Spetervisdump(char *dp, int datalen, int screenwidth)
1276115759Speter{
1277115759Speter	int col = 0;
1278100824Sdwmalone	char *cp;
1279100824Sdwmalone	int width;
12801590Srgrimes	char visbuf[5];
12811590Srgrimes
1282226153Sdes	printf("       \"");
12831590Srgrimes	col = 8;
12841590Srgrimes	for (;datalen > 0; datalen--, dp++) {
1285226153Sdes		 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
12861590Srgrimes		cp = visbuf;
12871590Srgrimes		/*
12881590Srgrimes		 * Keep track of printables and
12891590Srgrimes		 * space chars (like fold(1)).
12901590Srgrimes		 */
12911590Srgrimes		if (col == 0) {
1292226153Sdes			putchar('\t');
12931590Srgrimes			col = 8;
12941590Srgrimes		}
12951590Srgrimes		switch(*cp) {
12961590Srgrimes		case '\n':
12971590Srgrimes			col = 0;
1298226153Sdes			putchar('\n');
12991590Srgrimes			continue;
13001590Srgrimes		case '\t':
13011590Srgrimes			width = 8 - (col&07);
13021590Srgrimes			break;
13031590Srgrimes		default:
13041590Srgrimes			width = strlen(cp);
13051590Srgrimes		}
13061590Srgrimes		if (col + width > (screenwidth-2)) {
1307226153Sdes			printf("\\\n\t");
13081590Srgrimes			col = 8;
13091590Srgrimes		}
13101590Srgrimes		col += width;
13111590Srgrimes		do {
1312226153Sdes			putchar(*cp++);
13131590Srgrimes		} while (*cp);
13141590Srgrimes	}
13151590Srgrimes	if (col == 0)
1316226153Sdes		printf("       ");
1317226153Sdes	printf("\"\n");
13181590Srgrimes}
13191590Srgrimes
1320115759Spetervoid
1321115759Speterktrgenio(struct ktr_genio *ktr, int len)
1322115759Speter{
1323115759Speter	int datalen = len - sizeof (struct ktr_genio);
1324115759Speter	char *dp = (char *)ktr + sizeof (struct ktr_genio);
1325115759Speter	static int screenwidth = 0;
1326115759Speter	int i, binary;
1327115759Speter
1328251072Spjd	printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1329251072Spjd		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1330251072Spjd		datalen == 1 ? "" : "s");
1331251072Spjd	if (suppressdata)
1332251072Spjd		return;
1333115759Speter	if (screenwidth == 0) {
1334115759Speter		struct winsize ws;
1335115759Speter
1336115759Speter		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1337115759Speter		    ws.ws_col > 8)
1338115759Speter			screenwidth = ws.ws_col;
1339115759Speter		else
1340115759Speter			screenwidth = 80;
1341115759Speter	}
1342115759Speter	if (maxdata && datalen > maxdata)
1343115759Speter		datalen = maxdata;
1344115759Speter
1345115759Speter	for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1346115759Speter		if (dp[i] >= 32 && dp[i] < 127)
1347115759Speter			continue;
1348115759Speter		if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1349115759Speter			continue;
1350115759Speter		binary = 1;
1351115759Speter	}
1352115759Speter	if (binary)
1353115759Speter		hexdump(dp, datalen, screenwidth);
1354115759Speter	else
1355115759Speter		visdump(dp, datalen, screenwidth);
1356115759Speter}
1357115759Speter
1358100824Sdwmaloneconst char *signames[] = {
13591590Srgrimes	"NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",	/*  1 - 6  */
13601590Srgrimes	"EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",		/*  7 - 12 */
13611590Srgrimes	"PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",		/* 13 - 18 */
13621590Srgrimes	"CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",		/* 19 - 24 */
13631590Srgrimes	"XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",	/* 25 - 30 */
13641590Srgrimes	"USR2", NULL,						/* 31 - 32 */
13651590Srgrimes};
13661590Srgrimes
1367100824Sdwmalonevoid
1368219138Sdchaginktrpsig(struct ktr_psig *psig)
13691590Srgrimes{
1370219138Sdchagin	if (psig->signo > 0 && psig->signo < NSIG)
1371226153Sdes		printf("SIG%s ", signames[psig->signo]);
1372160294Skib	else
1373226153Sdes		printf("SIG %d ", psig->signo);
1374240820Sjilles	if (psig->action == SIG_DFL) {
1375240820Sjilles		printf("SIG_DFL code=");
1376240820Sjilles		sigcodename(psig->signo, psig->code);
1377240820Sjilles		putchar('\n');
1378240820Sjilles	} else {
1379240820Sjilles		printf("caught handler=0x%lx mask=0x%x code=",
1380240820Sjilles		    (u_long)psig->action, psig->mask.__bits[0]);
1381240820Sjilles		sigcodename(psig->signo, psig->code);
1382240820Sjilles		putchar('\n');
1383100824Sdwmalone	}
13841590Srgrimes}
13851590Srgrimes
1386100824Sdwmalonevoid
1387234494Sjhbktrcsw_old(struct ktr_csw_old *cs)
13881590Srgrimes{
1389226153Sdes	printf("%s %s\n", cs->out ? "stop" : "resume",
13901590Srgrimes		cs->user ? "user" : "kernel");
13911590Srgrimes}
13921590Srgrimes
1393234494Sjhbvoid
1394234494Sjhbktrcsw(struct ktr_csw *cs)
1395234494Sjhb{
1396234494Sjhb	printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume",
1397234494Sjhb	    cs->user ? "user" : "kernel", cs->wmesg);
1398234494Sjhb}
1399234494Sjhb
1400165916Sjhb#define	UTRACE_DLOPEN_START		1
1401165916Sjhb#define	UTRACE_DLOPEN_STOP		2
1402165916Sjhb#define	UTRACE_DLCLOSE_START		3
1403165916Sjhb#define	UTRACE_DLCLOSE_STOP		4
1404165916Sjhb#define	UTRACE_LOAD_OBJECT		5
1405165916Sjhb#define	UTRACE_UNLOAD_OBJECT		6
1406165916Sjhb#define	UTRACE_ADD_RUNDEP		7
1407165916Sjhb#define	UTRACE_PRELOAD_FINISHED		8
1408165916Sjhb#define	UTRACE_INIT_CALL		9
1409165916Sjhb#define	UTRACE_FINI_CALL		10
1410165916Sjhb
1411165916Sjhbstruct utrace_rtld {
1412165916Sjhb	char sig[4];				/* 'RTLD' */
1413165916Sjhb	int event;
1414165916Sjhb	void *handle;
1415165916Sjhb	void *mapbase;
1416165916Sjhb	size_t mapsize;
1417165916Sjhb	int refcnt;
1418165916Sjhb	char name[MAXPATHLEN];
1419165916Sjhb};
1420165916Sjhb
1421165916Sjhbvoid
1422165916Sjhbktruser_rtld(int len, unsigned char *p)
1423165916Sjhb{
1424165916Sjhb	struct utrace_rtld *ut = (struct utrace_rtld *)p;
1425165916Sjhb	void *parent;
1426165916Sjhb	int mode;
1427165916Sjhb
1428165916Sjhb	switch (ut->event) {
1429165916Sjhb	case UTRACE_DLOPEN_START:
1430165916Sjhb		mode = ut->refcnt;
1431165916Sjhb		printf("dlopen(%s, ", ut->name);
1432165916Sjhb		switch (mode & RTLD_MODEMASK) {
1433165916Sjhb		case RTLD_NOW:
1434165916Sjhb			printf("RTLD_NOW");
1435165916Sjhb			break;
1436165916Sjhb		case RTLD_LAZY:
1437165916Sjhb			printf("RTLD_LAZY");
1438165916Sjhb			break;
1439165916Sjhb		default:
1440165916Sjhb			printf("%#x", mode & RTLD_MODEMASK);
1441165916Sjhb		}
1442165916Sjhb		if (mode & RTLD_GLOBAL)
1443165916Sjhb			printf(" | RTLD_GLOBAL");
1444165916Sjhb		if (mode & RTLD_TRACE)
1445165916Sjhb			printf(" | RTLD_TRACE");
1446165916Sjhb		if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
1447165916Sjhb			printf(" | %#x", mode &
1448165916Sjhb			    ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
1449165916Sjhb		printf(")\n");
1450165916Sjhb		break;
1451165916Sjhb	case UTRACE_DLOPEN_STOP:
1452165916Sjhb		printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
1453165916Sjhb		    ut->refcnt);
1454165916Sjhb		break;
1455165916Sjhb	case UTRACE_DLCLOSE_START:
1456165916Sjhb		printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
1457165916Sjhb		    ut->refcnt);
1458165916Sjhb		break;
1459165916Sjhb	case UTRACE_DLCLOSE_STOP:
1460165916Sjhb		printf("dlclose(%p) finished\n", ut->handle);
1461165916Sjhb		break;
1462165916Sjhb	case UTRACE_LOAD_OBJECT:
1463165916Sjhb		printf("RTLD: loaded   %p @ %p - %p (%s)\n", ut->handle,
1464165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1465165916Sjhb		    ut->name);
1466165916Sjhb		break;
1467165916Sjhb	case UTRACE_UNLOAD_OBJECT:
1468165916Sjhb		printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
1469165916Sjhb		    ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1470165916Sjhb		    ut->name);
1471165916Sjhb		break;
1472165916Sjhb	case UTRACE_ADD_RUNDEP:
1473165916Sjhb		parent = ut->mapbase;
1474165916Sjhb		printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
1475165916Sjhb		    ut->handle, ut->name, ut->refcnt);
1476165916Sjhb		break;
1477165916Sjhb	case UTRACE_PRELOAD_FINISHED:
1478165916Sjhb		printf("RTLD: LD_PRELOAD finished\n");
1479165916Sjhb		break;
1480165916Sjhb	case UTRACE_INIT_CALL:
1481165916Sjhb		printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1482165916Sjhb		    ut->name);
1483165916Sjhb		break;
1484165916Sjhb	case UTRACE_FINI_CALL:
1485165916Sjhb		printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1486165916Sjhb		    ut->name);
1487165916Sjhb		break;
1488165916Sjhb	default:
1489165916Sjhb		p += 4;
1490165916Sjhb		len -= 4;
1491165916Sjhb		printf("RTLD: %d ", len);
1492165916Sjhb		while (len--)
1493165916Sjhb			if (decimal)
1494165916Sjhb				printf(" %d", *p++);
1495165916Sjhb			else
1496165916Sjhb				printf(" %02x", *p++);
1497165916Sjhb		printf("\n");
1498165916Sjhb	}
1499165916Sjhb}
1500165916Sjhb
1501165812Sjhbstruct utrace_malloc {
1502165812Sjhb	void *p;
1503165812Sjhb	size_t s;
1504165812Sjhb	void *r;
1505165812Sjhb};
1506165812Sjhb
1507100824Sdwmalonevoid
1508226329Sdesktruser_malloc(unsigned char *p)
1509165812Sjhb{
1510165812Sjhb	struct utrace_malloc *ut = (struct utrace_malloc *)p;
1511165812Sjhb
1512199265Scperciva	if (ut->p == (void *)(intptr_t)(-1))
1513199265Scperciva		printf("malloc_init()\n");
1514199265Scperciva	else if (ut->s == 0)
1515199265Scperciva		printf("free(%p)\n", ut->p);
1516199265Scperciva	else if (ut->p == NULL)
1517199265Scperciva		printf("%p = malloc(%zu)\n", ut->r, ut->s);
1518199265Scperciva	else
1519199265Scperciva		printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1520165812Sjhb}
1521165812Sjhb
1522165812Sjhbvoid
1523100824Sdwmalonektruser(int len, unsigned char *p)
152418400Sphk{
1525165812Sjhb
1526165916Sjhb	if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1527165916Sjhb		ktruser_rtld(len, p);
1528165916Sjhb		return;
1529165916Sjhb	}
1530165916Sjhb
1531165812Sjhb	if (len == sizeof(struct utrace_malloc)) {
1532226329Sdes		ktruser_malloc(p);
1533165812Sjhb		return;
1534165812Sjhb	}
1535165812Sjhb
1536226153Sdes	printf("%d ", len);
153718470Sphk	while (len--)
1538127402Sphk		if (decimal)
1539226153Sdes			printf(" %d", *p++);
1540127402Sphk		else
1541226153Sdes			printf(" %02x", *p++);
1542226153Sdes	printf("\n");
154318400Sphk}
154418400Sphk
1545100824Sdwmalonevoid
1546255219Spjdktrcaprights(cap_rights_t *rightsp)
1547255219Spjd{
1548255219Spjd
1549255219Spjd	printf("cap_rights_t ");
1550255219Spjd	capname(rightsp);
1551255219Spjd	printf("\n");
1552255219Spjd}
1553255219Spjd
1554255219Spjdvoid
1555176471Sdesktrsockaddr(struct sockaddr *sa)
1556176471Sdes{
1557176471Sdes/*
1558176471Sdes TODO: Support additional address families
1559176471Sdes	#include <netnatm/natm.h>
1560176471Sdes	struct sockaddr_natm	*natm;
1561252356Sdavide	#include <netsmb/netbios.h>
1562252356Sdavide	struct sockaddr_nb	*nb;
1563176471Sdes*/
1564176471Sdes	char addr[64];
1565176471Sdes
1566176471Sdes	/*
1567176471Sdes	 * note: ktrstruct() has already verified that sa points to a
1568176471Sdes	 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1569176471Sdes	 * sa->sa_len bytes long.
1570176471Sdes	 */
1571176471Sdes	printf("struct sockaddr { ");
1572176471Sdes	sockfamilyname(sa->sa_family);
1573176471Sdes	printf(", ");
1574176471Sdes
1575176471Sdes#define check_sockaddr_len(n)					\
1576226329Sdes	if (sa_##n.s##n##_len < sizeof(struct sockaddr_##n)) {	\
1577176471Sdes		printf("invalid");				\
1578176471Sdes		break;						\
1579176471Sdes	}
1580176471Sdes
1581176471Sdes	switch(sa->sa_family) {
1582176471Sdes	case AF_INET: {
1583226329Sdes		struct sockaddr_in sa_in;
1584176471Sdes
1585226329Sdes		memset(&sa_in, 0, sizeof(sa_in));
1586246719Szont		memcpy(&sa_in, sa, sa->sa_len);
1587176471Sdes		check_sockaddr_len(in);
1588226329Sdes		inet_ntop(AF_INET, &sa_in.sin_addr, addr, sizeof addr);
1589226329Sdes		printf("%s:%u", addr, ntohs(sa_in.sin_port));
1590176471Sdes		break;
1591176471Sdes	}
1592176471Sdes#ifdef NETATALK
1593176471Sdes	case AF_APPLETALK: {
1594226329Sdes		struct sockaddr_at	sa_at;
1595176471Sdes		struct netrange		*nr;
1596176471Sdes
1597226329Sdes		memset(&sa_at, 0, sizeof(sa_at));
1598246719Szont		memcpy(&sa_at, sa, sa->sa_len);
1599176471Sdes		check_sockaddr_len(at);
1600226329Sdes		nr = &sa_at.sat_range.r_netrange;
1601226329Sdes		printf("%d.%d, %d-%d, %d", ntohs(sa_at.sat_addr.s_net),
1602226329Sdes			sa_at.sat_addr.s_node, ntohs(nr->nr_firstnet),
1603176471Sdes			ntohs(nr->nr_lastnet), nr->nr_phase);
1604176471Sdes		break;
1605176471Sdes	}
1606176471Sdes#endif
1607176471Sdes	case AF_INET6: {
1608226329Sdes		struct sockaddr_in6 sa_in6;
1609176471Sdes
1610226329Sdes		memset(&sa_in6, 0, sizeof(sa_in6));
1611246719Szont		memcpy(&sa_in6, sa, sa->sa_len);
1612176471Sdes		check_sockaddr_len(in6);
1613251486Sae		getnameinfo((struct sockaddr *)&sa_in6, sizeof(sa_in6),
1614251486Sae		    addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
1615226329Sdes		printf("[%s]:%u", addr, htons(sa_in6.sin6_port));
1616176471Sdes		break;
1617176471Sdes	}
1618176471Sdes#ifdef IPX
1619176471Sdes	case AF_IPX: {
1620226329Sdes		struct sockaddr_ipx sa_ipx;
1621176471Sdes
1622226329Sdes		memset(&sa_ipx, 0, sizeof(sa_ipx));
1623246719Szont		memcpy(&sa_ipx, sa, sa->sa_len);
1624176471Sdes		check_sockaddr_len(ipx);
1625176471Sdes		/* XXX wish we had ipx_ntop */
1626226329Sdes		printf("%s", ipx_ntoa(sa_ipx.sipx_addr));
1627226329Sdes		free(sa_ipx);
1628176471Sdes		break;
1629176471Sdes	}
1630176471Sdes#endif
1631176471Sdes	case AF_UNIX: {
1632226329Sdes		struct sockaddr_un sa_un;
1633176471Sdes
1634226329Sdes		memset(&sa_un, 0, sizeof(sa_un));
1635246719Szont		memcpy(&sa_un, sa, sa->sa_len);
1636226329Sdes		printf("%.*s", (int)sizeof(sa_un.sun_path), sa_un.sun_path);
1637176471Sdes		break;
1638176471Sdes	}
1639176471Sdes	default:
1640176471Sdes		printf("unknown address family");
1641176471Sdes	}
1642176471Sdes	printf(" }\n");
1643176471Sdes}
1644176471Sdes
1645176471Sdesvoid
1646176471Sdesktrstat(struct stat *statp)
1647176471Sdes{
1648176471Sdes	char mode[12], timestr[PATH_MAX + 4];
1649176471Sdes	struct passwd *pwd;
1650176471Sdes	struct group  *grp;
1651176471Sdes	struct tm *tm;
1652176471Sdes
1653176471Sdes	/*
1654176471Sdes	 * note: ktrstruct() has already verified that statp points to a
1655176471Sdes	 * buffer exactly sizeof(struct stat) bytes long.
1656176471Sdes	 */
1657176471Sdes	printf("struct stat {");
1658256107Sdes	printf("dev=%ju, ino=%ju, ",
1659256107Sdes		(uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino);
1660256107Sdes	if (resolv == 0)
1661256107Sdes		printf("mode=0%jo, ", (uintmax_t)statp->st_mode);
1662256107Sdes	else {
1663256107Sdes		strmode(statp->st_mode, mode);
1664256107Sdes		printf("mode=%s, ", mode);
1665256107Sdes	}
1666256107Sdes	printf("nlink=%ju, ", (uintmax_t)statp->st_nlink);
1667176471Sdes	if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1668176471Sdes		printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1669176471Sdes	else
1670176471Sdes		printf("uid=\"%s\", ", pwd->pw_name);
1671176471Sdes	if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1672176471Sdes		printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1673176471Sdes	else
1674176471Sdes		printf("gid=\"%s\", ", grp->gr_name);
1675176471Sdes	printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1676176471Sdes	printf("atime=");
1677176471Sdes	if (resolv == 0)
1678205793Sed		printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1679176471Sdes	else {
1680205793Sed		tm = localtime(&statp->st_atim.tv_sec);
1681226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1682176471Sdes		printf("\"%s\"", timestr);
1683176471Sdes	}
1684205793Sed	if (statp->st_atim.tv_nsec != 0)
1685205793Sed		printf(".%09ld, ", statp->st_atim.tv_nsec);
1686176471Sdes	else
1687176471Sdes		printf(", ");
1688176471Sdes	printf("stime=");
1689176471Sdes	if (resolv == 0)
1690205793Sed		printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1691176471Sdes	else {
1692205793Sed		tm = localtime(&statp->st_mtim.tv_sec);
1693226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1694176471Sdes		printf("\"%s\"", timestr);
1695176471Sdes	}
1696205793Sed	if (statp->st_mtim.tv_nsec != 0)
1697205793Sed		printf(".%09ld, ", statp->st_mtim.tv_nsec);
1698176471Sdes	else
1699176471Sdes		printf(", ");
1700176471Sdes	printf("ctime=");
1701176471Sdes	if (resolv == 0)
1702205793Sed		printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1703176471Sdes	else {
1704205793Sed		tm = localtime(&statp->st_ctim.tv_sec);
1705226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1706176471Sdes		printf("\"%s\"", timestr);
1707176471Sdes	}
1708205793Sed	if (statp->st_ctim.tv_nsec != 0)
1709205793Sed		printf(".%09ld, ", statp->st_ctim.tv_nsec);
1710176471Sdes	else
1711176471Sdes		printf(", ");
1712176471Sdes	printf("birthtime=");
1713176471Sdes	if (resolv == 0)
1714205793Sed		printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
1715176471Sdes	else {
1716205793Sed		tm = localtime(&statp->st_birthtim.tv_sec);
1717226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1718176471Sdes		printf("\"%s\"", timestr);
1719176471Sdes	}
1720205793Sed	if (statp->st_birthtim.tv_nsec != 0)
1721205793Sed		printf(".%09ld, ", statp->st_birthtim.tv_nsec);
1722176471Sdes	else
1723176471Sdes		printf(", ");
1724176471Sdes	printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1725176471Sdes		(uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
1726176471Sdes		(intmax_t)statp->st_blocks, statp->st_flags);
1727176471Sdes	printf(" }\n");
1728176471Sdes}
1729176471Sdes
1730176471Sdesvoid
1731176471Sdesktrstruct(char *buf, size_t buflen)
1732176471Sdes{
1733176471Sdes	char *name, *data;
1734176471Sdes	size_t namelen, datalen;
1735176471Sdes	int i;
1736255219Spjd	cap_rights_t rights;
1737204045Simp	struct stat sb;
1738204045Simp	struct sockaddr_storage ss;
1739176471Sdes
1740176471Sdes	for (name = buf, namelen = 0;
1741176471Sdes	     namelen < buflen && name[namelen] != '\0';
1742176471Sdes	     ++namelen)
1743176471Sdes		/* nothing */;
1744176471Sdes	if (namelen == buflen)
1745176471Sdes		goto invalid;
1746176471Sdes	if (name[namelen] != '\0')
1747176471Sdes		goto invalid;
1748176471Sdes	data = buf + namelen + 1;
1749176471Sdes	datalen = buflen - namelen - 1;
1750176471Sdes	if (datalen == 0)
1751176471Sdes		goto invalid;
1752176471Sdes	/* sanity check */
1753226329Sdes	for (i = 0; i < (int)namelen; ++i)
1754226329Sdes		if (!isalpha(name[i]))
1755176471Sdes			goto invalid;
1756255219Spjd	if (strcmp(name, "caprights") == 0) {
1757255219Spjd		if (datalen != sizeof(cap_rights_t))
1758255219Spjd			goto invalid;
1759255219Spjd		memcpy(&rights, data, datalen);
1760255219Spjd		ktrcaprights(&rights);
1761255219Spjd	} else if (strcmp(name, "stat") == 0) {
1762176471Sdes		if (datalen != sizeof(struct stat))
1763176471Sdes			goto invalid;
1764204045Simp		memcpy(&sb, data, datalen);
1765204045Simp		ktrstat(&sb);
1766176471Sdes	} else if (strcmp(name, "sockaddr") == 0) {
1767204045Simp		if (datalen > sizeof(ss))
1768204045Simp			goto invalid;
1769204045Simp		memcpy(&ss, data, datalen);
1770246720Szont		if (datalen != ss.ss_len)
1771176471Sdes			goto invalid;
1772204045Simp		ktrsockaddr((struct sockaddr *)&ss);
1773176471Sdes	} else {
1774176471Sdes		printf("unknown structure\n");
1775176471Sdes	}
1776176471Sdes	return;
1777176471Sdesinvalid:
1778176471Sdes	printf("invalid record\n");
1779176471Sdes}
1780176471Sdes
1781226269Sdesvoid
1782226269Sdesktrcapfail(struct ktr_cap_fail *ktr)
1783226269Sdes{
1784226495Sdes	switch (ktr->cap_type) {
1785226495Sdes	case CAPFAIL_NOTCAPABLE:
1786226495Sdes		/* operation on fd with insufficient capabilities */
1787226495Sdes		printf("operation requires ");
1788255219Spjd		capname(&ktr->cap_needed);
1789226495Sdes		printf(", process holds ");
1790255219Spjd		capname(&ktr->cap_held);
1791226495Sdes		break;
1792226495Sdes	case CAPFAIL_INCREASE:
1793226495Sdes		/* requested more capabilities than fd already has */
1794226495Sdes		printf("attempt to increase capabilities from ");
1795255219Spjd		capname(&ktr->cap_held);
1796226505Sdes		printf(" to ");
1797255219Spjd		capname(&ktr->cap_needed);
1798226495Sdes		break;
1799226495Sdes	case CAPFAIL_SYSCALL:
1800226495Sdes		/* called restricted syscall */
1801226495Sdes		printf("disallowed system call");
1802226495Sdes		break;
1803226495Sdes	case CAPFAIL_LOOKUP:
1804226495Sdes		/* used ".." in strict-relative mode */
1805226495Sdes		printf("restricted VFS lookup");
1806226495Sdes		break;
1807226495Sdes	default:
1808226495Sdes		printf("unknown capability failure: ");
1809255219Spjd		capname(&ktr->cap_needed);
1810226495Sdes		printf(" ");
1811255219Spjd		capname(&ktr->cap_held);
1812226495Sdes		break;
1813226495Sdes	}
1814233925Sjhb	printf("\n");
1815226269Sdes}
1816226269Sdes
1817233925Sjhbvoid
1818233925Sjhbktrfault(struct ktr_fault *ktr)
1819233925Sjhb{
1820233925Sjhb
1821233925Sjhb	printf("0x%jx ", ktr->vaddr);
1822233925Sjhb	vmprotname(ktr->type);
1823233925Sjhb	printf("\n");
1824233925Sjhb}
1825233925Sjhb
1826233925Sjhbvoid
1827233925Sjhbktrfaultend(struct ktr_faultend *ktr)
1828233925Sjhb{
1829233925Sjhb
1830233925Sjhb	vmresultname(ktr->result);
1831233925Sjhb	printf("\n");
1832233925Sjhb}
1833233925Sjhb
1834219138Sdchagin#if defined(__amd64__) || defined(__i386__)
1835176471Sdesvoid
1836219138Sdchaginlinux_ktrsyscall(struct ktr_syscall *ktr)
1837219138Sdchagin{
1838219138Sdchagin	int narg = ktr->ktr_narg;
1839219138Sdchagin	register_t *ip;
1840219138Sdchagin
1841219138Sdchagin	if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
1842219138Sdchagin		printf("[%d]", ktr->ktr_code);
1843219138Sdchagin	else
1844219138Sdchagin		printf("%s", linux_syscallnames[ktr->ktr_code]);
1845219138Sdchagin	ip = &ktr->ktr_args[0];
1846219138Sdchagin	if (narg) {
1847219138Sdchagin		char c = '(';
1848219138Sdchagin		while (narg > 0)
1849219138Sdchagin			print_number(ip, narg, c);
1850219138Sdchagin		putchar(')');
1851219138Sdchagin	}
1852219138Sdchagin	putchar('\n');
1853219138Sdchagin}
1854219138Sdchagin
1855219138Sdchaginvoid
1856219138Sdchaginlinux_ktrsysret(struct ktr_sysret *ktr)
1857219138Sdchagin{
1858219138Sdchagin	register_t ret = ktr->ktr_retval;
1859219138Sdchagin	int error = ktr->ktr_error;
1860219138Sdchagin	int code = ktr->ktr_code;
1861219138Sdchagin
1862219138Sdchagin	if (code >= nlinux_syscalls || code < 0)
1863219138Sdchagin		printf("[%d] ", code);
1864219138Sdchagin	else
1865219138Sdchagin		printf("%s ", linux_syscallnames[code]);
1866219138Sdchagin
1867219138Sdchagin	if (error == 0) {
1868219138Sdchagin		if (fancy) {
1869219138Sdchagin			printf("%ld", (long)ret);
1870219138Sdchagin			if (ret < 0 || ret > 9)
1871226153Sdes				printf("/%#lx", (unsigned long)ret);
1872219138Sdchagin		} else {
1873219138Sdchagin			if (decimal)
1874219138Sdchagin				printf("%ld", (long)ret);
1875219138Sdchagin			else
1876226153Sdes				printf("%#lx", (unsigned long)ret);
1877219138Sdchagin		}
1878219138Sdchagin	} else if (error == ERESTART)
1879219138Sdchagin		printf("RESTART");
1880219138Sdchagin	else if (error == EJUSTRETURN)
1881219138Sdchagin		printf("JUSTRETURN");
1882219138Sdchagin	else {
1883219138Sdchagin		if (ktr->ktr_error <= ELAST + 1)
1884219138Sdchagin			error = abs(bsd_to_linux_errno[ktr->ktr_error]);
1885219138Sdchagin		else
1886219138Sdchagin			error = 999;
1887219138Sdchagin		printf("-1 errno %d", error);
1888219138Sdchagin		if (fancy)
1889219138Sdchagin			printf(" %s", strerror(ktr->ktr_error));
1890219138Sdchagin	}
1891219138Sdchagin	putchar('\n');
1892219138Sdchagin}
1893219138Sdchagin#endif
1894219138Sdchagin
1895219138Sdchaginvoid
1896100824Sdwmaloneusage(void)
18971590Srgrimes{
1898219043Sdchagin	fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] "
1899177856Sru	    "[-m maxdata] [-p pid] [-t trstr]\n");
19001590Srgrimes	exit(1);
19011590Srgrimes}
1902