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