]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - usr.bin/kdump/kdump.c
MFC 234494:
[FreeBSD/stable/9.git] / usr.bin / kdump / kdump.c
1 /*-
2  * Copyright (c) 1988, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #ifndef lint
31 static const char copyright[] =
32 "@(#) Copyright (c) 1988, 1993\n\
33         The Regents of the University of California.  All rights reserved.\n";
34 #endif /* not lint */
35
36 #ifndef lint
37 #if 0
38 static char sccsid[] = "@(#)kdump.c     8.1 (Berkeley) 6/6/93";
39 #endif
40 #endif /* not lint */
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #define _KERNEL
45 extern int errno;
46 #include <sys/errno.h>
47 #undef _KERNEL
48 #include <sys/param.h>
49 #include <sys/errno.h>
50 #define _KERNEL
51 #include <sys/time.h>
52 #undef _KERNEL
53 #include <sys/uio.h>
54 #include <sys/ktrace.h>
55 #include <sys/ioctl.h>
56 #include <sys/socket.h>
57 #include <sys/stat.h>
58 #include <sys/sysent.h>
59 #include <sys/un.h>
60 #include <sys/queue.h>
61 #ifdef IPX
62 #include <sys/types.h>
63 #include <netipx/ipx.h>
64 #endif
65 #ifdef NETATALK
66 #include <netatalk/at.h>
67 #endif
68 #include <arpa/inet.h>
69 #include <netinet/in.h>
70 #include <ctype.h>
71 #include <dlfcn.h>
72 #include <err.h>
73 #include <grp.h>
74 #include <inttypes.h>
75 #include <locale.h>
76 #include <pwd.h>
77 #include <stdio.h>
78 #include <stdlib.h>
79 #include <string.h>
80 #include <time.h>
81 #include <unistd.h>
82 #include <vis.h>
83 #include "ktrace.h"
84 #include "kdump_subr.h"
85
86 u_int abidump(struct ktr_header *);
87 int fetchprocinfo(struct ktr_header *, u_int *);
88 int fread_tail(void *, int, int);
89 void dumpheader(struct ktr_header *);
90 void ktrsyscall(struct ktr_syscall *, u_int);
91 void ktrsysret(struct ktr_sysret *, u_int);
92 void ktrnamei(char *, int);
93 void hexdump(char *, int, int);
94 void visdump(char *, int, int);
95 void ktrgenio(struct ktr_genio *, int);
96 void ktrpsig(struct ktr_psig *);
97 void ktrcsw(struct ktr_csw *);
98 void ktrcsw_old(struct ktr_csw_old *);
99 void ktruser(int, unsigned char *);
100 void ktrsockaddr(struct sockaddr *);
101 void ktrstat(struct stat *);
102 void ktrstruct(char *, size_t);
103 void ktrfault(struct ktr_fault *);
104 void ktrfaultend(struct ktr_faultend *);
105 void usage(void);
106 void sockfamilyname(int);
107 const char *ioctlname(u_long);
108
109 int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata,
110     resolv = 0, abiflag = 0;
111 const char *tracefile = DEF_TRACEFILE;
112 struct ktr_header ktr_header;
113
114 #define TIME_FORMAT     "%b %e %T %Y"
115 #define eqs(s1, s2)     (strcmp((s1), (s2)) == 0)
116
117 #define print_number(i,n,c) do {                \
118         if (decimal)                            \
119                 printf("%c%ld", c, (long)*i);   \
120         else                                    \
121                 printf("%c%#lx", c, (long)*i);  \
122         i++;                                    \
123         n--;                                    \
124         c = ',';                                \
125         } while (0);
126
127 #if defined(__amd64__) || defined(__i386__)
128
129 void linux_ktrsyscall(struct ktr_syscall *);
130 void linux_ktrsysret(struct ktr_sysret *);
131 extern char *linux_syscallnames[];
132 extern int nlinux_syscalls;
133
134 /*
135  * from linux.h
136  * Linux syscalls return negative errno's, we do positive and map them
137  */
138 static int bsd_to_linux_errno[ELAST + 1] = {
139         -0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9,
140         -10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
141         -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
142         -30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
143         -90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
144         -100,-101,-102,-103,-104,-105,-106,-107,-108,-109,
145         -110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
146         -116, -66,  -6,  -6,  -6,  -6,  -6, -37, -38,  -9,
147         -6,  -6, -43, -42, -75,-125, -84, -95, -16, -74,
148         -72, -67, -71
149 };
150 #endif
151
152 struct proc_info
153 {
154         TAILQ_ENTRY(proc_info)  info;
155         u_int                   sv_flags;
156         pid_t                   pid;
157 };
158
159 TAILQ_HEAD(trace_procs, proc_info) trace_procs;
160
161 int
162 main(int argc, char *argv[])
163 {
164         int ch, ktrlen, size;
165         void *m;
166         int trpoints = ALL_POINTS;
167         int drop_logged;
168         pid_t pid = 0;
169         u_int sv_flags;
170
171         (void) setlocale(LC_CTYPE, "");
172
173         while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1)
174                 switch((char)ch) {
175                 case 'A':
176                         abiflag = 1;
177                         break;
178                 case 'f':
179                         tracefile = optarg;
180                         break;
181                 case 'd':
182                         decimal = 1;
183                         break;
184                 case 'l':
185                         tail = 1;
186                         break;
187                 case 'm':
188                         maxdata = atoi(optarg);
189                         break;
190                 case 'n':
191                         fancy = 0;
192                         break;
193                 case 'p':
194                         pid = atoi(optarg);
195                         break;
196                 case 'r':
197                         resolv = 1;
198                         break;
199                 case 's':
200                         suppressdata = 1;
201                         break;
202                 case 'E':
203                         timestamp = 3;  /* elapsed timestamp */
204                         break;
205                 case 'H':
206                         threads = 1;
207                         break;
208                 case 'R':
209                         timestamp = 2;  /* relative timestamp */
210                         break;
211                 case 'T':
212                         timestamp = 1;
213                         break;
214                 case 't':
215                         trpoints = getpoints(optarg);
216                         if (trpoints < 0)
217                                 errx(1, "unknown trace point in %s", optarg);
218                         break;
219                 default:
220                         usage();
221                 }
222
223         if (argc > optind)
224                 usage();
225
226         m = (void *)malloc(size = 1025);
227         if (m == NULL)
228                 errx(1, "%s", strerror(ENOMEM));
229         if (!freopen(tracefile, "r", stdin))
230                 err(1, "%s", tracefile);
231         TAILQ_INIT(&trace_procs);
232         drop_logged = 0;
233         while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
234                 if (ktr_header.ktr_type & KTR_DROP) {
235                         ktr_header.ktr_type &= ~KTR_DROP;
236                         if (!drop_logged && threads) {
237                                 (void)printf(
238                                     "%6jd %6jd %-8.*s Events dropped.\n",
239                                     (intmax_t)ktr_header.ktr_pid,
240                                     ktr_header.ktr_tid > 0 ?
241                                     (intmax_t)ktr_header.ktr_tid : 0,
242                                     MAXCOMLEN, ktr_header.ktr_comm);
243                                 drop_logged = 1;
244                         } else if (!drop_logged) {
245                                 (void)printf("%6jd %-8.*s Events dropped.\n",
246                                     (intmax_t)ktr_header.ktr_pid, MAXCOMLEN,
247                                     ktr_header.ktr_comm);
248                                 drop_logged = 1;
249                         }
250                 }
251                 if (trpoints & (1<<ktr_header.ktr_type))
252                         if (pid == 0 || ktr_header.ktr_pid == pid)
253                                 dumpheader(&ktr_header);
254                 if ((ktrlen = ktr_header.ktr_len) < 0)
255                         errx(1, "bogus length 0x%x", ktrlen);
256                 if (ktrlen > size) {
257                         m = (void *)realloc(m, ktrlen+1);
258                         if (m == NULL)
259                                 errx(1, "%s", strerror(ENOMEM));
260                         size = ktrlen;
261                 }
262                 if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
263                         errx(1, "data too short");
264                 if (fetchprocinfo(&ktr_header, (u_int *)m) != 0)
265                         continue;
266                 sv_flags = abidump(&ktr_header);
267                 if (pid && ktr_header.ktr_pid != pid)
268                         continue;
269                 if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
270                         continue;
271                 drop_logged = 0;
272                 switch (ktr_header.ktr_type) {
273                 case KTR_SYSCALL:
274 #if defined(__amd64__) || defined(__i386__)
275                         if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
276                                 linux_ktrsyscall((struct ktr_syscall *)m);
277                         else
278 #endif
279                                 ktrsyscall((struct ktr_syscall *)m, sv_flags);
280                         break;
281                 case KTR_SYSRET:
282 #if defined(__amd64__) || defined(__i386__)
283                         if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX)
284                                 linux_ktrsysret((struct ktr_sysret *)m);
285                         else
286 #endif
287                                 ktrsysret((struct ktr_sysret *)m, sv_flags);
288                         break;
289                 case KTR_NAMEI:
290                 case KTR_SYSCTL:
291                         ktrnamei(m, ktrlen);
292                         break;
293                 case KTR_GENIO:
294                         ktrgenio((struct ktr_genio *)m, ktrlen);
295                         break;
296                 case KTR_PSIG:
297                         ktrpsig((struct ktr_psig *)m);
298                         break;
299                 case KTR_CSW:
300                         if (ktrlen == sizeof(struct ktr_csw_old))
301                                 ktrcsw_old((struct ktr_csw_old *)m);
302                         else
303                                 ktrcsw((struct ktr_csw *)m);
304                         break;
305                 case KTR_USER:
306                         ktruser(ktrlen, m);
307                         break;
308                 case KTR_STRUCT:
309                         ktrstruct(m, ktrlen);
310                         break;
311                 case KTR_FAULT:
312                         ktrfault((struct ktr_fault *)m);
313                         break;
314                 case KTR_FAULTEND:
315                         ktrfaultend((struct ktr_faultend *)m);
316                         break;
317                 default:
318                         printf("\n");
319                         break;
320                 }
321                 if (tail)
322                         (void)fflush(stdout);
323         }
324         return 0;
325 }
326
327 int
328 fread_tail(void *buf, int size, int num)
329 {
330         int i;
331
332         while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
333                 (void)sleep(1);
334                 clearerr(stdin);
335         }
336         return (i);
337 }
338
339 int
340 fetchprocinfo(struct ktr_header *kth, u_int *flags)
341 {
342         struct proc_info *pi;
343
344         switch (kth->ktr_type) {
345         case KTR_PROCCTOR:
346                 TAILQ_FOREACH(pi, &trace_procs, info) {
347                         if (pi->pid == kth->ktr_pid) {
348                                 TAILQ_REMOVE(&trace_procs, pi, info);
349                                 break;
350                         }
351                 }
352                 pi = malloc(sizeof(struct proc_info));
353                 if (pi == NULL)
354                         errx(1, "%s", strerror(ENOMEM));
355                 pi->sv_flags = *flags;
356                 pi->pid = kth->ktr_pid;
357                 TAILQ_INSERT_TAIL(&trace_procs, pi, info);
358                 return (1);
359
360         case KTR_PROCDTOR:
361                 TAILQ_FOREACH(pi, &trace_procs, info) {
362                         if (pi->pid == kth->ktr_pid) {
363                                 TAILQ_REMOVE(&trace_procs, pi, info);
364                                 free(pi);
365                                 break;
366                         }
367                 }
368                 return (1);
369         }
370
371         return (0);
372 }
373
374 u_int
375 abidump(struct ktr_header *kth)
376 {
377         struct proc_info *pi;
378         const char *abi;
379         const char *arch;
380         u_int flags = 0;
381
382         TAILQ_FOREACH(pi, &trace_procs, info) {
383                 if (pi->pid == kth->ktr_pid) {
384                         flags = pi->sv_flags;
385                         break;
386                 }
387         }
388
389         if (abiflag == 0)
390                 return (flags);
391
392         switch (flags & SV_ABI_MASK) {
393         case SV_ABI_LINUX:
394                 abi = "L";
395                 break;
396         case SV_ABI_FREEBSD:
397                 abi = "F";
398                 break;
399         default:
400                 abi = "U";
401                 break;
402         }
403
404         if (flags != 0) {
405                 if (flags & SV_LP64)
406                         arch = "64";
407                 else
408                         arch = "32";
409         } else
410                 arch = "00";
411
412         printf("%s%s  ", abi, arch);
413
414         return (flags);
415 }
416
417 void
418 dumpheader(struct ktr_header *kth)
419 {
420         static char unknown[64];
421         static struct timeval prevtime, temp;
422         const char *type;
423
424         switch (kth->ktr_type) {
425         case KTR_SYSCALL:
426                 type = "CALL";
427                 break;
428         case KTR_SYSRET:
429                 type = "RET ";
430                 break;
431         case KTR_NAMEI:
432                 type = "NAMI";
433                 break;
434         case KTR_GENIO:
435                 type = "GIO ";
436                 break;
437         case KTR_PSIG:
438                 type = "PSIG";
439                 break;
440         case KTR_CSW:
441                 type = "CSW ";
442                 break;
443         case KTR_USER:
444                 type = "USER";
445                 break;
446         case KTR_STRUCT:
447                 type = "STRU";
448                 break;
449         case KTR_SYSCTL:
450                 type = "SCTL";
451                 break;
452         case KTR_PROCCTOR:
453                 /* FALLTHROUGH */
454         case KTR_PROCDTOR:
455                 return;
456         case KTR_FAULT:
457                 type = "PFLT";
458                 break;
459         case KTR_FAULTEND:
460                 type = "PRET";
461                 break;
462         default:
463                 (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
464                 type = unknown;
465         }
466
467         /*
468          * The ktr_tid field was previously the ktr_buffer field, which held
469          * the kernel pointer value for the buffer associated with data
470          * following the record header.  It now holds a threadid, but only
471          * for trace files after the change.  Older trace files still contain
472          * kernel pointers.  Detect this and suppress the results by printing
473          * negative tid's as 0.
474          */
475         if (threads)
476                 (void)printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid,
477                     kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0,
478                     MAXCOMLEN, kth->ktr_comm);
479         else
480                 (void)printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN,
481                     kth->ktr_comm);
482         if (timestamp) {
483                 if (timestamp == 3) {
484                         if (prevtime.tv_sec == 0)
485                                 prevtime = kth->ktr_time;
486                         timevalsub(&kth->ktr_time, &prevtime);
487                 }
488                 if (timestamp == 2) {
489                         temp = kth->ktr_time;
490                         timevalsub(&kth->ktr_time, &prevtime);
491                         prevtime = temp;
492                 }
493                 (void)printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec,
494                     kth->ktr_time.tv_usec);
495         }
496         (void)printf("%s  ", type);
497 }
498
499 #include <sys/syscall.h>
500 #define KTRACE
501 #include <sys/kern/syscalls.c>
502 #undef KTRACE
503 int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
504
505 void
506 ktrsyscall(struct ktr_syscall *ktr, u_int flags)
507 {
508         int narg = ktr->ktr_narg;
509         register_t *ip;
510
511         if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
512             (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0))
513                 (void)printf("[%d]", ktr->ktr_code);
514         else
515                 (void)printf("%s", syscallnames[ktr->ktr_code]);
516         ip = &ktr->ktr_args[0];
517         if (narg) {
518                 char c = '(';
519                 if (fancy &&
520                     (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
521                         if (ktr->ktr_code == SYS_ioctl) {
522                                 const char *cp;
523                                 print_number(ip,narg,c);
524                                 if ((cp = ioctlname(*ip)) != NULL)
525                                         (void)printf(",%s", cp);
526                                 else {
527                                         if (decimal)
528                                                 (void)printf(",%ld", (long)*ip);
529                                         else
530                                                 (void)printf(",%#lx ", (long)*ip);
531                                 }
532                                 c = ',';
533                                 ip++;
534                                 narg--;
535                         } else if (ktr->ktr_code == SYS_ptrace) {
536                                 (void)putchar('(');
537                                 ptraceopname ((int)*ip);
538                                 c = ',';
539                                 ip++;
540                                 narg--;
541                         } else if (ktr->ktr_code == SYS_access ||
542                                    ktr->ktr_code == SYS_eaccess) {
543                                 print_number(ip,narg,c);
544                                 (void)putchar(',');
545                                 accessmodename ((int)*ip);
546                                 ip++;
547                                 narg--;
548                         } else if (ktr->ktr_code == SYS_open) {
549                                 int     flags;
550                                 int     mode;
551                                 print_number(ip,narg,c);
552                                 flags = *ip;
553                                 mode = *++ip;
554                                 (void)putchar(',');
555                                 flagsandmodename (flags, mode, decimal);
556                                 ip++;
557                                 narg-=2;
558                         } else if (ktr->ktr_code == SYS_wait4) {
559                                 print_number(ip,narg,c);
560                                 print_number(ip,narg,c);
561                                 (void)putchar(',');
562                                 wait4optname ((int)*ip);
563                                 ip++;
564                                 narg--;
565                         } else if (ktr->ktr_code == SYS_chmod ||
566                                    ktr->ktr_code == SYS_fchmod ||
567                                    ktr->ktr_code == SYS_lchmod) {
568                                 print_number(ip,narg,c);
569                                 (void)putchar(',');
570                                 modename ((int)*ip);
571                                 ip++;
572                                 narg--;
573                         } else if (ktr->ktr_code == SYS_mknod) {
574                                 print_number(ip,narg,c);
575                                 (void)putchar(',');
576                                 modename ((int)*ip);
577                                 ip++;
578                                 narg--;
579                         } else if (ktr->ktr_code == SYS_getfsstat) {
580                                 print_number(ip,narg,c);
581                                 print_number(ip,narg,c);
582                                 (void)putchar(',');
583                                 getfsstatflagsname ((int)*ip);
584                                 ip++;
585                                 narg--;
586                         } else if (ktr->ktr_code == SYS_mount) {
587                                 print_number(ip,narg,c);
588                                 print_number(ip,narg,c);
589                                 (void)putchar(',');
590                                 mountflagsname ((int)*ip);
591                                 ip++;
592                                 narg--;
593                         } else if (ktr->ktr_code == SYS_unmount) {
594                                 print_number(ip,narg,c);
595                                 (void)putchar(',');
596                                 mountflagsname ((int)*ip);
597                                 ip++;
598                                 narg--;
599                         } else if (ktr->ktr_code == SYS_recvmsg ||
600                                    ktr->ktr_code == SYS_sendmsg) {
601                                 print_number(ip,narg,c);
602                                 print_number(ip,narg,c);
603                                 (void)putchar(',');
604                                 sendrecvflagsname ((int)*ip);
605                                 ip++;
606                                 narg--;
607                         } else if (ktr->ktr_code == SYS_recvfrom ||
608                                    ktr->ktr_code == SYS_sendto) {
609                                 print_number(ip,narg,c);
610                                 print_number(ip,narg,c);
611                                 print_number(ip,narg,c);
612                                 (void)putchar(',');
613                                 sendrecvflagsname ((int)*ip);
614                                 ip++;
615                                 narg--;
616                         } else if (ktr->ktr_code == SYS_chflags ||
617                                    ktr->ktr_code == SYS_fchflags ||
618                                    ktr->ktr_code == SYS_lchflags) {
619                                 print_number(ip,narg,c);
620                                 (void)putchar(',');
621                                 modename((int)*ip);
622                                 ip++;
623                                 narg--;
624                         } else if (ktr->ktr_code == SYS_kill) {
625                                 print_number(ip,narg,c);
626                                 (void)putchar(',');
627                                 signame((int)*ip);
628                                 ip++;
629                                 narg--;
630                         } else if (ktr->ktr_code == SYS_reboot) {
631                                 (void)putchar('(');
632                                 rebootoptname((int)*ip);
633                                 ip++;
634                                 narg--;
635                         } else if (ktr->ktr_code == SYS_umask) {
636                                 (void)putchar('(');
637                                 modename((int)*ip);
638                                 ip++;
639                                 narg--;
640                         } else if (ktr->ktr_code == SYS_msync) {
641                                 print_number(ip,narg,c);
642                                 print_number(ip,narg,c);
643                                 (void)putchar(',');
644                                 msyncflagsname((int)*ip);
645                                 ip++;
646                                 narg--;
647 #ifdef SYS_freebsd6_mmap
648                         } else if (ktr->ktr_code == SYS_freebsd6_mmap) {
649                                 print_number(ip,narg,c);
650                                 print_number(ip,narg,c);
651                                 (void)putchar(',');
652                                 mmapprotname ((int)*ip);
653                                 (void)putchar(',');
654                                 ip++;
655                                 narg--;
656                                 mmapflagsname ((int)*ip);
657                                 ip++;
658                                 narg--;
659 #endif
660                         } else if (ktr->ktr_code == SYS_mmap) {
661                                 print_number(ip,narg,c);
662                                 print_number(ip,narg,c);
663                                 (void)putchar(',');
664                                 mmapprotname ((int)*ip);
665                                 (void)putchar(',');
666                                 ip++;
667                                 narg--;
668                                 mmapflagsname ((int)*ip);
669                                 ip++;
670                                 narg--;
671                         } else if (ktr->ktr_code == SYS_mprotect) {
672                                 print_number(ip,narg,c);
673                                 print_number(ip,narg,c);
674                                 (void)putchar(',');
675                                 mmapprotname ((int)*ip);
676                                 ip++;
677                                 narg--;
678                         } else if (ktr->ktr_code == SYS_madvise) {
679                                 print_number(ip,narg,c);
680                                 print_number(ip,narg,c);
681                                 (void)putchar(',');
682                                 madvisebehavname((int)*ip);
683                                 ip++;
684                                 narg--;
685                         } else if (ktr->ktr_code == SYS_setpriority) {
686                                 print_number(ip,narg,c);
687                                 print_number(ip,narg,c);
688                                 (void)putchar(',');
689                                 prioname((int)*ip);
690                                 ip++;
691                                 narg--;
692                         } else if (ktr->ktr_code == SYS_fcntl) {
693                                 int cmd;
694                                 int arg;
695                                 print_number(ip,narg,c);
696                                 cmd = *ip;
697                                 arg = *++ip;
698                                 (void)putchar(',');
699                                 fcntlcmdname(cmd, arg, decimal);
700                                 ip++;
701                                 narg-=2;
702                         } else if (ktr->ktr_code == SYS_socket) {
703                                 int sockdomain;
704                                 (void)putchar('(');
705                                 sockdomain=(int)*ip;
706                                 sockdomainname(sockdomain);
707                                 ip++;
708                                 narg--;
709                                 (void)putchar(',');
710                                 socktypename((int)*ip);
711                                 ip++;
712                                 narg--;
713                                 if (sockdomain == PF_INET ||
714                                     sockdomain == PF_INET6) {
715                                         (void)putchar(',');
716                                         sockipprotoname((int)*ip);
717                                         ip++;
718                                         narg--;
719                                 }
720                                 c = ',';
721                         } else if (ktr->ktr_code == SYS_setsockopt ||
722                                    ktr->ktr_code == SYS_getsockopt) {
723                                 print_number(ip,narg,c);
724                                 (void)putchar(',');
725                                 sockoptlevelname((int)*ip, decimal);
726                                 if ((int)*ip == SOL_SOCKET) {
727                                         ip++;
728                                         narg--;
729                                         (void)putchar(',');
730                                         sockoptname((int)*ip);
731                                 }
732                                 ip++;
733                                 narg--;
734 #ifdef SYS_freebsd6_lseek
735                         } else if (ktr->ktr_code == SYS_freebsd6_lseek) {
736                                 print_number(ip,narg,c);
737                                 /* Hidden 'pad' argument, not in lseek(2) */
738                                 print_number(ip,narg,c);
739                                 print_number(ip,narg,c);
740                                 (void)putchar(',');
741                                 whencename ((int)*ip);
742                                 ip++;
743                                 narg--;
744 #endif
745                         } else if (ktr->ktr_code == SYS_lseek) {
746                                 print_number(ip,narg,c);
747                                 /* Hidden 'pad' argument, not in lseek(2) */
748                                 print_number(ip,narg,c);
749                                 (void)putchar(',');
750                                 whencename ((int)*ip);
751                                 ip++;
752                                 narg--;
753
754                         } else if (ktr->ktr_code == SYS_flock) {
755                                 print_number(ip,narg,c);
756                                 (void)putchar(',');
757                                 flockname((int)*ip);
758                                 ip++;
759                                 narg--;
760                         } else if (ktr->ktr_code == SYS_mkfifo ||
761                                    ktr->ktr_code == SYS_mkdir) {
762                                 print_number(ip,narg,c);
763                                 (void)putchar(',');
764                                 modename((int)*ip);
765                                 ip++;
766                                 narg--;
767                         } else if (ktr->ktr_code == SYS_shutdown) {
768                                 print_number(ip,narg,c);
769                                 (void)putchar(',');
770                                 shutdownhowname((int)*ip);
771                                 ip++;
772                                 narg--;
773                         } else if (ktr->ktr_code == SYS_socketpair) {
774                                 (void)putchar('(');
775                                 sockdomainname((int)*ip);
776                                 ip++;
777                                 narg--;
778                                 (void)putchar(',');
779                                 socktypename((int)*ip);
780                                 ip++;
781                                 narg--;
782                                 c = ',';
783                         } else if (ktr->ktr_code == SYS_getrlimit ||
784                                    ktr->ktr_code == SYS_setrlimit) {
785                                 (void)putchar('(');
786                                 rlimitname((int)*ip);
787                                 ip++;
788                                 narg--;
789                                 c = ',';
790                         } else if (ktr->ktr_code == SYS_quotactl) {
791                                 print_number(ip,narg,c);
792                                 (void)putchar(',');
793                                 quotactlname((int)*ip);
794                                 ip++;
795                                 narg--;
796                                 c = ',';
797                         } else if (ktr->ktr_code == SYS_nfssvc) {
798                                 (void)putchar('(');
799                                 nfssvcname((int)*ip);
800                                 ip++;
801                                 narg--;
802                                 c = ',';
803                         } else if (ktr->ktr_code == SYS_rtprio) {
804                                 (void)putchar('(');
805                                 rtprioname((int)*ip);
806                                 ip++;
807                                 narg--;
808                                 c = ',';
809                         } else if (ktr->ktr_code == SYS___semctl) {
810                                 print_number(ip,narg,c);
811                                 print_number(ip,narg,c);
812                                 (void)putchar(',');
813                                 semctlname((int)*ip);
814                                 ip++;
815                                 narg--;
816                         } else if (ktr->ktr_code == SYS_semget) {
817                                 print_number(ip,narg,c);
818                                 print_number(ip,narg,c);
819                                 (void)putchar(',');
820                                 semgetname((int)*ip);
821                                 ip++;
822                                 narg--;
823                         } else if (ktr->ktr_code == SYS_msgctl) {
824                                 print_number(ip,narg,c);
825                                 (void)putchar(',');
826                                 shmctlname((int)*ip);
827                                 ip++;
828                                 narg--;
829                         } else if (ktr->ktr_code == SYS_shmat) {
830                                 print_number(ip,narg,c);
831                                 print_number(ip,narg,c);
832                                 (void)putchar(',');
833                                 shmatname((int)*ip);
834                                 ip++;
835                                 narg--;
836                         } else if (ktr->ktr_code == SYS_shmctl) {
837                                 print_number(ip,narg,c);
838                                 (void)putchar(',');
839                                 shmctlname((int)*ip);
840                                 ip++;
841                                 narg--;
842                         } else if (ktr->ktr_code == SYS_minherit) {
843                                 print_number(ip,narg,c);
844                                 print_number(ip,narg,c);
845                                 (void)putchar(',');
846                                 minheritname((int)*ip);
847                                 ip++;
848                                 narg--;
849                         } else if (ktr->ktr_code == SYS_rfork) {
850                                 (void)putchar('(');
851                                 rforkname((int)*ip);
852                                 ip++;
853                                 narg--;
854                                 c = ',';
855                         } else if (ktr->ktr_code == SYS_lio_listio) {
856                                 (void)putchar('(');
857                                 lio_listioname((int)*ip);
858                                 ip++;
859                                 narg--;
860                                 c = ',';
861                         } else if (ktr->ktr_code == SYS_mlockall) {
862                                 (void)putchar('(');
863                                 mlockallname((int)*ip);
864                                 ip++;
865                                 narg--;
866                         } else if (ktr->ktr_code == SYS_sched_setscheduler) {
867                                 print_number(ip,narg,c);
868                                 (void)putchar(',');
869                                 schedpolicyname((int)*ip);
870                                 ip++;
871                                 narg--;
872                         } else if (ktr->ktr_code == SYS_sched_get_priority_max ||
873                                    ktr->ktr_code == SYS_sched_get_priority_min) {
874                                 (void)putchar('(');
875                                 schedpolicyname((int)*ip);
876                                 ip++;
877                                 narg--;
878                         } else if (ktr->ktr_code == SYS_sendfile) {
879                                 print_number(ip,narg,c);
880                                 print_number(ip,narg,c);
881                                 print_number(ip,narg,c);
882                                 print_number(ip,narg,c);
883                                 print_number(ip,narg,c);
884                                 print_number(ip,narg,c);
885                                 (void)putchar(',');
886                                 sendfileflagsname((int)*ip);
887                                 ip++;
888                                 narg--;
889                         } else if (ktr->ktr_code == SYS_kldsym) {
890                                 print_number(ip,narg,c);
891                                 (void)putchar(',');
892                                 kldsymcmdname((int)*ip);
893                                 ip++;
894                                 narg--;
895                         } else if (ktr->ktr_code == SYS_sigprocmask) {
896                                 (void)putchar('(');
897                                 sigprocmaskhowname((int)*ip);
898                                 ip++;
899                                 narg--;
900                                 c = ',';
901                         } else if (ktr->ktr_code == SYS___acl_get_file ||
902                                    ktr->ktr_code == SYS___acl_set_file ||
903                                    ktr->ktr_code == SYS___acl_get_fd ||
904                                    ktr->ktr_code == SYS___acl_set_fd ||
905                                    ktr->ktr_code == SYS___acl_delete_file ||
906                                    ktr->ktr_code == SYS___acl_delete_fd ||
907                                    ktr->ktr_code == SYS___acl_aclcheck_file ||
908                                    ktr->ktr_code == SYS___acl_aclcheck_fd ||
909                                    ktr->ktr_code == SYS___acl_get_link ||
910                                    ktr->ktr_code == SYS___acl_set_link ||
911                                    ktr->ktr_code == SYS___acl_delete_link ||
912                                    ktr->ktr_code == SYS___acl_aclcheck_link) {
913                                 print_number(ip,narg,c);
914                                 (void)putchar(',');
915                                 acltypename((int)*ip);
916                                 ip++;
917                                 narg--;
918                         } else if (ktr->ktr_code == SYS_sigaction) {
919                                 (void)putchar('(');
920                                 signame((int)*ip);
921                                 ip++;
922                                 narg--;
923                                 c = ',';
924                         } else if (ktr->ktr_code == SYS_extattrctl) {
925                                 print_number(ip,narg,c);
926                                 (void)putchar(',');
927                                 extattrctlname((int)*ip);
928                                 ip++;
929                                 narg--;
930                         } else if (ktr->ktr_code == SYS_nmount) {
931                                 print_number(ip,narg,c);
932                                 print_number(ip,narg,c);
933                                 (void)putchar(',');
934                                 mountflagsname ((int)*ip);
935                                 ip++;
936                                 narg--;
937                         } else if (ktr->ktr_code == SYS_thr_create) {
938                                 print_number(ip,narg,c);
939                                 print_number(ip,narg,c);
940                                 (void)putchar(',');
941                                 thrcreateflagsname ((int)*ip);
942                                 ip++;
943                                 narg--;
944                         } else if (ktr->ktr_code == SYS_thr_kill) {
945                                 print_number(ip,narg,c);
946                                 (void)putchar(',');
947                                 signame ((int)*ip);
948                                 ip++;
949                                 narg--;
950                         } else if (ktr->ktr_code == SYS_kldunloadf) {
951                                 print_number(ip,narg,c);
952                                 (void)putchar(',');
953                                 kldunloadfflagsname ((int)*ip);
954                                 ip++;
955                                 narg--;
956                         } else if (ktr->ktr_code == SYS_posix_fadvise) {
957                                 print_number(ip,narg,c);
958                                 print_number(ip,narg,c);
959                                 print_number(ip,narg,c);
960                                 (void)putchar(',');
961                                 fadvisebehavname((int)*ip);
962                                 ip++;
963                                 narg--;
964                         }
965                 }
966                 while (narg > 0) {
967                         print_number(ip,narg,c);
968                 }
969                 (void)putchar(')');
970         }
971         (void)putchar('\n');
972 }
973
974 void
975 ktrsysret(struct ktr_sysret *ktr, u_int flags)
976 {
977         register_t ret = ktr->ktr_retval;
978         int error = ktr->ktr_error;
979         int code = ktr->ktr_code;
980
981         if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) ||
982             (code >= nsyscalls || code < 0))
983                 (void)printf("[%d] ", code);
984         else
985                 (void)printf("%s ", syscallnames[code]);
986
987         if (error == 0) {
988                 if (fancy) {
989                         (void)printf("%ld", (long)ret);
990                         if (ret < 0 || ret > 9)
991                                 (void)printf("/%#lx", (long)ret);
992                 } else {
993                         if (decimal)
994                                 (void)printf("%ld", (long)ret);
995                         else
996                                 (void)printf("%#lx", (long)ret);
997                 }
998         } else if (error == ERESTART)
999                 (void)printf("RESTART");
1000         else if (error == EJUSTRETURN)
1001                 (void)printf("JUSTRETURN");
1002         else {
1003                 (void)printf("-1 errno %d", ktr->ktr_error);
1004                 if (fancy)
1005                         (void)printf(" %s", strerror(ktr->ktr_error));
1006         }
1007         (void)putchar('\n');
1008 }
1009
1010 void
1011 ktrnamei(char *cp, int len)
1012 {
1013         (void)printf("\"%.*s\"\n", len, cp);
1014 }
1015
1016 void
1017 hexdump(char *p, int len, int screenwidth)
1018 {
1019         int n, i;
1020         int width;
1021
1022         width = 0;
1023         do {
1024                 width += 2;
1025                 i = 13;                 /* base offset */
1026                 i += (width / 2) + 1;   /* spaces every second byte */
1027                 i += (width * 2);       /* width of bytes */
1028                 i += 3;                 /* "  |" */
1029                 i += width;             /* each byte */
1030                 i += 1;                 /* "|" */
1031         } while (i < screenwidth);
1032         width -= 2;
1033
1034         for (n = 0; n < len; n += width) {
1035                 for (i = n; i < n + width; i++) {
1036                         if ((i % width) == 0) { /* beginning of line */
1037                                 printf("       0x%04x", i);
1038                         }
1039                         if ((i % 2) == 0) {
1040                                 printf(" ");
1041                         }
1042                         if (i < len)
1043                                 printf("%02x", p[i] & 0xff);
1044                         else
1045                                 printf("  ");
1046                 }
1047                 printf("  |");
1048                 for (i = n; i < n + width; i++) {
1049                         if (i >= len)
1050                                 break;
1051                         if (p[i] >= ' ' && p[i] <= '~')
1052                                 printf("%c", p[i]);
1053                         else
1054                                 printf(".");
1055                 }
1056                 printf("|\n");
1057         }
1058         if ((i % width) != 0)
1059                 printf("\n");
1060 }
1061
1062 void
1063 visdump(char *dp, int datalen, int screenwidth)
1064 {
1065         int col = 0;
1066         char *cp;
1067         int width;
1068         char visbuf[5];
1069
1070         (void)printf("       \"");
1071         col = 8;
1072         for (;datalen > 0; datalen--, dp++) {
1073                 (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
1074                 cp = visbuf;
1075                 /*
1076                  * Keep track of printables and
1077                  * space chars (like fold(1)).
1078                  */
1079                 if (col == 0) {
1080                         (void)putchar('\t');
1081                         col = 8;
1082                 }
1083                 switch(*cp) {
1084                 case '\n':
1085                         col = 0;
1086                         (void)putchar('\n');
1087                         continue;
1088                 case '\t':
1089                         width = 8 - (col&07);
1090                         break;
1091                 default:
1092                         width = strlen(cp);
1093                 }
1094                 if (col + width > (screenwidth-2)) {
1095                         (void)printf("\\\n\t");
1096                         col = 8;
1097                 }
1098                 col += width;
1099                 do {
1100                         (void)putchar(*cp++);
1101                 } while (*cp);
1102         }
1103         if (col == 0)
1104                 (void)printf("       ");
1105         (void)printf("\"\n");
1106 }
1107
1108 void
1109 ktrgenio(struct ktr_genio *ktr, int len)
1110 {
1111         int datalen = len - sizeof (struct ktr_genio);
1112         char *dp = (char *)ktr + sizeof (struct ktr_genio);
1113         static int screenwidth = 0;
1114         int i, binary;
1115
1116         if (screenwidth == 0) {
1117                 struct winsize ws;
1118
1119                 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1120                     ws.ws_col > 8)
1121                         screenwidth = ws.ws_col;
1122                 else
1123                         screenwidth = 80;
1124         }
1125         printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
1126                 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
1127                 datalen == 1 ? "" : "s");
1128         if (suppressdata)
1129                 return;
1130         if (maxdata && datalen > maxdata)
1131                 datalen = maxdata;
1132
1133         for (i = 0, binary = 0; i < datalen && binary == 0; i++)  {
1134                 if (dp[i] >= 32 && dp[i] < 127)
1135                         continue;
1136                 if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9)
1137                         continue;
1138                 binary = 1;
1139         }
1140         if (binary)
1141                 hexdump(dp, datalen, screenwidth);
1142         else
1143                 visdump(dp, datalen, screenwidth);
1144 }
1145
1146 const char *signames[] = {
1147         "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT",     /*  1 - 6  */
1148         "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS",             /*  7 - 12 */
1149         "PIPE", "ALRM",  "TERM", "URG", "STOP", "TSTP",         /* 13 - 18 */
1150         "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU",           /* 19 - 24 */
1151         "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1",        /* 25 - 30 */
1152         "USR2", NULL,                                           /* 31 - 32 */
1153 };
1154
1155 void
1156 ktrpsig(struct ktr_psig *psig)
1157 {
1158         if (psig->signo > 0 && psig->signo < NSIG)
1159                 (void)printf("SIG%s ", signames[psig->signo]);
1160         else
1161                 (void)printf("SIG %d ", psig->signo);
1162         if (psig->action == SIG_DFL)
1163                 (void)printf("SIG_DFL code=0x%x\n", psig->code);
1164         else {
1165                 (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n",
1166                     (u_long)psig->action, psig->mask.__bits[0], psig->code);
1167         }
1168 }
1169
1170 void
1171 ktrcsw_old(struct ktr_csw_old *cs)
1172 {
1173         (void)printf("%s %s\n", cs->out ? "stop" : "resume",
1174                 cs->user ? "user" : "kernel");
1175 }
1176
1177 void
1178 ktrcsw(struct ktr_csw *cs)
1179 {
1180         printf("%s %s \"%s\"\n", cs->out ? "stop" : "resume",
1181             cs->user ? "user" : "kernel", cs->wmesg);
1182 }
1183
1184 #define UTRACE_DLOPEN_START             1
1185 #define UTRACE_DLOPEN_STOP              2
1186 #define UTRACE_DLCLOSE_START            3
1187 #define UTRACE_DLCLOSE_STOP             4
1188 #define UTRACE_LOAD_OBJECT              5
1189 #define UTRACE_UNLOAD_OBJECT            6
1190 #define UTRACE_ADD_RUNDEP               7
1191 #define UTRACE_PRELOAD_FINISHED         8
1192 #define UTRACE_INIT_CALL                9
1193 #define UTRACE_FINI_CALL                10
1194
1195 struct utrace_rtld {
1196         char sig[4];                            /* 'RTLD' */
1197         int event;
1198         void *handle;
1199         void *mapbase;
1200         size_t mapsize;
1201         int refcnt;
1202         char name[MAXPATHLEN];
1203 };
1204
1205 void
1206 ktruser_rtld(int len, unsigned char *p)
1207 {
1208         struct utrace_rtld *ut = (struct utrace_rtld *)p;
1209         void *parent;
1210         int mode;
1211
1212         switch (ut->event) {
1213         case UTRACE_DLOPEN_START:
1214                 mode = ut->refcnt;
1215                 printf("dlopen(%s, ", ut->name);
1216                 switch (mode & RTLD_MODEMASK) {
1217                 case RTLD_NOW:
1218                         printf("RTLD_NOW");
1219                         break;
1220                 case RTLD_LAZY:
1221                         printf("RTLD_LAZY");
1222                         break;
1223                 default:
1224                         printf("%#x", mode & RTLD_MODEMASK);
1225                 }
1226                 if (mode & RTLD_GLOBAL)
1227                         printf(" | RTLD_GLOBAL");
1228                 if (mode & RTLD_TRACE)
1229                         printf(" | RTLD_TRACE");
1230                 if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
1231                         printf(" | %#x", mode &
1232                             ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
1233                 printf(")\n");
1234                 break;
1235         case UTRACE_DLOPEN_STOP:
1236                 printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
1237                     ut->refcnt);
1238                 break;
1239         case UTRACE_DLCLOSE_START:
1240                 printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
1241                     ut->refcnt);
1242                 break;
1243         case UTRACE_DLCLOSE_STOP:
1244                 printf("dlclose(%p) finished\n", ut->handle);
1245                 break;
1246         case UTRACE_LOAD_OBJECT:
1247                 printf("RTLD: loaded   %p @ %p - %p (%s)\n", ut->handle,
1248                     ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1249                     ut->name);
1250                 break;
1251         case UTRACE_UNLOAD_OBJECT:
1252                 printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
1253                     ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
1254                     ut->name);
1255                 break;
1256         case UTRACE_ADD_RUNDEP:
1257                 parent = ut->mapbase;
1258                 printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
1259                     ut->handle, ut->name, ut->refcnt);
1260                 break;
1261         case UTRACE_PRELOAD_FINISHED:
1262                 printf("RTLD: LD_PRELOAD finished\n");
1263                 break;
1264         case UTRACE_INIT_CALL:
1265                 printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1266                     ut->name);
1267                 break;
1268         case UTRACE_FINI_CALL:
1269                 printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1270                     ut->name);
1271                 break;
1272         default:
1273                 p += 4;
1274                 len -= 4;
1275                 printf("RTLD: %d ", len);
1276                 while (len--)
1277                         if (decimal)
1278                                 printf(" %d", *p++);
1279                         else
1280                                 printf(" %02x", *p++);
1281                 printf("\n");
1282         }
1283 }
1284
1285 struct utrace_malloc {
1286         void *p;
1287         size_t s;
1288         void *r;
1289 };
1290
1291 void
1292 ktruser_malloc(int len, unsigned char *p)
1293 {
1294         struct utrace_malloc *ut = (struct utrace_malloc *)p;
1295
1296         if (ut->p == (void *)(intptr_t)(-1))
1297                 printf("malloc_init()\n");
1298         else if (ut->s == 0)
1299                 printf("free(%p)\n", ut->p);
1300         else if (ut->p == NULL)
1301                 printf("%p = malloc(%zu)\n", ut->r, ut->s);
1302         else
1303                 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1304 }
1305
1306 void
1307 ktruser(int len, unsigned char *p)
1308 {
1309
1310         if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1311                 ktruser_rtld(len, p);
1312                 return;
1313         }
1314
1315         if (len == sizeof(struct utrace_malloc)) {
1316                 ktruser_malloc(len, p);
1317                 return;
1318         }
1319
1320         (void)printf("%d ", len);
1321         while (len--)
1322                 if (decimal)
1323                         (void)printf(" %d", *p++);
1324                 else
1325                         (void)printf(" %02x", *p++);
1326         (void)printf("\n");
1327 }
1328
1329 void
1330 ktrsockaddr(struct sockaddr *sa)
1331 {
1332 /*
1333  TODO: Support additional address families
1334         #include <netnatm/natm.h>
1335         struct sockaddr_natm    *natm;
1336         #include <netsmb/netbios.h>
1337         struct sockaddr_nb      *nb;
1338 */
1339         char addr[64];
1340
1341         /*
1342          * note: ktrstruct() has already verified that sa points to a
1343          * buffer at least sizeof(struct sockaddr) bytes long and exactly
1344          * sa->sa_len bytes long.
1345          */
1346         printf("struct sockaddr { ");
1347         sockfamilyname(sa->sa_family);
1348         printf(", ");
1349
1350 #define check_sockaddr_len(n)                                   \
1351         if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \
1352                 printf("invalid");                              \
1353                 break;                                          \
1354         }
1355
1356         switch(sa->sa_family) {
1357         case AF_INET: {
1358                 struct sockaddr_in      *sa_in;
1359
1360                 sa_in = (struct sockaddr_in *)sa;
1361                 check_sockaddr_len(in);
1362                 inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr);
1363                 printf("%s:%u", addr, ntohs(sa_in->sin_port));
1364                 break;
1365         }
1366 #ifdef NETATALK
1367         case AF_APPLETALK: {
1368                 struct sockaddr_at      *sa_at;
1369                 struct netrange         *nr;
1370
1371                 sa_at = (struct sockaddr_at *)sa;
1372                 check_sockaddr_len(at);
1373                 nr = &sa_at->sat_range.r_netrange;
1374                 printf("%d.%d, %d-%d, %d", ntohs(sa_at->sat_addr.s_net),
1375                         sa_at->sat_addr.s_node, ntohs(nr->nr_firstnet),
1376                         ntohs(nr->nr_lastnet), nr->nr_phase);
1377                 break;
1378         }
1379 #endif
1380         case AF_INET6: {
1381                 struct sockaddr_in6     *sa_in6;
1382
1383                 sa_in6 = (struct sockaddr_in6 *)sa;
1384                 check_sockaddr_len(in6);
1385                 inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr);
1386                 printf("[%s]:%u", addr, htons(sa_in6->sin6_port));
1387                 break;
1388         }
1389 #ifdef IPX
1390         case AF_IPX: {
1391                 struct sockaddr_ipx     *sa_ipx;
1392
1393                 sa_ipx = (struct sockaddr_ipx *)sa;
1394                 check_sockaddr_len(ipx);
1395                 /* XXX wish we had ipx_ntop */
1396                 printf("%s", ipx_ntoa(sa_ipx->sipx_addr));
1397                 break;
1398         }
1399 #endif
1400         case AF_UNIX: {
1401                 struct sockaddr_un *sa_un;
1402
1403                 sa_un = (struct sockaddr_un *)sa;
1404                 check_sockaddr_len(un);
1405                 printf("%.*s", (int)sizeof(sa_un->sun_path), sa_un->sun_path);
1406                 break;
1407         }
1408         default:
1409                 printf("unknown address family");
1410         }
1411         printf(" }\n");
1412 }
1413
1414 void
1415 ktrstat(struct stat *statp)
1416 {
1417         char mode[12], timestr[PATH_MAX + 4];
1418         struct passwd *pwd;
1419         struct group  *grp;
1420         struct tm *tm;
1421
1422         /*
1423          * note: ktrstruct() has already verified that statp points to a
1424          * buffer exactly sizeof(struct stat) bytes long.
1425          */
1426         printf("struct stat {");
1427         strmode(statp->st_mode, mode);
1428         printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ",
1429                 (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode,
1430                 (uintmax_t)statp->st_nlink);
1431         if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1432                 printf("uid=%ju, ", (uintmax_t)statp->st_uid);
1433         else
1434                 printf("uid=\"%s\", ", pwd->pw_name);
1435         if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1436                 printf("gid=%ju, ", (uintmax_t)statp->st_gid);
1437         else
1438                 printf("gid=\"%s\", ", grp->gr_name);
1439         printf("rdev=%ju, ", (uintmax_t)statp->st_rdev);
1440         printf("atime=");
1441         if (resolv == 0)
1442                 printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1443         else {
1444                 tm = localtime(&statp->st_atim.tv_sec);
1445                 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1446                 printf("\"%s\"", timestr);
1447         }
1448         if (statp->st_atim.tv_nsec != 0)
1449                 printf(".%09ld, ", statp->st_atim.tv_nsec);
1450         else
1451                 printf(", ");
1452         printf("stime=");
1453         if (resolv == 0)
1454                 printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1455         else {
1456                 tm = localtime(&statp->st_mtim.tv_sec);
1457                 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1458                 printf("\"%s\"", timestr);
1459         }
1460         if (statp->st_mtim.tv_nsec != 0)
1461                 printf(".%09ld, ", statp->st_mtim.tv_nsec);
1462         else
1463                 printf(", ");
1464         printf("ctime=");
1465         if (resolv == 0)
1466                 printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1467         else {
1468                 tm = localtime(&statp->st_ctim.tv_sec);
1469                 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1470                 printf("\"%s\"", timestr);
1471         }
1472         if (statp->st_ctim.tv_nsec != 0)
1473                 printf(".%09ld, ", statp->st_ctim.tv_nsec);
1474         else
1475                 printf(", ");
1476         printf("birthtime=");
1477         if (resolv == 0)
1478                 printf("%jd", (intmax_t)statp->st_birthtim.tv_sec);
1479         else {
1480                 tm = localtime(&statp->st_birthtim.tv_sec);
1481                 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1482                 printf("\"%s\"", timestr);
1483         }
1484         if (statp->st_birthtim.tv_nsec != 0)
1485                 printf(".%09ld, ", statp->st_birthtim.tv_nsec);
1486         else
1487                 printf(", ");
1488         printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x",
1489                 (uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize,
1490                 (intmax_t)statp->st_blocks, statp->st_flags);
1491         printf(" }\n");
1492 }
1493
1494 void
1495 ktrstruct(char *buf, size_t buflen)
1496 {
1497         char *name, *data;
1498         size_t namelen, datalen;
1499         int i;
1500         struct stat sb;
1501         struct sockaddr_storage ss;
1502
1503         for (name = buf, namelen = 0;
1504              namelen < buflen && name[namelen] != '\0';
1505              ++namelen)
1506                 /* nothing */;
1507         if (namelen == buflen)
1508                 goto invalid;
1509         if (name[namelen] != '\0')
1510                 goto invalid;
1511         data = buf + namelen + 1;
1512         datalen = buflen - namelen - 1;
1513         if (datalen == 0)
1514                 goto invalid;
1515         /* sanity check */
1516         for (i = 0; i < namelen; ++i)
1517                 if (!isalpha((unsigned char)name[i]))
1518                         goto invalid;
1519         if (strcmp(name, "stat") == 0) {
1520                 if (datalen != sizeof(struct stat))
1521                         goto invalid;
1522                 memcpy(&sb, data, datalen);
1523                 ktrstat(&sb);
1524         } else if (strcmp(name, "sockaddr") == 0) {
1525                 if (datalen > sizeof(ss))
1526                         goto invalid;
1527                 memcpy(&ss, data, datalen);
1528                 if (datalen < sizeof(struct sockaddr) ||
1529                     datalen != ss.ss_len)
1530                         goto invalid;
1531                 ktrsockaddr((struct sockaddr *)&ss);
1532         } else {
1533                 printf("unknown structure\n");
1534         }
1535         return;
1536 invalid:
1537         printf("invalid record\n");
1538 }
1539
1540 void
1541 ktrfault(struct ktr_fault *ktr)
1542 {
1543
1544         printf("0x%jx ", ktr->vaddr);
1545         vmprotname(ktr->type);
1546         printf("\n");
1547 }
1548
1549 void
1550 ktrfaultend(struct ktr_faultend *ktr)
1551 {
1552
1553         vmresultname(ktr->result);
1554         printf("\n");
1555 }
1556
1557 #if defined(__amd64__) || defined(__i386__)
1558 void
1559 linux_ktrsyscall(struct ktr_syscall *ktr)
1560 {
1561         int narg = ktr->ktr_narg;
1562         register_t *ip;
1563
1564         if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0)
1565                 printf("[%d]", ktr->ktr_code);
1566         else
1567                 printf("%s", linux_syscallnames[ktr->ktr_code]);
1568         ip = &ktr->ktr_args[0];
1569         if (narg) {
1570                 char c = '(';
1571                 while (narg > 0)
1572                         print_number(ip, narg, c);
1573                 putchar(')');
1574         }
1575         putchar('\n');
1576 }
1577
1578 void
1579 linux_ktrsysret(struct ktr_sysret *ktr)
1580 {
1581         register_t ret = ktr->ktr_retval;
1582         int error = ktr->ktr_error;
1583         int code = ktr->ktr_code;
1584
1585         if (code >= nlinux_syscalls || code < 0)
1586                 printf("[%d] ", code);
1587         else
1588                 printf("%s ", linux_syscallnames[code]);
1589
1590         if (error == 0) {
1591                 if (fancy) {
1592                         printf("%ld", (long)ret);
1593                         if (ret < 0 || ret > 9)
1594                                 printf("/%#lx", (long)ret);
1595                 } else {
1596                         if (decimal)
1597                                 printf("%ld", (long)ret);
1598                         else
1599                                 printf("%#lx", (long)ret);
1600                 }
1601         } else if (error == ERESTART)
1602                 printf("RESTART");
1603         else if (error == EJUSTRETURN)
1604                 printf("JUSTRETURN");
1605         else {
1606                 if (ktr->ktr_error <= ELAST + 1)
1607                         error = abs(bsd_to_linux_errno[ktr->ktr_error]);
1608                 else
1609                         error = 999;
1610                 printf("-1 errno %d", error);
1611                 if (fancy)
1612                         printf(" %s", strerror(ktr->ktr_error));
1613         }
1614         putchar('\n');
1615 }
1616 #endif
1617
1618 void
1619 usage(void)
1620 {
1621         fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] "
1622             "[-m maxdata] [-p pid] [-t trstr]\n");
1623         exit(1);
1624 }