GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/kdump/kdump.c Lines: 196 585 33.5 %
Date: 2016-12-06 Branches: 109 470 23.2 %

Line Branch Exec Source
1
/*	$OpenBSD: kdump.c,v 1.129 2016/07/18 09:36:50 guenther Exp $	*/
2
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
#include <sys/param.h>	/* MAXCOMLEN nitems */
33
#include <sys/time.h>
34
#include <sys/signal.h>
35
#include <sys/uio.h>
36
#include <sys/ktrace.h>
37
#include <sys/ioctl.h>
38
#include <sys/malloc.h>
39
#include <sys/namei.h>
40
#include <sys/ptrace.h>
41
#include <sys/sem.h>
42
#include <sys/shm.h>
43
#include <sys/socket.h>
44
#include <sys/sysctl.h>
45
#include <sys/siginfo.h>
46
#include <sys/vmmeter.h>
47
#include <sys/tty.h>
48
#include <sys/wait.h>
49
#define PLEDGENAMES
50
#include <sys/pledge.h>
51
#undef PLEDGENAMES
52
#define _KERNEL
53
#include <errno.h>
54
#undef _KERNEL
55
#include <ddb/db_var.h>
56
#include <machine/cpu.h>
57
58
#include <ctype.h>
59
#include <err.h>
60
#include <fcntl.h>
61
#include <limits.h>
62
#include <netdb.h>
63
#include <poll.h>
64
#include <signal.h>
65
#include <stdio.h>
66
#include <stdlib.h>
67
#include <stdint.h>
68
#include <string.h>
69
#include <unistd.h>
70
#include <vis.h>
71
72
#include "ktrace.h"
73
#include "kdump.h"
74
#include "kdump_subr.h"
75
#include "extern.h"
76
77
int timestamp, decimal, iohex, fancy = 1, maxdata = INT_MAX;
78
int needtid, tail, basecol;
79
char *tracefile = DEF_TRACEFILE;
80
struct ktr_header ktr_header;
81
pid_t pid_opt = -1;
82
83
#define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
84
85
#include <sys/syscall.h>
86
87
#define KTRACE
88
#define PTRACE
89
#define NFSCLIENT
90
#define NFSSERVER
91
#define SYSVSEM
92
#define SYSVMSG
93
#define SYSVSHM
94
#define ACCOUNTING
95
#include <kern/syscalls.c>
96
#undef KTRACE
97
#undef PTRACE
98
#undef NFSCLIENT
99
#undef NFSSERVER
100
#undef SYSVSEM
101
#undef SYSVMSG
102
#undef SYSVSHM
103
#undef ACCOUNTING
104
105
106
static char *ptrace_ops[] = {
107
	"PT_TRACE_ME",	"PT_READ_I",	"PT_READ_D",	"PT_READ_U",
108
	"PT_WRITE_I",	"PT_WRITE_D",	"PT_WRITE_U",	"PT_CONTINUE",
109
	"PT_KILL",	"PT_ATTACH",	"PT_DETACH",	"PT_IO",
110
	"PT_SET_EVENT_MASK", "PT_GET_EVENT_MASK", "PT_GET_PROCESS_STATE",
111
	"PT_GET_THREAD_FIRST", "PT_GET_THREAD_NEXT",
112
};
113
114
static int fread_tail(void *, size_t, size_t);
115
static void dumpheader(struct ktr_header *);
116
static void ktrgenio(struct ktr_genio *, size_t);
117
static void ktrnamei(const char *, size_t);
118
static void ktrpsig(struct ktr_psig *);
119
static void ktrsyscall(struct ktr_syscall *, size_t);
120
static const char *kresolvsysctl(int, const int *);
121
static void ktrsysret(struct ktr_sysret *, size_t);
122
static void ktruser(struct ktr_user *, size_t);
123
static void ktrexec(const char*, size_t);
124
static void ktrpledge(struct ktr_pledge *, size_t);
125
static void usage(void);
126
static void ioctldecode(int);
127
static void ptracedecode(int);
128
static void atfd(int);
129
static void polltimeout(int);
130
static void wait4pid(int);
131
static void signame(int);
132
static void semctlname(int);
133
static void shmctlname(int);
134
static void semgetname(int);
135
static void flagsandmodename(int);
136
static void clockname(int);
137
static void sockoptlevelname(int);
138
static void ktraceopname(int);
139
140
static int screenwidth;
141
142
int
143
main(int argc, char *argv[])
144
1
{
145
	int ch, silent;
146
	size_t ktrlen, size;
147
1
	int trpoints = ALL_POINTS;
148
	const char *errstr;
149
	void *m;
150
151
1
	if (screenwidth == 0) {
152
		struct winsize ws;
153
154


2
		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
155
		    ws.ws_col > 8)
156
1
			screenwidth = ws.ws_col;
157
		else
158
			screenwidth = 80;
159
	}
160
161
1
	while ((ch = getopt(argc, argv, "f:dHlm:np:RTt:xX")) != -1)
162
		switch (ch) {
163
		case 'f':
164
			tracefile = optarg;
165
			break;
166
		case 'd':
167
			decimal = 1;
168
			break;
169
		case 'H':
170
			needtid = 1;
171
			break;
172
		case 'l':
173
			tail = 1;
174
			break;
175
		case 'm':
176
			maxdata = strtonum(optarg, 0, INT_MAX, &errstr);
177
			if (errstr)
178
				errx(1, "-m %s: %s", optarg, errstr);
179
			break;
180
		case 'n':
181
			fancy = 0;
182
			break;
183
		case 'p':
184
			pid_opt = strtonum(optarg, 1, INT_MAX, &errstr);
185
			if (errstr)
186
				errx(1, "-p %s: %s", optarg, errstr);
187
			break;
188
		case 'R':	/* relative timestamp */
189
			timestamp = timestamp == 1 ? 3 : 2;
190
			break;
191
		case 'T':
192
			timestamp = timestamp == 2 ? 3 : 1;
193
			break;
194
		case 't':
195
			trpoints = getpoints(optarg, DEF_POINTS);
196
			if (trpoints < 0)
197
				errx(1, "unknown trace point in %s", optarg);
198
			break;
199
		case 'x':
200
			iohex = 1;
201
			break;
202
		case 'X':
203
			iohex = 2;
204
			break;
205
		default:
206
			usage();
207
		}
208
1
	if (argc > optind)
209
		usage();
210
211
1
	if (pledge("stdio rpath getpw wpath cpath", NULL) == -1)
212
		err(1, "pledge");
213
214
1
	m = malloc(size = 1025);
215
1
	if (m == NULL)
216
		err(1, NULL);
217
1
	if (!freopen(tracefile, "r", stdin))
218
		err(1, "%s", tracefile);
219
220

2
	if (fread_tail(&ktr_header, sizeof(struct ktr_header), 1) == 0 ||
221
1
	    ktr_header.ktr_type != htobe32(KTR_START))
222
		errx(1, "%s: not a dump", tracefile);
223
981
	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
224
980
		silent = 0;
225

980
		if (pid_opt != -1 && pid_opt != ktr_header.ktr_pid)
226
			silent = 1;
227

980
		if (silent == 0 && trpoints & (1<<ktr_header.ktr_type))
228
980
			dumpheader(&ktr_header);
229
980
		ktrlen = ktr_header.ktr_len;
230
980
		if (ktrlen > size) {
231
			void *newm;
232
233
1
			if (ktrlen == SIZE_MAX)
234
				errx(1, "data too long");
235
1
			newm = realloc(m, ktrlen+1);
236
1
			if (newm == NULL)
237
				err(1, "realloc");
238
1
			m = newm;
239
1
			size = ktrlen;
240
		}
241

980
		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
242
			errx(1, "data too short");
243
980
		if (silent)
244
			continue;
245
980
		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
246
			continue;
247


980
		switch (ktr_header.ktr_type) {
248
		case KTR_SYSCALL:
249
355
			ktrsyscall((struct ktr_syscall *)m, ktrlen);
250
355
			break;
251
		case KTR_SYSRET:
252
355
			ktrsysret((struct ktr_sysret *)m, ktrlen);
253
355
			break;
254
		case KTR_NAMEI:
255
136
			ktrnamei(m, ktrlen);
256
136
			break;
257
		case KTR_GENIO:
258
3
			ktrgenio((struct ktr_genio *)m, ktrlen);
259
3
			break;
260
		case KTR_PSIG:
261
			ktrpsig((struct ktr_psig *)m);
262
			break;
263
		case KTR_STRUCT:
264
130
			ktrstruct(m, ktrlen);
265
130
			break;
266
		case KTR_USER:
267
			ktruser(m, ktrlen);
268
			break;
269
		case KTR_EXECARGS:
270
		case KTR_EXECENV:
271
1
			ktrexec(m, ktrlen);
272
1
			break;
273
		case KTR_PLEDGE:
274
			ktrpledge((struct ktr_pledge *)m, ktrlen);
275
			break;
276
		default:
277
			printf("\n");
278
			break;
279
		}
280
980
		if (tail)
281
			(void)fflush(stdout);
282
	}
283
1
	exit(0);
284
}
285
286
static int
287
fread_tail(void *buf, size_t size, size_t num)
288
1962
{
289
	int i;
290
291

3924
	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
292
		(void)sleep(1);
293
		clearerr(stdin);
294
	}
295
1962
	return (i);
296
}
297
298
static void
299
dumpheader(struct ktr_header *kth)
300
980
{
301
	static struct timespec prevtime;
302
	char unknown[64], *type;
303
	struct timespec temp;
304
305


980
	switch (kth->ktr_type) {
306
	case KTR_SYSCALL:
307
355
		type = "CALL";
308
355
		break;
309
	case KTR_SYSRET:
310
355
		type = "RET ";
311
355
		break;
312
	case KTR_NAMEI:
313
136
		type = "NAMI";
314
136
		break;
315
	case KTR_GENIO:
316
3
		type = "GIO ";
317
3
		break;
318
	case KTR_PSIG:
319
		type = "PSIG";
320
		break;
321
	case KTR_STRUCT:
322
130
		type = "STRU";
323
130
		break;
324
	case KTR_USER:
325
		type = "USER";
326
		break;
327
	case KTR_EXECARGS:
328
1
		type = "ARGS";
329
1
		break;
330
	case KTR_EXECENV:
331
		type = "ENV ";
332
		break;
333
	case KTR_PLEDGE:
334
		type = "PLDG";
335
		break;
336
	default:
337
		/* htobe32() not guaranteed to work as case label */
338
		if (kth->ktr_type == htobe32(KTR_START)) {
339
			type = "STRT";
340
			break;
341
		}
342
		(void)snprintf(unknown, sizeof unknown, "UNKNOWN(%u)",
343
		    kth->ktr_type);
344
		type = unknown;
345
	}
346
347
980
	basecol = printf("%6ld", (long)kth->ktr_pid);
348
980
	if (needtid)
349
		basecol += printf("/%-7ld", (long)kth->ktr_tid);
350
980
	basecol += printf(" %-8.*s ", MAXCOMLEN, kth->ktr_comm);
351
980
	if (timestamp) {
352
		if (timestamp == 3) {
353
			if (prevtime.tv_sec == 0)
354
				prevtime = kth->ktr_time;
355
			timespecsub(&kth->ktr_time, &prevtime, &temp);
356
		} else if (timestamp == 2) {
357
			timespecsub(&kth->ktr_time, &prevtime, &temp);
358
			prevtime = kth->ktr_time;
359
		} else
360
			temp = kth->ktr_time;
361
		basecol += printf("%lld.%06ld ", (long long)temp.tv_sec,
362
		    temp.tv_nsec / 1000);
363
	}
364
980
	basecol += printf("%s  ", type);
365
980
}
366
367
/*
368
 * Base Formatters
369
 */
370
371
/* some syscalls have padding that shouldn't be shown */
372
static int
373
pad(long arg)
374
34
{
375
	/* nothing printed */
376
34
	return (1);
377
}
378
379
/* a formatter that just saves the argument for the next formatter */
380
int arg1;
381
static int
382
pass_two(long arg)
383
70
{
384
70
	arg1 = (int)arg;
385
386
	/* nothing printed */
387
70
	return (1);
388
}
389
390
static int
391
pdeclong(long arg)
392
{
393
	(void)printf("%ld", arg);
394
	return (0);
395
}
396
397
static int
398
pdeculong(long arg)
399
23
{
400
23
	(void)printf("%lu", arg);
401
23
	return (0);
402
}
403
404
static int
405
phexlong(long arg)
406
456
{
407
456
	(void)printf("%#lx", arg);
408
456
	return (0);
409
}
410
411
static int
412
pnonfancy(long arg)
413
{
414
	if (decimal)
415
		(void)printf("%ld", arg);
416
	else
417
		(void)printf("%#lx", arg);
418
	return (0);
419
}
420
421
static void
422
pdecint(int arg)
423
174
{
424
174
	(void)printf("%d", arg);
425
174
}
426
427
static void
428
pdecuint(int arg)
429
{
430
	(void)printf("%u", arg);
431
}
432
433
static void
434
phexint(int arg)
435
{
436
	(void)printf("%#x", arg);
437
}
438
439
static void
440
poctint(int arg)
441
{
442
	(void)printf("%#o", arg);
443
}
444
445
446
#ifdef __LP64__
447
448
/* on LP64, long long arguments are the same as long arguments */
449
#define Phexlonglong	Phexlong
450
#define phexll		NULL		/* not actually used on LP64 */
451
452
#else /* __LP64__ */
453
454
/* on ILP32, long long arguments are passed as two 32bit args */
455
#define Phexlonglong	PASS_LONGLONG, Phexll
456
457
static int
458
phexll(long arg2)
459
{
460
	long long val;
461
462
#if _BYTE_ORDER == _LITTLE_ENDIAN
463
	val = ((long long)arg2 << 32) | ((long long)arg1 & 0xffffffff);
464
#else
465
	val = ((long long)arg1 << 32) | ((long long)arg2 & 0xffffffff);
466
#endif
467
468
	if (fancy || !decimal)
469
		(void)printf("%#llx", val);
470
	else
471
		(void)printf("%lld", val);
472
	return (0);
473
}
474
475
#endif /* __LP64__ */
476
477
static int (*long_formatters[])(long) = {
478
	NULL,
479
	pdeclong,
480
	pdeculong,
481
	phexlong,
482
	pass_two,
483
	pass_two,
484
	phexll,
485
	pad,
486
	pnonfancy,
487
};
488
489
static void (*formatters[])(int) = {
490
	NULL,
491
	pdecint,
492
	phexint,
493
	poctint,
494
	pdecuint,
495
	ioctldecode,
496
	ptracedecode,
497
	atfd,
498
	polltimeout,
499
	wait4pid,
500
	signame,
501
	semctlname,
502
	shmctlname,
503
	semgetname,
504
	flagsandmodename,
505
	clockname,
506
	sockoptlevelname,
507
	ktraceopname,
508
	fcntlcmdname,
509
	modename,
510
	flagsname,
511
	openflagsname,
512
	atflagsname,
513
	accessmodename,
514
	mmapprotname,
515
	mmapflagsname,
516
	wait4optname,
517
	sendrecvflagsname,
518
	mountflagsname,
519
	rebootoptname,
520
	flockname,
521
	sockoptname,
522
	sockipprotoname,
523
	socktypename,
524
	sockflagsname,
525
	sockfamilyname,
526
	mlockallname,
527
	shmatname,
528
	whencename,
529
	pathconfname,
530
	rlimitname,
531
	shutdownhowname,
532
	prioname,
533
	madvisebehavname,
534
	msyncflagsname,
535
	clocktypename,
536
	rusagewho,
537
	sigactionflagname,
538
	sigprocmaskhowname,
539
	minheritname,
540
	quotactlname,
541
	sigill_name,
542
	sigtrap_name,
543
	sigemt_name,
544
	sigfpe_name,
545
	sigbus_name,
546
	sigsegv_name,
547
	sigchld_name,
548
	ktracefacname,
549
	itimername,
550
	sigset,
551
	uidname,
552
	gidname,
553
	syslogflagname,
554
};
555
556
enum {
557
	/* the end of the (known) arguments is recognized by the zero fill */
558
	end_of_args	=  0,
559
560
	/* negative are the negative of the index into long_formatters[] */
561
	Pdeclong	= -1,
562
	Pdeculong	= -2,
563
	Phexlong	= -3,
564
	PASS_TWO	= -4,
565
566
/* the remaining long formatters still get called when non-fancy (-n option) */
567
#define FMT_IS_NONFANCY(x)	((x) <= PASS_LONGLONG)
568
	PASS_LONGLONG	= -5,
569
	Phexll		= -6,
570
	PAD		= -7,
571
	Pnonfancy	= -8,
572
573
	/* positive values are the index into formatters[] */
574
	Pdecint		= 1,
575
	Phexint,
576
	Poctint,
577
	Pdecuint,
578
	Ioctldecode,
579
	Ptracedecode,
580
	Atfd,
581
	Polltimeout,
582
	Wait4pid,
583
	Signame,
584
	Semctlname,
585
	Shmctlname,
586
	Semgetname,
587
	Flagsandmodename,
588
	Clockname,
589
	Sockoptlevelname,
590
	Ktraceopname,
591
	Fcntlcmdname,
592
	Modename,
593
	Flagsname,
594
	Openflagsname,
595
	Atflagsname,
596
	Accessmodename,
597
	Mmapprotname,
598
	Mmapflagsname,
599
	Wait4optname,
600
	Sendrecvflagsname,
601
	Mountflagsname,
602
	Rebootoptname,
603
	Flockname,
604
	Sockoptname,
605
	Sockipprotoname,
606
	Socktypename,
607
	Sockflagsname,
608
	Sockfamilyname,
609
	Mlockallname,
610
	Shmatname,
611
	Whencename,
612
	Pathconfname,
613
	Rlimitname,
614
	Shutdownhowname,
615
	Prioname,
616
	Madvisebehavname,
617
	Msyncflagsname,
618
	Clocktypename,
619
	Rusagewho,
620
	Sigactionflagname,
621
	Sigprocmaskhowname,
622
	Minheritname,
623
	Quotactlname,
624
	Sigill_name,
625
	Sigtrap_name,
626
	Sigemt_name,
627
	Sigfpe_name,
628
	Sigbus_name,
629
	Sigsegv_name,
630
	Sigchld_name,
631
	Ktracefacname,
632
	Itimername,
633
	Sigset,
634
	Uidname,
635
	Gidname,
636
	Syslogflagname,
637
};
638
639
#define Pptr		Phexlong
640
#define	Psize		Pdeculong	/* size_t for small buffers */
641
#define	Pbigsize	Phexlong	/* size_t for I/O buffers */
642
#define Pcount		Pdecint		/* int for a count of something */
643
#define Pfd		Pdecint
644
#define Ppath		Phexlong
645
#define Pdev_t		Pdecint
646
#define Ppid_t		Pdecint
647
#define Ppgid		Pdecint		/* pid or negative pgid */
648
#define Poff_t		Phexlonglong
649
#define Pmsqid		Pdecint
650
#define Pshmid		Pdecint
651
#define Psemid		Pdecint
652
#define Pkey_t		Pdecint
653
#define Pucount		Pdecuint
654
#define Chflagsname	Phexlong	/* to be added */
655
#define Sockprotoname	Phexlong	/* to be added */
656
#define Swapctlname	Phexlong	/* to be added */
657
#define Msgflgname	Phexlong	/* to be added */
658
659
660
typedef signed char formatter;
661
static const formatter scargs[][8] = {
662
    [SYS_exit]		= { Pdecint },
663
    [SYS_read]		= { Pfd, Pptr, Pbigsize },
664
    [SYS_write]		= { Pfd, Pptr, Pbigsize },
665
    [SYS_open]		= { Ppath, PASS_TWO, Flagsandmodename },
666
    [SYS_close]		= { Pfd },
667
    [SYS_getentropy]	= { Pptr, Psize },
668
    [SYS___tfork]	= { Pptr, Psize },
669
    [SYS_link]		= { Ppath, Ppath },
670
    [SYS_unlink]	= { Ppath },
671
    [SYS_wait4]		= { Wait4pid, Pptr, Wait4optname },
672
    [SYS_chdir]		= { Ppath },
673
    [SYS_fchdir]	= { Pfd },
674
    [SYS_mknod]		= { Ppath, Modename, Pdev_t },
675
    [SYS_chmod]		= { Ppath, Modename },
676
    [SYS_chown]		= { Ppath, Uidname, Gidname },
677
    [SYS_break]		= { Pptr },
678
    [SYS_getrusage]	= { Rusagewho, Pptr },
679
    [SYS_mount]		= { Pptr, Ppath, Mountflagsname, Pptr },
680
    [SYS_unmount]	= { Ppath, Mountflagsname },
681
    [SYS_setuid]	= { Uidname },
682
    [SYS_ptrace]	= { Ptracedecode, Ppid_t, Pptr, Pdecint },
683
    [SYS_recvmsg]	= { Pfd, Pptr, Sendrecvflagsname },
684
    [SYS_sendmsg]	= { Pfd, Pptr, Sendrecvflagsname },
685
    [SYS_recvfrom]	= { Pfd, Pptr, Pbigsize, Sendrecvflagsname },
686
    [SYS_accept]	= { Pfd, Pptr, Pptr },
687
    [SYS_getpeername]	= { Pfd, Pptr, Pptr },
688
    [SYS_getsockname]	= { Pfd, Pptr, Pptr },
689
    [SYS_access]	= { Ppath, Accessmodename },
690
    [SYS_chflags]	= { Ppath, Chflagsname },
691
    [SYS_fchflags]	= { Pfd, Chflagsname },
692
    [SYS_kill]		= { Ppgid, Signame },
693
    [SYS_stat]		= { Ppath, Pptr },
694
    [SYS_lstat]		= { Ppath, Pptr },
695
    [SYS_dup]		= { Pfd },
696
    [SYS_fstatat]	= { Atfd, Ppath, Pptr, Atflagsname },
697
    [SYS_profil]	= { Pptr, Pbigsize, Pbigsize, Pdecuint },
698
    [SYS_ktrace]	= { Ppath, Ktraceopname, Ktracefacname, Ppgid },
699
    [SYS_sigaction]	= { Signame, Pptr, Pptr },
700
    [SYS_sigprocmask]	= { Sigprocmaskhowname, Sigset },
701
    [SYS_getlogin_r]	= { Pptr, Psize },
702
    [SYS_setlogin]	= { Pptr },
703
    [SYS_acct]		= { Ppath },
704
    [SYS_fstat]		= { Pfd, Pptr },
705
    [SYS_ioctl]		= { Pfd, Ioctldecode, Pptr },
706
    [SYS_reboot]	= { Rebootoptname },
707
    [SYS_revoke]	= { Ppath },
708
    [SYS_symlink]	= { Ppath, Ppath },
709
    [SYS_readlink]	= { Ppath, Pptr, Psize },
710
    [SYS_execve]	= { Ppath, Pptr, Pptr },
711
    [SYS_umask]		= { Modename },
712
    [SYS_chroot]	= { Ppath },
713
    [SYS_getfsstat]	= { Pptr, Pbigsize, Mountflagsname },
714
    [SYS_statfs]	= { Ppath, Pptr },
715
    [SYS_fstatfs]	= { Pfd, Pptr },
716
    [SYS_fhstatfs]	= { Pptr, Pptr },
717
    [SYS_gettimeofday]	= { Pptr, Pptr },
718
    [SYS_settimeofday]	= { Pptr, Pptr },
719
    [SYS_setitimer]	= { Itimername, Pptr, Pptr },
720
    [SYS_getitimer]	= { Itimername, Pptr },
721
    [SYS_select]	= { Pcount, Pptr, Pptr, Pptr, Pptr },
722
    [SYS_kevent]	= { Pfd, Pptr, Pcount, Pptr, Pcount, Pptr },
723
    [SYS_munmap]	= { Pptr, Pbigsize },
724
    [SYS_mprotect]	= { Pptr, Pbigsize, Mmapprotname },
725
    [SYS_madvise]	= { Pptr, Pbigsize, Madvisebehavname },
726
    [SYS_utimes]	= { Ppath, Pptr },
727
    [SYS_futimes]	= { Pfd, Pptr },
728
    [SYS_kbind]		= { Pptr, Psize, Phexlonglong },
729
    [SYS_mincore]	= { Pptr, Pbigsize, Pptr },
730
    [SYS_getgroups]	= { Pcount, Pptr },
731
    [SYS_setgroups]	= { Pcount, Pptr },
732
    [SYS_setpgid]	= { Ppid_t, Ppid_t },
733
    [SYS_sendsyslog]	= { Pptr, Psize, Syslogflagname },
734
    [SYS_utimensat]	= { Atfd, Ppath, Pptr, Atflagsname },
735
    [SYS_futimens]	= { Pfd, Pptr },
736
    [SYS_clock_gettime]	= { Clockname, Pptr },
737
    [SYS_clock_settime]	= { Clockname, Pptr },
738
    [SYS_clock_getres]	= { Clockname, Pptr },
739
    [SYS_dup2]		= { Pfd, Pfd },
740
    [SYS_nanosleep]	= { Pptr, Pptr },
741
    [SYS_fcntl]		= { Pfd, PASS_TWO, Fcntlcmdname },
742
    [SYS_accept4]	= { Pfd, Pptr, Pptr, Sockflagsname },
743
    [SYS___thrsleep]	= { Pptr, Clockname, Pptr, Pptr, Pptr },
744
    [SYS_fsync]		= { Pfd },
745
    [SYS_setpriority]	= { Prioname, Ppid_t, Pdecint },
746
    [SYS_socket]	= { Sockfamilyname, Socktypename, Sockprotoname },
747
    [SYS_connect]	= { Pfd, Pptr, Pucount },
748
    [SYS_getdents]	= { Pfd, Pptr, Pbigsize },
749
    [SYS_getpriority]	= { Prioname, Ppid_t },
750
    [SYS_pipe2]		= { Pptr, Flagsname },
751
    [SYS_dup3]		= { Pfd, Pfd, Flagsname },
752
    [SYS_sigreturn]	= { Pptr },
753
    [SYS_bind]		= { Pfd, Pptr, Pucount },
754
    [SYS_setsockopt]	= { Pfd, PASS_TWO, Sockoptlevelname, Pptr, Pdecint },
755
    [SYS_listen]	= { Pfd, Pdecint },
756
    [SYS_chflagsat]	= { Atfd, Ppath, Chflagsname, Atflagsname },
757
    [SYS_ppoll]		= { Pptr, Pucount, Pptr, Pptr },
758
    [SYS_pselect]	= { Pcount, Pptr, Pptr, Pptr, Pptr, Pptr },
759
    [SYS_sigsuspend]	= { Sigset },
760
    [SYS_getsockopt]	= { Pfd, PASS_TWO, Sockoptlevelname, Pptr, Pptr },
761
    [SYS_thrkill]	= { Ppid_t, Signame, Pptr },
762
    [SYS_readv]		= { Pfd, Pptr, Pcount },
763
    [SYS_writev]	= { Pfd, Pptr, Pcount },
764
    [SYS_fchown]	= { Pfd, Uidname, Gidname },
765
    [SYS_fchmod]	= { Pfd, Modename },
766
    [SYS_setreuid]	= { Uidname, Uidname },
767
    [SYS_setregid]	= { Gidname, Gidname },
768
    [SYS_rename]	= { Ppath, Ppath },
769
    [SYS_flock]		= { Pfd, Flockname },
770
    [SYS_mkfifo]	= { Ppath, Modename },
771
    [SYS_sendto]	= { Pfd, Pptr, Pbigsize, Sendrecvflagsname },
772
    [SYS_shutdown]	= { Pfd, Shutdownhowname },
773
    [SYS_socketpair]	= { Sockfamilyname, Socktypename, Sockprotoname, Pptr },
774
    [SYS_mkdir]		= { Ppath, Modename },
775
    [SYS_rmdir]		= { Ppath },
776
    [SYS_adjtime]	= { Pptr, Pptr },
777
    [SYS_quotactl]	= { Ppath, Quotactlname, Uidname, Pptr },
778
    [SYS_nfssvc]	= { Phexint, Pptr },
779
    [SYS_getfh]		= { Ppath, Pptr },
780
    [SYS_sysarch]	= { Pdecint, Pptr },
781
    [SYS_pread]		= { Pfd, Pptr, Pbigsize, PAD, Poff_t },
782
    [SYS_pwrite]	= { Pfd, Pptr, Pbigsize, PAD, Poff_t },
783
    [SYS_setgid]	= { Gidname },
784
    [SYS_setegid]	= { Gidname },
785
    [SYS_seteuid]	= { Uidname },
786
    [SYS_pathconf]	= { Ppath, Pathconfname },
787
    [SYS_fpathconf]	= { Pfd, Pathconfname },
788
    [SYS_swapctl]	= { Swapctlname, Pptr, Pdecint },
789
    [SYS_getrlimit]	= { Rlimitname, Pptr },
790
    [SYS_setrlimit]	= { Rlimitname, Pptr },
791
    [SYS_mmap]		= { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, PAD, Poff_t },
792
    [SYS_lseek]		= { Pfd, PAD, Poff_t, Whencename },
793
    [SYS_truncate]	= { Ppath, PAD, Poff_t },
794
    [SYS_ftruncate]	= { Pfd, PAD, Poff_t },
795
    [SYS_sysctl]	= { Pptr, Pcount, Pptr, Pptr, Pptr, Psize },
796
    [SYS_mlock]		= { Pptr, Pbigsize },
797
    [SYS_munlock]	= { Pptr, Pbigsize },
798
    [SYS_getpgid]	= { Ppid_t },
799
    [SYS_utrace]	= { Pptr, Pptr, Psize },
800
    [SYS_semget]	= { Pkey_t, Pcount, Semgetname },
801
    [SYS_msgget]	= { Pkey_t, Msgflgname },
802
    [SYS_msgsnd]	= { Pmsqid, Pptr, Psize, Msgflgname },
803
    [SYS_msgrcv]	= { Pmsqid, Pptr, Psize, Pdeclong, Msgflgname },
804
    [SYS_shmat]		= { Pshmid, Pptr, Shmatname },
805
    [SYS_shmdt]		= { Pptr },
806
    [SYS_minherit]	= { Pptr, Pbigsize, Minheritname },
807
    [SYS_poll]		= { Pptr, Pucount, Polltimeout },
808
    [SYS_lchown]	= { Ppath, Uidname, Gidname },
809
    [SYS_getsid]	= { Ppid_t },
810
    [SYS_msync]		= { Pptr, Pbigsize, Msyncflagsname },
811
    [SYS_pipe]		= { Pptr },
812
    [SYS_fhopen]	= { Pptr, Openflagsname },
813
    [SYS_preadv]	= { Pfd, Pptr, Pcount, PAD, Poff_t },
814
    [SYS_pwritev]	= { Pfd, Pptr, Pcount, PAD, Poff_t },
815
    [SYS_mlockall]	= { Mlockallname },
816
    [SYS_getresuid]	= { Pptr, Pptr, Pptr },
817
    [SYS_setresuid]	= { Uidname, Uidname, Uidname },
818
    [SYS_getresgid]	= { Pptr, Pptr, Pptr },
819
    [SYS_setresgid]	= { Gidname, Gidname, Gidname },
820
    [SYS_mquery]	= { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, PAD, Poff_t },
821
    [SYS_closefrom]	= { Pfd },
822
    [SYS_sigaltstack]	= { Pptr, Pptr },
823
    [SYS_shmget]	= { Pkey_t, Pbigsize, Semgetname },
824
    [SYS_semop]		= { Psemid, Pptr, Psize },
825
    [SYS_fhstat]	= { Pptr, Pptr },
826
    [SYS___semctl]	= { Psemid, Pcount, Semctlname, Pptr },
827
    [SYS_shmctl]	= { Pshmid, Shmctlname, Pptr },
828
    [SYS_msgctl]	= { Pmsqid, Shmctlname, Pptr },
829
    [SYS___thrwakeup]	= { Pptr, Pcount },
830
    [SYS___threxit]	= { Pptr },
831
    [SYS___thrsigdivert] = { Sigset, Pptr, Pptr },
832
    [SYS___getcwd]	= { Pptr, Psize },
833
    [SYS_adjfreq]	= { Pptr, Pptr },
834
    [SYS_setrtable]	= { Pdecint },
835
    [SYS_faccessat]	= { Atfd, Ppath, Accessmodename, Atflagsname },
836
    [SYS_fchmodat]	= { Atfd, Ppath, Modename, Atflagsname },
837
    [SYS_fchownat]	= { Atfd, Ppath, Uidname, Gidname, Atflagsname },
838
    [SYS_linkat]	= { Atfd, Ppath, Atfd, Ppath, Atflagsname },
839
    [SYS_mkdirat]	= { Atfd, Ppath, Modename },
840
    [SYS_mkfifoat]	= { Atfd, Ppath, Modename },
841
    [SYS_mknodat]	= { Atfd, Ppath, Modename, Pdev_t },
842
    [SYS_openat]	= { Atfd, Ppath, PASS_TWO, Flagsandmodename },
843
    [SYS_readlinkat]	= { Atfd, Ppath, Pptr, Psize },
844
    [SYS_renameat]	= { Atfd, Ppath, Atfd, Ppath },
845
    [SYS_symlinkat]	= { Ppath, Atfd, Ppath },
846
    [SYS_unlinkat]	= { Atfd, Ppath, Atflagsname },
847
    [SYS___set_tcb]	= { Pptr },
848
};
849
850
851
static void
852
ktrsyscall(struct ktr_syscall *ktr, size_t ktrlen)
853
355
{
854
	register_t *ap;
855
	int narg;
856
	char sep;
857
858
355
	if (ktr->ktr_argsize > ktrlen)
859
		errx(1, "syscall argument length %d > ktr header length %zu",
860
		    ktr->ktr_argsize, ktrlen);
861
862
355
	narg = ktr->ktr_argsize / sizeof(register_t);
863
355
	sep = '\0';
864
865
355
	if (ktr->ktr_code >= SYS_MAXSYSCALL || ktr->ktr_code < 0)
866
		(void)printf("[%d]", ktr->ktr_code);
867
	else
868
355
		(void)printf("%s", syscallnames[ktr->ktr_code]);
869
355
	ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
870
355
	(void)putchar('(');
871
872

355
	if (ktr->ktr_code == SYS_sysctl && fancy) {
873
		const char *s;
874
		int n, i, *top;
875
876
		n = ap[1];
877
		if (n > CTL_MAXNAME)
878
			n = CTL_MAXNAME;
879
		if (n < 0)
880
			errx(1, "invalid sysctl length %d", n);
881
		if (n > 0) {
882
			top = (int *)(ap + 6);
883
			printf("%d", top[0]);
884
			for (i = 1; i < n; i++)
885
				printf(".%d", top[i]);
886
			if ((s = kresolvsysctl(0, top)) != NULL) {
887
				printf("<%s", s);
888
				for (i = 1; i < n; i++) {
889
					if ((s = kresolvsysctl(i, top)) != NULL)
890
						printf(".%s", s);
891
					else
892
						printf(".%d", top[i]);
893
				}
894
				putchar('>');
895
			}
896
		}
897
898
		sep = ',';
899
		ap += 2;
900
		narg -= 2;
901
355
	} else if (ktr->ktr_code < nitems(scargs)) {
902
355
		const formatter *fmts = scargs[ktr->ktr_code];
903
		int fmt;
904
905

1621
		while (narg && (fmt = *fmts) != 0) {
906
911
			if (sep)
907
454
				putchar(sep);
908
911
			sep = ',';
909
911
			if (!fancy && !FMT_IS_NONFANCY(fmt))
910
				fmt = Pnonfancy;
911
911
			if (fmt > 0)
912
328
				formatters[fmt]((int)*ap);
913
583
			else if (long_formatters[-fmt](*ap))
914
104
				sep = '\0';
915
911
			fmts++;
916
911
			ap++;
917
911
			narg--;
918
		}
919
	}
920
921
355
	while (narg > 0) {
922
		if (sep)
923
			putchar(sep);
924
		if (decimal)
925
			(void)printf("%ld", (long)*ap);
926
		else
927
			(void)printf("%#lx", (long)*ap);
928
		sep = ',';
929
		ap++;
930
		narg--;
931
	}
932
355
	(void)printf(")\n");
933
355
}
934
935
static struct ctlname topname[] = CTL_NAMES;
936
static struct ctlname kernname[] = CTL_KERN_NAMES;
937
static struct ctlname vmname[] = CTL_VM_NAMES;
938
static struct ctlname fsname[] = CTL_FS_NAMES;
939
static struct ctlname netname[] = CTL_NET_NAMES;
940
static struct ctlname hwname[] = CTL_HW_NAMES;
941
static struct ctlname debugname[CTL_DEBUG_MAXID];
942
static struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES;
943
static struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES;
944
static struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES;
945
static struct ctlname kernprocname[] = {
946
	{ NULL },
947
	{ "all" },
948
	{ "pid" },
949
	{ "pgrp" },
950
	{ "session" },
951
	{ "tty" },
952
	{ "uid" },
953
	{ "ruid" },
954
	{ "kthread" },
955
};
956
static struct ctlname ttysname[] = CTL_KERN_TTY_NAMES;
957
static struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES;
958
static struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES;
959
static struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES;
960
static struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES;
961
#ifdef CTL_MACHDEP_NAMES
962
static struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
963
#endif
964
static struct ctlname ddbname[] = CTL_DDB_NAMES;
965
966
#ifndef nitems
967
#define nitems(_a)    (sizeof((_a)) / sizeof((_a)[0]))
968
#endif
969
970
#define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)
971
972
static const char *
973
kresolvsysctl(int depth, const int *top)
974
{
975
	struct ctlname *names;
976
	size_t		limit;
977
	int		idx = top[depth];
978
979
	names = NULL;
980
981
	switch (depth) {
982
	case 0:
983
		SETNAME(topname);
984
		break;
985
	case 1:
986
		switch (top[0]) {
987
		case CTL_KERN:
988
			SETNAME(kernname);
989
			break;
990
		case CTL_VM:
991
			SETNAME(vmname);
992
			break;
993
		case CTL_FS:
994
			SETNAME(fsname);
995
			break;
996
		case CTL_NET:
997
			SETNAME(netname);
998
			break;
999
		case CTL_DEBUG:
1000
			SETNAME(debugname);
1001
			break;
1002
		case CTL_HW:
1003
			SETNAME(hwname);
1004
			break;
1005
#ifdef CTL_MACHDEP_NAMES
1006
		case CTL_MACHDEP:
1007
			SETNAME(machdepname);
1008
			break;
1009
#endif
1010
		case CTL_DDB:
1011
			SETNAME(ddbname);
1012
			break;
1013
		}
1014
		break;
1015
	case 2:
1016
		switch (top[0]) {
1017
		case CTL_KERN:
1018
			switch (top[1]) {
1019
			case KERN_MALLOCSTATS:
1020
				SETNAME(kernmallocname);
1021
				break;
1022
			case KERN_FORKSTAT:
1023
				SETNAME(forkstatname);
1024
				break;
1025
			case KERN_NCHSTATS:
1026
				SETNAME(nchstatsname);
1027
				break;
1028
			case KERN_TTY:
1029
				SETNAME(ttysname);
1030
				break;
1031
			case KERN_SEMINFO:
1032
				SETNAME(semname);
1033
				break;
1034
			case KERN_SHMINFO:
1035
				SETNAME(shmname);
1036
				break;
1037
			case KERN_WATCHDOG:
1038
				SETNAME(watchdogname);
1039
				break;
1040
			case KERN_PROC:
1041
				idx++;	/* zero is valid at this level */
1042
				SETNAME(kernprocname);
1043
				break;
1044
			case KERN_TIMECOUNTER:
1045
				SETNAME(tcname);
1046
				break;
1047
			}
1048
		}
1049
		break;
1050
	}
1051
	if (names != NULL && idx > 0 && idx < limit)
1052
		return (names[idx].ctl_name);
1053
	return (NULL);
1054
}
1055
1056
static void
1057
ktrsysret(struct ktr_sysret *ktr, size_t ktrlen)
1058
355
{
1059
355
	register_t ret = 0;
1060
	long long retll;
1061
355
	int error = ktr->ktr_error;
1062
355
	int code = ktr->ktr_code;
1063
1064
355
	if (ktrlen < sizeof(*ktr))
1065
		errx(1, "sysret length %zu < ktr header length %zu",
1066
		    ktrlen, sizeof(*ktr));
1067
355
	ktrlen -= sizeof(*ktr);
1068
355
	if (error == 0) {
1069
353
		if (ktrlen == sizeof(ret)) {
1070
353
			memcpy(&ret, ktr+1, sizeof(ret));
1071
353
			retll = ret;
1072
		} else if (ktrlen == sizeof(retll))
1073
			memcpy(&retll, ktr+1, sizeof(retll));
1074
		else
1075
			errx(1, "sysret bogus length %zu", ktrlen);
1076
	}
1077
1078
355
	if (code >= SYS_MAXSYSCALL || code < 0)
1079
		(void)printf("[%d] ", code);
1080
	else
1081
355
		(void)printf("%s ", syscallnames[code]);
1082
1083
355
doerr:
1084
355
	if (error == 0) {
1085
353
		if (fancy) {
1086

353
			switch (code) {
1087
			case SYS_lseek:
1088
2
				(void)printf("%lld", retll);
1089
2
				if (retll < 0 || retll > 9)
1090
					(void)printf("/%#llx", retll);
1091
				break;
1092
			case SYS_sigprocmask:
1093
			case SYS_sigpending:
1094
				sigset(ret);
1095
				break;
1096
			case SYS___thrsigdivert:
1097
				signame(ret);
1098
				break;
1099
			case SYS_getuid:
1100
			case SYS_geteuid:
1101
				uidname(ret);
1102
				break;
1103
			case SYS_getgid:
1104
			case SYS_getegid:
1105
				gidname(ret);
1106
				break;
1107
			/* syscalls that return errno values */
1108
			case SYS_getlogin_r:
1109
			case SYS___thrsleep:
1110
				if ((error = ret) != 0)
1111
					goto doerr;
1112
				/* FALLTHROUGH */
1113
			default:
1114
351
				(void)printf("%ld", (long)ret);
1115
351
				if (ret < 0 || ret > 9)
1116
37
					(void)printf("/%#lx", (long)ret);
1117
			}
1118
		} else {
1119
			if (decimal)
1120
				(void)printf("%lld", retll);
1121
			else
1122
				(void)printf("%#llx", retll);
1123
		}
1124
2
	} else if (error == ERESTART)
1125
		(void)printf("RESTART");
1126
2
	else if (error == EJUSTRETURN)
1127
		(void)printf("JUSTRETURN");
1128
	else {
1129
2
		(void)printf("-1 errno %d", error);
1130
2
		if (fancy)
1131
2
			(void)printf(" %s", strerror(error));
1132
	}
1133
355
	(void)putchar('\n');
1134
355
}
1135
1136
static void
1137
ktrnamei(const char *cp, size_t len)
1138
136
{
1139
136
	showbufc(basecol, (unsigned char *)cp, len, VIS_DQ | VIS_TAB | VIS_NL);
1140
136
}
1141
1142
void
1143
showbufc(int col, unsigned char *dp, size_t datalen, int flags)
1144
140
{
1145
	int width;
1146
	unsigned char visbuf[5], *cp;
1147
1148
140
	flags |= VIS_CSTYLE;
1149
140
	putchar('"');
1150
140
	col++;
1151
9639
	for (; datalen > 0; datalen--, dp++) {
1152
9499
		(void)vis(visbuf, *dp, flags, *(dp+1));
1153
9499
		cp = visbuf;
1154
1155
		/*
1156
		 * Keep track of printables and
1157
		 * space chars (like fold(1)).
1158
		 */
1159
9499
		if (col == 0) {
1160
6
			(void)putchar('\t');
1161
6
			col = 8;
1162
		}
1163
9499
		switch (*cp) {
1164
		case '\n':
1165
6
			col = 0;
1166
6
			(void)putchar('\n');
1167
			continue;
1168
		case '\t':
1169
12
			width = 8 - (col&07);
1170
12
			break;
1171
		default:
1172
9481
			width = strlen(cp);
1173
		}
1174
9493
		if (col + width > (screenwidth-2)) {
1175
116
			(void)printf("\\\n\t");
1176
116
			col = 8;
1177
		}
1178
9493
		col += width;
1179
		do {
1180
16071
			(void)putchar(*cp++);
1181
16071
		} while (*cp);
1182
	}
1183
140
	if (col == 0)
1184
		(void)printf("       ");
1185
140
	(void)printf("\"\n");
1186
140
}
1187
1188
static void
1189
showbuf(unsigned char *dp, size_t datalen)
1190
3
{
1191
	int i, j;
1192
3
	int col = 0, bpl;
1193
	unsigned char c;
1194
1195
3
	if (iohex == 1) {
1196
		putchar('\t');
1197
		col = 8;
1198
		for (i = 0; i < datalen; i++) {
1199
			printf("%02x", dp[i]);
1200
			col += 3;
1201
			if (i < datalen - 1) {
1202
				if (col + 3 > screenwidth) {
1203
					printf("\n\t");
1204
					col = 8;
1205
				} else
1206
					putchar(' ');
1207
			}
1208
		}
1209
		putchar('\n');
1210
		return;
1211
	}
1212
3
	if (iohex == 2) {
1213
		bpl = (screenwidth - 13)/4;
1214
		if (bpl <= 0)
1215
			bpl = 1;
1216
		for (i = 0; i < datalen; i += bpl) {
1217
			printf("   %04x:  ", i);
1218
			for (j = 0; j < bpl; j++) {
1219
				if (i+j >= datalen)
1220
					printf("   ");
1221
				else
1222
					printf("%02x ", dp[i+j]);
1223
			}
1224
			putchar(' ');
1225
			for (j = 0; j < bpl; j++) {
1226
				if (i+j >= datalen)
1227
					break;
1228
				c = dp[i+j];
1229
				if (!isprint(c))
1230
					c = '.';
1231
				putchar(c);
1232
			}
1233
			putchar('\n');
1234
		}
1235
		return;
1236
	}
1237
1238
3
	(void)printf("       ");
1239
3
	showbufc(7, dp, datalen, 0);
1240
}
1241
1242
static void
1243
ktrgenio(struct ktr_genio *ktr, size_t len)
1244
3
{
1245
3
	unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
1246
	size_t datalen;
1247
1248
3
	if (len < sizeof(struct ktr_genio))
1249
		errx(1, "invalid ktr genio length %zu", len);
1250
1251
3
	datalen = len - sizeof(struct ktr_genio);
1252
1253
3
	printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1254
		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
1255
3
	if (maxdata == 0)
1256
		return;
1257
3
	if (datalen > maxdata)
1258
		datalen = maxdata;
1259
3
	if (iohex && !datalen)
1260
		return;
1261
3
	showbuf(dp, datalen);
1262
}
1263
1264
static void
1265
ktrpsig(struct ktr_psig *psig)
1266
{
1267
	signame(psig->signo);
1268
	printf(" ");
1269
	if (psig->action == SIG_DFL)
1270
		(void)printf("SIG_DFL");
1271
	else {
1272
		(void)printf("caught handler=0x%lx mask=",
1273
		    (u_long)psig->action);
1274
		sigset(psig->mask);
1275
	}
1276
	if (psig->code) {
1277
		printf(" code ");
1278
		if (fancy) {
1279
			switch (psig->signo) {
1280
			case SIGILL:
1281
				sigill_name(psig->code);
1282
				break;
1283
			case SIGTRAP:
1284
				sigtrap_name(psig->code);
1285
				break;
1286
			case SIGEMT:
1287
				sigemt_name(psig->code);
1288
				break;
1289
			case SIGFPE:
1290
				sigfpe_name(psig->code);
1291
				break;
1292
			case SIGBUS:
1293
				sigbus_name(psig->code);
1294
				break;
1295
			case SIGSEGV:
1296
				sigsegv_name(psig->code);
1297
				break;
1298
			case SIGCHLD:
1299
				sigchld_name(psig->code);
1300
				break;
1301
			}
1302
		}
1303
		printf("<%d>", psig->code);
1304
	}
1305
1306
	switch (psig->signo) {
1307
	case SIGSEGV:
1308
	case SIGILL:
1309
	case SIGBUS:
1310
	case SIGFPE:
1311
		printf(" addr=%p trapno=%d", psig->si.si_addr,
1312
		    psig->si.si_trapno);
1313
		break;
1314
	default:
1315
		break;
1316
	}
1317
	printf("\n");
1318
}
1319
1320
static void
1321
ktruser(struct ktr_user *usr, size_t len)
1322
{
1323
	if (len < sizeof(struct ktr_user))
1324
		errx(1, "invalid ktr user length %zu", len);
1325
	len -= sizeof(struct ktr_user);
1326
	printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id);
1327
	printf(" %zu bytes\n", len);
1328
	showbuf((unsigned char *)(usr + 1), len);
1329
}
1330
1331
static void
1332
ktrexec(const char *ptr, size_t len)
1333
1
{
1334
	int i, col;
1335
	size_t l;
1336
1337
1
	putchar('\n');
1338
1
	i = 0;
1339
3
	while (len > 0) {
1340
1
		l = strnlen(ptr, len);
1341
1
		col = printf("\t[%d] = ", i++);
1342
1
		col += 7;	/* tab expands from 1 to 8 columns */
1343
1
		showbufc(col, (unsigned char *)ptr, l, VIS_DQ|VIS_TAB|VIS_NL);
1344
1
		if (l == len) {
1345
			printf("\tunterminated argument\n");
1346
			break;
1347
		}
1348
1
		len -= l + 1;
1349
1
		ptr += l + 1;
1350
	}
1351
1
}
1352
1353
static void
1354
ktrpledge(struct ktr_pledge *pledge, size_t len)
1355
{
1356
	char *name = "";
1357
	int i;
1358
1359
	if (len < sizeof(struct ktr_pledge))
1360
		errx(1, "invalid ktr pledge length %zu", len);
1361
1362
	if (pledge->syscall >= SYS_MAXSYSCALL || pledge->syscall < 0)
1363
		(void)printf("[%d]", pledge->syscall);
1364
	else
1365
		(void)printf("%s", syscallnames[pledge->syscall]);
1366
	printf(", ");
1367
	for (i = 0; pledge->code && pledgenames[i].bits != 0; i++) {
1368
		if (pledgenames[i].bits & pledge->code) {
1369
			name = pledgenames[i].name;
1370
			break;
1371
		}
1372
	}
1373
	printf("\"%s\"", name);
1374
	(void)printf(", errno %d", pledge->error);
1375
	if (fancy)
1376
		(void)printf(" %s", strerror(pledge->error));
1377
	printf("\n");
1378
}
1379
1380
static void
1381
usage(void)
1382
{
1383
1384
	extern char *__progname;
1385
	fprintf(stderr, "usage: %s "
1386
	    "[-dHlnRTXx] [-f file] [-m maxdata] [-p pid]\n"
1387
	    "%*s[-t [cinpstuxX+]]\n",
1388
	    __progname, (int)(sizeof("usage: ") + strlen(__progname)), "");
1389
	exit(1);
1390
}
1391
1392
1393
/*
1394
 * FORMATTERS
1395
 */
1396
1397
static void
1398
ioctldecode(int cmd)
1399
{
1400
	char dirbuf[4], *dir = dirbuf;
1401
	const char *cp;
1402
1403
	if ((cp = ioctlname((unsigned)cmd)) != NULL) {
1404
		(void)printf("%s", cp);
1405
		return;
1406
	}
1407
1408
	if (cmd & IOC_IN)
1409
		*dir++ = 'W';
1410
	if (cmd & IOC_OUT)
1411
		*dir++ = 'R';
1412
	*dir = '\0';
1413
1414
	printf("_IO%s('%c',%d",
1415
	    dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1416
	if ((cmd & IOC_VOID) == 0)
1417
		printf(decimal ? ",%u)" : ",%#x)", (cmd >> 16) & 0xff);
1418
	else
1419
		printf(")");
1420
}
1421
1422
static void
1423
ptracedecode(int request)
1424
{
1425
	if (request >= 0 && request < nitems(ptrace_ops))
1426
		(void)printf("%s", ptrace_ops[request]);
1427
	else switch(request) {
1428
#ifdef PT_GETFPREGS
1429
	case PT_GETFPREGS:
1430
		(void)printf("PT_GETFPREGS");
1431
		break;
1432
#endif
1433
	case PT_GETREGS:
1434
		(void)printf("PT_GETREGS");
1435
		break;
1436
#ifdef PT_GETXMMREGS
1437
	case PT_GETXMMREGS:
1438
		(void)printf("PT_GETXMMREGS");
1439
		break;
1440
#endif
1441
#ifdef PT_SETFPREGS
1442
	case PT_SETFPREGS:
1443
		(void)printf("PT_SETFPREGS");
1444
		break;
1445
#endif
1446
	case PT_SETREGS:
1447
		(void)printf("PT_SETREGS");
1448
		break;
1449
#ifdef PT_SETXMMREGS
1450
	case PT_SETXMMREGS:
1451
		(void)printf("PT_SETXMMREGS");
1452
		break;
1453
#endif
1454
#ifdef PT_STEP
1455
	case PT_STEP:
1456
		(void)printf("PT_STEP");
1457
		break;
1458
#endif
1459
#ifdef PT_WCOOKIE
1460
	case PT_WCOOKIE:
1461
		(void)printf("PT_WCOOKIE");
1462
		break;
1463
#endif
1464
	default:
1465
		pdecint(request);
1466
	}
1467
}
1468
1469
1470
static void
1471
atfd(int fd)
1472
{
1473
	if (fd == AT_FDCWD)
1474
		(void)printf("AT_FDCWD");
1475
	else
1476
		pdecint(fd);
1477
}
1478
1479
static void
1480
polltimeout(int timeout)
1481
{
1482
	if (timeout == INFTIM)
1483
		(void)printf("INFTIM");
1484
	else
1485
		pdecint(timeout);
1486
}
1487
1488
static void
1489
wait4pid(int pid)
1490
{
1491
	if (pid == WAIT_ANY)
1492
		(void)printf("WAIT_ANY");
1493
	else if (pid == WAIT_MYPGRP)
1494
		(void)printf("WAIT_MYPGRP");
1495
	else
1496
		pdecint(pid);		/* ppgid */
1497
}
1498
1499
static void
1500
signame(int sig)
1501
{
1502
	if (sig > 0 && sig < NSIG)
1503
		(void)printf("SIG%s", sys_signame[sig]);
1504
	else
1505
		(void)printf("SIG %d", sig);
1506
}
1507
1508
void
1509
sigset(int ss)
1510
{
1511
	int	or = 0;
1512
	int	cnt = 0;
1513
	int	i;
1514
1515
	for (i = 1; i < NSIG; i++)
1516
		if (sigismember(&ss, i))
1517
			cnt++;
1518
	if (cnt > (NSIG-1)/2) {
1519
		ss = ~ss;
1520
		putchar('~');
1521
	}
1522
1523
	if (ss == 0) {
1524
		(void)printf("0<>");
1525
		return;
1526
	}
1527
1528
	printf("%#x<", ss);
1529
	for (i = 1; i < NSIG; i++)
1530
		if (sigismember(&ss, i)) {
1531
			if (or) putchar('|'); else or=1;
1532
			signame(i);
1533
		}
1534
	printf(">");
1535
}
1536
1537
static void
1538
semctlname(int cmd)
1539
{
1540
	switch (cmd) {
1541
	case GETNCNT:
1542
		(void)printf("GETNCNT");
1543
		break;
1544
	case GETPID:
1545
		(void)printf("GETPID");
1546
		break;
1547
	case GETVAL:
1548
		(void)printf("GETVAL");
1549
		break;
1550
	case GETALL:
1551
		(void)printf("GETALL");
1552
		break;
1553
	case GETZCNT:
1554
		(void)printf("GETZCNT");
1555
		break;
1556
	case SETVAL:
1557
		(void)printf("SETVAL");
1558
		break;
1559
	case SETALL:
1560
		(void)printf("SETALL");
1561
		break;
1562
	case IPC_RMID:
1563
		(void)printf("IPC_RMID");
1564
		break;
1565
	case IPC_SET:
1566
		(void)printf("IPC_SET");
1567
		break;
1568
	case IPC_STAT:
1569
		(void)printf("IPC_STAT");
1570
		break;
1571
	default: /* Should not reach */
1572
		(void)printf("<invalid=%d>", cmd);
1573
	}
1574
}
1575
1576
static void
1577
shmctlname(int cmd)
1578
{
1579
	switch (cmd) {
1580
	case IPC_RMID:
1581
		(void)printf("IPC_RMID");
1582
		break;
1583
	case IPC_SET:
1584
		(void)printf("IPC_SET");
1585
		break;
1586
	case IPC_STAT:
1587
		(void)printf("IPC_STAT");
1588
		break;
1589
	default: /* Should not reach */
1590
		(void)printf("<invalid=%d>", cmd);
1591
	}
1592
}
1593
1594
1595
static void
1596
semgetname(int flag)
1597
{
1598
	int	or = 0;
1599
	if_print_or(flag, IPC_CREAT, or);
1600
	if_print_or(flag, IPC_EXCL, or);
1601
	if_print_or(flag, SEM_R, or);
1602
	if_print_or(flag, SEM_A, or);
1603
	if_print_or(flag, (SEM_R>>3), or);
1604
	if_print_or(flag, (SEM_A>>3), or);
1605
	if_print_or(flag, (SEM_R>>6), or);
1606
	if_print_or(flag, (SEM_A>>6), or);
1607
1608
	if (flag & ~(IPC_CREAT|IPC_EXCL|SEM_R|SEM_A|((SEM_R|SEM_A)>>3)|
1609
	    ((SEM_R|SEM_A)>>6)))
1610
		printf("<invalid=%#x>", flag);
1611
}
1612
1613
1614
/*
1615
 * Only used by SYS_open and SYS_openat. Unless O_CREAT is set in flags, the
1616
 * mode argument is unused (and often bogus and misleading).
1617
 */
1618
static void
1619
flagsandmodename(int mode)
1620
70
{
1621
70
	openflagsname(arg1);
1622
70
	if ((arg1 & O_CREAT) == O_CREAT) {
1623
66
		(void)putchar(',');
1624
66
		modename(mode);
1625
4
	} else if (!fancy)
1626
		(void)printf(",<unused>%#o", mode);
1627
70
}
1628
1629
static void
1630
clockname(int clockid)
1631
{
1632
	clocktypename(__CLOCK_TYPE(clockid));
1633
	if (__CLOCK_PTID(clockid) != 0)
1634
		printf("(%d)", __CLOCK_PTID(clockid));
1635
}
1636
1637
/*
1638
 * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value
1639
 * referring to a line in /etc/protocols.
1640
 */
1641
static void
1642
sockoptlevelname(int optname)
1643
{
1644
	struct protoent *pe;
1645
1646
	if (arg1 == SOL_SOCKET) {
1647
		(void)printf("SOL_SOCKET,");
1648
		sockoptname(optname);
1649
	} else {
1650
		pe = getprotobynumber(arg1);
1651
		(void)printf("%u<%s>,%d", arg1,
1652
		    pe != NULL ? pe->p_name : "unknown", optname);
1653
	}
1654
}
1655
1656
static void
1657
ktraceopname(int ops)
1658
{
1659
	int invalid = 0;
1660
1661
	printf("%#x<", ops);
1662
	switch (KTROP(ops)) {
1663
	case KTROP_SET:
1664
		printf("KTROP_SET");
1665
		break;
1666
	case KTROP_CLEAR:
1667
		printf("KTROP_CLEAR");
1668
		break;
1669
	case KTROP_CLEARFILE:
1670
		printf("KTROP_CLEARFILE");
1671
		break;
1672
	default:
1673
		printf("KTROP(%d)", KTROP(ops));
1674
		invalid = 1;
1675
		break;
1676
	}
1677
	if (ops & KTRFLAG_DESCEND) printf("|KTRFLAG_DESCEND");
1678
	printf(">");
1679
	if (invalid || (ops & ~(KTROP((unsigned)-1) | KTRFLAG_DESCEND)))
1680
		(void)printf("<invalid>%d", ops);
1681
}