1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1988, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#define _WANT_KERNEL_ERRNO
33#ifdef __LP64__
34#define	_WANT_KEVENT32
35#endif
36#define	_WANT_FREEBSD11_KEVENT
37#define	_WANT_FREEBSD_BITSET
38#include <sys/param.h>
39#include <sys/capsicum.h>
40#include <sys/_bitset.h>
41#include <sys/bitset.h>
42#include <sys/errno.h>
43#include <sys/time.h>
44#include <sys/uio.h>
45#include <sys/event.h>
46#include <sys/ktrace.h>
47#include <sys/mman.h>
48#include <sys/ioctl.h>
49#include <sys/poll.h>
50#include <sys/socket.h>
51#include <sys/stat.h>
52#include <sys/sysent.h>
53#include <sys/umtx.h>
54#include <sys/un.h>
55#include <sys/queue.h>
56#include <sys/wait.h>
57#ifdef WITH_CASPER
58#include <sys/nv.h>
59#endif
60#include <arpa/inet.h>
61#include <netinet/in.h>
62#include <ctype.h>
63#include <capsicum_helpers.h>
64#include <err.h>
65#include <grp.h>
66#include <inttypes.h>
67#include <locale.h>
68#include <netdb.h>
69#include <nl_types.h>
70#include <pwd.h>
71#include <stddef.h>
72#include <stdio.h>
73#include <stdlib.h>
74#include <string.h>
75#include <sysdecode.h>
76#include <time.h>
77#include <unistd.h>
78#include <vis.h>
79#include "ktrace.h"
80#include "kdump.h"
81
82#ifdef WITH_CASPER
83#include <libcasper.h>
84
85#include <casper/cap_grp.h>
86#include <casper/cap_pwd.h>
87#endif
88
89int fetchprocinfo(struct ktr_header *, u_int *);
90u_int findabi(struct ktr_header *);
91int fread_tail(void *, int, int);
92void dumpheader(struct ktr_header *, u_int);
93void dumptimeval(struct ktr_header_v0 *kth);
94void dumptimespec(struct ktr_header *kth);
95void ktrsyscall(struct ktr_syscall *, u_int);
96void ktrsysret(struct ktr_sysret *, u_int);
97void ktrnamei(char *, int);
98void hexdump(char *, int, int);
99void visdump(char *, int, int);
100void ktrgenio(struct ktr_genio *, int);
101void ktrpsig(struct ktr_psig *);
102void ktrcsw(struct ktr_csw *);
103void ktrcsw_old(struct ktr_csw_old *);
104void ktruser(int, void *);
105void ktrcaprights(cap_rights_t *);
106void ktritimerval(struct itimerval *it);
107void ktrsockaddr(struct sockaddr *);
108void ktrstat(struct stat *);
109void ktrstruct(char *, size_t);
110void ktrcapfail(struct ktr_cap_fail *);
111void ktrfault(struct ktr_fault *);
112void ktrfaultend(struct ktr_faultend *);
113void ktrkevent(struct kevent *);
114void ktrpollfd(struct pollfd *);
115void ktrstructarray(struct ktr_struct_array *, size_t);
116void ktrbitset(char *, struct bitset *, size_t);
117void ktrsyscall_freebsd(struct ktr_syscall *ktr, register_t **resip,
118    int *resnarg, char *resc, u_int sv_flags);
119void usage(void);
120
121#define	TIMESTAMP_NONE		0x0
122#define	TIMESTAMP_ABSOLUTE	0x1
123#define	TIMESTAMP_ELAPSED	0x2
124#define	TIMESTAMP_RELATIVE	0x4
125
126bool decimal, fancy = true, resolv;
127static bool abiflag, suppressdata, syscallno, tail, threads, cpuflag;
128static int timestamp, maxdata;
129static const char *tracefile = DEF_TRACEFILE;
130static struct ktr_header ktr_header;
131static short version;
132
133#define TIME_FORMAT	"%b %e %T %Y"
134#define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
135
136struct proc_info
137{
138	TAILQ_ENTRY(proc_info)	info;
139	u_int			sv_flags;
140	pid_t			pid;
141};
142
143static TAILQ_HEAD(trace_procs, proc_info) trace_procs;
144
145#ifdef WITH_CASPER
146static cap_channel_t *cappwd, *capgrp;
147
148static int
149cappwdgrp_setup(cap_channel_t **cappwdp, cap_channel_t **capgrpp)
150{
151	cap_channel_t *capcas, *cappwdloc, *capgrploc;
152	const char *cmds[1], *fields[1];
153
154	capcas = cap_init();
155	if (capcas == NULL) {
156		err(1, "unable to create casper process");
157		exit(1);
158	}
159	cappwdloc = cap_service_open(capcas, "system.pwd");
160	capgrploc = cap_service_open(capcas, "system.grp");
161	/* Casper capability no longer needed. */
162	cap_close(capcas);
163	if (cappwdloc == NULL || capgrploc == NULL) {
164		if (cappwdloc == NULL)
165			warn("unable to open system.pwd service");
166		if (capgrploc == NULL)
167			warn("unable to open system.grp service");
168		exit(1);
169	}
170	/* Limit system.pwd to only getpwuid() function and pw_name field. */
171	cmds[0] = "getpwuid";
172	if (cap_pwd_limit_cmds(cappwdloc, cmds, 1) < 0)
173		err(1, "unable to limit system.pwd service");
174	fields[0] = "pw_name";
175	if (cap_pwd_limit_fields(cappwdloc, fields, 1) < 0)
176		err(1, "unable to limit system.pwd service");
177	/* Limit system.grp to only getgrgid() function and gr_name field. */
178	cmds[0] = "getgrgid";
179	if (cap_grp_limit_cmds(capgrploc, cmds, 1) < 0)
180		err(1, "unable to limit system.grp service");
181	fields[0] = "gr_name";
182	if (cap_grp_limit_fields(capgrploc, fields, 1) < 0)
183		err(1, "unable to limit system.grp service");
184
185	*cappwdp = cappwdloc;
186	*capgrpp = capgrploc;
187	return (0);
188}
189#endif	/* WITH_CASPER */
190
191void
192print_integer_arg(const char *(*decoder)(int), int value)
193{
194	const char *str;
195
196	str = decoder(value);
197	if (str != NULL)
198		printf("%s", str);
199	else {
200		if (decimal)
201			printf("<invalid=%d>", value);
202		else
203			printf("<invalid=%#x>", value);
204	}
205}
206
207/* Like print_integer_arg but unknown values are treated as valid. */
208void
209print_integer_arg_valid(const char *(*decoder)(int), int value)
210{
211	const char *str;
212
213	str = decoder(value);
214	if (str != NULL)
215		printf("%s", str);
216	else {
217		if (decimal)
218			printf("%d", value);
219		else
220			printf("%#x", value);
221	}
222}
223
224bool
225print_mask_arg_part(bool (*decoder)(FILE *, int, int *), int value, int *rem)
226{
227
228	printf("%#x<", value);
229	return (decoder(stdout, value, rem));
230}
231
232void
233print_mask_arg(bool (*decoder)(FILE *, int, int *), int value)
234{
235	bool invalid;
236	int rem;
237
238	invalid = !print_mask_arg_part(decoder, value, &rem);
239	printf(">");
240	if (invalid)
241		printf("<invalid>%u", rem);
242}
243
244void
245print_mask_arg0(bool (*decoder)(FILE *, int, int *), int value)
246{
247	bool invalid;
248	int rem;
249
250	if (value == 0) {
251		printf("0");
252		return;
253	}
254	printf("%#x<", value);
255	invalid = !decoder(stdout, value, &rem);
256	printf(">");
257	if (invalid)
258		printf("<invalid>%u", rem);
259}
260
261static void
262decode_fileflags(fflags_t value)
263{
264	bool invalid;
265	fflags_t rem;
266
267	if (value == 0) {
268		printf("0");
269		return;
270	}
271	printf("%#x<", value);
272	invalid = !sysdecode_fileflags(stdout, value, &rem);
273	printf(">");
274	if (invalid)
275		printf("<invalid>%u", rem);
276}
277
278void
279decode_filemode(int value)
280{
281	bool invalid;
282	int rem;
283
284	if (value == 0) {
285		printf("0");
286		return;
287	}
288	printf("%#o<", value);
289	invalid = !sysdecode_filemode(stdout, value, &rem);
290	printf(">");
291	if (invalid)
292		printf("<invalid>%u", rem);
293}
294
295void
296print_mask_arg32(bool (*decoder)(FILE *, uint32_t, uint32_t *), uint32_t value)
297{
298	bool invalid;
299	uint32_t rem;
300
301	printf("%#x<", value);
302	invalid = !decoder(stdout, value, &rem);
303	printf(">");
304	if (invalid)
305		printf("<invalid>%u", rem);
306}
307
308void
309print_mask_argul(bool (*decoder)(FILE *, u_long, u_long *), u_long value)
310{
311	bool invalid;
312	u_long rem;
313
314	if (value == 0) {
315		printf("0");
316		return;
317	}
318	printf("%#lx<", value);
319	invalid = !decoder(stdout, value, &rem);
320	printf(">");
321	if (invalid)
322		printf("<invalid>%lu", rem);
323}
324
325int
326main(int argc, char *argv[])
327{
328	int ch, ktrlen, size;
329	void *m;
330	int trpoints = ALL_POINTS;
331	int drop_logged;
332	pid_t pid = 0;
333	u_int sv_flags;
334
335	setlocale(LC_CTYPE, "");
336
337	timestamp = TIMESTAMP_NONE;
338
339	while ((ch = getopt(argc,argv,"f:cdElm:np:AHRrSsTt:")) != -1)
340		switch (ch) {
341		case 'A':
342			abiflag = true;
343			break;
344		case 'f':
345			tracefile = optarg;
346			break;
347		case 'c':
348			cpuflag = true;
349			break;
350		case 'd':
351			decimal = true;
352			break;
353		case 'l':
354			tail = true;
355			break;
356		case 'm':
357			maxdata = atoi(optarg);
358			break;
359		case 'n':
360			fancy = false;
361			break;
362		case 'p':
363			pid = atoi(optarg);
364			break;
365		case 'r':
366			resolv = true;
367			break;
368		case 'S':
369			syscallno = true;
370			break;
371		case 's':
372			suppressdata = true;
373			break;
374		case 'E':
375			timestamp |= TIMESTAMP_ELAPSED;
376			break;
377		case 'H':
378			threads = true;
379			break;
380		case 'R':
381			timestamp |= TIMESTAMP_RELATIVE;
382			break;
383		case 'T':
384			timestamp |= TIMESTAMP_ABSOLUTE;
385			break;
386		case 't':
387			trpoints = getpoints(optarg);
388			if (trpoints < 0)
389				errx(1, "unknown trace point in %s", optarg);
390			break;
391		default:
392			usage();
393		}
394
395	if (argc > optind)
396		usage();
397
398	m = malloc(size = 1025);
399	if (m == NULL)
400		errx(1, "%s", strerror(ENOMEM));
401	if (strcmp(tracefile, "-") != 0)
402		if (!freopen(tracefile, "r", stdin))
403			err(1, "%s", tracefile);
404
405	caph_cache_catpages();
406	caph_cache_tzdata();
407
408#ifdef WITH_CASPER
409	if (resolv) {
410		if (cappwdgrp_setup(&cappwd, &capgrp) < 0) {
411			cappwd = NULL;
412			capgrp = NULL;
413		}
414	}
415	if (!resolv || (cappwd != NULL && capgrp != NULL)) {
416		if (caph_enter() < 0)
417			err(1, "unable to enter capability mode");
418	}
419#else
420	if (!resolv) {
421		if (caph_enter() < 0)
422			err(1, "unable to enter capability mode");
423	}
424#endif
425	if (caph_limit_stdio() == -1)
426		err(1, "unable to limit stdio");
427
428	TAILQ_INIT(&trace_procs);
429	drop_logged = 0;
430	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
431		if (ktr_header.ktr_type & KTR_VERSIONED) {
432			ktr_header.ktr_type &= ~KTR_VERSIONED;
433			version = ktr_header.ktr_version;
434		} else
435			version = KTR_VERSION0;
436		if (ktr_header.ktr_type & KTR_DROP) {
437			ktr_header.ktr_type &= ~KTR_DROP;
438			if (!drop_logged && threads) {
439				printf(
440				    "%6d %6d %-8.*s Events dropped.\n",
441				    ktr_header.ktr_pid,
442				    ktr_header.ktr_tid > 0 ?
443				    (lwpid_t)ktr_header.ktr_tid : 0,
444				    MAXCOMLEN, ktr_header.ktr_comm);
445				drop_logged = 1;
446			} else if (!drop_logged) {
447				printf("%6d %-8.*s Events dropped.\n",
448				    ktr_header.ktr_pid, MAXCOMLEN,
449				    ktr_header.ktr_comm);
450				drop_logged = 1;
451			}
452		}
453		if ((ktrlen = ktr_header.ktr_len) < 0)
454			errx(1, "bogus length 0x%x", ktrlen);
455		if (ktrlen > size) {
456			m = realloc(m, ktrlen+1);
457			if (m == NULL)
458				errx(1, "%s", strerror(ENOMEM));
459			size = ktrlen;
460		}
461		if (version == KTR_VERSION0 &&
462		    fseek(stdin, KTR_OFFSET_V0, SEEK_CUR) < 0)
463			errx(1, "%s", strerror(errno));
464		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
465			errx(1, "data too short");
466		if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
467			continue;
468		if (pid && ktr_header.ktr_pid != pid &&
469		    ktr_header.ktr_tid != pid)
470			continue;
471		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
472			continue;
473		sv_flags = findabi(&ktr_header);
474		dumpheader(&ktr_header, sv_flags);
475		drop_logged = 0;
476		switch (ktr_header.ktr_type) {
477		case KTR_SYSCALL:
478			ktrsyscall((struct ktr_syscall *)m, sv_flags);
479			break;
480		case KTR_SYSRET:
481			ktrsysret((struct ktr_sysret *)m, sv_flags);
482			break;
483		case KTR_NAMEI:
484		case KTR_SYSCTL:
485			ktrnamei(m, ktrlen);
486			break;
487		case KTR_GENIO:
488			ktrgenio((struct ktr_genio *)m, ktrlen);
489			break;
490		case KTR_PSIG:
491			ktrpsig((struct ktr_psig *)m);
492			break;
493		case KTR_CSW:
494			if (ktrlen == sizeof(struct ktr_csw_old))
495				ktrcsw_old((struct ktr_csw_old *)m);
496			else
497				ktrcsw((struct ktr_csw *)m);
498			break;
499		case KTR_USER:
500			ktruser(ktrlen, m);
501			break;
502		case KTR_STRUCT:
503			ktrstruct(m, ktrlen);
504			break;
505		case KTR_CAPFAIL:
506			ktrcapfail((struct ktr_cap_fail *)m);
507			break;
508		case KTR_FAULT:
509			ktrfault((struct ktr_fault *)m);
510			break;
511		case KTR_FAULTEND:
512			ktrfaultend((struct ktr_faultend *)m);
513			break;
514		case KTR_STRUCT_ARRAY:
515			ktrstructarray((struct ktr_struct_array *)m, ktrlen);
516			break;
517		default:
518			printf("\n");
519			break;
520		}
521		if (tail)
522			fflush(stdout);
523	}
524	return 0;
525}
526
527int
528fread_tail(void *buf, int size, int num)
529{
530	int i;
531
532	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
533		sleep(1);
534		clearerr(stdin);
535	}
536	return (i);
537}
538
539int
540fetchprocinfo(struct ktr_header *kth, u_int *flags)
541{
542	struct proc_info *pi;
543
544	switch (kth->ktr_type) {
545	case KTR_PROCCTOR:
546		TAILQ_FOREACH(pi, &trace_procs, info) {
547			if (pi->pid == kth->ktr_pid) {
548				TAILQ_REMOVE(&trace_procs, pi, info);
549				break;
550			}
551		}
552		pi = malloc(sizeof(struct proc_info));
553		if (pi == NULL)
554			errx(1, "%s", strerror(ENOMEM));
555		pi->sv_flags = *flags;
556		pi->pid = kth->ktr_pid;
557		TAILQ_INSERT_TAIL(&trace_procs, pi, info);
558		return (1);
559
560	case KTR_PROCDTOR:
561		TAILQ_FOREACH(pi, &trace_procs, info) {
562			if (pi->pid == kth->ktr_pid) {
563				TAILQ_REMOVE(&trace_procs, pi, info);
564				free(pi);
565				break;
566			}
567		}
568		return (1);
569	}
570
571	return (0);
572}
573
574u_int
575findabi(struct ktr_header *kth)
576{
577	struct proc_info *pi;
578
579	TAILQ_FOREACH(pi, &trace_procs, info) {
580		if (pi->pid == kth->ktr_pid) {
581			return (pi->sv_flags);
582		}
583	}
584	return (0);
585}
586
587void
588dumptimeval(struct ktr_header_v0 *kth)
589{
590	static struct timeval prevtime, prevtime_e;
591	struct timeval temp;
592	const char *sign;
593
594	if (timestamp & TIMESTAMP_ABSOLUTE) {
595		printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
596		    kth->ktr_time.tv_usec);
597	}
598	if (timestamp & TIMESTAMP_ELAPSED) {
599		if (prevtime_e.tv_sec == 0)
600			prevtime_e = kth->ktr_time;
601		timersub(&kth->ktr_time, &prevtime_e, &temp);
602		printf("%jd.%06ld ", (intmax_t)temp.tv_sec,
603		    temp.tv_usec);
604	}
605	if (timestamp & TIMESTAMP_RELATIVE) {
606		if (prevtime.tv_sec == 0)
607			prevtime = kth->ktr_time;
608		if (timercmp(&kth->ktr_time, &prevtime, <)) {
609			timersub(&prevtime, &kth->ktr_time, &temp);
610			sign = "-";
611		} else {
612			timersub(&kth->ktr_time, &prevtime, &temp);
613			sign = "";
614		}
615		prevtime = kth->ktr_time;
616		printf("%s%jd.%06ld ", sign, (intmax_t)temp.tv_sec,
617		    temp.tv_usec);
618	}
619}
620
621void
622dumptimespec(struct ktr_header *kth)
623{
624	static struct timespec prevtime, prevtime_e;
625	struct timespec temp;
626	const char *sign;
627
628	if (timestamp & TIMESTAMP_ABSOLUTE) {
629		printf("%jd.%09ld ", (intmax_t)kth->ktr_time.tv_sec,
630		    kth->ktr_time.tv_nsec);
631	}
632	if (timestamp & TIMESTAMP_ELAPSED) {
633		if (prevtime_e.tv_sec == 0)
634			prevtime_e = kth->ktr_time;
635		timespecsub(&kth->ktr_time, &prevtime_e, &temp);
636		printf("%jd.%09ld ", (intmax_t)temp.tv_sec,
637		    temp.tv_nsec);
638	}
639	if (timestamp & TIMESTAMP_RELATIVE) {
640		if (prevtime.tv_sec == 0)
641			prevtime = kth->ktr_time;
642		if (timespeccmp(&kth->ktr_time, &prevtime, <)) {
643			timespecsub(&prevtime, &kth->ktr_time, &temp);
644			sign = "-";
645		} else {
646			timespecsub(&kth->ktr_time, &prevtime, &temp);
647			sign = "";
648		}
649		prevtime = kth->ktr_time;
650		printf("%s%jd.%09ld ", sign, (intmax_t)temp.tv_sec,
651		    temp.tv_nsec);
652	}
653}
654
655void
656dumpheader(struct ktr_header *kth, u_int sv_flags)
657{
658	static char unknown[64];
659	const char *abi;
660	const char *arch;
661	const char *type;
662
663	switch (kth->ktr_type) {
664	case KTR_SYSCALL:
665		type = "CALL";
666		break;
667	case KTR_SYSRET:
668		type = "RET ";
669		break;
670	case KTR_NAMEI:
671		type = "NAMI";
672		break;
673	case KTR_GENIO:
674		type = "GIO ";
675		break;
676	case KTR_PSIG:
677		type = "PSIG";
678		break;
679	case KTR_CSW:
680		type = "CSW ";
681		break;
682	case KTR_USER:
683		type = "USER";
684		break;
685	case KTR_STRUCT:
686	case KTR_STRUCT_ARRAY:
687		type = "STRU";
688		break;
689	case KTR_SYSCTL:
690		type = "SCTL";
691		break;
692	case KTR_CAPFAIL:
693		type = "CAP ";
694		break;
695	case KTR_FAULT:
696		type = "PFLT";
697		break;
698	case KTR_FAULTEND:
699		type = "PRET";
700		break;
701	default:
702		sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
703		type = unknown;
704	}
705
706	/*
707	 * The ktr_tid field was previously the ktr_buffer field, which held
708	 * the kernel pointer value for the buffer associated with data
709	 * following the record header.  It now holds a threadid, but only
710	 * for trace files after the change.  Older trace files still contain
711	 * kernel pointers.  Detect this and suppress the results by printing
712	 * negative tid's as 0.
713	 */
714	if (threads)
715		printf("%6d %6d %-8.*s ", kth->ktr_pid,
716		    kth->ktr_tid > 0 ? (lwpid_t)kth->ktr_tid : 0,
717		    MAXCOMLEN, kth->ktr_comm);
718	else
719		printf("%6d %-8.*s ", kth->ktr_pid, MAXCOMLEN, kth->ktr_comm);
720        if (timestamp) {
721		if (version == KTR_VERSION0)
722			dumptimeval((struct ktr_header_v0 *)kth);
723		else
724			dumptimespec(kth);
725	}
726	if (cpuflag && version > KTR_VERSION0)
727		printf("%3d ", kth->ktr_cpu);
728	printf("%s  ", type);
729	if (abiflag != 0) {
730		switch (sv_flags & SV_ABI_MASK) {
731		case SV_ABI_LINUX:
732			abi = "L";
733			break;
734		case SV_ABI_FREEBSD:
735			abi = "F";
736			break;
737		default:
738			abi = "U";
739			break;
740		}
741
742		if ((sv_flags & SV_LP64) != 0)
743			arch = "64";
744		else if ((sv_flags & SV_ILP32) != 0)
745			arch = "32";
746		else
747			arch = "00";
748
749		printf("%s%s  ", abi, arch);
750	}
751}
752
753#include <sys/syscall.h>
754
755static void
756ioctlname(unsigned long val)
757{
758	const char *str;
759
760	str = sysdecode_ioctlname(val);
761	if (str != NULL)
762		printf("%s", str);
763	else if (decimal)
764		printf("%lu", val);
765	else
766		printf("%#lx", val);
767}
768
769static enum sysdecode_abi
770syscallabi(u_int sv_flags)
771{
772
773	if (sv_flags == 0)
774		return (SYSDECODE_ABI_FREEBSD);
775	switch (sv_flags & SV_ABI_MASK) {
776	case SV_ABI_FREEBSD:
777		return (SYSDECODE_ABI_FREEBSD);
778	case SV_ABI_LINUX:
779#ifdef __LP64__
780		if (sv_flags & SV_ILP32)
781			return (SYSDECODE_ABI_LINUX32);
782#endif
783		return (SYSDECODE_ABI_LINUX);
784	default:
785		return (SYSDECODE_ABI_UNKNOWN);
786	}
787}
788
789static void
790syscallname(u_int code, u_int sv_flags)
791{
792	const char *name;
793
794	name = sysdecode_syscallname(syscallabi(sv_flags), code);
795	if (name == NULL)
796		printf("[%d]", code);
797	else {
798		printf("%s", name);
799		if (syscallno)
800			printf("[%d]", code);
801	}
802}
803
804static void
805print_signal(int signo)
806{
807	const char *signame;
808
809	signame = sysdecode_signal(signo);
810	if (signame != NULL)
811		printf("%s", signame);
812	else
813		printf("SIG %d", signo);
814}
815
816void
817ktrsyscall(struct ktr_syscall *ktr, u_int sv_flags)
818{
819	int narg = ktr->ktr_narg;
820	register_t *ip;
821
822	syscallname(ktr->ktr_code, sv_flags);
823	ip = &ktr->ktr_args[0];
824	if (narg) {
825		char c = '(';
826		if (fancy) {
827			switch (sv_flags & SV_ABI_MASK) {
828			case SV_ABI_FREEBSD:
829				ktrsyscall_freebsd(ktr, &ip, &narg, &c,
830				    sv_flags);
831				break;
832#ifdef SYSDECODE_HAVE_LINUX
833			case SV_ABI_LINUX:
834#ifdef __amd64__
835				if (sv_flags & SV_ILP32)
836					ktrsyscall_linux32(ktr, &ip,
837					    &narg, &c);
838				else
839#endif
840				ktrsyscall_linux(ktr, &ip, &narg, &c);
841				break;
842#endif /* SYSDECODE_HAVE_LINUX */
843			}
844		}
845		while (narg > 0)
846			print_number(ip, narg, c);
847		putchar(')');
848	}
849	putchar('\n');
850}
851
852void
853ktrsyscall_freebsd(struct ktr_syscall *ktr, register_t **resip,
854    int *resnarg, char *resc, u_int sv_flags)
855{
856	int narg = ktr->ktr_narg;
857	register_t *ip, *first;
858	intmax_t arg;
859	int quad_align, quad_slots;
860
861	ip = first = &ktr->ktr_args[0];
862	char c = *resc;
863
864			quad_align = 0;
865			if (sv_flags & SV_ILP32) {
866#ifdef __powerpc__
867				quad_align = 1;
868#endif
869				quad_slots = 2;
870			} else
871				quad_slots = 1;
872			switch (ktr->ktr_code) {
873			case SYS_bindat:
874			case SYS_chflagsat:
875			case SYS_connectat:
876			case SYS_faccessat:
877			case SYS_fchmodat:
878			case SYS_fchownat:
879			case SYS_fstatat:
880			case SYS_futimesat:
881			case SYS_linkat:
882			case SYS_mkdirat:
883			case SYS_mkfifoat:
884			case SYS_mknodat:
885			case SYS_openat:
886			case SYS_readlinkat:
887			case SYS_renameat:
888			case SYS_unlinkat:
889			case SYS_utimensat:
890				putchar('(');
891				print_integer_arg_valid(sysdecode_atfd, *ip);
892				c = ',';
893				ip++;
894				narg--;
895				break;
896			}
897			switch (ktr->ktr_code) {
898			case SYS_ioctl: {
899				print_number(ip, narg, c);
900				putchar(c);
901				ioctlname(*ip);
902				c = ',';
903				ip++;
904				narg--;
905				break;
906			}
907			case SYS_ptrace:
908				putchar('(');
909				print_integer_arg(sysdecode_ptrace_request, *ip);
910				c = ',';
911				ip++;
912				narg--;
913				break;
914			case SYS_access:
915			case SYS_eaccess:
916			case SYS_faccessat:
917				print_number(ip, narg, c);
918				putchar(',');
919				print_mask_arg(sysdecode_access_mode, *ip);
920				ip++;
921				narg--;
922				break;
923			case SYS_close_range:
924				print_number(ip, narg, c);
925				print_number(ip, narg, c);
926				putchar(',');
927				print_mask_arg0(sysdecode_close_range_flags,
928				    *ip);
929				ip += 3;
930				narg -= 3;
931				break;
932			case SYS_open:
933			case SYS_openat:
934				print_number(ip, narg, c);
935				putchar(',');
936				print_mask_arg(sysdecode_open_flags, ip[0]);
937				if ((ip[0] & O_CREAT) == O_CREAT) {
938					putchar(',');
939					decode_filemode(ip[1]);
940				}
941				ip += 2;
942				narg -= 2;
943				break;
944			case SYS_wait4:
945				print_number(ip, narg, c);
946				print_number(ip, narg, c);
947				putchar(',');
948				print_mask_arg0(sysdecode_wait4_options, *ip);
949				ip++;
950				narg--;
951				break;
952			case SYS_wait6:
953				putchar('(');
954				print_integer_arg(sysdecode_idtype, *ip);
955				c = ',';
956				ip++;
957				narg--;
958				print_number64(first, ip, narg, c);
959				print_number(ip, narg, c);
960				putchar(',');
961				print_mask_arg(sysdecode_wait6_options, *ip);
962				ip++;
963				narg--;
964				break;
965			case SYS_chmod:
966			case SYS_fchmod:
967			case SYS_lchmod:
968			case SYS_fchmodat:
969				print_number(ip, narg, c);
970				putchar(',');
971				decode_filemode(*ip);
972				ip++;
973				narg--;
974				break;
975			case SYS_mknodat:
976				print_number(ip, narg, c);
977				putchar(',');
978				decode_filemode(*ip);
979				ip++;
980				narg--;
981				break;
982			case SYS_getfsstat:
983				print_number(ip, narg, c);
984				print_number(ip, narg, c);
985				putchar(',');
986				print_integer_arg(sysdecode_getfsstat_mode, *ip);
987				ip++;
988				narg--;
989				break;
990			case SYS_mount:
991				print_number(ip, narg, c);
992				print_number(ip, narg, c);
993				putchar(',');
994				print_mask_arg0(sysdecode_mount_flags, *ip);
995				ip++;
996				narg--;
997				break;
998			case SYS_unmount:
999				print_number(ip, narg, c);
1000				putchar(',');
1001				print_mask_arg0(sysdecode_mount_flags, *ip);
1002				ip++;
1003				narg--;
1004				break;
1005			case SYS_recvmsg:
1006			case SYS_sendmsg:
1007				print_number(ip, narg, c);
1008				print_number(ip, narg, c);
1009				putchar(',');
1010				print_mask_arg0(sysdecode_msg_flags, *ip);
1011				ip++;
1012				narg--;
1013				break;
1014			case SYS_recvfrom:
1015			case SYS_sendto:
1016				print_number(ip, narg, c);
1017				print_number(ip, narg, c);
1018				print_number(ip, narg, c);
1019				putchar(',');
1020				print_mask_arg0(sysdecode_msg_flags, *ip);
1021				ip++;
1022				narg--;
1023				break;
1024			case SYS_chflags:
1025			case SYS_chflagsat:
1026			case SYS_fchflags:
1027			case SYS_lchflags:
1028				print_number(ip, narg, c);
1029				putchar(',');
1030				decode_fileflags(*ip);
1031				ip++;
1032				narg--;
1033				break;
1034			case SYS_kill:
1035				print_number(ip, narg, c);
1036				putchar(',');
1037				print_signal(*ip);
1038				ip++;
1039				narg--;
1040				break;
1041			case SYS_reboot:
1042				putchar('(');
1043				print_mask_arg(sysdecode_reboot_howto, *ip);
1044				ip++;
1045				narg--;
1046				break;
1047			case SYS_umask:
1048				putchar('(');
1049				decode_filemode(*ip);
1050				ip++;
1051				narg--;
1052				break;
1053			case SYS_msync:
1054				print_number(ip, narg, c);
1055				print_number(ip, narg, c);
1056				putchar(',');
1057				print_mask_arg(sysdecode_msync_flags, *ip);
1058				ip++;
1059				narg--;
1060				break;
1061#ifdef SYS_freebsd6_mmap
1062			case SYS_freebsd6_mmap:
1063				print_number(ip, narg, c);
1064				print_number(ip, narg, c);
1065				putchar(',');
1066				print_mask_arg(sysdecode_mmap_prot, *ip);
1067				putchar(',');
1068				ip++;
1069				narg--;
1070				print_mask_arg(sysdecode_mmap_flags, *ip);
1071				ip++;
1072				narg--;
1073				break;
1074#endif
1075			case SYS_mmap:
1076				print_number(ip, narg, c);
1077				print_number(ip, narg, c);
1078				putchar(',');
1079				print_mask_arg(sysdecode_mmap_prot, *ip);
1080				putchar(',');
1081				ip++;
1082				narg--;
1083				print_mask_arg(sysdecode_mmap_flags, *ip);
1084				ip++;
1085				narg--;
1086				break;
1087			case SYS_mprotect:
1088				print_number(ip, narg, c);
1089				print_number(ip, narg, c);
1090				putchar(',');
1091				print_mask_arg(sysdecode_mmap_prot, *ip);
1092				ip++;
1093				narg--;
1094				break;
1095			case SYS_madvise:
1096				print_number(ip, narg, c);
1097				print_number(ip, narg, c);
1098				putchar(',');
1099				print_integer_arg(sysdecode_madvice, *ip);
1100				ip++;
1101				narg--;
1102				break;
1103			case SYS_pathconf:
1104			case SYS_lpathconf:
1105			case SYS_fpathconf:
1106				print_number(ip, narg, c);
1107				putchar(',');
1108				print_integer_arg(sysdecode_pathconf_name, *ip);
1109				ip++;
1110				narg--;
1111				break;
1112			case SYS_getpriority:
1113			case SYS_setpriority:
1114				putchar('(');
1115				print_integer_arg(sysdecode_prio_which, *ip);
1116				c = ',';
1117				ip++;
1118				narg--;
1119				break;
1120			case SYS_fcntl:
1121				print_number(ip, narg, c);
1122				putchar(',');
1123				print_integer_arg(sysdecode_fcntl_cmd, ip[0]);
1124				if (sysdecode_fcntl_arg_p(ip[0])) {
1125					putchar(',');
1126					if (ip[0] == F_SETFL)
1127						print_mask_arg(
1128						    sysdecode_fcntl_fileflags,
1129							ip[1]);
1130					else
1131						sysdecode_fcntl_arg(stdout,
1132						    ip[0], ip[1],
1133						    decimal ? 10 : 16);
1134				}
1135				ip += 2;
1136				narg -= 2;
1137				break;
1138			case SYS_socket: {
1139				int sockdomain;
1140				putchar('(');
1141				sockdomain = *ip;
1142				print_integer_arg(sysdecode_socketdomain,
1143				    sockdomain);
1144				ip++;
1145				narg--;
1146				putchar(',');
1147				print_mask_arg(sysdecode_socket_type, *ip);
1148				ip++;
1149				narg--;
1150				if (sockdomain == PF_INET ||
1151				    sockdomain == PF_INET6) {
1152					putchar(',');
1153					print_integer_arg(sysdecode_ipproto,
1154					    *ip);
1155					ip++;
1156					narg--;
1157				}
1158				c = ',';
1159				break;
1160			}
1161			case SYS_setsockopt:
1162			case SYS_getsockopt: {
1163				const char *str;
1164
1165				print_number(ip, narg, c);
1166				putchar(',');
1167				print_integer_arg_valid(sysdecode_sockopt_level,
1168				    *ip);
1169				str = sysdecode_sockopt_name(ip[0], ip[1]);
1170				if (str != NULL) {
1171					printf(",%s", str);
1172					ip++;
1173					narg--;
1174				}
1175				ip++;
1176				narg--;
1177				break;
1178			}
1179#ifdef SYS_freebsd6_lseek
1180			case SYS_freebsd6_lseek:
1181				print_number(ip, narg, c);
1182				/* Hidden 'pad' argument, not in lseek(2) */
1183				print_number(ip, narg, c);
1184				print_number64(first, ip, narg, c);
1185				putchar(',');
1186				print_integer_arg(sysdecode_whence, *ip);
1187				ip++;
1188				narg--;
1189				break;
1190#endif
1191			case SYS_lseek:
1192				print_number(ip, narg, c);
1193				print_number64(first, ip, narg, c);
1194				putchar(',');
1195				print_integer_arg(sysdecode_whence, *ip);
1196				ip++;
1197				narg--;
1198				break;
1199			case SYS_flock:
1200				print_number(ip, narg, c);
1201				putchar(',');
1202				print_mask_arg(sysdecode_flock_operation, *ip);
1203				ip++;
1204				narg--;
1205				break;
1206			case SYS_mkfifo:
1207			case SYS_mkfifoat:
1208			case SYS_mkdir:
1209			case SYS_mkdirat:
1210				print_number(ip, narg, c);
1211				putchar(',');
1212				decode_filemode(*ip);
1213				ip++;
1214				narg--;
1215				break;
1216			case SYS_shutdown:
1217				print_number(ip, narg, c);
1218				putchar(',');
1219				print_integer_arg(sysdecode_shutdown_how, *ip);
1220				ip++;
1221				narg--;
1222				break;
1223			case SYS_socketpair:
1224				putchar('(');
1225				print_integer_arg(sysdecode_socketdomain, *ip);
1226				ip++;
1227				narg--;
1228				putchar(',');
1229				print_mask_arg(sysdecode_socket_type, *ip);
1230				ip++;
1231				narg--;
1232				c = ',';
1233				break;
1234			case SYS_getrlimit:
1235			case SYS_setrlimit:
1236				putchar('(');
1237				print_integer_arg(sysdecode_rlimit, *ip);
1238				ip++;
1239				narg--;
1240				c = ',';
1241				break;
1242			case SYS_getrusage:
1243				putchar('(');
1244				print_integer_arg(sysdecode_getrusage_who, *ip);
1245				ip++;
1246				narg--;
1247				c = ',';
1248				break;
1249			case SYS_quotactl:
1250				print_number(ip, narg, c);
1251				putchar(',');
1252				if (!sysdecode_quotactl_cmd(stdout, *ip)) {
1253					if (decimal)
1254						printf("<invalid=%d>", (int)*ip);
1255					else
1256						printf("<invalid=%#x>",
1257						    (int)*ip);
1258				}
1259				ip++;
1260				narg--;
1261				c = ',';
1262				break;
1263			case SYS_nfssvc:
1264				putchar('(');
1265				print_integer_arg(sysdecode_nfssvc_flags, *ip);
1266				ip++;
1267				narg--;
1268				c = ',';
1269				break;
1270			case SYS_rtprio:
1271			case SYS_rtprio_thread:
1272				putchar('(');
1273				print_integer_arg(sysdecode_rtprio_function,
1274				    *ip);
1275				ip++;
1276				narg--;
1277				c = ',';
1278				break;
1279			case SYS___semctl:
1280				print_number(ip, narg, c);
1281				print_number(ip, narg, c);
1282				putchar(',');
1283				print_integer_arg(sysdecode_semctl_cmd, *ip);
1284				ip++;
1285				narg--;
1286				break;
1287			case SYS_semget:
1288				print_number(ip, narg, c);
1289				print_number(ip, narg, c);
1290				putchar(',');
1291				print_mask_arg(sysdecode_semget_flags, *ip);
1292				ip++;
1293				narg--;
1294				break;
1295			case SYS_msgctl:
1296				print_number(ip, narg, c);
1297				putchar(',');
1298				print_integer_arg(sysdecode_msgctl_cmd, *ip);
1299				ip++;
1300				narg--;
1301				break;
1302			case SYS_shmat:
1303				print_number(ip, narg, c);
1304				print_number(ip, narg, c);
1305				putchar(',');
1306				print_mask_arg(sysdecode_shmat_flags, *ip);
1307				ip++;
1308				narg--;
1309				break;
1310			case SYS_shmctl:
1311				print_number(ip, narg, c);
1312				putchar(',');
1313				print_integer_arg(sysdecode_shmctl_cmd, *ip);
1314				ip++;
1315				narg--;
1316				break;
1317#ifdef SYS_freebsd12_shm_open
1318			case SYS_freebsd12_shm_open:
1319				if (ip[0] == (uintptr_t)SHM_ANON) {
1320					printf("(SHM_ANON");
1321					ip++;
1322				} else {
1323					print_number(ip, narg, c);
1324				}
1325				putchar(',');
1326				print_mask_arg(sysdecode_open_flags, ip[0]);
1327				putchar(',');
1328				decode_filemode(ip[1]);
1329				ip += 2;
1330				narg -= 2;
1331				break;
1332#endif
1333			case SYS_shm_open2:
1334				if (ip[0] == (uintptr_t)SHM_ANON) {
1335					printf("(SHM_ANON");
1336					ip++;
1337				} else {
1338					print_number(ip, narg, c);
1339				}
1340				putchar(',');
1341				print_mask_arg(sysdecode_open_flags, ip[0]);
1342				putchar(',');
1343				decode_filemode(ip[1]);
1344				putchar(',');
1345				print_mask_arg(sysdecode_shmflags, ip[2]);
1346				ip += 3;
1347				narg -= 3;
1348				break;
1349			case SYS_minherit:
1350				print_number(ip, narg, c);
1351				print_number(ip, narg, c);
1352				putchar(',');
1353				print_integer_arg(sysdecode_minherit_inherit,
1354				    *ip);
1355				ip++;
1356				narg--;
1357				break;
1358			case SYS_rfork:
1359				putchar('(');
1360				print_mask_arg(sysdecode_rfork_flags, *ip);
1361				ip++;
1362				narg--;
1363				c = ',';
1364				break;
1365			case SYS_lio_listio:
1366				putchar('(');
1367				print_integer_arg(sysdecode_lio_listio_mode,
1368				    *ip);
1369				ip++;
1370				narg--;
1371				c = ',';
1372				break;
1373			case SYS_mlockall:
1374				putchar('(');
1375				print_mask_arg(sysdecode_mlockall_flags, *ip);
1376				ip++;
1377				narg--;
1378				break;
1379			case SYS_sched_setscheduler:
1380				print_number(ip, narg, c);
1381				putchar(',');
1382				print_integer_arg(sysdecode_scheduler_policy,
1383				    *ip);
1384				ip++;
1385				narg--;
1386				break;
1387			case SYS_sched_get_priority_max:
1388			case SYS_sched_get_priority_min:
1389				putchar('(');
1390				print_integer_arg(sysdecode_scheduler_policy,
1391				    *ip);
1392				ip++;
1393				narg--;
1394				break;
1395			case SYS_sendfile:
1396				print_number(ip, narg, c);
1397				print_number(ip, narg, c);
1398				print_number(ip, narg, c);
1399				print_number(ip, narg, c);
1400				print_number(ip, narg, c);
1401				print_number(ip, narg, c);
1402				putchar(',');
1403				print_mask_arg(sysdecode_sendfile_flags, *ip);
1404				ip++;
1405				narg--;
1406				break;
1407			case SYS_kldsym:
1408				print_number(ip, narg, c);
1409				putchar(',');
1410				print_integer_arg(sysdecode_kldsym_cmd, *ip);
1411				ip++;
1412				narg--;
1413				break;
1414			case SYS_sigprocmask:
1415				putchar('(');
1416				print_integer_arg(sysdecode_sigprocmask_how,
1417				    *ip);
1418				ip++;
1419				narg--;
1420				c = ',';
1421				break;
1422			case SYS___acl_get_file:
1423			case SYS___acl_set_file:
1424			case SYS___acl_get_fd:
1425			case SYS___acl_set_fd:
1426			case SYS___acl_delete_file:
1427			case SYS___acl_delete_fd:
1428			case SYS___acl_aclcheck_file:
1429			case SYS___acl_aclcheck_fd:
1430			case SYS___acl_get_link:
1431			case SYS___acl_set_link:
1432			case SYS___acl_delete_link:
1433			case SYS___acl_aclcheck_link:
1434				print_number(ip, narg, c);
1435				putchar(',');
1436				print_integer_arg(sysdecode_acltype, *ip);
1437				ip++;
1438				narg--;
1439				break;
1440			case SYS_sigaction:
1441				putchar('(');
1442				print_signal(*ip);
1443				ip++;
1444				narg--;
1445				c = ',';
1446				break;
1447			case SYS_extattrctl:
1448				print_number(ip, narg, c);
1449				putchar(',');
1450				print_integer_arg(sysdecode_extattrnamespace,
1451				    *ip);
1452				ip++;
1453				narg--;
1454				break;
1455			case SYS_nmount:
1456				print_number(ip, narg, c);
1457				print_number(ip, narg, c);
1458				putchar(',');
1459				print_mask_arg0(sysdecode_mount_flags, *ip);
1460				ip++;
1461				narg--;
1462				break;
1463			case SYS_thr_create:
1464				print_number(ip, narg, c);
1465				print_number(ip, narg, c);
1466				putchar(',');
1467				print_mask_arg(sysdecode_thr_create_flags, *ip);
1468				ip++;
1469				narg--;
1470				break;
1471			case SYS_thr_kill:
1472				print_number(ip, narg, c);
1473				putchar(',');
1474				print_signal(*ip);
1475				ip++;
1476				narg--;
1477				break;
1478			case SYS_kldunloadf:
1479				print_number(ip, narg, c);
1480				putchar(',');
1481				print_integer_arg(sysdecode_kldunload_flags,
1482				    *ip);
1483				ip++;
1484				narg--;
1485				break;
1486			case SYS_linkat:
1487			case SYS_renameat:
1488			case SYS_symlinkat:
1489				print_number(ip, narg, c);
1490				putchar(',');
1491				print_integer_arg_valid(sysdecode_atfd, *ip);
1492				ip++;
1493				narg--;
1494				print_number(ip, narg, c);
1495				break;
1496			case SYS_cap_fcntls_limit:
1497				print_number(ip, narg, c);
1498				putchar(',');
1499				arg = *ip;
1500				ip++;
1501				narg--;
1502				print_mask_arg32(sysdecode_cap_fcntlrights, arg);
1503				break;
1504			case SYS_posix_fadvise:
1505				print_number(ip, narg, c);
1506				print_number(ip, narg, c);
1507				print_number(ip, narg, c);
1508				(void)putchar(',');
1509				print_integer_arg(sysdecode_fadvice, *ip);
1510				ip++;
1511				narg--;
1512				break;
1513			case SYS_procctl:
1514				putchar('(');
1515				print_integer_arg(sysdecode_idtype, *ip);
1516				c = ',';
1517				ip++;
1518				narg--;
1519				print_number64(first, ip, narg, c);
1520				putchar(',');
1521				print_integer_arg(sysdecode_procctl_cmd, *ip);
1522				ip++;
1523				narg--;
1524				break;
1525			case SYS__umtx_op: {
1526				int op;
1527
1528				print_number(ip, narg, c);
1529				putchar(',');
1530				if (print_mask_arg_part(sysdecode_umtx_op_flags,
1531				    *ip, &op))
1532					putchar('|');
1533				print_integer_arg(sysdecode_umtx_op, op);
1534				putchar('>');
1535				switch (*ip) {
1536				case UMTX_OP_CV_WAIT:
1537					ip++;
1538					narg--;
1539					putchar(',');
1540					print_mask_argul(
1541					    sysdecode_umtx_cvwait_flags, *ip);
1542					break;
1543				case UMTX_OP_RW_RDLOCK:
1544					ip++;
1545					narg--;
1546					putchar(',');
1547					print_mask_argul(
1548					    sysdecode_umtx_rwlock_flags, *ip);
1549					break;
1550				}
1551				ip++;
1552				narg--;
1553				break;
1554			}
1555			case SYS_ftruncate:
1556			case SYS_truncate:
1557				print_number(ip, narg, c);
1558				print_number64(first, ip, narg, c);
1559				break;
1560			case SYS_fchownat:
1561				print_number(ip, narg, c);
1562				print_number(ip, narg, c);
1563				print_number(ip, narg, c);
1564				break;
1565			case SYS_fstatat:
1566			case SYS_utimensat:
1567				print_number(ip, narg, c);
1568				print_number(ip, narg, c);
1569				break;
1570			case SYS_unlinkat:
1571				print_number(ip, narg, c);
1572				break;
1573			case SYS_sysarch:
1574				putchar('(');
1575				print_integer_arg(sysdecode_sysarch_number, *ip);
1576				ip++;
1577				narg--;
1578				c = ',';
1579				break;
1580			case SYS_getitimer:
1581			case SYS_setitimer:
1582				putchar('(');
1583				print_integer_arg(sysdecode_itimer, *ip);
1584				ip++;
1585				narg--;
1586				c = ',';
1587				break;
1588			}
1589			switch (ktr->ktr_code) {
1590			case SYS_chflagsat:
1591			case SYS_fchownat:
1592			case SYS_faccessat:
1593			case SYS_fchmodat:
1594			case SYS_fstatat:
1595			case SYS_linkat:
1596			case SYS_unlinkat:
1597			case SYS_utimensat:
1598				putchar(',');
1599				print_mask_arg0(sysdecode_atflags, *ip);
1600				ip++;
1601				narg--;
1602				break;
1603			}
1604	*resc = c;
1605	*resip = ip;
1606	*resnarg = narg;
1607}
1608
1609void
1610ktrsysret(struct ktr_sysret *ktr, u_int sv_flags)
1611{
1612	register_t ret = ktr->ktr_retval;
1613	int error = ktr->ktr_error;
1614
1615	syscallname(ktr->ktr_code, sv_flags);
1616	printf(" ");
1617
1618	if (error == 0) {
1619		if (fancy) {
1620			printf("%ld", (long)ret);
1621			if (ret < 0 || ret > 9)
1622				printf("/%#lx", (unsigned long)ret);
1623		} else {
1624			if (decimal)
1625				printf("%ld", (long)ret);
1626			else
1627				printf("%#lx", (unsigned long)ret);
1628		}
1629	} else if (error == ERESTART)
1630		printf("RESTART");
1631	else if (error == EJUSTRETURN)
1632		printf("JUSTRETURN");
1633	else {
1634		printf("-1 errno %d", sysdecode_freebsd_to_abi_errno(
1635		    syscallabi(sv_flags), error));
1636		if (fancy)
1637			printf(" %s", strerror(ktr->ktr_error));
1638	}
1639	putchar('\n');
1640}
1641
1642void
1643ktrnamei(char *cp, int len)
1644{
1645	printf("\"%.*s\"\n", len, cp);
1646}
1647
1648void
1649hexdump(char *p, int len, int screenwidth)
1650{
1651	int n, i;
1652	int width;
1653
1654	width = 0;
1655	do {
1656		width += 2;
1657		i = 13;			/* base offset */
1658		i += (width / 2) + 1;	/* spaces every second byte */
1659		i += (width * 2);	/* width of bytes */
1660		i += 3;			/* "  |" */
1661		i += width;		/* each byte */
1662		i += 1;			/* "|" */
1663	} while (i < screenwidth);
1664	width -= 2;
1665
1666	for (n = 0; n < len; n += width) {
1667		for (i = n; i < n + width; i++) {
1668			if ((i % width) == 0) {	/* beginning of line */
1669				printf("       0x%04x", i);
1670			}
1671			if ((i % 2) == 0) {
1672				printf(" ");
1673			}
1674			if (i < len)
1675				printf("%02x", p[i] & 0xff);
1676			else
1677				printf("  ");
1678		}
1679		printf("  |");
1680		for (i = n; i < n + width; i++) {
1681			if (i >= len)
1682				break;
1683			if (p[i] >= ' ' && p[i] <= '~')
1684				printf("%c", p[i]);
1685			else
1686				printf(".");
1687		}
1688		printf("|\n");
1689	}
1690	if ((i % width) != 0)
1691		printf("\n");
1692}
1693
1694void
1695visdump(char *dp, int datalen, int screenwidth)
1696{
1697	int col = 0;
1698	char *cp;
1699	int width;
1700	char visbuf[5];
1701
1702	printf("       \"");
1703	col = 8;
1704	for (;datalen > 0; datalen--, dp++) {
1705		vis(visbuf, *dp, VIS_CSTYLE | VIS_NOLOCALE, *(dp+1));
1706		cp = visbuf;
1707		/*
1708		 * Keep track of printables and
1709		 * space chars (like fold(1)).
1710		 */
1711		if (col == 0) {
1712			putchar('\t');
1713			col = 8;
1714		}
1715		switch(*cp) {
1716		case '\n':
1717			col = 0;
1718			putchar('\n');
1719			continue;
1720		case '\t':
1721			width = 8 - (col&07);
1722			break;
1723		default:
1724			width = strlen(cp);
1725		}
1726		if (col + width > (screenwidth-2)) {
1727			printf("\\\n\t");
1728			col = 8;
1729		}
1730		col += width;
1731		do {
1732			putchar(*cp++);
1733		} while (*cp);
1734	}
1735	if (col == 0)
1736		printf("       ");
1737	printf("\"\n");
1738}
1739
1740void
1741ktrgenio(struct ktr_genio *ktr, int len)
1742{
1743	int datalen = len - sizeof (struct ktr_genio);
1744	char *dp = (char *)ktr + sizeof (struct ktr_genio);
1745	static int screenwidth = 0;
1746	int i, binary;
1747
1748	printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1749		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1750		datalen == 1 ? "" : "s");
1751	if (suppressdata)
1752		return;
1753	if (screenwidth == 0) {
1754		struct winsize ws;
1755
1756		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1757		    ws.ws_col > 8)
1758			screenwidth = ws.ws_col;
1759		else
1760			screenwidth = 80;
1761	}
1762	if (maxdata && datalen > maxdata)
1763		datalen = maxdata;
1764
1765	for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1766		if (dp[i] >= 32 && dp[i] < 127)
1767			continue;
1768		if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1769			continue;
1770		binary = 1;
1771	}
1772	if (binary)
1773		hexdump(dp, datalen, screenwidth);
1774	else
1775		visdump(dp, datalen, screenwidth);
1776}
1777
1778void
1779ktrpsig(struct ktr_psig *psig)
1780{
1781	const char *str;
1782
1783	print_signal(psig->signo);
1784	if (psig->action == SIG_DFL) {
1785		printf(" SIG_DFL");
1786	} else {
1787		printf(" caught handler=0x%lx mask=0x%x",
1788		    (u_long)psig->action, psig->mask.__bits[0]);
1789	}
1790	printf(" code=");
1791	str = sysdecode_sigcode(psig->signo, psig->code);
1792	if (str != NULL)
1793		printf("%s", str);
1794	else
1795		printf("<invalid=%#x>", psig->code);
1796	putchar('\n');
1797}
1798
1799void
1800ktrcsw_old(struct ktr_csw_old *cs)
1801{
1802	printf("%s %s\n", cs->out ? "stop" : "resume",
1803		cs->user ? "user" : "kernel");
1804}
1805
1806void
1807ktrcsw(struct ktr_csw *cs)
1808{
1809	printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume",
1810	    cs->user ? "user" : "kernel", cs->wmesg);
1811}
1812
1813void
1814ktruser(int len, void *p)
1815{
1816	unsigned char *cp;
1817
1818	if (sysdecode_utrace(stdout, p, len)) {
1819		printf("\n");
1820		return;
1821	}
1822
1823	printf("%d ", len);
1824	cp = p;
1825	while (len--)
1826		if (decimal)
1827			printf(" %d", *cp++);
1828		else
1829			printf(" %02x", *cp++);
1830	printf("\n");
1831}
1832
1833void
1834ktrcaprights(cap_rights_t *rightsp)
1835{
1836
1837	printf("cap_rights_t ");
1838	sysdecode_cap_rights(stdout, rightsp);
1839	printf("\n");
1840}
1841
1842static void
1843ktrtimeval(struct timeval *tv)
1844{
1845
1846	printf("{%ld, %ld}", (long)tv->tv_sec, tv->tv_usec);
1847}
1848
1849void
1850ktritimerval(struct itimerval *it)
1851{
1852
1853	printf("itimerval { .interval = ");
1854	ktrtimeval(&it->it_interval);
1855	printf(", .value = ");
1856	ktrtimeval(&it->it_value);
1857	printf(" }\n");
1858}
1859
1860void
1861ktrsockaddr(struct sockaddr *sa)
1862{
1863/*
1864 TODO: Support additional address families
1865	#include <netsmb/netbios.h>
1866	struct sockaddr_nb	*nb;
1867*/
1868	const char *str;
1869	char addr[64];
1870
1871	/*
1872	 * note: ktrstruct() has already verified that sa points to a
1873	 * buffer at least sizeof(struct sockaddr) bytes long and exactly
1874	 * sa->sa_len bytes long.
1875	 */
1876	printf("struct sockaddr { ");
1877	str = sysdecode_sockaddr_family(sa->sa_family);
1878	if (str != NULL)
1879		printf("%s", str);
1880	else
1881		printf("<invalid=%d>", sa->sa_family);
1882	printf(", ");
1883
1884#define check_sockaddr_len(n)					\
1885	if (sa_##n.s##n##_len < sizeof(struct sockaddr_##n)) {	\
1886		printf("invalid");				\
1887		break;						\
1888	}
1889
1890	switch(sa->sa_family) {
1891	case AF_INET: {
1892		struct sockaddr_in sa_in;
1893
1894		memset(&sa_in, 0, sizeof(sa_in));
1895		memcpy(&sa_in, sa, sa->sa_len);
1896		check_sockaddr_len(in);
1897		inet_ntop(AF_INET, &sa_in.sin_addr, addr, sizeof addr);
1898		printf("%s:%u", addr, ntohs(sa_in.sin_port));
1899		break;
1900	}
1901	case AF_INET6: {
1902		struct sockaddr_in6 sa_in6;
1903
1904		memset(&sa_in6, 0, sizeof(sa_in6));
1905		memcpy(&sa_in6, sa, sa->sa_len);
1906		check_sockaddr_len(in6);
1907		getnameinfo((struct sockaddr *)&sa_in6, sizeof(sa_in6),
1908		    addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
1909		printf("[%s]:%u", addr, htons(sa_in6.sin6_port));
1910		break;
1911	}
1912	case AF_UNIX: {
1913		struct sockaddr_un sa_un;
1914
1915		memset(&sa_un, 0, sizeof(sa_un));
1916		memcpy(&sa_un, sa, sa->sa_len);
1917		printf("%.*s", (int)sizeof(sa_un.sun_path), sa_un.sun_path);
1918		break;
1919	}
1920	default:
1921		printf("unknown address family");
1922	}
1923	printf(" }\n");
1924}
1925
1926void
1927ktrstat(struct stat *statp)
1928{
1929	char mode[12], timestr[PATH_MAX + 4];
1930	struct passwd *pwd;
1931	struct group  *grp;
1932	struct tm *tm;
1933
1934	/*
1935	 * note: ktrstruct() has already verified that statp points to a
1936	 * buffer exactly sizeof(struct stat) bytes long.
1937	 */
1938	printf("struct stat {");
1939	printf("dev=%ju, ino=%ju, ",
1940		(uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino);
1941	if (!resolv)
1942		printf("mode=0%jo, ", (uintmax_t)statp->st_mode);
1943	else {
1944		strmode(statp->st_mode, mode);
1945		printf("mode=%s, ", mode);
1946	}
1947	printf("nlink=%ju, ", (uintmax_t)statp->st_nlink);
1948	if (!resolv) {
1949		pwd = NULL;
1950	} else {
1951#ifdef WITH_CASPER
1952		if (cappwd != NULL)
1953			pwd = cap_getpwuid(cappwd, statp->st_uid);
1954		else
1955#endif
1956			pwd = getpwuid(statp->st_uid);
1957	}
1958	if (pwd == NULL)
1959		printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1960	else
1961		printf("uid=\"%s\", ", pwd->pw_name);
1962	if (!resolv) {
1963		grp = NULL;
1964	} else {
1965#ifdef WITH_CASPER
1966		if (capgrp != NULL)
1967			grp = cap_getgrgid(capgrp, statp->st_gid);
1968		else
1969#endif
1970			grp = getgrgid(statp->st_gid);
1971	}
1972	if (grp == NULL)
1973		printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1974	else
1975		printf("gid=\"%s\", ", grp->gr_name);
1976	printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1977	printf("atime=");
1978	if (!resolv)
1979		printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1980	else {
1981		tm = localtime(&statp->st_atim.tv_sec);
1982		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1983		printf("\"%s\"", timestr);
1984	}
1985	if (statp->st_atim.tv_nsec != 0)
1986		printf(".%09ld, ", statp->st_atim.tv_nsec);
1987	else
1988		printf(", ");
1989	printf("mtime=");
1990	if (!resolv)
1991		printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1992	else {
1993		tm = localtime(&statp->st_mtim.tv_sec);
1994		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1995		printf("\"%s\"", timestr);
1996	}
1997	if (statp->st_mtim.tv_nsec != 0)
1998		printf(".%09ld, ", statp->st_mtim.tv_nsec);
1999	else
2000		printf(", ");
2001	printf("ctime=");
2002	if (!resolv)
2003		printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
2004	else {
2005		tm = localtime(&statp->st_ctim.tv_sec);
2006		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
2007		printf("\"%s\"", timestr);
2008	}
2009	if (statp->st_ctim.tv_nsec != 0)
2010		printf(".%09ld, ", statp->st_ctim.tv_nsec);
2011	else
2012		printf(", ");
2013	printf("birthtime=");
2014	if (!resolv)
2015		printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
2016	else {
2017		tm = localtime(&statp->st_birthtim.tv_sec);
2018		strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
2019		printf("\"%s\"", timestr);
2020	}
2021	if (statp->st_birthtim.tv_nsec != 0)
2022		printf(".%09ld, ", statp->st_birthtim.tv_nsec);
2023	else
2024		printf(", ");
2025	printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
2026		(uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
2027		(intmax_t)statp->st_blocks, statp->st_flags);
2028	printf(" }\n");
2029}
2030
2031void
2032ktrbitset(char *name, struct bitset *set, size_t setlen)
2033{
2034	int i, maxi, c = 0;
2035
2036	if (setlen > INT32_MAX)
2037		setlen = INT32_MAX;
2038	maxi = setlen * CHAR_BIT;
2039	printf("%s [ ", name);
2040	for (i = 0; i < maxi; i++) {
2041		if (!BIT_ISSET(setlen, i, set))
2042			continue;
2043		if (c == 0)
2044			printf("%d", i);
2045		else
2046			printf(", %d", i);
2047		c++;
2048	}
2049	if (c == 0)
2050		printf(" empty ]\n");
2051	else
2052		printf(" ]\n");
2053}
2054
2055void
2056ktrstruct(char *buf, size_t buflen)
2057{
2058	char *name, *data;
2059	size_t namelen, datalen;
2060	int i;
2061	cap_rights_t rights;
2062	struct itimerval it;
2063	struct stat sb;
2064	struct sockaddr_storage ss;
2065	struct bitset *set;
2066
2067	for (name = buf, namelen = 0;
2068	     namelen < buflen && name[namelen] != '\0';
2069	     ++namelen)
2070		/* nothing */;
2071	if (namelen == buflen)
2072		goto invalid;
2073	if (name[namelen] != '\0')
2074		goto invalid;
2075	data = buf + namelen + 1;
2076	datalen = buflen - namelen - 1;
2077	if (datalen == 0)
2078		goto invalid;
2079	/* sanity check */
2080	for (i = 0; i < (int)namelen; ++i)
2081		if (!isalpha(name[i]) && name[i] != '_')
2082			goto invalid;
2083	if (strcmp(name, "caprights") == 0) {
2084		if (datalen != sizeof(cap_rights_t))
2085			goto invalid;
2086		memcpy(&rights, data, datalen);
2087		ktrcaprights(&rights);
2088	} else if (strcmp(name, "itimerval") == 0) {
2089		if (datalen != sizeof(struct itimerval))
2090			goto invalid;
2091		memcpy(&it, data, datalen);
2092		ktritimerval(&it);
2093	} else if (strcmp(name, "stat") == 0) {
2094		if (datalen != sizeof(struct stat))
2095			goto invalid;
2096		memcpy(&sb, data, datalen);
2097		ktrstat(&sb);
2098	} else if (strcmp(name, "sockaddr") == 0) {
2099		if (datalen > sizeof(ss))
2100			goto invalid;
2101		memcpy(&ss, data, datalen);
2102		if (datalen != ss.ss_len)
2103			goto invalid;
2104		ktrsockaddr((struct sockaddr *)&ss);
2105	} else if (strcmp(name, "cpuset_t") == 0) {
2106		if (datalen < 1)
2107			goto invalid;
2108		set = malloc(datalen);
2109		if (set == NULL)
2110			errx(1, "%s", strerror(ENOMEM));
2111		memcpy(set, data, datalen);
2112		ktrbitset(name, set, datalen);
2113		free(set);
2114	} else {
2115#ifdef SYSDECODE_HAVE_LINUX
2116		if (ktrstruct_linux(name, data, datalen) == false)
2117#endif
2118			printf("unknown structure\n");
2119	}
2120	return;
2121invalid:
2122	printf("invalid record\n");
2123}
2124
2125void
2126ktrcapfail(struct ktr_cap_fail *ktr)
2127{
2128	union ktr_cap_data *kcd = &ktr->cap_data;
2129
2130	switch (ktr->cap_type) {
2131	case CAPFAIL_NOTCAPABLE:
2132		/* operation on fd with insufficient capabilities */
2133		printf("operation requires ");
2134		sysdecode_cap_rights(stdout, &kcd->cap_needed);
2135		printf(", descriptor holds ");
2136		sysdecode_cap_rights(stdout, &kcd->cap_held);
2137		break;
2138	case CAPFAIL_INCREASE:
2139		/* requested more capabilities than fd already has */
2140		printf("attempt to increase capabilities from ");
2141		sysdecode_cap_rights(stdout, &kcd->cap_held);
2142		printf(" to ");
2143		sysdecode_cap_rights(stdout, &kcd->cap_needed);
2144		break;
2145	case CAPFAIL_SYSCALL:
2146		/* called restricted syscall */
2147		printf("system call not allowed: ");
2148		syscallname(ktr->cap_code, ktr->cap_svflags);
2149		if (syscallabi(ktr->cap_svflags) == SYSDECODE_ABI_FREEBSD) {
2150			switch (ktr->cap_code) {
2151			case SYS_sysarch:
2152				printf(", op: ");
2153				print_integer_arg(sysdecode_sysarch_number,
2154				    kcd->cap_int);
2155				break;
2156			case SYS_fcntl:
2157				printf(", cmd: ");
2158				print_integer_arg(sysdecode_fcntl_cmd,
2159				    kcd->cap_int);
2160				break;
2161			}
2162		}
2163		break;
2164	case CAPFAIL_SIGNAL:
2165		/* sent signal to proc other than self */
2166		syscallname(ktr->cap_code, ktr->cap_svflags);
2167		printf(": signal delivery not allowed: ");
2168		print_integer_arg(sysdecode_signal, kcd->cap_int);
2169		break;
2170	case CAPFAIL_PROTO:
2171		/* created socket with restricted protocol */
2172		syscallname(ktr->cap_code, ktr->cap_svflags);
2173		printf(": protocol not allowed: ");
2174		print_integer_arg(sysdecode_ipproto, kcd->cap_int);
2175		break;
2176	case CAPFAIL_SOCKADDR:
2177		/* unable to look up address */
2178		syscallname(ktr->cap_code, ktr->cap_svflags);
2179		printf(": restricted address lookup: ");
2180		ktrsockaddr(&kcd->cap_sockaddr);
2181		return;
2182	case CAPFAIL_NAMEI:
2183		/* absolute or AT_FDCWD path, ".." path, etc. */
2184		syscallname(ktr->cap_code, ktr->cap_svflags);
2185		printf(": restricted VFS lookup: %s\n", kcd->cap_path);
2186		return;
2187	case CAPFAIL_CPUSET:
2188		/* modification of an external cpuset */
2189		syscallname(ktr->cap_code, ktr->cap_svflags);
2190		printf(": restricted cpuset operation\n");
2191		return;
2192	default:
2193		syscallname(ktr->cap_code, ktr->cap_svflags);
2194		printf(": unknown capability failure\n");
2195		return;
2196	}
2197	printf("\n");
2198}
2199
2200void
2201ktrfault(struct ktr_fault *ktr)
2202{
2203
2204	printf("0x%jx ", (uintmax_t)ktr->vaddr);
2205	print_mask_arg(sysdecode_vmprot, ktr->type);
2206	printf("\n");
2207}
2208
2209void
2210ktrfaultend(struct ktr_faultend *ktr)
2211{
2212	const char *str;
2213
2214	str = sysdecode_vmresult(ktr->result);
2215	if (str != NULL)
2216		printf("%s", str);
2217	else
2218		printf("<invalid=%d>", ktr->result);
2219	printf("\n");
2220}
2221
2222void
2223ktrkevent(struct kevent *kev)
2224{
2225
2226	printf("{ ident=");
2227	switch (kev->filter) {
2228	case EVFILT_READ:
2229	case EVFILT_WRITE:
2230	case EVFILT_VNODE:
2231	case EVFILT_PROC:
2232	case EVFILT_TIMER:
2233	case EVFILT_PROCDESC:
2234	case EVFILT_EMPTY:
2235		printf("%ju", (uintmax_t)kev->ident);
2236		break;
2237	case EVFILT_SIGNAL:
2238		print_signal(kev->ident);
2239		break;
2240	default:
2241		printf("%p", (void *)kev->ident);
2242	}
2243	printf(", filter=");
2244	print_integer_arg(sysdecode_kevent_filter, kev->filter);
2245	printf(", flags=");
2246	print_mask_arg0(sysdecode_kevent_flags, kev->flags);
2247	printf(", fflags=");
2248	sysdecode_kevent_fflags(stdout, kev->filter, kev->fflags,
2249	    decimal ? 10 : 16);
2250	printf(", data=%#jx, udata=%p }", (uintmax_t)kev->data, kev->udata);
2251}
2252
2253void
2254ktrpollfd(struct pollfd *pfd)
2255{
2256
2257	printf("{ fd=%d", pfd->fd);
2258	printf(", events=");
2259	print_mask_arg0(sysdecode_pollfd_events, pfd->events);
2260	printf(", revents=");
2261	print_mask_arg0(sysdecode_pollfd_events, pfd->revents);
2262	printf("}");
2263}
2264
2265void
2266ktrstructarray(struct ktr_struct_array *ksa, size_t buflen)
2267{
2268	struct kevent kev;
2269	struct pollfd pfd;
2270	char *name, *data;
2271	size_t namelen, datalen;
2272	int i;
2273	bool first;
2274
2275	buflen -= sizeof(*ksa);
2276	for (name = (char *)(ksa + 1), namelen = 0;
2277	     namelen < buflen && name[namelen] != '\0';
2278	     ++namelen)
2279		/* nothing */;
2280	if (namelen == buflen)
2281		goto invalid;
2282	if (name[namelen] != '\0')
2283		goto invalid;
2284	/* sanity check */
2285	for (i = 0; i < (int)namelen; ++i)
2286		if (!isalnum(name[i]) && name[i] != '_')
2287			goto invalid;
2288	data = name + namelen + 1;
2289	datalen = buflen - namelen - 1;
2290	printf("struct %s[] = { ", name);
2291	first = true;
2292	for (; datalen >= ksa->struct_size;
2293	    data += ksa->struct_size, datalen -= ksa->struct_size) {
2294		if (!first)
2295			printf("\n             ");
2296		else
2297			first = false;
2298		if (strcmp(name, "kevent") == 0) {
2299			if (ksa->struct_size != sizeof(kev))
2300				goto bad_size;
2301			memcpy(&kev, data, sizeof(kev));
2302			ktrkevent(&kev);
2303		} else if (strcmp(name, "freebsd11_kevent") == 0) {
2304			struct freebsd11_kevent kev11;
2305
2306			if (ksa->struct_size != sizeof(kev11))
2307				goto bad_size;
2308			memcpy(&kev11, data, sizeof(kev11));
2309			memset(&kev, 0, sizeof(kev));
2310			kev.ident = kev11.ident;
2311			kev.filter = kev11.filter;
2312			kev.flags = kev11.flags;
2313			kev.fflags = kev11.fflags;
2314			kev.data = kev11.data;
2315			kev.udata = kev11.udata;
2316			ktrkevent(&kev);
2317#ifdef _WANT_KEVENT32
2318		} else if (strcmp(name, "kevent32") == 0) {
2319			struct kevent32 kev32;
2320
2321			if (ksa->struct_size != sizeof(kev32))
2322				goto bad_size;
2323			memcpy(&kev32, data, sizeof(kev32));
2324			memset(&kev, 0, sizeof(kev));
2325			kev.ident = kev32.ident;
2326			kev.filter = kev32.filter;
2327			kev.flags = kev32.flags;
2328			kev.fflags = kev32.fflags;
2329#if BYTE_ORDER == BIG_ENDIAN
2330			kev.data = kev32.data2 | ((int64_t)kev32.data1 << 32);
2331#else
2332			kev.data = kev32.data1 | ((int64_t)kev32.data2 << 32);
2333#endif
2334			kev.udata = (void *)(uintptr_t)kev32.udata;
2335			ktrkevent(&kev);
2336		} else if (strcmp(name, "freebsd11_kevent32") == 0) {
2337			struct freebsd11_kevent32 kev32;
2338
2339			if (ksa->struct_size != sizeof(kev32))
2340				goto bad_size;
2341			memcpy(&kev32, data, sizeof(kev32));
2342			memset(&kev, 0, sizeof(kev));
2343			kev.ident = kev32.ident;
2344			kev.filter = kev32.filter;
2345			kev.flags = kev32.flags;
2346			kev.fflags = kev32.fflags;
2347			kev.data = kev32.data;
2348			kev.udata = (void *)(uintptr_t)kev32.udata;
2349			ktrkevent(&kev);
2350#endif
2351		} else if (strcmp(name, "pollfd") == 0) {
2352			if (ksa->struct_size != sizeof(pfd))
2353				goto bad_size;
2354			memcpy(&pfd, data, sizeof(pfd));
2355			ktrpollfd(&pfd);
2356		} else {
2357			printf("<unknown structure> }\n");
2358			return;
2359		}
2360	}
2361	printf(" }\n");
2362	return;
2363invalid:
2364	printf("invalid record\n");
2365	return;
2366bad_size:
2367	printf("<bad size> }\n");
2368	return;
2369}
2370
2371void
2372usage(void)
2373{
2374	fprintf(stderr, "usage: kdump [-dEnlHRrSsTA] [-f trfile] "
2375	    "[-m maxdata] [-p pid] [-t trstr]\n");
2376	exit(1);
2377}
2378