Home | History | Annotate | Line # | Download | only in kdump
kdump.c revision 1.96.4.3
      1  1.96.4.3  wrstuden /*	$NetBSD: kdump.c,v 1.96.4.3 2008/09/24 16:38:59 wrstuden Exp $	*/
      2      1.17     mikel 
      3       1.1       cgd /*-
      4       1.1       cgd  * Copyright (c) 1988, 1993
      5       1.1       cgd  *	The Regents of the University of California.  All rights reserved.
      6       1.1       cgd  *
      7       1.1       cgd  * Redistribution and use in source and binary forms, with or without
      8       1.1       cgd  * modification, are permitted provided that the following conditions
      9       1.1       cgd  * are met:
     10       1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     11       1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     12       1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     14       1.1       cgd  *    documentation and/or other materials provided with the distribution.
     15      1.59       agc  * 3. Neither the name of the University nor the names of its contributors
     16       1.1       cgd  *    may be used to endorse or promote products derived from this software
     17       1.1       cgd  *    without specific prior written permission.
     18       1.1       cgd  *
     19       1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20       1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21       1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22       1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23       1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24       1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25       1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26       1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27       1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28       1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29       1.1       cgd  * SUCH DAMAGE.
     30       1.1       cgd  */
     31       1.1       cgd 
     32      1.17     mikel #include <sys/cdefs.h>
     33       1.1       cgd #ifndef lint
     34  1.96.4.2  wrstuden __COPYRIGHT("@(#) Copyright (c) 1988, 1993\
     35  1.96.4.2  wrstuden  The Regents of the University of California.  All rights reserved.");
     36       1.1       cgd #endif /* not lint */
     37       1.1       cgd 
     38       1.1       cgd #ifndef lint
     39      1.12       jtc #if 0
     40      1.12       jtc static char sccsid[] = "@(#)kdump.c	8.4 (Berkeley) 4/28/95";
     41      1.17     mikel #else
     42  1.96.4.3  wrstuden __RCSID("$NetBSD: kdump.c,v 1.96.4.3 2008/09/24 16:38:59 wrstuden Exp $");
     43      1.12       jtc #endif
     44       1.1       cgd #endif /* not lint */
     45       1.1       cgd 
     46       1.1       cgd #include <sys/param.h>
     47      1.14     mikel #define _KERNEL
     48       1.1       cgd #include <sys/errno.h>
     49      1.14     mikel #undef _KERNEL
     50       1.1       cgd #include <sys/time.h>
     51       1.1       cgd #include <sys/uio.h>
     52       1.1       cgd #include <sys/ktrace.h>
     53       1.1       cgd #include <sys/ioctl.h>
     54       1.1       cgd #include <sys/ptrace.h>
     55       1.4   mycroft 
     56      1.46      manu #include <ctype.h>
     57       1.4   mycroft #include <err.h>
     58       1.4   mycroft #include <signal.h>
     59      1.48       dsl #include <stddef.h>
     60       1.1       cgd #include <stdio.h>
     61       1.1       cgd #include <stdlib.h>
     62       1.1       cgd #include <string.h>
     63       1.4   mycroft #include <unistd.h>
     64       1.4   mycroft #include <vis.h>
     65       1.4   mycroft 
     66       1.1       cgd #include "ktrace.h"
     67      1.28  jdolecek #include "setemul.h"
     68      1.28  jdolecek 
     69      1.28  jdolecek #include <sys/syscall.h>
     70       1.1       cgd 
     71      1.81  christos static int timestamp, decimal, plain, tail, maxdata = -1, numeric;
     72      1.81  christos static int word_size = 0;
     73      1.81  christos static pid_t do_pid = -1;
     74      1.81  christos static const char *tracefile = NULL;
     75      1.81  christos static struct ktr_header ktr_header;
     76      1.81  christos static int emul_changed = 0;
     77       1.1       cgd 
     78       1.1       cgd #define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
     79      1.73  christos #define small(v)	(((long)(v) >= 0) && ((long)(v) < 10))
     80       1.1       cgd 
     81      1.78      matt static const char * const ptrace_ops[] = {
     82      1.11  christos 	"PT_TRACE_ME",	"PT_READ_I",	"PT_READ_D",	"PT_READ_U",
     83      1.11  christos 	"PT_WRITE_I",	"PT_WRITE_D",	"PT_WRITE_U",	"PT_CONTINUE",
     84      1.78      matt 	"PT_KILL",	"PT_ATTACH",	"PT_DETACH",	"PT_IO",
     85      1.84  christos 	"PT_DUMPCORE",	"PT_LWPINFO", 	"PT_SYSCALL",
     86      1.11  christos };
     87      1.11  christos 
     88      1.78      matt #ifdef PT_MACHDEP_STRINGS
     89      1.78      matt static const char * const ptrace_machdep_ops[] = { PT_MACHDEP_STRINGS };
     90      1.78      matt #endif
     91      1.78      matt 
     92      1.78      matt static const char * const linux_ptrace_ops[] = {
     93      1.31  jdolecek 	"PTRACE_TRACEME",
     94      1.31  jdolecek 	"PTRACE_PEEKTEXT", "PTRACE_PEEKDATA", "PTRACE_PEEKUSER",
     95      1.31  jdolecek 	"PTRACE_POKETEXT", "PTRACE_POKEDATA", "PTRACE_POKEUSER",
     96      1.31  jdolecek 	"PTRACE_CONT", "PTRACE_KILL", "PTRACE_SINGLESTEP",
     97      1.31  jdolecek 	NULL, NULL,
     98      1.31  jdolecek 	"PTRACE_GETREGS", "PTRACE_SETREGS", "PTRACE_GETFPREGS",
     99      1.31  jdolecek 	"PTRACE_SETFPREGS", "PTRACE_ATTACH", "PTRACE_DETACH",
    100      1.96     njoly 	NULL, NULL, NULL, NULL, NULL, NULL,
    101      1.31  jdolecek 	"PTRACE_SYSCALL",
    102      1.31  jdolecek };
    103      1.31  jdolecek 
    104      1.72       mrg int	main(int, char **);
    105      1.81  christos static int	fread_tail(void *, size_t, size_t);
    106      1.81  christos static int	dumpheader(struct ktr_header *);
    107      1.81  christos static void	output_long(u_long, int);
    108      1.81  christos static void	ioctldecode(u_long);
    109      1.81  christos static void	ktrsyscall(struct ktr_syscall *);
    110      1.81  christos static void	ktrsysret(struct ktr_sysret *, int);
    111      1.81  christos static void	ktrnamei(char *, int);
    112      1.81  christos static void	ktremul(char *, int, int);
    113      1.81  christos static void	ktrgenio(struct ktr_genio *, int);
    114      1.81  christos static void	ktrpsig(void *, int);
    115      1.81  christos static void	ktrcsw(struct ktr_csw *);
    116      1.81  christos static void	ktruser(struct ktr_user *, int);
    117      1.81  christos static void	ktrmmsg(struct ktr_mmsg *, int);
    118      1.81  christos static void	ktrmool(struct ktr_mool *, int);
    119      1.86      manu static void	ktrmib(int *, int);
    120      1.95     perry static void	usage(void) __dead;
    121      1.81  christos static void	eprint(int);
    122      1.81  christos static void	rprint(register_t);
    123      1.72       mrg static const char *signame(long, int);
    124      1.64      manu static void hexdump_buf(const void *, int, int);
    125      1.58       dsl static void visdump_buf(const void *, int, int);
    126      1.17     mikel 
    127       1.4   mycroft int
    128      1.81  christos main(int argc, char **argv)
    129       1.1       cgd {
    130       1.1       cgd 	int ch, ktrlen, size;
    131      1.18     lukem 	void *m;
    132      1.58       dsl 	int trpoints = 0;
    133      1.58       dsl 	int trset = 0;
    134      1.27  jdolecek 	const char *emul_name = "netbsd";
    135      1.58       dsl 	int col;
    136      1.65       dsl 	char *cp;
    137      1.11  christos 
    138      1.81  christos 	setprogname(argv[0]);
    139      1.67       dsl 	while ((ch = getopt(argc, argv, "e:f:dlm:Nnp:RTt:xX:")) != -1) {
    140       1.4   mycroft 		switch (ch) {
    141      1.11  christos 		case 'e':
    142      1.27  jdolecek 			emul_name = strdup(optarg); /* it's safer to copy it */
    143      1.11  christos 			break;
    144       1.1       cgd 		case 'f':
    145       1.1       cgd 			tracefile = optarg;
    146       1.1       cgd 			break;
    147       1.1       cgd 		case 'd':
    148       1.1       cgd 			decimal = 1;
    149       1.1       cgd 			break;
    150       1.1       cgd 		case 'l':
    151       1.1       cgd 			tail = 1;
    152       1.1       cgd 			break;
    153      1.39    atatat 		case 'p':
    154      1.67       dsl 			do_pid = strtoul(optarg, &cp, 0);
    155      1.67       dsl 			if (*cp != 0)
    156      1.67       dsl 				errx(1,"invalid number %s", optarg);
    157      1.39    atatat 			break;
    158       1.1       cgd 		case 'm':
    159      1.67       dsl 			maxdata = strtoul(optarg, &cp, 0);
    160      1.67       dsl 			if (*cp != 0)
    161      1.67       dsl 				errx(1,"invalid number %s", optarg);
    162       1.1       cgd 			break;
    163      1.43    atatat 		case 'N':
    164      1.43    atatat 			numeric++;
    165      1.43    atatat 			break;
    166       1.1       cgd 		case 'n':
    167      1.36  christos 			plain++;
    168       1.1       cgd 			break;
    169       1.1       cgd 		case 'R':
    170       1.1       cgd 			timestamp = 2;	/* relative timestamp */
    171       1.1       cgd 			break;
    172       1.1       cgd 		case 'T':
    173       1.1       cgd 			timestamp = 1;
    174       1.1       cgd 			break;
    175       1.1       cgd 		case 't':
    176      1.58       dsl 			trset = 1;
    177      1.58       dsl 			trpoints = getpoints(trpoints, optarg);
    178       1.4   mycroft 			if (trpoints < 0)
    179       1.4   mycroft 				errx(1, "unknown trace point in %s", optarg);
    180       1.1       cgd 			break;
    181      1.52       dsl 		case 'x':
    182      1.66      manu 			word_size = 1;
    183      1.66      manu 			break;
    184      1.66      manu 		case 'X':
    185      1.65       dsl 			word_size = strtoul(optarg, &cp, 0);
    186      1.65       dsl 			if (*cp != 0 || word_size & (word_size - 1) ||
    187      1.67       dsl 			    word_size > 16 || word_size <= 0)
    188      1.66      manu 				errx(1, "argument to -X must be "
    189      1.66      manu 				    "1, 2, 4, 8 or 16");
    190      1.52       dsl 			break;
    191       1.1       cgd 		default:
    192       1.1       cgd 			usage();
    193       1.1       cgd 		}
    194      1.67       dsl 	}
    195       1.1       cgd 	argv += optind;
    196       1.1       cgd 	argc -= optind;
    197       1.1       cgd 
    198      1.58       dsl 	if (!trset)
    199      1.58       dsl 		trpoints = ALL_POINTS;
    200      1.58       dsl 
    201      1.41    atatat 	if (tracefile == NULL) {
    202      1.41    atatat 		if (argc == 1) {
    203      1.41    atatat 			tracefile = argv[0];
    204      1.41    atatat 			argv++;
    205      1.41    atatat 			argc--;
    206      1.76     enami 		} else
    207      1.41    atatat 			tracefile = DEF_TRACEFILE;
    208      1.41    atatat 	}
    209      1.41    atatat 
    210      1.41    atatat 	if (argc > 0)
    211       1.1       cgd 		usage();
    212       1.1       cgd 
    213      1.27  jdolecek 	setemul(emul_name, 0, 0);
    214      1.42      manu 	mach_lookup_emul();
    215      1.27  jdolecek 
    216      1.27  jdolecek 	m = malloc(size = 1024);
    217       1.4   mycroft 	if (m == NULL)
    218      1.27  jdolecek 		errx(1, "malloc: %s", strerror(ENOMEM));
    219       1.4   mycroft 	if (!freopen(tracefile, "r", stdin))
    220       1.4   mycroft 		err(1, "%s", tracefile);
    221      1.81  christos 	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
    222      1.76     enami 		if (trpoints & (1 << ktr_header.ktr_type) &&
    223      1.76     enami 		    (do_pid == -1 || ktr_header.ktr_pid == do_pid))
    224      1.58       dsl 			col = dumpheader(&ktr_header);
    225      1.58       dsl 		else
    226      1.58       dsl 			col = -1;
    227       1.4   mycroft 		if ((ktrlen = ktr_header.ktr_len) < 0)
    228       1.4   mycroft 			errx(1, "bogus length 0x%x", ktrlen);
    229       1.1       cgd 		if (ktrlen > size) {
    230      1.58       dsl 			while (ktrlen > size)
    231      1.58       dsl 				size *= 2;
    232      1.58       dsl 			m = realloc(m, size);
    233       1.4   mycroft 			if (m == NULL)
    234      1.27  jdolecek 				errx(1, "realloc: %s", strerror(ENOMEM));
    235       1.1       cgd 		}
    236       1.4   mycroft 		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
    237       1.4   mycroft 			errx(1, "data too short");
    238      1.58       dsl 		if (col == -1)
    239       1.1       cgd 			continue;
    240      1.27  jdolecek 
    241      1.27  jdolecek 		/* update context to match currently processed record */
    242      1.27  jdolecek 		ectx_sanify(ktr_header.ktr_pid);
    243      1.27  jdolecek 
    244       1.1       cgd 		switch (ktr_header.ktr_type) {
    245       1.1       cgd 		case KTR_SYSCALL:
    246      1.58       dsl 			ktrsyscall(m);
    247       1.1       cgd 			break;
    248       1.1       cgd 		case KTR_SYSRET:
    249      1.58       dsl 			ktrsysret(m, ktrlen);
    250       1.1       cgd 			break;
    251       1.1       cgd 		case KTR_NAMEI:
    252       1.1       cgd 			ktrnamei(m, ktrlen);
    253       1.1       cgd 			break;
    254       1.1       cgd 		case KTR_GENIO:
    255      1.58       dsl 			ktrgenio(m, ktrlen);
    256       1.1       cgd 			break;
    257       1.1       cgd 		case KTR_PSIG:
    258      1.60  christos 			ktrpsig(m, ktrlen);
    259       1.1       cgd 			break;
    260       1.1       cgd 		case KTR_CSW:
    261      1.58       dsl 			ktrcsw(m);
    262       1.1       cgd 			break;
    263      1.11  christos 		case KTR_EMUL:
    264      1.27  jdolecek 			ktremul(m, ktrlen, size);
    265      1.11  christos 			break;
    266      1.32  jdolecek 		case KTR_USER:
    267      1.58       dsl 			ktruser(m, ktrlen);
    268      1.32  jdolecek 			break;
    269      1.46      manu 		case KTR_MMSG:
    270      1.58       dsl 			ktrmmsg(m, ktrlen);
    271      1.46      manu 			break;
    272      1.69      manu 		case KTR_MOOL:
    273      1.69      manu 			ktrmool(m, ktrlen);
    274      1.69      manu 			break;
    275      1.58       dsl 		case KTR_EXEC_ARG:
    276      1.58       dsl 		case KTR_EXEC_ENV:
    277      1.58       dsl 			visdump_buf(m, ktrlen, col);
    278      1.58       dsl 			break;
    279      1.86      manu 		case KTR_MIB:
    280      1.86      manu 			ktrmib(m, ktrlen);
    281      1.86      manu 			break;
    282      1.58       dsl 		default:
    283      1.72       mrg 			putchar('\n');
    284      1.79       dsl 			hexdump_buf(m, ktrlen, word_size ? word_size : 1);
    285       1.1       cgd 		}
    286       1.1       cgd 		if (tail)
    287       1.1       cgd 			(void)fflush(stdout);
    288       1.1       cgd 	}
    289      1.17     mikel 	return (0);
    290       1.1       cgd }
    291       1.1       cgd 
    292      1.81  christos static int
    293      1.81  christos fread_tail(void *buf, size_t num, size_t size)
    294       1.1       cgd {
    295       1.1       cgd 	int i;
    296       1.1       cgd 
    297       1.1       cgd 	while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
    298       1.1       cgd 		(void)sleep(1);
    299       1.1       cgd 		clearerr(stdin);
    300       1.1       cgd 	}
    301       1.1       cgd 	return (i);
    302       1.1       cgd }
    303       1.1       cgd 
    304      1.81  christos static int
    305      1.81  christos dumpheader(struct ktr_header *kth)
    306       1.1       cgd {
    307      1.81  christos 	char unknown[64];
    308      1.81  christos 	const char *type;
    309      1.83  christos 	union holdtime {
    310      1.83  christos 		struct timeval tv;
    311      1.83  christos 		struct timespec ts;
    312      1.83  christos 	};
    313      1.83  christos 	static union holdtime prevtime;
    314      1.83  christos 	union holdtime temp;
    315      1.58       dsl 	int col;
    316       1.1       cgd 
    317       1.1       cgd 	switch (kth->ktr_type) {
    318       1.1       cgd 	case KTR_SYSCALL:
    319       1.1       cgd 		type = "CALL";
    320       1.1       cgd 		break;
    321       1.1       cgd 	case KTR_SYSRET:
    322       1.1       cgd 		type = "RET ";
    323       1.1       cgd 		break;
    324       1.1       cgd 	case KTR_NAMEI:
    325       1.1       cgd 		type = "NAMI";
    326       1.1       cgd 		break;
    327       1.1       cgd 	case KTR_GENIO:
    328       1.1       cgd 		type = "GIO ";
    329       1.1       cgd 		break;
    330       1.1       cgd 	case KTR_PSIG:
    331       1.1       cgd 		type = "PSIG";
    332       1.1       cgd 		break;
    333       1.1       cgd 	case KTR_CSW:
    334      1.60  christos 		type = "CSW ";
    335       1.1       cgd 		break;
    336      1.11  christos 	case KTR_EMUL:
    337      1.11  christos 		type = "EMUL";
    338      1.11  christos 		break;
    339      1.32  jdolecek 	case KTR_USER:
    340      1.94       dsl 		type = "MISC";
    341      1.32  jdolecek 		break;
    342      1.46      manu 	case KTR_MMSG:
    343      1.46      manu 		type = "MMSG";
    344      1.46      manu 		break;
    345      1.69      manu 	case KTR_MOOL:
    346      1.69      manu 		type = "MOOL";
    347      1.69      manu 		break;
    348      1.58       dsl 	case KTR_EXEC_ENV:
    349      1.58       dsl 		type = "ENV";
    350      1.58       dsl 		break;
    351      1.58       dsl 	case KTR_EXEC_ARG:
    352      1.58       dsl 		type = "ARG";
    353      1.58       dsl 		break;
    354      1.83  christos 	case KTR_SAUPCALL:
    355      1.83  christos 		type = "SAU";
    356      1.83  christos 		break;
    357      1.86      manu 	case KTR_MIB:
    358      1.86      manu 		type = "MIB";
    359      1.86      manu 		break;
    360       1.1       cgd 	default:
    361      1.81  christos 		(void)snprintf(unknown, sizeof(unknown), "UNKNOWN(%d)",
    362      1.81  christos 		    kth->ktr_type);
    363       1.1       cgd 		type = unknown;
    364       1.1       cgd 	}
    365       1.1       cgd 
    366      1.83  christos 	col = printf("%6d ", kth->ktr_pid);
    367      1.83  christos 	if (kth->ktr_version > KTRFACv0)
    368      1.83  christos 		col += printf("%6d ", kth->ktr_lid);
    369      1.83  christos 	col += printf("%-8.*s ", MAXCOMLEN, kth->ktr_comm);
    370       1.1       cgd 	if (timestamp) {
    371       1.1       cgd 		if (timestamp == 2) {
    372      1.83  christos 			if (kth->ktr_version == KTRFACv0) {
    373      1.83  christos 				if (prevtime.tv.tv_sec == 0)
    374      1.83  christos 					temp.tv.tv_sec = temp.tv.tv_usec = 0;
    375      1.83  christos 				else
    376      1.83  christos 					timersub(&kth->ktr_tv,
    377      1.83  christos 					    &prevtime.tv, &temp.tv);
    378      1.83  christos 				prevtime.tv = kth->ktr_tv;
    379      1.83  christos 			} else {
    380      1.83  christos 				if (prevtime.ts.tv_sec == 0)
    381      1.83  christos 					temp.ts.tv_sec = temp.ts.tv_nsec = 0;
    382      1.83  christos 				else
    383      1.83  christos 					timespecsub(&kth->ktr_time,
    384      1.83  christos 					    &prevtime.ts, &temp.ts);
    385      1.83  christos 				prevtime.ts = kth->ktr_time;
    386      1.83  christos 			}
    387      1.83  christos 		} else {
    388      1.83  christos 			if (kth->ktr_version == KTRFACv0)
    389      1.83  christos 				temp.tv = kth->ktr_tv;
    390      1.58       dsl 			else
    391      1.83  christos 				temp.ts = kth->ktr_time;
    392      1.83  christos 		}
    393      1.83  christos 		if (kth->ktr_version == KTRFACv0)
    394      1.83  christos 			col += printf("%ld.%06ld ",
    395      1.83  christos 			    (long)temp.tv.tv_sec, (long)temp.tv.tv_usec);
    396      1.83  christos 		else
    397      1.83  christos 			col += printf("%ld.%09ld ",
    398      1.83  christos 			    (long)temp.ts.tv_sec, (long)temp.ts.tv_nsec);
    399       1.1       cgd 	}
    400      1.58       dsl 	col += printf("%-4s  ", type);
    401      1.58       dsl 	return col;
    402       1.1       cgd }
    403       1.1       cgd 
    404      1.81  christos static void
    405      1.81  christos output_long(u_long it, int as_x)
    406      1.72       mrg {
    407      1.72       mrg 	if (cur_emul->flags & EMUL_FLAG_NETBSD32)
    408      1.72       mrg 		printf(as_x ? "%#x" : "%d", (u_int)it);
    409      1.72       mrg 	else
    410      1.72       mrg 		printf(as_x ? "%#lx" : "%ld", it);
    411      1.72       mrg }
    412      1.72       mrg 
    413      1.81  christos static void
    414      1.81  christos ioctldecode(u_long cmd)
    415      1.13  christos {
    416      1.13  christos 	char dirbuf[4], *dir = dirbuf;
    417      1.90     njoly 	int c;
    418      1.13  christos 
    419      1.15       cgd 	if (cmd & IOC_IN)
    420      1.15       cgd 		*dir++ = 'W';
    421      1.13  christos 	if (cmd & IOC_OUT)
    422      1.13  christos 		*dir++ = 'R';
    423      1.13  christos 	*dir = '\0';
    424      1.13  christos 
    425      1.90     njoly 	c = (cmd >> 8) & 0xff;
    426      1.90     njoly 	if (isprint(c))
    427      1.90     njoly 		printf(",_IO%s('%c',", dirbuf, c);
    428      1.90     njoly 	else
    429      1.90     njoly 		printf(",_IO%s(0x%02x,", dirbuf, c);
    430      1.72       mrg 	output_long(cmd & 0xff, decimal == 0);
    431      1.72       mrg 	if ((cmd & IOC_VOID) == 0) {
    432      1.72       mrg 		putchar(',');
    433      1.85  christos 		output_long(IOCPARM_LEN(cmd), decimal == 0);
    434      1.72       mrg 	}
    435      1.72       mrg 	putchar(')');
    436      1.13  christos }
    437       1.1       cgd 
    438      1.81  christos static void
    439      1.81  christos ktrsyscall(struct ktr_syscall *ktr)
    440       1.1       cgd {
    441      1.71       mrg 	int argcount;
    442      1.67       dsl 	const struct emulation *emul = cur_emul;
    443      1.18     lukem 	register_t *ap;
    444      1.67       dsl 	char c;
    445      1.81  christos 	const char *cp;
    446      1.67       dsl 	const char *sys_name;
    447       1.1       cgd 
    448      1.72       mrg 	argcount = ktr->ktr_argsize / sizeof (*ap);
    449      1.72       mrg 
    450      1.67       dsl 	emul_changed = 0;
    451      1.67       dsl 
    452      1.72       mrg 	if (numeric ||
    453      1.76     enami 	    ((ktr->ktr_code >= emul->nsysnames || ktr->ktr_code < 0) &&
    454      1.76     enami 	    mach_traps_dispatch(&ktr->ktr_code, &emul) == 0)) {
    455      1.67       dsl 		sys_name = "?";
    456       1.1       cgd 		(void)printf("[%d]", ktr->ktr_code);
    457      1.67       dsl 	} else {
    458      1.67       dsl 		sys_name = emul->sysnames[ktr->ktr_code];
    459      1.67       dsl 		(void)printf("%s", sys_name);
    460      1.67       dsl 	}
    461      1.72       mrg #ifdef _LP64
    462      1.72       mrg #define NETBSD32_	"netbsd32_"
    463      1.72       mrg 	if (cur_emul->flags & EMUL_FLAG_NETBSD32) {
    464      1.72       mrg 		size_t len = strlen(NETBSD32_);
    465      1.72       mrg 		if (strncmp(sys_name, NETBSD32_, len) == 0)
    466      1.72       mrg 			sys_name += len;
    467      1.72       mrg 	}
    468      1.72       mrg #undef NETBSD32_
    469      1.72       mrg #endif
    470      1.76     enami 
    471       1.7       cgd 	ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
    472      1.67       dsl 	if (argcount) {
    473      1.67       dsl 		c = '(';
    474      1.67       dsl 		if (plain) {
    475      1.67       dsl 			;
    476      1.67       dsl 
    477      1.67       dsl 		} else if (strcmp(sys_name, "exit") == 0) {
    478      1.67       dsl 			ectx_delete();
    479      1.67       dsl 
    480      1.72       mrg 		} else if (strcmp(sys_name, "ioctl") == 0 && argcount >= 2) {
    481      1.72       mrg 			(void)putchar('(');
    482      1.73  christos 			output_long((long)*ap, !(decimal || small(*ap)));
    483      1.67       dsl 			ap++;
    484      1.67       dsl 			argcount--;
    485      1.67       dsl 			if ((cp = ioctlname(*ap)) != NULL)
    486      1.67       dsl 				(void)printf(",%s", cp);
    487      1.67       dsl 			else
    488      1.67       dsl 				ioctldecode(*ap);
    489      1.67       dsl 			ap++;
    490      1.67       dsl 			argcount--;
    491      1.67       dsl 			c = ',';
    492      1.67       dsl 
    493      1.82  christos 		} else if ((strstr(sys_name, "sigaction") != NULL ||
    494      1.82  christos 		    strstr(sys_name, "sigvec") != NULL) && argcount >= 1) {
    495      1.82  christos 			(void)printf("(SIG%s", signame(ap[0], 1));
    496      1.82  christos 			ap += 1;
    497      1.82  christos 			argcount -= 1;
    498      1.82  christos 			c = ',';
    499      1.82  christos 
    500      1.82  christos 		} else if ((strcmp(sys_name, "kill") == 0 ||
    501      1.82  christos 		    strcmp(sys_name, "killpg") == 0) && argcount >= 2) {
    502      1.72       mrg 			putchar('(');
    503      1.73  christos 			output_long((long)ap[0], !(decimal || small(*ap)));
    504      1.72       mrg 			(void)printf(", SIG%s", signame(ap[1], 1));
    505      1.67       dsl 			ap += 2;
    506      1.67       dsl 			argcount -= 2;
    507      1.67       dsl 			c = ',';
    508      1.67       dsl 
    509      1.67       dsl 		} else if (strcmp(sys_name, "ptrace") == 0 && argcount >= 1) {
    510      1.72       mrg 			putchar('(');
    511  1.96.4.1  wrstuden 			if (strcmp(emul->name, "linux") == 0 ||
    512  1.96.4.1  wrstuden 			    strcmp(emul->name, "linux32") == 0) {
    513      1.87       mrg 				if ((long)*ap >= 0 && *ap <
    514      1.72       mrg 				    sizeof(linux_ptrace_ops) /
    515      1.72       mrg 				    sizeof(linux_ptrace_ops[0]))
    516      1.72       mrg 					(void)printf("%s",
    517      1.37  christos 					    linux_ptrace_ops[*ap]);
    518      1.72       mrg 				else
    519      1.72       mrg 					output_long((long)*ap, 1);
    520      1.67       dsl 			} else {
    521      1.87       mrg 				if ((long)*ap >= 0 && *ap <
    522      1.12       jtc 				    sizeof(ptrace_ops) / sizeof(ptrace_ops[0]))
    523      1.72       mrg 					(void)printf("%s", ptrace_ops[*ap]);
    524      1.78      matt #ifdef PT_MACHDEP_STRINGS
    525      1.78      matt 				else if (*ap >= PT_FIRSTMACH &&
    526      1.78      matt 				    *ap - PT_FIRSTMACH <
    527      1.78      matt 						sizeof(ptrace_machdep_ops) /
    528      1.78      matt 						sizeof(ptrace_machdep_ops[0]))
    529      1.78      matt 					(void)printf("%s", ptrace_machdep_ops[*ap - PT_FIRSTMACH]);
    530      1.78      matt #endif
    531      1.75     enami 				else
    532      1.72       mrg 					output_long((long)*ap, 1);
    533      1.67       dsl 			}
    534      1.67       dsl 			ap++;
    535      1.67       dsl 			argcount--;
    536      1.67       dsl 			c = ',';
    537      1.37  christos 
    538       1.1       cgd 		}
    539      1.67       dsl 		while (argcount > 0) {
    540      1.72       mrg 			putchar(c);
    541      1.73  christos 			output_long((long)*ap, !(decimal || small(*ap)));
    542      1.67       dsl 			ap++;
    543      1.67       dsl 			argcount--;
    544       1.1       cgd 			c = ',';
    545       1.1       cgd 		}
    546       1.1       cgd 		(void)putchar(')');
    547       1.1       cgd 	}
    548       1.1       cgd 	(void)putchar('\n');
    549       1.1       cgd }
    550       1.1       cgd 
    551      1.81  christos static void
    552      1.81  christos ktrsysret(struct ktr_sysret *ktr, int len)
    553       1.1       cgd {
    554      1.67       dsl 	const struct emulation *emul;
    555      1.18     lukem 	int error = ktr->ktr_error;
    556      1.18     lukem 	int code = ktr->ktr_code;
    557       1.1       cgd 
    558      1.67       dsl 	if (emul_changed)  {
    559      1.67       dsl 		/* In order to get system call name right in execve return */
    560      1.67       dsl 		emul = prev_emul;
    561      1.67       dsl 		emul_changed = 0;
    562      1.67       dsl 	} else
    563      1.67       dsl 		emul = cur_emul;
    564      1.35      manu 
    565      1.94       dsl 	if (numeric || ((code >= emul->nsysnames || code < 0 || plain > 1) &&
    566      1.94       dsl 	    mach_traps_dispatch(&code, &emul) == 0))
    567       1.1       cgd 		(void)printf("[%d] ", code);
    568       1.1       cgd 	else
    569      1.67       dsl 		(void)printf("%s ", emul->sysnames[code]);
    570       1.1       cgd 
    571      1.22  christos 	switch (error) {
    572      1.22  christos 	case 0:
    573      1.48       dsl 		rprint(ktr->ktr_retval);
    574      1.48       dsl 		if (len > offsetof(struct ktr_sysret, ktr_retval_1) &&
    575      1.48       dsl 		    ktr->ktr_retval_1 != 0) {
    576      1.48       dsl 			(void)printf(", ");
    577      1.48       dsl 			rprint(ktr->ktr_retval_1);
    578       1.1       cgd 		}
    579      1.22  christos 		break;
    580      1.22  christos 
    581      1.22  christos 	default:
    582      1.22  christos 		eprint(error);
    583      1.22  christos 		break;
    584      1.22  christos 	}
    585      1.22  christos 	(void)putchar('\n');
    586      1.48       dsl }
    587      1.48       dsl 
    588      1.81  christos static void
    589      1.48       dsl rprint(register_t ret)
    590      1.48       dsl {
    591      1.76     enami 
    592      1.48       dsl 	if (!plain) {
    593      1.48       dsl 		(void)printf("%ld", (long)ret);
    594      1.73  christos 		if (!small(ret))
    595      1.48       dsl 			(void)printf("/%#lx", (long)ret);
    596      1.48       dsl 	} else {
    597      1.73  christos 		if (decimal || small(ret))
    598      1.48       dsl 			(void)printf("%ld", (long)ret);
    599      1.48       dsl 		else
    600      1.48       dsl 			(void)printf("%#lx", (long)ret);
    601      1.48       dsl 	}
    602      1.22  christos }
    603      1.22  christos 
    604      1.22  christos /*
    605      1.22  christos  * We print the original emulation's error numerically, but we
    606      1.22  christos  * translate it to netbsd to print it symbolically.
    607      1.22  christos  */
    608      1.81  christos static void
    609      1.81  christos eprint(int e)
    610      1.22  christos {
    611      1.22  christos 	int i = e;
    612      1.22  christos 
    613      1.67       dsl 	if (cur_emul->errnomap) {
    614      1.22  christos 
    615      1.22  christos 		/* No remapping for ERESTART and EJUSTRETURN */
    616      1.22  christos 		/* Kludge for linux that has negative error numbers */
    617      1.67       dsl 		if (cur_emul->errnomap[2] > 0 && e < 0)
    618      1.22  christos 			goto normal;
    619      1.22  christos 
    620      1.67       dsl 		for (i = 0; i < cur_emul->nerrnomap; i++)
    621      1.67       dsl 			if (e == cur_emul->errnomap[i])
    622      1.22  christos 				break;
    623      1.22  christos 
    624      1.67       dsl 		if (i == cur_emul->nerrnomap) {
    625      1.22  christos 			printf("-1 unknown errno %d", e);
    626      1.22  christos 			return;
    627      1.22  christos 		}
    628      1.22  christos 	}
    629      1.22  christos 
    630      1.22  christos normal:
    631      1.22  christos 	switch (i) {
    632      1.22  christos 	case ERESTART:
    633       1.1       cgd 		(void)printf("RESTART");
    634      1.22  christos 		break;
    635      1.22  christos 
    636      1.22  christos 	case EJUSTRETURN:
    637       1.1       cgd 		(void)printf("JUSTRETURN");
    638      1.22  christos 		break;
    639      1.22  christos 
    640      1.22  christos 	default:
    641      1.22  christos 		(void)printf("-1 errno %d", e);
    642      1.36  christos 		if (!plain)
    643      1.22  christos 			(void)printf(" %s", strerror(i));
    644       1.1       cgd 	}
    645       1.1       cgd }
    646       1.1       cgd 
    647      1.81  christos static void
    648      1.81  christos ktrnamei(char *cp, int len)
    649       1.1       cgd {
    650      1.17     mikel 
    651       1.1       cgd 	(void)printf("\"%.*s\"\n", len, cp);
    652       1.1       cgd }
    653       1.1       cgd 
    654      1.81  christos static void
    655      1.81  christos ktremul(char *name, int len, int bufsize)
    656      1.11  christos {
    657      1.76     enami 
    658      1.27  jdolecek 	if (len >= bufsize)
    659      1.27  jdolecek 		len = bufsize - 1;
    660      1.11  christos 
    661      1.27  jdolecek 	name[len] = '\0';
    662      1.27  jdolecek 	setemul(name, ktr_header.ktr_pid, 1);
    663      1.35      manu 	emul_changed = 1;
    664      1.11  christos 
    665      1.11  christos 	(void)printf("\"%s\"\n", name);
    666      1.11  christos }
    667      1.11  christos 
    668      1.52       dsl static void
    669      1.81  christos hexdump_buf(const void *vdp, int datalen, int word_sz)
    670      1.52       dsl {
    671      1.65       dsl 	const char hex[] = "0123456789abcdef";
    672      1.77       dsl 	char chars[16], prev[16];
    673      1.65       dsl 	char bytes[16 * 3 + 4];
    674      1.58       dsl 	const unsigned char *dp = vdp;
    675      1.65       dsl 	const unsigned char *datalim = dp + datalen;
    676      1.65       dsl 	const unsigned char *line_end;
    677      1.80     lukem 	int off, l = 0, c;
    678      1.65       dsl 	char *cp, *bp;
    679      1.65       dsl 	int divmask = word_sz - 1;	/* block size in bytes */
    680      1.65       dsl 	int gdelim = 3;			/* gap between blocks */
    681      1.65       dsl 	int bsize = 2;			/* increment for each byte */
    682      1.65       dsl 	int width;
    683      1.77       dsl 	int dupl = 0;
    684      1.65       dsl #if _BYTE_ORDER == _LITTLE_ENDIAN
    685      1.65       dsl 	int bswap = word_sz - 1;
    686      1.65       dsl #else
    687      1.65       dsl #define	bswap 0
    688      1.65       dsl #endif
    689      1.65       dsl 
    690      1.65       dsl 	switch (word_sz) {
    691      1.65       dsl 	case 2:
    692      1.65       dsl 		gdelim = 2;
    693      1.64      manu 		break;
    694      1.64      manu 	case 1:
    695      1.65       dsl 		divmask = 7;
    696      1.65       dsl 		bsize = 3;
    697      1.65       dsl 		gdelim = 1;
    698      1.65       dsl 		break;
    699      1.64      manu 	default:
    700      1.64      manu 		break;
    701      1.64      manu 	}
    702      1.65       dsl 	width = 16 * bsize + (16 / (divmask + 1)) * gdelim;
    703      1.79       dsl 	if (word_sz != 1)
    704      1.65       dsl 		width += 2;
    705      1.65       dsl 
    706      1.65       dsl 	for (off = 0; dp < datalim; off += l) {
    707      1.65       dsl 		memset(bytes, ' ', sizeof bytes);
    708      1.65       dsl 		line_end = dp + 16;
    709      1.77       dsl 		if (line_end >= datalim) {
    710      1.65       dsl 			line_end = datalim;
    711      1.77       dsl 			dupl |= 1;	/* need to print */
    712      1.77       dsl 		} else {
    713      1.77       dsl 			if (dupl == 0 || memcmp(dp, prev, sizeof chars))
    714      1.77       dsl 				dupl |= 1;
    715      1.77       dsl 		}
    716      1.77       dsl 
    717      1.77       dsl 		if (!(dupl & 1)) {
    718      1.77       dsl 			/* This is a duplicate of the line above, count 'em */
    719      1.77       dsl 			dupl += 2;
    720      1.77       dsl 			dp = line_end;
    721      1.77       dsl 			continue;
    722      1.77       dsl 		}
    723      1.77       dsl 
    724      1.77       dsl 		if (dupl > 3) {
    725      1.77       dsl 			/* previous line as a duplicate */
    726      1.77       dsl 			if (dupl == 5)
    727      1.77       dsl 				/* Only one duplicate, print line */
    728      1.77       dsl 				printf("\t%-5.3x%.*s%.*s\n",
    729      1.77       dsl 					off - l, width, bytes, l, chars);
    730      1.77       dsl 			else
    731      1.77       dsl 				printf("\t%.*s\n",
    732      1.77       dsl 					snprintf(NULL, 0, "%3x", off), "*****");
    733      1.77       dsl 		}
    734      1.52       dsl 
    735      1.65       dsl 		for (l = 0, bp = bytes, cp = chars; dp < line_end; l++) {
    736      1.52       dsl 			c = *dp++;
    737      1.77       dsl 			prev[l] = c;
    738      1.65       dsl 			if ((l & divmask) == 0)
    739      1.65       dsl 				bp += gdelim;
    740      1.65       dsl 			bp[(l ^ bswap) * bsize] = hex[c >> 4];
    741      1.65       dsl 			bp[(l ^ bswap) * bsize + 1] = hex[c & 0xf];
    742      1.52       dsl 			*cp++ = isgraph(c) ? c : '.';
    743      1.76     enami 		}
    744      1.64      manu 
    745      1.67       dsl 		printf("\t%-5.3x%.*s%.*s\n", off, width, bytes, l, chars);
    746      1.77       dsl 		dupl = 2;
    747      1.52       dsl 	}
    748      1.52       dsl }
    749      1.52       dsl 
    750      1.58       dsl static void
    751      1.58       dsl visdump_buf(const void *vdp, int datalen, int col)
    752       1.1       cgd {
    753      1.58       dsl 	const unsigned char *dp = vdp;
    754      1.18     lukem 	char *cp;
    755      1.18     lukem 	int width;
    756       1.1       cgd 	char visbuf[5];
    757      1.20       mrg 	static int screenwidth = 0;
    758       1.1       cgd 
    759       1.1       cgd 	if (screenwidth == 0) {
    760       1.1       cgd 		struct winsize ws;
    761       1.1       cgd 
    762      1.36  christos 		if (!plain && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
    763       1.1       cgd 		    ws.ws_col > 8)
    764       1.1       cgd 			screenwidth = ws.ws_col;
    765       1.1       cgd 		else
    766       1.1       cgd 			screenwidth = 80;
    767       1.1       cgd 	}
    768      1.58       dsl 
    769      1.58       dsl 	(void)printf("\"");
    770      1.58       dsl 	col++;
    771       1.4   mycroft 	for (; datalen > 0; datalen--, dp++) {
    772      1.58       dsl 		(void)svis(visbuf, *dp, VIS_CSTYLE,
    773      1.93       agc 		    datalen > 1 ? *(dp + 1) : 0, "\"\n");
    774       1.1       cgd 		cp = visbuf;
    775       1.1       cgd 		/*
    776       1.1       cgd 		 * Keep track of printables and
    777       1.1       cgd 		 * space chars (like fold(1)).
    778       1.1       cgd 		 */
    779       1.1       cgd 		if (col == 0) {
    780       1.1       cgd 			(void)putchar('\t');
    781       1.1       cgd 			col = 8;
    782       1.1       cgd 		}
    783      1.76     enami 		switch (*cp) {
    784       1.1       cgd 		case '\n':
    785       1.1       cgd 			col = 0;
    786       1.1       cgd 			(void)putchar('\n');
    787       1.1       cgd 			continue;
    788       1.1       cgd 		case '\t':
    789      1.58       dsl 			width = 8 - (col & 07);
    790       1.1       cgd 			break;
    791       1.1       cgd 		default:
    792       1.1       cgd 			width = strlen(cp);
    793       1.1       cgd 		}
    794      1.58       dsl 		if (col + width > (screenwidth - 2)) {
    795       1.1       cgd 			(void)printf("\\\n\t");
    796       1.1       cgd 			col = 8;
    797      1.74     enami 			if (*cp == '\t')
    798      1.74     enami 				width = 8;
    799       1.1       cgd 		}
    800       1.1       cgd 		col += width;
    801       1.1       cgd 		do {
    802       1.1       cgd 			(void)putchar(*cp++);
    803       1.1       cgd 		} while (*cp);
    804       1.1       cgd 	}
    805       1.1       cgd 	if (col == 0)
    806       1.1       cgd 		(void)printf("       ");
    807       1.1       cgd 	(void)printf("\"\n");
    808      1.58       dsl }
    809      1.58       dsl 
    810      1.81  christos static void
    811      1.81  christos ktrgenio(struct ktr_genio *ktr, int len)
    812      1.58       dsl {
    813      1.58       dsl 	int datalen = len - sizeof (struct ktr_genio);
    814      1.58       dsl 	char *dp = (char *)ktr + sizeof (struct ktr_genio);
    815      1.58       dsl 
    816      1.86      manu 	if (ktr->ktr_fd != -1)
    817      1.86      manu 		printf("fd %d ", ktr->ktr_fd);
    818      1.86      manu 	printf("%s %d bytes\n",
    819      1.76     enami 	    ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
    820      1.58       dsl 	if (maxdata == 0)
    821      1.58       dsl 		return;
    822      1.58       dsl 	if (maxdata > 0 && datalen > maxdata)
    823      1.58       dsl 		datalen = maxdata;
    824      1.65       dsl 	if (word_size) {
    825      1.65       dsl 		hexdump_buf(dp, datalen, word_size);
    826      1.58       dsl 		return;
    827      1.58       dsl 	}
    828      1.58       dsl 	(void)printf("       ");
    829      1.58       dsl 	visdump_buf(dp, datalen, 7);
    830       1.1       cgd }
    831       1.1       cgd 
    832      1.81  christos static void
    833      1.81  christos ktrpsig(void *v, int len)
    834       1.1       cgd {
    835      1.21   mycroft 	int signo, first;
    836      1.60  christos 	struct {
    837      1.60  christos 		struct ktr_psig ps;
    838      1.60  christos 		siginfo_t si;
    839      1.60  christos 	} *psig = v;
    840      1.60  christos 	siginfo_t *si = &psig->si;
    841      1.60  christos 	const char *code;
    842      1.60  christos 
    843      1.60  christos 	(void)printf("SIG%s ", signame(psig->ps.signo, 0));
    844      1.60  christos 	if (psig->ps.action == SIG_DFL)
    845      1.60  christos 		(void)printf("SIG_DFL");
    846      1.21   mycroft 	else {
    847      1.60  christos 		(void)printf("caught handler=%p mask=(", psig->ps.action);
    848      1.21   mycroft 		first = 1;
    849      1.21   mycroft 		for (signo = 1; signo < NSIG; signo++) {
    850      1.60  christos 			if (sigismember(&psig->ps.mask, signo)) {
    851      1.21   mycroft 				if (first)
    852      1.21   mycroft 					first = 0;
    853      1.21   mycroft 				else
    854      1.21   mycroft 					(void)printf(",");
    855      1.21   mycroft 				(void)printf("%d", signo);
    856      1.21   mycroft 			}
    857      1.21   mycroft 		}
    858      1.60  christos 		(void)printf(")");
    859      1.60  christos 	}
    860      1.60  christos 	switch (len) {
    861      1.60  christos 	case sizeof(struct ktr_psig):
    862      1.61  christos 		if (psig->ps.code)
    863      1.61  christos 			printf(" code=0x%x", psig->ps.code);
    864      1.61  christos 		printf(psig->ps.action == SIG_DFL ? "\n" : ")\n");
    865      1.60  christos 		return;
    866      1.60  christos 	case sizeof(*psig):
    867      1.60  christos 		if (si->si_code == 0) {
    868      1.61  christos 			printf(": code=SI_USER sent by pid=%d, uid=%d)\n",
    869      1.76     enami 			    si->si_pid, si->si_uid);
    870      1.60  christos 			return;
    871      1.60  christos 		}
    872      1.60  christos 
    873      1.60  christos 		if (si->si_code < 0) {
    874      1.60  christos 			switch (si->si_code) {
    875      1.60  christos 			case SI_TIMER:
    876      1.61  christos 				printf(": code=SI_TIMER sigval %p)\n",
    877      1.91    dogcow 				    si->si_value.sival_ptr);
    878      1.60  christos 				return;
    879      1.60  christos 			case SI_QUEUE:
    880      1.60  christos 				code = "SI_QUEUE";
    881      1.60  christos 				break;
    882      1.60  christos 			case SI_ASYNCIO:
    883      1.60  christos 				code = "SI_ASYNCIO";
    884      1.60  christos 				break;
    885      1.60  christos 			case SI_MESGQ:
    886      1.60  christos 				code = "SI_MESGQ";
    887      1.60  christos 				break;
    888      1.60  christos 			default:
    889      1.60  christos 				code = NULL;
    890      1.60  christos 				break;
    891      1.60  christos 			}
    892      1.60  christos 			if (code)
    893      1.61  christos 				printf(": code=%s unimplemented)\n", code);
    894      1.60  christos 			else
    895      1.61  christos 				printf(": code=%d unimplemented)\n",
    896      1.60  christos 				    si->si_code);
    897      1.60  christos 			return;
    898      1.60  christos 		}
    899      1.60  christos 
    900  1.96.4.3  wrstuden 		if (si->si_code == SI_NOINFO) {
    901  1.96.4.3  wrstuden 			printf(": code=SI_NOINFO\n");
    902  1.96.4.3  wrstuden 			return;
    903  1.96.4.3  wrstuden 		}
    904  1.96.4.3  wrstuden 
    905      1.60  christos 		code = siginfocodename(si->si_signo, si->si_code);
    906      1.60  christos 		switch (si->si_signo) {
    907      1.60  christos 		case SIGCHLD:
    908      1.60  christos 			printf(": code=%s child pid=%d, uid=%d, "
    909      1.76     enami 			    " status=%u, utime=%lu, stime=%lu)\n",
    910      1.60  christos 			    code, si->si_pid,
    911      1.62      matt 			    si->si_uid, si->si_status,
    912      1.62      matt 			    (unsigned long) si->si_utime,
    913      1.76     enami 			    (unsigned long) si->si_stime);
    914      1.60  christos 			return;
    915      1.60  christos 		case SIGILL:
    916      1.60  christos 		case SIGFPE:
    917      1.60  christos 		case SIGSEGV:
    918      1.60  christos 		case SIGBUS:
    919      1.60  christos 		case SIGTRAP:
    920      1.61  christos 			printf(": code=%s, addr=%p, trap=%d)\n",
    921      1.60  christos 			    code, si->si_addr, si->si_trap);
    922      1.60  christos 			return;
    923      1.60  christos 		case SIGIO:
    924      1.61  christos 			printf(": code=%s, fd=%d, band=%lx)\n",
    925      1.60  christos 			    code, si->si_fd, si->si_band);
    926      1.60  christos 			return;
    927      1.60  christos 		default:
    928      1.61  christos 			printf(": code=%s, errno=%d)\n",
    929      1.60  christos 			    code, si->si_errno);
    930      1.60  christos 			return;
    931      1.60  christos 		}
    932      1.60  christos 		/*NOTREACHED*/
    933      1.60  christos 	default:
    934      1.60  christos 		warnx("Unhandled size %d for ktrpsig\n", len);
    935      1.60  christos 		break;
    936      1.21   mycroft 	}
    937       1.1       cgd }
    938       1.1       cgd 
    939      1.81  christos static void
    940      1.81  christos ktrcsw(struct ktr_csw *cs)
    941       1.1       cgd {
    942      1.17     mikel 
    943       1.1       cgd 	(void)printf("%s %s\n", cs->out ? "stop" : "resume",
    944       1.4   mycroft 	    cs->user ? "user" : "kernel");
    945      1.32  jdolecek }
    946      1.32  jdolecek 
    947      1.81  christos static void
    948      1.81  christos ktruser(struct ktr_user *usr, int len)
    949      1.32  jdolecek {
    950      1.32  jdolecek 	int i;
    951      1.40  jdolecek 	unsigned char *dta;
    952      1.34  jdolecek 
    953      1.92       dsl 	len -= sizeof(struct ktr_user);
    954      1.92       dsl 	printf("%.*s:", KTR_USER_MAXIDLEN, usr->ktr_id);
    955      1.92       dsl 	dta = (unsigned char *)(usr + 1);
    956      1.92       dsl 	if (word_size) {
    957      1.92       dsl 		printf("\n");
    958      1.92       dsl 		hexdump_buf(dta, len, word_size);
    959      1.92       dsl 		return;
    960      1.92       dsl 	}
    961      1.92       dsl 	printf(" %d, ", len);
    962      1.92       dsl 	for (i = 0; i < len; i++)
    963      1.40  jdolecek 		printf("%02x", (unsigned int) dta[i]);
    964      1.92       dsl 	printf("\n");
    965      1.37  christos }
    966      1.37  christos 
    967      1.81  christos static void
    968      1.81  christos ktrmmsg(struct ktr_mmsg *mmsg, int len)
    969      1.46      manu {
    970      1.63      manu 	const char *service_name;
    971      1.81  christos 	const char *reply;
    972      1.63      manu 	int id;
    973      1.63      manu 
    974      1.63      manu 	id = mmsg->ktr_id;
    975      1.63      manu 	if ((id / 100) % 2) {  /* Message reply */
    976      1.63      manu 		reply = " reply";
    977      1.63      manu 		id -= 100;
    978      1.63      manu 	} else {
    979      1.63      manu 		reply = "";
    980      1.63      manu 	}
    981      1.63      manu 
    982      1.63      manu 	if ((service_name = mach_service_name(id)) != NULL)
    983      1.68      manu 		printf("%s%s [%d]\n", service_name, reply, mmsg->ktr_id);
    984      1.76     enami 	else
    985      1.63      manu 		printf("unknown service%s [%d]\n", reply, mmsg->ktr_id);
    986      1.46      manu 
    987      1.65       dsl 	hexdump_buf(mmsg, len, word_size ? word_size : 4);
    988      1.69      manu }
    989      1.69      manu 
    990      1.81  christos static void
    991      1.81  christos ktrmool(struct ktr_mool *mool, int len)
    992      1.69      manu {
    993      1.69      manu 	size_t size = mool->size;
    994      1.69      manu 
    995      1.76     enami 	printf("%ld/0x%lx bytes at %p\n",
    996      1.70      manu 	    (u_long)size, (u_long)size, mool->uaddr);
    997      1.69      manu 	mool++;
    998      1.69      manu 	hexdump_buf(mool, size, word_size ? word_size : 4);
    999      1.46      manu }
   1000      1.46      manu 
   1001      1.86      manu static void
   1002      1.86      manu ktrmib(int *namep, int len)
   1003      1.86      manu {
   1004      1.86      manu 	int i;
   1005      1.86      manu 
   1006      1.86      manu 	for (i = 0; i < (len / sizeof(*namep)); i++)
   1007      1.86      manu 		printf("%s%d", (i == 0) ? "" : ".", namep[i]);
   1008      1.86      manu 	printf("\n");
   1009      1.86      manu }
   1010      1.86      manu 
   1011      1.37  christos static const char *
   1012      1.37  christos signame(long sig, int xlat)
   1013      1.37  christos {
   1014      1.37  christos 	static char buf[64];
   1015      1.76     enami 
   1016      1.44  jdolecek 	if (sig == 0)
   1017      1.44  jdolecek 		return " 0";
   1018      1.44  jdolecek 	else if (sig < 0 || sig >= NSIG) {
   1019      1.37  christos 		(void)snprintf(buf, sizeof(buf), "*unknown %ld*", sig);
   1020      1.37  christos 		return buf;
   1021      1.37  christos 	} else
   1022      1.67       dsl 		return sys_signame[(xlat && cur_emul->signalmap != NULL) ?
   1023      1.67       dsl 		    cur_emul->signalmap[sig] : sig];
   1024       1.1       cgd }
   1025       1.1       cgd 
   1026      1.81  christos static void
   1027      1.81  christos usage(void)
   1028       1.1       cgd {
   1029       1.4   mycroft 
   1030      1.81  christos 	(void)fprintf(stderr, "Usage: %s [-dlNnRT] [-e emulation] "
   1031      1.46      manu 	   "[-f file] [-m maxdata] [-p pid]\n             [-t trstr] "
   1032      1.81  christos 	   "[-x | -X size] [file]\n", getprogname());
   1033       1.1       cgd 	exit(1);
   1034      1.11  christos }
   1035