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