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: releng/11.0/usr.bin/kdump/kdump.c 303092 2016-07-20 15:02:37Z kib $");
431590Srgrimes
4455206Speter#define _KERNEL
452215Scsgrextern int errno;
462215Scsgr#include <sys/errno.h>
4755206Speter#undef _KERNEL
481590Srgrimes#include <sys/param.h>
49263234Srwatson#include <sys/capsicum.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>
60273053Sjhb#include <sys/umtx.h>
61176471Sdes#include <sys/un.h>
62219043Sdchagin#include <sys/queue.h>
63255493Sjhb#include <sys/wait.h>
64296047Soshogbo#ifdef HAVE_LIBCASPER
65285063Soshogbo#include <sys/nv.h>
66285063Soshogbo#endif
67190168Sdelphij#include <arpa/inet.h>
68176471Sdes#include <netinet/in.h>
69190168Sdelphij#include <ctype.h>
7027443Scharnier#include <err.h>
71176471Sdes#include <grp.h>
72176471Sdes#include <inttypes.h>
7327443Scharnier#include <locale.h>
74251486Sae#include <netdb.h>
75251073Spjd#include <nl_types.h>
76176471Sdes#include <pwd.h>
771590Srgrimes#include <stdio.h>
781590Srgrimes#include <stdlib.h>
791590Srgrimes#include <string.h>
80292236Sjhb#include <sysdecode.h>
81251073Spjd#include <termios.h>
82176471Sdes#include <time.h>
8327443Scharnier#include <unistd.h>
8427443Scharnier#include <vis.h>
851590Srgrimes#include "ktrace.h"
86158766Snetchild#include "kdump_subr.h"
871590Srgrimes
88296047Soshogbo#ifdef HAVE_LIBCASPER
89296047Soshogbo#include <libcasper.h>
90296047Soshogbo
91296047Soshogbo#include <casper/cap_grp.h>
92296047Soshogbo#include <casper/cap_pwd.h>
93296047Soshogbo#endif
94296047Soshogbo
95219043Sdchaginu_int abidump(struct ktr_header *);
96219043Sdchaginint fetchprocinfo(struct ktr_header *, u_int *);
97100824Sdwmaloneint fread_tail(void *, int, int);
98100824Sdwmalonevoid dumpheader(struct ktr_header *);
99219043Sdchaginvoid ktrsyscall(struct ktr_syscall *, u_int);
100219043Sdchaginvoid ktrsysret(struct ktr_sysret *, u_int);
101100824Sdwmalonevoid ktrnamei(char *, int);
102115759Spetervoid hexdump(char *, int, int);
103115759Spetervoid visdump(char *, int, int);
104100824Sdwmalonevoid ktrgenio(struct ktr_genio *, int);
105219138Sdchaginvoid ktrpsig(struct ktr_psig *);
106100824Sdwmalonevoid ktrcsw(struct ktr_csw *);
107234494Sjhbvoid ktrcsw_old(struct ktr_csw_old *);
108273048Sjhbvoid ktruser_malloc(void *);
109273048Sjhbvoid ktruser_rtld(int, void *);
110273048Sjhbvoid ktruser(int, void *);
111255219Spjdvoid ktrcaprights(cap_rights_t *);
112303092Skibvoid ktritimerval(struct itimerval *it);
113176471Sdesvoid ktrsockaddr(struct sockaddr *);
114176471Sdesvoid ktrstat(struct stat *);
115176471Sdesvoid ktrstruct(char *, size_t);
116226269Sdesvoid ktrcapfail(struct ktr_cap_fail *);
117233925Sjhbvoid ktrfault(struct ktr_fault *);
118233925Sjhbvoid ktrfaultend(struct ktr_faultend *);
119251073Spjdvoid limitfd(int fd);
120100824Sdwmalonevoid usage(void);
121100824Sdwmalone
122263756Ssobomax#define	TIMESTAMP_NONE		0x0
123263756Ssobomax#define	TIMESTAMP_ABSOLUTE	0x1
124263756Ssobomax#define	TIMESTAMP_ELAPSED	0x2
125263756Ssobomax#define	TIMESTAMP_RELATIVE	0x4
126263756Ssobomax
127294849Sjhbextern const char *signames[];
128273048Sjhb
129273048Sjhbstatic int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
130263879Sbdrewery    resolv = 0, abiflag = 0, syscallno = 0;
131273048Sjhbstatic const char *tracefile = DEF_TRACEFILE;
132273048Sjhbstatic struct ktr_header ktr_header;
1331590Srgrimes
134176471Sdes#define TIME_FORMAT	"%b %e %T %Y"
1351590Srgrimes#define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
1361590Srgrimes
137226262Sdes#define print_number(i,n,c) do {					\
138226262Sdes	if (decimal)							\
139226262Sdes		printf("%c%jd", c, (intmax_t)*i);			\
140226262Sdes	else								\
141226262Sdes		printf("%c%#jx", c, (uintmax_t)(u_register_t)*i);	\
142226262Sdes	i++;								\
143226262Sdes	n--;								\
144226262Sdes	c = ',';							\
145226164Sdes} while (0)
146219138Sdchagin
147219043Sdchaginstruct proc_info
148219043Sdchagin{
149219043Sdchagin	TAILQ_ENTRY(proc_info)	info;
150219043Sdchagin	u_int			sv_flags;
151219043Sdchagin	pid_t			pid;
152219043Sdchagin};
153219043Sdchagin
154273048Sjhbstatic TAILQ_HEAD(trace_procs, proc_info) trace_procs;
155219043Sdchagin
156296047Soshogbo#ifdef HAVE_LIBCASPER
157259434Spjdstatic cap_channel_t *cappwd, *capgrp;
158259434Spjd#endif
159259434Spjd
160253456Spjdstatic void
161253456Spjdstrerror_init(void)
162253456Spjd{
163253456Spjd
164253456Spjd	/*
165253456Spjd	 * Cache NLS data before entering capability mode.
166253456Spjd	 * XXXPJD: There should be strerror_init() and strsignal_init() in libc.
167253456Spjd	 */
168253456Spjd	(void)catopen("libc", NL_CAT_LOCALE);
169253456Spjd}
170253456Spjd
171253456Spjdstatic void
172253456Spjdlocaltime_init(void)
173253456Spjd{
174253456Spjd	time_t ltime;
175253456Spjd
176253456Spjd	/*
177253456Spjd	 * Allow localtime(3) to cache /etc/localtime content before entering
178253456Spjd	 * capability mode.
179253456Spjd	 * XXXPJD: There should be localtime_init() in libc.
180253456Spjd	 */
181253456Spjd	(void)time(&ltime);
182253456Spjd	(void)localtime(&ltime);
183253456Spjd}
184253456Spjd
185296047Soshogbo#ifdef HAVE_LIBCASPER
186259434Spjdstatic int
187259434Spjdcappwdgrp_setup(cap_channel_t **cappwdp, cap_channel_t **capgrpp)
188259434Spjd{
189259434Spjd	cap_channel_t *capcas, *cappwdloc, *capgrploc;
190259434Spjd	const char *cmds[1], *fields[1];
191259434Spjd
192259434Spjd	capcas = cap_init();
193259434Spjd	if (capcas == NULL) {
194296047Soshogbo		err(1, "unable to create casper process");
195296047Soshogbo		exit(1);
196259434Spjd	}
197259434Spjd	cappwdloc = cap_service_open(capcas, "system.pwd");
198259434Spjd	capgrploc = cap_service_open(capcas, "system.grp");
199259434Spjd	/* Casper capability no longer needed. */
200259434Spjd	cap_close(capcas);
201259434Spjd	if (cappwdloc == NULL || capgrploc == NULL) {
202259434Spjd		if (cappwdloc == NULL)
203259434Spjd			warn("unable to open system.pwd service");
204259434Spjd		if (capgrploc == NULL)
205259434Spjd			warn("unable to open system.grp service");
206259580Spjd		exit(1);
207259434Spjd	}
208259434Spjd	/* Limit system.pwd to only getpwuid() function and pw_name field. */
209259434Spjd	cmds[0] = "getpwuid";
210259580Spjd	if (cap_pwd_limit_cmds(cappwdloc, cmds, 1) < 0)
211259580Spjd		err(1, "unable to limit system.pwd service");
212259434Spjd	fields[0] = "pw_name";
213259580Spjd	if (cap_pwd_limit_fields(cappwdloc, fields, 1) < 0)
214259580Spjd		err(1, "unable to limit system.pwd service");
215259434Spjd	/* Limit system.grp to only getgrgid() function and gr_name field. */
216259434Spjd	cmds[0] = "getgrgid";
217259580Spjd	if (cap_grp_limit_cmds(capgrploc, cmds, 1) < 0)
218259580Spjd		err(1, "unable to limit system.grp service");
219259434Spjd	fields[0] = "gr_name";
220259580Spjd	if (cap_grp_limit_fields(capgrploc, fields, 1) < 0)
221259580Spjd		err(1, "unable to limit system.grp service");
222259434Spjd
223259434Spjd	*cappwdp = cappwdloc;
224259434Spjd	*capgrpp = capgrploc;
225259434Spjd	return (0);
226259434Spjd}
227296047Soshogbo#endif	/* HAVE_LIBCASPER */
228259434Spjd
229100824Sdwmaloneint
230100824Sdwmalonemain(int argc, char *argv[])
2311590Srgrimes{
2321590Srgrimes	int ch, ktrlen, size;
233100824Sdwmalone	void *m;
2341590Srgrimes	int trpoints = ALL_POINTS;
235112201Sjhb	int drop_logged;
236115759Speter	pid_t pid = 0;
237219043Sdchagin	u_int sv_flags;
2381590Srgrimes
239226153Sdes	setlocale(LC_CTYPE, "");
24011823Sache
241263756Ssobomax	timestamp = TIMESTAMP_NONE;
242263756Ssobomax
243263879Sbdrewery	while ((ch = getopt(argc,argv,"f:dElm:np:AHRrSsTt:")) != -1)
244226153Sdes		switch (ch) {
245219043Sdchagin		case 'A':
246219043Sdchagin			abiflag = 1;
247219043Sdchagin			break;
2481590Srgrimes		case 'f':
2491590Srgrimes			tracefile = optarg;
2501590Srgrimes			break;
2511590Srgrimes		case 'd':
2521590Srgrimes			decimal = 1;
2531590Srgrimes			break;
2541590Srgrimes		case 'l':
2551590Srgrimes			tail = 1;
2561590Srgrimes			break;
2571590Srgrimes		case 'm':
2581590Srgrimes			maxdata = atoi(optarg);
2591590Srgrimes			break;
2601590Srgrimes		case 'n':
2611590Srgrimes			fancy = 0;
2621590Srgrimes			break;
263115759Speter		case 'p':
264115759Speter			pid = atoi(optarg);
265115759Speter			break;
266176471Sdes		case 'r':
267176471Sdes			resolv = 1;
268176471Sdes			break;
269263879Sbdrewery		case 'S':
270263879Sbdrewery			syscallno = 1;
271263879Sbdrewery			break;
272152331Srwatson		case 's':
273152331Srwatson			suppressdata = 1;
274152331Srwatson			break;
275123187Speter		case 'E':
276263756Ssobomax			timestamp |= TIMESTAMP_ELAPSED;
277123187Speter			break;
278151930Srwatson		case 'H':
279151930Srwatson			threads = 1;
280151930Srwatson			break;
2811590Srgrimes		case 'R':
282263756Ssobomax			timestamp |= TIMESTAMP_RELATIVE;
2831590Srgrimes			break;
2841590Srgrimes		case 'T':
285263756Ssobomax			timestamp |= TIMESTAMP_ABSOLUTE;
2861590Srgrimes			break;
2871590Srgrimes		case 't':
2881590Srgrimes			trpoints = getpoints(optarg);
28927443Scharnier			if (trpoints < 0)
29027443Scharnier				errx(1, "unknown trace point in %s", optarg);
2911590Srgrimes			break;
2921590Srgrimes		default:
2931590Srgrimes			usage();
2941590Srgrimes		}
2951590Srgrimes
29619853Sfenner	if (argc > optind)
2971590Srgrimes		usage();
2981590Srgrimes
299226153Sdes	m = malloc(size = 1025);
30027443Scharnier	if (m == NULL)
30127443Scharnier		errx(1, "%s", strerror(ENOMEM));
302299998Ssjg	if (strcmp(tracefile, "-") != 0)
303299995Ssjg		if (!freopen(tracefile, "r", stdin))
304299995Ssjg			err(1, "%s", tracefile);
305251073Spjd
306253456Spjd	strerror_init();
307253456Spjd	localtime_init();
308296047Soshogbo#ifdef HAVE_LIBCASPER
309259434Spjd	if (resolv != 0) {
310259434Spjd		if (cappwdgrp_setup(&cappwd, &capgrp) < 0) {
311259434Spjd			cappwd = NULL;
312259434Spjd			capgrp = NULL;
313259434Spjd		}
314259434Spjd	}
315259434Spjd	if (resolv == 0 || (cappwd != NULL && capgrp != NULL)) {
316259434Spjd		if (cap_enter() < 0 && errno != ENOSYS)
317259434Spjd			err(1, "unable to enter capability mode");
318259434Spjd	}
319259434Spjd#else
320251167Spjd	if (resolv == 0) {
321251167Spjd		if (cap_enter() < 0 && errno != ENOSYS)
322251167Spjd			err(1, "unable to enter capability mode");
323251167Spjd	}
324259434Spjd#endif
325251073Spjd	limitfd(STDIN_FILENO);
326251073Spjd	limitfd(STDOUT_FILENO);
327251073Spjd	limitfd(STDERR_FILENO);
328251073Spjd
329219043Sdchagin	TAILQ_INIT(&trace_procs);
330112201Sjhb	drop_logged = 0;
3311590Srgrimes	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
332112201Sjhb		if (ktr_header.ktr_type & KTR_DROP) {
333112201Sjhb			ktr_header.ktr_type &= ~KTR_DROP;
334151930Srwatson			if (!drop_logged && threads) {
335226153Sdes				printf(
336203551Sjh				    "%6jd %6jd %-8.*s Events dropped.\n",
337203551Sjh				    (intmax_t)ktr_header.ktr_pid,
338203551Sjh				    ktr_header.ktr_tid > 0 ?
339203551Sjh				    (intmax_t)ktr_header.ktr_tid : 0,
340203551Sjh				    MAXCOMLEN, ktr_header.ktr_comm);
341151930Srwatson				drop_logged = 1;
342151930Srwatson			} else if (!drop_logged) {
343226153Sdes				printf("%6jd %-8.*s Events dropped.\n",
344203551Sjh				    (intmax_t)ktr_header.ktr_pid, MAXCOMLEN,
345112201Sjhb				    ktr_header.ktr_comm);
346112201Sjhb				drop_logged = 1;
347112201Sjhb			}
348112201Sjhb		}
3491590Srgrimes		if (trpoints & (1<<ktr_header.ktr_type))
350236577Sjhb			if (pid == 0 || ktr_header.ktr_pid == pid ||
351236577Sjhb			    ktr_header.ktr_tid == pid)
352115759Speter				dumpheader(&ktr_header);
35327443Scharnier		if ((ktrlen = ktr_header.ktr_len) < 0)
35427443Scharnier			errx(1, "bogus length 0x%x", ktrlen);
3551590Srgrimes		if (ktrlen > size) {
356226153Sdes			m = realloc(m, ktrlen+1);
35727443Scharnier			if (m == NULL)
35827443Scharnier				errx(1, "%s", strerror(ENOMEM));
3591590Srgrimes			size = ktrlen;
3601590Srgrimes		}
36127443Scharnier		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
36227443Scharnier			errx(1, "data too short");
363219043Sdchagin		if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
364219043Sdchagin			continue;
365219043Sdchagin		sv_flags = abidump(&ktr_header);
366236577Sjhb		if (pid && ktr_header.ktr_pid != pid &&
367236577Sjhb		    ktr_header.ktr_tid != pid)
368115759Speter			continue;
3691590Srgrimes		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
3701590Srgrimes			continue;
371112201Sjhb		drop_logged = 0;
3721590Srgrimes		switch (ktr_header.ktr_type) {
3731590Srgrimes		case KTR_SYSCALL:
374294849Sjhb			ktrsyscall((struct ktr_syscall *)m, sv_flags);
3751590Srgrimes			break;
3761590Srgrimes		case KTR_SYSRET:
377295931Sjhb			ktrsysret((struct ktr_sysret *)m, sv_flags);
3781590Srgrimes			break;
3791590Srgrimes		case KTR_NAMEI:
380189707Sjhb		case KTR_SYSCTL:
3811590Srgrimes			ktrnamei(m, ktrlen);
3821590Srgrimes			break;
3831590Srgrimes		case KTR_GENIO:
3841590Srgrimes			ktrgenio((struct ktr_genio *)m, ktrlen);
3851590Srgrimes			break;
3861590Srgrimes		case KTR_PSIG:
387219138Sdchagin			ktrpsig((struct ktr_psig *)m);
3881590Srgrimes			break;
3891590Srgrimes		case KTR_CSW:
390234494Sjhb			if (ktrlen == sizeof(struct ktr_csw_old))
391234494Sjhb				ktrcsw_old((struct ktr_csw_old *)m);
392234494Sjhb			else
393234494Sjhb				ktrcsw((struct ktr_csw *)m);
3941590Srgrimes			break;
39518400Sphk		case KTR_USER:
39618470Sphk			ktruser(ktrlen, m);
39718400Sphk			break;
398176471Sdes		case KTR_STRUCT:
399176471Sdes			ktrstruct(m, ktrlen);
400176471Sdes			break;
401226269Sdes		case KTR_CAPFAIL:
402226269Sdes			ktrcapfail((struct ktr_cap_fail *)m);
403233925Sjhb			break;
404233925Sjhb		case KTR_FAULT:
405233925Sjhb			ktrfault((struct ktr_fault *)m);
406233925Sjhb			break;
407233925Sjhb		case KTR_FAULTEND:
408233925Sjhb			ktrfaultend((struct ktr_faultend *)m);
409233925Sjhb			break;
410112203Sjhb		default:
411112203Sjhb			printf("\n");
412112203Sjhb			break;
4131590Srgrimes		}
4141590Srgrimes		if (tail)
415226153Sdes			fflush(stdout);
4161590Srgrimes	}
417100824Sdwmalone	return 0;
4181590Srgrimes}
4191590Srgrimes
420251073Spjdvoid
421251073Spjdlimitfd(int fd)
422251073Spjd{
423251073Spjd	cap_rights_t rights;
424251073Spjd	unsigned long cmd;
425251073Spjd
426255219Spjd	cap_rights_init(&rights, CAP_FSTAT);
427273048Sjhb	cmd = 0;
428251073Spjd
429251073Spjd	switch (fd) {
430251073Spjd	case STDIN_FILENO:
431255219Spjd		cap_rights_set(&rights, CAP_READ);
432251073Spjd		break;
433251073Spjd	case STDOUT_FILENO:
434255219Spjd		cap_rights_set(&rights, CAP_IOCTL, CAP_WRITE);
435251073Spjd		cmd = TIOCGETA;	/* required by isatty(3) in printf(3) */
436251073Spjd		break;
437251073Spjd	case STDERR_FILENO:
438255219Spjd		cap_rights_set(&rights, CAP_WRITE);
439251073Spjd		if (!suppressdata) {
440255219Spjd			cap_rights_set(&rights, CAP_IOCTL);
441251073Spjd			cmd = TIOCGWINSZ;
442251073Spjd		}
443251073Spjd		break;
444251073Spjd	default:
445251073Spjd		abort();
446251073Spjd	}
447251073Spjd
448255219Spjd	if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS)
449251073Spjd		err(1, "unable to limit rights for descriptor %d", fd);
450273048Sjhb	if (cmd != 0 && cap_ioctls_limit(fd, &cmd, 1) < 0 && errno != ENOSYS)
451251073Spjd		err(1, "unable to limit ioctls for descriptor %d", fd);
452251073Spjd}
453251073Spjd
454100824Sdwmaloneint
455100824Sdwmalonefread_tail(void *buf, int size, int num)
4561590Srgrimes{
4571590Srgrimes	int i;
4581590Srgrimes
4591590Srgrimes	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
460226153Sdes		sleep(1);
4611590Srgrimes		clearerr(stdin);
4621590Srgrimes	}
4631590Srgrimes	return (i);
4641590Srgrimes}
4651590Srgrimes
466219043Sdchaginint
467219043Sdchaginfetchprocinfo(struct ktr_header *kth, u_int *flags)
468219043Sdchagin{
469219043Sdchagin	struct proc_info *pi;
470219043Sdchagin
471219043Sdchagin	switch (kth->ktr_type) {
472219043Sdchagin	case KTR_PROCCTOR:
473219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
474219043Sdchagin			if (pi->pid == kth->ktr_pid) {
475219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
476219043Sdchagin				break;
477219043Sdchagin			}
478219043Sdchagin		}
479219043Sdchagin		pi = malloc(sizeof(struct proc_info));
480219043Sdchagin		if (pi == NULL)
481219043Sdchagin			errx(1, "%s", strerror(ENOMEM));
482219043Sdchagin		pi->sv_flags = *flags;
483219043Sdchagin		pi->pid = kth->ktr_pid;
484219043Sdchagin		TAILQ_INSERT_TAIL(&trace_procs, pi, info);
485219043Sdchagin		return (1);
486219043Sdchagin
487219043Sdchagin	case KTR_PROCDTOR:
488219043Sdchagin		TAILQ_FOREACH(pi, &trace_procs, info) {
489219043Sdchagin			if (pi->pid == kth->ktr_pid) {
490219043Sdchagin				TAILQ_REMOVE(&trace_procs, pi, info);
491219043Sdchagin				free(pi);
492219043Sdchagin				break;
493219043Sdchagin			}
494219043Sdchagin		}
495219043Sdchagin		return (1);
496219043Sdchagin	}
497219043Sdchagin
498219043Sdchagin	return (0);
499219043Sdchagin}
500219043Sdchagin
501219043Sdchaginu_int
502219043Sdchaginabidump(struct ktr_header *kth)
503219043Sdchagin{
504219043Sdchagin	struct proc_info *pi;
505219043Sdchagin	const char *abi;
506219043Sdchagin	const char *arch;
507219043Sdchagin	u_int flags = 0;
508219043Sdchagin
509219043Sdchagin	TAILQ_FOREACH(pi, &trace_procs, info) {
510219043Sdchagin		if (pi->pid == kth->ktr_pid) {
511219043Sdchagin			flags = pi->sv_flags;
512219043Sdchagin			break;
513219043Sdchagin		}
514219043Sdchagin	}
515219043Sdchagin
516219043Sdchagin	if (abiflag == 0)
517219043Sdchagin		return (flags);
518219043Sdchagin
519219043Sdchagin	switch (flags & SV_ABI_MASK) {
520219043Sdchagin	case SV_ABI_LINUX:
521219043Sdchagin		abi = "L";
522219043Sdchagin		break;
523219043Sdchagin	case SV_ABI_FREEBSD:
524219043Sdchagin		abi = "F";
525219043Sdchagin		break;
526296042Sjhb	case SV_ABI_CLOUDABI:
527296042Sjhb		abi = "C";
528296042Sjhb		break;
529219043Sdchagin	default:
530219043Sdchagin		abi = "U";
531219043Sdchagin		break;
532219043Sdchagin	}
533219043Sdchagin
534296570Sjhb	if (flags & SV_LP64)
535296570Sjhb		arch = "64";
536296570Sjhb	else if (flags & SV_ILP32)
537296570Sjhb		arch = "32";
538296570Sjhb	else
539219043Sdchagin		arch = "00";
540219043Sdchagin
541219043Sdchagin	printf("%s%s  ", abi, arch);
542219043Sdchagin
543219043Sdchagin	return (flags);
544219043Sdchagin}
545219043Sdchagin
546100824Sdwmalonevoid
547100824Sdwmalonedumpheader(struct ktr_header *kth)
5481590Srgrimes{
5491590Srgrimes	static char unknown[64];
550263756Ssobomax	static struct timeval prevtime, prevtime_e, temp;
551100824Sdwmalone	const char *type;
552281970Ssobomax	const char *sign;
5531590Srgrimes
5541590Srgrimes	switch (kth->ktr_type) {
5551590Srgrimes	case KTR_SYSCALL:
5561590Srgrimes		type = "CALL";
5571590Srgrimes		break;
5581590Srgrimes	case KTR_SYSRET:
5591590Srgrimes		type = "RET ";
5601590Srgrimes		break;
5611590Srgrimes	case KTR_NAMEI:
5621590Srgrimes		type = "NAMI";
5631590Srgrimes		break;
5641590Srgrimes	case KTR_GENIO:
5651590Srgrimes		type = "GIO ";
5661590Srgrimes		break;
5671590Srgrimes	case KTR_PSIG:
5681590Srgrimes		type = "PSIG";
5691590Srgrimes		break;
5701590Srgrimes	case KTR_CSW:
571171333Sjhb		type = "CSW ";
5721590Srgrimes		break;
57318400Sphk	case KTR_USER:
57418400Sphk		type = "USER";
57518400Sphk		break;
576176471Sdes	case KTR_STRUCT:
577176471Sdes		type = "STRU";
578176471Sdes		break;
579189707Sjhb	case KTR_SYSCTL:
580189707Sjhb		type = "SCTL";
581189707Sjhb		break;
582219043Sdchagin	case KTR_PROCCTOR:
583219043Sdchagin		/* FALLTHROUGH */
584219043Sdchagin	case KTR_PROCDTOR:
585219043Sdchagin		return;
586226269Sdes	case KTR_CAPFAIL:
587226269Sdes		type = "CAP ";
588226269Sdes		break;
589233925Sjhb	case KTR_FAULT:
590233925Sjhb		type = "PFLT";
591233925Sjhb		break;
592233925Sjhb	case KTR_FAULTEND:
593233925Sjhb		type = "PRET";
594233925Sjhb		break;
5951590Srgrimes	default:
596226153Sdes		sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
5971590Srgrimes		type = unknown;
5981590Srgrimes	}
5991590Srgrimes
600151930Srwatson	/*
601151930Srwatson	 * The ktr_tid field was previously the ktr_buffer field, which held
602151930Srwatson	 * the kernel pointer value for the buffer associated with data
603151930Srwatson	 * following the record header.  It now holds a threadid, but only
604151930Srwatson	 * for trace files after the change.  Older trace files still contain
605151930Srwatson	 * kernel pointers.  Detect this and suppress the results by printing
606151930Srwatson	 * negative tid's as 0.
607151930Srwatson	 */
608151930Srwatson	if (threads)
609226153Sdes		printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid,
610203551Sjh		    kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0,
611203551Sjh		    MAXCOMLEN, kth->ktr_comm);
612151930Srwatson	else
613226153Sdes		printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN,
614151930Srwatson		    kth->ktr_comm);
615263756Ssobomax        if (timestamp) {
616263756Ssobomax		if (timestamp & TIMESTAMP_ABSOLUTE) {
617263756Ssobomax			printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
618263756Ssobomax			    kth->ktr_time.tv_usec);
619123187Speter		}
620263756Ssobomax		if (timestamp & TIMESTAMP_ELAPSED) {
621263756Ssobomax			if (prevtime_e.tv_sec == 0)
622263756Ssobomax				prevtime_e = kth->ktr_time;
623263756Ssobomax			timevalsub(&kth->ktr_time, &prevtime_e);
624263756Ssobomax			printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
625263756Ssobomax			    kth->ktr_time.tv_usec);
626263756Ssobomax			timevaladd(&kth->ktr_time, &prevtime_e);
627263756Ssobomax		}
628263756Ssobomax		if (timestamp & TIMESTAMP_RELATIVE) {
629281970Ssobomax			if (prevtime.tv_sec == 0)
630281970Ssobomax				prevtime = kth->ktr_time;
6311590Srgrimes			temp = kth->ktr_time;
6321590Srgrimes			timevalsub(&kth->ktr_time, &prevtime);
633281970Ssobomax			if ((intmax_t)kth->ktr_time.tv_sec < 0) {
634281970Ssobomax                        	kth->ktr_time = prevtime;
635281970Ssobomax				prevtime = temp;
636281970Ssobomax				timevalsub(&kth->ktr_time, &prevtime);
637281970Ssobomax				sign = "-";
638281970Ssobomax			} else {
639281970Ssobomax				prevtime = temp;
640281970Ssobomax				sign = "";
641281970Ssobomax			}
642281970Ssobomax			printf("%s%jd.%06ld ", sign, (intmax_t)kth->ktr_time.tv_sec,
643263756Ssobomax			    kth->ktr_time.tv_usec);
6441590Srgrimes		}
6451590Srgrimes	}
646226153Sdes	printf("%s  ", type);
6471590Srgrimes}
6481590Srgrimes
6491590Srgrimes#include <sys/syscall.h>
6501590Srgrimes
651292622Sjhbstatic void
652292622Sjhbioctlname(unsigned long val)
653292622Sjhb{
654292622Sjhb	const char *str;
655292622Sjhb
656292622Sjhb	str = sysdecode_ioctlname(val);
657292622Sjhb	if (str != NULL)
658292622Sjhb		printf("%s", str);
659292622Sjhb	else if (decimal)
660292622Sjhb		printf("%lu", val);
661292622Sjhb	else
662292622Sjhb		printf("%#lx", val);
663292622Sjhb}
664292622Sjhb
665294849Sjhbstatic enum sysdecode_abi
666294849Sjhbsyscallabi(u_int sv_flags)
667294849Sjhb{
668294849Sjhb
669294849Sjhb	if (sv_flags == 0)
670295056Sjhb		return (SYSDECODE_ABI_FREEBSD);
671294849Sjhb	switch (sv_flags & SV_ABI_MASK) {
672294849Sjhb	case SV_ABI_FREEBSD:
673295056Sjhb		return (SYSDECODE_ABI_FREEBSD);
674294849Sjhb#if defined(__amd64__) || defined(__i386__)
675294849Sjhb	case SV_ABI_LINUX:
676294849Sjhb#ifdef __amd64__
677294849Sjhb		if (sv_flags & SV_ILP32)
678295056Sjhb			return (SYSDECODE_ABI_LINUX32);
679294849Sjhb#endif
680295056Sjhb		return (SYSDECODE_ABI_LINUX);
681294849Sjhb#endif
682296042Sjhb#if defined(__aarch64__) || defined(__amd64__)
683296042Sjhb	case SV_ABI_CLOUDABI:
684296042Sjhb		return (SYSDECODE_ABI_CLOUDABI64);
685296042Sjhb#endif
686294849Sjhb	default:
687295056Sjhb		return (SYSDECODE_ABI_UNKNOWN);
688294849Sjhb	}
689294849Sjhb}
690294849Sjhb
691294849Sjhbstatic void
692294849Sjhbsyscallname(u_int code, u_int sv_flags)
693294849Sjhb{
694294849Sjhb	const char *name;
695294849Sjhb
696294849Sjhb	name = sysdecode_syscallname(syscallabi(sv_flags), code);
697294849Sjhb	if (name == NULL)
698294849Sjhb		printf("[%d]", code);
699294849Sjhb	else {
700294849Sjhb		printf("%s", name);
701294849Sjhb		if (syscallno)
702294849Sjhb			printf("[%d]", code);
703294849Sjhb	}
704294849Sjhb}
705294849Sjhb
706100824Sdwmalonevoid
707294849Sjhbktrsyscall(struct ktr_syscall *ktr, u_int sv_flags)
7081590Srgrimes{
709100824Sdwmalone	int narg = ktr->ktr_narg;
710100824Sdwmalone	register_t *ip;
711226269Sdes	intmax_t arg;
7121590Srgrimes
713294849Sjhb	syscallname(ktr->ktr_code, sv_flags);
71447957Sdt	ip = &ktr->ktr_args[0];
7151590Srgrimes	if (narg) {
7161590Srgrimes		char c = '(';
717219043Sdchagin		if (fancy &&
718294849Sjhb		    (sv_flags == 0 ||
719294849Sjhb		    (sv_flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
720226148Sdes			switch (ktr->ktr_code) {
721254296Sjilles			case SYS_bindat:
722254296Sjilles			case SYS_connectat:
723254291Sjilles			case SYS_faccessat:
724254291Sjilles			case SYS_fchmodat:
725254291Sjilles			case SYS_fchownat:
726254291Sjilles			case SYS_fstatat:
727254291Sjilles			case SYS_futimesat:
728254291Sjilles			case SYS_linkat:
729254291Sjilles			case SYS_mkdirat:
730254291Sjilles			case SYS_mkfifoat:
731254291Sjilles			case SYS_mknodat:
732254291Sjilles			case SYS_openat:
733254291Sjilles			case SYS_readlinkat:
734254291Sjilles			case SYS_renameat:
735254291Sjilles			case SYS_unlinkat:
736277610Sjilles			case SYS_utimensat:
737254291Sjilles				putchar('(');
738254291Sjilles				atfdname(*ip, decimal);
739254291Sjilles				c = ',';
740254291Sjilles				ip++;
741254291Sjilles				narg--;
742254291Sjilles				break;
743254291Sjilles			}
744254291Sjilles			switch (ktr->ktr_code) {
745226148Sdes			case SYS_ioctl: {
746226150Sdes				print_number(ip, narg, c);
747226157Sdes				putchar(c);
748292622Sjhb				ioctlname(*ip);
7491590Srgrimes				c = ',';
7501590Srgrimes				ip++;
7511590Srgrimes				narg--;
752226148Sdes				break;
753226148Sdes			}
754226148Sdes			case SYS_ptrace:
755226153Sdes				putchar('(');
756226164Sdes				ptraceopname(*ip);
7571590Srgrimes				c = ',';
7581590Srgrimes				ip++;
7591590Srgrimes				narg--;
760226148Sdes				break;
761226148Sdes			case SYS_access:
762226148Sdes			case SYS_eaccess:
763254291Sjilles			case SYS_faccessat:
764226150Sdes				print_number(ip, narg, c);
765226153Sdes				putchar(',');
766226164Sdes				accessmodename(*ip);
767158766Snetchild				ip++;
768158766Snetchild				narg--;
769226148Sdes				break;
770226148Sdes			case SYS_open:
771254291Sjilles			case SYS_openat:
772226150Sdes				print_number(ip, narg, c);
773226153Sdes				putchar(',');
774226164Sdes				flagsandmodename(ip[0], ip[1], decimal);
775226148Sdes				ip += 2;
776226148Sdes				narg -= 2;
777226148Sdes				break;
778226148Sdes			case SYS_wait4:
779226150Sdes				print_number(ip, narg, c);
780226150Sdes				print_number(ip, narg, c);
781255493Sjhb				/*
782255493Sjhb				 * A flags value of zero is valid for
783255493Sjhb				 * wait4() but not for wait6(), so
784255493Sjhb				 * handle zero special here.
785255493Sjhb				 */
786255493Sjhb				if (*ip == 0) {
787255493Sjhb					print_number(ip, narg, c);
788255493Sjhb				} else {
789255493Sjhb					putchar(',');
790255493Sjhb					wait6optname(*ip);
791255493Sjhb					ip++;
792255493Sjhb					narg--;
793255493Sjhb				}
794255493Sjhb				break;
795255493Sjhb			case SYS_wait6:
796255493Sjhb				putchar('(');
797255493Sjhb				idtypename(*ip, decimal);
798255493Sjhb				c = ',';
799255493Sjhb				ip++;
800255493Sjhb				narg--;
801255493Sjhb				print_number(ip, narg, c);
802255493Sjhb				print_number(ip, narg, c);
803226153Sdes				putchar(',');
804255493Sjhb				wait6optname(*ip);
805158766Snetchild				ip++;
806158766Snetchild				narg--;
807226148Sdes				break;
808226148Sdes			case SYS_chmod:
809226148Sdes			case SYS_fchmod:
810226148Sdes			case SYS_lchmod:
811299005Sbapt			case SYS_fchmodat:
812226150Sdes				print_number(ip, narg, c);
813226153Sdes				putchar(',');
814226164Sdes				modename(*ip);
815158766Snetchild				ip++;
816158766Snetchild				narg--;
817226148Sdes				break;
818226148Sdes			case SYS_mknod:
819254291Sjilles			case SYS_mknodat:
820226150Sdes				print_number(ip, narg, c);
821226153Sdes				putchar(',');
822226164Sdes				modename(*ip);
823158766Snetchild				ip++;
824158766Snetchild				narg--;
825226148Sdes				break;
826226148Sdes			case SYS_getfsstat:
827226150Sdes				print_number(ip, narg, c);
828226150Sdes				print_number(ip, narg, c);
829226153Sdes				putchar(',');
830226164Sdes				getfsstatflagsname(*ip);
831158766Snetchild				ip++;
832158766Snetchild				narg--;
833226148Sdes				break;
834226148Sdes			case SYS_mount:
835226150Sdes				print_number(ip, narg, c);
836226150Sdes				print_number(ip, narg, c);
837226153Sdes				putchar(',');
838226164Sdes				mountflagsname(*ip);
839158766Snetchild				ip++;
840158766Snetchild				narg--;
841226148Sdes				break;
842226148Sdes			case SYS_unmount:
843226150Sdes				print_number(ip, narg, c);
844226153Sdes				putchar(',');
845226164Sdes				mountflagsname(*ip);
846158766Snetchild				ip++;
847158766Snetchild				narg--;
848226148Sdes				break;
849226148Sdes			case SYS_recvmsg:
850226148Sdes			case SYS_sendmsg:
851226150Sdes				print_number(ip, narg, c);
852226150Sdes				print_number(ip, narg, c);
853226153Sdes				putchar(',');
854226164Sdes				sendrecvflagsname(*ip);
855158766Snetchild				ip++;
856158766Snetchild				narg--;
857226148Sdes				break;
858226148Sdes			case SYS_recvfrom:
859226148Sdes			case SYS_sendto:
860226150Sdes				print_number(ip, narg, c);
861226150Sdes				print_number(ip, narg, c);
862226150Sdes				print_number(ip, narg, c);
863226153Sdes				putchar(',');
864226164Sdes				sendrecvflagsname(*ip);
865158766Snetchild				ip++;
866158766Snetchild				narg--;
867226148Sdes				break;
868226148Sdes			case SYS_chflags:
869226148Sdes			case SYS_fchflags:
870226148Sdes			case SYS_lchflags:
871226150Sdes				print_number(ip, narg, c);
872226153Sdes				putchar(',');
873226164Sdes				modename(*ip);
874158766Snetchild				ip++;
875158766Snetchild				narg--;
876226148Sdes				break;
877226148Sdes			case SYS_kill:
878226150Sdes				print_number(ip, narg, c);
879226153Sdes				putchar(',');
880226164Sdes				signame(*ip);
881158766Snetchild				ip++;
882158766Snetchild				narg--;
883226148Sdes				break;
884226148Sdes			case SYS_reboot:
885226153Sdes				putchar('(');
886226164Sdes				rebootoptname(*ip);
887158766Snetchild				ip++;
888158766Snetchild				narg--;
889226148Sdes				break;
890226148Sdes			case SYS_umask:
891226153Sdes				putchar('(');
892226164Sdes				modename(*ip);
893158766Snetchild				ip++;
894158766Snetchild				narg--;
895226148Sdes				break;
896226148Sdes			case SYS_msync:
897226150Sdes				print_number(ip, narg, c);
898226150Sdes				print_number(ip, narg, c);
899226153Sdes				putchar(',');
900226164Sdes				msyncflagsname(*ip);
901158766Snetchild				ip++;
902158766Snetchild				narg--;
903226148Sdes				break;
904171221Speter#ifdef SYS_freebsd6_mmap
905226148Sdes			case SYS_freebsd6_mmap:
906226150Sdes				print_number(ip, narg, c);
907226150Sdes				print_number(ip, narg, c);
908226153Sdes				putchar(',');
909226164Sdes				mmapprotname(*ip);
910226153Sdes				putchar(',');
911171221Speter				ip++;
912171221Speter				narg--;
913226164Sdes				mmapflagsname(*ip);
914171221Speter				ip++;
915171221Speter				narg--;
916226148Sdes				break;
917171221Speter#endif
918226148Sdes			case SYS_mmap:
919226150Sdes				print_number(ip, narg, c);
920226150Sdes				print_number(ip, narg, c);
921226153Sdes				putchar(',');
922226164Sdes				mmapprotname(*ip);
923226153Sdes				putchar(',');
924158766Snetchild				ip++;
925158766Snetchild				narg--;
926226164Sdes				mmapflagsname(*ip);
927158766Snetchild				ip++;
928158766Snetchild				narg--;
929226148Sdes				break;
930226148Sdes			case SYS_mprotect:
931226150Sdes				print_number(ip, narg, c);
932226150Sdes				print_number(ip, narg, c);
933226153Sdes				putchar(',');
934226164Sdes				mmapprotname(*ip);
935158766Snetchild				ip++;
936158766Snetchild				narg--;
937226148Sdes				break;
938226148Sdes			case SYS_madvise:
939226150Sdes				print_number(ip, narg, c);
940226150Sdes				print_number(ip, narg, c);
941226153Sdes				putchar(',');
942226164Sdes				madvisebehavname(*ip);
943158766Snetchild				ip++;
944158766Snetchild				narg--;
945226148Sdes				break;
946226148Sdes			case SYS_setpriority:
947226150Sdes				print_number(ip, narg, c);
948226150Sdes				print_number(ip, narg, c);
949226153Sdes				putchar(',');
950226164Sdes				prioname(*ip);
951158766Snetchild				ip++;
952158766Snetchild				narg--;
953226148Sdes				break;
954226148Sdes			case SYS_fcntl:
955226150Sdes				print_number(ip, narg, c);
956226153Sdes				putchar(',');
957226164Sdes				fcntlcmdname(ip[0], ip[1], decimal);
958226148Sdes				ip += 2;
959226148Sdes				narg -= 2;
960226148Sdes				break;
961226148Sdes			case SYS_socket: {
962165758Srodrigc				int sockdomain;
963226153Sdes				putchar('(');
964226164Sdes				sockdomain = *ip;
965165758Srodrigc				sockdomainname(sockdomain);
966158766Snetchild				ip++;
967158766Snetchild				narg--;
968226153Sdes				putchar(',');
969254922Sjilles				socktypenamewithflags(*ip);
970158766Snetchild				ip++;
971158766Snetchild				narg--;
972165758Srodrigc				if (sockdomain == PF_INET ||
973165758Srodrigc				    sockdomain == PF_INET6) {
974226153Sdes					putchar(',');
975226164Sdes					sockipprotoname(*ip);
976165758Srodrigc					ip++;
977165758Srodrigc					narg--;
978165758Srodrigc				}
979158766Snetchild				c = ',';
980226148Sdes				break;
981226148Sdes			}
982226148Sdes			case SYS_setsockopt:
983226148Sdes			case SYS_getsockopt:
984226150Sdes				print_number(ip, narg, c);
985226153Sdes				putchar(',');
986226164Sdes				sockoptlevelname(*ip, decimal);
987226151Sdes				if (*ip == SOL_SOCKET) {
988175138Sjhb					ip++;
989175138Sjhb					narg--;
990226153Sdes					putchar(',');
991226164Sdes					sockoptname(*ip);
992175138Sjhb				}
993158766Snetchild				ip++;
994158766Snetchild				narg--;
995226148Sdes				break;
996171221Speter#ifdef SYS_freebsd6_lseek
997226148Sdes			case SYS_freebsd6_lseek:
998226150Sdes				print_number(ip, narg, c);
999158766Snetchild				/* Hidden 'pad' argument, not in lseek(2) */
1000226150Sdes				print_number(ip, narg, c);
1001226150Sdes				print_number(ip, narg, c);
1002226153Sdes				putchar(',');
1003226164Sdes				whencename(*ip);
1004158766Snetchild				ip++;
1005158766Snetchild				narg--;
1006226148Sdes				break;
1007171221Speter#endif
1008226148Sdes			case SYS_lseek:
1009226150Sdes				print_number(ip, narg, c);
1010171221Speter				/* Hidden 'pad' argument, not in lseek(2) */
1011226150Sdes				print_number(ip, narg, c);
1012226153Sdes				putchar(',');
1013226164Sdes				whencename(*ip);
1014171221Speter				ip++;
1015171221Speter				narg--;
1016226148Sdes				break;
1017226148Sdes			case SYS_flock:
1018226150Sdes				print_number(ip, narg, c);
1019226153Sdes				putchar(',');
1020226164Sdes				flockname(*ip);
1021158766Snetchild				ip++;
1022158766Snetchild				narg--;
1023226148Sdes				break;
1024226148Sdes			case SYS_mkfifo:
1025254291Sjilles			case SYS_mkfifoat:
1026226148Sdes			case SYS_mkdir:
1027254291Sjilles			case SYS_mkdirat:
1028226150Sdes				print_number(ip, narg, c);
1029226153Sdes				putchar(',');
1030226164Sdes				modename(*ip);
1031158766Snetchild				ip++;
1032158766Snetchild				narg--;
1033226148Sdes				break;
1034226148Sdes			case SYS_shutdown:
1035226150Sdes				print_number(ip, narg, c);
1036226153Sdes				putchar(',');
1037226164Sdes				shutdownhowname(*ip);
1038158766Snetchild				ip++;
1039158766Snetchild				narg--;
1040226148Sdes				break;
1041226148Sdes			case SYS_socketpair:
1042226153Sdes				putchar('(');
1043226164Sdes				sockdomainname(*ip);
1044158766Snetchild				ip++;
1045158766Snetchild				narg--;
1046226153Sdes				putchar(',');
1047254922Sjilles				socktypenamewithflags(*ip);
1048158766Snetchild				ip++;
1049158766Snetchild				narg--;
1050158766Snetchild				c = ',';
1051226148Sdes				break;
1052226148Sdes			case SYS_getrlimit:
1053226148Sdes			case SYS_setrlimit:
1054226153Sdes				putchar('(');
1055226164Sdes				rlimitname(*ip);
1056158766Snetchild				ip++;
1057158766Snetchild				narg--;
1058158766Snetchild				c = ',';
1059226148Sdes				break;
1060226148Sdes			case SYS_quotactl:
1061226150Sdes				print_number(ip, narg, c);
1062226153Sdes				putchar(',');
1063226164Sdes				quotactlname(*ip);
1064158766Snetchild				ip++;
1065158766Snetchild				narg--;
1066158766Snetchild				c = ',';
1067226148Sdes				break;
1068226148Sdes			case SYS_nfssvc:
1069226153Sdes				putchar('(');
1070226164Sdes				nfssvcname(*ip);
1071158766Snetchild				ip++;
1072158766Snetchild				narg--;
1073158766Snetchild				c = ',';
1074226148Sdes				break;
1075226148Sdes			case SYS_rtprio:
1076226153Sdes				putchar('(');
1077226164Sdes				rtprioname(*ip);
1078158766Snetchild				ip++;
1079158766Snetchild				narg--;
1080158766Snetchild				c = ',';
1081226148Sdes				break;
1082226148Sdes			case SYS___semctl:
1083226150Sdes				print_number(ip, narg, c);
1084226150Sdes				print_number(ip, narg, c);
1085226153Sdes				putchar(',');
1086226164Sdes				semctlname(*ip);
1087158766Snetchild				ip++;
1088158766Snetchild				narg--;
1089226148Sdes				break;
1090226148Sdes			case SYS_semget:
1091226150Sdes				print_number(ip, narg, c);
1092226150Sdes				print_number(ip, narg, c);
1093226153Sdes				putchar(',');
1094226164Sdes				semgetname(*ip);
1095158766Snetchild				ip++;
1096158766Snetchild				narg--;
1097226148Sdes				break;
1098226148Sdes			case SYS_msgctl:
1099226150Sdes				print_number(ip, narg, c);
1100226153Sdes				putchar(',');
1101226164Sdes				shmctlname(*ip);
1102158766Snetchild				ip++;
1103158766Snetchild				narg--;
1104226148Sdes				break;
1105226148Sdes			case SYS_shmat:
1106226150Sdes				print_number(ip, narg, c);
1107226150Sdes				print_number(ip, narg, c);
1108226153Sdes				putchar(',');
1109226164Sdes				shmatname(*ip);
1110158766Snetchild				ip++;
1111158766Snetchild				narg--;
1112226148Sdes				break;
1113226148Sdes			case SYS_shmctl:
1114226150Sdes				print_number(ip, narg, c);
1115226153Sdes				putchar(',');
1116226164Sdes				shmctlname(*ip);
1117158766Snetchild				ip++;
1118158766Snetchild				narg--;
1119226148Sdes				break;
1120269408Srpaulo			case SYS_shm_open:
1121269408Srpaulo				print_number(ip, narg, c);
1122269408Srpaulo				putchar(',');
1123269408Srpaulo				flagsname(ip[0]);
1124273048Sjhb				printf(",0%o", (unsigned int)ip[1]);
1125269408Srpaulo				ip += 3;
1126269408Srpaulo				narg -= 3;
1127269408Srpaulo				break;
1128226148Sdes			case SYS_minherit:
1129226150Sdes				print_number(ip, narg, c);
1130226150Sdes				print_number(ip, narg, c);
1131226153Sdes				putchar(',');
1132226164Sdes				minheritname(*ip);
1133158766Snetchild				ip++;
1134158766Snetchild				narg--;
1135226148Sdes				break;
1136226148Sdes			case SYS_rfork:
1137226153Sdes				putchar('(');
1138226164Sdes				rforkname(*ip);
1139158766Snetchild				ip++;
1140158766Snetchild				narg--;
1141158766Snetchild				c = ',';
1142226148Sdes				break;
1143226148Sdes			case SYS_lio_listio:
1144226153Sdes				putchar('(');
1145226164Sdes				lio_listioname(*ip);
1146158766Snetchild				ip++;
1147158766Snetchild				narg--;
1148158766Snetchild				c = ',';
1149226148Sdes				break;
1150226148Sdes			case SYS_mlockall:
1151226153Sdes				putchar('(');
1152226164Sdes				mlockallname(*ip);
1153158766Snetchild				ip++;
1154158766Snetchild				narg--;
1155226148Sdes				break;
1156226148Sdes			case SYS_sched_setscheduler:
1157226150Sdes				print_number(ip, narg, c);
1158226153Sdes				putchar(',');
1159226164Sdes				schedpolicyname(*ip);
1160158766Snetchild				ip++;
1161158766Snetchild				narg--;
1162226148Sdes				break;
1163226148Sdes			case SYS_sched_get_priority_max:
1164226148Sdes			case SYS_sched_get_priority_min:
1165226153Sdes				putchar('(');
1166226164Sdes				schedpolicyname(*ip);
1167158766Snetchild				ip++;
1168158766Snetchild				narg--;
1169226148Sdes				break;
1170226148Sdes			case SYS_sendfile:
1171226150Sdes				print_number(ip, narg, c);
1172226150Sdes				print_number(ip, narg, c);
1173226150Sdes				print_number(ip, narg, c);
1174226150Sdes				print_number(ip, narg, c);
1175226150Sdes				print_number(ip, narg, c);
1176226150Sdes				print_number(ip, narg, c);
1177226153Sdes				putchar(',');
1178278857Spluknet				sendfileflagsname(*(int *)ip);
1179158766Snetchild				ip++;
1180158766Snetchild				narg--;
1181226148Sdes				break;
1182226148Sdes			case SYS_kldsym:
1183226150Sdes				print_number(ip, narg, c);
1184226153Sdes				putchar(',');
1185226164Sdes				kldsymcmdname(*ip);
1186158766Snetchild				ip++;
1187158766Snetchild				narg--;
1188226148Sdes				break;
1189226148Sdes			case SYS_sigprocmask:
1190226153Sdes				putchar('(');
1191226164Sdes				sigprocmaskhowname(*ip);
1192158766Snetchild				ip++;
1193158766Snetchild				narg--;
1194158766Snetchild				c = ',';
1195226148Sdes				break;
1196226148Sdes			case SYS___acl_get_file:
1197226148Sdes			case SYS___acl_set_file:
1198226148Sdes			case SYS___acl_get_fd:
1199226148Sdes			case SYS___acl_set_fd:
1200226148Sdes			case SYS___acl_delete_file:
1201226148Sdes			case SYS___acl_delete_fd:
1202226148Sdes			case SYS___acl_aclcheck_file:
1203226148Sdes			case SYS___acl_aclcheck_fd:
1204226148Sdes			case SYS___acl_get_link:
1205226148Sdes			case SYS___acl_set_link:
1206226148Sdes			case SYS___acl_delete_link:
1207226148Sdes			case SYS___acl_aclcheck_link:
1208226150Sdes				print_number(ip, narg, c);
1209226153Sdes				putchar(',');
1210226164Sdes				acltypename(*ip);
1211158766Snetchild				ip++;
1212158766Snetchild				narg--;
1213226148Sdes				break;
1214226148Sdes			case SYS_sigaction:
1215226153Sdes				putchar('(');
1216226164Sdes				signame(*ip);
1217158766Snetchild				ip++;
1218158766Snetchild				narg--;
1219158766Snetchild				c = ',';
1220226148Sdes				break;
1221226148Sdes			case SYS_extattrctl:
1222226150Sdes				print_number(ip, narg, c);
1223226153Sdes				putchar(',');
1224226164Sdes				extattrctlname(*ip);
1225158766Snetchild				ip++;
1226158766Snetchild				narg--;
1227226148Sdes				break;
1228226148Sdes			case SYS_nmount:
1229226150Sdes				print_number(ip, narg, c);
1230226150Sdes				print_number(ip, narg, c);
1231226153Sdes				putchar(',');
1232226164Sdes				mountflagsname(*ip);
1233158766Snetchild				ip++;
1234158766Snetchild				narg--;
1235226148Sdes				break;
1236226148Sdes			case SYS_thr_create:
1237226150Sdes				print_number(ip, narg, c);
1238226150Sdes				print_number(ip, narg, c);
1239226153Sdes				putchar(',');
1240226164Sdes				thrcreateflagsname(*ip);
1241158766Snetchild				ip++;
1242158766Snetchild				narg--;
1243226148Sdes				break;
1244226148Sdes			case SYS_thr_kill:
1245226150Sdes				print_number(ip, narg, c);
1246226153Sdes				putchar(',');
1247226164Sdes				signame(*ip);
1248158766Snetchild				ip++;
1249158766Snetchild				narg--;
1250226148Sdes				break;
1251226148Sdes			case SYS_kldunloadf:
1252226150Sdes				print_number(ip, narg, c);
1253226153Sdes				putchar(',');
1254226164Sdes				kldunloadfflagsname(*ip);
1255158766Snetchild				ip++;
1256158766Snetchild				narg--;
1257226148Sdes				break;
1258254291Sjilles			case SYS_linkat:
1259254291Sjilles			case SYS_renameat:
1260254291Sjilles			case SYS_symlinkat:
1261254291Sjilles				print_number(ip, narg, c);
1262254291Sjilles				putchar(',');
1263254291Sjilles				atfdname(*ip, decimal);
1264254291Sjilles				ip++;
1265254291Sjilles				narg--;
1266254291Sjilles				break;
1267247602Spjd			case SYS_cap_fcntls_limit:
1268247602Spjd				print_number(ip, narg, c);
1269247602Spjd				putchar(',');
1270247602Spjd				arg = *ip;
1271247602Spjd				ip++;
1272247602Spjd				narg--;
1273247602Spjd				capfcntlname(arg);
1274247602Spjd				break;
1275232072Sjhb			case SYS_posix_fadvise:
1276232128Sjhb				print_number(ip, narg, c);
1277232128Sjhb				print_number(ip, narg, c);
1278232128Sjhb				print_number(ip, narg, c);
1279232072Sjhb				(void)putchar(',');
1280232072Sjhb				fadvisebehavname((int)*ip);
1281232072Sjhb				ip++;
1282232072Sjhb				narg--;
1283232072Sjhb				break;
1284255708Sjhb			case SYS_procctl:
1285255708Sjhb				putchar('(');
1286255708Sjhb				idtypename(*ip, decimal);
1287255708Sjhb				c = ',';
1288255708Sjhb				ip++;
1289255708Sjhb				narg--;
1290255708Sjhb				print_number(ip, narg, c);
1291255708Sjhb				putchar(',');
1292255708Sjhb				procctlcmdname(*ip);
1293255708Sjhb				ip++;
1294255708Sjhb				narg--;
1295255708Sjhb				break;
1296273053Sjhb			case SYS__umtx_op:
1297273053Sjhb				print_number(ip, narg, c);
1298273053Sjhb				putchar(',');
1299273053Sjhb				umtxopname(*ip);
1300273053Sjhb				switch (*ip) {
1301273053Sjhb				case UMTX_OP_CV_WAIT:
1302273053Sjhb					ip++;
1303273053Sjhb					narg--;
1304273053Sjhb					putchar(',');
1305273053Sjhb					umtxcvwaitflags(*ip);
1306273053Sjhb					break;
1307273053Sjhb				case UMTX_OP_RW_RDLOCK:
1308273053Sjhb					ip++;
1309273053Sjhb					narg--;
1310273053Sjhb					putchar(',');
1311273053Sjhb					umtxrwlockflags(*ip);
1312273053Sjhb					break;
1313273053Sjhb				}
1314273053Sjhb				ip++;
1315273053Sjhb				narg--;
13161590Srgrimes			}
13171590Srgrimes		}
1318199024Sattilio		while (narg > 0) {
1319226150Sdes			print_number(ip, narg, c);
13201590Srgrimes		}
1321226153Sdes		putchar(')');
13221590Srgrimes	}
1323226153Sdes	putchar('\n');
13241590Srgrimes}
13251590Srgrimes
1326100824Sdwmalonevoid
1327294849Sjhbktrsysret(struct ktr_sysret *ktr, u_int sv_flags)
13281590Srgrimes{
1329100824Sdwmalone	register_t ret = ktr->ktr_retval;
1330100824Sdwmalone	int error = ktr->ktr_error;
13311590Srgrimes
1332294849Sjhb	syscallname(ktr->ktr_code, sv_flags);
1333294849Sjhb	printf(" ");
13341590Srgrimes
13351590Srgrimes	if (error == 0) {
13361590Srgrimes		if (fancy) {
1337226153Sdes			printf("%ld", (long)ret);
13381590Srgrimes			if (ret < 0 || ret > 9)
1339226153Sdes				printf("/%#lx", (unsigned long)ret);
13401590Srgrimes		} else {
13411590Srgrimes			if (decimal)
1342226153Sdes				printf("%ld", (long)ret);
13431590Srgrimes			else
1344226153Sdes				printf("%#lx", (unsigned long)ret);
13451590Srgrimes		}
13461590Srgrimes	} else if (error == ERESTART)
1347226153Sdes		printf("RESTART");
13481590Srgrimes	else if (error == EJUSTRETURN)
1349226153Sdes		printf("JUSTRETURN");
13501590Srgrimes	else {
1351295931Sjhb		printf("-1 errno %d", sysdecode_freebsd_to_abi_errno(
1352295931Sjhb		    syscallabi(sv_flags), error));
13531590Srgrimes		if (fancy)
1354226153Sdes			printf(" %s", strerror(ktr->ktr_error));
13551590Srgrimes	}
1356226153Sdes	putchar('\n');
13571590Srgrimes}
13581590Srgrimes
1359100824Sdwmalonevoid
1360100824Sdwmalonektrnamei(char *cp, int len)
13611590Srgrimes{
1362226153Sdes	printf("\"%.*s\"\n", len, cp);
13631590Srgrimes}
13641590Srgrimes
1365100824Sdwmalonevoid
1366115759Speterhexdump(char *p, int len, int screenwidth)
13671590Srgrimes{
1368115759Speter	int n, i;
1369115759Speter	int width;
1370115759Speter
1371115759Speter	width = 0;
1372115759Speter	do {
1373115759Speter		width += 2;
1374115759Speter		i = 13;			/* base offset */
1375115759Speter		i += (width / 2) + 1;	/* spaces every second byte */
1376115759Speter		i += (width * 2);	/* width of bytes */
1377115759Speter		i += 3;			/* "  |" */
1378115759Speter		i += width;		/* each byte */
1379115759Speter		i += 1;			/* "|" */
1380115759Speter	} while (i < screenwidth);
1381115759Speter	width -= 2;
1382115759Speter
1383115759Speter	for (n = 0; n < len; n += width) {
1384115759Speter		for (i = n; i < n + width; i++) {
1385115759Speter			if ((i % width) == 0) {	/* beginning of line */
1386115759Speter				printf("       0x%04x", i);
1387115759Speter			}
1388115759Speter			if ((i % 2) == 0) {
1389115759Speter				printf(" ");
1390115759Speter			}
1391115759Speter			if (i < len)
1392115759Speter				printf("%02x", p[i] & 0xff);
1393115759Speter			else
1394115759Speter				printf("  ");
1395115759Speter		}
1396115759Speter		printf("  |");
1397115759Speter		for (i = n; i < n + width; i++) {
1398115759Speter			if (i >= len)
1399115759Speter				break;
1400115759Speter			if (p[i] >= ' ' && p[i] <= '~')
1401115759Speter				printf("%c", p[i]);
1402115759Speter			else
1403115759Speter				printf(".");
1404115759Speter		}
1405115759Speter		printf("|\n");
1406115759Speter	}
1407115759Speter	if ((i % width) != 0)
1408115759Speter		printf("\n");
1409115759Speter}
1410115759Speter
1411115759Spetervoid
1412115759Spetervisdump(char *dp, int datalen, int screenwidth)
1413115759Speter{
1414115759Speter	int col = 0;
1415100824Sdwmalone	char *cp;
1416100824Sdwmalone	int width;
14171590Srgrimes	char visbuf[5];
14181590Srgrimes
1419226153Sdes	printf("       \"");
14201590Srgrimes	col = 8;
14211590Srgrimes	for (;datalen > 0; datalen--, dp++) {
1422226153Sdes		 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
14231590Srgrimes		cp = visbuf;
14241590Srgrimes		/*
14251590Srgrimes		 * Keep track of printables and
14261590Srgrimes		 * space chars (like fold(1)).
14271590Srgrimes		 */
14281590Srgrimes		if (col == 0) {
1429226153Sdes			putchar('\t');
14301590Srgrimes			col = 8;
14311590Srgrimes		}
14321590Srgrimes		switch(*cp) {
14331590Srgrimes		case '\n':
14341590Srgrimes			col = 0;
1435226153Sdes			putchar('\n');
14361590Srgrimes			continue;
14371590Srgrimes		case '\t':
14381590Srgrimes			width = 8 - (col&07);
14391590Srgrimes			break;
14401590Srgrimes		default:
14411590Srgrimes			width = strlen(cp);
14421590Srgrimes		}
14431590Srgrimes		if (col + width > (screenwidth-2)) {
1444226153Sdes			printf("\\\n\t");
14451590Srgrimes			col = 8;
14461590Srgrimes		}
14471590Srgrimes		col += width;
14481590Srgrimes		do {
1449226153Sdes			putchar(*cp++);
14501590Srgrimes		} while (*cp);
14511590Srgrimes	}
14521590Srgrimes	if (col == 0)
1453226153Sdes		printf("       ");
1454226153Sdes	printf("\"\n");
14551590Srgrimes}
14561590Srgrimes
1457115759Spetervoid
1458115759Speterktrgenio(struct ktr_genio *ktr, int len)
1459115759Speter{
1460115759Speter	int datalen = len - sizeof (struct ktr_genio);
1461115759Speter	char *dp = (char *)ktr + sizeof (struct ktr_genio);
1462115759Speter	static int screenwidth = 0;
1463115759Speter	int i, binary;
1464115759Speter
1465251072Spjd	printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1466251072Spjd		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1467251072Spjd		datalen == 1 ? "" : "s");
1468251072Spjd	if (suppressdata)
1469251072Spjd		return;
1470115759Speter	if (screenwidth == 0) {
1471115759Speter		struct winsize ws;
1472115759Speter
1473115759Speter		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1474115759Speter		    ws.ws_col > 8)
1475115759Speter			screenwidth = ws.ws_col;
1476115759Speter		else
1477115759Speter			screenwidth = 80;
1478115759Speter	}
1479115759Speter	if (maxdata && datalen > maxdata)
1480115759Speter		datalen = maxdata;
1481115759Speter
1482115759Speter	for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1483115759Speter		if (dp[i] >= 32 && dp[i] < 127)
1484115759Speter			continue;
1485115759Speter		if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1486115759Speter			continue;
1487115759Speter		binary = 1;
1488115759Speter	}
1489115759Speter	if (binary)
1490115759Speter		hexdump(dp, datalen, screenwidth);
1491115759Speter	else
1492115759Speter		visdump(dp, datalen, screenwidth);
1493115759Speter}
1494115759Speter
1495100824Sdwmaloneconst char *signames[] = {
14961590Srgrimes	"NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",	/*  1 - 6  */
14971590Srgrimes	"EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",		/*  7 - 12 */
14981590Srgrimes	"PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",		/* 13 - 18 */
14991590Srgrimes	"CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",		/* 19 - 24 */
15001590Srgrimes	"XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",	/* 25 - 30 */
15011590Srgrimes	"USR2", NULL,						/* 31 - 32 */
15021590Srgrimes};
15031590Srgrimes
1504100824Sdwmalonevoid
1505219138Sdchaginktrpsig(struct ktr_psig *psig)
15061590Srgrimes{
1507219138Sdchagin	if (psig->signo > 0 && psig->signo < NSIG)
1508226153Sdes		printf("SIG%s ", signames[psig->signo]);
1509160294Skib	else
1510226153Sdes		printf("SIG %d ", psig->signo);
1511240820Sjilles	if (psig->action == SIG_DFL) {
1512240820Sjilles		printf("SIG_DFL code=");
1513240820Sjilles		sigcodename(psig->signo, psig->code);
1514240820Sjilles		putchar('\n');
1515240820Sjilles	} else {
1516240820Sjilles		printf("caught handler=0x%lx mask=0x%x code=",
1517240820Sjilles		    (u_long)psig->action, psig->mask.__bits[0]);
1518240820Sjilles		sigcodename(psig->signo, psig->code);
1519240820Sjilles		putchar('\n');
1520100824Sdwmalone	}
15211590Srgrimes}
15221590Srgrimes
1523100824Sdwmalonevoid
1524234494Sjhbktrcsw_old(struct ktr_csw_old *cs)
15251590Srgrimes{
1526226153Sdes	printf("%s %s\n", cs->out ? "stop" : "resume",
15271590Srgrimes		cs->user ? "user" : "kernel");
15281590Srgrimes}
15291590Srgrimes
1530234494Sjhbvoid
1531234494Sjhbktrcsw(struct ktr_csw *cs)
1532234494Sjhb{
1533234494Sjhb	printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume",
1534234494Sjhb	    cs->user ? "user" : "kernel", cs->wmesg);
1535234494Sjhb}
1536234494Sjhb
1537165916Sjhbvoid
1538288957Sbdreweryktruser(int len, void *p)
1539165916Sjhb{
1540273048Sjhb	unsigned char *cp;
1541165916Sjhb
1542292236Sjhb	if (sysdecode_utrace(stdout, p, len)) {
1543165916Sjhb		printf("\n");
1544165916Sjhb		return;
1545165916Sjhb	}
1546165916Sjhb
1547226153Sdes	printf("%d ", len);
1548273048Sjhb	cp = p;
154918470Sphk	while (len--)
1550127402Sphk		if (decimal)
1551273048Sjhb			printf(" %d", *cp++);
1552127402Sphk		else
1553273048Sjhb			printf(" %02x", *cp++);
1554226153Sdes	printf("\n");
155518400Sphk}
155618400Sphk
1557100824Sdwmalonevoid
1558255219Spjdktrcaprights(cap_rights_t *rightsp)
1559255219Spjd{
1560255219Spjd
1561255219Spjd	printf("cap_rights_t ");
1562255219Spjd	capname(rightsp);
1563255219Spjd	printf("\n");
1564255219Spjd}
1565255219Spjd
1566303092Skibstatic void
1567303092Skibktrtimeval(struct timeval *tv)
1568303092Skib{
1569303092Skib
1570303092Skib	printf("{%ld, %ld}", (long)tv->tv_sec, tv->tv_usec);
1571303092Skib}
1572303092Skib
1573255219Spjdvoid
1574303092Skibktritimerval(struct itimerval *it)
1575303092Skib{
1576303092Skib
1577303092Skib	printf("itimerval { .interval = ");
1578303092Skib	ktrtimeval(&it->it_interval);
1579303092Skib	printf(", .value = ");
1580303092Skib	ktrtimeval(&it->it_value);
1581303092Skib	printf(" }\n");
1582303092Skib}
1583303092Skib
1584303092Skibvoid
1585176471Sdesktrsockaddr(struct sockaddr *sa)
1586176471Sdes{
1587176471Sdes/*
1588176471Sdes TODO: Support additional address families
1589176471Sdes	#include <netnatm/natm.h>
1590176471Sdes	struct sockaddr_natm	*natm;
1591252356Sdavide	#include <netsmb/netbios.h>
1592252356Sdavide	struct sockaddr_nb	*nb;
1593176471Sdes*/
1594176471Sdes	char addr[64];
1595176471Sdes
1596176471Sdes	/*
1597176471Sdes	 * note: ktrstruct() has already verified that sa points to a
1598176471Sdes	 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1599176471Sdes	 * sa->sa_len bytes long.
1600176471Sdes	 */
1601176471Sdes	printf("struct sockaddr { ");
1602176471Sdes	sockfamilyname(sa->sa_family);
1603176471Sdes	printf(", ");
1604176471Sdes
1605176471Sdes#define check_sockaddr_len(n)					\
1606226329Sdes	if (sa_##n.s##n##_len < sizeof(struct sockaddr_##n)) {	\
1607176471Sdes		printf("invalid");				\
1608176471Sdes		break;						\
1609176471Sdes	}
1610176471Sdes
1611176471Sdes	switch(sa->sa_family) {
1612176471Sdes	case AF_INET: {
1613226329Sdes		struct sockaddr_in sa_in;
1614176471Sdes
1615226329Sdes		memset(&sa_in, 0, sizeof(sa_in));
1616246719Szont		memcpy(&sa_in, sa, sa->sa_len);
1617176471Sdes		check_sockaddr_len(in);
1618226329Sdes		inet_ntop(AF_INET, &sa_in.sin_addr, addr, sizeof addr);
1619226329Sdes		printf("%s:%u", addr, ntohs(sa_in.sin_port));
1620176471Sdes		break;
1621176471Sdes	}
1622176471Sdes	case AF_INET6: {
1623226329Sdes		struct sockaddr_in6 sa_in6;
1624176471Sdes
1625226329Sdes		memset(&sa_in6, 0, sizeof(sa_in6));
1626246719Szont		memcpy(&sa_in6, sa, sa->sa_len);
1627176471Sdes		check_sockaddr_len(in6);
1628251486Sae		getnameinfo((struct sockaddr *)&sa_in6, sizeof(sa_in6),
1629251486Sae		    addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
1630226329Sdes		printf("[%s]:%u", addr, htons(sa_in6.sin6_port));
1631176471Sdes		break;
1632176471Sdes	}
1633176471Sdes	case AF_UNIX: {
1634226329Sdes		struct sockaddr_un sa_un;
1635176471Sdes
1636226329Sdes		memset(&sa_un, 0, sizeof(sa_un));
1637246719Szont		memcpy(&sa_un, sa, sa->sa_len);
1638226329Sdes		printf("%.*s", (int)sizeof(sa_un.sun_path), sa_un.sun_path);
1639176471Sdes		break;
1640176471Sdes	}
1641176471Sdes	default:
1642176471Sdes		printf("unknown address family");
1643176471Sdes	}
1644176471Sdes	printf(" }\n");
1645176471Sdes}
1646176471Sdes
1647176471Sdesvoid
1648176471Sdesktrstat(struct stat *statp)
1649176471Sdes{
1650176471Sdes	char mode[12], timestr[PATH_MAX + 4];
1651176471Sdes	struct passwd *pwd;
1652176471Sdes	struct group  *grp;
1653176471Sdes	struct tm *tm;
1654176471Sdes
1655176471Sdes	/*
1656176471Sdes	 * note: ktrstruct() has already verified that statp points to a
1657176471Sdes	 * buffer exactly sizeof(struct stat) bytes long.
1658176471Sdes	 */
1659176471Sdes	printf("struct stat {");
1660256107Sdes	printf("dev=%ju, ino=%ju, ",
1661256107Sdes		(uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino);
1662256107Sdes	if (resolv == 0)
1663256107Sdes		printf("mode=0%jo, ", (uintmax_t)statp->st_mode);
1664256107Sdes	else {
1665256107Sdes		strmode(statp->st_mode, mode);
1666256107Sdes		printf("mode=%s, ", mode);
1667256107Sdes	}
1668256107Sdes	printf("nlink=%ju, ", (uintmax_t)statp->st_nlink);
1669259434Spjd	if (resolv == 0) {
1670259434Spjd		pwd = NULL;
1671259434Spjd	} else {
1672296047Soshogbo#ifdef HAVE_LIBCASPER
1673259434Spjd		if (cappwd != NULL)
1674259434Spjd			pwd = cap_getpwuid(cappwd, statp->st_uid);
1675259434Spjd		else
1676259434Spjd#endif
1677259434Spjd			pwd = getpwuid(statp->st_uid);
1678259434Spjd	}
1679259434Spjd	if (pwd == NULL)
1680176471Sdes		printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1681176471Sdes	else
1682176471Sdes		printf("uid=\"%s\", ", pwd->pw_name);
1683259434Spjd	if (resolv == 0) {
1684259434Spjd		grp = NULL;
1685259434Spjd	} else {
1686296047Soshogbo#ifdef HAVE_LIBCASPER
1687259434Spjd		if (capgrp != NULL)
1688259434Spjd			grp = cap_getgrgid(capgrp, statp->st_gid);
1689259434Spjd		else
1690259434Spjd#endif
1691259434Spjd			grp = getgrgid(statp->st_gid);
1692259434Spjd	}
1693259434Spjd	if (grp == NULL)
1694176471Sdes		printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1695176471Sdes	else
1696176471Sdes		printf("gid=\"%s\", ", grp->gr_name);
1697176471Sdes	printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1698176471Sdes	printf("atime=");
1699176471Sdes	if (resolv == 0)
1700205793Sed		printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1701176471Sdes	else {
1702205793Sed		tm = localtime(&statp->st_atim.tv_sec);
1703226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1704176471Sdes		printf("\"%s\"", timestr);
1705176471Sdes	}
1706205793Sed	if (statp->st_atim.tv_nsec != 0)
1707205793Sed		printf(".%09ld, ", statp->st_atim.tv_nsec);
1708176471Sdes	else
1709176471Sdes		printf(", ");
1710300428Sngie	printf("mtime=");
1711176471Sdes	if (resolv == 0)
1712205793Sed		printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1713176471Sdes	else {
1714205793Sed		tm = localtime(&statp->st_mtim.tv_sec);
1715226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1716176471Sdes		printf("\"%s\"", timestr);
1717176471Sdes	}
1718205793Sed	if (statp->st_mtim.tv_nsec != 0)
1719205793Sed		printf(".%09ld, ", statp->st_mtim.tv_nsec);
1720176471Sdes	else
1721176471Sdes		printf(", ");
1722176471Sdes	printf("ctime=");
1723176471Sdes	if (resolv == 0)
1724205793Sed		printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1725176471Sdes	else {
1726205793Sed		tm = localtime(&statp->st_ctim.tv_sec);
1727226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1728176471Sdes		printf("\"%s\"", timestr);
1729176471Sdes	}
1730205793Sed	if (statp->st_ctim.tv_nsec != 0)
1731205793Sed		printf(".%09ld, ", statp->st_ctim.tv_nsec);
1732176471Sdes	else
1733176471Sdes		printf(", ");
1734176471Sdes	printf("birthtime=");
1735176471Sdes	if (resolv == 0)
1736205793Sed		printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
1737176471Sdes	else {
1738205793Sed		tm = localtime(&statp->st_birthtim.tv_sec);
1739226153Sdes		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1740176471Sdes		printf("\"%s\"", timestr);
1741176471Sdes	}
1742205793Sed	if (statp->st_birthtim.tv_nsec != 0)
1743205793Sed		printf(".%09ld, ", statp->st_birthtim.tv_nsec);
1744176471Sdes	else
1745176471Sdes		printf(", ");
1746176471Sdes	printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1747176471Sdes		(uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
1748176471Sdes		(intmax_t)statp->st_blocks, statp->st_flags);
1749176471Sdes	printf(" }\n");
1750176471Sdes}
1751176471Sdes
1752176471Sdesvoid
1753176471Sdesktrstruct(char *buf, size_t buflen)
1754176471Sdes{
1755176471Sdes	char *name, *data;
1756176471Sdes	size_t namelen, datalen;
1757176471Sdes	int i;
1758255219Spjd	cap_rights_t rights;
1759303092Skib	struct itimerval it;
1760204045Simp	struct stat sb;
1761204045Simp	struct sockaddr_storage ss;
1762176471Sdes
1763176471Sdes	for (name = buf, namelen = 0;
1764176471Sdes	     namelen < buflen && name[namelen] != '\0';
1765176471Sdes	     ++namelen)
1766176471Sdes		/* nothing */;
1767176471Sdes	if (namelen == buflen)
1768176471Sdes		goto invalid;
1769176471Sdes	if (name[namelen] != '\0')
1770176471Sdes		goto invalid;
1771176471Sdes	data = buf + namelen + 1;
1772176471Sdes	datalen = buflen - namelen - 1;
1773176471Sdes	if (datalen == 0)
1774176471Sdes		goto invalid;
1775176471Sdes	/* sanity check */
1776226329Sdes	for (i = 0; i < (int)namelen; ++i)
1777226329Sdes		if (!isalpha(name[i]))
1778176471Sdes			goto invalid;
1779255219Spjd	if (strcmp(name, "caprights") == 0) {
1780255219Spjd		if (datalen != sizeof(cap_rights_t))
1781255219Spjd			goto invalid;
1782255219Spjd		memcpy(&rights, data, datalen);
1783255219Spjd		ktrcaprights(&rights);
1784303092Skib	} else if (strcmp(name, "itimerval") == 0) {
1785303092Skib		if (datalen != sizeof(struct itimerval))
1786303092Skib			goto invalid;
1787303092Skib		memcpy(&it, data, datalen);
1788303092Skib		ktritimerval(&it);
1789255219Spjd	} else if (strcmp(name, "stat") == 0) {
1790176471Sdes		if (datalen != sizeof(struct stat))
1791176471Sdes			goto invalid;
1792204045Simp		memcpy(&sb, data, datalen);
1793204045Simp		ktrstat(&sb);
1794176471Sdes	} else if (strcmp(name, "sockaddr") == 0) {
1795204045Simp		if (datalen > sizeof(ss))
1796204045Simp			goto invalid;
1797204045Simp		memcpy(&ss, data, datalen);
1798246720Szont		if (datalen != ss.ss_len)
1799176471Sdes			goto invalid;
1800204045Simp		ktrsockaddr((struct sockaddr *)&ss);
1801176471Sdes	} else {
1802176471Sdes		printf("unknown structure\n");
1803176471Sdes	}
1804176471Sdes	return;
1805176471Sdesinvalid:
1806176471Sdes	printf("invalid record\n");
1807176471Sdes}
1808176471Sdes
1809226269Sdesvoid
1810226269Sdesktrcapfail(struct ktr_cap_fail *ktr)
1811226269Sdes{
1812226495Sdes	switch (ktr->cap_type) {
1813226495Sdes	case CAPFAIL_NOTCAPABLE:
1814226495Sdes		/* operation on fd with insufficient capabilities */
1815226495Sdes		printf("operation requires ");
1816255219Spjd		capname(&ktr->cap_needed);
1817262405Spjd		printf(", descriptor holds ");
1818255219Spjd		capname(&ktr->cap_held);
1819226495Sdes		break;
1820226495Sdes	case CAPFAIL_INCREASE:
1821226495Sdes		/* requested more capabilities than fd already has */
1822226495Sdes		printf("attempt to increase capabilities from ");
1823255219Spjd		capname(&ktr->cap_held);
1824226505Sdes		printf(" to ");
1825255219Spjd		capname(&ktr->cap_needed);
1826226495Sdes		break;
1827226495Sdes	case CAPFAIL_SYSCALL:
1828226495Sdes		/* called restricted syscall */
1829226495Sdes		printf("disallowed system call");
1830226495Sdes		break;
1831226495Sdes	case CAPFAIL_LOOKUP:
1832226495Sdes		/* used ".." in strict-relative mode */
1833226495Sdes		printf("restricted VFS lookup");
1834226495Sdes		break;
1835226495Sdes	default:
1836226495Sdes		printf("unknown capability failure: ");
1837255219Spjd		capname(&ktr->cap_needed);
1838226495Sdes		printf(" ");
1839255219Spjd		capname(&ktr->cap_held);
1840226495Sdes		break;
1841226495Sdes	}
1842233925Sjhb	printf("\n");
1843226269Sdes}
1844226269Sdes
1845233925Sjhbvoid
1846233925Sjhbktrfault(struct ktr_fault *ktr)
1847233925Sjhb{
1848233925Sjhb
1849276758Sdchagin	printf("0x%jx ", (uintmax_t)ktr->vaddr);
1850233925Sjhb	vmprotname(ktr->type);
1851233925Sjhb	printf("\n");
1852233925Sjhb}
1853233925Sjhb
1854233925Sjhbvoid
1855233925Sjhbktrfaultend(struct ktr_faultend *ktr)
1856233925Sjhb{
1857233925Sjhb
1858233925Sjhb	vmresultname(ktr->result);
1859233925Sjhb	printf("\n");
1860233925Sjhb}
1861233925Sjhb
1862176471Sdesvoid
1863100824Sdwmaloneusage(void)
18641590Srgrimes{
1865263879Sbdrewery	fprintf(stderr, "usage: kdump [-dEnlHRrSsTA] [-f trfile] "
1866177856Sru	    "[-m maxdata] [-p pid] [-t trstr]\n");
18671590Srgrimes	exit(1);
18681590Srgrimes}
1869