GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/kdump/kdump.c Lines: 275 551 49.9 %
Date: 2017-11-13 Branches: 168 466 36.1 %

Line Branch Exec Source
1
/*	$OpenBSD: kdump.c,v 1.132 2017/10/07 19:46:22 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
{
145
	int ch, silent;
146
	size_t ktrlen, size;
147
	int trpoints = ALL_POINTS;
148
622
	const char *errstr;
149
	void *m;
150
151
311
	if (screenwidth == 0) {
152
311
		struct winsize ws;
153
154


1323
		if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
155
79
		    ws.ws_col > 8)
156
79
			screenwidth = ws.ws_col;
157
		else
158
			screenwidth = 80;
159
311
	}
160
161
1238
	while ((ch = getopt(argc, argv, "f:dHlm:np:RTt:xX")) != -1)
162



308
		switch (ch) {
163
		case 'f':
164
308
			tracefile = optarg;
165
308
			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
311
	if (argc > optind)
209
		usage();
210
211
311
	if (pledge("stdio rpath getpw flock cpath wpath", NULL) == -1)
212
		err(1, "pledge");
213
214
311
	m = malloc(size = 1025);
215
311
	if (m == NULL)
216
		err(1, NULL);
217
311
	if (!freopen(tracefile, "r", stdin))
218
		err(1, "%s", tracefile);
219
220

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

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

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

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


4684447
		switch (ktr_header.ktr_type) {
248
		case KTR_SYSCALL:
249
1839923
			ktrsyscall(m, ktrlen);
250
1839923
			break;
251
		case KTR_SYSRET:
252
1839926
			ktrsysret(m, ktrlen);
253
1839926
			break;
254
		case KTR_NAMEI:
255
690306
			ktrnamei(m, ktrlen);
256
690306
			break;
257
		case KTR_GENIO:
258
169234
			ktrgenio(m, ktrlen);
259
169234
			break;
260
		case KTR_PSIG:
261
1144
			ktrpsig(m);
262
1144
			break;
263
		case KTR_STRUCT:
264
142927
			ktrstruct(m, ktrlen);
265
142927
			break;
266
		case KTR_USER:
267
			ktruser(m, ktrlen);
268
			break;
269
		case KTR_EXECARGS:
270
		case KTR_EXECENV:
271
987
			ktrexec(m, ktrlen);
272
987
			break;
273
		case KTR_PLEDGE:
274
			ktrpledge(m, ktrlen);
275
			break;
276
		default:
277
			printf("\n");
278
			break;
279
		}
280
4684447
		if (tail)
281
			(void)fflush(stdout);
282
	}
283
	exit(0);
284
}
285
286
static int
287
fread_tail(void *buf, size_t size, size_t num)
288
{
289
	int i;
290
291
28108548
	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
292
		(void)sleep(1);
293
		clearerr(stdin);
294
	}
295
9369516
	return (i);
296
}
297
298
static void
299
dumpheader(struct ktr_header *kth)
300
{
301
	static struct timespec prevtime;
302
9368894
	char unknown[64], *type;
303
	struct timespec temp;
304
305


4684447
	switch (kth->ktr_type) {
306
	case KTR_SYSCALL:
307
		type = "CALL";
308
1839923
		break;
309
	case KTR_SYSRET:
310
		type = "RET ";
311
1839926
		break;
312
	case KTR_NAMEI:
313
		type = "NAMI";
314
690306
		break;
315
	case KTR_GENIO:
316
		type = "GIO ";
317
169234
		break;
318
	case KTR_PSIG:
319
		type = "PSIG";
320
1144
		break;
321
	case KTR_STRUCT:
322
		type = "STRU";
323
142927
		break;
324
	case KTR_USER:
325
		type = "USER";
326
		break;
327
	case KTR_EXECARGS:
328
		type = "ARGS";
329
987
		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
4684447
	basecol = printf("%6ld", (long)kth->ktr_pid);
348
4684447
	if (needtid)
349
		basecol += printf("/%-7ld", (long)kth->ktr_tid);
350
4684447
	basecol += printf(" %-8.*s ", MAXCOMLEN, kth->ktr_comm);
351
4684447
	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
4684447
	basecol += printf("%s  ", type);
365
4684447
}
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
{
375
	/* nothing printed */
376
428720
	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
{
384
848930
	arg1 = (int)arg;
385
386
	/* nothing printed */
387
424465
	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
{
400
269778
	(void)printf("%lu", arg);
401
134889
	return (0);
402
}
403
404
static int
405
phexlong(long arg)
406
{
407
4546916
	(void)printf("%#lx", arg);
408
2273458
	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
{
424
1575046
	(void)printf("%d", arg);
425
787523
}
426
427
static void
428
pdecuint(int arg)
429
{
430
2344
	(void)printf("%u", arg);
431
1172
}
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
	futexflagname,
555
};
556
557
enum {
558
	/* the end of the (known) arguments is recognized by the zero fill */
559
	end_of_args	=  0,
560
561
	/* negative are the negative of the index into long_formatters[] */
562
	Pdeclong	= -1,
563
	Pdeculong	= -2,
564
	Phexlong	= -3,
565
	PASS_TWO	= -4,
566
567
/* the remaining long formatters still get called when non-fancy (-n option) */
568
#define FMT_IS_NONFANCY(x)	((x) <= PASS_LONGLONG)
569
	PASS_LONGLONG	= -5,
570
	Phexll		= -6,
571
	PAD		= -7,
572
	Pnonfancy	= -8,
573
574
	/* positive values are the index into formatters[] */
575
	Pdecint		= 1,
576
	Phexint,
577
	Poctint,
578
	Pdecuint,
579
	Ioctldecode,
580
	Ptracedecode,
581
	Atfd,
582
	Polltimeout,
583
	Wait4pid,
584
	Signame,
585
	Semctlname,
586
	Shmctlname,
587
	Semgetname,
588
	Flagsandmodename,
589
	Clockname,
590
	Sockoptlevelname,
591
	Ktraceopname,
592
	Fcntlcmdname,
593
	Modename,
594
	Flagsname,
595
	Openflagsname,
596
	Atflagsname,
597
	Accessmodename,
598
	Mmapprotname,
599
	Mmapflagsname,
600
	Wait4optname,
601
	Sendrecvflagsname,
602
	Mountflagsname,
603
	Rebootoptname,
604
	Flockname,
605
	Sockoptname,
606
	Sockipprotoname,
607
	Socktypename,
608
	Sockflagsname,
609
	Sockfamilyname,
610
	Mlockallname,
611
	Shmatname,
612
	Whencename,
613
	Pathconfname,
614
	Rlimitname,
615
	Shutdownhowname,
616
	Prioname,
617
	Madvisebehavname,
618
	Msyncflagsname,
619
	Clocktypename,
620
	Rusagewho,
621
	Sigactionflagname,
622
	Sigprocmaskhowname,
623
	Minheritname,
624
	Quotactlname,
625
	Sigill_name,
626
	Sigtrap_name,
627
	Sigemt_name,
628
	Sigfpe_name,
629
	Sigbus_name,
630
	Sigsegv_name,
631
	Sigchld_name,
632
	Ktracefacname,
633
	Itimername,
634
	Sigset,
635
	Uidname,
636
	Gidname,
637
	Syslogflagname,
638
	Futexflagname,
639
};
640
641
#define Pptr		Phexlong
642
#define	Psize		Pdeculong	/* size_t for small buffers */
643
#define	Pbigsize	Phexlong	/* size_t for I/O buffers */
644
#define Pcount		Pdecint		/* int for a count of something */
645
#define Pfd		Pdecint
646
#define Ppath		Phexlong
647
#define Pdev_t		Pdecint
648
#define Ppid_t		Pdecint
649
#define Ppgid		Pdecint		/* pid or negative pgid */
650
#define Poff_t		Phexlonglong
651
#define Pmsqid		Pdecint
652
#define Pshmid		Pdecint
653
#define Psemid		Pdecint
654
#define Pkey_t		Pdecint
655
#define Pucount		Pdecuint
656
#define Chflagsname	Phexlong	/* to be added */
657
#define Sockprotoname	Phexlong	/* to be added */
658
#define Swapctlname	Phexlong	/* to be added */
659
#define Msgflgname	Phexlong	/* to be added */
660
661
662
typedef signed char formatter;
663
static const formatter scargs[][8] = {
664
    [SYS_exit]		= { Pdecint },
665
    [SYS_read]		= { Pfd, Pptr, Pbigsize },
666
    [SYS_write]		= { Pfd, Pptr, Pbigsize },
667
    [SYS_open]		= { Ppath, PASS_TWO, Flagsandmodename },
668
    [SYS_close]		= { Pfd },
669
    [SYS_getentropy]	= { Pptr, Psize },
670
    [SYS___tfork]	= { Pptr, Psize },
671
    [SYS_link]		= { Ppath, Ppath },
672
    [SYS_unlink]	= { Ppath },
673
    [SYS_wait4]		= { Wait4pid, Pptr, Wait4optname },
674
    [SYS_chdir]		= { Ppath },
675
    [SYS_fchdir]	= { Pfd },
676
    [SYS_mknod]		= { Ppath, Modename, Pdev_t },
677
    [SYS_chmod]		= { Ppath, Modename },
678
    [SYS_chown]		= { Ppath, Uidname, Gidname },
679
    [SYS_break]		= { Pptr },
680
    [SYS_getrusage]	= { Rusagewho, Pptr },
681
    [SYS_mount]		= { Pptr, Ppath, Mountflagsname, Pptr },
682
    [SYS_unmount]	= { Ppath, Mountflagsname },
683
    [SYS_setuid]	= { Uidname },
684
    [SYS_ptrace]	= { Ptracedecode, Ppid_t, Pptr, Pdecint },
685
    [SYS_recvmsg]	= { Pfd, Pptr, Sendrecvflagsname },
686
    [SYS_sendmsg]	= { Pfd, Pptr, Sendrecvflagsname },
687
    [SYS_recvfrom]	= { Pfd, Pptr, Pbigsize, Sendrecvflagsname },
688
    [SYS_accept]	= { Pfd, Pptr, Pptr },
689
    [SYS_getpeername]	= { Pfd, Pptr, Pptr },
690
    [SYS_getsockname]	= { Pfd, Pptr, Pptr },
691
    [SYS_access]	= { Ppath, Accessmodename },
692
    [SYS_chflags]	= { Ppath, Chflagsname },
693
    [SYS_fchflags]	= { Pfd, Chflagsname },
694
    [SYS_kill]		= { Ppgid, Signame },
695
    [SYS_stat]		= { Ppath, Pptr },
696
    [SYS_lstat]		= { Ppath, Pptr },
697
    [SYS_dup]		= { Pfd },
698
    [SYS_fstatat]	= { Atfd, Ppath, Pptr, Atflagsname },
699
    [SYS_profil]	= { Pptr, Pbigsize, Pbigsize, Pdecuint },
700
    [SYS_ktrace]	= { Ppath, Ktraceopname, Ktracefacname, Ppgid },
701
    [SYS_fktrace]	= { Pfd, Ktraceopname, Ktracefacname, Ppgid },
702
    [SYS_sigaction]	= { Signame, Pptr, Pptr },
703
    [SYS_sigprocmask]	= { Sigprocmaskhowname, Sigset },
704
    [SYS_getlogin_r]	= { Pptr, Psize },
705
    [SYS_setlogin]	= { Pptr },
706
    [SYS_acct]		= { Ppath },
707
    [SYS_fstat]		= { Pfd, Pptr },
708
    [SYS_ioctl]		= { Pfd, Ioctldecode, Pptr },
709
    [SYS_reboot]	= { Rebootoptname },
710
    [SYS_revoke]	= { Ppath },
711
    [SYS_symlink]	= { Ppath, Ppath },
712
    [SYS_readlink]	= { Ppath, Pptr, Psize },
713
    [SYS_execve]	= { Ppath, Pptr, Pptr },
714
    [SYS_umask]		= { Modename },
715
    [SYS_chroot]	= { Ppath },
716
    [SYS_getfsstat]	= { Pptr, Pbigsize, Mountflagsname },
717
    [SYS_statfs]	= { Ppath, Pptr },
718
    [SYS_fstatfs]	= { Pfd, Pptr },
719
    [SYS_fhstatfs]	= { Pptr, Pptr },
720
    [SYS_gettimeofday]	= { Pptr, Pptr },
721
    [SYS_settimeofday]	= { Pptr, Pptr },
722
    [SYS_setitimer]	= { Itimername, Pptr, Pptr },
723
    [SYS_getitimer]	= { Itimername, Pptr },
724
    [SYS_select]	= { Pcount, Pptr, Pptr, Pptr, Pptr },
725
    [SYS_kevent]	= { Pfd, Pptr, Pcount, Pptr, Pcount, Pptr },
726
    [SYS_munmap]	= { Pptr, Pbigsize },
727
    [SYS_mprotect]	= { Pptr, Pbigsize, Mmapprotname },
728
    [SYS_madvise]	= { Pptr, Pbigsize, Madvisebehavname },
729
    [SYS_utimes]	= { Ppath, Pptr },
730
    [SYS_futimes]	= { Pfd, Pptr },
731
    [SYS_kbind]		= { Pptr, Psize, Phexlonglong },
732
    [SYS_mincore]	= { Pptr, Pbigsize, Pptr },
733
    [SYS_getgroups]	= { Pcount, Pptr },
734
    [SYS_setgroups]	= { Pcount, Pptr },
735
    [SYS_setpgid]	= { Ppid_t, Ppid_t },
736
    [SYS_futex]		= { Pptr, Futexflagname, Pcount, Pptr, Pptr },
737
    [SYS_sendsyslog]	= { Pptr, Psize, Syslogflagname },
738
    [SYS_utimensat]	= { Atfd, Ppath, Pptr, Atflagsname },
739
    [SYS_futimens]	= { Pfd, Pptr },
740
    [SYS_clock_gettime]	= { Clockname, Pptr },
741
    [SYS_clock_settime]	= { Clockname, Pptr },
742
    [SYS_clock_getres]	= { Clockname, Pptr },
743
    [SYS_dup2]		= { Pfd, Pfd },
744
    [SYS_nanosleep]	= { Pptr, Pptr },
745
    [SYS_fcntl]		= { Pfd, PASS_TWO, Fcntlcmdname },
746
    [SYS_accept4]	= { Pfd, Pptr, Pptr, Sockflagsname },
747
    [SYS___thrsleep]	= { Pptr, Clockname, Pptr, Pptr, Pptr },
748
    [SYS_fsync]		= { Pfd },
749
    [SYS_setpriority]	= { Prioname, Ppid_t, Pdecint },
750
    [SYS_socket]	= { Sockfamilyname, Socktypename, Sockprotoname },
751
    [SYS_connect]	= { Pfd, Pptr, Pucount },
752
    [SYS_getdents]	= { Pfd, Pptr, Pbigsize },
753
    [SYS_getpriority]	= { Prioname, Ppid_t },
754
    [SYS_pipe2]		= { Pptr, Flagsname },
755
    [SYS_dup3]		= { Pfd, Pfd, Flagsname },
756
    [SYS_sigreturn]	= { Pptr },
757
    [SYS_bind]		= { Pfd, Pptr, Pucount },
758
    [SYS_setsockopt]	= { Pfd, PASS_TWO, Sockoptlevelname, Pptr, Pdecint },
759
    [SYS_listen]	= { Pfd, Pdecint },
760
    [SYS_chflagsat]	= { Atfd, Ppath, Chflagsname, Atflagsname },
761
    [SYS_ppoll]		= { Pptr, Pucount, Pptr, Pptr },
762
    [SYS_pselect]	= { Pcount, Pptr, Pptr, Pptr, Pptr, Pptr },
763
    [SYS_sigsuspend]	= { Sigset },
764
    [SYS_getsockopt]	= { Pfd, PASS_TWO, Sockoptlevelname, Pptr, Pptr },
765
    [SYS_thrkill]	= { Ppid_t, Signame, Pptr },
766
    [SYS_readv]		= { Pfd, Pptr, Pcount },
767
    [SYS_writev]	= { Pfd, Pptr, Pcount },
768
    [SYS_fchown]	= { Pfd, Uidname, Gidname },
769
    [SYS_fchmod]	= { Pfd, Modename },
770
    [SYS_setreuid]	= { Uidname, Uidname },
771
    [SYS_setregid]	= { Gidname, Gidname },
772
    [SYS_rename]	= { Ppath, Ppath },
773
    [SYS_flock]		= { Pfd, Flockname },
774
    [SYS_mkfifo]	= { Ppath, Modename },
775
    [SYS_sendto]	= { Pfd, Pptr, Pbigsize, Sendrecvflagsname },
776
    [SYS_shutdown]	= { Pfd, Shutdownhowname },
777
    [SYS_socketpair]	= { Sockfamilyname, Socktypename, Sockprotoname, Pptr },
778
    [SYS_mkdir]		= { Ppath, Modename },
779
    [SYS_rmdir]		= { Ppath },
780
    [SYS_adjtime]	= { Pptr, Pptr },
781
    [SYS_quotactl]	= { Ppath, Quotactlname, Uidname, Pptr },
782
    [SYS_nfssvc]	= { Phexint, Pptr },
783
    [SYS_getfh]		= { Ppath, Pptr },
784
    [SYS_sysarch]	= { Pdecint, Pptr },
785
    [SYS_pread]		= { Pfd, Pptr, Pbigsize, PAD, Poff_t },
786
    [SYS_pwrite]	= { Pfd, Pptr, Pbigsize, PAD, Poff_t },
787
    [SYS_setgid]	= { Gidname },
788
    [SYS_setegid]	= { Gidname },
789
    [SYS_seteuid]	= { Uidname },
790
    [SYS_pathconf]	= { Ppath, Pathconfname },
791
    [SYS_fpathconf]	= { Pfd, Pathconfname },
792
    [SYS_swapctl]	= { Swapctlname, Pptr, Pdecint },
793
    [SYS_getrlimit]	= { Rlimitname, Pptr },
794
    [SYS_setrlimit]	= { Rlimitname, Pptr },
795
    [SYS_mmap]		= { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, PAD, Poff_t },
796
    [SYS_lseek]		= { Pfd, PAD, Poff_t, Whencename },
797
    [SYS_truncate]	= { Ppath, PAD, Poff_t },
798
    [SYS_ftruncate]	= { Pfd, PAD, Poff_t },
799
    [SYS_sysctl]	= { Pptr, Pcount, Pptr, Pptr, Pptr, Psize },
800
    [SYS_mlock]		= { Pptr, Pbigsize },
801
    [SYS_munlock]	= { Pptr, Pbigsize },
802
    [SYS_getpgid]	= { Ppid_t },
803
    [SYS_utrace]	= { Pptr, Pptr, Psize },
804
    [SYS_semget]	= { Pkey_t, Pcount, Semgetname },
805
    [SYS_msgget]	= { Pkey_t, Msgflgname },
806
    [SYS_msgsnd]	= { Pmsqid, Pptr, Psize, Msgflgname },
807
    [SYS_msgrcv]	= { Pmsqid, Pptr, Psize, Pdeclong, Msgflgname },
808
    [SYS_shmat]		= { Pshmid, Pptr, Shmatname },
809
    [SYS_shmdt]		= { Pptr },
810
    [SYS_minherit]	= { Pptr, Pbigsize, Minheritname },
811
    [SYS_poll]		= { Pptr, Pucount, Polltimeout },
812
    [SYS_lchown]	= { Ppath, Uidname, Gidname },
813
    [SYS_getsid]	= { Ppid_t },
814
    [SYS_msync]		= { Pptr, Pbigsize, Msyncflagsname },
815
    [SYS_pipe]		= { Pptr },
816
    [SYS_fhopen]	= { Pptr, Openflagsname },
817
    [SYS_preadv]	= { Pfd, Pptr, Pcount, PAD, Poff_t },
818
    [SYS_pwritev]	= { Pfd, Pptr, Pcount, PAD, Poff_t },
819
    [SYS_mlockall]	= { Mlockallname },
820
    [SYS_getresuid]	= { Pptr, Pptr, Pptr },
821
    [SYS_setresuid]	= { Uidname, Uidname, Uidname },
822
    [SYS_getresgid]	= { Pptr, Pptr, Pptr },
823
    [SYS_setresgid]	= { Gidname, Gidname, Gidname },
824
    [SYS_mquery]	= { Pptr, Pbigsize, Mmapprotname, Mmapflagsname, Pfd, PAD, Poff_t },
825
    [SYS_closefrom]	= { Pfd },
826
    [SYS_sigaltstack]	= { Pptr, Pptr },
827
    [SYS_shmget]	= { Pkey_t, Pbigsize, Semgetname },
828
    [SYS_semop]		= { Psemid, Pptr, Psize },
829
    [SYS_fhstat]	= { Pptr, Pptr },
830
    [SYS___semctl]	= { Psemid, Pcount, Semctlname, Pptr },
831
    [SYS_shmctl]	= { Pshmid, Shmctlname, Pptr },
832
    [SYS_msgctl]	= { Pmsqid, Shmctlname, Pptr },
833
    [SYS___thrwakeup]	= { Pptr, Pcount },
834
    [SYS___threxit]	= { Pptr },
835
    [SYS___thrsigdivert] = { Sigset, Pptr, Pptr },
836
    [SYS___getcwd]	= { Pptr, Psize },
837
    [SYS_adjfreq]	= { Pptr, Pptr },
838
    [SYS_setrtable]	= { Pdecint },
839
    [SYS_faccessat]	= { Atfd, Ppath, Accessmodename, Atflagsname },
840
    [SYS_fchmodat]	= { Atfd, Ppath, Modename, Atflagsname },
841
    [SYS_fchownat]	= { Atfd, Ppath, Uidname, Gidname, Atflagsname },
842
    [SYS_linkat]	= { Atfd, Ppath, Atfd, Ppath, Atflagsname },
843
    [SYS_mkdirat]	= { Atfd, Ppath, Modename },
844
    [SYS_mkfifoat]	= { Atfd, Ppath, Modename },
845
    [SYS_mknodat]	= { Atfd, Ppath, Modename, Pdev_t },
846
    [SYS_openat]	= { Atfd, Ppath, PASS_TWO, Flagsandmodename },
847
    [SYS_readlinkat]	= { Atfd, Ppath, Pptr, Psize },
848
    [SYS_renameat]	= { Atfd, Ppath, Atfd, Ppath },
849
    [SYS_symlinkat]	= { Ppath, Atfd, Ppath },
850
    [SYS_unlinkat]	= { Atfd, Ppath, Atflagsname },
851
    [SYS___set_tcb]	= { Pptr },
852
};
853
854
855
static void
856
ktrsyscall(struct ktr_syscall *ktr, size_t ktrlen)
857
{
858
	register_t *ap;
859
	int narg;
860
	char sep;
861
862
3679846
	if (ktr->ktr_argsize > ktrlen)
863
		errx(1, "syscall argument length %d > ktr header length %zu",
864
		    ktr->ktr_argsize, ktrlen);
865
866
1839923
	narg = ktr->ktr_argsize / sizeof(register_t);
867
	sep = '\0';
868
869

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

19480518
		while (narg && (fmt = *fmts) != 0) {
910
5266716
			if (sep)
911
5602802
				putchar(sep);
912
			sep = ',';
913
5266716
			if (!fancy && !FMT_IS_NONFANCY(fmt))
914
				fmt = Pnonfancy;
915
5266716
			if (fmt > 0)
916
2219544
				formatters[fmt]((int)*ap);
917
3047172
			else if (long_formatters[-fmt](*ap))
918
638825
				sep = '\0';
919
5266716
			fmts++;
920
5266716
			ap++;
921
5266716
			narg--;
922
		}
923
1838363
	}
924
925
3704498
	while (narg > 0) {
926
12326
		if (sep)
927
22684
			putchar(sep);
928
12326
		if (decimal)
929
			(void)printf("%ld", (long)*ap);
930
		else
931
12326
			(void)printf("%#lx", (long)*ap);
932
		sep = ',';
933
12326
		ap++;
934
12326
		narg--;
935
	}
936
1839923
	(void)printf(")\n");
937
1839923
}
938
939
static struct ctlname topname[] = CTL_NAMES;
940
static struct ctlname kernname[] = CTL_KERN_NAMES;
941
static struct ctlname vmname[] = CTL_VM_NAMES;
942
static struct ctlname fsname[] = CTL_FS_NAMES;
943
static struct ctlname netname[] = CTL_NET_NAMES;
944
static struct ctlname hwname[] = CTL_HW_NAMES;
945
static struct ctlname debugname[CTL_DEBUG_MAXID];
946
static struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES;
947
static struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES;
948
static struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES;
949
static struct ctlname kernprocname[] = {
950
	{ NULL },
951
	{ "all" },
952
	{ "pid" },
953
	{ "pgrp" },
954
	{ "session" },
955
	{ "tty" },
956
	{ "uid" },
957
	{ "ruid" },
958
	{ "kthread" },
959
};
960
static struct ctlname ttysname[] = CTL_KERN_TTY_NAMES;
961
static struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES;
962
static struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES;
963
static struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES;
964
static struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES;
965
#ifdef CTL_MACHDEP_NAMES
966
static struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
967
#endif
968
static struct ctlname ddbname[] = CTL_DDB_NAMES;
969
970
#ifndef nitems
971
#define nitems(_a)    (sizeof((_a)) / sizeof((_a)[0]))
972
#endif
973
974
#define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)
975
976
static const char *
977
kresolvsysctl(int depth, const int *top)
978
{
979
	struct ctlname *names;
980
	size_t		limit;
981
7800
	int		idx = top[depth];
982
983
	names = NULL;
984
985

4680
	switch (depth) {
986
	case 0:
987
		SETNAME(topname);
988
1560
		break;
989
	case 1:
990


3120
		switch (top[0]) {
991
		case CTL_KERN:
992
			SETNAME(kernname);
993
1040
			break;
994
		case CTL_VM:
995
			SETNAME(vmname);
996
260
			break;
997
		case CTL_FS:
998
			SETNAME(fsname);
999
			break;
1000
		case CTL_NET:
1001
			SETNAME(netname);
1002
			break;
1003
		case CTL_DEBUG:
1004
			SETNAME(debugname);
1005
			break;
1006
		case CTL_HW:
1007
			SETNAME(hwname);
1008
260
			break;
1009
#ifdef CTL_MACHDEP_NAMES
1010
		case CTL_MACHDEP:
1011
			SETNAME(machdepname);
1012
			break;
1013
#endif
1014
		case CTL_DDB:
1015
			SETNAME(ddbname);
1016
			break;
1017
		}
1018
		break;
1019
	case 2:
1020
		switch (top[0]) {
1021
		case CTL_KERN:
1022
			switch (top[1]) {
1023
			case KERN_MALLOCSTATS:
1024
				SETNAME(kernmallocname);
1025
				break;
1026
			case KERN_FORKSTAT:
1027
				SETNAME(forkstatname);
1028
				break;
1029
			case KERN_NCHSTATS:
1030
				SETNAME(nchstatsname);
1031
				break;
1032
			case KERN_TTY:
1033
				SETNAME(ttysname);
1034
				break;
1035
			case KERN_SEMINFO:
1036
				SETNAME(semname);
1037
				break;
1038
			case KERN_SHMINFO:
1039
				SETNAME(shmname);
1040
				break;
1041
			case KERN_WATCHDOG:
1042
				SETNAME(watchdogname);
1043
				break;
1044
			case KERN_PROC:
1045
				idx++;	/* zero is valid at this level */
1046
				SETNAME(kernprocname);
1047
				break;
1048
			case KERN_TIMECOUNTER:
1049
				SETNAME(tcname);
1050
				break;
1051
			}
1052
		}
1053
		break;
1054
	}
1055

6240
	if (names != NULL && idx > 0 && idx < limit)
1056
3120
		return (names[idx].ctl_name);
1057
	return (NULL);
1058
3120
}
1059
1060
static void
1061
ktrsysret(struct ktr_sysret *ktr, size_t ktrlen)
1062
{
1063
	register_t ret = 0;
1064
	long long retll;
1065
3679852
	int error = ktr->ktr_error;
1066
1839926
	int code = ktr->ktr_code;
1067
1068
1839926
	if (ktrlen < sizeof(*ktr))
1069
		errx(1, "sysret length %zu < ktr header length %zu",
1070
		    ktrlen, sizeof(*ktr));
1071
1839926
	ktrlen -= sizeof(*ktr);
1072
1839926
	if (error == 0) {
1073
1236646
		if (ktrlen == sizeof(ret)) {
1074
1236646
			memcpy(&ret, ktr+1, sizeof(ret));
1075
			retll = ret;
1076
1236646
		} else if (ktrlen == sizeof(retll))
1077
			memcpy(&retll, ktr+1, sizeof(retll));
1078
		else
1079
			errx(1, "sysret bogus length %zu", ktrlen);
1080
	}
1081
1082
3679852
	if (code >= SYS_MAXSYSCALL || code < 0)
1083
		(void)printf("[%d] ", code);
1084
	else
1085
1839926
		(void)printf("%s ", syscallnames[code]);
1086
1087
doerr:
1088
1839926
	if (error == 0) {
1089
1236646
		if (fancy) {
1090


1236646
			switch (code) {
1091
			case SYS_lseek:
1092
75229
				(void)printf("%lld", retll);
1093
75229
				if (retll < 0 || retll > 9)
1094
75045
					(void)printf("/%#llx", retll);
1095
				break;
1096
			case SYS_sigprocmask:
1097
			case SYS_sigpending:
1098
2490
				sigset(ret);
1099
2490
				break;
1100
			case SYS___thrsigdivert:
1101
				signame(ret);
1102
				break;
1103
			case SYS_getuid:
1104
			case SYS_geteuid:
1105
464
				uidname(ret);
1106
464
				break;
1107
			case SYS_getgid:
1108
			case SYS_getegid:
1109
464
				gidname(ret);
1110
464
				break;
1111
			/* syscalls that return errno values */
1112
			case SYS_getlogin_r:
1113
			case SYS___thrsleep:
1114
				if ((error = ret) != 0)
1115
					goto doerr;
1116
				/* FALLTHROUGH */
1117
			default:
1118
1157999
				(void)printf("%ld", (long)ret);
1119
1157999
				if (ret < 0 || ret > 9)
1120
266845
					(void)printf("/%#lx", (long)ret);
1121
			}
1122
		} else {
1123
			if (decimal)
1124
				(void)printf("%lld", retll);
1125
			else
1126
				(void)printf("%#llx", retll);
1127
		}
1128
603280
	} else if (error == ERESTART)
1129
524
		(void)printf("RESTART");
1130
602756
	else if (error == EJUSTRETURN)
1131
1143
		(void)printf("JUSTRETURN");
1132
	else {
1133
601613
		(void)printf("-1 errno %d", error);
1134
601613
		if (fancy)
1135
601613
			(void)printf(" %s", strerror(error));
1136
	}
1137
3679852
	(void)putchar('\n');
1138
1839926
}
1139
1140
static void
1141
ktrnamei(const char *cp, size_t len)
1142
{
1143
1380612
	showbufc(basecol, (unsigned char *)cp, len, VIS_DQ | VIS_TAB | VIS_NL);
1144
690306
}
1145
1146
void
1147
showbufc(int col, unsigned char *dp, size_t datalen, int flags)
1148
{
1149
	int width;
1150
1730686
	unsigned char visbuf[5], *cp;
1151
1152
865343
	flags |= VIS_CSTYLE;
1153
1730686
	putchar('"');
1154
865343
	col++;
1155
123077414
	for (; datalen > 0; datalen--, dp++) {
1156
60673364
		(void)vis(visbuf, *dp, flags, *(dp+1));
1157
		cp = visbuf;
1158
1159
		/*
1160
		 * Keep track of printables and
1161
		 * space chars (like fold(1)).
1162
		 */
1163
60673364
		if (col == 0) {
1164
436244
			(void)putchar('\t');
1165
			col = 8;
1166
218122
		}
1167
60673364
		switch (*cp) {
1168
		case '\n':
1169
			col = 0;
1170
653392
			(void)putchar('\n');
1171
			continue;
1172
		case '\t':
1173
523046
			width = 8 - (col&07);
1174
523046
			break;
1175
		default:
1176
59823622
			width = strlen(cp);
1177
59823622
		}
1178
60346668
		if (col + width > (screenwidth-2)) {
1179
922039
			(void)printf("\\\n\t");
1180
			col = 8;
1181
922039
		}
1182
60346668
		col += width;
1183
60346668
		do {
1184
199225218
			(void)putchar(*cp++);
1185
99612609
		} while (*cp);
1186
	}
1187
865343
	if (col == 0)
1188
108574
		(void)printf("       ");
1189
865343
	(void)printf("\"\n");
1190
865343
}
1191
1192
static void
1193
showbuf(unsigned char *dp, size_t datalen)
1194
{
1195
	int i, j;
1196
	int col = 0, bpl;
1197
	unsigned char c;
1198
1199
338468
	if (iohex == 1) {
1200
		putchar('\t');
1201
		col = 8;
1202
		for (i = 0; i < datalen; i++) {
1203
			printf("%02x", dp[i]);
1204
			col += 3;
1205
			if (i < datalen - 1) {
1206
				if (col + 3 > screenwidth) {
1207
					printf("\n\t");
1208
					col = 8;
1209
				} else
1210
					putchar(' ');
1211
			}
1212
		}
1213
		putchar('\n');
1214
		return;
1215
	}
1216
169234
	if (iohex == 2) {
1217
		bpl = (screenwidth - 13)/4;
1218
		if (bpl <= 0)
1219
			bpl = 1;
1220
		for (i = 0; i < datalen; i += bpl) {
1221
			printf("   %04x:  ", i);
1222
			for (j = 0; j < bpl; j++) {
1223
				if (i+j >= datalen)
1224
					printf("   ");
1225
				else
1226
					printf("%02x ", dp[i+j]);
1227
			}
1228
			putchar(' ');
1229
			for (j = 0; j < bpl; j++) {
1230
				if (i+j >= datalen)
1231
					break;
1232
				c = dp[i+j];
1233
				if (!isprint(c))
1234
					c = '.';
1235
				putchar(c);
1236
			}
1237
			putchar('\n');
1238
		}
1239
		return;
1240
	}
1241
1242
169234
	(void)printf("       ");
1243
169234
	showbufc(7, dp, datalen, 0);
1244
338468
}
1245
1246
static void
1247
ktrgenio(struct ktr_genio *ktr, size_t len)
1248
{
1249
338468
	unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
1250
	size_t datalen;
1251
1252
169234
	if (len < sizeof(struct ktr_genio))
1253
		errx(1, "invalid ktr genio length %zu", len);
1254
1255
169234
	datalen = len - sizeof(struct ktr_genio);
1256
1257
338468
	printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1258
169234
		ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
1259
169234
	if (maxdata == 0)
1260
		return;
1261
169234
	if (datalen > maxdata)
1262
		datalen = maxdata;
1263
169234
	if (iohex && !datalen)
1264
		return;
1265
169234
	showbuf(dp, datalen);
1266
338468
}
1267
1268
static void
1269
ktrpsig(struct ktr_psig *psig)
1270
{
1271
2288
	signame(psig->signo);
1272
1144
	printf(" ");
1273
1144
	if (psig->action == SIG_DFL)
1274
		(void)printf("SIG_DFL");
1275
	else {
1276
1144
		(void)printf("caught handler=0x%lx mask=",
1277
1144
		    (u_long)psig->action);
1278
1144
		sigset(psig->mask);
1279
	}
1280
1144
	if (psig->code) {
1281
		printf(" code ");
1282
		if (fancy) {
1283
			switch (psig->signo) {
1284
			case SIGILL:
1285
				sigill_name(psig->code);
1286
				break;
1287
			case SIGTRAP:
1288
				sigtrap_name(psig->code);
1289
				break;
1290
			case SIGEMT:
1291
				sigemt_name(psig->code);
1292
				break;
1293
			case SIGFPE:
1294
				sigfpe_name(psig->code);
1295
				break;
1296
			case SIGBUS:
1297
				sigbus_name(psig->code);
1298
				break;
1299
			case SIGSEGV:
1300
				sigsegv_name(psig->code);
1301
				break;
1302
			case SIGCHLD:
1303
				sigchld_name(psig->code);
1304
				break;
1305
			}
1306
		}
1307
		printf("<%d>", psig->code);
1308
	}
1309
1310

1144
	switch (psig->signo) {
1311
	case SIGSEGV:
1312
	case SIGILL:
1313
	case SIGBUS:
1314
	case SIGFPE:
1315
		printf(" addr=%p trapno=%d", psig->si.si_addr,
1316
		    psig->si.si_trapno);
1317
		break;
1318
	default:
1319
		break;
1320
	}
1321
1144
	printf("\n");
1322
1144
}
1323
1324
static void
1325
ktruser(struct ktr_user *usr, size_t len)
1326
{
1327
	if (len < sizeof(struct ktr_user))
1328
		errx(1, "invalid ktr user length %zu", len);
1329
	len -= sizeof(struct ktr_user);
1330
	printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id);
1331
	printf(" %zu bytes\n", len);
1332
	showbuf((unsigned char *)(usr + 1), len);
1333
}
1334
1335
static void
1336
ktrexec(const char *ptr, size_t len)
1337
{
1338
	int i, col;
1339
	size_t l;
1340
1341
2961
	putchar('\n');
1342
	i = 0;
1343
11612
	while (len > 0) {
1344
4819
		l = strnlen(ptr, len);
1345
4819
		col = printf("\t[%d] = ", i++);
1346
4819
		col += 7;	/* tab expands from 1 to 8 columns */
1347
4819
		showbufc(col, (unsigned char *)ptr, l, VIS_DQ|VIS_TAB|VIS_NL);
1348
4819
		if (l == len) {
1349
			printf("\tunterminated argument\n");
1350
			break;
1351
		}
1352
4819
		len -= l + 1;
1353
4819
		ptr += l + 1;
1354
	}
1355
987
}
1356
1357
static void
1358
ktrpledge(struct ktr_pledge *pledge, size_t len)
1359
{
1360
	char *name = "";
1361
	int i;
1362
1363
	if (len < sizeof(struct ktr_pledge))
1364
		errx(1, "invalid ktr pledge length %zu", len);
1365
1366
	if (pledge->syscall >= SYS_MAXSYSCALL || pledge->syscall < 0)
1367
		(void)printf("[%d]", pledge->syscall);
1368
	else
1369
		(void)printf("%s", syscallnames[pledge->syscall]);
1370
	printf(", ");
1371
	for (i = 0; pledge->code && pledgenames[i].bits != 0; i++) {
1372
		if (pledgenames[i].bits & pledge->code) {
1373
			name = pledgenames[i].name;
1374
			break;
1375
		}
1376
	}
1377
	printf("\"%s\"", name);
1378
	(void)printf(", errno %d", pledge->error);
1379
	if (fancy)
1380
		(void)printf(" %s", strerror(pledge->error));
1381
	printf("\n");
1382
}
1383
1384
static void
1385
usage(void)
1386
{
1387
1388
	extern char *__progname;
1389
	fprintf(stderr, "usage: %s "
1390
	    "[-dHlnRTXx] [-f file] [-m maxdata] [-p pid]\n"
1391
	    "%*s[-t [cinpstuxX+]]\n",
1392
	    __progname, (int)(sizeof("usage: ") + strlen(__progname)), "");
1393
	exit(1);
1394
}
1395
1396
1397
/*
1398
 * FORMATTERS
1399
 */
1400
1401
static void
1402
ioctldecode(int cmd)
1403
{
1404
536
	char dirbuf[4], *dir = dirbuf;
1405
	const char *cp;
1406
1407
268
	if ((cp = ioctlname((unsigned)cmd)) != NULL) {
1408
268
		(void)printf("%s", cp);
1409
268
		return;
1410
	}
1411
1412
	if (cmd & IOC_IN)
1413
		*dir++ = 'W';
1414
	if (cmd & IOC_OUT)
1415
		*dir++ = 'R';
1416
	*dir = '\0';
1417
1418
	printf("_IO%s('%c',%d",
1419
	    dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1420
	if ((cmd & IOC_VOID) == 0)
1421
		printf(decimal ? ",%u)" : ",%#x)", (cmd >> 16) & 0xff);
1422
	else
1423
		printf(")");
1424
268
}
1425
1426
static void
1427
ptracedecode(int request)
1428
{
1429
	if (request >= 0 && request < nitems(ptrace_ops))
1430
		(void)printf("%s", ptrace_ops[request]);
1431
	else switch(request) {
1432
#ifdef PT_GETFPREGS
1433
	case PT_GETFPREGS:
1434
		(void)printf("PT_GETFPREGS");
1435
		break;
1436
#endif
1437
	case PT_GETREGS:
1438
		(void)printf("PT_GETREGS");
1439
		break;
1440
#ifdef PT_GETXMMREGS
1441
	case PT_GETXMMREGS:
1442
		(void)printf("PT_GETXMMREGS");
1443
		break;
1444
#endif
1445
#ifdef PT_SETFPREGS
1446
	case PT_SETFPREGS:
1447
		(void)printf("PT_SETFPREGS");
1448
		break;
1449
#endif
1450
	case PT_SETREGS:
1451
		(void)printf("PT_SETREGS");
1452
		break;
1453
#ifdef PT_SETXMMREGS
1454
	case PT_SETXMMREGS:
1455
		(void)printf("PT_SETXMMREGS");
1456
		break;
1457
#endif
1458
#ifdef PT_STEP
1459
	case PT_STEP:
1460
		(void)printf("PT_STEP");
1461
		break;
1462
#endif
1463
#ifdef PT_WCOOKIE
1464
	case PT_WCOOKIE:
1465
		(void)printf("PT_WCOOKIE");
1466
		break;
1467
#endif
1468
	default:
1469
		pdecint(request);
1470
	}
1471
}
1472
1473
1474
static void
1475
atfd(int fd)
1476
{
1477
	if (fd == AT_FDCWD)
1478
		(void)printf("AT_FDCWD");
1479
	else
1480
		pdecint(fd);
1481
}
1482
1483
static void
1484
polltimeout(int timeout)
1485
{
1486
24
	if (timeout == INFTIM)
1487
		(void)printf("INFTIM");
1488
	else
1489
12
		pdecint(timeout);
1490
12
}
1491
1492
static void
1493
wait4pid(int pid)
1494
{
1495
2404
	if (pid == WAIT_ANY)
1496
1182
		(void)printf("WAIT_ANY");
1497
20
	else if (pid == WAIT_MYPGRP)
1498
		(void)printf("WAIT_MYPGRP");
1499
	else
1500
20
		pdecint(pid);		/* ppgid */
1501
1202
}
1502
1503
static void
1504
signame(int sig)
1505
{
1506
40248
	if (sig > 0 && sig < NSIG)
1507
20124
		(void)printf("SIG%s", sys_signame[sig]);
1508
	else
1509
		(void)printf("SIG %d", sig);
1510
20124
}
1511
1512
void
1513
sigset(int ss)
1514
{
1515
	int	or = 0;
1516
	int	cnt = 0;
1517
	int	i;
1518
1519
1583736
	for (i = 1; i < NSIG; i++)
1520
767872
		if (sigismember(&ss, i))
1521
33260
			cnt++;
1522
23996
	if (cnt > (NSIG-1)/2) {
1523
984
		ss = ~ss;
1524
1968
		putchar('~');
1525
	}
1526
1527
23996
	if (ss == 0) {
1528
20256
		(void)printf("0<>");
1529
20256
		return;
1530
	}
1531
1532
3740
	printf("%#x<", ss);
1533
246840
	for (i = 1; i < NSIG; i++)
1534
119680
		if (sigismember(&ss, i)) {
1535

3740
			if (or) putchar('|'); else or=1;
1536
3740
			signame(i);
1537
3740
		}
1538
3740
	printf(">");
1539
27736
}
1540
1541
static void
1542
semctlname(int cmd)
1543
{
1544
	switch (cmd) {
1545
	case GETNCNT:
1546
		(void)printf("GETNCNT");
1547
		break;
1548
	case GETPID:
1549
		(void)printf("GETPID");
1550
		break;
1551
	case GETVAL:
1552
		(void)printf("GETVAL");
1553
		break;
1554
	case GETALL:
1555
		(void)printf("GETALL");
1556
		break;
1557
	case GETZCNT:
1558
		(void)printf("GETZCNT");
1559
		break;
1560
	case SETVAL:
1561
		(void)printf("SETVAL");
1562
		break;
1563
	case SETALL:
1564
		(void)printf("SETALL");
1565
		break;
1566
	case IPC_RMID:
1567
		(void)printf("IPC_RMID");
1568
		break;
1569
	case IPC_SET:
1570
		(void)printf("IPC_SET");
1571
		break;
1572
	case IPC_STAT:
1573
		(void)printf("IPC_STAT");
1574
		break;
1575
	default: /* Should not reach */
1576
		(void)printf("<invalid=%d>", cmd);
1577
	}
1578
}
1579
1580
static void
1581
shmctlname(int cmd)
1582
{
1583
	switch (cmd) {
1584
	case IPC_RMID:
1585
		(void)printf("IPC_RMID");
1586
		break;
1587
	case IPC_SET:
1588
		(void)printf("IPC_SET");
1589
		break;
1590
	case IPC_STAT:
1591
		(void)printf("IPC_STAT");
1592
		break;
1593
	default: /* Should not reach */
1594
		(void)printf("<invalid=%d>", cmd);
1595
	}
1596
}
1597
1598
1599
static void
1600
semgetname(int flag)
1601
{
1602
	int	or = 0;
1603
	if_print_or(flag, IPC_CREAT, or);
1604
	if_print_or(flag, IPC_EXCL, or);
1605
	if_print_or(flag, SEM_R, or);
1606
	if_print_or(flag, SEM_A, or);
1607
	if_print_or(flag, (SEM_R>>3), or);
1608
	if_print_or(flag, (SEM_A>>3), or);
1609
	if_print_or(flag, (SEM_R>>6), or);
1610
	if_print_or(flag, (SEM_A>>6), or);
1611
1612
	if (flag & ~(IPC_CREAT|IPC_EXCL|SEM_R|SEM_A|((SEM_R|SEM_A)>>3)|
1613
	    ((SEM_R|SEM_A)>>6)))
1614
		printf("<invalid=%#x>", flag);
1615
}
1616
1617
1618
/*
1619
 * Only used by SYS_open and SYS_openat. Unless O_CREAT is set in flags, the
1620
 * mode argument is unused (and often bogus and misleading).
1621
 */
1622
static void
1623
flagsandmodename(int mode)
1624
{
1625
681434
	openflagsname(arg1);
1626
340717
	if ((arg1 & O_CREAT) == O_CREAT) {
1627
341122
		(void)putchar(',');
1628
170561
		modename(mode);
1629
340717
	} else if (!fancy)
1630
		(void)printf(",<unused>%#o", mode);
1631
340717
}
1632
1633
static void
1634
clockname(int clockid)
1635
{
1636
10020
	clocktypename(__CLOCK_TYPE(clockid));
1637
5010
	if (__CLOCK_PTID(clockid) != 0)
1638
		printf("(%d)", __CLOCK_PTID(clockid));
1639
5010
}
1640
1641
/*
1642
 * [g|s]etsockopt's level argument can either be SOL_SOCKET or a value
1643
 * referring to a line in /etc/protocols.
1644
 */
1645
static void
1646
sockoptlevelname(int optname)
1647
{
1648
	struct protoent *pe;
1649
1650
10504
	if (arg1 == SOL_SOCKET) {
1651
5252
		(void)printf("SOL_SOCKET,");
1652
5252
		sockoptname(optname);
1653
5252
	} else {
1654
		pe = getprotobynumber(arg1);
1655
		(void)printf("%u<%s>,%d", arg1,
1656
		    pe != NULL ? pe->p_name : "unknown", optname);
1657
	}
1658
5252
}
1659
1660
static void
1661
ktraceopname(int ops)
1662
{
1663
	int invalid = 0;
1664
1665
	printf("%#x<", ops);
1666
	switch (KTROP(ops)) {
1667
	case KTROP_SET:
1668
		printf("KTROP_SET");
1669
		break;
1670
	case KTROP_CLEAR:
1671
		printf("KTROP_CLEAR");
1672
		break;
1673
	case KTROP_CLEARFILE:
1674
		printf("KTROP_CLEARFILE");
1675
		break;
1676
	default:
1677
		printf("KTROP(%d)", KTROP(ops));
1678
		invalid = 1;
1679
		break;
1680
	}
1681
	if (ops & KTRFLAG_DESCEND) printf("|KTRFLAG_DESCEND");
1682
	printf(">");
1683
	if (invalid || (ops & ~(KTROP((unsigned)-1) | KTRFLAG_DESCEND)))
1684
		(void)printf("<invalid>%d", ops);
1685
}