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